@rubytech/create-maxy-code 0.1.62 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/__tests__/installer-specialist-registration.test.js +112 -0
  2. package/dist/index.js +22 -0
  3. package/dist/specialist-registration.js +78 -0
  4. package/package.json +1 -1
  5. package/payload/platform/plugins/admin/PLUGIN.md +22 -0
  6. package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +50 -13
  7. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +22 -21
  8. package/payload/platform/plugins/contacts/PLUGIN.md +9 -0
  9. package/payload/platform/plugins/docs/references/admin-session.md +55 -7
  10. package/payload/platform/plugins/email/PLUGIN.md +9 -0
  11. package/payload/platform/plugins/epc/PLUGIN.md +5 -0
  12. package/payload/platform/plugins/loop/PLUGIN.md +27 -0
  13. package/payload/platform/plugins/memory/PLUGIN.md +37 -0
  14. package/payload/platform/plugins/memory/mcp/dist/index.js +3 -3
  15. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  16. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js +137 -75
  17. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js.map +1 -1
  18. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts +0 -17
  19. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts.map +1 -1
  20. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js +32 -4
  21. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +65 -0
  23. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -0
  24. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +182 -0
  25. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -0
  26. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +8 -8
  27. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
  28. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts +2 -0
  29. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts.map +1 -0
  30. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js +241 -0
  31. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js.map +1 -0
  32. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
  33. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +9 -0
  34. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  35. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts +1 -1
  36. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts.map +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js +9 -1
  38. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts.map +1 -1
  40. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js +10 -2
  41. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js.map +1 -1
  42. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts +1 -1
  43. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts.map +1 -1
  44. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js +5 -1
  45. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js.map +1 -1
  46. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts +1 -1
  47. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts.map +1 -1
  48. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js +5 -1
  49. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js.map +1 -1
  50. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  51. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +4 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  53. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts.map +1 -1
  54. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +4 -0
  55. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js.map +1 -1
  56. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts.map +1 -1
  57. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +4 -0
  58. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
  59. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.d.ts.map +1 -1
  60. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js +4 -0
  61. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js.map +1 -1
  62. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
  63. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +4 -0
  64. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
  65. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.d.ts.map +1 -1
  66. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +4 -0
  67. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js.map +1 -1
  68. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.d.ts.map +1 -1
  69. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js +4 -0
  70. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js.map +1 -1
  71. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  72. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +5 -0
  73. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  74. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
  75. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +4 -0
  76. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
  77. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.d.ts.map +1 -1
  78. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js +4 -0
  79. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js.map +1 -1
  80. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.d.ts.map +1 -1
  81. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js +4 -0
  82. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js.map +1 -1
  83. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
  84. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +5 -0
  85. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
  86. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  87. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +6 -0
  88. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  89. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts.map +1 -1
  90. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js +4 -0
  91. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js.map +1 -1
  92. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  93. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +4 -0
  94. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  95. package/payload/platform/plugins/memory/mcp/vitest.config.ts +10 -3
  96. package/payload/platform/plugins/outlook/PLUGIN.md +7 -0
  97. package/payload/platform/plugins/preval/.claude-plugin/plugin.json +1 -1
  98. package/payload/platform/plugins/preval/PLUGIN.md +16 -8
  99. package/payload/platform/plugins/preval/hooks/preval-prompt-required.sh +140 -0
  100. package/payload/platform/plugins/preval/skills/property-preval/SKILL.md +44 -14
  101. package/payload/platform/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
  102. package/payload/platform/plugins/preval/skills/property-preval/references/render.py +247 -62
  103. package/payload/platform/plugins/preval/skills/property-preval/references/template-inputs.schema.json +29 -19
  104. package/payload/platform/plugins/property-data/PLUGIN.md +22 -0
  105. package/payload/platform/plugins/replicate/PLUGIN.md +3 -0
  106. package/payload/platform/plugins/scheduling/PLUGIN.md +8 -0
  107. package/payload/platform/plugins/tasks/PLUGIN.md +14 -0
  108. package/payload/platform/plugins/telegram/PLUGIN.md +3 -0
  109. package/payload/platform/plugins/waitlist/PLUGIN.md +7 -0
  110. package/payload/platform/plugins/whatsapp/PLUGIN.md +12 -0
  111. package/payload/platform/plugins/workflows/PLUGIN.md +8 -0
  112. package/payload/platform/services/claude-session-manager/dist/index.js +39 -1
  113. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  114. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +21 -0
  115. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  116. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +148 -41
  117. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  118. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +23 -0
  119. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -0
  120. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +141 -0
  121. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -0
  122. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +13 -2
  123. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
  124. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +135 -37
  125. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  126. package/payload/premium-plugins/real-agent/agents/compliance.md +1 -1
  127. package/payload/premium-plugins/real-agent/plugins/epc/PLUGIN.md +5 -0
  128. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +27 -0
  129. package/payload/premium-plugins/real-agent/plugins/preval/.claude-plugin/plugin.json +1 -1
  130. package/payload/premium-plugins/real-agent/plugins/preval/PLUGIN.md +16 -8
  131. package/payload/premium-plugins/real-agent/plugins/preval/hooks/preval-prompt-required.sh +140 -0
  132. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/SKILL.md +44 -14
  133. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
  134. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/render.py +247 -62
  135. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template-inputs.schema.json +29 -19
  136. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +22 -0
  137. package/payload/server/public/assets/{admin-DhN3G8W7.js → admin-ymReS1mN.js} +1 -1
  138. package/payload/server/public/assets/{data-B2ZVXOcE.js → data-D6U2e85B.js} +1 -1
  139. package/payload/server/public/assets/{graph-BAMGPHrK.js → graph-C274PN27.js} +1 -1
  140. package/payload/server/public/assets/{graph-labels-D9eBbvxo.js → graph-labels-DQFzd1FY.js} +1 -1
  141. package/payload/server/public/assets/{page-DjdVMWCz.js → page-D-OLjort.js} +1 -1
  142. package/payload/server/public/assets/{page-CV27Al6Z.js → page-DFFt9_Q0.js} +1 -1
  143. package/payload/server/public/data.html +3 -3
  144. package/payload/server/public/graph.html +3 -3
  145. package/payload/server/public/index.html +4 -4
  146. package/payload/server/server.js +1 -1
