@clawos-dev/clawd 0.2.231 → 0.2.232

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +34 -70
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -5556,11 +5556,12 @@ var init_schemas = __esm({
5556
5556
  });
5557
5557
 
5558
5558
  // ../protocol/src/frames.ts
5559
- var PROTOCOL_VERSION;
5559
+ var PROTOCOL_VERSION, DISPATCH_MCP_ID;
5560
5560
  var init_frames = __esm({
5561
5561
  "../protocol/src/frames.ts"() {
5562
5562
  "use strict";
5563
5563
  PROTOCOL_VERSION = 1;
5564
+ DISPATCH_MCP_ID = "dispatch";
5564
5565
  }
5565
5566
  });
5566
5567
 
@@ -12148,17 +12149,8 @@ function buildSpawnArgs(ctx) {
12148
12149
  if (ctx.addDirs) {
12149
12150
  for (const dir of ctx.addDirs) args.push("--add-dir", dir);
12150
12151
  }
12151
- if (ctx.dispatchMcpConfigPath) {
12152
- args.push("--mcp-config", ctx.dispatchMcpConfigPath);
12153
- }
12154
- if (ctx.ticketMcpConfigPath) {
12155
- args.push("--mcp-config", ctx.ticketMcpConfigPath);
12156
- }
12157
- if (ctx.shiftMcpConfigPath) {
12158
- args.push("--mcp-config", ctx.shiftMcpConfigPath);
12159
- }
12160
- if (ctx.inboxMcpConfigPath) {
12161
- args.push("--mcp-config", ctx.inboxMcpConfigPath);
12152
+ for (const mcp of ctx.mcpConfigs ?? []) {
12153
+ args.push("--mcp-config", mcp.path);
12162
12154
  }
12163
12155
  args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
12164
12156
  if (ctx.effort) args.push("--effort", ctx.effort);
@@ -41818,6 +41810,7 @@ var import_node_os4 = __toESM(require("os"), 1);
41818
41810
  var import_node_path7 = __toESM(require("path"), 1);
41819
41811
 
41820
41812
  // src/session/reducer.ts
41813
+ init_protocol();
41821
41814
  init_runtime();
41822
41815
 
41823
41816
  // src/permission/rules.ts
@@ -42045,10 +42038,7 @@ function buildSpawnContext(state, deps) {
42045
42038
  if (dispatchId) env.CLAWD_DISPATCH_ID = dispatchId;
42046
42039
  const personaId = file.ownerPersonaId;
42047
42040
  if (personaId) env.CLAWD_PERSONA_ID = personaId;
42048
- const dispatchMcpConfigPath2 = deps.getDispatchMcpConfigPath?.() ?? null;
42049
- const ticketMcpConfigPath2 = deps.getTicketMcpConfigPath?.() ?? null;
42050
- const shiftMcpConfigPath2 = deps.getShiftMcpConfigPath?.() ?? null;
42051
- const inboxMcpConfigPath2 = deps.getInboxMcpConfigPath?.() ?? null;
42041
+ const mcpConfigs = deps.getMcpConfigs?.() ?? [];
42052
42042
  const ctx = {
42053
42043
  cwd: file.cwd,
42054
42044
  toolSessionId: file.toolSessionId,
@@ -42059,12 +42049,7 @@ function buildSpawnContext(state, deps) {
42059
42049
  // Phase 2 capability platform (plan §3): personaRoot 透传给 buildSpawnArgs;
42060
42050
  // 内部 shouldSandbox(cwd, personaRoot) 决定是否注入 --settings sandbox-settings.
42061
42051
  personaRoot: deps.personaRoot,
42062
- // Persona dispatch:所有 session(A B)都挂同一份 dispatch.mcp.json,让两边的 cc
42063
- // 都能看到 personaDispatch / personaDispatchComplete tool;按 env 区分实际行为。
42064
- dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0,
42065
- ticketMcpConfigPath: ticketMcpConfigPath2 ?? void 0,
42066
- shiftMcpConfigPath: shiftMcpConfigPath2 ?? void 0,
42067
- inboxMcpConfigPath: inboxMcpConfigPath2 ?? void 0,
42052
+ ...mcpConfigs.length > 0 ? { mcpConfigs } : {},
42068
42053
  // shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
42069
42054
  // 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
42070
42055
  personaId
@@ -42092,7 +42077,7 @@ function buildSpawnContext(state, deps) {
42092
42077
  }
42093
42078
  ctx.extraSystemPrompt = buildConnectionPrompt(promptArgs);
42094
42079
  }
42095
- if (dispatchMcpConfigPath2) {
42080
+ if (mcpConfigs.some((c) => c.id === DISPATCH_MCP_ID)) {
42096
42081
  ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + DISPATCH_SYSTEM_PROMPT_HINT;
42097
42082
  }
42098
42083
  if (daemonUrl) {
@@ -42875,13 +42860,9 @@ var SessionRunner = class {
42875
42860
  // 单栏 refactor (spec 2026-06-02 §5.1): cc 子进程 env 注入 CLAWD_DAEMON_URL,让 assistant
42876
42861
  // curl daemon HTTP RPC adapter (/api/rpc/<method>) 触发管理操作。null = HTTP adapter 未启。
42877
42862
  getDaemonUrl: this.hooks.getDaemonUrl,
42878
- // Persona dispatch:透传 dispatch.mcp.json 路径闭包 + B→dispatchId 反查闭包。
42879
- // 见 reducer.buildSpawnContext CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
42880
- getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
42881
- getShiftMcpConfigPath: this.hooks.getShiftMcpConfigPath,
42882
- getInboxMcpConfigPath: this.hooks.getInboxMcpConfigPath,
42883
- // Ticket MCP:透传 ticket.mcp.json 路径闭包(所有 persona session 都挂,无 gating)
42884
- getTicketMcpConfigPath: this.hooks.getTicketMcpConfigPath,
42863
+ // daemon MCP server 列表闭包透传;见 reducer.buildSpawnContext 派生
42864
+ // SpawnContext.mcpConfigs + DISPATCH_MCP_ID 判断 dispatch 教学注入
42865
+ getMcpConfigs: this.hooks.getMcpConfigs,
42885
42866
  lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
42886
42867
  // ReadyGate v2:透传 mode 让 reducer send / ready-detected 分支决定走暂存队列还是直写
42887
42868
  mode: this.hooks.mode,
@@ -43711,12 +43692,9 @@ var SessionManager = class {
43711
43692
  // 单栏 refactor (spec 2026-06-02 §5.1): 透传 daemon HTTP RPC base URL 闭包,
43712
43693
  // reducer 把它注入 cc 子进程 env CLAWD_DAEMON_URL.
43713
43694
  getDaemonUrl: this.deps.getDaemonUrl,
43714
- // Persona dispatch (Task 7): dispatch.mcp.json 路径 + B sessionId → dispatchId 反查
43715
- // 闭包透传给 reducer,让 cc spawn 加 --mcp-config flag + B session CLAWD_DISPATCH_ID env.
43716
- getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
43717
- getTicketMcpConfigPath: this.deps.ticketMcpConfigPath ? () => this.deps.ticketMcpConfigPath ?? null : void 0,
43718
- getShiftMcpConfigPath: this.deps.shiftMcpConfigPath ? () => this.deps.shiftMcpConfigPath ?? null : void 0,
43719
- getInboxMcpConfigPath: this.deps.inboxMcpConfigPath ? () => this.deps.inboxMcpConfigPath ?? null : void 0,
43695
+ // daemon MCP server 列表闭包透传给 reducer,cc spawn 逐项加 --mcp-config flag;
43696
+ // B session CLAWD_DISPATCH_ID env 由下方 lookupDispatchByBSessionId 反查闭包负责。
43697
+ getMcpConfigs: () => this.deps.mcpConfigs ?? [],
43720
43698
  lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
43721
43699
  // file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
43722
43700
  onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
@@ -48169,17 +48147,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
48169
48147
  if (ctx.addDirs) {
48170
48148
  for (const dir of ctx.addDirs) args.push("--add-dir", dir);
48171
48149
  }
48172
- if (ctx.dispatchMcpConfigPath) {
48173
- args.push("--mcp-config", ctx.dispatchMcpConfigPath);
48174
- }
48175
- if (ctx.ticketMcpConfigPath) {
48176
- args.push("--mcp-config", ctx.ticketMcpConfigPath);
48177
- }
48178
- if (ctx.shiftMcpConfigPath) {
48179
- args.push("--mcp-config", ctx.shiftMcpConfigPath);
48180
- }
48181
- if (ctx.inboxMcpConfigPath) {
48182
- args.push("--mcp-config", ctx.inboxMcpConfigPath);
48150
+ for (const mcp of ctx.mcpConfigs ?? []) {
48151
+ args.push("--mcp-config", mcp.path);
48183
48152
  }
48184
48153
  args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
48185
48154
  if (ctx.effort) args.push("--effort", ctx.effort);
@@ -59689,6 +59658,7 @@ async function startDaemon(config) {
59689
59658
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
59690
59659
  const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
59691
59660
  const here = typeof __dirname === "string" ? __dirname : import_node_path64.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
59661
+ const mcpConfigs = [];
59692
59662
  const dispatchServerCandidates = [
59693
59663
  import_node_path64.default.join(here, "dispatch", "mcp-server.cjs"),
59694
59664
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
@@ -59696,16 +59666,16 @@ async function startDaemon(config) {
59696
59666
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
59697
59667
  ];
59698
59668
  const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
59699
- let dispatchMcpConfigPath2;
59700
59669
  if (dispatchServerScriptPath) {
59701
59670
  const dispatchLogPath = import_node_path64.default.join(logDir, "dispatch-mcp-server.log");
59702
- dispatchMcpConfigPath2 = writeDispatchMcpConfig({
59671
+ const dispatchCfgPath = writeDispatchMcpConfig({
59703
59672
  dataDir: config.dataDir,
59704
59673
  serverScriptPath: dispatchServerScriptPath,
59705
59674
  logPath: dispatchLogPath
59706
59675
  });
59676
+ mcpConfigs.push({ id: DISPATCH_MCP_ID, path: dispatchCfgPath });
59707
59677
  logger.info("dispatch.mcp.json written", {
59708
- path: dispatchMcpConfigPath2,
59678
+ path: dispatchCfgPath,
59709
59679
  server: dispatchServerScriptPath,
59710
59680
  serverLog: dispatchLogPath
59711
59681
  });
@@ -59719,18 +59689,18 @@ async function startDaemon(config) {
59719
59689
  import_node_path64.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
59720
59690
  ];
59721
59691
  const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
59722
- let ticketMcpConfigPath2;
59723
59692
  if (ticketServerScriptPath) {
59724
59693
  const ticketLogPath = import_node_path64.default.join(logDir, "ticket-mcp-server.log");
59725
- ticketMcpConfigPath2 = writeTicketMcpConfig({
59694
+ const ticketCfgPath = writeTicketMcpConfig({
59726
59695
  dataDir: config.dataDir,
59727
59696
  serverScriptPath: ticketServerScriptPath,
59728
59697
  apiBaseUrl: config.clawosApi ?? DEFAULT_CLAWOS_API,
59729
59698
  apiKey: resolveClawdTicketsApiKey(),
59730
59699
  logPath: ticketLogPath
59731
59700
  });
59701
+ mcpConfigs.push({ id: "ticket", path: ticketCfgPath });
59732
59702
  logger.info("ticket.mcp.json written", {
59733
- path: ticketMcpConfigPath2,
59703
+ path: ticketCfgPath,
59734
59704
  server: ticketServerScriptPath,
59735
59705
  serverLog: ticketLogPath
59736
59706
  });
@@ -59744,16 +59714,16 @@ async function startDaemon(config) {
59744
59714
  import_node_path64.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
59745
59715
  ];
59746
59716
  const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
59747
- let shiftMcpConfigPath2;
59748
59717
  if (shiftServerScriptPath) {
59749
59718
  const shiftLogPath = import_node_path64.default.join(logDir, "shift-mcp-server.log");
59750
- shiftMcpConfigPath2 = await writeShiftMcpConfig({
59719
+ const shiftCfgPath = await writeShiftMcpConfig({
59751
59720
  dataDir: config.dataDir,
59752
59721
  serverScriptPath: shiftServerScriptPath,
59753
59722
  logPath: shiftLogPath
59754
59723
  });
59724
+ mcpConfigs.push({ id: "shift", path: shiftCfgPath });
59755
59725
  logger.info("shift.mcp.json written", {
59756
- path: shiftMcpConfigPath2,
59726
+ path: shiftCfgPath,
59757
59727
  server: shiftServerScriptPath,
59758
59728
  serverLog: shiftLogPath
59759
59729
  });
@@ -59768,16 +59738,16 @@ async function startDaemon(config) {
59768
59738
  import_node_path64.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
59769
59739
  ];
59770
59740
  const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
59771
- let inboxMcpConfigPath2;
59772
59741
  if (inboxServerScriptPath) {
59773
59742
  const inboxLogPath = import_node_path64.default.join(logDir, "inbox-mcp-server.log");
59774
- inboxMcpConfigPath2 = await writeInboxMcpConfig({
59743
+ const inboxCfgPath = await writeInboxMcpConfig({
59775
59744
  dataDir: config.dataDir,
59776
59745
  serverScriptPath: inboxServerScriptPath,
59777
59746
  logPath: inboxLogPath
59778
59747
  });
59748
+ mcpConfigs.push({ id: "inbox", path: inboxCfgPath });
59779
59749
  logger.info("inbox.mcp.json written", {
59780
- path: inboxMcpConfigPath2,
59750
+ path: inboxCfgPath,
59781
59751
  server: inboxServerScriptPath,
59782
59752
  serverLog: inboxLogPath
59783
59753
  });
@@ -59823,18 +59793,12 @@ async function startDaemon(config) {
59823
59793
  // 127.0.0.1(不是 config.host)—— cc 跑在本机,loopback 最稳;外部访问限制 + http-router
59824
59794
  // 的 isLoopback 兜底已确保安全。
59825
59795
  getDaemonUrl: () => `http://127.0.0.1:${config.port}`,
59826
- // Persona dispatch (Task 8): manager 通过这两个 deps 跟 PersonaDispatchManager 协作。
59827
- // - personaDispatchManager: manager.createDispatchedSession 用它 registerBSession;
59828
- // reducer 通过闭包反查 dispatchId 注 CLAWD_DISPATCH_ID env。
59829
- // - dispatchMcpConfigPath: reducer 透传到 SpawnContext,cc spawn 加 --mcp-config flag。
59796
+ // Persona dispatch (Task 8): manager.createDispatchedSession personaDispatchManager
59797
+ // registerBSession;reducer 通过闭包反查 dispatchId CLAWD_DISPATCH_ID env。
59830
59798
  personaDispatchManager,
59831
- dispatchMcpConfigPath: dispatchMcpConfigPath2,
59832
- ticketMcpConfigPath: ticketMcpConfigPath2,
59833
- // shift v1:所有 persona session 都挂 shift.mcp.json(不做 persona gating)。
59834
- // 缺省 = shift-mcp-server.cjs 没 build 出来,cc 看不到 shift tool 但 scheduler 仍跑。
59835
- shiftMcpConfigPath: shiftMcpConfigPath2,
59836
- // sendDm MCP tool:所有 persona session 都挂 inbox.mcp.json(无 gating)。
59837
- inboxMcpConfigPath: inboxMcpConfigPath2,
59799
+ // daemon 级 MCP server 登记表(dispatch / ticket / shift / inbox / ...,上方各 writer
59800
+ // 块写盘成功即登记);reducer 透传到 SpawnContext.mcpConfigs,cc spawn 逐项 --mcp-config。
59801
+ mcpConfigs,
59838
59802
  broadcastFrame: (frame, target) => {
59839
59803
  if (target === "all") {
59840
59804
  transport?.broadcastAll(frame);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.231",
3
+ "version": "0.2.232",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",