@caelo-cms/mcp-server 0.11.5 → 0.11.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"admin-server.d.ts","sourceRoot":"","sources":["../src/admin-server.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAI/E,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,6BAA6B,CAAC;AAGrC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAID,6EAA6E;AAC7E,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,GAAE,MAAM,GAAG,SAAsD,GACnE,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAMvE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAwH7E"}
1
+ {"version":3,"file":"admin-server.d.ts","sourceRoot":"","sources":["../src/admin-server.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAI/E,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,6BAA6B,CAAC;AAIrC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAID,6EAA6E;AAC7E,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,GAAE,MAAM,GAAG,SAAsD,GACnE,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAMvE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgI7E"}
@@ -21,16 +21,20 @@
21
21
  * unknown tool name refreshes too. Never on a timer: every request wakes
22
22
  * the admin's Cloud Run instance, and an idle session left open overnight
23
23
  * kept it running around the clock;
24
- * - the work session `caelo_open_session` opened is held in process state
25
- * so the agent doesn't thread it through every call; it also rides the
26
- * response so a restarted server can resume a specific session via
27
- * `chatSessionId`.
24
+ * - the work session `caelo_open_session` opened last is held in process
25
+ * state so a single agent doesn't thread it through every call; it also
26
+ * rides the response so a restarted server can resume a specific session
27
+ * via `chatSessionId`. Agents sharing this process (sub-agents) each pass
28
+ * their own as `workSessionId` (#1253);
29
+ * - every call carries an idempotency key made of this process's id and the
30
+ * call's JSON-RPC id, so a repeated request returns the first result.
28
31
  */
29
32
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
30
33
  import { resolveApprovalWaitMs } from "./approval-wait.js";
31
34
  import { postAdmin, resolveTimeoutMs } from "./http.js";
32
35
  import { uploadImages } from "./image-upload.js";
33
- import { createAdminMcpServer, } from "./surfaces/admin-surface.js";
36
+ import { createAdminMcpServer, NoWorkSessionError, } from "./surfaces/admin-surface.js";
37
+ import { rpcToolCallId } from "./surfaces/rpc-tool-call-id.js";
34
38
  import { ownVersion } from "./version-handshake.js";
35
39
  const DEFAULT_CATALOGUE_MAX_AGE_MS = 5 * 60_000;
36
40
  /** The catalogue's max age: the option, else the env var, else 5 minutes. */
@@ -65,6 +69,8 @@ export async function startAdminMcpServer(opts) {
65
69
  let signature = catalogueSignature(catalogue.tools);
66
70
  const maxAgeMs = resolveCatalogueMaxAgeMs(opts.catalogueMaxAgeMs);
67
71
  let currentSession = null;
72
+ /** Unique per process: JSON-RPC ids repeat across processes, never within one. */
73
+ const processKey = crypto.randomUUID();
68
74
  let connected = false;
69
75
  let refreshing = null;
70
76
  // #678 — the catalogue is the ADMIN's: an upgrade or an activated plugin
@@ -97,13 +103,21 @@ export async function startAdminMcpServer(opts) {
97
103
  });
98
104
  return currentSession;
99
105
  },
100
- currentSessionId: async () => currentSession?.chatSessionId ?? null,
101
- executeTool: (call) => postAdmin({
102
- ...target,
103
- path: "/api/mcp/tool",
104
- body: call,
105
- timeoutMs: resolveTimeoutMs(120_000),
106
- }),
106
+ executeTool: async ({ rpcRequestId, chatSessionId, ...call }) => {
107
+ const session = chatSessionId ?? currentSession?.chatSessionId;
108
+ if (!session)
109
+ throw new NoWorkSessionError();
110
+ return postAdmin({
111
+ ...target,
112
+ path: "/api/mcp/tool",
113
+ body: {
114
+ ...call,
115
+ chatSessionId: session,
116
+ toolCallId: rpcToolCallId(`stdio:${processKey}`, rpcRequestId),
117
+ },
118
+ timeoutMs: resolveTimeoutMs(120_000),
119
+ });
120
+ },
107
121
  getContext: () => postAdmin({
108
122
  ...target,
109
123
  path: "/api/mcp/context",
@@ -1 +1 @@
1
- {"version":3,"file":"admin-server.js","sourceRoot":"","sources":["../src/admin-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-server.js","sourceRoot":"","sources":["../src/admin-server.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAwB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,oBAAoB,EAGpB,kBAAkB,GAGnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAmBpD,MAAM,4BAA4B,GAAG,CAAC,GAAG,MAAM,CAAC;AAEhD,6EAA6E;AAC7E,MAAM,UAAU,wBAAwB,CACtC,MAA0B,EAC1B,MAA0B,OAAO,CAAC,GAAG,CAAC,8BAA8B;IAEpE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,CAAC,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA4B;IAC7D,OAAO,IAAI,CAAC,SAAS,CACnB,CAAC,GAAG,KAAK,CAAC;SACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAoB;IAC5D,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAC9D,MAAM,cAAc,GAAG,GAAG,EAAE,CAC1B,SAAS,CAA0B;QACjC,GAAG,MAAM;QACT,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,EAAE;QACR,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACL,uEAAuE;IACvE,6DAA6D;IAC7D,IAAI,SAAS,GAAG,MAAM,cAAc,EAAE,CAAC;IACvC,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,IAAI,YAAY,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAElE,IAAI,cAAc,GAA+B,IAAI,CAAC;IACtD,kFAAkF;IAClF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACvC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAAU,GAA4B,IAAI,CAAC;IAE/C,yEAAyE;IACzE,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,MAAM,GAAG,oBAAoB,CACjC;QACE,aAAa,EAAE,KAAK,IAAI,EAAE;YACxB,iEAAiE;YACjE,IAAI,OAAO,EAAE;gBAAE,MAAM,gBAAgB,EAAE,CAAC;YACxC,OAAO,SAAS,CAAC,KAAK,CAAC;QACzB,CAAC;QACD,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,kEAAkE;gBAClE,MAAM,gBAAgB,EAAE,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,0BAA0B,EAAE,CAAC;YAC/B,CAAC;YACD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QACD,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC3B,0BAA0B,EAAE,CAAC;YAC7B,cAAc,GAAG,MAAM,SAAS,CAAsB;gBACpD,GAAG,MAAM;gBACT,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;YACH,OAAO,cAAc,CAAC;QACxB,CAAC;QACD,WAAW,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE;YAC9D,MAAM,OAAO,GAAG,aAAa,IAAI,cAAc,EAAE,aAAa,CAAC;YAC/D,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;YAC7C,OAAO,SAAS,CAAsB;gBACpC,GAAG,MAAM;gBACT,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE;oBACJ,GAAG,IAAI;oBACP,aAAa,EAAE,OAAO;oBACtB,UAAU,EAAE,aAAa,CAAC,SAAS,UAAU,EAAE,EAAE,YAAY,CAAC;iBAC/D;gBACD,SAAS,EAAE,gBAAgB,CAAC,OAAO,CAAC;aACrC,CAAC,CAAC;QACL,CAAC;QACD,UAAU,EAAE,GAAG,EAAE,CACf,SAAS,CAAqB;YAC5B,GAAG,MAAM;YACT,IAAI,EAAE,kBAAkB;YACxB,IAAI,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE;YACnC,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC;SACpC,CAAC;QACJ,oBAAoB,EAAE,CAAC,UAAU,EAAE,EAAE,CACnC,SAAS,CAAkB;YACzB,GAAG,MAAM;YACT,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,UAAU,EAAE;YACpB,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC;SACpC,CAAC;QACJ,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;QAClD,mEAAmE;QACnE,4DAA4D;QAC5D,uBAAuB,EAAE,KAAK,IAAI,EAAE;YAClC,MAAM,gBAAgB,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;KACF,EACD;QACE,aAAa,EAAE,UAAU,EAAE;QAC3B,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,IAAI;QACjB,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtF,CACF,CAAC;IAEF,sFAAsF;IACtF,MAAM,gBAAgB,GAAG,GAAqB,EAAE;QAC9C,UAAU,KAAK,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;YACpC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrD,IAAI,aAAa,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC9C,SAAS,GAAG,IAAI,CAAC;YACjB,YAAY,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,SAAS,GAAG,aAAa,CAAC;YAC1B,IAAI,SAAS;gBAAE,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,GAAY,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,QAAQ,CAAC;IAClE,+EAA+E;IAC/E,MAAM,0BAA0B,GAAG,GAAS,EAAE;QAC5C,IAAI,CAAC,OAAO,EAAE;YAAE,OAAO;QACvB,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;YACtC,oEAAoE;YACpE,6DAA6D;YAC7D,OAAO,CAAC,KAAK,CACX,oDAAoD,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACjG,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACnE,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC"}
@@ -7,9 +7,16 @@
7
7
  * The stdio shim (../admin-server.ts) backs it with HTTP calls to
8
8
  * `/api/mcp/*`, caching the catalogue and holding the work session in
9
9
  * process memory. The admin's remote endpoint `/api/mcp/remote/admin`
10
- * (issue #806) backs it with the `mcp.*` ops in-process; its transport is
11
- * stateless, so the work session lives on the connection's row instead.
12
- * Both show an agent the same tools and the same results.
10
+ * (issue #806) backs it with the Power-MCP steps in-process; its transport
11
+ * is stateless, so the work session is bound to the MCP transport session
12
+ * (`Mcp-Session-Id`) in the database instead. Both show an agent the same
13
+ * tools and the same results.
14
+ *
15
+ * Issue #1253 — one work session per agent. Several agents may share one
16
+ * connection (a client's sub-agents), and a connection has one current
17
+ * session at most, so every catalogue tool takes an optional
18
+ * `workSessionId`: the session that call runs in. It is added to the
19
+ * schemas here and taken off the arguments before the call reaches Caelo.
13
20
  */
14
21
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
15
22
  import { type CallToolResult } from "@modelcontextprotocol/sdk/types.js";
@@ -64,14 +71,21 @@ export interface AdminSurfaceBackend {
64
71
  listCatalogue(): Promise<readonly RemoteTool[]>;
65
72
  /** One catalogue tool by name; the shim refreshes its cache on a miss (#678). */
66
73
  findTool(name: string): Promise<RemoteTool | undefined>;
67
- /** Open / resume the work session and remember it as current. */
74
+ /** Open a new work session (or resume a named one) and remember it as current. */
68
75
  openSession(input: OpenSessionInput): Promise<OpenSessionResponse>;
69
- /** The current work session, or null before caelo_open_session. */
70
- currentSessionId(): Promise<string | null>;
76
+ /**
77
+ * Run one catalogue tool. `chatSessionId` is the call's own
78
+ * `workSessionId`; without it the backend uses its current session and
79
+ * throws {@link NoWorkSessionError} when it has none. `rpcRequestId` is
80
+ * the JSON-RPC id of the `tools/call`, from which the backend derives an
81
+ * idempotency key unique to its transport (a retried request with the
82
+ * same id gets the first result).
83
+ */
71
84
  executeTool(call: {
72
85
  toolName: string;
73
86
  args: Record<string, unknown>;
74
- chatSessionId: string;
87
+ chatSessionId?: string;
88
+ rpcRequestId: string | number;
75
89
  }): Promise<ExecuteToolResponse>;
76
90
  getContext(): Promise<GetContextResponse>;
77
91
  /** Reads the operator's decision; the agent can never make it. */
@@ -110,6 +124,11 @@ export interface AdminSurfaceOptions {
110
124
  */
111
125
  readonly listChanged: boolean;
112
126
  }
127
+ /** Thrown by a backend asked to run a call with no work session to run it in. */
128
+ export declare class NoWorkSessionError extends Error {
129
+ readonly name = "NoWorkSessionError";
130
+ constructor();
131
+ }
113
132
  /** Build the Power-MCP server over `backend`. The caller connects a transport. */
114
133
  export declare function createAdminMcpServer(backend: AdminSurfaceBackend, opts: AdminSurfaceOptions): Server;
115
134
  //# sourceMappingURL=admin-surface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-surface.d.ts","sourceRoot":"","sources":["../../src/surfaces/admin-surface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-surface.d.ts","sourceRoot":"","sources":["../../src/surfaces/admin-surface.ts"],"names":[],"mappings":"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"}
@@ -8,14 +8,21 @@
8
8
  * The stdio shim (../admin-server.ts) backs it with HTTP calls to
9
9
  * `/api/mcp/*`, caching the catalogue and holding the work session in
10
10
  * process memory. The admin's remote endpoint `/api/mcp/remote/admin`
11
- * (issue #806) backs it with the `mcp.*` ops in-process; its transport is
12
- * stateless, so the work session lives on the connection's row instead.
13
- * Both show an agent the same tools and the same results.
11
+ * (issue #806) backs it with the Power-MCP steps in-process; its transport
12
+ * is stateless, so the work session is bound to the MCP transport session
13
+ * (`Mcp-Session-Id`) in the database instead. Both show an agent the same
14
+ * tools and the same results.
15
+ *
16
+ * Issue #1253 — one work session per agent. Several agents may share one
17
+ * connection (a client's sub-agents), and a connection has one current
18
+ * session at most, so every catalogue tool takes an optional
19
+ * `workSessionId`: the session that call runs in. It is added to the
20
+ * schemas here and taken off the arguments before the call reaches Caelo.
14
21
  */
15
22
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
16
23
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
17
24
  import { describeApprovalOutcome, waitForApproval, } from "../approval-wait.js";
18
- import { ADMIN_AWAIT_APPROVAL_TOOL, ADMIN_LOCAL_TOOLS, ADMIN_MCP_INSTRUCTIONS, adminAwaitApprovalInput, GET_CONTEXT_TOOL, OPEN_SESSION_TOOL, openSessionInput, UPLOAD_IMAGES_TOOL, } from "../tool-definitions.js";
25
+ import { ADMIN_AWAIT_APPROVAL_TOOL, ADMIN_LOCAL_TOOLS, ADMIN_MCP_INSTRUCTIONS, adminAwaitApprovalInput, GET_CONTEXT_TOOL, OPEN_SESSION_TOOL, openSessionInput, UPLOAD_IMAGES_TOOL, WORK_SESSION_ARG, WORK_SESSION_PROPERTY, } from "../tool-definitions.js";
19
26
  /** An outcome as an MCP tool result; a failed apply is an error result. */
20
27
  function outcomeResult(o) {
21
28
  return {
@@ -48,6 +55,42 @@ function changesCatalogue(o) {
48
55
  function errorResult(text) {
49
56
  return { isError: true, content: [{ type: "text", text }] };
50
57
  }
58
+ /** Thrown by a backend asked to run a call with no work session to run it in. */
59
+ export class NoWorkSessionError extends Error {
60
+ name = "NoWorkSessionError";
61
+ constructor() {
62
+ super("no open work session — call caelo_open_session first. Every caelo write lands in a session's chat; " +
63
+ "when several agents share this connection, each opens its own session and passes it as workSessionId on every call.");
64
+ }
65
+ }
66
+ /** A catalogue tool's schema with the optional per-call work session (see the header). */
67
+ function withWorkSessionArg(schema) {
68
+ const properties = (schema.properties ?? {});
69
+ if (WORK_SESSION_ARG in properties) {
70
+ // A tool's own argument of this name would be swallowed; the catalogue
71
+ // test keeps every tool clear of it.
72
+ throw new Error(`catalogue tool schema already declares "${WORK_SESSION_ARG}"`);
73
+ }
74
+ return {
75
+ ...schema,
76
+ type: "object",
77
+ properties: { ...properties, [WORK_SESSION_ARG]: WORK_SESSION_PROPERTY },
78
+ };
79
+ }
80
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
81
+ /** Split the per-call work session off a call's arguments. */
82
+ function takeWorkSession(raw) {
83
+ const { [WORK_SESSION_ARG]: value, ...args } = raw;
84
+ if (value === undefined)
85
+ return { ok: true, args };
86
+ if (typeof value !== "string" || !UUID_RE.test(value)) {
87
+ return {
88
+ ok: false,
89
+ message: `${WORK_SESSION_ARG} must be the chatSessionId caelo_open_session returned (a UUID)`,
90
+ };
91
+ }
92
+ return { ok: true, workSessionId: value, args };
93
+ }
51
94
  /** Build the Power-MCP server over `backend`. The caller connects a transport. */
52
95
  export function createAdminMcpServer(backend, opts) {
53
96
  const uploadTool = opts.uploadImagesTool ?? UPLOAD_IMAGES_TOOL;
@@ -61,7 +104,7 @@ export function createAdminMcpServer(backend, opts) {
61
104
  ...(await backend.listCatalogue()).map((t) => ({
62
105
  name: t.name,
63
106
  description: t.description,
64
- inputSchema: t.inputSchema,
107
+ inputSchema: withWorkSessionArg(t.inputSchema),
65
108
  })),
66
109
  ],
67
110
  }));
@@ -118,9 +161,10 @@ export function createAdminMcpServer(backend, opts) {
118
161
  type: "text",
119
162
  text: JSON.stringify(session, null, 2) +
120
163
  (session.resumed
121
- ? `\nResumed the operator's session '${session.title}' — its earlier unstaged work continues here. `
122
- : `\nOpened a new session '${session.title}'. `) +
164
+ ? `\nContinuing session '${session.title}' — its earlier unstaged work continues here. `
165
+ : `\nOpened a new session '${session.title}' (a chat of your own in the Caelo admin). `) +
123
166
  "Subsequent caelo tool calls write to the site's shared draft (or this session's experiment branch). " +
167
+ `If other agents share this connection, pass ${WORK_SESSION_ARG}: "${session.chatSessionId}" on every call. ` +
124
168
  "Stage with stage_changes when the operator asks for it (otherwise offer it when a change is done); the operator clicks Publish live in the Caelo admin.",
125
169
  },
126
170
  ],
@@ -142,16 +186,23 @@ export function createAdminMcpServer(backend, opts) {
142
186
  if (!remote) {
143
187
  return errorResult(`unknown tool: ${name}`);
144
188
  }
145
- const chatSessionId = await backend.currentSessionId();
146
- if (!chatSessionId) {
147
- return errorResult("no open work session — call caelo_open_session first. Every caelo write lands on a " +
148
- "session's preview branch; without one there is nothing to write to.");
189
+ const split = takeWorkSession(req.params.arguments ?? {});
190
+ if (!split.ok)
191
+ return errorResult(split.message);
192
+ let result;
193
+ try {
194
+ result = await backend.executeTool({
195
+ toolName: name,
196
+ args: split.args,
197
+ ...(split.workSessionId ? { chatSessionId: split.workSessionId } : {}),
198
+ rpcRequestId: extra.requestId,
199
+ });
200
+ }
201
+ catch (e) {
202
+ if (e instanceof NoWorkSessionError)
203
+ return errorResult(e.message);
204
+ throw e;
149
205
  }
150
- const result = await backend.executeTool({
151
- toolName: name,
152
- args: req.params.arguments ?? {},
153
- chatSessionId,
154
- });
155
206
  if (result.approval) {
156
207
  // Issue #658 — the call queued a proposal: wait for the operator's
157
208
  // decision (bounded) and return it in THIS result, so the agent
@@ -1 +1 @@
1
- {"version":3,"file":"admin-surface.js","sourceRoot":"","sources":["../../src/surfaces/admin-surface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-surface.js","sourceRoot":"","sources":["../../src/surfaces/admin-surface.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,8 @@
9
9
  export { type ApprovalOutcome, DEFAULT_APPROVAL_WAIT_MS, } from "../approval-wait.js";
10
10
  export type { ChatApprovalState, SendChatResult } from "../chat-approval.js";
11
11
  export { ADMIN_MCP_INSTRUCTIONS, type CaeloChatInput, CHAT_MCP_INSTRUCTIONS, type OpenSessionInput, REMOTE_UPLOAD_IMAGES_TOOL, UPLOAD_IMAGES_TOOL, } from "../tool-definitions.js";
12
- export { type AdminSurfaceBackend, type AdminSurfaceOptions, createAdminMcpServer, type ExecuteToolResponse, type GetContextResponse, type OpenSessionResponse, type RemoteTool, } from "./admin-surface.js";
12
+ export { type AdminSurfaceBackend, type AdminSurfaceOptions, createAdminMcpServer, type ExecuteToolResponse, type GetContextResponse, NoWorkSessionError, type OpenSessionResponse, type RemoteTool, } from "./admin-surface.js";
13
13
  export { type ChatSurfaceBackend, type ChatSurfaceOptions, createChatMcpServer, } from "./chat-surface.js";
14
+ export { rpcToolCallId } from "./rpc-tool-call-id.js";
14
15
  export { type StoreImageMeta, type UploadImagesResult, uploadImagesWith } from "./upload.js";
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/surfaces/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,eAAe,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,sBAAsB,EACtB,KAAK,cAAc,EACnB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/surfaces/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,eAAe,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,sBAAsB,EACtB,KAAK,cAAc,EACnB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -9,7 +9,8 @@
9
9
  */
10
10
  export { DEFAULT_APPROVAL_WAIT_MS, } from "../approval-wait.js";
11
11
  export { ADMIN_MCP_INSTRUCTIONS, CHAT_MCP_INSTRUCTIONS, REMOTE_UPLOAD_IMAGES_TOOL, UPLOAD_IMAGES_TOOL, } from "../tool-definitions.js";
12
- export { createAdminMcpServer, } from "./admin-surface.js";
12
+ export { createAdminMcpServer, NoWorkSessionError, } from "./admin-surface.js";
13
13
  export { createChatMcpServer, } from "./chat-surface.js";
14
+ export { rpcToolCallId } from "./rpc-tool-call-id.js";
14
15
  export { uploadImagesWith } from "./upload.js";
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/surfaces/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;GAOG;AAEH,OAAO,EAEL,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EAEtB,qBAAqB,EAErB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,oBAAoB,GAKrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAgD,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/surfaces/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;GAOG;AAEH,OAAO,EAEL,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EAEtB,qBAAqB,EAErB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,oBAAoB,EAGpB,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAgD,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * #1253 — the idempotency key of an MCP tool call: one per (session key,
3
+ * JSON-RPC request id) — the remote transport session, or the stdio
4
+ * process. Hashed over an unambiguous encoding of both, so a long id is never truncated into another call's
5
+ * key and the numeric id `1` is not the string id `"1"` (JSON-RPC allows
6
+ * both) — a collision would hand a new call the first one's cached result.
7
+ *
8
+ * @returns `rpc-` and 64 hex characters (fits the 128-character key).
9
+ */
10
+ export declare function rpcToolCallId(sessionKey: string, rpcRequestId: string | number): string;
11
+ //# sourceMappingURL=rpc-tool-call-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-tool-call-id.d.ts","sourceRoot":"","sources":["../../src/surfaces/rpc-tool-call-id.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAKvF"}
@@ -0,0 +1,18 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ import { createHash } from "node:crypto";
3
+ /**
4
+ * #1253 — the idempotency key of an MCP tool call: one per (session key,
5
+ * JSON-RPC request id) — the remote transport session, or the stdio
6
+ * process. Hashed over an unambiguous encoding of both, so a long id is never truncated into another call's
7
+ * key and the numeric id `1` is not the string id `"1"` (JSON-RPC allows
8
+ * both) — a collision would hand a new call the first one's cached result.
9
+ *
10
+ * @returns `rpc-` and 64 hex characters (fits the 128-character key).
11
+ */
12
+ export function rpcToolCallId(sessionKey, rpcRequestId) {
13
+ const digest = createHash("sha256")
14
+ .update(JSON.stringify([sessionKey, rpcRequestId]))
15
+ .digest("hex");
16
+ return `rpc-${digest}`;
17
+ }
18
+ //# sourceMappingURL=rpc-tool-call-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-tool-call-id.js","sourceRoot":"","sources":["../../src/surfaces/rpc-tool-call-id.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,YAA6B;IAC7E,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;SAChC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;SAClD,MAAM,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO,OAAO,MAAM,EAAE,CAAC;AACzB,CAAC"}
@@ -216,7 +216,6 @@ export declare const openSessionInput: z.ZodObject<{
216
216
  title: z.ZodOptional<z.ZodString>;
217
217
  pageId: z.ZodOptional<z.ZodString>;
218
218
  chatSessionId: z.ZodOptional<z.ZodString>;
219
- newSession: z.ZodOptional<z.ZodBoolean>;
220
219
  }, z.core.$strict>;
221
220
  export type OpenSessionInput = z.infer<typeof openSessionInput>;
222
221
  export declare const OPEN_SESSION_TOOL: {
@@ -237,13 +236,21 @@ export declare const OPEN_SESSION_TOOL: {
237
236
  type: string;
238
237
  description: string;
239
238
  };
240
- newSession: {
241
- type: string;
242
- description: string;
243
- };
244
239
  };
245
240
  };
246
241
  };
242
+ /**
243
+ * Issue #1253 — the per-call work session. Every catalogue tool gains this
244
+ * optional argument on the Power-MCP surface (and loses it again before the
245
+ * call reaches Caelo): agents sharing one connection each name their own
246
+ * session, because a connection has one current session at most.
247
+ */
248
+ export declare const WORK_SESSION_ARG = "workSessionId";
249
+ /** The JSON-Schema property {@link WORK_SESSION_ARG} adds to each tool. */
250
+ export declare const WORK_SESSION_PROPERTY: {
251
+ readonly type: "string";
252
+ readonly description: "Your work session (the chatSessionId from caelo_open_session). Required when several agents share this connection; otherwise the session you opened last.";
253
+ };
247
254
  export declare const adminAwaitApprovalInput: z.ZodObject<{
248
255
  proposalId: z.ZodString;
249
256
  }, z.core.$strict>;
@@ -435,10 +442,6 @@ export declare const ADMIN_LOCAL_TOOLS: readonly [{
435
442
  type: string;
436
443
  description: string;
437
444
  };
438
- newSession: {
439
- type: string;
440
- description: string;
441
- };
442
445
  };
443
446
  };
444
447
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-definitions.d.ts","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAKtB,CAAC;AAEb;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAQvB,CAAC;AAIb,oEAAoE;AACpE,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C,wFAAwF;AACxF,eAAO,MAAM,mBAAmB;;;;;;;;;kBAMrB,CAAC;AAoBZ,oFAAoF;AACpF,eAAO,MAAM,iBAAiB;;;;;;;;kBAAmE,CAAC;AA4ClG,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrC,CAAC;AAIF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;kBAOtB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B3B,CAAC;AAEF,eAAO,MAAM,sBAAsB;;kBAA0D,CAAC;AAE9F,mFAAmF;AACnF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;CAiBpC,CAAC;AAIF,eAAO,MAAM,gBAAgB;;;;;kBAOlB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;CAwB7B,CAAC;AAEF,eAAO,MAAM,uBAAuB;;kBAAuD,CAAC;AAE5F,oFAAoF;AACpF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;CAgBrC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;CAO5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA2E,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKpB,CAAC"}
1
+ {"version":3,"file":"tool-definitions.d.ts","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAKtB,CAAC;AAEb;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QASvB,CAAC;AAIb,oEAAoE;AACpE,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C,wFAAwF;AACxF,eAAO,MAAM,mBAAmB;;;;;;;;;kBAMrB,CAAC;AAoBZ,oFAAoF;AACpF,eAAO,MAAM,iBAAiB;;;;;;;;kBAAmE,CAAC;AA4ClG,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAO9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrC,CAAC;AAIF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;kBAOtB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B3B,CAAC;AAEF,eAAO,MAAM,sBAAsB;;kBAA0D,CAAC;AAE9F,mFAAmF;AACnF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;CAiBpC,CAAC;AAIF,eAAO,MAAM,gBAAgB;;;;kBAMlB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;CAoB7B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB;;;CAIxB,CAAC;AAEX,eAAO,MAAM,uBAAuB;;kBAAuD,CAAC;AAE5F,oFAAoF;AACpF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;CAgBrC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;CAO5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA2E,CAAC;AAEnG;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKpB,CAAC"}
@@ -30,7 +30,8 @@ export const CHAT_MCP_INSTRUCTIONS = [
30
30
  */
31
31
  export const ADMIN_MCP_INSTRUCTIONS = [
32
32
  "This server edits a Caelo CMS site. Before any other caelo tool:",
33
- "1. Call caelo_open_session once. It resumes the operator's most recent open session (pass newSession: true only when the operator asks for a fresh one; chatSessionId resumes a specific one). Every write lands in the site's shared draft (or the session's own experiment branch); stage with stage_changes when the operator asks for it (otherwise offer it when a change is done), but nothing reaches the live site until the operator clicks Publish live in the Caelo admin.",
33
+ "1. Call caelo_open_session once. It opens your own work session — a chat of yours in the Caelo admin, where the operator can follow, undo and stop your work (pass chatSessionId only to continue a session you opened earlier). Every write lands in the site's shared draft (or the session's own experiment branch); stage with stage_changes when the operator asks for it (otherwise offer it when a change is done), but nothing reaches the live site until the operator clicks Publish live in the Caelo admin.",
34
+ "When several agents work in parallel over this connection (sub-agents), each one calls caelo_open_session itself and passes the workSessionId it got on every caelo call, so each works in its own session. Parallel agents never block each other; two calls that edit the same page or entity at once get a conflict that says to re-read and redo the edit.",
34
35
  "2. Call caelo_get_context once and follow it: it carries the site model, tool playbook, staging rules, site memory (brand voice, glossary) and the skills index.",
35
36
  "3. Load every skill the context marks ALWAYS APPLIES with load_skill before the work it covers (e.g. before writing any visitor-facing copy).",
36
37
  "Every tool in this list works over MCP, including approval-gated ones (marked APPROVAL-GATED — deploys, users/roles, languages/locales, plugin settings, bulk deletes …). Call them yourself: Caelo shows the operator an approval card in the Caelo admin (their Live Edit chat and the pending-approvals page), the call waits for Approve/Reject and returns the decision; if the wait times out, call caelo_await_approval with the proposalId. Tell the operator what you requested and that they approve the card in Caelo. Never ask the operator to paste a prompt into the Caelo admin chat or to do a step there that a tool here can do, and never re-propose a pending proposal.",
@@ -185,33 +186,40 @@ export const openSessionInput = z
185
186
  title: z.string().min(1).max(200).optional(),
186
187
  pageId: z.string().uuid().optional(),
187
188
  chatSessionId: z.string().uuid().optional(),
188
- newSession: z.boolean().optional(),
189
189
  })
190
190
  .strict();
191
191
  export const OPEN_SESSION_TOOL = {
192
192
  name: "caelo_open_session",
193
- description: "Open the Caelo work session your subsequent tool calls run in. Every write lands in the site's shared " +
194
- "draft — invisible to the live site until it is staged and the operator clicks Publish live in the Caelo admin. " +
195
- "Call this ONCE before any other caelo tool. By default it RESUMES the operator's own most recent open " +
196
- "session (so earlier unstaged work continues in the same chat); pass newSession: true only when the " +
197
- "operator wants a separate fresh session, or chatSessionId to resume a specific one. Optional pageId " +
198
- "resumes (or opens) that page's session.",
193
+ description: "Open your Caelo work session: a chat of your own in the operator's Caelo admin, in the site's shared " +
194
+ "draft — your writes are invisible to the live site until they are staged and the operator clicks Publish live. " +
195
+ "Call this ONCE before any other caelo tool; every call opens a NEW session (each agent gets its own, so the " +
196
+ "operator can undo or stop each agent's work on its own). Pass chatSessionId only to continue a session you " +
197
+ "opened earlier. When several agents share this connection, each passes the returned chatSessionId as " +
198
+ "workSessionId on every caelo call. Optional pageId binds the new session to that page.",
199
199
  inputSchema: {
200
200
  type: "object",
201
201
  properties: {
202
202
  title: { type: "string", description: "Session title shown in the Caelo admin chat list." },
203
- pageId: { type: "string", description: "Optional page UUID to bind the session to." },
203
+ pageId: { type: "string", description: "Optional page UUID to bind the new session to." },
204
204
  chatSessionId: {
205
205
  type: "string",
206
- description: "Resume this specific session instead of the most recent one.",
207
- },
208
- newSession: {
209
- type: "boolean",
210
- description: "Open a fresh session instead of resuming the most recent open one.",
206
+ description: "Continue this session (one you opened earlier) instead of opening a new one.",
211
207
  },
212
208
  },
213
209
  },
214
210
  };
211
+ /**
212
+ * Issue #1253 — the per-call work session. Every catalogue tool gains this
213
+ * optional argument on the Power-MCP surface (and loses it again before the
214
+ * call reaches Caelo): agents sharing one connection each name their own
215
+ * session, because a connection has one current session at most.
216
+ */
217
+ export const WORK_SESSION_ARG = "workSessionId";
218
+ /** The JSON-Schema property {@link WORK_SESSION_ARG} adds to each tool. */
219
+ export const WORK_SESSION_PROPERTY = {
220
+ type: "string",
221
+ description: "Your work session (the chatSessionId from caelo_open_session). Required when several agents share this connection; otherwise the session you opened last.",
222
+ };
215
223
  export const adminAwaitApprovalInput = z.object({ proposalId: z.string().uuid() }).strict();
216
224
  /** Issue #658 — keep waiting for a decision after a gated call's wait timed out. */
217
225
  export const ADMIN_AWAIT_APPROVAL_TOOL = {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@caelo-cms/mcp-server",
3
3
  "mcpName": "io.github.caelo-cms/caelo",
4
- "version": "0.11.5",
4
+ "version": "0.11.7",
5
5
  "private": false,
6
6
  "license": "MPL-2.0",
7
7
  "description": "MCP servers for Caelo CMS: `caelo_chat` (talk to Caelo's own AI) and the admin-scoped Power-MCP (the full chat-runner tool catalogue, driven by your own agent). Lets Claude Code (or any MCP-aware client) drive a Caelo install from outside the browser.",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.11.5",
2
+ "version": "0.11.7",
3
3
  "tools": [
4
4
  {
5
5
  "name": "read_content",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  {
46
46
  "name": "edit_content",
47
- "description": "Surgical string-replace in a module's, template's or layout's `html`/`css`/`js` — cheap, minimal-diff edits of existing code.\nPREFER over `update_modules_many` for targeted changes; use `update_modules_many` for wholesale rewrites, new modules, or `fields`/`displayName`/`kind` changes.\nCORE RULES:\n- Read the body first with `read_content`. Edits apply in order, all-or-nothing.\n- Success returns the NEW `sha=` + line-numbered snippets of changed regions: chain further `edit_content` calls with that sha and the fresh line numbers, WITHOUT re-reading.\n- Templates/layouts are APPROVAL-GATED: you propose, the Owner clicks Approve on the card. Do not claim such an edit was applied.\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.",
47
+ "description": "Surgical string-replace in a module's, template's or layout's `html`/`css`/`js` — cheap, minimal-diff edits of existing code.\nPREFER over `update_modules_many` for targeted changes; use `update_modules_many` for wholesale rewrites, new modules, or `fields`/`displayName`/`kind` changes.\nCORE RULES:\n- Read the body first with `read_content`. Edits apply in order, all-or-nothing.\n- Success returns the NEW `sha=` + line-numbered snippets of changed regions: chain further `edit_content` calls with that sha and the fresh line numbers, WITHOUT re-reading.\n- Templates/layouts are APPROVAL-GATED: you propose, the Owner clicks Approve on the card. Do not claim such an edit was applied.\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.",
48
48
  "inputSchema": {
49
49
  "type": "object",
50
50
  "properties": {
@@ -229,7 +229,7 @@
229
229
  },
230
230
  {
231
231
  "name": "build_page",
232
- "description": "Build a WHOLE page in ONE transaction: create (`page:{slug, title}`) or target existing (`page:{pageId}`) + the full ordered module list (each entry places one module into a template block, top to bottom; on an existing page entries append). Any invalid entry aborts everything (error names `modules[i]` + failing field); nothing is written.\nUSE FOR: every page creation (THE page-creation tool); any page needing >1 module — never `add_module` / `create_content_instances` chains. `modules: []` = intentionally empty page shell.\nDO NOT USE FOR: one incremental module on an existing page -> `add_module` (target `page`); site chrome header/footer -> `add_module` (target `layout`; chrome never rides in a page body).\nCORE RULES:\n- Creating: typed page -> `page.pageType` (+ `properties`/`terms`; an ordinary page omits pageType); always `page.metaDescription`, and `status:\"published\"` for a page that belongs on the site — a Stage refuses published pages without a description and builds only published ones; the result says what still blocks a Stage.\n- Per module, two modes: `moduleId` places an EXISTING module (`list_modules`; reuse first — shared modules keep pages consistent), or mint with `displayName` + `html` + `description` + `kind` + explicit `fields[]` (all required).\n- Pair `{{field_name}}` placeholders in `html` with `fields[]` in semantic snake_case (`hero_title`, `primary_cta_href`); never heuristic names (`cta2label2`) or numbered scalars (`label1`..`label10` -> ONE `list` field or a `module-list`).\n- An overview of pages (guides hub, category page) is ONE `list` field bound to a page query (`bind:\"source\"`, `source:{kind:\"query\", defaults:{page_type:…}}`; `term_pages` / `children`), never a hand-kept card per page.\n- Nested modules in the SAME call: inner entry gets `ref` and NO `blockName` (detached: minted + content-bound, not placed); the outer module's `module`/`module-list` field value references it as `{\"$ref\":\"<ref>\"}`, any array order. Never an `add_module` -> `remove_module_from` -> `create_content_instances` chain. E.g. `modules:[{ref:'btn', displayName:'Button', html:'<button>{{label}}</button>', fields:[…], content:{source:'inline', values:{label:'Go'}}}, {blockName:'content', displayName:'CTA', html:'<section>{{>cta}}</section>', fields:[{name:'cta', kind:'module', label:'CTA', allowedModuleTypes:['button']}], content:{source:'inline', values:{cta:{'$ref':'btn'}}}}]`\n- Zero templates on the site -> bootstrap first (`create_layout` -> `create_template`).\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.\nTypical call: `{page:{slug:'pricing', title:'Pricing', status:'published', metaDescription:'…'}, modules:[{blockName:'content', displayName:'Pricing Hero', kind:'hero', description:'…', html:'<section><h1>{{hero_title}}</h1></section>', fields:[{name:'hero_title', kind:'text', label:'Hero title'}], content:{source:'inline', values:{hero_title:'Fair pricing'}}}, …]}`",
232
+ "description": "Build a WHOLE page in ONE transaction: create (`page:{slug, title}`) or target existing (`page:{pageId}`) + the full ordered module list (each entry places one module into a template block, top to bottom; on an existing page entries append). Any invalid entry aborts everything (error names `modules[i]` + failing field); nothing is written.\nUSE FOR: every page creation (THE page-creation tool); any page needing >1 module — never `add_module` / `create_content_instances` chains. `modules: []` = intentionally empty page shell.\nDO NOT USE FOR: one incremental module on an existing page -> `add_module` (target `page`); site chrome header/footer -> `add_module` (target `layout`; chrome never rides in a page body).\nCORE RULES:\n- Creating: `page.pageType` (+ `properties`/`terms`); always `page.metaDescription`, and `status:\"published\"` for a page that belongs on the site — a Stage refuses published pages without a description and builds only published ones; the result says what still blocks a Stage.\n- Per module, two modes: `moduleId` places an EXISTING module (`list_modules`; reuse first — shared modules keep pages consistent), or mint with `displayName` + `html` + `description` + `kind` + explicit `fields[]` (all required).\n- `fields[]` names in semantic snake_case (`hero_title`, `primary_cta_href`); never heuristic names (`cta2label2`) or numbered scalars (`label1`..`label10` -> ONE `list` field or a `module-list`).\n- An overview of pages (guides hub, category page) is ONE `list` field bound to a page query (`bind:\"source\"`, `source:{kind:\"query\", defaults:{page_type:…}}`; `term_pages` / `children`), never a hand-kept card per page.\n- Nested modules in the SAME call: inner entry gets `ref` and NO `blockName` (detached: minted + content-bound, not placed); the outer module's `module`/`module-list` field value references it as `{\"$ref\":\"<ref>\"}`, any array order. Never an `add_module` -> `remove_module_from` -> `create_content_instances` chain. E.g. `modules:[{ref:'btn', displayName:'Button', html:'<button>{{label}}</button>', fields:[…], content:{source:'inline', values:{label:'Go'}}}, {blockName:'content', displayName:'CTA', html:'<section>{{>cta}}</section>', fields:[{name:'cta', kind:'module', label:'CTA', allowedModuleTypes:['button']}], content:{source:'inline', values:{cta:{'$ref':'btn'}}}}]`\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.\nTypical call: `{page:{slug:'pricing', title:'Pricing', status:'published', metaDescription:'…'}, modules:[{blockName:'content', displayName:'Pricing Hero', kind:'hero', description:'…', html:'<section><h1>{{hero_title}}</h1></section>', fields:[{name:'hero_title', kind:'text', label:'Hero title'}], content:{source:'inline', values:{hero_title:'Fair pricing'}}}, …]}`",
233
233
  "inputSchema": {
234
234
  "type": "object",
235
235
  "additionalProperties": false,
@@ -267,12 +267,12 @@
267
267
  "templateId": {
268
268
  "type": "string",
269
269
  "format": "uuid",
270
- "description": "Omit -> the page type's default template (without `pageType`: site default)."
270
+ "description": "Omit -> the page type's default template."
271
271
  },
272
272
  "pageType": {
273
273
  "type": "string",
274
274
  "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
275
- "description": "What the page IS: a slug `list_page_types` shows for this site (e.g. `news` for an article); page queries ('latest news') find pages by it. Omit it for an ordinary page (gets the type listing `templateId`, else the site default). Never guess a slug."
275
+ "description": "REQUIRED for a new page (unless `templateId` belongs to exactly one type): what the page IS, a slug `list_page_types` shows (e.g. `news` for an article); page queries ('latest news') find pages by it. Never guess a slug."
276
276
  },
277
277
  "properties": {
278
278
  "type": "object",
@@ -468,7 +468,7 @@
468
468
  "node",
469
469
  "values"
470
470
  ],
471
- "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep `id` on resend.",
471
+ "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep the `id` of existing entries.",
472
472
  "properties": {
473
473
  "id": {
474
474
  "type": "string"
@@ -637,7 +637,7 @@
637
637
  },
638
638
  {
639
639
  "name": "set_page_module_content_many",
640
- "description": "Set content values of 1..N placements (may span pages) in one transaction. Content lives in a content_instance bound to the placement.\nUSE FOR: page-local copy ('change the hero heading on /home to X'), a whole page's text, the same fix across pages.\nDO NOT USE FOR: pages/modules not existing yet -> one `build_page` call (never `add_module` + this tool); one entry's text -> `patch_page_module_fields`; every page using the module (structure/styling/fields) -> `update_modules_many`.\nCORE RULES:\n- UNSYNCED placements (default) stay local. A SYNCED placement aborts the batch -> `fork_placement_content` it or deliberately `set_content_instance_values_many` (propagates everywhere), then resend.\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]`, the placement, the failing field); nothing is written.\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.",
640
+ "description": "Set content values of 1..N placements (may span pages) in one transaction. Content lives in a content_instance bound to the placement.\nUSE FOR: page-local copy ('change the hero heading on /home to X'), a whole page's text, the same fix across pages.\nDO NOT USE FOR: pages/modules not existing yet -> one `build_page` call (never `add_module` + this tool); one entry's text -> `patch_page_module_fields`; every page using the module (structure/styling/fields) -> `update_modules_many`.\nCORE RULES:\n- UNSYNCED placements (default) stay local. A SYNCED placement aborts the batch -> `fork_placement_content` it or deliberately `set_content_instance_values_many` (propagates everywhere).\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]`, the placement, the failing field); nothing is written.\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.",
641
641
  "inputSchema": {
642
642
  "type": "object",
643
643
  "additionalProperties": false,
@@ -685,7 +685,7 @@
685
685
  },
686
686
  {
687
687
  "name": "create_content_instances",
688
- "description": "Mint 1..N shared, reusable content_instances in one transaction — for content shown identically on several pages (site footer copyright, brand banner on product pages, repeated blog CTA). Bind each via `set_placement_content({syncMode:'synced'})`; edits then propagate everywhere bound.\nDO NOT USE FOR: one-off per-page content -> `set_page_module_content_many` (auto-mints a private instance); creating the page/modules too -> `build_page` (its `content` mints + binds in the same call).\nCORE RULES:\n- BEFORE CALLING: check `list_content_instances` — a row with matching purpose + module + placement pattern -> BIND it via `set_placement_content`; duplicate shared rows defeat the point.\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]` + failing field); nothing is written.\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.",
688
+ "description": "Mint 1..N shared, reusable content_instances in one transaction — for content shown identically on several pages (site footer copyright, brand banner on product pages, repeated blog CTA). Bind each via `set_placement_content({syncMode:'synced'})`; edits then propagate everywhere bound.\nDO NOT USE FOR: one-off per-page content -> `set_page_module_content_many` (auto-mints a private instance); creating the page/modules too -> `build_page` (its `content` mints + binds in the same call).\nCORE RULES:\n- BEFORE CALLING: check `list_content_instances` — a row with matching purpose + module + placement pattern -> BIND it via `set_placement_content`; duplicate shared rows defeat the point.\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]` + failing field); nothing is written.\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.",
689
689
  "inputSchema": {
690
690
  "type": "object",
691
691
  "additionalProperties": false,
@@ -795,7 +795,7 @@
795
795
  },
796
796
  {
797
797
  "name": "set_content_instance_values_many",
798
- "description": "Edit values of 1..N shared content_instances in one transaction. Each item propagates to EVERY page it renders on: its `synced` placements and every page of the parents that show it (blast radius = `pages` in `list_content_instances`).\nUSE FOR: deliberate shared-content changes — check `purpose`, pages and parents first (`list_content_instances` / `get_content_instance`).\nDO NOT USE FOR: an edit meant for ONE page -> `set_page_module_content_many` (unsynced placement) or `fork_placement_content` first (synced); module structure -> `update_modules_many`.\nCORE RULES:\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]`); nothing is written.\n- Optional metadata in the same write: `slug`, `displayName` (`null` clears), `purpose`.\n- The result names per item where the edit now shows — relay it when the reach is wider than the operator asked for.\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.",
798
+ "description": "Edit values of 1..N shared content_instances in one transaction. Each item propagates to EVERY page it renders on: its `synced` placements and every page of the parents that show it (blast radius = `pages` in `list_content_instances`).\nUSE FOR: deliberate shared-content changes — check `purpose`, pages and parents first (`list_content_instances` / `get_content_instance`).\nDO NOT USE FOR: an edit meant for ONE page -> `set_page_module_content_many` (unsynced placement) or `fork_placement_content` first (synced); module structure -> `update_modules_many`.\nCORE RULES:\n- All-or-nothing: an invalid item aborts the batch (error names `items[i]`); nothing is written.\n- Optional metadata in the same write: `slug`, `displayName` (`null` clears), `purpose`.\n- The result names per item where the edit now shows — relay it when the reach is wider than the operator asked for.\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.",
799
799
  "inputSchema": {
800
800
  "type": "object",
801
801
  "additionalProperties": false,
@@ -1945,9 +1945,96 @@
1945
1945
  }
1946
1946
  }
1947
1947
  },
1948
+ {
1949
+ "name": "retry_tool_call",
1950
+ "description": "Fix a failed write call with a small patch instead of resending it — only for a call whose result names `retry_tool_call`. Paths are segment arrays exactly as the error names them (`[\"page\",\"pageType\"]`, `[\"modules\",3,\"html\"]`). `set` writes a value, `remove` drops a key or array entry, `replace` swaps one exact text inside one string (must match once). The patched call runs as a new call (permissions, validation, approval re-checked); if it fails again, patch the same toolCallId again.",
1951
+ "inputSchema": {
1952
+ "type": "object",
1953
+ "additionalProperties": false,
1954
+ "required": [
1955
+ "toolCallId"
1956
+ ],
1957
+ "properties": {
1958
+ "toolCallId": {
1959
+ "type": "string",
1960
+ "description": "The failed call's id, from its result."
1961
+ },
1962
+ "set": {
1963
+ "type": "array",
1964
+ "items": {
1965
+ "type": "object",
1966
+ "additionalProperties": false,
1967
+ "required": [
1968
+ "path",
1969
+ "value"
1970
+ ],
1971
+ "properties": {
1972
+ "path": {
1973
+ "type": "array",
1974
+ "minItems": 1,
1975
+ "items": {
1976
+ "type": [
1977
+ "string",
1978
+ "integer"
1979
+ ]
1980
+ },
1981
+ "description": "Segment array as the error names it, e.g. [\"modules\",3,\"html\"]."
1982
+ },
1983
+ "value": {}
1984
+ }
1985
+ }
1986
+ },
1987
+ "remove": {
1988
+ "type": "array",
1989
+ "items": {
1990
+ "type": "array",
1991
+ "minItems": 1,
1992
+ "items": {
1993
+ "type": [
1994
+ "string",
1995
+ "integer"
1996
+ ]
1997
+ },
1998
+ "description": "Segment array as the error names it, e.g. [\"modules\",3,\"html\"]."
1999
+ }
2000
+ },
2001
+ "replace": {
2002
+ "type": "array",
2003
+ "items": {
2004
+ "type": "object",
2005
+ "additionalProperties": false,
2006
+ "required": [
2007
+ "path",
2008
+ "old",
2009
+ "new"
2010
+ ],
2011
+ "properties": {
2012
+ "path": {
2013
+ "type": "array",
2014
+ "minItems": 1,
2015
+ "items": {
2016
+ "type": [
2017
+ "string",
2018
+ "integer"
2019
+ ]
2020
+ },
2021
+ "description": "Segment array as the error names it, e.g. [\"modules\",3,\"html\"]."
2022
+ },
2023
+ "old": {
2024
+ "type": "string"
2025
+ },
2026
+ "new": {
2027
+ "type": "string"
2028
+ }
2029
+ }
2030
+ }
2031
+ }
2032
+ }
2033
+ }
2034
+ },
1948
2035
  {
1949
2036
  "name": "get_site_defaults",
1950
- "description": "Fetch CURRENT site defaults + identity: default layout/template (slug + UUID), siteName, sitePurpose, siteLanguage (`<html lang>`), design brief. Read before set_site_defaults / set_site_identity, and after them for fresh state instead of repeating the write.",
2037
+ "description": "Fetch CURRENT site defaults + identity: default layout (slug + UUID), siteName, sitePurpose, siteLanguage (`<html lang>`), design brief. Read before set_site_defaults / set_site_identity, and after them for fresh state instead of repeating the write.",
1951
2038
  "inputSchema": {
1952
2039
  "type": "object",
1953
2040
  "properties": {},
@@ -2014,7 +2101,7 @@
2014
2101
  },
2015
2102
  {
2016
2103
  "name": "list_users",
2017
- "description": "List site users (email, display name, roles); read-only. Changes: propose_create_user / propose_set_user_roles / propose_delete_user (Owner-approved). Re-call after an Owner approved one.",
2104
+ "description": "List site users (email, display name, roles); read-only. Changes: propose_create_user / propose_set_user_roles / propose_delete_user (Owner-approved).",
2018
2105
  "inputSchema": {
2019
2106
  "type": "object",
2020
2107
  "properties": {
@@ -2195,7 +2282,7 @@
2195
2282
  },
2196
2283
  {
2197
2284
  "name": "add_module",
2198
- "description": "Add ONE module to a page, a layout (site-wide chrome on every page) or a template (fans out to every page of that page type).\nUSE FOR: one incremental module on an existing page; chrome (`target:\"layout\"`); a module on every page of a template.\nDO NOT USE FOR: a new page or a page needing >1 module -> `build_page` (whole ordered list WITH content, one transaction).\nCORE RULES:\n- Two modes, all targets. Reuse (check `list_modules` first): `moduleId` places a SHARED module without a duplicate; a later `update_modules_many` changes it everywhere. Placement-only: authoring fields passed alongside are NOT applied (result says so) — to change the module, place by `moduleId`, then `update_modules_many`. Mint: `html` + `displayName` + `kind` + `fields[]` (`[]` = no fields of its own, used verbatim).\n- AUTHOR EXPLICITLY: pair `{{field_name}}` placeholders in `html` with explicit `fields[]` in semantic snake_case (`hero_title`, `primary_cta_href`, `nav_items`); never heuristic names (`cta2label2`, `spanText`).\n- LISTS ARE LISTS: 10-item menu = ONE `list` field, never `label1`..`label10`; tag cloud = ONE `list` (`listType:\"texts\"`); multi-part items (image + heading + text) -> custom list type (`upsert_list_types_many`) or a `module-list` of a card module.\n- Initial content comes IN THIS CALL via `values`. A mint with `fields` but neither `values` nor field defaults is REJECTED (would render empty placeholders).\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.\n\nOver this connection the install's AI is not used: the AI part comes back to you — a work item to answer with your own model and send back through the tool it names, or an `AiDelegated:` answer that says what to do instead (see caelo_get_context).",
2285
+ "description": "Add ONE module to a page, a layout (site-wide chrome on every page) or a template (fans out to every page of that page type).\nUSE FOR: one incremental module on an existing page; chrome (`target:\"layout\"`); a module on every page of a template.\nDO NOT USE FOR: a new page or a page needing >1 module -> `build_page` (whole ordered list WITH content, one transaction).\nCORE RULES:\n- Two modes, all targets. Reuse (check `list_modules` first): `moduleId` places a SHARED module without a duplicate; a later `update_modules_many` changes it everywhere. Placement-only: authoring fields passed alongside are NOT applied (result says so) — to change the module, place by `moduleId`, then `update_modules_many`. Mint: `html` + `displayName` + `kind` + `fields[]` (`[]` = no fields of its own, used verbatim).\n- AUTHOR EXPLICITLY: `fields[]` names in semantic snake_case (`hero_title`, `primary_cta_href`, `nav_items`); never heuristic names (`cta2label2`, `spanText`).\n- LISTS ARE LISTS: 10-item menu = ONE `list` field, never `label1`..`label10`; tag cloud = ONE `list` (`listType:\"texts\"`); multi-part items (image + heading + text) -> custom list type (`upsert_list_types_many`) or a `module-list` of a card module.\n- Initial content: `values` in this call (or field `default`s).\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.\n\nOver this connection the install's AI is not used: the AI part comes back to you — a work item to answer with your own model and send back through the tool it names, or an `AiDelegated:` answer that says what to do instead (see caelo_get_context).",
2199
2286
  "inputSchema": {
2200
2287
  "type": "object",
2201
2288
  "additionalProperties": false,
@@ -2276,7 +2363,7 @@
2276
2363
  "type": "string",
2277
2364
  "minLength": 1,
2278
2365
  "maxLength": 50000,
2279
- "description": "Module HTML. Plain source (no CDATA or extra escaping). Placeholders: `{{field}}` primitives, `{{>field}}` single nested `module`, `{{#field}}…{{/field}}` `list` and `module-list`. Accordion, tabs, carousel, mobile-nav -> `data-caelo-ui` markup (see `js`) instead of custom JS."
2366
+ "description": "Module HTML. Plain source (no CDATA or extra escaping). Placeholders: `{{field}}` primitives, `{{>field}}` single nested `module`, `{{#field}}…{{/field}}` `list` and `module-list`. Accordion, tabs, carousel, mobile-nav -> `data-caelo-ui` markup (snippets on `build_page` `modules[].js`) instead of custom JS."
2280
2367
  },
2281
2368
  "css": {
2282
2369
  "type": "string",
@@ -2286,7 +2373,7 @@
2286
2373
  "js": {
2287
2374
  "type": "string",
2288
2375
  "maxLength": 50000,
2289
- "description": "Vanilla JS. Plain source (no CDATA or extra escaping). Emitted ONCE per page into a shared `<script defer>` with all other modules — SHARED top-level scope, NO implicit `root`/`el`/`module`/`this`. Wrap in an IIFE, query `document.querySelectorAll('.your-module-root …')`, iterate matches so multiple placements work. Omit for presentational modules. Touch ONLY this module's markup — another module's script goes into that module, never into a header/footer because it loads everywhere. Text, links, menu entries live in `html` (crawlers read no js output); js only shows/hides/toggles. Deliberate site-wide behaviour on hooks many modules share: comment `/* caelo:site-wide: <reason> */`. `data-caelo-ui` kit — use it instead of JS for these (accessible, shipped once per page, style freely in module CSS):\n- `accordion` (FAQ, collapsible): `<div data-caelo-ui=\"accordion\" data-single>` with `<details id=\"...\"><summary>Question</summary><div>Answer</div></details>` items; `data-single` keeps one open; a link to `#<details id>` opens it.\n- `tabs`: `<div data-caelo-ui=\"tabs\"><div role=\"tablist\" aria-label=\"...\"><button type=\"button\" role=\"tab\" id=\"t1\" aria-controls=\"p1\" aria-selected=\"true\">...</button><button type=\"button\" role=\"tab\" id=\"t2\" aria-controls=\"p2\" aria-selected=\"false\" tabindex=\"-1\">...</button></div><div role=\"tabpanel\" id=\"p1\" aria-labelledby=\"t1\">...</div><div role=\"tabpanel\" id=\"p2\" aria-labelledby=\"t2\" hidden>...</div></div>`; ids unique on the page.\n- `carousel` (slider, testimonials): `<section data-caelo-ui=\"carousel\" aria-roledescription=\"carousel\" aria-label=\"...\"><div data-caelo-carousel-track tabindex=\"0\"><div role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 3\">...</div>...</div><button type=\"button\" data-caelo-carousel-prev aria-label=\"Previous slide\"><span aria-hidden=\"true\">&lsaquo;</span></button><button type=\"button\" data-caelo-carousel-next aria-label=\"Next slide\"><span aria-hidden=\"true\">&rsaquo;</span></button></section>`; icon buttons keep visible content aria-hidden, text buttons need no aria-label. One slide per view; set the slides' `flex-basis` in module CSS to show more.\n- `mobile-nav` (menu collapsing behind a toggle on small screens): `<nav class=\"caelo-nav-menu\" data-caelo-ui=\"mobile-nav\" data-nav-open=\"false\"><button type=\"button\" class=\"caelo-nav-toggle\" aria-expanded=\"false\" aria-label=\"Menu\"><span class=\"caelo-nav-bar\"></span><span class=\"caelo-nav-bar\"></span><span class=\"caelo-nav-bar\"></span></button><ul>{{#menu}}<li>…</li>{{/menu}}</ul></nav>` around the module's menu `list` field.\nWrite module JS only for behaviour the kit does not cover."
2376
+ "description": "Vanilla JS. Plain source (no CDATA or extra escaping). Emitted ONCE per page into a shared `<script defer>` with all other modules — SHARED top-level scope, NO implicit `root`/`el`/`module`/`this`. Wrap in an IIFE, query `document.querySelectorAll('.your-module-root …')`, iterate matches so multiple placements work. Omit for presentational modules. Touch ONLY this module's markup — another module's script goes into that module, never into a header/footer because it loads everywhere. Text, links, menu entries live in `html` (crawlers read no js output); js only shows/hides/toggles. Deliberate site-wide behaviour on hooks many modules share: comment `/* caelo:site-wide: <reason> */`. Accordion, tabs, carousel, mobile-nav: use the `data-caelo-ui` kit (markup on `build_page` `modules[].js`), not custom JS."
2290
2377
  },
2291
2378
  "bindThemeLiterals": {
2292
2379
  "type": "boolean",
@@ -2348,7 +2435,7 @@
2348
2435
  "node",
2349
2436
  "values"
2350
2437
  ],
2351
- "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep `id` on resend.",
2438
+ "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep the `id` of existing entries.",
2352
2439
  "properties": {
2353
2440
  "id": {
2354
2441
  "type": "string"
@@ -2508,7 +2595,7 @@
2508
2595
  },
2509
2596
  {
2510
2597
  "name": "create_template",
2511
- "description": "Create a template (reusable HTML+CSS shell pages bind to) for a page type, e.g. 'a blog-post template'. NOT for a one-off page (`build_page`).\nCORE RULES:\n- An ordinary template omits `pageType` (it joins the site's default page type). Pass `pageType` only with a slug `list_page_types` shows; never guess one (`page`, `article` …).\n- A new KIND of content (news, products) is a page type first: `upsert_page_types_many` needs a template id -> create the template, then the type listing it (or pass an existing type's slug).\n- `layoutId`: optional when a default layout exists (`get_site_defaults`; omitted -> that default); else REQUIRED, pick from `list_layouts` (omitting fails with 'no defaults'). Zero layouts -> `create_layout` first.\n- Slots in `html` MUST be `<caelo-slot name=\"X\"></caelo-slot>`, NOT comments like `<!-- block:X -->` (ignored -> page renders empty). Every block name needs a matching slot.",
2598
+ "description": "Create a template (reusable HTML+CSS shell pages bind to) for a page type, e.g. 'a blog-post template'. NOT for a one-off page (`build_page`).\nCORE RULES:\n- Exactly one of `pageType` (a slug `list_page_types` shows; never guess one) or, for a new KIND of content (news, products), `newPageType` — it creates the type with this template as its default in the same call.\n- `layoutId`: optional when a default layout exists (`get_site_defaults`; omitted -> that default); else REQUIRED, pick from `list_layouts` (omitting fails with 'no defaults'). Zero layouts -> `create_layout` first.\n- Slots in `html` MUST be `<caelo-slot name=\"X\"></caelo-slot>`, NOT comments like `<!-- block:X -->` (ignored -> page renders empty). Every block name needs a matching slot.",
2512
2599
  "inputSchema": {
2513
2600
  "type": "object",
2514
2601
  "additionalProperties": false,
@@ -2544,6 +2631,58 @@
2544
2631
  "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
2545
2632
  "description": "Existing page type slug from `list_page_types`; the template joins its templates."
2546
2633
  },
2634
+ "newPageType": {
2635
+ "type": "object",
2636
+ "additionalProperties": false,
2637
+ "required": [
2638
+ "slug",
2639
+ "name",
2640
+ "purpose",
2641
+ "collection"
2642
+ ],
2643
+ "description": "New page type for this template, e.g. `{slug:'news', name:'News article', purpose:'Dated company news, listed newest first', collection:true}`.",
2644
+ "properties": {
2645
+ "slug": {
2646
+ "type": "string",
2647
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$"
2648
+ },
2649
+ "name": {
2650
+ "type": "string",
2651
+ "minLength": 1,
2652
+ "maxLength": 200
2653
+ },
2654
+ "purpose": {
2655
+ "type": "string",
2656
+ "minLength": 1,
2657
+ "maxLength": 1000
2658
+ },
2659
+ "collection": {
2660
+ "type": "boolean",
2661
+ "description": "true: many similar pages meant to be listed or queried (blog, news, products, jobs, docs); false: standalone pages (home, about, contact, legal, landing)."
2662
+ },
2663
+ "properties": {
2664
+ "type": "array",
2665
+ "items": {
2666
+ "type": "object",
2667
+ "description": "a field: {name, label, type, required?, default?, options?, …}"
2668
+ }
2669
+ },
2670
+ "vocabularies": {
2671
+ "type": "array",
2672
+ "items": {
2673
+ "type": "object",
2674
+ "description": "{list: <vocabulary list id>, cardinality: one|many, required?}"
2675
+ }
2676
+ },
2677
+ "distinctFrom": {
2678
+ "type": "array",
2679
+ "items": {
2680
+ "type": "string"
2681
+ },
2682
+ "description": "Existing slugs it is deliberately NOT (refused as a duplicate otherwise, e.g. `blogs` next to `blog`)."
2683
+ }
2684
+ }
2685
+ },
2547
2686
  "blocks": {
2548
2687
  "type": "array",
2549
2688
  "description": "Omit to auto-derive one block per `<caelo-slot>` (displayName = name); pass only for nicer displayNames or explicit positions.",
@@ -2769,20 +2908,18 @@
2769
2908
  },
2770
2909
  {
2771
2910
  "name": "set_site_defaults",
2772
- "description": "Set the site-wide default layout and/or template for new pages created without one. Safe to call directly: existing pages keep theirs.\nCORE RULES: pass slugs (e.g. `site-default`), not UUIDs; current values via `get_site_defaults`, slugs via `list_layouts`/`list_templates`. FIRST set needs both fields, afterwards only the changed one. No layouts/templates yet -> `create_layout` -> `create_template` first.",
2911
+ "description": "Set the site-wide default layout for new templates created without one. Safe to call directly: existing templates keep theirs. Pass the slug (e.g. `site-default`, from `list_layouts`), not a UUID. No layouts yet -> `create_layout` first.",
2773
2912
  "inputSchema": {
2774
2913
  "type": "object",
2775
2914
  "additionalProperties": false,
2915
+ "required": [
2916
+ "defaultLayoutSlug"
2917
+ ],
2776
2918
  "properties": {
2777
2919
  "defaultLayoutSlug": {
2778
2920
  "type": "string",
2779
2921
  "minLength": 1,
2780
2922
  "maxLength": 120
2781
- },
2782
- "defaultTemplateSlug": {
2783
- "type": "string",
2784
- "minLength": 1,
2785
- "maxLength": 120
2786
2923
  }
2787
2924
  }
2788
2925
  }
@@ -2870,7 +3007,7 @@
2870
3007
  },
2871
3008
  {
2872
3009
  "name": "bootstrap_site_scaffold",
2873
- "description": "Bootstrap a fresh install (layout + template + site defaults) — when the status note says 'needs setup' for them. Idempotent: each call detects and runs the next missing stage; the RESULT says which ran and what next.\n- No layout: queues a layout PROPOSAL the operator approves on the chat's card. Don't claim it exists; after approval call this tool AGAIN.\n- Layout exists: creates the template + pins site defaults directly. All exist: no-op.\nAll inputs optional; defaults = header/content/footer layout, single-block `home` template, pinned defaults.",
3010
+ "description": "Bootstrap a fresh install (layout + template + site defaults) — when the status note says 'needs setup' for them. Idempotent: each call detects and runs the next missing stage; the RESULT says which ran and what next.\n- No layout: queues a layout PROPOSAL the operator approves on the chat's card. Don't claim it exists; after approval call this tool AGAIN.\n- Layout exists: creates the template + pins the default layout directly. All exist: no-op.\nAll inputs optional; defaults = header/content/footer layout, single-block `home` template of page type `home`, pinned layout.",
2874
3011
  "inputSchema": {
2875
3012
  "type": "object",
2876
3013
  "additionalProperties": false,
@@ -2920,6 +3057,37 @@
2920
3057
  "minLength": 1,
2921
3058
  "maxLength": 256
2922
3059
  },
3060
+ "templatePageType": {
3061
+ "type": "object",
3062
+ "additionalProperties": false,
3063
+ "required": [
3064
+ "slug",
3065
+ "name",
3066
+ "purpose",
3067
+ "collection"
3068
+ ],
3069
+ "description": "Page type the template serves (joins it when the slug exists, else creates it). Default `home`.",
3070
+ "properties": {
3071
+ "slug": {
3072
+ "type": "string",
3073
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$"
3074
+ },
3075
+ "name": {
3076
+ "type": "string",
3077
+ "minLength": 1,
3078
+ "maxLength": 200
3079
+ },
3080
+ "purpose": {
3081
+ "type": "string",
3082
+ "minLength": 1,
3083
+ "maxLength": 1000
3084
+ },
3085
+ "collection": {
3086
+ "type": "boolean",
3087
+ "description": "true: many similar pages to list or query; false: standalone pages."
3088
+ }
3089
+ }
3090
+ },
2923
3091
  "setAsDefaults": {
2924
3092
  "type": "boolean"
2925
3093
  }
@@ -2983,6 +3151,11 @@
2983
3151
  "type": "string",
2984
3152
  "format": "uuid"
2985
3153
  },
3154
+ "pageType": {
3155
+ "type": "string",
3156
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
3157
+ "description": "The copy's page type (`list_page_types`); omit = the source's."
3158
+ },
2986
3159
  "newParentPageId": {
2987
3160
  "type": [
2988
3161
  "string",
@@ -3693,6 +3866,27 @@
3693
3866
  "additionalProperties": false
3694
3867
  }
3695
3868
  },
3869
+ {
3870
+ "name": "get_stage_status",
3871
+ "description": "Where Stage builds stand: phase, pages built, run time, estimated time left (with its basis) and a failed run's reason + step. No args = newest Stage runs.\nUSE FOR: a Stage that outlasted `stage_changes`' wait; the operator asks how far staging is or why a Stage failed. DO NOT USE FOR quality scores/findings -> `get_quality_audit`.\nCORE RULES: call again only after the estimated time has passed, never in a loop. Never re-run `stage_changes` for a queued/running Stage. Succeeded -> `get_quality_audit` with that `deployRunId`.",
3872
+ "inputSchema": {
3873
+ "type": "object",
3874
+ "properties": {
3875
+ "deployRunId": {
3876
+ "description": "The run `stage_changes` / `get_quality_audit` named. Omit = the newest Stage runs.",
3877
+ "type": "string",
3878
+ "format": "uuid"
3879
+ },
3880
+ "limit": {
3881
+ "description": "Default 5.",
3882
+ "type": "integer",
3883
+ "minimum": 1,
3884
+ "maximum": 20
3885
+ }
3886
+ },
3887
+ "additionalProperties": false
3888
+ }
3889
+ },
3696
3890
  {
3697
3891
  "name": "list_quality_audits",
3698
3892
  "description": "List recent quality audits of staging deploys, newest first. Find an audit id for `get_quality_audit` or check whether the last Stage's audit still runs.",
@@ -4447,7 +4641,7 @@
4447
4641
  },
4448
4642
  {
4449
4643
  "name": "update_modules_many",
4450
- "description": "Edit module structure (`html`, `fields`, `css`, `js`, `displayName`, `description`, `kind`, `type`) of 1..N modules. Every page using a module follows; chat-branched until publish.\nUSE FOR: wholesale rewrites, new module bodies, changes to `fields`/`displayName`/`kind`/`type`/`description`, the same fix across modules.\nDO NOT USE FOR: a TARGETED change to existing `html`/`css`/`js` -> PREFER `edit_content` (surgical string-replace: cheaper, reviewable diff); page/instance content -> `set_page_module_content_many` (per page) | `set_content_instance_values_many` (shared); page metadata -> `update_pages_many`; templates -> `propose_update_template`.\nCORE RULES:\n- AUTHOR EXPLICITLY: pair `{{field_name}}` placeholders in `html` with explicit `fields[]` in semantic snake_case (`hero_title`, `primary_cta_href`, `nav_items`); never heuristic names (`cta2label2`, `spanText`).\n- LISTS ARE LISTS: 10-item menu = ONE `list` field, never `label1`..`label10`; tag cloud = ONE `list` (`listType:\"texts\"`); multi-part items (image + heading + text) -> custom list type (`upsert_list_types_many`) or a `module-list` of a card module.\n- KEEP METADATA FRESH: update `description` + `kind` when a module's purpose drifts (`list_modules` relies on them).\n- `fields` is the WHOLE list (omitted fields are dropped): read it first with `read_content` `field:\"fields\"` and resend every field. A field resent without `default` keeps its stored one.\n- Items apply independently: a failed item (not found, draft conflict, invalid field) is reported with its reason, the rest commits; nothing updated -> error. One snapshot per module.\n- INTERNAL LINKS (`html` hrefs, `url`/`link` fields, list-entry links): write the page path (e.g. `/about`). Target MUST be an existing page (`list_pages`) or it is refused — create an empty shell first (`build_page({page:{slug, title}, modules:[]})`) or link after. `/` and `/#section` are always valid. Exception: links to pages of this chat's site-import run are kept and resolved by `resolve_import_links` at the end. Media/files: media URL (`find_media`). External: full `https://` URL.",
4644
+ "description": "Edit module structure (`html`, `fields`, `css`, `js`, `displayName`, `description`, `kind`, `type`) of 1..N modules. Every page using a module follows; chat-branched until publish.\nUSE FOR: wholesale rewrites, new module bodies, changes to `fields`/`displayName`/`kind`/`type`/`description`, the same fix across modules.\nDO NOT USE FOR: a TARGETED change to existing `html`/`css`/`js` -> PREFER `edit_content` (surgical string-replace: cheaper, reviewable diff); page/instance content -> `set_page_module_content_many` (per page) | `set_content_instance_values_many` (shared); page metadata -> `update_pages_many`; templates -> `propose_update_template`.\nCORE RULES:\n- AUTHOR EXPLICITLY: `fields[]` names in semantic snake_case (`hero_title`, `primary_cta_href`, `nav_items`); never heuristic names (`cta2label2`, `spanText`).\n- LISTS ARE LISTS: 10-item menu = ONE `list` field, never `label1`..`label10`; tag cloud = ONE `list` (`listType:\"texts\"`); multi-part items (image + heading + text) -> custom list type (`upsert_list_types_many`) or a `module-list` of a card module.\n- KEEP METADATA FRESH: update `description` + `kind` when a module's purpose drifts (`list_modules` relies on them).\n- `fields` is the WHOLE list (omitted fields are dropped): read it first with `read_content` `field:\"fields\"` and pass every field. A field passed without `default` keeps its stored one.\n- Items apply independently: a failed item (not found, draft conflict, invalid field) is reported with its reason, the rest commits; nothing updated -> error. One snapshot per module.\n- INTERNAL LINKS: path of an EXISTING page (`/about`, `/#section`; `list_pages`) — a link to a page not built yet is refused (pages of this chat's site import excepted). External: full `https://` URL.",
4451
4645
  "inputSchema": {
4452
4646
  "type": "object",
4453
4647
  "additionalProperties": false,
@@ -4497,7 +4691,7 @@
4497
4691
  },
4498
4692
  "html": {
4499
4693
  "type": "string",
4500
- "description": "Module HTML. Plain source (no CDATA or extra escaping). Placeholders: `{{field}}` primitives, `{{>field}}` single nested `module`, `{{#field}}…{{/field}}` `list` and `module-list`. Accordion, tabs, carousel, mobile-nav -> `data-caelo-ui` markup (see `js`) instead of custom JS."
4694
+ "description": "Module HTML. Plain source (no CDATA or extra escaping). Placeholders: `{{field}}` primitives, `{{>field}}` single nested `module`, `{{#field}}…{{/field}}` `list` and `module-list`. Accordion, tabs, carousel, mobile-nav -> `data-caelo-ui` markup (snippets on `build_page` `modules[].js`) instead of custom JS."
4501
4695
  },
4502
4696
  "css": {
4503
4697
  "type": "string",
@@ -4505,7 +4699,7 @@
4505
4699
  },
4506
4700
  "js": {
4507
4701
  "type": "string",
4508
- "description": "Vanilla JS. Plain source (no CDATA or extra escaping). Emitted ONCE per page into a shared `<script defer>` with all other modules — SHARED top-level scope, NO implicit `root`/`el`/`module`/`this`. Wrap in an IIFE, query `document.querySelectorAll('.your-module-root …')`, iterate matches so multiple placements work. Omit for presentational modules. Touch ONLY this module's markup — another module's script goes into that module, never into a header/footer because it loads everywhere. Text, links, menu entries live in `html` (crawlers read no js output); js only shows/hides/toggles. Deliberate site-wide behaviour on hooks many modules share: comment `/* caelo:site-wide: <reason> */`. `data-caelo-ui` kit — use it instead of JS for these (accessible, shipped once per page, style freely in module CSS):\n- `accordion` (FAQ, collapsible): `<div data-caelo-ui=\"accordion\" data-single>` with `<details id=\"...\"><summary>Question</summary><div>Answer</div></details>` items; `data-single` keeps one open; a link to `#<details id>` opens it.\n- `tabs`: `<div data-caelo-ui=\"tabs\"><div role=\"tablist\" aria-label=\"...\"><button type=\"button\" role=\"tab\" id=\"t1\" aria-controls=\"p1\" aria-selected=\"true\">...</button><button type=\"button\" role=\"tab\" id=\"t2\" aria-controls=\"p2\" aria-selected=\"false\" tabindex=\"-1\">...</button></div><div role=\"tabpanel\" id=\"p1\" aria-labelledby=\"t1\">...</div><div role=\"tabpanel\" id=\"p2\" aria-labelledby=\"t2\" hidden>...</div></div>`; ids unique on the page.\n- `carousel` (slider, testimonials): `<section data-caelo-ui=\"carousel\" aria-roledescription=\"carousel\" aria-label=\"...\"><div data-caelo-carousel-track tabindex=\"0\"><div role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 3\">...</div>...</div><button type=\"button\" data-caelo-carousel-prev aria-label=\"Previous slide\"><span aria-hidden=\"true\">&lsaquo;</span></button><button type=\"button\" data-caelo-carousel-next aria-label=\"Next slide\"><span aria-hidden=\"true\">&rsaquo;</span></button></section>`; icon buttons keep visible content aria-hidden, text buttons need no aria-label. One slide per view; set the slides' `flex-basis` in module CSS to show more.\n- `mobile-nav` (menu collapsing behind a toggle on small screens): `<nav class=\"caelo-nav-menu\" data-caelo-ui=\"mobile-nav\" data-nav-open=\"false\"><button type=\"button\" class=\"caelo-nav-toggle\" aria-expanded=\"false\" aria-label=\"Menu\"><span class=\"caelo-nav-bar\"></span><span class=\"caelo-nav-bar\"></span><span class=\"caelo-nav-bar\"></span></button><ul>{{#menu}}<li>…</li>{{/menu}}</ul></nav>` around the module's menu `list` field.\nWrite module JS only for behaviour the kit does not cover."
4702
+ "description": "Vanilla JS. Plain source (no CDATA or extra escaping). Emitted ONCE per page into a shared `<script defer>` with all other modules — SHARED top-level scope, NO implicit `root`/`el`/`module`/`this`. Wrap in an IIFE, query `document.querySelectorAll('.your-module-root …')`, iterate matches so multiple placements work. Omit for presentational modules. Touch ONLY this module's markup — another module's script goes into that module, never into a header/footer because it loads everywhere. Text, links, menu entries live in `html` (crawlers read no js output); js only shows/hides/toggles. Deliberate site-wide behaviour on hooks many modules share: comment `/* caelo:site-wide: <reason> */`. Accordion, tabs, carousel, mobile-nav: use the `data-caelo-ui` kit (markup on `build_page` `modules[].js`), not custom JS."
4509
4703
  },
4510
4704
  "fields": {
4511
4705
  "type": "array",
@@ -4563,7 +4757,7 @@
4563
4757
  "node",
4564
4758
  "values"
4565
4759
  ],
4566
- "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep `id` on resend.",
4760
+ "description": "texts {node:\"text\", values:{text}} · links {node:\"link\", values:{label, link:{href}}} · menu {node:\"entry\", …, children}; keep the `id` of existing entries.",
4567
4761
  "properties": {
4568
4762
  "id": {
4569
4763
  "type": "string"
@@ -5135,7 +5329,7 @@
5135
5329
  "snapshots",
5136
5330
  "chat_runner_tools",
5137
5331
  "background_workers",
5138
- "domain_events",
5332
+ "change_journal",
5139
5333
  "email",
5140
5334
  "head_contributions",
5141
5335
  "url_slots",
@@ -6963,8 +7157,13 @@
6963
7157
  },
6964
7158
  "description": "From `list_import_pages`."
6965
7159
  },
7160
+ "pageType": {
7161
+ "description": "What the pages ARE (`list_page_types` slug). Required unless `templateId` belongs to one type.",
7162
+ "type": "string",
7163
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$"
7164
+ },
6966
7165
  "templateId": {
6967
- "description": "From `list_templates`; omit for the site default.",
7166
+ "description": "From `list_templates`; omit for the type's default template.",
6968
7167
  "type": "string",
6969
7168
  "format": "uuid"
6970
7169
  }
@@ -7621,7 +7820,7 @@
7621
7820
  },
7622
7821
  {
7623
7822
  "name": "upsert_list_types_many",
7624
- "description": "Create or replace list types (the SHAPE of a list).\nDO NOT USE FOR: a near-duplicate of a shipped type (reuse `links`/`menu`); changing a plugin-shipped type (create your own slug).\nCORE RULES:\n- `root.allow` = top-level node kinds. `purpose` = why the type exists (later reads decide by it). `max_depth` required when a node allows itself. `current_from` names the node's link field that marks the current page.\n- Field types: text, richtext, link (value {href}), media, select (`options`), boolean, number, date, icon, module (embedded; `accepts` = module types, absent = any), term (entries of vocabulary list `list: <slug>`).\n- Vocabulary types: one node kind with text fields `name` + `slug`.\n- `source` -> generated entries instead of stored children: {kind:'query', editable:[knobs an entry may change], defaults:{page_type, order, limit, …}} | {kind:'system', name: breadcrumbs|children|siblings|page_terms|term_pages} | {kind:'plugin', name}.\n- Mega menu: root.allow [\"column\"]; `column` {fields:[heading text], children:{name:\"links\", allow:[\"link\",\"news\"]}}; `link` {fields:[label text*, link link*], current_from:\"link\"}; `news` {fields:[heading text], source:{kind:\"query\", editable:[\"limit\"], defaults:{page_type:\"news\", order:\"published_desc\", limit:3}}} (`*` = required:true).\n- Reserved names: id, node, index, depth, first, last, items, page, site_text, recurse, is_*, has_*, count_*.\n- Changes are checked against every list of the type: a new required field needs a `default`; removing a kind/field with values is refused -> `dropValues:true` only if the operator agreed.\n- `expectedVersion` (from `list_list_types`) guards concurrent changes.",
7823
+ "description": "Create or replace list types (the SHAPE of a list).\nDO NOT USE FOR: a near-duplicate of a shipped type (reuse `links`/`menu`); changing a plugin-shipped type (create your own slug).\nCORE RULES:\n- `root.allow` = top-level node kinds. `purpose` = why the type exists (later reads decide by it). `current_from` names the node's link field that marks the current page.\n- Field types: text, richtext, link (value {href}), media, select (`options`), boolean, number, date, icon, module (embedded; `accepts` = module types, absent = any), term (entries of vocabulary list `list: <slug>`).\n- Vocabulary types: one node kind with text fields `name` + `slug`.\n- `source` -> generated entries instead of stored children: {kind:'query', editable:[knobs an entry may change], defaults:{page_type, order, limit, …}} | {kind:'system', name: breadcrumbs|children|siblings|page_terms|term_pages} | {kind:'plugin', name}.\n- Mega menu: root.allow [\"column\"]; `column` {fields:[heading text], children:{name:\"links\", allow:[\"link\",\"news\"]}}; `link` {fields:[label text*, link link*], current_from:\"link\"}; `news` {fields:[heading text], source:{kind:\"query\", editable:[\"limit\"], defaults:{page_type:\"news\", order:\"published_desc\", limit:3}}} (`*` = required:true).\n- `dropValues:true` deletes values of removed kinds/fields: only with the operator's consent.\n- `expectedVersion` (from `list_list_types`) guards concurrent changes.",
7625
7824
  "inputSchema": {
7626
7825
  "type": "object",
7627
7826
  "additionalProperties": false,
@@ -8029,7 +8228,7 @@
8029
8228
  },
8030
8229
  {
8031
8230
  "name": "upsert_page_types_many",
8032
- "description": "Create or replace page types in one transaction, when the operator starts a new kind of content ('a news section with categories', 'a job board').\nCORE RULES:\n- `templates`: ids from `list_templates`; none fits -> `create_template` WITHOUT `pageType` first, then list its id here. `defaultTemplate` is one of them.\n- `properties`: fields every page of the type carries (e.g. `author` text, `event_date` date); no `module` fields. `vocabularies[].list`: list id from `list_lists`.\n- Order for 'news with categories': `upsert_lists_many` (a `categories` list) -> `create_template` (no pageType) or reuse one -> this, with the template id -> `build_page`/`update_pages_many` with pageType, properties, terms.\n- Type in use: a new property's default is written into its pages; dropping a template they use is refused (move them first); dropping a property/vocabulary they hold values for needs `dropValues:true` (only with operator agreement). Pass `expectedVersion` from `list_page_types`.",
8231
+ "description": "Create or replace page types in one transaction, when the operator starts a new kind of content ('a news section with categories', 'a job board').\nCORE RULES:\n- `templates`: ids from `list_templates`; none fits -> `create_template` with `newPageType` instead (template + type in one call). `defaultTemplate` is one of them.\n- `properties`: fields every page of the type carries (e.g. `author` text, `event_date` date); no `module` fields. `vocabularies[].list`: list id from `list_lists`.\n- Order for 'news with categories': `upsert_lists_many` (a `categories` list) -> `create_template` with `newPageType` (or this, reusing a template) -> `build_page`/`update_pages_many` with pageType, properties, terms.\n- Type in use: a new property's default is written into its pages; dropping a template they use is refused (move them first); dropping a property/vocabulary they hold values for needs `dropValues:true` (only with operator agreement). Pass `expectedVersion` from `list_page_types`.",
8033
8232
  "inputSchema": {
8034
8233
  "type": "object",
8035
8234
  "additionalProperties": false,
@@ -8047,6 +8246,7 @@
8047
8246
  "slug",
8048
8247
  "name",
8049
8248
  "purpose",
8249
+ "collection",
8050
8250
  "templates",
8051
8251
  "defaultTemplate"
8052
8252
  ],
@@ -8060,6 +8260,10 @@
8060
8260
  "purpose": {
8061
8261
  "type": "string"
8062
8262
  },
8263
+ "collection": {
8264
+ "type": "boolean",
8265
+ "description": "true: many similar pages meant to be listed or queried (blog, news, products, jobs, docs); false: standalone pages (home, about, contact, legal, landing)."
8266
+ },
8063
8267
  "templates": {
8064
8268
  "type": "array",
8065
8269
  "items": {
@@ -8085,6 +8289,13 @@
8085
8289
  },
8086
8290
  "expectedVersion": {
8087
8291
  "type": "integer"
8292
+ },
8293
+ "distinctFrom": {
8294
+ "type": "array",
8295
+ "items": {
8296
+ "type": "string"
8297
+ },
8298
+ "description": "New type only: existing slugs it is deliberately NOT (refused as a duplicate otherwise, e.g. `blogs` next to `blog`)."
8088
8299
  }
8089
8300
  }
8090
8301
  }
@@ -8097,7 +8308,7 @@
8097
8308
  },
8098
8309
  {
8099
8310
  "name": "delete_page_types_many",
8100
- "description": "Delete page types by slug. Refused for the site's default type and while pages use it (move them first: `update_pages_many` `pageType`). Undoable.",
8311
+ "description": "Delete page types by slug. Refused while pages use it (move them first: `update_pages_many` `pageType`). Undoable.",
8101
8312
  "inputSchema": {
8102
8313
  "type": "object",
8103
8314
  "properties": {