aboutsummaryrefslogtreecommitdiff
path: root/mcp/server.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'mcp/server.mjs')
-rwxr-xr-xmcp/server.mjs23
1 files changed, 18 insertions, 5 deletions
diff --git a/mcp/server.mjs b/mcp/server.mjs
index 9c3bea4..c6e70f1 100755
--- a/mcp/server.mjs
+++ b/mcp/server.mjs
@@ -211,6 +211,8 @@ const pi = {
active = new Set(names);
},
sendMessage() {},
+ // pi-chrome logs authorization changes to the session history; there is none here.
+ appendEntry() {},
exec: async () => ({ code: 1, stdout: "", stderr: "not available in the MCP server" }),
};
@@ -223,10 +225,14 @@ async function emit(event, payload) {
// --- load pi-chrome ---------------------------------------------------------------------------
// pi-chrome imports typebox at runtime, and its own directory may have no node_modules: point it
-// at the copy pinned here, the version pi ships. jiti rather than Node's type stripping, because
-// pi-chrome uses constructor parameter properties, which strip-only mode rejects.
+// at the copy pinned here, the version pi ships, and pi-tui at a stand-in. jiti rather than Node's
+// type stripping, because pi-chrome uses constructor parameter properties, which strip-only mode
+// rejects.
const jiti = createJiti(import.meta.url, {
- alias: { typebox: fileURLToPath(import.meta.resolve("typebox")) },
+ alias: {
+ typebox: fileURLToPath(import.meta.resolve("typebox")),
+ "@earendil-works/pi-tui": fileURLToPath(new URL("pi-tui.mjs", import.meta.url)),
+ },
});
const extension = await jiti.import(EXTENSION, { default: true });
extension(pi);
@@ -245,12 +251,19 @@ if (active.size === 0) {
// A fork's primer may name another browser's tools, which differ by client: browser_* in pi,
// mcp__<server>__* elsewhere. pi-chrome reads PI_CHROME_OTHER_BROWSER_TOOLS as it builds the
// primer, synchronously inside the handler, so the variable only has to hold for that call.
+const UPSTREAM_SECTION = "chrome-profile-bridge";
async function instructionsWith(otherTools) {
const saved = process.env.PI_CHROME_OTHER_BROWSER_TOOLS;
if (otherTools) process.env.PI_CHROME_OTHER_BROWSER_TOOLS = otherTools;
- const pending = emit("before_agent_start", { systemPrompt: "" });
+ // pi-chrome adds its primer as named prompt sections, one per handler (upstream's and a fork's),
+ // or, written for an older pi, returns a whole systemPrompt instead. Take both; upstream's goes
+ // first.
+ const sections = {};
+ const pending = emit("before_agent_start", { systemPrompt: "", systemPromptOptions: { sections } });
process.env.PI_CHROME_OTHER_BROWSER_TOOLS = saved;
- const primer = (await pending)?.systemPrompt ?? "";
+ const returned = (await pending)?.systemPrompt ?? "";
+ const names = Object.keys(sections).sort((a, b) => (b === UPSTREAM_SECTION) - (a === UPSTREAM_SECTION));
+ const primer = [...names.map((name) => `<${name}>\n${sections[name]}\n</${name}>`), returned].join("\n");
return [ESSENTIALS, primer.split("\n").filter((line) => !/\/chrome\b/.test(line)).join("\n")].join("\n");
}
const OTHER_BROWSER_TOOLS = process.env.PI_CHROME_OTHER_BROWSER_TOOLS?.trim();