@@ -4,10 +4,13 @@ description: "Image generation via Replicate — three models for different prod
4
4
  tools:
5
5
  - name: image-generate
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: replicate-key-store
8
9
  publicAllowlist: false
10
+ adminAllowlist: true
9
11
  - name: replicate-key-verify
10
12
  publicAllowlist: false
13
+ adminAllowlist: true
11
14
  metadata: {"platform":{"optional":true,"recommended":true,"pluginKey":"replicate"}}
12
15
  mcp:
13
16
  command: node
@@ -4,20 +4,28 @@ description: "Calendar and scheduling — create events, manage appointments, se
4
4
  tools:
5
5
  - name: schedule-event
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: schedule-list
8
9
  publicAllowlist: false
10
+ adminAllowlist: false
9
11
  - name: schedule-get
10
12
  publicAllowlist: false
13
+ adminAllowlist: false
11
14
  - name: schedule-update
12
15
  publicAllowlist: false
16
+ adminAllowlist: false
13
17
  - name: schedule-cancel
14
18
  publicAllowlist: false
19
+ adminAllowlist: false
15
20
  - name: schedule-export-ics
16
21
  publicAllowlist: false
22
+ adminAllowlist: false
17
23
  - name: schedule-import-ics
18
24
  publicAllowlist: false
25
+ adminAllowlist: false
19
26
  - name: time-resolve
20
27
  publicAllowlist: false
28
+ adminAllowlist: true
21
29
  skills:
22
30
  - skills/daily-prep/SKILL.md
23
31
  - skills/briefing/SKILL.md
@@ -4,32 +4,46 @@ description: "Graph-backed task lifecycle management. Task nodes in Neo4j with d
4
4
  tools:
5
5
  - name: task-create
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: task-update
8
9
  publicAllowlist: false
10
+ adminAllowlist: false
9
11
  - name: task-list
10
12
  publicAllowlist: false
13
+ adminAllowlist: false
11
14
  - name: task-get
12
15
  publicAllowlist: false
16
+ adminAllowlist: false
13
17
  - name: task-relate
14
18
  publicAllowlist: false
19
+ adminAllowlist: false
15
20
  - name: task-complete
16
21
  publicAllowlist: false
22
+ adminAllowlist: false
17
23
  - name: task-ready
18
24
  publicAllowlist: false
25
+ adminAllowlist: false
19
26
  - name: session-list
20
27
  publicAllowlist: false
28
+ adminAllowlist: false
21
29
  - name: session-name
22
30
  publicAllowlist: false
31
+ adminAllowlist: false
23
32
  - name: project-create
24
33
  publicAllowlist: false
34
+ adminAllowlist: false
25
35
  - name: project-list
26
36
  publicAllowlist: false
37
+ adminAllowlist: false
27
38
  - name: project-get
28
39
  publicAllowlist: false
40
+ adminAllowlist: false
29
41
  - name: project-update
30
42
  publicAllowlist: false
