runpane 2.4.136 → 2.4.137
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/README.md +34 -3
- package/dist/agentContext.d.ts.map +1 -1
- package/dist/agentContext.js +72 -2
- package/dist/agentContext.js.map +1 -1
- package/dist/agentTasks.d.ts +1 -1
- package/dist/agentTasks.d.ts.map +1 -1
- package/dist/agentTasks.js +22 -4
- package/dist/agentTasks.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +17 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +136 -3
- package/dist/commands.js.map +1 -1
- package/dist/docs-index.json +1 -1
- package/dist/generated/contract.d.ts +1310 -173
- package/dist/generated/contract.d.ts.map +1 -1
- package/dist/generated/contract.js +2405 -280
- package/dist/generated/contract.js.map +1 -1
- package/dist/localControl.d.ts +65 -3
- package/dist/localControl.d.ts.map +1 -1
- package/dist/localControl.js +560 -27
- package/dist/localControl.js.map +1 -1
- package/dist/watchLines.d.ts +19 -0
- package/dist/watchLines.d.ts.map +1 -1
- package/dist/watchLines.js +31 -0
- package/dist/watchLines.js.map +1 -1
- package/package.json +1 -1
package/dist/localControl.js
CHANGED
|
@@ -15,6 +15,9 @@ exports.runSessionsSetAgent = runSessionsSetAgent;
|
|
|
15
15
|
exports.runSessionsAssociate = runSessionsAssociate;
|
|
16
16
|
exports.runSessionsDetach = runSessionsDetach;
|
|
17
17
|
exports.runSessionsOverview = runSessionsOverview;
|
|
18
|
+
exports.runLockAcquire = runLockAcquire;
|
|
19
|
+
exports.runLockRelease = runLockRelease;
|
|
20
|
+
exports.runLockList = runLockList;
|
|
18
21
|
exports.runPanesCost = runPanesCost;
|
|
19
22
|
exports.runWorkspaceState = runWorkspaceState;
|
|
20
23
|
exports.runWatch = runWatch;
|
|
@@ -29,13 +32,19 @@ exports.runPanelsCreate = runPanelsCreate;
|
|
|
29
32
|
exports.runPanelsOutput = runPanelsOutput;
|
|
30
33
|
exports.runPanelsInput = runPanelsInput;
|
|
31
34
|
exports.runPanelsScreen = runPanelsScreen;
|
|
35
|
+
exports.runPanelsLastMessage = runPanelsLastMessage;
|
|
36
|
+
exports.runReport = runReport;
|
|
32
37
|
exports.runPanelsSubmit = runPanelsSubmit;
|
|
38
|
+
exports.markSuggestionLine = markSuggestionLine;
|
|
39
|
+
exports.printPromptNotes = printPromptNotes;
|
|
33
40
|
exports.runPanelsSubmitComposer = runPanelsSubmitComposer;
|
|
34
41
|
exports.runPanelsWait = runPanelsWait;
|
|
35
42
|
exports.runAgentsDoctor = runAgentsDoctor;
|
|
36
43
|
exports.buildPanelInputRequest = buildPanelInputRequest;
|
|
37
44
|
exports.buildPaneCreateRequest = buildPaneCreateRequest;
|
|
45
|
+
const node_crypto_1 = require("node:crypto");
|
|
38
46
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
47
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
39
48
|
const node_process_1 = require("node:process");
|
|
40
49
|
const promises_1 = require("node:readline/promises");
|
|
41
50
|
const boundaryDecoder_1 = require("./boundaryDecoder");
|
|
@@ -65,6 +74,7 @@ const paneSummarySchema = boundaryDecoder_1.boundary.object({
|
|
|
65
74
|
name: boundaryDecoder_1.boundary.string,
|
|
66
75
|
status: boundaryDecoder_1.boundary.string,
|
|
67
76
|
agentStatus: boundaryDecoder_1.boundary.enumeration('active', 'idle'),
|
|
77
|
+
agentState: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('ready', 'working', 'blocked', 'none')),
|
|
68
78
|
worktreePath: boundaryDecoder_1.boundary.string,
|
|
69
79
|
repoId: boundaryDecoder_1.boundary.number,
|
|
70
80
|
repoName: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
@@ -76,7 +86,7 @@ const paneSummarySchema = boundaryDecoder_1.boundary.object({
|
|
|
76
86
|
ownership: boundaryDecoder_1.boundary.enumeration('pane', 'external'),
|
|
77
87
|
});
|
|
78
88
|
const panelBlockedSchema = boundaryDecoder_1.boundary.object({
|
|
79
|
-
kind: boundaryDecoder_1.boundary.enumeration('codex-update', 'agent-prompt', 'submission_unverified', 'unknown'),
|
|
89
|
+
kind: boundaryDecoder_1.boundary.enumeration('codex-update', 'agent-prompt', 'submission_unverified', 'composer-unknown', 'unknown'),
|
|
80
90
|
message: boundaryDecoder_1.boundary.string,
|
|
81
91
|
suggestedCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
82
92
|
});
|
|
@@ -100,6 +110,14 @@ const panelReadinessSchema = boundaryDecoder_1.boundary.object({
|
|
|
100
110
|
nextCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
101
111
|
});
|
|
102
112
|
const verificationSchema = boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('observed', 'unverifiable'));
|
|
113
|
+
const deliverySchema = boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({
|
|
114
|
+
state: boundaryDecoder_1.boundary.enumeration('taken', 'queued', 'in-composer', 'unknown'),
|
|
115
|
+
evidence: boundaryDecoder_1.boundary.enumeration('transcript', 'screen', 'argv'),
|
|
116
|
+
}));
|
|
117
|
+
const promptWarningsSchema = boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.object({
|
|
118
|
+
code: boundaryDecoder_1.boundary.enumeration('leading-bang-runs-shell', 'leading-hash-memory', 'leading-slash-command', 'leading-at-mention'),
|
|
119
|
+
message: boundaryDecoder_1.boundary.string,
|
|
120
|
+
})));
|
|
103
121
|
const initialInputSchema = boundaryDecoder_1.boundary.object({
|
|
104
122
|
delivered: boundaryDecoder_1.boundary.boolean,
|
|
105
123
|
submitted: boundaryDecoder_1.boundary.boolean,
|
|
@@ -108,6 +126,7 @@ const initialInputSchema = boundaryDecoder_1.boundary.object({
|
|
|
108
126
|
sequenceName: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('codex-ctrl-enter-cr', 'enter-cr', 'argument')),
|
|
109
127
|
verifiedSubmitted: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
110
128
|
verification: verificationSchema,
|
|
129
|
+
delivery: deliverySchema,
|
|
111
130
|
staged: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
112
131
|
attempts: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
113
132
|
sentAt: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
@@ -130,7 +149,52 @@ const archiveSafetySchema = boundaryDecoder_1.boundary.object({
|
|
|
130
149
|
sha: boundaryDecoder_1.boundary.string,
|
|
131
150
|
subject: boundaryDecoder_1.boundary.string,
|
|
132
151
|
}))),
|
|
152
|
+
reason: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('external-worktree', 'main-repo', 'missing-project-context', 'git-error')),
|
|
153
|
+
worktreeWillRemain: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.literal(true)),
|
|
154
|
+
upstreamGone: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
155
|
+
mergedViaPr: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({
|
|
156
|
+
number: boundaryDecoder_1.boundary.number,
|
|
157
|
+
headOid: boundaryDecoder_1.boundary.string,
|
|
158
|
+
})),
|
|
159
|
+
});
|
|
160
|
+
const agentReportFields = {
|
|
161
|
+
state: boundaryDecoder_1.boundary.enumeration('ready', 'blocked', 'failed', 'done'),
|
|
162
|
+
pr: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
163
|
+
head: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
164
|
+
summary: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
165
|
+
summaryTruncated: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.literal(true)),
|
|
166
|
+
summaryPath: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
167
|
+
question: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
168
|
+
reportedAt: boundaryDecoder_1.boundary.string,
|
|
169
|
+
};
|
|
170
|
+
const agentReportSchema = boundaryDecoder_1.boundary.object(agentReportFields);
|
|
171
|
+
const reportResultSchema = boundaryDecoder_1.boundary.object({
|
|
172
|
+
ok: boundaryDecoder_1.boundary.literal(true),
|
|
173
|
+
generation: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
174
|
+
paneId: boundaryDecoder_1.boundary.string,
|
|
175
|
+
panelId: boundaryDecoder_1.boundary.string,
|
|
176
|
+
report: agentReportSchema,
|
|
177
|
+
sessionIds: boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.string),
|
|
133
178
|
});
|
|
179
|
+
const panelLastMessageResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder_1.boundary.object({
|
|
180
|
+
ok: boundaryDecoder_1.boundary.literal(true),
|
|
181
|
+
panelId: boundaryDecoder_1.boundary.string,
|
|
182
|
+
paneId: boundaryDecoder_1.boundary.string,
|
|
183
|
+
agentType: boundaryDecoder_1.boundary.enumeration('claude', 'codex'),
|
|
184
|
+
text: boundaryDecoder_1.boundary.string,
|
|
185
|
+
length: boundaryDecoder_1.boundary.number,
|
|
186
|
+
limit: boundaryDecoder_1.boundary.number,
|
|
187
|
+
truncated: boundaryDecoder_1.boundary.boolean,
|
|
188
|
+
}), boundaryDecoder_1.boundary.object({
|
|
189
|
+
ok: boundaryDecoder_1.boundary.literal(false),
|
|
190
|
+
panelId: boundaryDecoder_1.boundary.string,
|
|
191
|
+
paneId: boundaryDecoder_1.boundary.string,
|
|
192
|
+
reason: boundaryDecoder_1.boundary.literal('transcript-unavailable'),
|
|
193
|
+
message: boundaryDecoder_1.boundary.string,
|
|
194
|
+
}));
|
|
195
|
+
const archiveBlockCodeSchema = boundaryDecoder_1.boundary.enumeration('uncommitted-changes', 'unpushed-commits', 'uncommitted-and-unpushed', 'status-unknown');
|
|
196
|
+
const worktreeCleanupSchema = boundaryDecoder_1.boundary.enumeration('completed', 'failed', 'timeout', 'not-applicable');
|
|
197
|
+
const trashDeletionSchema = boundaryDecoder_1.boundary.enumeration('pending', 'done');
|
|
134
198
|
const panelSummarySchema = boundaryDecoder_1.boundary.object({
|
|
135
199
|
id: boundaryDecoder_1.boundary.string,
|
|
136
200
|
panelId: boundaryDecoder_1.boundary.string,
|
|
@@ -140,10 +204,13 @@ const panelSummarySchema = boundaryDecoder_1.boundary.object({
|
|
|
140
204
|
active: boundaryDecoder_1.boundary.boolean,
|
|
141
205
|
initialized: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
142
206
|
agentType: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
207
|
+
agentDetection: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('declared', 'command', 'process', 'screen')),
|
|
208
|
+
launchCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
143
209
|
isCliPanel: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
144
210
|
position: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
145
211
|
createdAt: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
146
212
|
lastActiveAt: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
213
|
+
report: boundaryDecoder_1.boundary.optional(agentReportSchema),
|
|
147
214
|
});
|
|
148
215
|
const repoListResultSchema = boundaryDecoder_1.boundary.object({
|
|
149
216
|
ok: boundaryDecoder_1.boundary.literal(true),
|
|
@@ -256,6 +323,55 @@ const orchestrationPaneOverviewSchema = boundaryDecoder_1.boundary.object({
|
|
|
256
323
|
prTitle: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
257
324
|
prState: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
258
325
|
})),
|
|
326
|
+
report: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({ ...agentReportFields, panelId: boundaryDecoder_1.boundary.nonEmptyString })),
|
|
327
|
+
});
|
|
328
|
+
const lockOwnerSchema = boundaryDecoder_1.boundary.object({
|
|
329
|
+
kind: boundaryDecoder_1.boundary.enumeration('pane', 'external'),
|
|
330
|
+
paneId: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.nonEmptyString),
|
|
331
|
+
panelId: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.nonEmptyString),
|
|
332
|
+
label: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
333
|
+
});
|
|
334
|
+
const lockRecordSchema = boundaryDecoder_1.boundary.object({
|
|
335
|
+
name: boundaryDecoder_1.boundary.nonEmptyString,
|
|
336
|
+
scope: boundaryDecoder_1.boundary.enumeration('session', 'global'),
|
|
337
|
+
sessionId: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.nonEmptyString),
|
|
338
|
+
owner: lockOwnerSchema,
|
|
339
|
+
note: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
340
|
+
acquiredAt: boundaryDecoder_1.boundary.nonEmptyString,
|
|
341
|
+
expiresAt: boundaryDecoder_1.boundary.nonEmptyString,
|
|
342
|
+
ttlMs: boundaryDecoder_1.boundary.number,
|
|
343
|
+
});
|
|
344
|
+
const lockAcquireResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder_1.boundary.object({
|
|
345
|
+
ok: boundaryDecoder_1.boundary.literal(true),
|
|
346
|
+
acquired: boundaryDecoder_1.boundary.literal(true),
|
|
347
|
+
renewed: boundaryDecoder_1.boundary.boolean,
|
|
348
|
+
waitedMs: boundaryDecoder_1.boundary.number,
|
|
349
|
+
lock: lockRecordSchema,
|
|
350
|
+
}), boundaryDecoder_1.boundary.object({
|
|
351
|
+
ok: boundaryDecoder_1.boundary.literal(false),
|
|
352
|
+
acquired: boundaryDecoder_1.boundary.literal(false),
|
|
353
|
+
timedOut: boundaryDecoder_1.boundary.boolean,
|
|
354
|
+
waitedMs: boundaryDecoder_1.boundary.number,
|
|
355
|
+
heldBy: lockOwnerSchema,
|
|
356
|
+
expiresAt: boundaryDecoder_1.boundary.nonEmptyString,
|
|
357
|
+
lock: lockRecordSchema,
|
|
358
|
+
}));
|
|
359
|
+
const lockReleaseResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder_1.boundary.object({
|
|
360
|
+
ok: boundaryDecoder_1.boundary.literal(true),
|
|
361
|
+
released: boundaryDecoder_1.boundary.boolean,
|
|
362
|
+
forced: boundaryDecoder_1.boundary.boolean,
|
|
363
|
+
lock: boundaryDecoder_1.boundary.optional(lockRecordSchema),
|
|
364
|
+
}), boundaryDecoder_1.boundary.object({
|
|
365
|
+
ok: boundaryDecoder_1.boundary.literal(false),
|
|
366
|
+
released: boundaryDecoder_1.boundary.literal(false),
|
|
367
|
+
reason: boundaryDecoder_1.boundary.literal('not-owner'),
|
|
368
|
+
heldBy: lockOwnerSchema,
|
|
369
|
+
expiresAt: boundaryDecoder_1.boundary.nonEmptyString,
|
|
370
|
+
lock: lockRecordSchema,
|
|
371
|
+
}));
|
|
372
|
+
const lockListResultSchema = boundaryDecoder_1.boundary.object({
|
|
373
|
+
ok: boundaryDecoder_1.boundary.literal(true),
|
|
374
|
+
locks: boundaryDecoder_1.boundary.array(lockRecordSchema),
|
|
259
375
|
});
|
|
260
376
|
const runpaneSessionOverviewResultSchema = boundaryDecoder_1.boundary.object({
|
|
261
377
|
ok: boundaryDecoder_1.boundary.literal(true),
|
|
@@ -268,6 +384,7 @@ const runpaneSessionOverviewResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
268
384
|
freshness: boundaryDecoder_1.boundary.enumeration('current', 'stale'),
|
|
269
385
|
})),
|
|
270
386
|
refreshedAt: boundaryDecoder_1.boundary.nonEmptyString,
|
|
387
|
+
locks: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.array(lockRecordSchema)),
|
|
271
388
|
});
|
|
272
389
|
function orchestrationReportSchemaFields() {
|
|
273
390
|
return {
|
|
@@ -367,6 +484,8 @@ exports.paneCreateResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
367
484
|
ok: boundaryDecoder_1.boundary.boolean,
|
|
368
485
|
error: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
369
486
|
})),
|
|
487
|
+
promptFile: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
488
|
+
warnings: promptWarningsSchema,
|
|
370
489
|
}), boundaryDecoder_1.boundary.object({
|
|
371
490
|
ok: boundaryDecoder_1.boundary.literal(false),
|
|
372
491
|
index: boundaryDecoder_1.boundary.number,
|
|
@@ -385,7 +504,7 @@ const paneArchiveResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder
|
|
|
385
504
|
generation: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
386
505
|
paneId: boundaryDecoder_1.boundary.string,
|
|
387
506
|
blocked: boundaryDecoder_1.boundary.object({
|
|
388
|
-
code:
|
|
507
|
+
code: archiveBlockCodeSchema,
|
|
389
508
|
message: boundaryDecoder_1.boundary.string,
|
|
390
509
|
safetyCheck: archiveSafetySchema,
|
|
391
510
|
}),
|
|
@@ -398,7 +517,7 @@ const paneArchiveResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder
|
|
|
398
517
|
forced: boundaryDecoder_1.boundary.boolean,
|
|
399
518
|
safetyCheck: archiveSafetySchema,
|
|
400
519
|
blocked: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({
|
|
401
|
-
code:
|
|
520
|
+
code: archiveBlockCodeSchema,
|
|
402
521
|
message: boundaryDecoder_1.boundary.string,
|
|
403
522
|
safetyCheck: archiveSafetySchema,
|
|
404
523
|
})),
|
|
@@ -408,10 +527,35 @@ const paneArchiveResultSchema = boundaryDecoder_1.boundary.union(boundaryDecoder
|
|
|
408
527
|
paneId: boundaryDecoder_1.boundary.string,
|
|
409
528
|
archived: boundaryDecoder_1.boundary.literal(true),
|
|
410
529
|
forced: boundaryDecoder_1.boundary.boolean,
|
|
411
|
-
worktreeCleanup:
|
|
530
|
+
worktreeCleanup: worktreeCleanupSchema,
|
|
531
|
+
trashDeletion: boundaryDecoder_1.boundary.optional(trashDeletionSchema),
|
|
412
532
|
worktreePath: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
413
533
|
safetyCheck: archiveSafetySchema,
|
|
414
534
|
}));
|
|
535
|
+
const paneArchiveBulkResultSchema = boundaryDecoder_1.boundary.object({
|
|
536
|
+
ok: boundaryDecoder_1.boundary.boolean,
|
|
537
|
+
sessionId: boundaryDecoder_1.boundary.string,
|
|
538
|
+
merged: boundaryDecoder_1.boundary.literal(true),
|
|
539
|
+
dryRun: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.literal(true)),
|
|
540
|
+
removeWorktree: boundaryDecoder_1.boundary.boolean,
|
|
541
|
+
archived: boundaryDecoder_1.boundary.number,
|
|
542
|
+
skipped: boundaryDecoder_1.boundary.number,
|
|
543
|
+
failed: boundaryDecoder_1.boundary.number,
|
|
544
|
+
items: boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.object({
|
|
545
|
+
paneId: boundaryDecoder_1.boundary.string,
|
|
546
|
+
name: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
547
|
+
outcome: boundaryDecoder_1.boundary.enumeration('archived', 'would-archive', 'skipped', 'failed'),
|
|
548
|
+
skipped: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({
|
|
549
|
+
code: boundaryDecoder_1.boundary.enumeration('uncommitted-changes', 'unpushed-commits', 'uncommitted-and-unpushed', 'status-unknown', 'missing-pane', 'already-archived', 'main-repo'),
|
|
550
|
+
message: boundaryDecoder_1.boundary.string,
|
|
551
|
+
})),
|
|
552
|
+
error: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
553
|
+
safetyCheck: boundaryDecoder_1.boundary.optional(archiveSafetySchema),
|
|
554
|
+
worktreeCleanup: boundaryDecoder_1.boundary.optional(worktreeCleanupSchema),
|
|
555
|
+
trashDeletion: boundaryDecoder_1.boundary.optional(trashDeletionSchema),
|
|
556
|
+
worktreePath: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
557
|
+
})),
|
|
558
|
+
});
|
|
415
559
|
const panePinResultSchema = boundaryDecoder_1.boundary.object({
|
|
416
560
|
ok: boundaryDecoder_1.boundary.literal(true),
|
|
417
561
|
generation: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
@@ -452,6 +596,8 @@ const panelCreateResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
452
596
|
}),
|
|
453
597
|
readiness: boundaryDecoder_1.boundary.optional(panelReadinessSchema),
|
|
454
598
|
initialInput: boundaryDecoder_1.boundary.optional(initialInputSchema),
|
|
599
|
+
promptFile: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
600
|
+
warnings: promptWarningsSchema,
|
|
455
601
|
nextCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
456
602
|
});
|
|
457
603
|
const panelOutputResultSchema = boundaryDecoder_1.boundary.object({
|
|
@@ -490,6 +636,7 @@ exports.panelScreenResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
490
636
|
composer: boundaryDecoder_1.boundary.object({
|
|
491
637
|
isPresent: boundaryDecoder_1.boundary.boolean,
|
|
492
638
|
hasUndeliveredText: boundaryDecoder_1.boundary.boolean,
|
|
639
|
+
ghostText: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
493
640
|
}),
|
|
494
641
|
nextCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
495
642
|
});
|
|
@@ -503,8 +650,11 @@ exports.panelSubmitResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
503
650
|
sequenceName: boundaryDecoder_1.boundary.enumeration('codex-ctrl-enter-cr', 'enter-cr', 'tab'),
|
|
504
651
|
verifiedSubmitted: boundaryDecoder_1.boundary.boolean,
|
|
505
652
|
verification: verificationSchema,
|
|
653
|
+
delivery: deliverySchema,
|
|
506
654
|
sentAt: boundaryDecoder_1.boundary.string,
|
|
507
655
|
blocked: boundaryDecoder_1.boundary.optional(panelBlockedSchema),
|
|
656
|
+
promptFile: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
657
|
+
warnings: promptWarningsSchema,
|
|
508
658
|
nextCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
509
659
|
});
|
|
510
660
|
const panelSubmitComposerResultSchema = boundaryDecoder_1.boundary.object({
|
|
@@ -517,6 +667,7 @@ const panelSubmitComposerResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
517
667
|
sequenceName: boundaryDecoder_1.boundary.enumeration('codex-ctrl-enter-cr', 'enter-cr', 'tab'),
|
|
518
668
|
verifiedSubmitted: boundaryDecoder_1.boundary.boolean,
|
|
519
669
|
verification: verificationSchema,
|
|
670
|
+
delivery: deliverySchema,
|
|
520
671
|
sentAt: boundaryDecoder_1.boundary.string,
|
|
521
672
|
blocked: boundaryDecoder_1.boundary.optional(panelBlockedSchema),
|
|
522
673
|
nextCommand: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
@@ -554,7 +705,7 @@ const agentDoctorResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
554
705
|
})),
|
|
555
706
|
warnings: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.string)),
|
|
556
707
|
});
|
|
557
|
-
const workspaceEntryKindSchema = boundaryDecoder_1.boundary.enumeration('agent.ready', 'agent.busy', 'agent.blocked', 'agent.unknown', 'agent.idle', 'pane.created', 'pane.gone', 'panel.exited');
|
|
708
|
+
const workspaceEntryKindSchema = boundaryDecoder_1.boundary.enumeration('agent.ready', 'agent.busy', 'agent.blocked', 'agent.unknown', 'agent.idle', 'pane.created', 'pane.gone', 'panel.exited', 'pane.associated', 'pane.detached', 'pr.conflicted', 'pr.checks', 'pr.merged', 'agent.report');
|
|
558
709
|
const agentStateSchema = boundaryDecoder_1.boundary.enumeration('blocked', 'working', 'idle', 'unknown');
|
|
559
710
|
const workspacePanelSummarySchema = boundaryDecoder_1.boundary.object({
|
|
560
711
|
panelId: boundaryDecoder_1.boundary.string,
|
|
@@ -576,7 +727,7 @@ const workspaceEntrySchema = boundaryDecoder_1.boundary.object({
|
|
|
576
727
|
agentType: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
577
728
|
from: boundaryDecoder_1.boundary.optional(agentStateSchema),
|
|
578
729
|
to: boundaryDecoder_1.boundary.optional(agentStateSchema),
|
|
579
|
-
source: boundaryDecoder_1.boundary.enumeration('agent', 'exit', 'session'),
|
|
730
|
+
source: boundaryDecoder_1.boundary.enumeration('agent', 'exit', 'session', 'github'),
|
|
580
731
|
reason: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.nullable(boundaryDecoder_1.boundary.string)),
|
|
581
732
|
settledMs: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
582
733
|
idleMs: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
@@ -585,7 +736,14 @@ const workspaceEntrySchema = boundaryDecoder_1.boundary.object({
|
|
|
585
736
|
heldInputPresent: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
586
737
|
exitCode: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
587
738
|
baseline: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.literal(true)),
|
|
739
|
+
replay: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.literal(true)),
|
|
588
740
|
changedWhileAway: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
741
|
+
sessionId: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
742
|
+
sessionName: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
743
|
+
pr: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({ number: boundaryDecoder_1.boundary.number, url: boundaryDecoder_1.boundary.string, headOid: boundaryDecoder_1.boundary.string })),
|
|
744
|
+
checks: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('passed', 'failed')),
|
|
745
|
+
failingChecks: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.string)),
|
|
746
|
+
report: boundaryDecoder_1.boundary.optional(agentReportSchema),
|
|
589
747
|
panels: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.array(workspacePanelSummarySchema)),
|
|
590
748
|
});
|
|
591
749
|
exports.workspaceStateResultSchema = boundaryDecoder_1.boundary.object({
|
|
@@ -604,20 +762,24 @@ const workspaceWaitResultSchema = boundaryDecoder_1.boundary.object({
|
|
|
604
762
|
reset: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({
|
|
605
763
|
reason: boundaryDecoder_1.boundary.enumeration('first-use', 'epoch-changed', 'cursor-truncated', 'unknown-consumer'),
|
|
606
764
|
})),
|
|
765
|
+
session: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.object({ id: boundaryDecoder_1.boundary.string, name: boundaryDecoder_1.boundary.string })),
|
|
607
766
|
nextCommand: boundaryDecoder_1.boundary.string,
|
|
608
767
|
});
|
|
609
768
|
const repoSelectorSchema = boundaryDecoder_1.boundary.union(boundaryDecoder_1.boundary.nonEmptyString, boundaryDecoder_1.boundary.object({ id: boundaryDecoder_1.boundary.number }), boundaryDecoder_1.boundary.object({ path: boundaryDecoder_1.boundary.string }), boundaryDecoder_1.boundary.object({ name: boundaryDecoder_1.boundary.string }), boundaryDecoder_1.boundary.object({ active: boundaryDecoder_1.boundary.literal(true) }));
|
|
610
769
|
const paneToolInputSchema = boundaryDecoder_1.boundary.object({
|
|
611
770
|
agent: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
612
771
|
command: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
772
|
+
agentType: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
613
773
|
title: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
614
774
|
initialInput: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
775
|
+
initialInputAsFilePointer: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
615
776
|
});
|
|
616
777
|
const paneCreateRequestInputSchema = boundaryDecoder_1.boundary.object({
|
|
617
778
|
repo: repoSelectorSchema,
|
|
618
779
|
panes: boundaryDecoder_1.boundary.array(boundaryDecoder_1.boundary.object({
|
|
619
780
|
name: boundaryDecoder_1.boundary.string,
|
|
620
781
|
worktreeName: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
782
|
+
branch: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
621
783
|
baseBranch: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
622
784
|
sessionPrompt: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.string),
|
|
623
785
|
pinned: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
@@ -646,6 +808,8 @@ const paneAdoptRequestInputSchema = boundaryDecoder_1.boundary.object({
|
|
|
646
808
|
launch: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
647
809
|
})),
|
|
648
810
|
dryRun: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
811
|
+
waitReady: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
812
|
+
readyTimeoutMs: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.number),
|
|
649
813
|
noFocus: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
650
814
|
focus: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.boolean),
|
|
651
815
|
source: boundaryDecoder_1.boundary.optional(boundaryDecoder_1.boundary.enumeration('user', 'agent')),
|
|
@@ -775,9 +939,123 @@ async function runSessionsOverview(parsed) {
|
|
|
775
939
|
for (const pane of result.panes) {
|
|
776
940
|
const details = pane.missing ? 'missing' : pane.archived ? 'archived' : pane.panels.map(panel => `${panel.title}=${panel.state}`).join(', ') || 'no terminal panels';
|
|
777
941
|
console.log(` ${pane.name}: ${details}`);
|
|
942
|
+
if (pane.report) {
|
|
943
|
+
console.log(` report ${(0, watchLines_1.describeReport)(pane.report)} (panel ${pane.report.panelId}, ${pane.report.reportedAt})`);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
for (const lock of result.locks ?? []) {
|
|
947
|
+
console.log(` lock ${formatLockLine(lock)}`);
|
|
948
|
+
}
|
|
949
|
+
return 0;
|
|
950
|
+
}
|
|
951
|
+
/** One daemon call waits at most this long; longer waits chain calls, each blocking in the daemon. */
|
|
952
|
+
const LOCK_WAIT_PER_CALL_MS = 120_000;
|
|
953
|
+
async function runLockAcquire(parsed) {
|
|
954
|
+
const name = requireLockName(parsed, 'acquire');
|
|
955
|
+
if (parsed.lockTtlMs === undefined)
|
|
956
|
+
throw new Error('runpane lock acquire requires --ttl <duration>, such as --ttl 30m.');
|
|
957
|
+
const request = { name, ttlMs: parsed.lockTtlMs, note: parsed.note, owner: lockOwnerFromParsed(parsed, false) };
|
|
958
|
+
const waitMs = parsed.lockWaitMs ?? 0;
|
|
959
|
+
const startedAt = Date.now();
|
|
960
|
+
let result;
|
|
961
|
+
for (;;) {
|
|
962
|
+
const callWaitMs = Math.min(Math.max(0, waitMs - (Date.now() - startedAt)), LOCK_WAIT_PER_CALL_MS);
|
|
963
|
+
result = await (0, daemonClient_1.invokeDaemon)('runpane:locks:acquire', [{ ...request, waitMs: callWaitMs }], lockAcquireResultSchema, {
|
|
964
|
+
paneDir: parsed.paneDir,
|
|
965
|
+
timeoutMs: callWaitMs + 15_000,
|
|
966
|
+
});
|
|
967
|
+
// Only a call that waited out its whole window without the lock coming free chains another.
|
|
968
|
+
if (result.ok || !result.timedOut || Date.now() - startedAt >= waitMs)
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
const final = { ...result, waitedMs: Date.now() - startedAt };
|
|
972
|
+
if (parsed.json) {
|
|
973
|
+
printJson(final);
|
|
974
|
+
}
|
|
975
|
+
else if (final.ok) {
|
|
976
|
+
console.log(`${final.renewed ? 'Renewed' : 'Acquired'} lock ${formatLockLine(final.lock)}`);
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
console.log(`Lock ${final.lock.name} is held by ${formatLockOwner(final.heldBy)} until ${final.expiresAt}${final.lock.note ? ` (${final.lock.note})` : ''}.`);
|
|
980
|
+
}
|
|
981
|
+
return final.ok ? 0 : 1;
|
|
982
|
+
}
|
|
983
|
+
async function runLockRelease(parsed) {
|
|
984
|
+
const name = requireLockName(parsed, 'release');
|
|
985
|
+
const request = {
|
|
986
|
+
name,
|
|
987
|
+
force: parsed.force || undefined,
|
|
988
|
+
sessionId: parsed.sessionId?.trim() || undefined,
|
|
989
|
+
owner: lockOwnerFromParsed(parsed, parsed.force === true),
|
|
990
|
+
};
|
|
991
|
+
const result = await (0, daemonClient_1.invokeDaemon)('runpane:locks:release', [request], lockReleaseResultSchema, { paneDir: parsed.paneDir });
|
|
992
|
+
if (parsed.json) {
|
|
993
|
+
printJson(result);
|
|
994
|
+
}
|
|
995
|
+
else if (!result.ok) {
|
|
996
|
+
console.log(`Lock ${name} is held by ${formatLockOwner(result.heldBy)} until ${result.expiresAt}; only its owner can release it. Rerun with --force to release it anyway.`);
|
|
997
|
+
}
|
|
998
|
+
else if (result.released) {
|
|
999
|
+
console.log(`${result.forced ? 'Force-released' : 'Released'} lock ${name}.`);
|
|
778
1000
|
}
|
|
1001
|
+
else {
|
|
1002
|
+
console.log(`Lock ${name} was not held.`);
|
|
1003
|
+
}
|
|
1004
|
+
return result.ok ? 0 : 1;
|
|
1005
|
+
}
|
|
1006
|
+
async function runLockList(parsed) {
|
|
1007
|
+
const sessionId = parsed.sessionId?.trim() || undefined;
|
|
1008
|
+
const result = await (0, daemonClient_1.invokeDaemon)('runpane:locks:list', [{ sessionId }], lockListResultSchema, { paneDir: parsed.paneDir });
|
|
1009
|
+
if (parsed.json) {
|
|
1010
|
+
printJson(result);
|
|
1011
|
+
return 0;
|
|
1012
|
+
}
|
|
1013
|
+
for (const lock of result.locks)
|
|
1014
|
+
console.log(formatLockLine(lock));
|
|
1015
|
+
if (result.locks.length === 0)
|
|
1016
|
+
console.log('No locks held.');
|
|
779
1017
|
return 0;
|
|
780
1018
|
}
|
|
1019
|
+
function requireLockName(parsed, action) {
|
|
1020
|
+
const name = parsed.name?.trim();
|
|
1021
|
+
if (!name)
|
|
1022
|
+
throw new Error(`runpane lock ${action} requires --name <name>.`);
|
|
1023
|
+
return name;
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* The caller owns the lock: --pane/--panel when given, else the Pane terminal
|
|
1027
|
+
* it runs in ($PANE_SESSION_ID/$PANE_PANEL_ID). Outside Pane, --note names the owner.
|
|
1028
|
+
*/
|
|
1029
|
+
function lockOwnerFromParsed(parsed, forced) {
|
|
1030
|
+
const explicit = Boolean(parsed.paneId || parsed.panelId);
|
|
1031
|
+
const paneId = explicit ? parsed.paneId : process.env.PANE_SESSION_ID?.trim() || undefined;
|
|
1032
|
+
const panelId = explicit ? parsed.panelId : process.env.PANE_PANEL_ID?.trim() || undefined;
|
|
1033
|
+
const owner = {};
|
|
1034
|
+
if (paneId || panelId) {
|
|
1035
|
+
if (paneId)
|
|
1036
|
+
owner.paneId = paneId;
|
|
1037
|
+
if (panelId)
|
|
1038
|
+
owner.panelId = panelId;
|
|
1039
|
+
return owner;
|
|
1040
|
+
}
|
|
1041
|
+
const label = parsed.note?.trim();
|
|
1042
|
+
if (!label && !forced) {
|
|
1043
|
+
throw new Error('Outside a Pane terminal, pass --note <text> to say who holds the lock (or --pane/--panel to act for a Pane).');
|
|
1044
|
+
}
|
|
1045
|
+
if (label)
|
|
1046
|
+
owner.label = label;
|
|
1047
|
+
return owner;
|
|
1048
|
+
}
|
|
1049
|
+
function formatLockOwner(owner) {
|
|
1050
|
+
if (owner.kind === 'external')
|
|
1051
|
+
return `external "${owner.label ?? ''}"`;
|
|
1052
|
+
return owner.panelId ? `pane ${owner.paneId} panel ${owner.panelId}` : `pane ${owner.paneId}`;
|
|
1053
|
+
}
|
|
1054
|
+
function formatLockLine(lock) {
|
|
1055
|
+
const scope = lock.scope === 'session' ? `session ${lock.sessionId}` : 'global';
|
|
1056
|
+
const note = lock.note ? ` (${lock.note})` : '';
|
|
1057
|
+
return `${lock.name} [${scope}] held by ${formatLockOwner(lock.owner)} until ${lock.expiresAt}${note}`;
|
|
1058
|
+
}
|
|
781
1059
|
function sessionSelectorFromParsed(parsed) {
|
|
782
1060
|
const sessionId = parsed.sessionId?.trim();
|
|
783
1061
|
if (!sessionId)
|
|
@@ -867,12 +1145,21 @@ async function runWatch(parsed) {
|
|
|
867
1145
|
? undefined
|
|
868
1146
|
: parsed.agentsOnly || parsed.follow ? true : undefined;
|
|
869
1147
|
const includeHeldInput = parsed.includeHeldInput && !parsed.noHeldInput ? true : undefined;
|
|
1148
|
+
// Lines mode turns presence into STUCK; JSON mode passes heldInputPresent through as the equivalent.
|
|
870
1149
|
const includeHeldInputPresence = defaults.includeHeldInputPresence
|
|
871
|
-
&& !parsed.noHeldInput && parsed.follow
|
|
1150
|
+
&& !parsed.noHeldInput && parsed.follow ? true : undefined;
|
|
872
1151
|
const cadenceValueFlagPresent = (0, commands_1.hasCadenceValueFlag)(parsed);
|
|
873
1152
|
// Cadence state lives in the daemon per named consumer, so an anonymous follower names itself.
|
|
1153
|
+
// A Session watch is named after the Session, so it survives an orchestrator agent switch.
|
|
1154
|
+
const sessionCursor = parsed.sessionId ? sessionWatchCursorName(parsed.sessionId) : undefined;
|
|
1155
|
+
const panelCursor = process.env.PANE_PANEL_ID ? derivedWatchCursorName('panel', process.env.PANE_PANEL_ID) : undefined;
|
|
874
1156
|
const watchAs = parsed.watchAs
|
|
875
|
-
?? (parsed.follow ?
|
|
1157
|
+
?? (parsed.follow ? sessionCursor || panelCursor || (cadenceValueFlagPresent ? `follow-${process.pid}` : undefined) : undefined);
|
|
1158
|
+
// --quiet drops lines that only prove liveness; --self-test still prints its WATCH OK result.
|
|
1159
|
+
const emitControlLine = (line) => {
|
|
1160
|
+
if (!parsed.quiet)
|
|
1161
|
+
emitWatchLine(line);
|
|
1162
|
+
};
|
|
876
1163
|
const request = {
|
|
877
1164
|
as: watchAs,
|
|
878
1165
|
since: parsed.watchSince,
|
|
@@ -881,6 +1168,8 @@ async function runWatch(parsed) {
|
|
|
881
1168
|
limit: parsed.limit,
|
|
882
1169
|
kinds: parsed.watchKinds,
|
|
883
1170
|
paneIds: parsed.watchPaneIds,
|
|
1171
|
+
// The daemon resolves the Session (id or exact name) and re-reads its Panes on every read.
|
|
1172
|
+
session: parsed.sessionId,
|
|
884
1173
|
excludePaneIds: parsed.watchExcludePaneIds,
|
|
885
1174
|
repo: parsed.repo,
|
|
886
1175
|
nameContains: parsed.nameContains,
|
|
@@ -914,12 +1203,20 @@ async function runWatch(parsed) {
|
|
|
914
1203
|
timeoutMs: timeoutMs + 5_000,
|
|
915
1204
|
eventInclude: [],
|
|
916
1205
|
});
|
|
1206
|
+
if (request.session && !result.session) {
|
|
1207
|
+
// An older daemon ignores the unknown field and would watch every Pane instead.
|
|
1208
|
+
throw new Error('This Pane daemon does not support runpane watch --session; update Pane, or pass one --pane per Session Pane.');
|
|
1209
|
+
}
|
|
917
1210
|
if (failingCode) {
|
|
918
|
-
|
|
1211
|
+
emitControlLine((0, watchLines_1.formatNonEntry)('_reconnected', { generation: result.generation }, format));
|
|
919
1212
|
failingCode = undefined;
|
|
920
1213
|
}
|
|
921
1214
|
if (!armed && (parsed.follow || parsed.selfTest)) {
|
|
922
|
-
|
|
1215
|
+
const okLine = (0, watchLines_1.formatNonEntry)('_ok', { generation: result.generation, epoch: result.epoch }, format);
|
|
1216
|
+
if (parsed.selfTest)
|
|
1217
|
+
emitWatchLine(okLine);
|
|
1218
|
+
else
|
|
1219
|
+
emitControlLine(okLine);
|
|
923
1220
|
armed = true;
|
|
924
1221
|
if (parsed.selfTest)
|
|
925
1222
|
return 0;
|
|
@@ -927,7 +1224,7 @@ async function runWatch(parsed) {
|
|
|
927
1224
|
for (const line of (0, watchLines_1.formatWaitResult)(result, format))
|
|
928
1225
|
emitWatchLine(line);
|
|
929
1226
|
if (heartbeatMs > 0 && Date.now() - lastHeartbeatAt >= heartbeatMs) {
|
|
930
|
-
|
|
1227
|
+
emitControlLine((0, watchLines_1.formatNonEntry)('_heartbeat', {
|
|
931
1228
|
generation: result.generation,
|
|
932
1229
|
at: new Date().toISOString(),
|
|
933
1230
|
}, format));
|
|
@@ -958,6 +1255,27 @@ async function runWatch(parsed) {
|
|
|
958
1255
|
function emitWatchLine(line) {
|
|
959
1256
|
node_process_1.stdout.write(`${line}\n`);
|
|
960
1257
|
}
|
|
1258
|
+
/** Names older daemons accept; the daemon itself allows up to 128 characters. */
|
|
1259
|
+
const PORTABLE_WATCH_CURSOR_PATTERN = /^[A-Za-z0-9._-]{1,64}$/u;
|
|
1260
|
+
/**
|
|
1261
|
+
* Returns a derived watch cursor name (one runpane builds from an ID, not one the user typed)
|
|
1262
|
+
* that every daemon accepts. A name that is too long or has other characters becomes
|
|
1263
|
+
* `<prefix>-<first 12 hex chars of its sha256>`, which is stable across runs.
|
|
1264
|
+
*/
|
|
1265
|
+
function derivedWatchCursorName(prefix, name) {
|
|
1266
|
+
if (PORTABLE_WATCH_CURSOR_PATTERN.test(name))
|
|
1267
|
+
return name;
|
|
1268
|
+
return `${prefix}-${(0, node_crypto_1.createHash)('sha256').update(name).digest('hex').slice(0, 12)}`;
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Default cursor for `watch --session`: `session-<uuid>` for a Session id
|
|
1272
|
+
* (`__orchestration_session_<uuid>__`), `session-<name>` for a name, shortened like any
|
|
1273
|
+
* derived name when it is longer than 64 characters or has other characters.
|
|
1274
|
+
*/
|
|
1275
|
+
function sessionWatchCursorName(session) {
|
|
1276
|
+
const uuid = /^__orchestration_session_(.+)__$/u.exec(session)?.[1];
|
|
1277
|
+
return derivedWatchCursorName('session', `session-${uuid ?? session}`);
|
|
1278
|
+
}
|
|
961
1279
|
function watchErrorCode(error) {
|
|
962
1280
|
return error instanceof daemonClient_1.PaneDaemonClientError ? error.code ?? 'PaneDaemonClientError' : error.name || 'Error';
|
|
963
1281
|
}
|
|
@@ -1012,6 +1330,9 @@ async function runPanesAdopt(parsed) {
|
|
|
1012
1330
|
if (!parsed.repo || !parsed.repoPath || !parsed.name) {
|
|
1013
1331
|
throw new Error('runpane panes adopt requires --repo, --path, and --name.');
|
|
1014
1332
|
}
|
|
1333
|
+
if (!parsed.launch && (parsed.initialInput !== undefined || parsed.initialInputFile !== undefined || parsed.waitReady)) {
|
|
1334
|
+
throw new Error('runpane panes adopt only sends a prompt or waits for readiness with --launch. Add --launch to start the agent now.');
|
|
1335
|
+
}
|
|
1015
1336
|
const tool = await buildToolSpec(parsed, 'panes adopt');
|
|
1016
1337
|
request = {
|
|
1017
1338
|
repo: parsed.repo,
|
|
@@ -1026,6 +1347,8 @@ async function runPanesAdopt(parsed) {
|
|
|
1026
1347
|
launch: parsed.launch || undefined,
|
|
1027
1348
|
}],
|
|
1028
1349
|
dryRun: parsed.dryRun || undefined,
|
|
1350
|
+
waitReady: parsed.waitReady || undefined,
|
|
1351
|
+
readyTimeoutMs: parsed.readyTimeoutMs,
|
|
1029
1352
|
noFocus: parsed.noFocus || undefined,
|
|
1030
1353
|
focus: parsed.focus || undefined,
|
|
1031
1354
|
source: parsed.source === 'user' || parsed.source === 'agent' ? parsed.source : undefined,
|
|
@@ -1035,7 +1358,7 @@ async function runPanesAdopt(parsed) {
|
|
|
1035
1358
|
await confirmPaneAdopt(parsed, request);
|
|
1036
1359
|
const result = await (0, daemonClient_1.invokeDaemon)('runpane:panes:adopt', [request], exports.paneCreateResultSchema, {
|
|
1037
1360
|
paneDir: parsed.paneDir,
|
|
1038
|
-
timeoutMs: 120_000,
|
|
1361
|
+
timeoutMs: 120_000 + (request.waitReady ? (request.readyTimeoutMs ?? 30_000) : 0),
|
|
1039
1362
|
});
|
|
1040
1363
|
if (parsed.json)
|
|
1041
1364
|
printJson(result);
|
|
@@ -1044,8 +1367,11 @@ async function runPanesAdopt(parsed) {
|
|
|
1044
1367
|
return result.ok ? 0 : 1;
|
|
1045
1368
|
}
|
|
1046
1369
|
async function runPanesArchive(parsed) {
|
|
1370
|
+
if (parsed.sessionId) {
|
|
1371
|
+
return runPanesArchiveSession(parsed, parsed.sessionId);
|
|
1372
|
+
}
|
|
1047
1373
|
if (!parsed.paneId) {
|
|
1048
|
-
throw new Error('runpane panes archive requires --pane.');
|
|
1374
|
+
throw new Error('runpane panes archive requires --pane (or --session with --merged).');
|
|
1049
1375
|
}
|
|
1050
1376
|
const request = {
|
|
1051
1377
|
paneId: parsed.paneId,
|
|
@@ -1056,7 +1382,9 @@ async function runPanesArchive(parsed) {
|
|
|
1056
1382
|
request.source = parsed.source;
|
|
1057
1383
|
if (parsed.dryRun)
|
|
1058
1384
|
request.dryRun = true;
|
|
1059
|
-
|
|
1385
|
+
if (parsed.removeWorktree)
|
|
1386
|
+
request.removeWorktree = true;
|
|
1387
|
+
await confirmPaneArchive(parsed, `Archive pane ${request.paneId}${request.force ? ' (including any uncommitted or unpushed work)' : ''}`);
|
|
1060
1388
|
const result = await (0, daemonClient_1.invokeDaemon)('runpane:panes:archive', [request], paneArchiveResultSchema, {
|
|
1061
1389
|
paneDir: parsed.paneDir,
|
|
1062
1390
|
timeoutMs: 40_000,
|
|
@@ -1069,6 +1397,31 @@ async function runPanesArchive(parsed) {
|
|
|
1069
1397
|
}
|
|
1070
1398
|
return result.ok ? 0 : 1;
|
|
1071
1399
|
}
|
|
1400
|
+
async function runPanesArchiveSession(parsed, sessionId) {
|
|
1401
|
+
if (!parsed.merged) {
|
|
1402
|
+
throw new Error('runpane panes archive --session requires --merged.');
|
|
1403
|
+
}
|
|
1404
|
+
const request = { sessionId, merged: true };
|
|
1405
|
+
if (parsed.source === 'user' || parsed.source === 'agent')
|
|
1406
|
+
request.source = parsed.source;
|
|
1407
|
+
if (parsed.dryRun)
|
|
1408
|
+
request.dryRun = true;
|
|
1409
|
+
if (parsed.removeWorktree)
|
|
1410
|
+
request.removeWorktree = true;
|
|
1411
|
+
await confirmPaneArchive(parsed, `Archive every merged or pushed Pane in Session ${sessionId}`);
|
|
1412
|
+
const result = await (0, daemonClient_1.invokeDaemon)('runpane:panes:archive', [request], paneArchiveBulkResultSchema, {
|
|
1413
|
+
paneDir: parsed.paneDir,
|
|
1414
|
+
// Each Pane refreshes its upstream and may wait for its worktree removal.
|
|
1415
|
+
timeoutMs: 600_000,
|
|
1416
|
+
});
|
|
1417
|
+
if (parsed.json) {
|
|
1418
|
+
printJson(result);
|
|
1419
|
+
}
|
|
1420
|
+
else {
|
|
1421
|
+
printPaneArchiveBulkResult(result);
|
|
1422
|
+
}
|
|
1423
|
+
return result.ok ? 0 : 1;
|
|
1424
|
+
}
|
|
1072
1425
|
async function runPanesPin(parsed, pinned) {
|
|
1073
1426
|
if (!parsed.paneId) {
|
|
1074
1427
|
throw new Error(`runpane panes ${pinned ? 'pin' : 'unpin'} requires --pane.`);
|
|
@@ -1218,12 +1571,84 @@ async function runPanelsScreen(parsed) {
|
|
|
1218
1571
|
printJson(result);
|
|
1219
1572
|
return 0;
|
|
1220
1573
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1574
|
+
const text = markSuggestionLine(result.text, result.composer.ghostText);
|
|
1575
|
+
node_process_1.stdout.write(text);
|
|
1576
|
+
if (text && !text.endsWith('\n')) {
|
|
1223
1577
|
node_process_1.stdout.write('\n');
|
|
1224
1578
|
}
|
|
1225
1579
|
return 0;
|
|
1226
1580
|
}
|
|
1581
|
+
async function runPanelsLastMessage(parsed) {
|
|
1582
|
+
if (!parsed.panelId) {
|
|
1583
|
+
throw new Error('runpane panels last-message requires --panel.');
|
|
1584
|
+
}
|
|
1585
|
+
const result = await (0, daemonClient_1.invokeDaemon)('runpane:panels:last-message', [{
|
|
1586
|
+
panelId: parsed.panelId,
|
|
1587
|
+
limit: parsed.limit,
|
|
1588
|
+
}], panelLastMessageResultSchema, {
|
|
1589
|
+
paneDir: parsed.paneDir,
|
|
1590
|
+
});
|
|
1591
|
+
if (parsed.json) {
|
|
1592
|
+
printJson(result);
|
|
1593
|
+
}
|
|
1594
|
+
else if (result.ok) {
|
|
1595
|
+
node_process_1.stdout.write(result.text);
|
|
1596
|
+
if (result.text && !result.text.endsWith('\n'))
|
|
1597
|
+
node_process_1.stdout.write('\n');
|
|
1598
|
+
if (result.truncated)
|
|
1599
|
+
console.error(`(showing the last ${result.limit} of ${result.length} characters)`);
|
|
1600
|
+
}
|
|
1601
|
+
else {
|
|
1602
|
+
console.error(`${result.reason}: ${result.message}`);
|
|
1603
|
+
}
|
|
1604
|
+
return result.ok ? 0 : 1;
|
|
1605
|
+
}
|
|
1606
|
+
/** Where a report is for: explicit --panel (with an optional --pane), else the Pane terminal's own panel. */
|
|
1607
|
+
function resolveReportIdentity(parsed, env = process.env) {
|
|
1608
|
+
if (parsed.paneId || parsed.panelId) {
|
|
1609
|
+
if (!parsed.panelId) {
|
|
1610
|
+
throw new Error('runpane report --pane also needs --panel <panel-id>. Find it with `runpane panels list --pane <pane-id>`.');
|
|
1611
|
+
}
|
|
1612
|
+
return parsed.paneId ? { paneId: parsed.paneId, panelId: parsed.panelId } : { panelId: parsed.panelId };
|
|
1613
|
+
}
|
|
1614
|
+
const panelId = env.PANE_PANEL_ID?.trim();
|
|
1615
|
+
if (!panelId) {
|
|
1616
|
+
throw new Error('runpane report cannot tell which panel is reporting. Run it inside a Pane terminal '
|
|
1617
|
+
+ '(which sets PANE_SESSION_ID and PANE_PANEL_ID), or pass --pane <pane-id> --panel <panel-id>.');
|
|
1618
|
+
}
|
|
1619
|
+
const paneId = env.PANE_SESSION_ID?.trim();
|
|
1620
|
+
return paneId ? { paneId, panelId } : { panelId };
|
|
1621
|
+
}
|
|
1622
|
+
/** The CLIs send one character past the daemon's 16,000 so it still marks an overlong summary truncated. */
|
|
1623
|
+
const MAX_SENT_SUMMARY_LENGTH = 16_001;
|
|
1624
|
+
async function runReport(parsed, env = process.env) {
|
|
1625
|
+
const identity = resolveReportIdentity(parsed, env);
|
|
1626
|
+
const summaryText = parsed.summaryFile !== undefined
|
|
1627
|
+
? stripUtf8Bom(readInputSource(parsed.summaryFile))
|
|
1628
|
+
: parsed.summary;
|
|
1629
|
+
const summaryPath = parsed.summaryFile !== undefined && parsed.summaryFile !== '-'
|
|
1630
|
+
? node_path_1.default.resolve(parsed.summaryFile)
|
|
1631
|
+
: undefined;
|
|
1632
|
+
const result = await (0, daemonClient_1.invokeDaemon)('runpane:report', [{
|
|
1633
|
+
...identity,
|
|
1634
|
+
state: parsed.reportState,
|
|
1635
|
+
pr: parsed.reportPr,
|
|
1636
|
+
head: parsed.reportHead,
|
|
1637
|
+
summary: summaryText?.slice(0, MAX_SENT_SUMMARY_LENGTH),
|
|
1638
|
+
summaryPath,
|
|
1639
|
+
question: parsed.question,
|
|
1640
|
+
}], reportResultSchema, {
|
|
1641
|
+
paneDir: parsed.paneDir,
|
|
1642
|
+
});
|
|
1643
|
+
if (parsed.json) {
|
|
1644
|
+
printJson(result);
|
|
1645
|
+
}
|
|
1646
|
+
else {
|
|
1647
|
+
const sessions = result.sessionIds.length > 0 ? ` Recorded on Session ${result.sessionIds.join(', ')}.` : '';
|
|
1648
|
+
console.log(`Reported ${(0, watchLines_1.describeReport)(result.report)} for panel ${result.panelId}.${sessions}`);
|
|
1649
|
+
}
|
|
1650
|
+
return 0;
|
|
1651
|
+
}
|
|
1227
1652
|
async function runPanelsSubmit(parsed) {
|
|
1228
1653
|
const request = buildPanelInputRequest(parsed, 'submit');
|
|
1229
1654
|
await confirmPanelInput(parsed, request, 'submit');
|
|
@@ -1237,15 +1662,50 @@ async function runPanelsSubmit(parsed) {
|
|
|
1237
1662
|
const verb = result.ok ? 'Submitted' : 'Could not verify';
|
|
1238
1663
|
const verified = result.verifiedSubmitted ? ' verified' : ' unverified';
|
|
1239
1664
|
console.log(`${verb} ${result.inputBytes} byte${result.inputBytes === 1 ? '' : 's'} via ${result.sequenceName} to panel ${result.panelId}.${verified}`);
|
|
1665
|
+
printDelivery(result.delivery);
|
|
1240
1666
|
if (result.blocked) {
|
|
1241
1667
|
console.log(`Blocked: ${result.blocked.message}`);
|
|
1242
1668
|
}
|
|
1669
|
+
printPromptNotes(result);
|
|
1243
1670
|
if (result.nextCommand) {
|
|
1244
1671
|
console.log(`Next: ${result.nextCommand}`);
|
|
1245
1672
|
}
|
|
1246
1673
|
}
|
|
1247
1674
|
return result.ok ? 0 : 1;
|
|
1248
1675
|
}
|
|
1676
|
+
/** Where the prompt went, for human output: `Delivery: queued (transcript)`. */
|
|
1677
|
+
function printDelivery(delivery, prefix = '') {
|
|
1678
|
+
if (delivery) {
|
|
1679
|
+
console.log(`${prefix}Delivery: ${delivery.state} (${delivery.evidence})`);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Mark the composer line that shows ghost text (a placeholder or the agent's
|
|
1684
|
+
* suggested next prompt), so it does not read as typed input.
|
|
1685
|
+
*/
|
|
1686
|
+
function markSuggestionLine(text, ghostText) {
|
|
1687
|
+
const ghost = ghostText?.split('\n')[0]?.trim();
|
|
1688
|
+
if (!ghost)
|
|
1689
|
+
return text;
|
|
1690
|
+
const lines = text.split('\n');
|
|
1691
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
1692
|
+
const line = lines[index].trim();
|
|
1693
|
+
if (/^[❯›>]/u.test(line) && line.includes(ghost)) {
|
|
1694
|
+
lines[index] = `${lines[index].trimEnd()} ⟨suggestion⟩`;
|
|
1695
|
+
break;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return lines.join('\n');
|
|
1699
|
+
}
|
|
1700
|
+
/** The prompt file Pane wrote and any leading-character warnings, for human output. */
|
|
1701
|
+
function printPromptNotes(result, prefix = '') {
|
|
1702
|
+
if (result.promptFile) {
|
|
1703
|
+
console.log(`${prefix}Prompt file: ${result.promptFile}`);
|
|
1704
|
+
}
|
|
1705
|
+
for (const warning of result.warnings ?? []) {
|
|
1706
|
+
console.log(`${prefix}Warning (${warning.code}): ${warning.message}`);
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1249
1709
|
async function runPanelsSubmitComposer(parsed) {
|
|
1250
1710
|
if (!parsed.panelId) {
|
|
1251
1711
|
throw new Error('runpane panels submit-composer requires --panel.');
|
|
@@ -1263,6 +1723,7 @@ async function runPanelsSubmitComposer(parsed) {
|
|
|
1263
1723
|
else {
|
|
1264
1724
|
const verified = result.verifiedSubmitted ? ' verified' : ' unverified';
|
|
1265
1725
|
console.log(`${result.ok ? 'Submitted' : 'Could not verify'} composer with ${result.sequenceName} to panel ${result.panelId}.${verified}`);
|
|
1726
|
+
printDelivery(result.delivery);
|
|
1266
1727
|
if (result.blocked) {
|
|
1267
1728
|
console.log(`Blocked: ${result.blocked.message}`);
|
|
1268
1729
|
}
|
|
@@ -1332,11 +1793,15 @@ function buildPanelInputRequest(parsed, command = 'input') {
|
|
|
1332
1793
|
throw new Error(`runpane panels ${command} requires --text, --keys, or --input-file.`);
|
|
1333
1794
|
}
|
|
1334
1795
|
if (parsed.keys !== undefined && command !== 'input') {
|
|
1335
|
-
throw new Error('--keys is for panels input; panels submit sends text followed by
|
|
1796
|
+
throw new Error('--keys is for panels input; panels submit sends text followed by the agent submit key.');
|
|
1797
|
+
}
|
|
1798
|
+
if (parsed.asFilePointer && command !== 'submit') {
|
|
1799
|
+
throw new Error('--as-file-pointer is for panels submit; panels input sends exact bytes.');
|
|
1336
1800
|
}
|
|
1337
1801
|
return {
|
|
1338
1802
|
panelId: parsed.panelId,
|
|
1339
1803
|
input: parsed.keys ? keysToBytes(parsed.keys) : parsed.panelInputFile ? readInputSource(parsed.panelInputFile) : parsed.panelInput ?? '',
|
|
1804
|
+
asFilePointer: parsed.asFilePointer || undefined,
|
|
1340
1805
|
};
|
|
1341
1806
|
}
|
|
1342
1807
|
/** `--keys down,enter`: named keys from the contract, or a single literal character each. */
|
|
@@ -1421,6 +1886,7 @@ async function buildPaneCreateRequest(parsed) {
|
|
|
1421
1886
|
panes: [{
|
|
1422
1887
|
name: parsed.name,
|
|
1423
1888
|
worktreeName: parsed.worktreeName,
|
|
1889
|
+
branch: parsed.branch,
|
|
1424
1890
|
baseBranch: parsed.baseBranch,
|
|
1425
1891
|
pinned: resolvePinnedOverride(parsed) ?? true,
|
|
1426
1892
|
tool,
|
|
@@ -1478,10 +1944,22 @@ async function confirmRepoAdd(parsed, request) {
|
|
|
1478
1944
|
}
|
|
1479
1945
|
}
|
|
1480
1946
|
async function buildToolSpec(parsed, command = 'panes create') {
|
|
1481
|
-
if (parsed.agent && parsed.toolCommand) {
|
|
1482
|
-
throw new Error('Use either --agent or --tool-command, not both.');
|
|
1483
|
-
}
|
|
1484
1947
|
const initialInput = resolveInitialInput(parsed);
|
|
1948
|
+
if (parsed.asFilePointer && initialInput === undefined) {
|
|
1949
|
+
throw new Error(`--as-file-pointer needs a prompt: pass --prompt or --initial-input-file to runpane ${command}.`);
|
|
1950
|
+
}
|
|
1951
|
+
const initialInputAsFilePointer = parsed.asFilePointer || undefined;
|
|
1952
|
+
// With --tool-command, --agent names the agent the command runs (a wrapper
|
|
1953
|
+
// such as `agent-farm run`); Pane launches the command unchanged.
|
|
1954
|
+
if (parsed.toolCommand && parsed.agent) {
|
|
1955
|
+
return {
|
|
1956
|
+
command: parsed.toolCommand,
|
|
1957
|
+
agentType: parsed.agent,
|
|
1958
|
+
title: parsed.title,
|
|
1959
|
+
initialInput,
|
|
1960
|
+
initialInputAsFilePointer,
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1485
1963
|
let agent = parsed.agent;
|
|
1486
1964
|
if (!agent && !parsed.toolCommand) {
|
|
1487
1965
|
if (!isInteractiveShell()) {
|
|
@@ -1494,6 +1972,7 @@ async function buildToolSpec(parsed, command = 'panes create') {
|
|
|
1494
1972
|
agent,
|
|
1495
1973
|
title: parsed.title,
|
|
1496
1974
|
initialInput,
|
|
1975
|
+
initialInputAsFilePointer,
|
|
1497
1976
|
};
|
|
1498
1977
|
}
|
|
1499
1978
|
if (!parsed.toolCommand) {
|
|
@@ -1503,11 +1982,12 @@ async function buildToolSpec(parsed, command = 'panes create') {
|
|
|
1503
1982
|
command: parsed.toolCommand,
|
|
1504
1983
|
title: parsed.title,
|
|
1505
1984
|
initialInput,
|
|
1985
|
+
initialInputAsFilePointer,
|
|
1506
1986
|
};
|
|
1507
1987
|
}
|
|
1508
1988
|
function resolveInitialInput(parsed) {
|
|
1509
1989
|
if (parsed.initialInput && parsed.initialInputFile) {
|
|
1510
|
-
throw new Error('Use either --initial-input/--prompt or --initial-input-file, not both.');
|
|
1990
|
+
throw new Error('Use either --initial-input/--prompt or --initial-input-file/--prompt-file, not both.');
|
|
1511
1991
|
}
|
|
1512
1992
|
if (parsed.initialInputFile) {
|
|
1513
1993
|
return readInputSource(parsed.initialInputFile);
|
|
@@ -1549,7 +2029,7 @@ async function confirmPaneAdopt(parsed, request) {
|
|
|
1549
2029
|
rl.close();
|
|
1550
2030
|
}
|
|
1551
2031
|
}
|
|
1552
|
-
async function confirmPaneArchive(parsed,
|
|
2032
|
+
async function confirmPaneArchive(parsed, question) {
|
|
1553
2033
|
if (parsed.dryRun || parsed.yes) {
|
|
1554
2034
|
return;
|
|
1555
2035
|
}
|
|
@@ -1558,8 +2038,7 @@ async function confirmPaneArchive(parsed, request) {
|
|
|
1558
2038
|
}
|
|
1559
2039
|
const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stdout });
|
|
1560
2040
|
try {
|
|
1561
|
-
const
|
|
1562
|
-
const answer = (await rl.question(`Archive pane ${request.paneId}${suffix}? [y/N] `)).trim().toLowerCase();
|
|
2041
|
+
const answer = (await rl.question(`${question}? [y/N] `)).trim().toLowerCase();
|
|
1563
2042
|
if (answer !== 'y' && answer !== 'yes') {
|
|
1564
2043
|
throw new Error('Cancelled.');
|
|
1565
2044
|
}
|
|
@@ -1735,6 +2214,12 @@ function workspaceLabel(kind) {
|
|
|
1735
2214
|
'pane.created': 'NEW',
|
|
1736
2215
|
'pane.gone': 'GONE',
|
|
1737
2216
|
'panel.exited': 'EXIT',
|
|
2217
|
+
'pane.associated': 'JOINED',
|
|
2218
|
+
'pane.detached': 'LEFT',
|
|
2219
|
+
'pr.conflicted': 'PR CONFLICTED',
|
|
2220
|
+
'pr.checks': 'PR CHECKS',
|
|
2221
|
+
'pr.merged': 'PR MERGED',
|
|
2222
|
+
'agent.report': 'REPORT',
|
|
1738
2223
|
};
|
|
1739
2224
|
return labels[kind];
|
|
1740
2225
|
}
|
|
@@ -1804,6 +2289,7 @@ function printPaneCreateResult(result) {
|
|
|
1804
2289
|
? ` Associated with Session ${item.association.sessionId}`
|
|
1805
2290
|
: ` Not associated with Session ${item.association.sessionId}: ${item.association.error ?? 'unknown error'}`);
|
|
1806
2291
|
}
|
|
2292
|
+
printPromptNotes(item, ' ');
|
|
1807
2293
|
if (item.nextCommand) {
|
|
1808
2294
|
console.log(` Next: ${item.nextCommand}`);
|
|
1809
2295
|
}
|
|
@@ -1828,11 +2314,44 @@ function printPaneArchiveResult(result) {
|
|
|
1828
2314
|
console.error(`Next: ${result.nextCommand}`);
|
|
1829
2315
|
return;
|
|
1830
2316
|
}
|
|
1831
|
-
|
|
2317
|
+
const trash = result.trashDeletion === 'pending' ? ' (files are still being deleted in the background)' : '';
|
|
2318
|
+
console.log(`Archived pane ${result.paneId}${result.forced ? ' (forced)' : ''}. Worktree cleanup: ${result.worktreeCleanup}${trash}.`);
|
|
2319
|
+
printArchiveSkipReason(result.safetyCheck);
|
|
2320
|
+
if (result.safetyCheck.mergedViaPr) {
|
|
2321
|
+
console.log(`Merged via PR #${result.safetyCheck.mergedViaPr.number} (head ${result.safetyCheck.mergedViaPr.headOid}).`);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
function printPaneArchiveBulkResult(result) {
|
|
2325
|
+
const verb = result.dryRun ? 'Would archive' : 'Archived';
|
|
2326
|
+
console.log(`${verb} ${result.archived} Pane(s) in Session ${result.sessionId}; skipped ${result.skipped}; failed ${result.failed}.`);
|
|
2327
|
+
for (const item of result.items) {
|
|
2328
|
+
const label = item.name ? `${item.name} (${item.paneId})` : item.paneId;
|
|
2329
|
+
if (item.outcome === 'skipped') {
|
|
2330
|
+
console.log(` skipped ${label}: ${item.skipped?.code ?? 'unknown'} - ${item.skipped?.message ?? ''}`);
|
|
2331
|
+
}
|
|
2332
|
+
else if (item.outcome === 'failed') {
|
|
2333
|
+
console.error(` failed ${label}: ${item.error ?? 'unknown error'}`);
|
|
2334
|
+
}
|
|
2335
|
+
else {
|
|
2336
|
+
const merged = item.safetyCheck?.mergedViaPr ? ` merged via PR #${item.safetyCheck.mergedViaPr.number}` : '';
|
|
2337
|
+
const trash = item.trashDeletion === 'pending' ? ', files deleting in background' : '';
|
|
2338
|
+
const cleanup = item.worktreeCleanup ? ` worktree ${item.worktreeCleanup}${trash}` : '';
|
|
2339
|
+
console.log(` ${item.outcome} ${label}${merged}${cleanup}`);
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
function printArchiveSkipReason(safetyCheck, print = console.log) {
|
|
2344
|
+
if (!safetyCheck.reason)
|
|
2345
|
+
return;
|
|
2346
|
+
print(`Safety check skipped: ${safetyCheck.reason}${safetyCheck.worktreeWillRemain ? '; the worktree stays on disk' : ''}.`);
|
|
1832
2347
|
}
|
|
1833
2348
|
function printArchiveCommitEvidence(safetyCheck, print = console.log) {
|
|
2349
|
+
printArchiveSkipReason(safetyCheck, print);
|
|
1834
2350
|
if (safetyCheck.upstream) {
|
|
1835
|
-
print(`Upstream: ${safetyCheck.upstream}${safetyCheck.upstreamRefreshed ? ' (refreshed)' : ''}`);
|
|
2351
|
+
print(`Upstream: ${safetyCheck.upstream}${safetyCheck.upstreamRefreshed ? ' (refreshed)' : ''}${safetyCheck.upstreamGone ? ' (gone from the remote)' : ''}`);
|
|
2352
|
+
}
|
|
2353
|
+
if (safetyCheck.mergedViaPr) {
|
|
2354
|
+
print(`Merged via PR #${safetyCheck.mergedViaPr.number} (head ${safetyCheck.mergedViaPr.headOid})`);
|
|
1836
2355
|
}
|
|
1837
2356
|
for (const commit of safetyCheck.unpushedCommitDetails ?? []) {
|
|
1838
2357
|
print(`Unpushed: ${commit.sha} ${commit.subject}`);
|
|
@@ -1847,6 +2366,7 @@ function printPanelCreateResult(result) {
|
|
|
1847
2366
|
}
|
|
1848
2367
|
}
|
|
1849
2368
|
printInitialInputDelivery(result.initialInput);
|
|
2369
|
+
printPromptNotes(result);
|
|
1850
2370
|
if (result.nextCommand) {
|
|
1851
2371
|
console.log(`Next: ${result.nextCommand}`);
|
|
1852
2372
|
}
|
|
@@ -1864,6 +2384,7 @@ function printInitialInputDelivery(initialInput, prefix = '') {
|
|
|
1864
2384
|
const attempts = initialInput.attempts === undefined ? '' : ` after ${initialInput.attempts} attempt${initialInput.attempts === 1 ? '' : 's'}`;
|
|
1865
2385
|
const staged = initialInput.staged === undefined ? '' : `; staged: ${initialInput.staged ? 'yes' : 'no'}`;
|
|
1866
2386
|
console.log(`${prefix}Initial input: ${status}${strategy}${attempts}${staged}`);
|
|
2387
|
+
printDelivery(initialInput.delivery, prefix);
|
|
1867
2388
|
if (initialInput.blocked) {
|
|
1868
2389
|
console.log(`${prefix}Initial input blocked: ${initialInput.blocked.message}`);
|
|
1869
2390
|
}
|
|
@@ -1923,7 +2444,8 @@ function printPanelListResult(result) {
|
|
|
1923
2444
|
const marker = panel.active ? '*' : ' ';
|
|
1924
2445
|
const initialized = panel.initialized === undefined ? '' : panel.initialized ? ' initialized' : ' not-initialized';
|
|
1925
2446
|
const agent = panel.agentType ? ` ${panel.agentType}` : '';
|
|
1926
|
-
|
|
2447
|
+
const detection = panel.agentDetection && panel.agentDetection !== 'command' ? ` (${panel.agentDetection})` : '';
|
|
2448
|
+
console.log(`${marker} ${panel.id}\t${panel.type}\t${panel.title}${initialized}${agent}${detection}`);
|
|
1927
2449
|
}
|
|
1928
2450
|
}
|
|
1929
2451
|
function isInteractiveShell() {
|
|
@@ -1949,6 +2471,7 @@ function parsePaneCreateItemPayload(value, index) {
|
|
|
1949
2471
|
return {
|
|
1950
2472
|
name: value.name,
|
|
1951
2473
|
worktreeName: value.worktreeName,
|
|
2474
|
+
branch: value.branch,
|
|
1952
2475
|
baseBranch: value.baseBranch,
|
|
1953
2476
|
sessionPrompt: value.sessionPrompt,
|
|
1954
2477
|
pinned: value.pinned,
|
|
@@ -1968,13 +2491,23 @@ function parsePaneToolSpecPayload(value, index) {
|
|
|
1968
2491
|
agent,
|
|
1969
2492
|
title: value.title,
|
|
1970
2493
|
initialInput: value.initialInput,
|
|
2494
|
+
initialInputAsFilePointer: value.initialInputAsFilePointer,
|
|
1971
2495
|
};
|
|
1972
2496
|
}
|
|
1973
2497
|
if (value.command !== undefined && value.command.trim().length > 0) {
|
|
2498
|
+
let agentType;
|
|
2499
|
+
try {
|
|
2500
|
+
agentType = value.agentType === undefined ? undefined : (0, boundaryDecoder_1.decodeBoundary)(value.agentType, agentSchema);
|
|
2501
|
+
}
|
|
2502
|
+
catch {
|
|
2503
|
+
throw new Error(`--from-json pane ${index} includes an unsupported agentType.`);
|
|
2504
|
+
}
|
|
1974
2505
|
return {
|
|
1975
2506
|
command: value.command,
|
|
2507
|
+
agentType,
|
|
1976
2508
|
title: value.title,
|
|
1977
2509
|
initialInput: value.initialInput,
|
|
2510
|
+
initialInputAsFilePointer: value.initialInputAsFilePointer,
|
|
1978
2511
|
};
|
|
1979
2512
|
}
|
|
1980
2513
|
throw new Error(`--from-json pane ${index} tool must include agent or command.`);
|