bridge-agent 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1299,21 +1299,21 @@ var require_errors = __commonJS({
1299
1299
  function extendErrors({ gen, keyword, schemaValue, data, errsCount, it }) {
1300
1300
  if (errsCount === void 0)
1301
1301
  throw new Error("ajv implementation error");
1302
- const err4 = gen.name("err");
1302
+ const err5 = gen.name("err");
1303
1303
  gen.forRange("i", errsCount, names_1.default.errors, (i) => {
1304
- gen.const(err4, (0, codegen_1._)`${names_1.default.vErrors}[${i}]`);
1305
- gen.if((0, codegen_1._)`${err4}.instancePath === undefined`, () => gen.assign((0, codegen_1._)`${err4}.instancePath`, (0, codegen_1.strConcat)(names_1.default.instancePath, it.errorPath)));
1306
- gen.assign((0, codegen_1._)`${err4}.schemaPath`, (0, codegen_1.str)`${it.errSchemaPath}/${keyword}`);
1304
+ gen.const(err5, (0, codegen_1._)`${names_1.default.vErrors}[${i}]`);
1305
+ gen.if((0, codegen_1._)`${err5}.instancePath === undefined`, () => gen.assign((0, codegen_1._)`${err5}.instancePath`, (0, codegen_1.strConcat)(names_1.default.instancePath, it.errorPath)));
1306
+ gen.assign((0, codegen_1._)`${err5}.schemaPath`, (0, codegen_1.str)`${it.errSchemaPath}/${keyword}`);
1307
1307
  if (it.opts.verbose) {
1308
- gen.assign((0, codegen_1._)`${err4}.schema`, schemaValue);
1309
- gen.assign((0, codegen_1._)`${err4}.data`, data);
1308
+ gen.assign((0, codegen_1._)`${err5}.schema`, schemaValue);
1309
+ gen.assign((0, codegen_1._)`${err5}.data`, data);
1310
1310
  }
1311
1311
  });
1312
1312
  }
1313
1313
  exports2.extendErrors = extendErrors;
1314
1314
  function addError(gen, errObj) {
1315
- const err4 = gen.const("err", errObj);
1316
- gen.if((0, codegen_1._)`${names_1.default.vErrors} === null`, () => gen.assign(names_1.default.vErrors, (0, codegen_1._)`[${err4}]`), (0, codegen_1._)`${names_1.default.vErrors}.push(${err4})`);
1315
+ const err5 = gen.const("err", errObj);
1316
+ gen.if((0, codegen_1._)`${names_1.default.vErrors} === null`, () => gen.assign(names_1.default.vErrors, (0, codegen_1._)`[${err5}]`), (0, codegen_1._)`${names_1.default.vErrors}.push(${err5})`);
1317
1317
  gen.code((0, codegen_1._)`${names_1.default.errors}++`);
1318
1318
  }
1319
1319
  function returnErrors(it, errs) {
@@ -7541,8 +7541,8 @@ var ZodType = class {
7541
7541
  } : {
7542
7542
  issues: ctx.common.issues
7543
7543
  };
7544
- } catch (err4) {
7545
- if (err4?.message?.toLowerCase()?.includes("encountered")) {
7544
+ } catch (err5) {
7545
+ if (err5?.message?.toLowerCase()?.includes("encountered")) {
7546
7546
  this["~standard"].async = true;
7547
7547
  }
7548
7548
  ctx.common = {
@@ -21243,16 +21243,16 @@ var handleFetchError = (e) => new Response(null, {
21243
21243
  status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500
21244
21244
  });
21245
21245
  var handleResponseError = (e, outgoing) => {
21246
- const err4 = e instanceof Error ? e : new Error("unknown error", { cause: e });
21247
- if (err4.code === "ERR_STREAM_PREMATURE_CLOSE") {
21246
+ const err5 = e instanceof Error ? e : new Error("unknown error", { cause: e });
21247
+ if (err5.code === "ERR_STREAM_PREMATURE_CLOSE") {
21248
21248
  console.info("The user aborted a request.");
21249
21249
  } else {
21250
21250
  console.error(e);
21251
21251
  if (!outgoing.headersSent) {
21252
21252
  outgoing.writeHead(500, { "Content-Type": "text/plain" });
21253
21253
  }
21254
- outgoing.end(`Error: ${err4.message}`);
21255
- outgoing.destroy(err4);
21254
+ outgoing.end(`Error: ${err5.message}`);
21255
+ outgoing.destroy(err5);
21256
21256
  }
21257
21257
  };
21258
21258
  var flushHeaders = (outgoing) => {
@@ -21309,8 +21309,8 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
21309
21309
  if (options.errorHandler) {
21310
21310
  try {
21311
21311
  res = await res;
21312
- } catch (err4) {
21313
- const errRes = await options.errorHandler(err4);
21312
+ } catch (err5) {
21313
+ const errRes = await options.errorHandler(err5);
21314
21314
  if (!errRes) {
21315
21315
  return;
21316
21316
  }
@@ -22411,11 +22411,8 @@ async function getProjectEvents(ctx, opts) {
22411
22411
  if (opts?.limit) params.set("limit", String(opts.limit));
22412
22412
  if (opts?.includeArchived) params.set("includeArchived", "true");
22413
22413
  const qs = params.toString();
22414
- return request(
22415
- ctx,
22416
- "GET",
22417
- projectPath(ctx, `/events${qs ? "?" + qs : ""}`, opts?.projectId)
22418
- );
22414
+ const basePath = opts?.workspaceScope ? workspacePath(ctx, `/events${qs ? "?" + qs : ""}`) : projectPath(ctx, `/events${qs ? "?" + qs : ""}`, opts?.projectId);
22415
+ return request(ctx, "GET", basePath);
22419
22416
  }
22420
22417
  async function listPersonas(ctx, opts) {
22421
22418
  const params = new URLSearchParams();
@@ -22460,6 +22457,44 @@ async function applyPersona(ctx, params) {
22460
22457
  personaId: params.personaId
22461
22458
  });
22462
22459
  }
22460
+ async function listRolePrompts(ctx) {
22461
+ return request(ctx, "GET", workspacePath(ctx, "/prompts"));
22462
+ }
22463
+ async function getRolePrompt(ctx, role) {
22464
+ const start = Date.now();
22465
+ const res = await request(
22466
+ ctx,
22467
+ "GET",
22468
+ workspacePath(ctx, `/prompts/${encodeURIComponent(role)}`)
22469
+ );
22470
+ const latencyMs = Date.now() - start;
22471
+ const bytes = res.content.length;
22472
+ console.log("[mcp] mcp.bridge_get_role_prompt", { role, wsId: ctx.workspaceId, latency_ms: latencyMs, bytes });
22473
+ let content = res.content;
22474
+ if (content.includes("{{PANEL_ID}}")) {
22475
+ content = content.replaceAll("{{PANEL_ID}}", ctx.agentId ?? "unknown");
22476
+ console.log("[mcp] prompts.runtime_var.substituted", { role, var: "PANEL_ID", resolved: true });
22477
+ }
22478
+ if (content.includes("{{WORKSPACE_ID}}")) {
22479
+ content = content.replaceAll("{{WORKSPACE_ID}}", ctx.workspaceId);
22480
+ console.log("[mcp] prompts.runtime_var.substituted", { role, var: "WORKSPACE_ID", resolved: true });
22481
+ }
22482
+ if (content.includes("{{PROJECT_ID}}")) {
22483
+ content = content.replaceAll("{{PROJECT_ID}}", ctx.projectId);
22484
+ console.log("[mcp] prompts.runtime_var.substituted", { role, var: "PROJECT_ID", resolved: true });
22485
+ }
22486
+ if (content.includes("{{GROUP_ID}}")) {
22487
+ content = content.replaceAll("{{GROUP_ID}}", "none");
22488
+ console.log("[mcp] prompts.runtime_var.substituted", { role, var: "GROUP_ID", resolved: true });
22489
+ }
22490
+ return { ...res, content };
22491
+ }
22492
+ async function updateRolePrompt(ctx, role, content) {
22493
+ return request(ctx, "PUT", workspacePath(ctx, `/prompts/${encodeURIComponent(role)}`), { content });
22494
+ }
22495
+ async function deleteRolePrompt(ctx, role) {
22496
+ return request(ctx, "DELETE", workspacePath(ctx, `/prompts/${encodeURIComponent(role)}`));
22497
+ }
22463
22498
 
22464
22499
  // ../mcp-server/src/tools/plan.ts
22465
22500
  function registerPlanTools(server, ctx) {
@@ -22604,6 +22639,46 @@ var AGENT_ROLES = [
22604
22639
  var USER_ASSIGNABLE_ROLES = AGENT_ROLES.filter((r) => r !== "orchestrator");
22605
22640
  var EVENT_ROLES = [...AGENT_ROLES, "system"];
22606
22641
 
22642
+ // ../shared/dist/tool-registry.js
22643
+ var BRIDGE_TOOL_DOCS = {
22644
+ // Project / plan
22645
+ bridge_get_project: "Project metadata: name, cwd, machineId",
22646
+ bridge_get_plan: "Read project spec/description",
22647
+ bridge_update_plan: "Update project spec/description",
22648
+ bridge_get_project_history: "Past run history and failure patterns",
22649
+ bridge_get_execution_status: "Run history with todo completion counts",
22650
+ // Todos
22651
+ bridge_get_todos: "List todos + session state for this project",
22652
+ bridge_add_todo: "Create a new todo (title, todoType, dependsOn)",
22653
+ bridge_update_todo: "Update a todo title or status",
22654
+ bridge_cancel_run: "Cancel active run (use before restarting a stale plan)",
22655
+ // Panel management
22656
+ bridge_list_agents: "All agents: role, status, inRun flag",
22657
+ bridge_get_agent_status: "Single agent status check",
22658
+ bridge_spawn_worker: "Spawn a new worker agent (agentKey, role)",
22659
+ bridge_kill_agent: "Terminate a stuck or dead agent",
22660
+ bridge_get_agent_output: "Read terminal output of any agent",
22661
+ bridge_send_input: "Send text input to an agent PTY",
22662
+ // Worker task lifecycle
22663
+ bridge_get_my_task: "Get the task assigned to this agent",
22664
+ bridge_complete_task: "Signal task completion",
22665
+ bridge_fail_task: "Signal task failure with a specific reason",
22666
+ bridge_get_todo_context: "Read todo output/error for a specific todo",
22667
+ bridge_assign_task: "Assign a pending todo to a specific agent",
22668
+ // Workspace scope (Phase 6)
22669
+ bridge_list_groups: "List all agent groups and their member agentIds",
22670
+ bridge_get_group_status: "Get agents in a group with status and last output line",
22671
+ bridge_dispatch_to_group: "Send a text message/command to every agent in a group",
22672
+ bridge_list_workspace_projects: "List all workspace projects with name, cwd, active run count",
22673
+ bridge_query_workspace: "Natural-language query about orchestration state",
22674
+ bridge_list_active_runs: "All active orchestration runs across workspace projects",
22675
+ bridge_peek_panel: "Read terminal output of any panel workspace-wide (no project boundary)",
22676
+ bridge_status_panel: "Get status of any panel in the workspace regardless of project"
22677
+ };
22678
+ if (Object.keys(BRIDGE_TOOL_DOCS).length === 0) {
22679
+ throw new Error("BRIDGE_TOOL_DOCS registry is empty at module load \u2014 fail fast");
22680
+ }
22681
+
22607
22682
  // ../mcp-server/src/tools/orchestration.ts
22608
22683
  function ok(data) {
22609
22684
  return { content: [{ type: "text", text: JSON.stringify(data) }] };
@@ -22742,9 +22817,10 @@ function registerOrchestrationTools(server, ctx) {
22742
22817
  );
22743
22818
  server.tool(
22744
22819
  "bridge_get_project_events",
22745
- "Query the project event log. Returns events newest-first. Use to recall decisions, discoveries, and blockers recorded by prior agents before starting new work. Filter by role or eventType to narrow results; use search for keyword lookup in summaries. Pass projectId to query a specific project (orchestrator must always pass it; per-project workers can omit).",
22820
+ "Query the project event log. Returns events newest-first. Use to recall decisions, discoveries, and blockers recorded by prior agents before starting new work. Filter by role or eventType to narrow results; use search for keyword lookup in summaries. Pass projectId to query a specific project (orchestrator must always pass it; per-project workers can omit). Set workspaceScope:true to get a cross-project timeline \u2014 all events across every project in the workspace.",
22746
22821
  {
22747
- projectId: external_exports.string().min(1).optional().describe("Target project ID. Defaults to caller panel's project. Required when called from the orchestrator (workspace scope)."),
22822
+ projectId: external_exports.string().min(1).optional().describe("Target project ID. Defaults to caller panel's project. Required when called from the orchestrator (workspace scope). Ignored when workspaceScope is true."),
22823
+ workspaceScope: external_exports.boolean().optional().describe("When true, returns all events across the entire workspace (all projects + workspace-level events). Useful for orchestrators managing multiple projects."),
22748
22824
  role: external_exports.string().optional().describe("Filter by role (e.g. reviewer, developer)"),
22749
22825
  eventType: external_exports.string().optional().describe("Filter by eventType slug"),
22750
22826
  tags: external_exports.string().optional().describe('Comma-separated tag list \u2014 only events containing ALL listed tags (e.g. "auth,security")'),
@@ -22983,6 +23059,60 @@ function registerPersonaTools(server, ctx) {
22983
23059
  );
22984
23060
  }
22985
23061
 
23062
+ // ../mcp-server/src/tools/role-prompts.ts
23063
+ function ok4(data) {
23064
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
23065
+ }
23066
+ function err4(message) {
23067
+ return { content: [{ type: "text", text: JSON.stringify({ ok: false, error: message }) }] };
23068
+ }
23069
+ async function safe4(fn) {
23070
+ try {
23071
+ return ok4(await fn());
23072
+ } catch (e) {
23073
+ const message = e instanceof Error ? e.message : String(e);
23074
+ if (e instanceof Error && (e.name === "TypeError" || e.name === "ReferenceError")) {
23075
+ console.error("[mcp-bridge] unexpected error in role-prompt tool handler", { name: e.name, message, stack: e.stack });
23076
+ }
23077
+ return err4(message);
23078
+ }
23079
+ }
23080
+ var ROLE_PROMPT_KEYS = AGENT_ROLES;
23081
+ var ListRolePromptsSchema = external_exports.object({});
23082
+ var GetRolePromptSchema = external_exports.object({
23083
+ role: external_exports.enum(ROLE_PROMPT_KEYS).describe("Role name: developer, reviewer, planner, executor, shell, runner, or orchestrator")
23084
+ });
23085
+ var UpdateRolePromptSchema = external_exports.object({
23086
+ role: external_exports.enum(ROLE_PROMPT_KEYS).describe("Role name to update"),
23087
+ content: external_exports.string().min(1).describe("New system prompt content")
23088
+ });
23089
+ function registerRolePromptTools(server, ctx) {
23090
+ server.tool(
23091
+ "bridge_list_role_prompts",
23092
+ "List all role prompts for the current workspace. Returns 7 entries (developer, reviewer, planner, executor, shell, runner, orchestrator) with merged workspace overrides or global defaults.",
23093
+ ListRolePromptsSchema.shape,
23094
+ () => safe4(() => listRolePrompts(ctx))
23095
+ );
23096
+ server.tool(
23097
+ "bridge_get_role_prompt",
23098
+ "Fetch the system prompt for a specific role. You MUST call this tool as your first action after spawn. Falls back to global default if no workspace override exists.",
23099
+ GetRolePromptSchema.shape,
23100
+ (params) => safe4(() => getRolePrompt(ctx, params.role))
23101
+ );
23102
+ server.tool(
23103
+ "bridge_update_role_prompt",
23104
+ "Update the workspace-specific system prompt for a role. Creates a workspace override; does not mutate the global default.",
23105
+ UpdateRolePromptSchema.shape,
23106
+ (params) => safe4(() => updateRolePrompt(ctx, params.role, params.content))
23107
+ );
23108
+ server.tool(
23109
+ "bridge_delete_role_prompt",
23110
+ "Revert a workspace role prompt to the global default. Removes the workspace-specific row; subsequent fetches return the system default content.",
23111
+ GetRolePromptSchema.shape,
23112
+ (params) => safe4(() => deleteRolePrompt(ctx, params.role))
23113
+ );
23114
+ }
23115
+
22986
23116
  // ../mcp-server/src/index.ts
22987
23117
  var sessions = /* @__PURE__ */ new Map();
22988
23118
  function buildMcpServer(ctx) {
@@ -22993,6 +23123,7 @@ function buildMcpServer(ctx) {
22993
23123
  registerMessagingTools(srv, ctx);
22994
23124
  registerWorkspaceTools(srv, ctx);
22995
23125
  registerPersonaTools(srv, ctx);
23126
+ registerRolePromptTools(srv, ctx);
22996
23127
  return srv;
22997
23128
  }
22998
23129
  async function parseBody(req) {
@@ -23097,8 +23228,8 @@ function startHttpServer() {
23097
23228
  const mcpServer = buildMcpServer(ctx);
23098
23229
  await mcpServer.connect(transport);
23099
23230
  await transport.handleRequest(req, res, body);
23100
- } catch (err4) {
23101
- console.error("[bridge-mcp] request error:", err4);
23231
+ } catch (err5) {
23232
+ console.error("[bridge-mcp] request error:", err5);
23102
23233
  if (!res.headersSent) {
23103
23234
  res.writeHead(500, { "Content-Type": "application/json" });
23104
23235
  res.end(JSON.stringify({ error: "Internal server error" }));
@@ -23133,8 +23264,8 @@ async function startStdioServer() {
23133
23264
  if (process.env["HTTP_MODE"] !== "false") {
23134
23265
  startHttpServer();
23135
23266
  } else {
23136
- startStdioServer().catch((err4) => {
23137
- console.error("[bridge-mcp] fatal:", err4);
23267
+ startStdioServer().catch((err5) => {
23268
+ console.error("[bridge-mcp] fatal:", err5);
23138
23269
  process.exit(1);
23139
23270
  });
23140
23271
  }