43
+ adminAllowlist: false
31
44
  - name: project-complete
32
45
  publicAllowlist: false
46
+ adminAllowlist: false
33
47
  metadata: {"platform":{"always":false,"embed":[],"pluginKey":"tasks"}}
34
48
  mcp:
35
49
  command: node
@@ -5,10 +5,13 @@ metadata: {"platform":{"optional":true}}
5
5
  tools:
6
6
  - name: message
7
7
  publicAllowlist: false
8
+ adminAllowlist: false
8
9
  - name: message-history
9
10
  publicAllowlist: false
11
+ adminAllowlist: false
10
12
  - name: telegram-webhook-register
11
13
  publicAllowlist: false
14
+ adminAllowlist: false
12
15
  mcp:
13
16
  command: node
14
17
  args:
@@ -4,18 +4,25 @@ description: "Waitlist lifecycle — workflow-based extraction from public conve
4
4
  tools:
5
5
  - name: waitlist-scan
6
6
  publicAllowlist: false
7
+ adminAllowlist: true
7
8
  - name: waitlist-extract
8
9
  publicAllowlist: false
10
+ adminAllowlist: true
9
11
  - name: waitlist-persist
10
12
  publicAllowlist: false
13
+ adminAllowlist: true
11
14
  - name: waitlist-list
12
15
  publicAllowlist: false
16
+ adminAllowlist: true
13
17
  - name: waitlist-review
14
18
  publicAllowlist: false
19
+ adminAllowlist: true
15
20
  - name: waitlist-setup
16
21
  publicAllowlist: false
22
+ adminAllowlist: true
17
23
  - name: waitlist-heal
18
24
  publicAllowlist: false
25
+ adminAllowlist: true
19
26
  always: false
20
27
  embed: false
21
28
  lifecycle: {"activate": "waitlist-setup", "heal": "waitlist-heal"}
@@ -4,28 +4,40 @@ description: WhatsApp messaging channel — Baileys QR pairing, DM/group policy
4
4
  tools:
5
5
  - name: whatsapp-login-start
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: whatsapp-login-wait
8
9
  publicAllowlist: false
10
+ adminAllowlist: false
9
11
  - name: whatsapp-status
10
12
  publicAllowlist: false
13
+ adminAllowlist: false
11
14
  - name: whatsapp-disconnect
12
15
  publicAllowlist: false
16
+ adminAllowlist: false
13
17
  - name: whatsapp-send
14
18
  publicAllowlist: false
19
+ adminAllowlist: false
15
20
  - name: whatsapp-send-document
16
21
  publicAllowlist: false
22
+ adminAllowlist: false
17
23
  - name: whatsapp-config
18
24
  publicAllowlist: false
25
+ adminAllowlist: false
19
26
  - name: whatsapp-activity
20
27
  publicAllowlist: false
28
+ adminAllowlist: false
21
29
  - name: whatsapp-conversations
22
30
  publicAllowlist: false
31
+ adminAllowlist: false
23
32
  - name: whatsapp-messages
24
33
  publicAllowlist: false
34
+ adminAllowlist: false
25
35
  - name: whatsapp-conversation-graph-state
26
36
  publicAllowlist: false
37
+ adminAllowlist: false
27
38
  - name: whatsapp-group-info
28
39
  publicAllowlist: false
40
+ adminAllowlist: false
29
41
  metadata: {"platform":{"embed":["admin"]}}
30
42
  mcp:
31
43
  command: node
@@ -4,20 +4,28 @@ description: "Structured executable workflows. Named compositions of MCP tool ca
4
4
  tools:
5
5
  - name: workflow-create
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: workflow-list
8
9
  publicAllowlist: false
10
+ adminAllowlist: false
9
11
  - name: workflow-get
10
12
  publicAllowlist: false
13
+ adminAllowlist: false
11
14
  - name: workflow-update
12
15
  publicAllowlist: false
16
+ adminAllowlist: false
13
17
  - name: workflow-delete
14
18
  publicAllowlist: false
19
+ adminAllowlist: false
15
20
  - name: workflow-validate
16
21
  publicAllowlist: false
22
+ adminAllowlist: false
17
23
  - name: workflow-execute
18
24
  publicAllowlist: false
25
+ adminAllowlist: false
19
26
  - name: workflow-runs
20
27
  publicAllowlist: false
28
+ adminAllowlist: false
21
29
  metadata: {"platform":{"always":false,"embed":[],"pluginKey":"workflows"}}
22
30
  mcp:
23
31
  command: node
@@ -12,6 +12,7 @@ import { createFsWatcher } from './fs-watcher.js';
12
12
  import { createReaper } from './reaper.js';
