@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.
- package/dist/__tests__/installer-specialist-registration.test.js +112 -0
- package/dist/index.js +22 -0
- package/dist/specialist-registration.js +78 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +22 -0
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +50 -13
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +22 -21
- package/payload/platform/plugins/contacts/PLUGIN.md +9 -0
- package/payload/platform/plugins/docs/references/admin-session.md +55 -7
- package/payload/platform/plugins/email/PLUGIN.md +9 -0
- package/payload/platform/plugins/epc/PLUGIN.md +5 -0
- package/payload/platform/plugins/loop/PLUGIN.md +27 -0
- package/payload/platform/plugins/memory/PLUGIN.md +37 -0
- package/payload/platform/plugins/memory/mcp/dist/index.js +3 -3
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js +137 -75
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts +0 -17
- package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js +32 -4
- package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +65 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +182 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +8 -8
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js +241 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +9 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js +9 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js +10 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js +5 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js +5 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +5 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +5 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +6 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +4 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +10 -3
- package/payload/platform/plugins/outlook/PLUGIN.md +7 -0
- package/payload/platform/plugins/preval/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/preval/PLUGIN.md +16 -8
- package/payload/platform/plugins/preval/hooks/preval-prompt-required.sh +140 -0
- package/payload/platform/plugins/preval/skills/property-preval/SKILL.md +44 -14
- package/payload/platform/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
- package/payload/platform/plugins/preval/skills/property-preval/references/render.py +247 -62
- package/payload/platform/plugins/preval/skills/property-preval/references/template-inputs.schema.json +29 -19
- package/payload/platform/plugins/property-data/PLUGIN.md +22 -0
- package/payload/platform/plugins/replicate/PLUGIN.md +3 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +8 -0
- package/payload/platform/plugins/tasks/PLUGIN.md +14 -0
- package/payload/platform/plugins/telegram/PLUGIN.md +3 -0
- package/payload/platform/plugins/waitlist/PLUGIN.md +7 -0
- package/payload/platform/plugins/whatsapp/PLUGIN.md +12 -0
- package/payload/platform/plugins/workflows/PLUGIN.md +8 -0
- package/payload/platform/services/claude-session-manager/dist/index.js +39 -1
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +21 -0
- 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 +148 -41
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +23 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +141 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +13 -2
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js +135 -37
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
- package/payload/premium-plugins/real-agent/agents/compliance.md +1 -1
- package/payload/premium-plugins/real-agent/plugins/epc/PLUGIN.md +5 -0
- package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +27 -0
- package/payload/premium-plugins/real-agent/plugins/preval/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agent/plugins/preval/PLUGIN.md +16 -8
- package/payload/premium-plugins/real-agent/plugins/preval/hooks/preval-prompt-required.sh +140 -0
- package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/SKILL.md +44 -14
- package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
- package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/render.py +247 -62
- package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template-inputs.schema.json +29 -19
- package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +22 -0
- package/payload/server/public/assets/{admin-DhN3G8W7.js → admin-ymReS1mN.js} +1 -1
- package/payload/server/public/assets/{data-B2ZVXOcE.js → data-D6U2e85B.js} +1 -1
- package/payload/server/public/assets/{graph-BAMGPHrK.js → graph-C274PN27.js} +1 -1
- package/payload/server/public/assets/{graph-labels-D9eBbvxo.js → graph-labels-DQFzd1FY.js} +1 -1
- package/payload/server/public/assets/{page-DjdVMWCz.js → page-D-OLjort.js} +1 -1
- package/payload/server/public/assets/{page-CV27Al6Z.js → page-DFFt9_Q0.js} +1 -1
- package/payload/server/public/data.html +3 -3
- package/payload/server/public/graph.html +3 -3
- package/payload/server/public/index.html +4 -4
- 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":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAA;
|
|
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.
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
|
267
|
-
// `claude [options] [command] [prompt]`; when set, the string becomes
|
|
268
|
-
// the session's first user turn at PTY startup. The
|
|
269
|
-
//
|
|
270
|
-
//
|
|
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=${
|
|
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
|
}
|