@rubytech/create-maxy-code 0.1.243 → 0.1.244
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.
- package/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +0 -5
- package/payload/platform/plugins/admin/mcp/dist/index.js +2 -3
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +4 -7
- package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +8 -18
- package/payload/platform/plugins/docs/references/internals.md +3 -6
- package/payload/platform/plugins/memory/PLUGIN.md +2 -2
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -32
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +6 -32
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +121 -129
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/templates/agents/public/IDENTITY.md +9 -62
- package/payload/platform/templates/agents/public/config.json +0 -1
- package/payload/server/{chunk-ZY6W3UA2.js → chunk-SRO5RFMV.js} +1 -20
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +7 -21
|
@@ -7,6 +7,11 @@ import type { HostResolution } from './config.js';
|
|
|
7
7
|
import type { ToolSurface } from './tool-surface.js';
|
|
8
8
|
import type { JsonlTail } from './jsonl-tail.js';
|
|
9
9
|
import type { PermissionModeTail } from './permission-mode-tail.js';
|
|
10
|
+
/** The per-spawn `permissions.deny` set for a public session (any channel):
|
|
11
|
+
* every CC native tool by bare name, a `(//**)` path form for every file tool,
|
|
12
|
+
* every harness tool by bare name, and the memory MCP server wildcard. Sorted
|
|
13
|
+
* and deduped so the emitted argv is stable and the audit test can compare. */
|
|
14
|
+
export declare function buildPublicDeny(): string[];
|
|
10
15
|
export interface PtyTracker {
|
|
11
16
|
/** Intrinsic Claude session id. Map key, duplicated here so
|
|
12
17
|
* `forEachLive` callbacks don't need a closure over the key. */
|
|
@@ -311,17 +316,8 @@ export interface SpawnArgs {
|
|
|
311
316
|
* call. Task 153. */
|
|
312
317
|
initialMessage?: string;
|
|
313
318
|
/** Task 346 — public agent slug under `<accountDir>/agents/<slug>/`.
|
|
314
|
-
*
|
|
315
|
-
* `<accountDir>/agents/<slug>/config.json` to honour `liveMemory`. Admin
|
|
316
|
-
* spawns ignore it. */
|
|
319
|
+
* Threaded onto the spawn env as the provenance / read-scope slug. */
|
|
317
320
|
agentSlug?: string;
|
|
318
|
-
/** Task 346 — resolved from `<accountDir>/agents/<agentSlug>/config.json`'s
|
|
319
|
-
* `liveMemory` boolean by the spawn handler before composing argv. When
|
|
320
|
-
* role='public' and false, every `mcp__plugin_memory_memory__*` tool is
|
|
321
|
-
* stripped from `--allowed-tools` and the `memory` MCP server is dropped
|
|
322
|
-
* from the per-spawn `.mcp.json`. Defaults to false when absent (the
|
|
323
|
-
* doc-default for new agents). Admin spawns ignore it. */
|
|
324
|
-
liveMemory?: boolean;
|
|
325
321
|
/** Task 382 — `sessionId` UUID of the active `:AdminConversation` (or
|
|
326
322
|
* `:PublicConversation`), threaded onto both admin and specialist spawn
|
|
327
323
|
* envs as `SESSION_NODE_ID`. The memory/contacts MCP wrappers read
|
|
@@ -391,29 +387,7 @@ interface McpConfigWriteParams {
|
|
|
391
387
|
* spawn is not a specialist; the role-based admin/public projection
|
|
392
388
|
* applies. */
|
|
393
389
|
specialistTools: readonly string[] | null;
|
|
394
|
-
/** Task 346 — when role='public' and false, the `memory` MCP server is
|
|
395
|
-
* excluded from the per-spawn `.mcp.json`. Admin spawns ignore this. */
|
|
396
|
-
liveMemory: boolean;
|
|
397
390
|
}
|
|
398
|
-
/** Task 346 — plugin name (matches `platform/plugins/memory/PLUGIN.md`'s
|
|
399
|
-
* directory basename) and qualified-tool prefix that `liveMemory: false`
|
|
400
|
-
* strips from a public spawn's `--allowed-tools`. The qualified shape
|
|
401
|
-
* `mcp__${plugin}__${tool}` is the formula tool-surface.ts produces in
|
|
402
|
-
* `loadToolSurface`. */
|
|
403
|
-
export declare const MEMORY_PLUGIN_NAME = "memory";
|
|
404
|
-
export declare function isMemoryToolName(qualified: string): boolean;
|
|
405
|
-
/** Task 346 — boot-tolerant reader for `<accountDir>/agents/<slug>/config.json`'s
|
|
406
|
-
* `liveMemory` field. Mirrors `platform/ui/app/lib/claude-agent/account.ts`
|
|
407
|
-
* `resolveAgentConfig` for the one field that gates the public memory
|
|
408
|
-
* surface. Absent file, malformed JSON, or non-boolean value → false
|
|
409
|
-
* (closed-by-default), matching the documented public-agent contract:
|
|
410
|
-
* agents opt IN to memory by setting `liveMemory: true`. Returns the
|
|
411
|
-
* resolved boolean and a short reason for the spawn log so a misconfigured
|
|
412
|
-
* agent is observable rather than silently denied. */
|
|
413
|
-
export declare function resolveLiveMemory(accountDir: string, agentSlug: string): {
|
|
414
|
-
liveMemory: boolean;
|
|
415
|
-
reason: string;
|
|
416
|
-
};
|
|
417
391
|
/** Task 165 — read the agent's `tools:` frontmatter line from
|
|
418
392
|
* `$CLAUDE_CONFIG_DIR/agents/<specialist>.md`. Loud-fails when the file
|
|
419
393
|
* is missing or when no `tools:` line exists in the frontmatter, since
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAClE,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAA;AAS3B,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAA;AAC5D,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAA;AA+B7B,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,56 @@ import { CC_NATIVE_TOOLS } from './specialist-drift.js';
|
|
|
67
67
|
// so an allowlist anchored on it stays native-excluding. Its only job is to
|
|
68
68
|
// make `--allowed-tools` present and non-empty so dontAsk fails closed.
|
|
69
69
|
const DONTASK_DENY_BASIS = 'mcp__none__deny-basis';
|
|
70
|
+
// Task 612 / 615 — every public spawn gets ZERO tool surface (webchat,
|
|
71
|
+
// whatsapp, telegram). Measured on realagent-code (claude 2.1.160, brand
|
|
72
|
+
// settings.json permissions.allow:["*"]): a per-spawn permissions.deny in the
|
|
73
|
+
// same --settings as the prompt-skip keys is the ONLY lever that beats the
|
|
74
|
+
// brand allow:["*"] — a global deny:["*"] is a no-op (the `*`-vs-`*` collision
|
|
75
|
+
// resolves to allow). Bare tool names gate command tools (Bash/Skill/Task) but
|
|
76
|
+
// are no-ops for file/path tools, which need a Tool(//**) path form;
|
|
77
|
+
// deny:["Read(//**)"] is absolute over any allow, so no attachment Read
|
|
78
|
+
// carve-out survives (the carve-out is dropped — see Task 613). A server-scoped
|
|
79
|
+
// mcp__<srv>__* wildcard gates the one MCP surface a public spawn could
|
|
80
|
+
// otherwise expose (the memory plugin, short prefix mcp__memory__). The deny
|
|
81
|
+
// list is enumerative and maintained in lockstep with CC_NATIVE_TOOLS (the
|
|
82
|
+
// pty-spawner-public-deny audit test reconciles them).
|
|
83
|
+
/** File tools that need a `Tool(//**)` path form alongside their bare name —
|
|
84
|
+
* a bare deny of these is a no-op against a path-argument call. */
|
|
85
|
+
const CC_FILE_PATH_TOOLS = [
|
|
86
|
+
'Read', 'Write', 'Edit', 'MultiEdit', 'Glob', 'Grep', 'LS', 'NotebookRead', 'NotebookEdit',
|
|
87
|
+
];
|
|
88
|
+
/** Harness/agent-framework tools that exist in a live public spawn but are NOT
|
|
89
|
+
* in CC_NATIVE_TOOLS, so they are listed here and denied by bare name. Two
|
|
90
|
+
* sources: the deferred-load set (`deferred_tools_delta.addedNames` — the
|
|
91
|
+
* Cron, Enter/Exit, and Task families, Monitor, PushNotification,
|
|
92
|
+
* RemoteTrigger, plus `ToolSearch`) and the EAGER agent-framework tools
|
|
93
|
+
* `ScheduleWakeup` +
|
|
94
|
+
* `Workflow`, which the Task 612 on-device acceptance probe found still
|
|
95
|
+
* reachable after the deferred set was denied — `Workflow` spawns subagents,
|
|
96
|
+
* so leaving it open is a privilege-escalation hole, not merely extra surface. */
|
|
97
|
+
const CC_HARNESS_TOOLS = [
|
|
98
|
+
'ToolSearch', 'Monitor', 'PushNotification', 'RemoteTrigger',
|
|
99
|
+
'ScheduleWakeup', 'Workflow',
|
|
100
|
+
'EnterPlanMode', 'ExitPlanMode', 'EnterWorktree', 'ExitWorktree',
|
|
101
|
+
'CronCreate', 'CronDelete', 'CronList',
|
|
102
|
+
'TaskCreate', 'TaskGet', 'TaskList', 'TaskOutput', 'TaskStop', 'TaskUpdate',
|
|
103
|
+
];
|
|
104
|
+
/** Server-scoped MCP wildcard(s) for the public surface. The only MCP server a
|
|
105
|
+
* public spawn could register is the memory plugin (short prefix). */
|
|
106
|
+
const PUBLIC_DENY_MCP = ['mcp__memory__*'];
|
|
107
|
+
/** The per-spawn `permissions.deny` set for a public session (any channel):
|
|
108
|
+
* every CC native tool by bare name, a `(//**)` path form for every file tool,
|
|
109
|
+
* every harness tool by bare name, and the memory MCP server wildcard. Sorted
|
|
110
|
+
* and deduped so the emitted argv is stable and the audit test can compare. */
|
|
111
|
+
export function buildPublicDeny() {
|
|
112
|
+
const entries = [
|
|
113
|
+
...CC_NATIVE_TOOLS,
|
|
114
|
+
...CC_HARNESS_TOOLS,
|
|
115
|
+
...CC_FILE_PATH_TOOLS.map((t) => `${t}(//**)`),
|
|
116
|
+
...PUBLIC_DENY_MCP,
|
|
117
|
+
];
|
|
118
|
+
return [...new Set(entries)].sort();
|
|
119
|
+
}
|
|
70
120
|
// Task 455 — two-layer alive invariant for the `livePtys` map.
|
|
71
121
|
//
|
|
72
122
|
// Layer 1: PURGE-ON-EXIT. Both the natural-exit handler
|
|
@@ -205,51 +255,6 @@ export const HEADLESS_ROLES = new Set([
|
|
|
205
255
|
'compiled-truth-rewriter',
|
|
206
256
|
]);
|
|
207
257
|
export const PERMISSION_MODES = ['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions', 'dontAsk'];
|
|
208
|
-
/** Task 346 — plugin name (matches `platform/plugins/memory/PLUGIN.md`'s
|
|
209
|
-
* directory basename) and qualified-tool prefix that `liveMemory: false`
|
|
210
|
-
* strips from a public spawn's `--allowed-tools`. The qualified shape
|
|
211
|
-
* `mcp__${plugin}__${tool}` is the formula tool-surface.ts produces in
|
|
212
|
-
* `loadToolSurface`. */
|
|
213
|
-
export const MEMORY_PLUGIN_NAME = 'memory';
|
|
214
|
-
const MEMORY_TOOL_PREFIX = `mcp__${MEMORY_PLUGIN_NAME}__`;
|
|
215
|
-
export function isMemoryToolName(qualified) {
|
|
216
|
-
return qualified.startsWith(MEMORY_TOOL_PREFIX);
|
|
217
|
-
}
|
|
218
|
-
/** Task 346 — boot-tolerant reader for `<accountDir>/agents/<slug>/config.json`'s
|
|
219
|
-
* `liveMemory` field. Mirrors `platform/ui/app/lib/claude-agent/account.ts`
|
|
220
|
-
* `resolveAgentConfig` for the one field that gates the public memory
|
|
221
|
-
* surface. Absent file, malformed JSON, or non-boolean value → false
|
|
222
|
-
* (closed-by-default), matching the documented public-agent contract:
|
|
223
|
-
* agents opt IN to memory by setting `liveMemory: true`. Returns the
|
|
224
|
-
* resolved boolean and a short reason for the spawn log so a misconfigured
|
|
225
|
-
* agent is observable rather than silently denied. */
|
|
226
|
-
export function resolveLiveMemory(accountDir, agentSlug) {
|
|
227
|
-
const path = join(accountDir, 'agents', agentSlug, 'config.json');
|
|
228
|
-
if (!existsSync(path))
|
|
229
|
-
return { liveMemory: false, reason: 'config-missing' };
|
|
230
|
-
let raw;
|
|
231
|
-
try {
|
|
232
|
-
raw = readFileSync(path, 'utf8');
|
|
233
|
-
}
|
|
234
|
-
catch (err) {
|
|
235
|
-
const m = err instanceof Error ? err.message : String(err);
|
|
236
|
-
return { liveMemory: false, reason: `read-failed:${m}` };
|
|
237
|
-
}
|
|
238
|
-
let parsed;
|
|
239
|
-
try {
|
|
240
|
-
parsed = JSON.parse(raw);
|
|
241
|
-
}
|
|
242
|
-
catch {
|
|
243
|
-
return { liveMemory: false, reason: 'invalid-json' };
|
|
244
|
-
}
|
|
245
|
-
if (typeof parsed.liveMemory === 'boolean') {
|
|
246
|
-
return { liveMemory: parsed.liveMemory, reason: 'config' };
|
|
247
|
-
}
|
|
248
|
-
if (parsed.liveMemory === undefined || parsed.liveMemory === null) {
|
|
249
|
-
return { liveMemory: false, reason: 'config-default' };
|
|
250
|
-
}
|
|
251
|
-
return { liveMemory: false, reason: `invalid-type:${typeof parsed.liveMemory}` };
|
|
252
|
-
}
|
|
253
258
|
/** Task 165 — read the agent's `tools:` frontmatter line from
|
|
254
259
|
* `$CLAUDE_CONFIG_DIR/agents/<specialist>.md`. Loud-fails when the file
|
|
255
260
|
* is missing or when no `tools:` line exists in the frontmatter, since
|
|
@@ -446,26 +451,11 @@ function writePerSpawnMcpConfig(p) {
|
|
|
446
451
|
for (const [name, desc] of p.toolSurface.mcpServers)
|
|
447
452
|
serversForRole.push([name, desc]);
|
|
448
453
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
publicPluginNames.add(m[1]);
|
|
455
|
-
}
|
|
456
|
-
// Task 346 — `liveMemory: false` drops the memory MCP server from the
|
|
457
|
-
// per-spawn `.mcp.json` in lockstep with the allowlist strip below.
|
|
458
|
-
// Booting the server only to have its tools filtered out wastes a
|
|
459
|
-
// child process and confuses the log: tool-inventory probes would
|
|
460
|
-
// still see memory-search exposed by the server while
|
|
461
|
-
// `--allowed-tools` refuses it.
|
|
462
|
-
if (!p.liveMemory)
|
|
463
|
-
publicPluginNames.delete(MEMORY_PLUGIN_NAME);
|
|
464
|
-
for (const [name, desc] of p.toolSurface.mcpServers) {
|
|
465
|
-
if (publicPluginNames.has(name))
|
|
466
|
-
serversForRole.push([name, desc]);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
454
|
+
// Task 615 — the public agent is toolless by construction. Its per-spawn
|
|
455
|
+
// `.mcp.json` registers ZERO servers; booting any MCP child for a surface
|
|
456
|
+
// whose `--allowed-tools` is empty and whose permissions.deny blocks every
|
|
457
|
+
// tool wastes a process and would surface tools in inventory probes the
|
|
458
|
+
// session can never call. (No `else` branch: serversForRole stays empty.)
|
|
469
459
|
// Task 142 — placeholder set includes PLATFORM_PORT (internal loopback,
|
|
470
460
|
// == MAXY_UI_INTERNAL_PORT) and MAXY_BRAND_PORT (brand-public). Both
|
|
471
461
|
// are stamped on the manager systemd unit by
|
|
@@ -903,44 +893,28 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
903
893
|
// tools are still READ above (jsonlTail.register consumes the array,
|
|
904
894
|
// strip-list observability still fires) but never reach argv.
|
|
905
895
|
// Operator (non-specialist) spawns retain the role-based push.
|
|
906
|
-
// Task
|
|
907
|
-
//
|
|
908
|
-
//
|
|
909
|
-
//
|
|
910
|
-
|
|
911
|
-
// default `resolveAgentConfig` uses) so spawns that arrive without a
|
|
912
|
-
// resolved value never silently widen the surface. Admin spawns are
|
|
913
|
-
// untouched.
|
|
914
|
-
const liveMemoryEnabled = args.role === 'public' ? (args.liveMemory === true) : true;
|
|
915
|
-
let publicLiveMemoryStripped = 0;
|
|
896
|
+
// Task 615 — every public spawn (any channel) gets ZERO tools. The per-spawn
|
|
897
|
+
// permissions.deny below is the authority; the allowlist exposes nothing and
|
|
898
|
+
// the attachment Read scope is dropped. Replaces the Task 346 liveMemory
|
|
899
|
+
// toggle, which only ever narrowed the public memory surface and is removed.
|
|
900
|
+
const isPublic = args.role === 'public';
|
|
916
901
|
const allowed = specialistTools !== null
|
|
917
902
|
? Array.from(new Set(specialistTools)).sort()
|
|
918
903
|
: (() => {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
if (isMemoryToolName(t)) {
|
|
924
|
-
publicLiveMemoryStripped += 1;
|
|
925
|
-
continue;
|
|
926
|
-
}
|
|
927
|
-
filtered.push(t);
|
|
928
|
-
}
|
|
929
|
-
return filtered.sort();
|
|
930
|
-
}
|
|
904
|
+
// Task 615 — expose nothing for any public spawn. The Task 609 sentinel
|
|
905
|
+
// below keeps --allowed-tools non-empty so dontAsk stays fail-closed.
|
|
906
|
+
if (isPublic)
|
|
907
|
+
return [];
|
|
931
908
|
// Task 579 — the admin operator spawn unions in every Claude Code
|
|
932
909
|
// native tool. The PLUGIN.md-derived `toolSurface.admin` covers only
|
|
933
910
|
// MCP tools; without this union, `--allowed-tools` is set explicitly
|
|
934
911
|
// to that subset and the CLI silently denies the built-ins (LS,
|
|
935
912
|
// Glob, Read, Bash, …), so the admin seat could not enumerate its
|
|
936
|
-
// own disk.
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
return Array.from(unioned).sort();
|
|
942
|
-
}
|
|
943
|
-
return Array.from(base).sort();
|
|
913
|
+
// own disk.
|
|
914
|
+
const unioned = new Set(deps.toolSurface.admin);
|
|
915
|
+
for (const t of CC_NATIVE_TOOLS)
|
|
916
|
+
unioned.add(t);
|
|
917
|
+
return Array.from(unioned).sort();
|
|
944
918
|
})();
|
|
945
919
|
if (isSpecialistSpawn) {
|
|
946
920
|
deps.logger(`pty-spawn-allowlist specialist=${args.specialist} source=native-agent-flag count=skipped stripped=${strippedCount}`);
|
|
@@ -952,10 +926,11 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
952
926
|
const excludedSample = args.role === 'public'
|
|
953
927
|
? Array.from(deps.toolSurface.admin).filter((t) => !deps.toolSurface.public.has(t)).sort().slice(0, 5).join(',')
|
|
954
928
|
: '';
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
929
|
+
// Task 615 — every public spawn resolves an empty allowlist and denies the
|
|
930
|
+
// whole surface, so report the closed posture; the authority is the
|
|
931
|
+
// op=public-deny-injected line.
|
|
932
|
+
const memoryField = isPublic ? ` memory=denied(zero-tool-surface)` : '';
|
|
933
|
+
deps.logger(`tool-allowlist role=${args.role} count=${allowed.length} excluded=${excludedSample}${memoryField}`);
|
|
959
934
|
}
|
|
960
935
|
// Task 485 — observability for the gated/open public-spawn split. Mode
|
|
961
936
|
// is inferred from the presence of the slice token (caller's bridge has
|
|
@@ -1040,8 +1015,18 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1040
1015
|
// `webchat` — WhatsApp/Telegram share the profile but stay `default`
|
|
1041
1016
|
// pending a separate decision (Task 506 scope). An explicit
|
|
1042
1017
|
// `args.permissionMode` (operator-selected) still wins.
|
|
1043
|
-
|
|
1044
|
-
|
|
1018
|
+
// Task 612 / 615 — every public spawn is an anonymous, zero-tool surface; it
|
|
1019
|
+
// is pinned to the strictest mode and is NOT operator-overridable. Forcing
|
|
1020
|
+
// dontAsk here (rather than letting `args.permissionMode` win, as Task 506
|
|
1021
|
+
// allowed) keeps the empty-allowlist 609 sentinel reachable and prevents a
|
|
1022
|
+
// future caller from downgrading the surface to bypassPermissions, which would
|
|
1023
|
+
// skip the per-spawn permissions.deny entirely. Other roles keep the
|
|
1024
|
+
// operator-selected mode.
|
|
1025
|
+
const effectiveMode = isSpecialistSpawn
|
|
1026
|
+
? (args.permissionMode ?? 'bypassPermissions')
|
|
1027
|
+
: isPublic
|
|
1028
|
+
? 'dontAsk'
|
|
1029
|
+
: (args.permissionMode ?? 'default');
|
|
1045
1030
|
const BOTH_PROMPTS = '{"skipDangerousModePermissionPrompt":true,"skipAutoPermissionPrompt":true}';
|
|
1046
1031
|
const FLAG_SETTINGS_BY_MODE = {
|
|
1047
1032
|
bypassPermissions: BOTH_PROMPTS,
|
|
@@ -1051,7 +1036,20 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1051
1036
|
acceptEdits: BOTH_PROMPTS,
|
|
1052
1037
|
dontAsk: BOTH_PROMPTS,
|
|
1053
1038
|
};
|
|
1054
|
-
|
|
1039
|
+
let flagSettingsValue = FLAG_SETTINGS_BY_MODE[effectiveMode] ?? '';
|
|
1040
|
+
// Task 612 / 615 — merge the zero-tool-surface permissions.deny into the SAME
|
|
1041
|
+
// --settings that carries the prompt-skip keys. Measured: this per-spawn deny
|
|
1042
|
+
// beats the brand allow:["*"] (the only lever that does). The gate binds on
|
|
1043
|
+
// role=public (every channel), not on effectiveMode — an operator who
|
|
1044
|
+
// hand-picks a non-dontAsk mode for a public spawn still gets the closed
|
|
1045
|
+
// surface.
|
|
1046
|
+
if (isPublic) {
|
|
1047
|
+
const base = flagSettingsValue ? JSON.parse(flagSettingsValue) : {};
|
|
1048
|
+
const deny = buildPublicDeny();
|
|
1049
|
+
base.permissions = { ...(base.permissions ?? {}), deny };
|
|
1050
|
+
flagSettingsValue = JSON.stringify(base);
|
|
1051
|
+
deps.logger(`op=public-deny-injected count=${deny.length} tools=${deny.join(',')}`);
|
|
1052
|
+
}
|
|
1055
1053
|
if (effectiveMode !== 'default') {
|
|
1056
1054
|
argv.push('--permission-mode', effectiveMode);
|
|
1057
1055
|
}
|
|
@@ -1084,9 +1082,10 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1084
1082
|
// instructions referenced the short per-spawn name, so short-prefix calls
|
|
1085
1083
|
// failed until the model guessed the long name. Per-account env (ACCOUNT_ID,
|
|
1086
1084
|
// USER_ID, NEO4J_URI, NEO4J_PASSWORD, PLATFORM_ROOT, CLAUDE_CONFIG_DIR) rides
|
|
1087
|
-
// the PTY env block below. Public spawns
|
|
1088
|
-
//
|
|
1089
|
-
//
|
|
1085
|
+
// the PTY env block below. Public spawns keep the per-spawn write so the
|
|
1086
|
+
// toolless visitor boots ZERO MCP servers (Task 615): the written file carries
|
|
1087
|
+
// an empty `mcpServers`, and `--strict-mcp-config` below blocks auto-discovery
|
|
1088
|
+
// of any project `.mcp.json`, so no server reaches an anonymous visitor.
|
|
1090
1089
|
let mcpConfigResult = null;
|
|
1091
1090
|
if (args.role === 'public' && !isSpecialistSpawn) {
|
|
1092
1091
|
mcpConfigResult = writePerSpawnMcpConfig({
|
|
@@ -1102,7 +1101,6 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1102
1101
|
targetDir: deps.mcpConfigDir ?? tmpdir(),
|
|
1103
1102
|
logger: deps.logger,
|
|
1104
1103
|
specialistTools,
|
|
1105
|
-
liveMemory: liveMemoryEnabled,
|
|
1106
1104
|
});
|
|
1107
1105
|
if (!mcpConfigResult.ok) {
|
|
1108
1106
|
return { ok: false, reason: 'mcp-config-write-failed', stderrTail: mcpConfigResult.detail };
|
|
@@ -1139,29 +1137,23 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1139
1137
|
// visible via the plugin-manifest log chain at session start, not here.
|
|
1140
1138
|
deps.logger(`pty-spawn-mcp-config role=${args.role} specialist=${args.specialist ?? 'none'} source=installed-plugins`);
|
|
1141
1139
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
//
|
|
1148
|
-
//
|
|
1149
|
-
//
|
|
1150
|
-
//
|
|
1151
|
-
//
|
|
1152
|
-
//
|
|
1153
|
-
//
|
|
1154
|
-
// non-
|
|
1155
|
-
//
|
|
1156
|
-
// guard
|
|
1157
|
-
//
|
|
1158
|
-
//
|
|
1159
|
-
// bare name against CC_NATIVE_TOOLS: the path-scoped Read(<dir>/**) attachment
|
|
1160
|
-
// entry is the documented Task 506 carve-out, not the unrestricted native
|
|
1161
|
-
// Read. Must precede the `--` prompt sentinel below, which ends option parsing.
|
|
1162
|
-
// The guard binds on effectiveMode === 'dontAsk', not the channel — public
|
|
1163
|
-
// webchat always resolves to dontAsk, and an operator-selected dontAsk admin
|
|
1164
|
-
// spawn is anchored too; both are the correct fail-closed invariant.
|
|
1140
|
+
// Task 612 / 615 — every public spawn denies all native Read (no path-scoped
|
|
1141
|
+
// carve-out survives the brand allow:["*"]), so no attachment --add-dir + Read
|
|
1142
|
+
// scope is pushed on any public channel; redelivering uploads off native Read
|
|
1143
|
+
// is Task 613.
|
|
1144
|
+
// Task 609 — a public spawn runs in dontAsk (Task 506 / 615), which
|
|
1145
|
+
// fail-closes only against tools NOT in an explicit --allowed-tools. The
|
|
1146
|
+
// public surface now resolves empty on every channel (Task 615), so the loops
|
|
1147
|
+
// above push NO --allowed-tools flag, leaving dontAsk nothing to deny against
|
|
1148
|
+
// and the brand settings.json allow:["*"] re-opens every native tool to an
|
|
1149
|
+
// anonymous visitor (fail-OPEN, the c11777df repro). Anchor the closed posture
|
|
1150
|
+
// with one non-native deny-basis token: its MCP server `none` is never
|
|
1151
|
+
// registered, so it grants nothing while making --allowed-tools present and
|
|
1152
|
+
// non-empty. Native exclusion is checked by bare name against CC_NATIVE_TOOLS.
|
|
1153
|
+
// Must precede the `--` prompt sentinel below, which ends option parsing. The
|
|
1154
|
+
// guard binds on effectiveMode === 'dontAsk', not the channel — every public
|
|
1155
|
+
// spawn resolves to dontAsk, and an operator-selected dontAsk admin spawn is
|
|
1156
|
+
// anchored too; both are the correct fail-closed invariant.
|
|
1165
1157
|
if (effectiveMode === 'dontAsk') {
|
|
1166
1158
|
const emittedAllowed = [];
|
|
1167
1159
|
for (let k = 0; k < argv.length - 1; k++) {
|