13
13
  import { projectsDirForCwd, sessionsDir } from './jsonl-path.js';
14
14
  import { runSystemPromptSelfTest, runIdentityDriftAssertion } from './system-prompt.js';
15
+ import { assertSpecialistDrift } from './specialist-drift.js';
15
16
  const TAG = '[claude-session-manager]';
16
17
  const log = (line) => console.log(`${TAG} ${line}`);
17
18
  function spawnPtyAdapter(cmd, args, env, cwd) {
@@ -68,7 +69,14 @@ async function main() {
68
69
  }
69
70
  process.exit(1);
70
71
  }
71
- log(`tool-surface admin=${toolSurface.admin.size} public=${toolSurface.public.size} mcpServers=${toolSurface.mcpServers.size}`);
72
+ log(`tool-surface admin=${toolSurface.admin.size} public=${toolSurface.public.size} all=${toolSurface.all.size} mcpServers=${toolSurface.mcpServers.size}`);
73
+ // Sanity ceiling — not a cap. Task 164 set the admin surface to a
74
+ // routing-only residual; if a future PLUGIN.md edit floods the admin
75
+ // allowlist we want one log line above the operator's eye-line rather
76
+ // than a silent return-to-2026.
77
+ if (toolSurface.admin.size > 50) {
78
+ log(`tool-surface-admin-too-wide count=${toolSurface.admin.size}`);
79
+ }
72
80
  // Boot gate — every admin-allowlist tool `mcp__<plugin>__*` must have a
73
81
  // server descriptor under the same plugin key. The reverse failure mode
74
82
  // (server registered with no allowlisted tool) is harmless — the LLM never
@@ -116,8 +124,37 @@ async function main() {
116
124
  log(`agents-dir-bundled path=${candidate}`);
117
125
  }
118
126
  }
127
+ // Boot-time specialist-drift assertion. Each specialist `.md` declares
128
+ // its tool surface as a comma-separated frontmatter line; a name that
129
+ // does not resolve to a known plugin tool, a CC-native tool, or an
130
+ // MCP-bridge namespace is silent "tool not found" at the first use. We
131
+ // catch the gap here instead of months later.
132
+ const driftAgentDirs = [
133
+ join(platformRoot, 'templates', 'specialists', 'agents'),
134
+ ...agentsDirs.admin,
135
+ join(config.accountDir, 'specialists', 'agents'),
136
+ ];
137
+ const specialistDrift = assertSpecialistDrift(driftAgentDirs, toolSurface);
138
+ if (!specialistDrift.ok) {
139
+ for (const d of specialistDrift.defects) {
140
+ log(`boot-failed reason=specialist-tool-drift specialist=${d.specialistName} tool=${d.tool} drift=${d.reason} path=${d.specialistPath}`);
141
+ }
142
+ process.exit(1);
143
+ }
144
+ log(`startup-self-test specialist-tool-drift=ok inspected=${specialistDrift.inspected}`);
119
145
  const accountId = basename(config.accountDir);
120
146
  const logDir = process.env.LOG_DIR ?? join(config.persistDir, 'logs');
147
+ // Task 165 — the manager process inherits CLAUDE_CONFIG_DIR from its
148
+ // systemd unit. pty-spawner reads specialist agent files from
149
+ // `<claudeConfigDir>/agents/<name>.md` when `--agent` is set. Absence is
150
+ // a boot-time refusal: without it, every specialist spawn would silently
151
+ // run as the admin agent on admin IDENTITY/SOUL scaffolding.
152
+ const claudeConfigDirResolved = process.env.CLAUDE_CONFIG_DIR ?? '';
153
+ if (!claudeConfigDirResolved) {
154
+ log('boot-failed reason=claude-config-dir-missing env=CLAUDE_CONFIG_DIR');
155
+ process.exit(1);
156
+ }
157
+ log(`claude-config-dir resolved=${claudeConfigDirResolved}`);
121
158
  // Boot-time drift catcher: render the prompt block with synthetic inputs
122
159
  // that exercise every optional sentinel. If a future refactor drops the
123
160
  // `<about-owner>` / `<dormant-plugins>` emit, the manager refuses to start
