@rubytech/create-maxy-code 0.1.243 → 0.1.246
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/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +230 -0
- package/payload/platform/neo4j/schema.cypher +0 -5
- package/payload/platform/plugins/admin/mcp/dist/index.js +3 -4
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +19 -22
- package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +38 -72
- package/payload/platform/plugins/cloudflare/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/cloudflare/PLUGIN.md +10 -7
- package/payload/platform/plugins/cloudflare/references/api.md +166 -0
- package/payload/platform/plugins/cloudflare/references/d1-data-capture.md +157 -0
- package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +6 -6
- package/payload/platform/plugins/cloudflare/references/hosting-sites.md +66 -0
- package/payload/platform/plugins/cloudflare/references/manual-setup.md +5 -3
- package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +72 -0
- package/payload/platform/plugins/docs/references/cloudflare.md +4 -4
- package/payload/platform/plugins/docs/references/deployment.md +1 -1
- package/payload/platform/plugins/docs/references/internals.md +3 -6
- package/payload/platform/plugins/memory/PLUGIN.md +2 -2
- package/payload/platform/scripts/setup-account.sh +16 -8
- 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/jsonl-tail.d.ts +12 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +7 -33
- 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 +150 -132
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +2 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +39 -6
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/templates/agents/public/IDENTITY.md +9 -62
- package/payload/platform/templates/specialists/agents/personal-assistant.md +2 -2
- package/payload/server/{chunk-ZY6W3UA2.js → chunk-JMEX5NRX.js} +1 -22
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +7 -21
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +0 -55
- package/payload/platform/templates/agents/public/SOUL.md +0 -19
- package/payload/platform/templates/agents/public/config.json +0 -9
|
@@ -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,65 @@ 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
|
+
* `LSP` (language-server code intelligence) was added by Task 614: a real
|
|
98
|
+
* `claude` capture exposes it, and the deny-list reconciliation test
|
|
99
|
+
* (public-deny-reconciliation.test.ts) flagged it as reachable-but-undenied.
|
|
100
|
+
*
|
|
101
|
+
* Maintainer note: this list and CC_FILE_PATH_TOOLS are name-only. The
|
|
102
|
+
* reconciliation test catches a NEW tool's bare-name omission, but a flat
|
|
103
|
+
* registry cannot reveal which tools take a path argument — so classifying a
|
|
104
|
+
* brand-new tool as a file tool that also needs a `(//**)` path form in
|
|
105
|
+
* CC_FILE_PATH_TOOLS remains a maintainer responsibility (Task 614). */
|
|
106
|
+
const CC_HARNESS_TOOLS = [
|
|
107
|
+
'ToolSearch', 'Monitor', 'PushNotification', 'RemoteTrigger',
|
|
108
|
+
'ScheduleWakeup', 'Workflow', 'LSP',
|
|
109
|
+
'EnterPlanMode', 'ExitPlanMode', 'EnterWorktree', 'ExitWorktree',
|
|
110
|
+
'CronCreate', 'CronDelete', 'CronList',
|
|
111
|
+
'TaskCreate', 'TaskGet', 'TaskList', 'TaskOutput', 'TaskStop', 'TaskUpdate',
|
|
112
|
+
];
|
|
113
|
+
/** Server-scoped MCP wildcard(s) for the public surface. The only MCP server a
|
|
114
|
+
* public spawn could register is the memory plugin (short prefix). */
|
|
115
|
+
const PUBLIC_DENY_MCP = ['mcp__memory__*'];
|
|
116
|
+
/** The per-spawn `permissions.deny` set for a public session (any channel):
|
|
117
|
+
* every CC native tool by bare name, a `(//**)` path form for every file tool,
|
|
118
|
+
* every harness tool by bare name, and the memory MCP server wildcard. Sorted
|
|
119
|
+
* and deduped so the emitted argv is stable and the audit test can compare. */
|
|
120
|
+
export function buildPublicDeny() {
|
|
121
|
+
const entries = [
|
|
122
|
+
...CC_NATIVE_TOOLS,
|
|
123
|
+
...CC_HARNESS_TOOLS,
|
|
124
|
+
...CC_FILE_PATH_TOOLS.map((t) => `${t}(//**)`),
|
|
125
|
+
...PUBLIC_DENY_MCP,
|
|
126
|
+
];
|
|
127
|
+
return [...new Set(entries)].sort();
|
|
128
|
+
}
|
|
70
129
|
// Task 455 — two-layer alive invariant for the `livePtys` map.
|
|
71
130
|
//
|
|
72
131
|
// Layer 1: PURGE-ON-EXIT. Both the natural-exit handler
|
|
@@ -205,51 +264,6 @@ export const HEADLESS_ROLES = new Set([
|
|
|
205
264
|
'compiled-truth-rewriter',
|
|
206
265
|
]);
|
|
207
266
|
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
267
|
/** Task 165 — read the agent's `tools:` frontmatter line from
|
|
254
268
|
* `$CLAUDE_CONFIG_DIR/agents/<specialist>.md`. Loud-fails when the file
|
|
255
269
|
* is missing or when no `tools:` line exists in the frontmatter, since
|
|
@@ -446,26 +460,11 @@ function writePerSpawnMcpConfig(p) {
|
|
|
446
460
|
for (const [name, desc] of p.toolSurface.mcpServers)
|
|
447
461
|
serversForRole.push([name, desc]);
|
|
448
462
|
}
|
|
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
|
-
}
|
|
463
|
+
// Task 615 — the public agent is toolless by construction. Its per-spawn
|
|
464
|
+
// `.mcp.json` registers ZERO servers; booting any MCP child for a surface
|
|
465
|
+
// whose `--allowed-tools` is empty and whose permissions.deny blocks every
|
|
466
|
+
// tool wastes a process and would surface tools in inventory probes the
|
|
467
|
+
// session can never call. (No `else` branch: serversForRole stays empty.)
|
|
469
468
|
// Task 142 — placeholder set includes PLATFORM_PORT (internal loopback,
|
|
470
469
|
// == MAXY_UI_INTERNAL_PORT) and MAXY_BRAND_PORT (brand-public). Both
|
|
471
470
|
// are stamped on the manager systemd unit by
|
|
@@ -787,7 +786,7 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
787
786
|
// [pty-spawn] log line emits later in this function. When the spawn is
|
|
788
787
|
// a specialist subagent we skip composeAppendSystemPrompt entirely, so
|
|
789
788
|
// those byte counts are zero — the agent file IS the prompt.
|
|
790
|
-
let composedBytes = { identity: 0, soul: 0, aboutOwner: 0, dormantPlugins: 0 };
|
|
789
|
+
let composedBytes = { identity: 0, soul: 0, knowledge: 0, aboutOwner: 0, dormantPlugins: 0 };
|
|
791
790
|
if (!isSpecialistSpawn) {
|
|
792
791
|
const composed = composeAppendSystemPrompt(composedHost, { accountDir: deps.accountDir, role: args.role }, {
|
|
793
792
|
aboutOwner: args.aboutOwner,
|
|
@@ -809,6 +808,15 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
809
808
|
const sep = composed.detail.lastIndexOf(':');
|
|
810
809
|
const file = sep > 0 ? composed.detail.slice(0, sep) : composed.detail;
|
|
811
810
|
const err = sep > 0 ? composed.detail.slice(sep + 1) : '';
|
|
811
|
+
// Task 618 — public dud refusals (empty/missing SOUL or KNOWLEDGE) carry
|
|
812
|
+
// their own reason so creation/Test-Greet names the file to author. The
|
|
813
|
+
// visitor sees an unavailable state; the dud is never served.
|
|
814
|
+
if (composed.reason === 'soul-empty' ||
|
|
815
|
+
composed.reason === 'knowledge-missing' ||
|
|
816
|
+
composed.reason === 'knowledge-empty') {
|
|
817
|
+
deps.logger(`[pty-spawn] spawn-failed reason=${composed.reason} role=public slug=${agentSlug} file=${file} err=${err}`);
|
|
818
|
+
return { ok: false, reason: composed.reason, stderrTail: composed.detail };
|
|
819
|
+
}
|
|
812
820
|
deps.logger(`[pty-spawn] spawn-failed reason=identity-unresolved accountDir=${deps.accountDir} role=${args.role} file=${file} err=${err}`);
|
|
813
821
|
return { ok: false, reason: 'identity-unresolved', stderrTail: composed.detail };
|
|
814
822
|
}
|
|
@@ -816,10 +824,18 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
816
824
|
composedBytes = {
|
|
817
825
|
identity: composed.identityBytes,
|
|
818
826
|
soul: composed.soulBytes,
|
|
827
|
+
knowledge: composed.knowledgeBytes,
|
|
819
828
|
aboutOwner: composed.aboutOwnerBytes,
|
|
820
829
|
dormantPlugins: composed.dormantPluginsBytes,
|
|
821
830
|
};
|
|
822
|
-
deps.logger(`compose-system-prompt-ok role=${args.role} accountDir=${deps.accountDir} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} identityBytes=${composed.identityBytes} soulBytes=${composed.soulBytes} aboutOwnerBytes=${composed.aboutOwnerBytes} dormantPluginsBytes=${composed.dormantPluginsBytes} pluginManifestBytes=${composed.pluginManifestBytes} specialistDomainsBytes=${composed.specialistDomainsBytes} chatSessionBytes=${composed.chatSessionBytes}`);
|
|
831
|
+
deps.logger(`compose-system-prompt-ok role=${args.role} accountDir=${deps.accountDir} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} identityBytes=${composed.identityBytes} soulBytes=${composed.soulBytes} knowledgeBytes=${composed.knowledgeBytes} aboutOwnerBytes=${composed.aboutOwnerBytes} dormantPluginsBytes=${composed.dormantPluginsBytes} pluginManifestBytes=${composed.pluginManifestBytes} specialistDomainsBytes=${composed.specialistDomainsBytes} chatSessionBytes=${composed.chatSessionBytes}`);
|
|
832
|
+
// Task 618 — one structured line per public compose carries the byte
|
|
833
|
+
// counts so "did KNOWLEDGE reach the prompt?" is answerable from logs
|
|
834
|
+
// without reproduction. knowledgeBytes=0 cannot occur on a successful
|
|
835
|
+
// public spawn (empty ⇒ refusal), so a 0 here would itself be the anomaly.
|
|
836
|
+
if (args.role === 'public') {
|
|
837
|
+
deps.logger(`[pty-spawn] op=public-prompt-compose role=public slug=${agentSlug} identityBytes=${composed.identityBytes} soulBytes=${composed.soulBytes} knowledgeBytes=${composed.knowledgeBytes}`);
|
|
838
|
+
}
|
|
823
839
|
}
|
|
824
840
|
else {
|
|
825
841
|
deps.logger(`compose-system-prompt-skipped role=${args.role} specialist=${args.specialist} reason=agent-file-is-the-prompt`);
|
|
@@ -903,44 +919,28 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
903
919
|
// tools are still READ above (jsonlTail.register consumes the array,
|
|
904
920
|
// strip-list observability still fires) but never reach argv.
|
|
905
921
|
// 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;
|
|
922
|
+
// Task 615 — every public spawn (any channel) gets ZERO tools. The per-spawn
|
|
923
|
+
// permissions.deny below is the authority; the allowlist exposes nothing and
|
|
924
|
+
// the attachment Read scope is dropped. Replaces the Task 346 liveMemory
|
|
925
|
+
// toggle, which only ever narrowed the public memory surface and is removed.
|
|
926
|
+
const isPublic = args.role === 'public';
|
|
916
927
|
const allowed = specialistTools !== null
|
|
917
928
|
? Array.from(new Set(specialistTools)).sort()
|
|
918
929
|
: (() => {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
if (isMemoryToolName(t)) {
|
|
924
|
-
publicLiveMemoryStripped += 1;
|
|
925
|
-
continue;
|
|
926
|
-
}
|
|
927
|
-
filtered.push(t);
|
|
928
|
-
}
|
|
929
|
-
return filtered.sort();
|
|
930
|
-
}
|
|
930
|
+
// Task 615 — expose nothing for any public spawn. The Task 609 sentinel
|
|
931
|
+
// below keeps --allowed-tools non-empty so dontAsk stays fail-closed.
|
|
932
|
+
if (isPublic)
|
|
933
|
+
return [];
|
|
931
934
|
// Task 579 — the admin operator spawn unions in every Claude Code
|
|
932
935
|
// native tool. The PLUGIN.md-derived `toolSurface.admin` covers only
|
|
933
936
|
// MCP tools; without this union, `--allowed-tools` is set explicitly
|
|
934
937
|
// to that subset and the CLI silently denies the built-ins (LS,
|
|
935
938
|
// 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();
|
|
939
|
+
// own disk.
|
|
940
|
+
const unioned = new Set(deps.toolSurface.admin);
|
|
941
|
+
for (const t of CC_NATIVE_TOOLS)
|
|
942
|
+
unioned.add(t);
|
|
943
|
+
return Array.from(unioned).sort();
|
|
944
944
|
})();
|
|
945
945
|
if (isSpecialistSpawn) {
|
|
946
946
|
deps.logger(`pty-spawn-allowlist specialist=${args.specialist} source=native-agent-flag count=skipped stripped=${strippedCount}`);
|
|
@@ -952,10 +952,11 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
952
952
|
const excludedSample = args.role === 'public'
|
|
953
953
|
? Array.from(deps.toolSurface.admin).filter((t) => !deps.toolSurface.public.has(t)).sort().slice(0, 5).join(',')
|
|
954
954
|
: '';
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
955
|
+
// Task 615 — every public spawn resolves an empty allowlist and denies the
|
|
956
|
+
// whole surface, so report the closed posture; the authority is the
|
|
957
|
+
// op=public-deny-injected line.
|
|
958
|
+
const memoryField = isPublic ? ` memory=denied(zero-tool-surface)` : '';
|
|
959
|
+
deps.logger(`tool-allowlist role=${args.role} count=${allowed.length} excluded=${excludedSample}${memoryField}`);
|
|
959
960
|
}
|
|
960
961
|
// Task 485 — observability for the gated/open public-spawn split. Mode
|
|
961
962
|
// is inferred from the presence of the slice token (caller's bridge has
|
|
@@ -1040,8 +1041,18 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1040
1041
|
// `webchat` — WhatsApp/Telegram share the profile but stay `default`
|
|
1041
1042
|
// pending a separate decision (Task 506 scope). An explicit
|
|
1042
1043
|
// `args.permissionMode` (operator-selected) still wins.
|
|
1043
|
-
|
|
1044
|
-
|
|
1044
|
+
// Task 612 / 615 — every public spawn is an anonymous, zero-tool surface; it
|
|
1045
|
+
// is pinned to the strictest mode and is NOT operator-overridable. Forcing
|
|
1046
|
+
// dontAsk here (rather than letting `args.permissionMode` win, as Task 506
|
|
1047
|
+
// allowed) keeps the empty-allowlist 609 sentinel reachable and prevents a
|
|
1048
|
+
// future caller from downgrading the surface to bypassPermissions, which would
|
|
1049
|
+
// skip the per-spawn permissions.deny entirely. Other roles keep the
|
|
1050
|
+
// operator-selected mode.
|
|
1051
|
+
const effectiveMode = isSpecialistSpawn
|
|
1052
|
+
? (args.permissionMode ?? 'bypassPermissions')
|
|
1053
|
+
: isPublic
|
|
1054
|
+
? 'dontAsk'
|
|
1055
|
+
: (args.permissionMode ?? 'default');
|
|
1045
1056
|
const BOTH_PROMPTS = '{"skipDangerousModePermissionPrompt":true,"skipAutoPermissionPrompt":true}';
|
|
1046
1057
|
const FLAG_SETTINGS_BY_MODE = {
|
|
1047
1058
|
bypassPermissions: BOTH_PROMPTS,
|
|
@@ -1051,7 +1062,20 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1051
1062
|
acceptEdits: BOTH_PROMPTS,
|
|
1052
1063
|
dontAsk: BOTH_PROMPTS,
|
|
1053
1064
|
};
|
|
1054
|
-
|
|
1065
|
+
let flagSettingsValue = FLAG_SETTINGS_BY_MODE[effectiveMode] ?? '';
|
|
1066
|
+
// Task 612 / 615 — merge the zero-tool-surface permissions.deny into the SAME
|
|
1067
|
+
// --settings that carries the prompt-skip keys. Measured: this per-spawn deny
|
|
1068
|
+
// beats the brand allow:["*"] (the only lever that does). The gate binds on
|
|
1069
|
+
// role=public (every channel), not on effectiveMode — an operator who
|
|
1070
|
+
// hand-picks a non-dontAsk mode for a public spawn still gets the closed
|
|
1071
|
+
// surface.
|
|
1072
|
+
if (isPublic) {
|
|
1073
|
+
const base = flagSettingsValue ? JSON.parse(flagSettingsValue) : {};
|
|
1074
|
+
const deny = buildPublicDeny();
|
|
1075
|
+
base.permissions = { ...(base.permissions ?? {}), deny };
|
|
1076
|
+
flagSettingsValue = JSON.stringify(base);
|
|
1077
|
+
deps.logger(`op=public-deny-injected count=${deny.length} tools=${deny.join(',')}`);
|
|
1078
|
+
}
|
|
1055
1079
|
if (effectiveMode !== 'default') {
|
|
1056
1080
|
argv.push('--permission-mode', effectiveMode);
|
|
1057
1081
|
}
|
|
@@ -1084,9 +1108,10 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1084
1108
|
// instructions referenced the short per-spawn name, so short-prefix calls
|
|
1085
1109
|
// failed until the model guessed the long name. Per-account env (ACCOUNT_ID,
|
|
1086
1110
|
// USER_ID, NEO4J_URI, NEO4J_PASSWORD, PLATFORM_ROOT, CLAUDE_CONFIG_DIR) rides
|
|
1087
|
-
// the PTY env block below. Public spawns
|
|
1088
|
-
//
|
|
1089
|
-
//
|
|
1111
|
+
// the PTY env block below. Public spawns keep the per-spawn write so the
|
|
1112
|
+
// toolless visitor boots ZERO MCP servers (Task 615): the written file carries
|
|
1113
|
+
// an empty `mcpServers`, and `--strict-mcp-config` below blocks auto-discovery
|
|
1114
|
+
// of any project `.mcp.json`, so no server reaches an anonymous visitor.
|
|
1090
1115
|
let mcpConfigResult = null;
|
|
1091
1116
|
if (args.role === 'public' && !isSpecialistSpawn) {
|
|
1092
1117
|
mcpConfigResult = writePerSpawnMcpConfig({
|
|
@@ -1102,7 +1127,6 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1102
1127
|
targetDir: deps.mcpConfigDir ?? tmpdir(),
|
|
1103
1128
|
logger: deps.logger,
|
|
1104
1129
|
specialistTools,
|
|
1105
|
-
liveMemory: liveMemoryEnabled,
|
|
1106
1130
|
});
|
|
1107
1131
|
if (!mcpConfigResult.ok) {
|
|
1108
1132
|
return { ok: false, reason: 'mcp-config-write-failed', stderrTail: mcpConfigResult.detail };
|
|
@@ -1139,29 +1163,23 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1139
1163
|
// visible via the plugin-manifest log chain at session start, not here.
|
|
1140
1164
|
deps.logger(`pty-spawn-mcp-config role=${args.role} specialist=${args.specialist ?? 'none'} source=installed-plugins`);
|
|
1141
1165
|
}
|
|
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.
|
|
1166
|
+
// Task 612 / 615 — every public spawn denies all native Read (no path-scoped
|
|
1167
|
+
// carve-out survives the brand allow:["*"]), so no attachment --add-dir + Read
|
|
1168
|
+
// scope is pushed on any public channel; redelivering uploads off native Read
|
|
1169
|
+
// is Task 613.
|
|
1170
|
+
// Task 609 — a public spawn runs in dontAsk (Task 506 / 615), which
|
|
1171
|
+
// fail-closes only against tools NOT in an explicit --allowed-tools. The
|
|
1172
|
+
// public surface now resolves empty on every channel (Task 615), so the loops
|
|
1173
|
+
// above push NO --allowed-tools flag, leaving dontAsk nothing to deny against
|
|
1174
|
+
// and the brand settings.json allow:["*"] re-opens every native tool to an
|
|
1175
|
+
// anonymous visitor (fail-OPEN, the c11777df repro). Anchor the closed posture
|
|
1176
|
+
// with one non-native deny-basis token: its MCP server `none` is never
|
|
1177
|
+
// registered, so it grants nothing while making --allowed-tools present and
|
|
1178
|
+
// non-empty. Native exclusion is checked by bare name against CC_NATIVE_TOOLS.
|
|
1179
|
+
// Must precede the `--` prompt sentinel below, which ends option parsing. The
|
|
1180
|
+
// guard binds on effectiveMode === 'dontAsk', not the channel — every public
|
|
1181
|
+
// spawn resolves to dontAsk, and an operator-selected dontAsk admin spawn is
|
|
1182
|
+
// anchored too; both are the correct fail-closed invariant.
|
|
1165
1183
|
if (effectiveMode === 'dontAsk') {
|
|
1166
1184
|
const emittedAllowed = [];
|
|
1167
1185
|
for (let k = 0; k < argv.length - 1; k++) {
|
|
@@ -1539,7 +1557,7 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
1539
1557
|
const responseMs = Date.now() - start;
|
|
1540
1558
|
deps.logger(`spawn-response-returned sessionId=${sessionId} pid=${pty.pid} ms=${responseMs}`);
|
|
1541
1559
|
deps.logger(`spawn pid=${pty.pid} sessionId=${sessionId} senderId=${args.senderId} role=${args.role} channel=${args.channel} permissionMode=${args.permissionMode ?? 'default'} remoteControl=${remoteControl} latency-ms=${responseMs}`);
|
|
1542
|
-
deps.logger(`[pty-spawn] sessionId=${sessionId} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} identityBytes=${composedBytes.identity} soulBytes=${composedBytes.soul} aboutOwnerBytes=${composedBytes.aboutOwner} dormantPluginsBytes=${composedBytes.dormantPlugins} accountDir=${deps.accountDir} role=${args.role} specialist=${args.specialist ?? 'none'} hostname=${deps.host.hostname} lanIPv4=${deps.host.lanIPv4} adminUrl=${deps.host.adminUrl} tunnelUrl=${composedHost.tunnelUrl ?? 'none'}`);
|
|
1560
|
+
deps.logger(`[pty-spawn] sessionId=${sessionId} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} identityBytes=${composedBytes.identity} soulBytes=${composedBytes.soul} knowledgeBytes=${composedBytes.knowledge} aboutOwnerBytes=${composedBytes.aboutOwner} dormantPluginsBytes=${composedBytes.dormantPlugins} accountDir=${deps.accountDir} role=${args.role} specialist=${args.specialist ?? 'none'} hostname=${deps.host.hostname} lanIPv4=${deps.host.lanIPv4} adminUrl=${deps.host.adminUrl} tunnelUrl=${composedHost.tunnelUrl ?? 'none'}`);
|
|
1543
1561
|
// Task 178 — emit [pty-spawn-tool-inventory] for specialist spawns. The
|
|
1544
1562
|
// probe runs in parallel with the real claude child's own MCP handshake
|
|
1545
1563
|
// and is fire-and-forget: it never blocks the spawn response, and its
|