@rubytech/create-maxy-code 0.1.34 → 0.1.36
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 +4 -1
- package/payload/platform/plugins/docs/references/platform.md +3 -1
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +0 -5
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +16 -6
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +0 -5
- 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 +98 -131
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +0 -1
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-observer.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-observer.js +38 -9
- package/payload/platform/services/claude-session-manager/dist/jsonl-observer.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +14 -61
- 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 +109 -104
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +30 -36
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.js +65 -58
- package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +5 -5
- package/payload/server/public/assets/{Checkbox-C6zXApx_.js → Checkbox-C_5g1tvd.js} +1 -1
- package/payload/server/public/assets/{admin-CF2ZQvXu.js → admin-CMhAQf3x.js} +24 -24
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BYXgFii5.js → architectureDiagram-Q4EWVU46-PATAR9cB.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-GIQ0eO13.js → blockDiagram-DXYQGD6D-BTtUDSn8.js} +1 -1
- package/payload/server/public/assets/{brand-DdhkC994.css → brand--hRSJcTa.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-BmyWfG-l.js → c4Diagram-AHTNJAMY-DagJLqud.js} +1 -1
- package/payload/server/public/assets/channel-ad6bhEyF.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DcWl0MQo.js → chunk-336JU56O-r_17ZSte.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BIW6kq6y.js → chunk-426QAEUC-BeZHE5Od.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CdoHpV4X.js → chunk-4TB4RGXK-BOKuzFDs.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-bn_a4sfU.js → chunk-5FUZZQ4R-CFPql_Mb.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-C_Rq8j_M.js → chunk-5PVQY5BW-B-ooj0Oj.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-CWQvoVKV.js → chunk-EDXVE4YY-pfgSmAaU.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-DBHn1kSk.js → chunk-ENJZ2VHE-Czo3wSBG.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-SW2Qx11O.js → chunk-ICPOFSXX-B0Kq8LNp.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BvIG7tVW.js → chunk-OYMX7WX6-BM97IkL3.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-BiBUb0cF.js → chunk-U2HBQHQK-Qu1CuohC.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-Y0MKZCCh.js → chunk-X2U36JSP-uDlh8MVE.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-DKPh06GH.js → chunk-YZCP3GAM-DUlG-OZ5.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-C2WNo-fK.js → chunk-ZZ45TVLE-BABivBFM.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-D9Gycby2.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-sUgm3wmz.js +1 -0
- package/payload/server/public/assets/clone-CZxh5VW0.js +1 -0
- package/payload/server/public/assets/{dagre-CrK8E9ee.js → dagre-BLaP4HDY.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-_o6uXcH8.js → dagre-KV5264BT-CVL1mRVD.js} +1 -1
- package/payload/server/public/assets/data-DarDs6k1.js +1 -0
- package/payload/server/public/assets/{device-url-actions-BcHerWqJ.js → device-url-actions-Dmhh-Azv.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-FFP9DKhc.js → diagram-5BDNPKRD-Db75sppc.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DpwD1jBP.js → diagram-G4DWMVQ6-Cj8Nvgev.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-C3K5agdK.js → diagram-MMDJMWI5-BGXJmtU0.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CbeDipbC.js → diagram-TYMM5635-FALU804i.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-XBIFndNy.js → erDiagram-SMLLAGMA-Dny5IMgt.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BvEgySyn.js → flowDiagram-DWJPFMVM-CvKuRNSd.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-D7gIRKJf.js → ganttDiagram-T4ZO3ILL-CMMNRVGJ.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-vJu_hcri.js → gitGraphDiagram-UUTBAWPF-GNp7o9CH.js} +1 -1
- package/payload/server/public/assets/graph-CG9KcTMy.js +1 -0
- package/payload/server/public/assets/graph-labels-DnFPoPy9.js +1 -0
- package/payload/server/public/assets/{graphlib-Dp0mN6JW.js → graphlib-Bbf4iSQ9.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-g4Dlc5Cr.js → infoDiagram-42DDH7IO-CKnsQ4zf.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D_45LXOe.js → ishikawaDiagram-UXIWVN3A-7iiLy5h7.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CggbHl6N.js → journeyDiagram-VCZTEJTY-BqbrYu64.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CysAe-Ab.js → kanban-definition-6JOO6SKY-B4xrW1HU.js} +1 -1
- package/payload/server/public/assets/{line-BAxq_DSY.js → line-VuY4jgLe.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-DbFuvkjL.js → mermaid-parser.core-BaqOkGpC.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-CehvJn5b.js → mermaid.core-CCQHCJiH.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DbPbBJ9h.js → mindmap-definition-QFDTVHPH-CD7_gX12.js} +1 -1
- package/payload/server/public/assets/page-BbunxlG3.js +1 -0
- package/payload/server/public/assets/{page-Co7KCRV8.js → page-CDFsJW62.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-cagLL9ng.js → pieDiagram-DEJITSTG-DYv6IDvS.js} +1 -1
- package/payload/server/public/assets/{public-B6TEcDLx.js → public-vZ5OE_BJ.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Keaa1jDh.js → quadrantDiagram-34T5L4WZ-Djjgb1kX.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-BcYRyn5z.js → requirementDiagram-MS252O5E-D1jpw_fu.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6--fKoG9NR.js → sankeyDiagram-XADWPNL6-CiWmspyf.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-lKG36-Di.js → sequenceDiagram-FGHM5R23-B1GXIeQe.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BuVsrlig.js → stateDiagram-FHFEXIEX-DX7QZrhc.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CekuC-ks.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-D6X6uq17.js → timeline-definition-GMOUNBTQ-BxiwnKFu.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BgvcfRVf.js → vennDiagram-DHZGUBPP-RxZA_K0W.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Cpd1xsrt.js → wardleyDiagram-NUSXRM2D-b2tVWjtB.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CDF5ZVFv.js → xychartDiagram-5P7HB3ND-D55tkJH1.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +149 -129
- package/payload/docs/desktop-code-controls.md +0 -63
- package/payload/server/public/assets/channel-C76knBRO.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Bohexn7P.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DVsmsAu7.js +0 -1
- package/payload/server/public/assets/clone-DUrXF4sO.js +0 -1
- package/payload/server/public/assets/data-j1WNhF8t.js +0 -1
- package/payload/server/public/assets/graph-C_f_9L_7.js +0 -1
- package/payload/server/public/assets/graph-labels-BSQJHlgf.js +0 -1
- package/payload/server/public/assets/page-B0BPrSE3.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DSt88_xL.js +0 -1
- /package/payload/server/public/assets/{brand-B-bNrpwc.js → brand-B62OQoRC.js} +0 -0
|
@@ -92,7 +92,6 @@ async function main() {
|
|
|
92
92
|
spawnCwd: config.spawnCwd,
|
|
93
93
|
claudeBin: config.claudeBin,
|
|
94
94
|
urlCaptureTimeoutMs: config.urlCaptureTimeoutMs,
|
|
95
|
-
observeTimeoutMs: config.observeTimeoutMs,
|
|
96
95
|
killGraceMs: config.killGraceMs,
|
|
97
96
|
jsonlReadMaxBytes: config.jsonlReadMaxBytes,
|
|
98
97
|
logger: log,
|
|
@@ -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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonl-observer.d.ts","sourceRoot":"","sources":["../src/jsonl-observer.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;8DAG0D;IAC1D,OAAO,EAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;IACtC;2DACuD;IACvD,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,OAAO,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB,CAAA;IAC1D,gEAAgE;IAChE,KAAK,IAAI,IAAI,CAAA;CACd;
|
|
1
|
+
{"version":3,"file":"jsonl-observer.d.ts","sourceRoot":"","sources":["../src/jsonl-observer.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;8DAG0D;IAC1D,OAAO,EAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;IACtC;2DACuD;IACvD,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,OAAO,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB,CAAA;IAC1D,gEAAgE;IAChE,KAAK,IAAI,IAAI,CAAA;CACd;AAoFD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GAAG,aAAa,CAgHhB"}
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
import { existsSync, mkdirSync, openSync, closeSync, readSync, readdirSync, statSync, watch } from 'node:fs';
|
|
25
25
|
import { join } from 'node:path';
|
|
26
26
|
const HEAD_READ_BYTES = 4 * 1024;
|
|
27
|
+
// Cap on the head-preview substring rendered in `*-no-match` log lines so
|
|
28
|
+
// a 4 KiB head doesn't spam a multi-line log row. 200 chars is the first
|
|
29
|
+
// line or two of a JSONL plus enough of the next record to spot a wrong
|
|
30
|
+
// bridge suffix at a glance.
|
|
31
|
+
const HEAD_PREVIEW_CHARS = 200;
|
|
27
32
|
/** Read the first HEAD_READ_BYTES of a file. Returns empty string on any
|
|
28
33
|
* IO error (ENOENT, EACCES, file truncated mid-read). The caller treats
|
|
29
34
|
* empty as "no match yet" and keeps the pending observation registered
|
|
@@ -55,13 +60,13 @@ function readHead(path, logger) {
|
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
/** Try to bind the given JSONL to any pending observation. Returns the
|
|
58
|
-
* observation that matched (already resolved)
|
|
63
|
+
* observation that matched (already resolved) and the bytes read. */
|
|
59
64
|
function tryBindFile(jsonlPath, pendings, logger) {
|
|
60
65
|
if (pendings.size === 0)
|
|
61
|
-
return null;
|
|
66
|
+
return { bound: null, head: '' };
|
|
62
67
|
const head = readHead(jsonlPath, logger);
|
|
63
68
|
if (!head)
|
|
64
|
-
return null;
|
|
69
|
+
return { bound: null, head: '' };
|
|
65
70
|
for (const p of pendings) {
|
|
66
71
|
if (p.settled)
|
|
67
72
|
continue;
|
|
@@ -72,10 +77,17 @@ function tryBindFile(jsonlPath, pendings, logger) {
|
|
|
72
77
|
p.settled = true;
|
|
73
78
|
p.resolve({ jsonlPath, claudeSessionId });
|
|
74
79
|
pendings.delete(p);
|
|
75
|
-
return p;
|
|
80
|
+
return { bound: p, head };
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
|
-
return null;
|
|
83
|
+
return { bound: null, head };
|
|
84
|
+
}
|
|
85
|
+
/** Build the head-preview field used in `*-no-match` log lines: cap at
|
|
86
|
+
* HEAD_PREVIEW_CHARS, replace control chars so a single log line stays
|
|
87
|
+
* one line, and JSON-quote so grep on `head-preview="…"` is reliable. */
|
|
88
|
+
function formatHeadPreview(head) {
|
|
89
|
+
const slice = head.length > HEAD_PREVIEW_CHARS ? head.slice(0, HEAD_PREVIEW_CHARS) : head;
|
|
90
|
+
return JSON.stringify(slice.replace(/[\x00-\x1f]/g, '.'));
|
|
79
91
|
}
|
|
80
92
|
export function createJsonlObserver(opts) {
|
|
81
93
|
const { projectsDir, logger } = opts;
|
|
@@ -90,9 +102,17 @@ export function createJsonlObserver(opts) {
|
|
|
90
102
|
const full = join(projectsDir, filename);
|
|
91
103
|
if (!existsSync(full))
|
|
92
104
|
return;
|
|
93
|
-
const bound = tryBindFile(full, pendings, logger);
|
|
105
|
+
const { bound, head } = tryBindFile(full, pendings, logger);
|
|
94
106
|
if (bound) {
|
|
95
107
|
logger(`jsonl-observer matched event=${eventType} path=${full} bridgeSuffix=${bound.bridgeSuffix}`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// No bind. If there are pending observations and the head is readable
|
|
111
|
+
// but the bridge suffix is missing, log the preview so an operator
|
|
112
|
+
// can see whether claude wrote a JSONL with a different suffix vs
|
|
113
|
+
// wrote nothing at all. Pendings=0 means no one is listening; skip.
|
|
114
|
+
if (pendings.size > 0 && head.length > 0) {
|
|
115
|
+
logger(`jsonl-observer watch-no-match event=${eventType} path=${full} head-bytes=${head.length} head-preview=${formatHeadPreview(head)} pendings=${pendings.size}`);
|
|
96
116
|
}
|
|
97
117
|
}
|
|
98
118
|
try {
|
|
@@ -122,20 +142,29 @@ export function createJsonlObserver(opts) {
|
|
|
122
142
|
settled: false,
|
|
123
143
|
};
|
|
124
144
|
// On-arm scan — close the race between this call and the fs.watch
|
|
125
|
-
// event firing for a JSONL Claude already wrote.
|
|
145
|
+
// event firing for a JSONL Claude already wrote. Tracks how many
|
|
146
|
+
// JSONLs were inspected and emits a head-preview line for every
|
|
147
|
+
// unrelated file so an operator can see whether the project dir is
|
|
148
|
+
// empty (claude wrote nothing yet) vs full of unrelated JSONLs
|
|
149
|
+
// (claude wrote one but its head bytes don't carry our suffix).
|
|
126
150
|
pendings.add(pending);
|
|
127
151
|
let scannedHit = false;
|
|
152
|
+
let scannedFiles = 0;
|
|
128
153
|
try {
|
|
129
154
|
for (const entry of readdirSync(projectsDir, { withFileTypes: true })) {
|
|
130
155
|
if (!entry.isFile() || !entry.name.endsWith('.jsonl'))
|
|
131
156
|
continue;
|
|
157
|
+
scannedFiles++;
|
|
132
158
|
const full = join(projectsDir, entry.name);
|
|
133
|
-
const bound = tryBindFile(full, pendings, logger);
|
|
159
|
+
const { bound, head } = tryBindFile(full, pendings, logger);
|
|
134
160
|
if (bound === pending) {
|
|
135
161
|
scannedHit = true;
|
|
136
162
|
logger(`jsonl-observer on-arm-scan-matched path=${full} bridgeSuffix=${bridgeSuffix}`);
|
|
137
163
|
break;
|
|
138
164
|
}
|
|
165
|
+
if (head.length > 0) {
|
|
166
|
+
logger(`jsonl-observer on-arm-scan-no-match path=${full} head-bytes=${head.length} head-preview=${formatHeadPreview(head)} bridgeSuffix=${bridgeSuffix}`);
|
|
167
|
+
}
|
|
139
168
|
}
|
|
140
169
|
}
|
|
141
170
|
catch (err) {
|
|
@@ -143,7 +172,7 @@ export function createJsonlObserver(opts) {
|
|
|
143
172
|
logger(`jsonl-observer on-arm-scan-failed dir=${projectsDir} message=${msg}`);
|
|
144
173
|
}
|
|
145
174
|
if (!scannedHit) {
|
|
146
|
-
logger(`jsonl-observer pending bridgeSuffix=${bridgeSuffix}`);
|
|
175
|
+
logger(`jsonl-observer pending bridgeSuffix=${bridgeSuffix} on-arm-files-scanned=${scannedFiles}`);
|
|
147
176
|
}
|
|
148
177
|
return {
|
|
149
178
|
promise,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonl-observer.js","sourceRoot":"","sources":["../src/jsonl-observer.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,2DAA2D;AAC3D,yEAAyE;AACzE,yEAAyE;AACzE,sEAAsE;AACtE,uEAAuE;AACvE,0EAA0E;AAC1E,uCAAuC;AACvC,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,kEAAkE;AAClE,yEAAyE;AACzE,yEAAyE;AACzE,qEAAqE;AACrE,iEAAiE;AACjE,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,sEAAsE;AACtE,mEAAmE;AAEnE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAkB,MAAM,SAAS,CAAA;AAC5H,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAkChC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"jsonl-observer.js","sourceRoot":"","sources":["../src/jsonl-observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import type { JsonlObserver } from './jsonl-observer.js';
|
|
|
4
4
|
import { type OwnerProfileBlock, type DormantPlugin } from './system-prompt.js';
|
|
5
5
|
import type { HostResolution } from './config.js';
|
|
6
6
|
import type { ToolSurface } from './tool-surface.js';
|
|
7
|
-
export type SpawnFailureReason = 'which-claude-not-found' | 'pty-spawn-failed' | 'url-capture-timeout' | 'host-context-unresolved' | 'identity-unresolved' | 'bridge-suffix-unparseable'
|
|
7
|
+
export type SpawnFailureReason = 'which-claude-not-found' | 'pty-spawn-failed' | 'url-capture-timeout' | 'host-context-unresolved' | 'identity-unresolved' | 'bridge-suffix-unparseable';
|
|
8
8
|
export type SpawnResult = {
|
|
9
9
|
ok: true;
|
|
10
10
|
session: StoredSession;
|
|
@@ -18,83 +18,36 @@ export interface SpawnDeps {
|
|
|
18
18
|
spawnCwd: string;
|
|
19
19
|
claudeBin: string;
|
|
20
20
|
urlCaptureTimeoutMs: number;
|
|
21
|
-
/** upper bound on how long the spawn promise waits for the
|
|
22
|
-
* jsonl-observer to bind a JSONL to the captured URL's bridge suffix.
|
|
23
|
-
* On timeout the PTY is killed and the spawn rejects with
|
|
24
|
-
* `observe-timeout`. Default 5 000 ms — generous; typical observation
|
|
25
|
-
* latency is well under 500 ms. Tests inject smaller values. */
|
|
26
|
-
observeTimeoutMs: number;
|
|
27
21
|
logger: Logger;
|
|
28
22
|
store: SessionStore;
|
|
29
|
-
/** host context resolved at boot. Used both to compose the
|
|
30
|
-
* sentinel-wrapped block injected via `--append-system-prompt` (hostname,
|
|
31
|
-
* LAN IPv4, admin URL, tunnel URL + the 30 MiB attachment ceiling
|
|
32
|
-
* doctrine) and to surface a `host-context-unresolved` failure when
|
|
33
|
-
* `lanIPv4` is null. One edit to this block changes the doctrine for
|
|
34
|
-
* every agent in every session. */
|
|
35
23
|
host: HostResolution;
|
|
36
|
-
/** per-account directory resolved once at boot. Per-spawn the
|
|
37
|
-
* composer reads `<accountDir>/agents/<role>/{IDENTITY.md,SOUL.md}` and
|
|
38
|
-
* appends them as `<identity>` / `<soul>` sentinels after the host +
|
|
39
|
-
* attachment-ceiling blocks. Missing or empty files reject the spawn
|
|
40
|
-
* with `identity-unresolved`; no silent fallback to stock Claude Code. */
|
|
41
24
|
accountDir: string;
|
|
42
|
-
/** precomputed tool surface for both roles. Loaded once at
|
|
43
|
-
* manager boot from a directory walk of platform/plugins/<name>/PLUGIN.md.
|
|
44
|
-
* The boot path refuses to start if any tool's PLUGIN.md entry lacks a
|
|
45
|
-
* publicAllowlist field, so by the time pty-spawner sees this struct, the
|
|
46
|
-
* per-tool decisions are guaranteed complete. */
|
|
47
25
|
toolSurface: ToolSurface;
|
|
48
|
-
/** observer for the JSONL file Claude Code writes.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
26
|
+
/** observer for the JSONL file Claude Code writes on first turn. The
|
|
27
|
+
* spawn promise does NOT block on this; instead the observation is
|
|
28
|
+
* fired-and-forgotten and promotes the row in the background. The
|
|
29
|
+
* observation is unbounded (no timeout) because operator typing latency
|
|
30
|
+
* is unbounded. */
|
|
53
31
|
observer: JsonlObserver;
|
|
54
|
-
/** fires once after the observer matches a JSONL to the
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* attach the public-tool audit watcher. */
|
|
32
|
+
/** fires once after the observer matches a JSONL to the session. The
|
|
33
|
+
* closure has already promoted the row by the time this is invoked.
|
|
34
|
+
* http-server uses this to attach the public-tool audit watcher. */
|
|
58
35
|
onJsonlObserved?: (session: StoredSession) => void;
|
|
36
|
+
/** optional per-spawn override for the tunnelUrl rendered into the
|
|
37
|
+
* `<host>` block. The manager service has no Neo4j credentials; the UI
|
|
38
|
+
* process resolves the tunnel state at /spawn enrichment time and
|
|
39
|
+
* forwards it on the spawn body. Null/undefined emits `tunnel-url: none`. */
|
|
40
|
+
tunnelUrlOverride?: string | null;
|
|
59
41
|
}
|
|
60
42
|
export interface SpawnArgs {
|
|
61
43
|
senderId: string;
|
|
62
44
|
role: Role;
|
|
63
45
|
channel: Channel;
|
|
64
|
-
/** Optional claude session id to resume. When set, the manager appends
|
|
65
|
-
* `--resume <id>` to the argv so claude rehydrates the prior JSONL into
|
|
66
|
-
* the new PTY. */
|
|
67
46
|
resumeClaudeSessionId?: string;
|
|
68
|
-
/** channel-plugin entries the spawned `claude` should attach
|
|
69
|
-
* to. Each entry is rendered as `--channels plugin:<name>@<marketplace>`
|
|
70
|
-
* on the spawn argv (e.g. `plugin:telegram@claude-plugins-official`).
|
|
71
|
-
* When omitted or empty, argv is byte-identical to today — existing
|
|
72
|
-
* Maxy installs with no channel plugins pay nothing for the addition. */
|
|
73
47
|
channels?: string[];
|
|
74
|
-
/** operator-selected permission mode. When set to anything
|
|
75
|
-
* other than `default`, the manager appends `--permission-mode <mode>`
|
|
76
|
-
* to the spawn argv so the claude CLI starts the session in that mode.
|
|
77
|
-
* `default` (or omitted) leaves argv byte-identical to today. */
|
|
78
48
|
permissionMode?: PermissionMode;
|
|
79
|
-
/** per-session attachment directory for role=public. When set,
|
|
80
|
-
* pty-spawner pre-creates the directory and appends `--add-dir <dir>` plus
|
|
81
|
-
* `--allowed-tools "Read(<dir>/**)"` to argv so claude can read public-chat
|
|
82
|
-
* uploads referenced in the dispatched turn. Ignored for non-public roles.
|
|
83
|
-
* The directory is per-(accountId, senderId) and deterministic; the bridge
|
|
84
|
-
* passes it at session-creation time so it covers every turn in the
|
|
85
|
-
* session, not just the first turn carrying attachments. */
|
|
86
49
|
attachmentDir?: string;
|
|
87
|
-
/** Per-spawn `<about-owner>` body resolved upstream by the UI process
|
|
88
|
-
* (which holds Neo4j credentials) and forwarded verbatim. Omitted by
|
|
89
|
-
* callers that have no owner concept; the composer suppresses the sentinel
|
|
90
|
-
* in that case. When the upstream read fails (Neo4j unreachable,
|
|
91
|
-
* AdminUser missing), the caller passes `{ok:false,reason}` so the agent
|
|
92
|
-
* sees `<about-owner>coverage-unresolved: <reason></about-owner>` rather
|
|
93
|
-
* than a silent omission. */
|
|
94
50
|
aboutOwner?: OwnerProfileBlock;
|
|
95
|
-
/** Per-spawn dormant-plugins list: plugins installed on disk but absent
|
|
96
|
-
* from `account.json.enabledPlugins`. Empty or absent suppresses the
|
|
97
|
-
* sentinel so the agent does not nudge against an empty set. */
|
|
98
51
|
dormantPlugins?: readonly DormantPlugin[];
|
|
99
52
|
}
|
|
100
53
|
export type PermissionMode = 'default' | 'acceptEdits' | 'plan' | 'auto';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pty-spawner.d.ts","sourceRoot":"","sources":["../src/pty-spawner.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAuCxD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,GACrB,yBAAyB,GACzB,qBAAqB,GACrB,2BAA2B,CAAA;AAE/B,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS,CAAA;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,cAAc,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,WAAW,CAAA;IACxB;;;;wBAIoB;IACpB,QAAQ,EAAE,aAAa,CAAA;IACvB;;yEAEqE;IACrE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAClD;;;kFAG8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,CAAA;AACxE,eAAO,MAAM,gBAAgB,EAAE,SAAS,cAAc,EAA+C,CAAA;AAErG,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CA8L/F;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqBzC"}
|
|
@@ -1,43 +1,72 @@
|
|
|
1
1
|
// Spawn a `claude --verbose` PTY child, capture the /remote-control URL,
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
2
|
+
// register the session keyed on the URL's bridge suffix, and return 200
|
|
3
|
+
// immediately. The PTY stream flows; Claude Code writes its intrinsic JSONL
|
|
4
|
+
// to ~/.<brand>/.claude/projects/<slug>/<intrinsic>.jsonl on the first
|
|
5
|
+
// operator turn — which may be seconds, minutes, or never. The jsonl-observer
|
|
6
|
+
// fires when that file appears and promotes the row to the intrinsic
|
|
7
|
+
// claudeSessionId without changing its surface identity.
|
|
7
8
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// inside this file: the PTY is registered in `store.addPending` while
|
|
15
|
-
// the URL is captured; the entry promotes into the main store on
|
|
16
|
-
// observation, or is removed on timeout or PTY exit before observe.
|
|
9
|
+
// The manager mints zero session ids of its own. The bridge suffix is the
|
|
10
|
+
// row's identifier from URL capture; the intrinsic id takes over for
|
|
11
|
+
// JSONL-bound routes once observation fires. /spawn no longer blocks on
|
|
12
|
+
// observation, so the `observe-timeout` failure mode (Task 065's loud-fail
|
|
13
|
+
// timer) is gone — an operator who clicks `+ New session` and then walks
|
|
14
|
+
// away does not get a killed PTY.
|
|
17
15
|
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// The `[claude-session-manager] spawn-failed reason=<…>` log line names
|
|
22
|
-
// the reason.
|
|
16
|
+
// Remaining spawn failure surfaces (all return 500 with `stderrTail`):
|
|
17
|
+
// which-claude-not-found, pty-spawn-failed, url-capture-timeout,
|
|
18
|
+
// bridge-suffix-unparseable, host-context-unresolved, identity-unresolved.
|
|
23
19
|
import { mkdirSync } from 'node:fs';
|
|
24
20
|
import { startUrlCapture } from './url-capture.js';
|
|
25
21
|
import { bridgeSuffixFromUrl } from './jsonl-path.js';
|
|
22
|
+
// CSI (Cursor / Style) escape sequence: ESC `[` <args> <final-letter>.
|
|
23
|
+
// Stripped from the PTY tail so failure logs are readable instead of an
|
|
24
|
+
// alphabet soup of `\x1b[1C`, `\x1b[38;5;246m`, etc.
|
|
25
|
+
const PTY_TAIL_CSI = /\x1b\[[0-9;?]*[A-Za-z]/g;
|
|
26
|
+
// 4 KiB rolling buffer is enough to show the welcome banner, the
|
|
27
|
+
// `/remote-control is active …` line, and any prompt or error message
|
|
28
|
+
// claude prints in the seconds between spawn and JSONL observation.
|
|
29
|
+
const PTY_TAIL_BYTES = 4 * 1024;
|
|
30
|
+
// Capped slice emitted into log lines (server.log) so a single failure
|
|
31
|
+
// line never balloons past ~2 KiB. The full tail still goes onto the wire
|
|
32
|
+
// (SpawnResult.stderrTail) so the UI can surface it.
|
|
33
|
+
const PTY_TAIL_LOG_BYTES = 1024;
|
|
34
|
+
function attachPtyTail(pty) {
|
|
35
|
+
let buf = '';
|
|
36
|
+
let sub = pty.onData((data) => {
|
|
37
|
+
buf += data.replace(PTY_TAIL_CSI, '');
|
|
38
|
+
if (buf.length > PTY_TAIL_BYTES)
|
|
39
|
+
buf = buf.slice(buf.length - PTY_TAIL_BYTES);
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
getTail: () => buf,
|
|
43
|
+
dispose: () => {
|
|
44
|
+
if (sub) {
|
|
45
|
+
sub.dispose();
|
|
46
|
+
sub = null;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function formatTailForLog(tail) {
|
|
52
|
+
const trimmed = tail.length > PTY_TAIL_LOG_BYTES ? tail.slice(-PTY_TAIL_LOG_BYTES) : tail;
|
|
53
|
+
return JSON.stringify(trimmed);
|
|
54
|
+
}
|
|
26
55
|
import { composeAppendSystemPrompt, } from './system-prompt.js';
|
|
27
56
|
export const PERMISSION_MODES = ['default', 'acceptEdits', 'plan', 'auto'];
|
|
28
57
|
export async function spawnClaudeSession(deps, args) {
|
|
29
58
|
const startedAt = new Date().toISOString();
|
|
30
59
|
const start = Date.now();
|
|
31
|
-
const
|
|
60
|
+
const composedHost = deps.tunnelUrlOverride !== undefined
|
|
61
|
+
? { ...deps.host, tunnelUrl: deps.tunnelUrlOverride }
|
|
62
|
+
: deps.host;
|
|
63
|
+
const composed = composeAppendSystemPrompt(composedHost, { accountDir: deps.accountDir, role: args.role }, { aboutOwner: args.aboutOwner, dormantPlugins: args.dormantPlugins });
|
|
32
64
|
if (!composed.ok) {
|
|
33
65
|
if (composed.reason === 'host-unresolved') {
|
|
34
66
|
const stderrTail = deps.host.lanIPv4Diagnostic ?? 'append-system-prompt unresolved';
|
|
35
67
|
deps.logger(`spawn-failed reason=host-context-unresolved stderr-tail=${JSON.stringify(stderrTail)}`);
|
|
36
68
|
return { ok: false, reason: 'host-context-unresolved', stderrTail };
|
|
37
69
|
}
|
|
38
|
-
// Split the `<path>:<code>` detail into separate file= and err= fields
|
|
39
|
-
// so an operator can grep either independently. stderrTail keeps the
|
|
40
|
-
// joined form per task contract.
|
|
41
70
|
const sep = composed.detail.lastIndexOf(':');
|
|
42
71
|
const file = sep > 0 ? composed.detail.slice(0, sep) : composed.detail;
|
|
43
72
|
const err = sep > 0 ? composed.detail.slice(sep + 1) : '';
|
|
@@ -45,6 +74,7 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
45
74
|
return { ok: false, reason: 'identity-unresolved', stderrTail: composed.detail };
|
|
46
75
|
}
|
|
47
76
|
const appendSystemPrompt = composed.block;
|
|
77
|
+
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}`);
|
|
48
78
|
const argv = [
|
|
49
79
|
'--verbose',
|
|
50
80
|
'--remote-control',
|
|
@@ -59,18 +89,11 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
59
89
|
argv.push('--channels', ch);
|
|
60
90
|
}
|
|
61
91
|
}
|
|
62
|
-
// per-role tool-allowlist argv. The set is precomputed at boot
|
|
63
|
-
// and never inferred per call; this loop just renders it. Sorted output
|
|
64
|
-
// gives byte-stable argv for snapshot tests and grep-friendly log lines.
|
|
65
92
|
const allowedSet = args.role === 'public' ? deps.toolSurface.public : deps.toolSurface.admin;
|
|
66
93
|
const allowed = Array.from(allowedSet).sort();
|
|
67
94
|
for (const tool of allowed) {
|
|
68
95
|
argv.push('--allowed-tools', tool);
|
|
69
96
|
}
|
|
70
|
-
// Observability — sample up to 5 excluded tool names so an operator
|
|
71
|
-
// grepping the spawn log can see at a glance what a public role cannot
|
|
72
|
-
// touch. Admin role excludes nothing; the field is still emitted (empty)
|
|
73
|
-
// so the line shape is uniform across roles.
|
|
74
97
|
const excludedSample = args.role === 'public'
|
|
75
98
|
? Array.from(deps.toolSurface.admin).filter((t) => !deps.toolSurface.public.has(t)).sort().slice(0, 5).join(',')
|
|
76
99
|
: '';
|
|
@@ -78,16 +101,13 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
78
101
|
if (args.permissionMode && args.permissionMode !== 'default') {
|
|
79
102
|
argv.push('--permission-mode', args.permissionMode);
|
|
80
103
|
}
|
|
81
|
-
// public-chat attachment passthrough. Pre-create the per-session
|
|
82
|
-
// upload dir (so --add-dir does not fail on a missing path), then grant
|
|
83
|
-
// claude scoped Read access to it. The Read allow-rule mirrors the dir, so
|
|
84
|
-
// a `Read("/etc/passwd")` call from the PTY is refused by claude's
|
|
85
|
-
// permissions layer regardless of any operator instruction in the turn.
|
|
86
104
|
if (args.role === 'public' && args.attachmentDir) {
|
|
87
105
|
mkdirSync(args.attachmentDir, { recursive: true });
|
|
88
106
|
argv.push('--add-dir', args.attachmentDir);
|
|
89
107
|
argv.push('--allowed-tools', `Read(${args.attachmentDir}/**)`);
|
|
90
108
|
}
|
|
109
|
+
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'}`);
|
|
110
|
+
const ptySpawnStart = Date.now();
|
|
91
111
|
let pty;
|
|
92
112
|
try {
|
|
93
113
|
pty = deps.spawnPty(deps.claudeBin, argv, {
|
|
@@ -99,110 +119,95 @@ export async function spawnClaudeSession(deps, args) {
|
|
|
99
119
|
const e = err;
|
|
100
120
|
const reason = e.code === 'ENOENT' ? 'which-claude-not-found' : 'pty-spawn-failed';
|
|
101
121
|
const stderrTail = e.message?.slice(-200) ?? '';
|
|
102
|
-
deps.logger(`spawn-failed reason=${reason} stderr-tail=${JSON.stringify(stderrTail)}`);
|
|
122
|
+
deps.logger(`spawn-failed reason=${reason} stderr-tail=${JSON.stringify(stderrTail)} pty-spawn-ms=${Date.now() - ptySpawnStart}`);
|
|
103
123
|
return { ok: false, reason, stderrTail };
|
|
104
124
|
}
|
|
125
|
+
deps.logger(`pty-spawned pid=${pty.pid} ms=${Date.now() - ptySpawnStart}`);
|
|
126
|
+
const tail = attachPtyTail(pty);
|
|
105
127
|
return await new Promise((resolve) => {
|
|
128
|
+
let settled = false;
|
|
129
|
+
const settle = (outcome) => {
|
|
130
|
+
if (settled)
|
|
131
|
+
return;
|
|
132
|
+
settled = true;
|
|
133
|
+
resolve(outcome);
|
|
134
|
+
};
|
|
106
135
|
startUrlCapture({
|
|
107
136
|
pty,
|
|
108
137
|
timeoutMs: deps.urlCaptureTimeoutMs,
|
|
109
138
|
logger: deps.logger,
|
|
110
139
|
onUrl: (url) => {
|
|
111
140
|
const bridgeSuffix = bridgeSuffixFromUrl(url);
|
|
141
|
+
deps.logger(`bridge-suffix-extracted suffix=${bridgeSuffix ?? 'null'} url=${url}`);
|
|
112
142
|
if (!bridgeSuffix) {
|
|
113
|
-
// Without a bridge suffix the observer cannot bind, the session
|
|
114
|
-
// cannot be promoted, and the PTY would hang as an orphan.
|
|
115
|
-
// Loud-fail.
|
|
116
143
|
pty.kill('SIGKILL');
|
|
117
|
-
|
|
118
|
-
|
|
144
|
+
const stderrTail = tail.getTail();
|
|
145
|
+
deps.logger(`spawn-failed reason=bridge-suffix-unparseable url=${url} stderr-tail=${formatTailForLog(stderrTail)}`);
|
|
146
|
+
settle({ ok: false, reason: 'bridge-suffix-unparseable', stderrTail });
|
|
119
147
|
return;
|
|
120
148
|
}
|
|
121
|
-
const
|
|
149
|
+
const session = {
|
|
122
150
|
bridgeSuffix,
|
|
151
|
+
claudeSessionId: null,
|
|
123
152
|
pid: pty.pid,
|
|
124
153
|
url,
|
|
125
154
|
startedAt,
|
|
126
155
|
senderId: args.senderId,
|
|
127
156
|
role: args.role,
|
|
128
157
|
channel: args.channel,
|
|
158
|
+
jsonlPath: null,
|
|
129
159
|
pty,
|
|
130
160
|
exited: false,
|
|
131
161
|
};
|
|
132
|
-
deps.store.addPending(
|
|
162
|
+
deps.store.addPending(session);
|
|
163
|
+
// Spawn-response side: respond on URL capture, no observer wait.
|
|
164
|
+
// The observation runs in the background and promotes the row when
|
|
165
|
+
// the first operator turn lands. `wait-ms` on `jsonl-observed` is
|
|
166
|
+
// unbounded by design — high values are the normal idle-then-typed
|
|
167
|
+
// case, not a fault.
|
|
133
168
|
const observation = deps.observer.observe({ bridgeSuffix });
|
|
134
|
-
let timer = null;
|
|
135
|
-
let settled = false;
|
|
136
|
-
const settle = (outcome) => {
|
|
137
|
-
if (settled)
|
|
138
|
-
return;
|
|
139
|
-
settled = true;
|
|
140
|
-
if (timer)
|
|
141
|
-
clearTimeout(timer);
|
|
142
|
-
resolve(outcome);
|
|
143
|
-
};
|
|
144
|
-
// PTY exit in the gap between URL capture and observation: drop
|
|
145
|
-
// the pending entry, cancel the observation, surface a hard
|
|
146
|
-
// error to the caller (no orphan). After promotion, the session
|
|
147
|
-
// installs its own onExit hook to flip the StoredSession.exited
|
|
148
|
-
// flag (see observation.promise.then below).
|
|
149
|
-
pty.onExit(() => {
|
|
150
|
-
pending.exited = true;
|
|
151
|
-
if (!settled) {
|
|
152
|
-
deps.store.removePending(bridgeSuffix);
|
|
153
|
-
observation.cancel();
|
|
154
|
-
deps.logger(`spawn-failed reason=pty-exited-before-observe bridgeSuffix=${bridgeSuffix}`);
|
|
155
|
-
settle({ ok: false, reason: 'pty-exited-before-observe', stderrTail: '' });
|
|
156
|
-
}
|
|
157
|
-
deps.logger(`kill pid=${pty.pid} reason=process-exited exit-code=0`);
|
|
158
|
-
});
|
|
159
|
-
// observe-loud-fail timer. Default 5 s; tests use
|
|
160
|
-
// shorter values via `observeTimeoutMs`.
|
|
161
|
-
timer = setTimeout(() => {
|
|
162
|
-
if (settled)
|
|
163
|
-
return;
|
|
164
|
-
deps.store.removePending(bridgeSuffix);
|
|
165
|
-
observation.cancel();
|
|
166
|
-
pty.kill('SIGKILL');
|
|
167
|
-
deps.logger(`spawn-await-observe-timeout bridgeSuffix=${bridgeSuffix} timeoutMs=${deps.observeTimeoutMs}`);
|
|
168
|
-
settle({ ok: false, reason: 'observe-timeout', stderrTail: '' });
|
|
169
|
-
}, deps.observeTimeoutMs);
|
|
170
169
|
observation.promise.then((observed) => {
|
|
171
|
-
if (settled)
|
|
172
|
-
return;
|
|
173
170
|
if (!observed) {
|
|
174
|
-
// Observer
|
|
175
|
-
//
|
|
171
|
+
// Observer cancelled (e.g. operator deleted the row before
|
|
172
|
+
// typing). Nothing to do — pending row is already gone.
|
|
176
173
|
return;
|
|
177
174
|
}
|
|
178
|
-
const
|
|
179
|
-
if (!
|
|
180
|
-
//
|
|
181
|
-
// microtask landed. Whichever branch fired has already settled.
|
|
175
|
+
const promoted = deps.store.promote(bridgeSuffix, observed.claudeSessionId, observed.jsonlPath);
|
|
176
|
+
if (!promoted) {
|
|
177
|
+
// Row was removed before promotion landed; drop the observation.
|
|
182
178
|
return;
|
|
183
179
|
}
|
|
184
|
-
// After promotion, attach the session's exit hook to the main-
|
|
185
|
-
// store entry so subsequent pty exits flip its `exited` flag and
|
|
186
|
-
// detach the audit watcher via the http-server onExit path.
|
|
187
|
-
pty.onExit(() => {
|
|
188
|
-
session.exited = true;
|
|
189
|
-
});
|
|
190
180
|
const waitMs = Date.now() - start;
|
|
191
|
-
deps.logger(`jsonl-observed pid=${pty.pid} sessionId=${observed.claudeSessionId} path=${observed.jsonlPath}`);
|
|
192
|
-
deps.logger(`
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
181
|
+
deps.logger(`jsonl-observed pid=${pty.pid} sessionId=${observed.claudeSessionId} bridgeSuffix=${bridgeSuffix} path=${observed.jsonlPath} wait-ms=${waitMs}`);
|
|
182
|
+
deps.logger(`session-id-promoted bridgeSuffix=${bridgeSuffix} intrinsic=${observed.claudeSessionId} pid=${pty.pid}`);
|
|
183
|
+
deps.logger(`[pty-spawn] sessionId=${observed.claudeSessionId} 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'}`);
|
|
184
|
+
deps.onJsonlObserved?.(promoted);
|
|
185
|
+
});
|
|
186
|
+
// PTY exit: flip the exited flag and cancel the observation. No
|
|
187
|
+
// hard error here — by design the PTY may outlive any number of
|
|
188
|
+
// operator-idle periods; only after promotion is the JSONL useful.
|
|
189
|
+
pty.onExit((e) => {
|
|
190
|
+
session.exited = true;
|
|
191
|
+
const stderrTail = tail.getTail();
|
|
192
|
+
tail.dispose();
|
|
193
|
+
observation.cancel();
|
|
194
|
+
if (session.claudeSessionId === null) {
|
|
195
|
+
// never typed → drop the pending row silently
|
|
196
|
+
deps.store.remove(bridgeSuffix);
|
|
197
|
+
deps.logger(`session-closed-idle bridgeSuffix=${bridgeSuffix} pid=${pty.pid}`);
|
|
198
|
+
}
|
|
199
|
+
deps.logger(`kill pid=${pty.pid} reason=process-exited exit-code=${e.exitCode} signal=${e.signal ?? 'none'} stderr-tail=${formatTailForLog(stderrTail)}`);
|
|
200
200
|
});
|
|
201
|
+
const responseMs = Date.now() - start;
|
|
202
|
+
deps.logger(`spawn-response-returned bridgeSuffix=${bridgeSuffix} pid=${pty.pid} ms=${responseMs}`);
|
|
203
|
+
deps.logger(`spawn pid=${pty.pid} sessionUrl=${url} senderId=${args.senderId} role=${args.role} channel=${args.channel} permissionMode=${args.permissionMode ?? 'default'} latency-ms=${responseMs}`);
|
|
204
|
+
settle({ ok: true, session });
|
|
201
205
|
},
|
|
202
206
|
onTimeout: () => {
|
|
203
207
|
pty.kill('SIGKILL');
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
const stderrTail = tail.getTail();
|
|
209
|
+
deps.logger(`spawn-failed reason=url-capture-timeout stderr-tail=${formatTailForLog(stderrTail)}`);
|
|
210
|
+
settle({ ok: false, reason: 'url-capture-timeout', stderrTail });
|
|
206
211
|
},
|
|
207
212
|
});
|
|
208
213
|
});
|