@@ -202,6 +239,7 @@ async function main() {
202
239
  logDir,
203
240
  agentsDirs,
204
241
  perAccountSpecialistsDir: join(config.accountDir, 'specialists', 'agents'),
242
+ claudeConfigDir: claudeConfigDirResolved,
205
243
  toolSurface,
206
244
  publicSpawnLimiter,
207
245
  publicToolAudit,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,13 @@ export interface SpawnDeps {
48
48
  logDir: string;
49
49
  agentsDirs: Readonly<Record<Role, readonly string[]>>;
50
50
  perAccountSpecialistsDir: string;
51
+ /** Per-brand Claude Code config dir — `$HOME/.<brand>/.claude`. The
52
+ * manager process inherits `CLAUDE_CONFIG_DIR` from its systemd unit;
53
+ * this field is the same value, plumbed through the deps surface so
54
+ * unit tests can substitute a tmp path. Claude Code resolves
55
+ * `--agent <name>` by reading `<claudeConfigDir>/agents/<name>.md`
56
+ * (Task 165). */
57
+ claudeConfigDir: string;
51
58
  mcpConfigDir?: string;
52
59
  toolSurface: ToolSurface;
53
60
  /** Fires once after the watcher reports the PID-file CREATE event for
@@ -100,7 +107,21 @@ interface McpConfigWriteParams {
100
107
  bridgeSuffixHint: string;
101
108
  targetDir: string;
102
109
  logger: Logger;
110
+ /** Task 165 — when the spawn is a specialist subagent, narrow the
111
+ * rendered mcp.json to only the MCP servers whose plugin namespace
112
+ * appears in the specialist's `tools:` frontmatter. `null` means the
113
+ * spawn is not a specialist; the role-based admin/public projection
114
+ * applies. */
115
+ specialistTools: readonly string[] | null;
103
116
  }
117
+ /** Task 165 — read the agent's `tools:` frontmatter line from
118
+ * `$CLAUDE_CONFIG_DIR/agents/<specialist>.md`. Loud-fails when the file
119
+ * is missing or when no `tools:` line exists in the frontmatter, since
120
+ * either case means `--agent <name>` would silently fall back to the
121
+ * admin surface — the exact defect Task 165 closes. Returns the tool
122
+ * names in the order they were declared (the caller sorts before
123
+ * emitting argv). */
124
+ export declare function readSpecialistTools(claudeConfigDir: string, specialist: string): string[];
104
125
  /** Builds the placeholder map for per-spawn `mcp.json` env substitution.
105
126
  * Exported for Task 142 unit coverage that asserts `PLATFORM_PORT` and
106
127
  * `MAXY_BRAND_PORT` resolve from the manager process env. */
@@ -1 +1 @@
1
- {"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@
23
23
  // Spawn failure surfaces (return 500 with `stderrTail`):
24
24
  // which-claude-not-found, pty-spawn-failed, pid-file-timeout,
25
25
  // host-context-unresolved, identity-unresolved, mcp-config-write-failed.
26
- import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
26
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
27
27
  import { tmpdir } from 'node:os';
28
28
  import { dirname, join } from 'node:path';
29
29
  import { startUrlCapture } from './url-capture.js';
@@ -55,6 +55,48 @@ function formatTailForLog(tail) {
55
55
  import { composeAppendSystemPrompt, } from './system-prompt.js';
56
56
  import { discoverHooks } from './hooks-discovery.js';
57
57
  export const PERMISSION_MODES = ['default', 'acceptEdits', 'plan', 'auto'];
58
+ /** Task 165 — read the agent's `tools:` frontmatter line from
59
+ * `$CLAUDE_CONFIG_DIR/agents/<specialist>.md`. Loud-fails when the file
60
+ * is missing or when no `tools:` line exists in the frontmatter, since
61
+ * either case means `--agent <name>` would silently fall back to the
62
+ * admin surface — the exact defect Task 165 closes. Returns the tool
63
+ * names in the order they were declared (the caller sorts before
64
+ * emitting argv). */
65
+ export function readSpecialistTools(claudeConfigDir, specialist) {
66
+ const path = join(claudeConfigDir, 'agents', `${specialist}.md`);
67
+ let raw;
68
+ try {
69
+ raw = readFileSync(path, 'utf8');
70
+ }
71
+ catch (err) {
72
+ const msg = err instanceof Error ? err.message : String(err);
73
+ throw new Error(`[pty-spawner] specialist-agent-file-missing path=${path} err=${msg}`);
74
+ }
75
+ // Frontmatter delimited by lines that contain only `---`. Read tools:
76
+ // line within the first delimited block.
77
+ const lines = raw.split(/\r?\n/);
78
+ if (lines[0]?.trim() !== '---') {
79
+ throw new Error(`[pty-spawner] specialist-agent-no-frontmatter path=${path}`);
80
+ }
81
+ let toolsLine = null;
82
+ for (let i = 1; i < lines.length; i++) {
83
+ const line = lines[i];
84
+ if (line.trim() === '---')
85
+ break;
86
+ const m = line.match(/^tools:\s*(.+)$/);
87
+ if (m) {
88
+ toolsLine = m[1];
89
+ break;
90
+ }
91
+ }
92
+ if (toolsLine === null) {
93
+ throw new Error(`[pty-spawner] specialist-agent-no-tools-line path=${path}`);
94
+ }
95
+ return toolsLine
96
+ .split(',')
97
+ .map((t) => t.trim())
98
+ .filter((t) => t.length > 0);
99
+ }
58
100
  function expandPlaceholders(raw, vars) {
59
101
  return raw.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/g, (m, name) => {
60
102
  return Object.prototype.hasOwnProperty.call(vars, name) ? vars[name] : m;
@@ -84,7 +126,24 @@ export function buildMcpPlaceholders(p, env = process.env) {
84
126
  }
85
127
  function writePerSpawnMcpConfig(p) {
86
128
  const serversForRole = [];
87
- if (p.role === 'admin') {
129
+ if (p.specialistTools !== null) {
130
+ // Task 165 — specialist spawn. Project the agent's `tools:`
131
+ // frontmatter to the set of plugin namespaces it references; include
132
+ // only those MCP servers. A specialist that only writes graph
133
+ // (database-operator: memory, contacts, tasks) does not get the
134
+ // dozens of other admin servers stamped into its mcp.json.
135
+ const specialistPluginNames = new Set();
136
+ for (const t of p.specialistTools) {
137
+ const m = t.match(/^mcp__(.+?)__/);
138
+ if (m)
139
+ specialistPluginNames.add(m[1]);
140
+ }
141
+ for (const [name, desc] of p.toolSurface.mcpServers) {
142
+ if (specialistPluginNames.has(name))
143
+ serversForRole.push([name, desc]);
144
+ }
145
+ }
146
+ else if (p.role === 'admin') {
88
147
  for (const [name, desc] of p.toolSurface.mcpServers)
89
148
  serversForRole.push([name, desc]);
90
149
  }
@@ -183,32 +242,54 @@ export async function spawnClaudeSession(deps, args) {
183
242
  const composedHost = deps.tunnelUrlOverride !== undefined
184
243
  ? { ...deps.host, tunnelUrl: deps.tunnelUrlOverride }
185
244
  : deps.host;
186
- const composed = composeAppendSystemPrompt(composedHost, { accountDir: deps.accountDir, role: args.role }, {
187
- aboutOwner: args.aboutOwner,
188
- dormantPlugins: args.dormantPlugins,
189
- activePlugins: args.activePlugins,
190
- specialistDomains: args.specialistDomains,
191
- });
192
- if (!composed.ok) {
193
- if (composed.reason === 'host-unresolved') {
194
- const stderrTail = deps.host.lanIPv4Diagnostic ?? 'append-system-prompt unresolved';
195
- deps.logger(`spawn-failed reason=host-context-unresolved stderr-tail=${JSON.stringify(stderrTail)}`);
196
- return { ok: false, reason: 'host-context-unresolved', stderrTail };
245
+ // Task 165 when the spawn is a specialist subagent (`--agent <name>`),
246
+ // the agent file at `$CLAUDE_CONFIG_DIR/agents/<name>.md` IS the prompt.
247
+ // Do not stack admin IDENTITY / SOUL / about-owner / plugin manifests on
248
+ // top: that scaffolding caused the recorder to behave as the admin agent
249
+ // on every turn since Task 147. Operator (non-specialist) spawns retain
250
+ // the full composer.
251
+ const isSpecialistSpawn = typeof args.specialist === 'string' && args.specialist.length > 0;
252
+ let appendSystemPrompt = '';
253
+ // The compose-system-prompt block carries per-section byte counts the
254
+ // [pty-spawn] log line emits later in this function. When the spawn is
255
+ // a specialist subagent we skip composeAppendSystemPrompt entirely, so
256
+ // those byte counts are zero — the agent file IS the prompt.
257
+ let composedBytes = { identity: 0, soul: 0, aboutOwner: 0, dormantPlugins: 0 };
258
+ if (!isSpecialistSpawn) {
259
+ const composed = composeAppendSystemPrompt(composedHost, { accountDir: deps.accountDir, role: args.role }, {
260
+ aboutOwner: args.aboutOwner,
261
+ dormantPlugins: args.dormantPlugins,
262
+ activePlugins: args.activePlugins,
263
+ specialistDomains: args.specialistDomains,
264
+ });
265
+ if (!composed.ok) {
266
+ if (composed.reason === 'host-unresolved') {
267
+ const stderrTail = deps.host.lanIPv4Diagnostic ?? 'append-system-prompt unresolved';
268
+ deps.logger(`spawn-failed reason=host-context-unresolved stderr-tail=${JSON.stringify(stderrTail)}`);
269
+ return { ok: false, reason: 'host-context-unresolved', stderrTail };
270
+ }
271
+ const sep = composed.detail.lastIndexOf(':');
272
+ const file = sep > 0 ? composed.detail.slice(0, sep) : composed.detail;
273
+ const err = sep > 0 ? composed.detail.slice(sep + 1) : '';
274
+ deps.logger(`[pty-spawn] spawn-failed reason=identity-unresolved accountDir=${deps.accountDir} role=${args.role} file=${file} err=${err}`);
275
+ return { ok: false, reason: 'identity-unresolved', stderrTail: composed.detail };
197
276
  }
198
- const sep = composed.detail.lastIndexOf(':');
199
- const file = sep > 0 ? composed.detail.slice(0, sep) : composed.detail;
200
- const err = sep > 0 ? composed.detail.slice(sep + 1) : '';
201
- deps.logger(`[pty-spawn] spawn-failed reason=identity-unresolved accountDir=${deps.accountDir} role=${args.role} file=${file} err=${err}`);
202
- return { ok: false, reason: 'identity-unresolved', stderrTail: composed.detail };
203
- }
204
- const appendSystemPrompt = composed.block;
205
- 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}`);
206
- const argv = [
207
- '--verbose',
208
- '--remote-control',
209
- '--append-system-prompt',
210
- appendSystemPrompt,
211
- ];
277
+ appendSystemPrompt = composed.block;
278
+ composedBytes = {
279
+ identity: composed.identityBytes,
280
+ soul: composed.soulBytes,
281
+ aboutOwner: composed.aboutOwnerBytes,
282
+ dormantPlugins: composed.dormantPluginsBytes,
283
+ };
284
+ 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}`);
285
+ }
286
+ else {
287
+ deps.logger(`compose-system-prompt-skipped role=${args.role} specialist=${args.specialist} reason=agent-file-is-the-prompt`);
288
+ }
289
+ const argv = ['--verbose', '--remote-control'];
290
+ if (!isSpecialistSpawn) {
291
+ argv.push('--append-system-prompt', appendSystemPrompt);
292
+ }
212
293
  if (args.resumeClaudeSessionId) {
213
294
  argv.push('--resume', args.resumeClaudeSessionId);
214
295
  }
@@ -223,15 +304,37 @@ export async function spawnClaudeSession(deps, args) {
223
304
  argv.push('--channels', ch);
224
305
  }
225
306
  }
226
- const allowedSet = args.role === 'public' ? deps.toolSurface.public : deps.toolSurface.admin;
227
- const allowed = Array.from(allowedSet).sort();
307
+ // Task 165 specialist spawn narrows `--allowed-tools` to the agent's
308
+ // frontmatter `tools:` list, not the admin surface. Pre-165, every
309
+ // specialist (recorder, etc.) was launched with the full 131-tool admin
310
+ // allowlist, defeating the agent file's gate. Operator spawns retain
311
+ // the role-based surface.
312
+ let specialistTools = null;
313
+ if (isSpecialistSpawn) {
314
+ try {
315
+ specialistTools = readSpecialistTools(deps.claudeConfigDir, args.specialist);
316
+ }
317
+ catch (err) {
318
+ const detail = err instanceof Error ? err.message : String(err);
319
+ deps.logger(`spawn-failed reason=identity-unresolved detail=${JSON.stringify(detail)}`);
320
+ return { ok: false, reason: 'identity-unresolved', stderrTail: detail };
321
+ }
322
+ }
323
+ const allowed = specialistTools !== null
324
+ ? Array.from(new Set(specialistTools)).sort()
325
+ : Array.from(args.role === 'public' ? deps.toolSurface.public : deps.toolSurface.admin).sort();
228
326
  for (const tool of allowed) {
229
327
  argv.push('--allowed-tools', tool);
230
328
  }
231
- const excludedSample = args.role === 'public'
232
- ? Array.from(deps.toolSurface.admin).filter((t) => !deps.toolSurface.public.has(t)).sort().slice(0, 5).join(',')
233
- : '';
234
- deps.logger(`tool-allowlist role=${args.role} count=${allowed.length} excluded=${excludedSample}`);
329
+ if (isSpecialistSpawn) {
330
+ deps.logger(`pty-spawn-allowlist specialist=${args.specialist} count=${allowed.length} sourced-from=agent-frontmatter`);
331
+ }
332
+ else {
333
+ const excludedSample = args.role === 'public'
334
+ ? Array.from(deps.toolSurface.admin).filter((t) => !deps.toolSurface.public.has(t)).sort().slice(0, 5).join(',')
335
+ : '';
336
+ deps.logger(`tool-allowlist role=${args.role} count=${allowed.length} excluded=${excludedSample}`);
337
+ }
235
338
  if (args.permissionMode && args.permissionMode !== 'default') {
236
339
  argv.push('--permission-mode', args.permissionMode);
237
340
  }
@@ -244,6 +347,7 @@ export async function spawnClaudeSession(deps, args) {
244
347
  bridgeSuffixHint: args.senderId,
245
348
  targetDir: deps.mcpConfigDir ?? tmpdir(),
246
349
  logger: deps.logger,
350
+ specialistTools,
247
351
  });
248
352
  if (!mcpConfigResult.ok) {
249
353
  return { ok: false, reason: 'mcp-config-write-failed', stderrTail: mcpConfigResult.detail };
@@ -263,16 +367,19 @@ export async function spawnClaudeSession(deps, args) {
263
367
  argv.push('--add-dir', args.attachmentDir);
264
368
  argv.push('--allowed-tools', `Read(${args.attachmentDir}/**)`);
265
369
  }
266
- // Task 153 — trailing positional `prompt`. The claude CLI signature is
267
- // `claude [options] [command] [prompt]`; when set, the string becomes
268
- // the session's first user turn at PTY startup. The JSONL first
269
- // `role=user` line equals this string verbatim. No /input call, no
270
- // bracketed-paste, no keystroke injection.
370
+ // Task 153 / 162 — trailing positional `prompt`. The claude CLI signature
371
+ // is `claude [options] [command] [prompt]`; when set, the string becomes
372
+ // the session's first user turn at PTY startup. The POSIX `--` sentinel
373
+ // ends options parsing so the preceding variadic flags (`--add-dir`,
374
+ // `--allowed-tools`) cannot swallow the prompt as another value.
375
+ const promptBytes = Buffer.byteLength(args.initialMessage ?? '', 'utf8');
376
+ let promptPositional = false;
271
377
  if (args.initialMessage && args.initialMessage.length > 0) {
272
- argv.push(args.initialMessage);
378
+ argv.push('--', args.initialMessage);
379
+ promptPositional = true;
273
380
  }
274
381
  const hooksResolved = discoverHooks(deps.spawnCwd, process.env.CLAUDE_CONFIG_DIR);
275
- deps.logger(`pty-spawn-start claudeBin=${deps.claudeBin} argv-count=${argv.length} append-system-prompt-bytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} permission-mode=${args.permissionMode ?? 'default'} resume=${args.resumeClaudeSessionId ? 'yes' : 'no'} hooksResolved=${hooksResolved.join(',') || 'none'}`);
382
+ deps.logger(`pty-spawn-start claudeBin=${deps.claudeBin} argv-count=${argv.length} append-system-prompt-bytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} permission-mode=${args.permissionMode ?? 'default'} resume=${args.resumeClaudeSessionId ? 'yes' : 'no'} specialist=${args.specialist ?? 'none'} prompt-positional=${promptPositional ? 'yes' : 'no'} prompt-bytes=${promptBytes} hooksResolved=${hooksResolved.join(',') || 'none'}`);
276
383
  const ptySpawnStart = Date.now();
277
384
  let pty;
278
385
  try {
@@ -367,7 +474,7 @@ export async function spawnClaudeSession(deps, args) {
367
474
  const responseMs = Date.now() - start;
368
475
  deps.logger(`spawn-response-returned sessionId=${session.sessionId} pid=${pty.pid} ms=${responseMs}`);
369
476
  deps.logger(`spawn pid=${pty.pid} sessionId=${session.sessionId} senderId=${args.senderId} role=${args.role} channel=${args.channel} permissionMode=${args.permissionMode ?? 'default'} latency-ms=${responseMs}`);
370
- deps.logger(`[pty-spawn] sessionId=${session.sessionId} appendSystemPromptBytes=${Buffer.byteLength(appendSystemPrompt, 'utf8')} identityBytes=${composed.identityBytes} soulBytes=${composed.soulBytes} aboutOwnerBytes=${composed.aboutOwnerBytes} dormantPluginsBytes=${composed.dormantPluginsBytes} accountDir=${deps.accountDir} role=${args.role} hostname=${deps.host.hostname} lanIPv4=${deps.host.lanIPv4} adminUrl=${deps.host.adminUrl} tunnelUrl=${composedHost.tunnelUrl ?? 'none'}`);
477
+ deps.logger(`[pty-spawn] sessionId=${session.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'}`);
371
478
  deps.onSessionReady?.(session);
372
479
  return { ok: true, session };
373
480
  }