orquesta-agent 0.2.240 → 0.2.242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/executor.d.ts +42 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +168 -59
- package/dist/executor.js.map +1 -1
- package/dist/index.js +147 -44
- package/dist/index.js.map +1 -1
- package/dist/local-server.d.ts +1 -1
- package/dist/local-server.d.ts.map +1 -1
- package/dist/local-server.js +7 -4
- package/dist/local-server.js.map +1 -1
- package/dist/socketio-transport.d.ts +2 -0
- package/dist/socketio-transport.d.ts.map +1 -1
- package/dist/socketio-transport.js.map +1 -1
- package/dist/supabase.d.ts +17 -0
- package/dist/supabase.d.ts.map +1 -1
- package/dist/supabase.js.map +1 -1
- package/dist/ui/public/welcome.js +8 -0
- package/package.json +2 -2
package/dist/executor.d.ts
CHANGED
|
@@ -82,6 +82,22 @@ export declare function setCliEndpoint(endpoint: string): void;
|
|
|
82
82
|
export declare function getCliEndpoint(): string;
|
|
83
83
|
export declare function setBrowserEnabled(enabled: boolean): void;
|
|
84
84
|
export declare function getBrowserEnabled(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Is orquesta-cli usable, and which copy of it should we run?
|
|
87
|
+
*
|
|
88
|
+
* The agent bundles orquesta-cli as a dependency so a no-Node / standalone
|
|
89
|
+
* install always has a CLI. That copy used to win unconditionally — it was
|
|
90
|
+
* probed first and its bin dir was prepended to PATH, and every spawn uses the
|
|
91
|
+
* bare name `orquesta`. So a user who updated their own global CLI kept getting
|
|
92
|
+
* the version pinned in orquesta-agent's package.json: the Interactive Session
|
|
93
|
+
* reported v0.2.138 on a machine running v0.2.140, and re-running the update
|
|
94
|
+
* flow could never change it, because the update flow bumps the AGENT and the
|
|
95
|
+
* agent's pin came along with it. QA-77.
|
|
96
|
+
*
|
|
97
|
+
* Now every candidate is probed and the NEWEST one wins. The bundled copy stays
|
|
98
|
+
* the floor (it is still found when nothing else is installed), it just no
|
|
99
|
+
* longer shadows a newer install.
|
|
100
|
+
*/
|
|
85
101
|
export declare function isOrquestaCliAvailable(): boolean;
|
|
86
102
|
export declare function resolveClaudeBinary(): string | null;
|
|
87
103
|
export declare function isClaudeCliAvailable(): boolean;
|
|
@@ -206,8 +222,27 @@ export interface GeneratePlanItemsOptions {
|
|
|
206
222
|
* This runs Claude to analyze the request and generate actionable tasks.
|
|
207
223
|
*/
|
|
208
224
|
export declare function generatePlanItems(options: GeneratePlanItemsOptions): Promise<void>;
|
|
225
|
+
/** The assisted-run item an interactive session was claimed against. */
|
|
226
|
+
export interface AssistedSessionEnvelope {
|
|
227
|
+
runId: string;
|
|
228
|
+
itemId: string;
|
|
229
|
+
branch: string;
|
|
230
|
+
/** The prompt row the claim minted, and the subject of the exit report. */
|
|
231
|
+
promptId: string;
|
|
232
|
+
/**
|
|
233
|
+
* HEAD when the session started, captured agent-side. The exit report diffs
|
|
234
|
+
* against it, so commits the person made by hand mid-session are counted too.
|
|
235
|
+
*/
|
|
236
|
+
baseSha?: string;
|
|
237
|
+
}
|
|
238
|
+
/** What `setOnSessionEnded` receives about the session that just ended. */
|
|
239
|
+
export interface SessionEndInfo {
|
|
240
|
+
sessionId: string;
|
|
241
|
+
workingDirectory: string;
|
|
242
|
+
assisted?: AssistedSessionEnvelope;
|
|
243
|
+
}
|
|
209
244
|
/** Register a callback to be called when an interactive session ends (PTY exits). */
|
|
210
|
-
export declare function setOnSessionEnded(cb: () => void): void;
|
|
245
|
+
export declare function setOnSessionEnded(cb: (info?: SessionEndInfo) => void): void;
|
|
211
246
|
export interface StartSessionOptions {
|
|
212
247
|
sessionId: string;
|
|
213
248
|
workingDirectory?: string;
|
|
@@ -230,6 +265,12 @@ export interface StartSessionOptions {
|
|
|
230
265
|
* per-id resume, so they fall back to --continue.
|
|
231
266
|
*/
|
|
232
267
|
resumeSessionId?: string;
|
|
268
|
+
/**
|
|
269
|
+
* Set when this session is a claimed item of an assisted QA run. Suppresses
|
|
270
|
+
* every deploy instruction in the system prompt (same rule as a dispatched
|
|
271
|
+
* assisted prompt) and is handed back on exit so the diff can be reported.
|
|
272
|
+
*/
|
|
273
|
+
assisted?: AssistedSessionEnvelope;
|
|
233
274
|
}
|
|
234
275
|
export interface ResumableSession {
|
|
235
276
|
sessionId: string;
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAkItD,OAAO,EAAgG,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -235,6 +235,10 @@ const promptCostCents = new Map();
|
|
|
235
235
|
// ever saw logs, and panels that read prompts.result (architecture extraction,
|
|
236
236
|
// auto-agent polling) found it empty.
|
|
237
237
|
const promptFinalResult = new Map();
|
|
238
|
+
// The CLI's own verdict for a run, from its `end` event. Kept per prompt because
|
|
239
|
+
// several prompts stream through the same process concurrently. See QA-76: an
|
|
240
|
+
// exit code is not evidence that the work succeeded.
|
|
241
|
+
const promptCliReportedFailure = new Map();
|
|
238
242
|
function trackFileModified(promptId, filePath) {
|
|
239
243
|
if (!executionFilesModified.has(promptId)) {
|
|
240
244
|
executionFilesModified.set(promptId, new Set());
|
|
@@ -720,66 +724,118 @@ const CLI_DETECTION_TTL_MS = 5 * 60 * 1000;
|
|
|
720
724
|
let orquestaCliCache = null;
|
|
721
725
|
let claudeCliCache = null;
|
|
722
726
|
let kimiCliCache = null;
|
|
727
|
+
/**
|
|
728
|
+
* Version of an orquesta-cli binary, or null when it does not run.
|
|
729
|
+
* '' means it runs but printed nothing we can parse as a version.
|
|
730
|
+
*/
|
|
731
|
+
function probeOrquestaVersion(bin) {
|
|
732
|
+
try {
|
|
733
|
+
const out = execSync(`${bin} --version`, { stdio: 'pipe', timeout: 15000, encoding: 'utf-8' });
|
|
734
|
+
return (out.match(/\d+\.\d+\.\d+/) || [''])[0];
|
|
735
|
+
}
|
|
736
|
+
catch {
|
|
737
|
+
return null;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
function compareSemver(a, b) {
|
|
741
|
+
const pa = a.split('.').map(n => parseInt(n, 10) || 0);
|
|
742
|
+
const pb = b.split('.').map(n => parseInt(n, 10) || 0);
|
|
743
|
+
for (let i = 0; i < 3; i++) {
|
|
744
|
+
if ((pa[i] || 0) !== (pb[i] || 0))
|
|
745
|
+
return (pa[i] || 0) - (pb[i] || 0);
|
|
746
|
+
}
|
|
747
|
+
return 0;
|
|
748
|
+
}
|
|
749
|
+
// The bin dir this module prepended to PATH on the last detection, so a later
|
|
750
|
+
// re-detection can drop it instead of stacking (and instead of letting a stale
|
|
751
|
+
// winner keep shadowing the one we just chose).
|
|
752
|
+
let injectedCliBinDir = null;
|
|
753
|
+
function prependToPath(binDir) {
|
|
754
|
+
if (injectedCliBinDir && injectedCliBinDir !== binDir) {
|
|
755
|
+
const parts = (process.env.PATH || '').split(path.delimiter).filter(p => p !== injectedCliBinDir);
|
|
756
|
+
process.env.PATH = parts.join(path.delimiter);
|
|
757
|
+
injectedCliBinDir = null;
|
|
758
|
+
}
|
|
759
|
+
const parts = (process.env.PATH || '').split(path.delimiter);
|
|
760
|
+
if (parts[0] !== binDir) {
|
|
761
|
+
// path.delimiter, not ':' — a hardcoded colon builds an unusable PATH on
|
|
762
|
+
// Windows, where the agent has to work too.
|
|
763
|
+
process.env.PATH = [binDir, ...parts.filter(p => p !== binDir)].join(path.delimiter);
|
|
764
|
+
}
|
|
765
|
+
injectedCliBinDir = binDir;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Is orquesta-cli usable, and which copy of it should we run?
|
|
769
|
+
*
|
|
770
|
+
* The agent bundles orquesta-cli as a dependency so a no-Node / standalone
|
|
771
|
+
* install always has a CLI. That copy used to win unconditionally — it was
|
|
772
|
+
* probed first and its bin dir was prepended to PATH, and every spawn uses the
|
|
773
|
+
* bare name `orquesta`. So a user who updated their own global CLI kept getting
|
|
774
|
+
* the version pinned in orquesta-agent's package.json: the Interactive Session
|
|
775
|
+
* reported v0.2.138 on a machine running v0.2.140, and re-running the update
|
|
776
|
+
* flow could never change it, because the update flow bumps the AGENT and the
|
|
777
|
+
* agent's pin came along with it. QA-77.
|
|
778
|
+
*
|
|
779
|
+
* Now every candidate is probed and the NEWEST one wins. The bundled copy stays
|
|
780
|
+
* the floor (it is still found when nothing else is installed), it just no
|
|
781
|
+
* longer shadows a newer install.
|
|
782
|
+
*/
|
|
723
783
|
export function isOrquestaCliAvailable() {
|
|
724
784
|
const now = Date.now();
|
|
725
785
|
if (orquestaCliCache && now - orquestaCliCache.at < CLI_DETECTION_TTL_MS) {
|
|
726
786
|
return orquestaCliCache.available;
|
|
727
787
|
}
|
|
728
|
-
|
|
729
|
-
// First: check bundled CLI (orquesta-cli installed as dependency)
|
|
788
|
+
const home = process.env.HOME || process.env.USERPROFILE || '/root';
|
|
730
789
|
const bundledBin = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'node_modules', '.bin', 'orquesta');
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
orquestaCliCache = { available, at: now };
|
|
741
|
-
return available;
|
|
742
|
-
}
|
|
790
|
+
const candidates = [];
|
|
791
|
+
if (fs.existsSync(bundledBin))
|
|
792
|
+
candidates.push(bundledBin);
|
|
793
|
+
// Whatever `orquesta` resolves to right now — but only after dropping any bin
|
|
794
|
+
// dir a previous detection injected, or we would just re-measure our own pick.
|
|
795
|
+
if (injectedCliBinDir) {
|
|
796
|
+
process.env.PATH = (process.env.PATH || '')
|
|
797
|
+
.split(path.delimiter).filter(p => p !== injectedCliBinDir).join(path.delimiter);
|
|
798
|
+
injectedCliBinDir = null;
|
|
743
799
|
}
|
|
744
|
-
catch { /* bundled not working */ }
|
|
745
|
-
// Second: check PATH
|
|
746
800
|
try {
|
|
747
|
-
execSync('
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
778
|
-
catch { }
|
|
801
|
+
const prefix = execSync('npm prefix -g', { stdio: 'pipe', timeout: 5000, encoding: 'utf-8' }).trim();
|
|
802
|
+
if (prefix)
|
|
803
|
+
candidates.push(path.join(prefix, 'bin', 'orquesta'));
|
|
804
|
+
}
|
|
805
|
+
catch { /* npm may not be installed at all (standalone binary machines) */ }
|
|
806
|
+
candidates.push(`${home}/.npm-global/bin/orquesta`, `${home}/.nvm/versions/node/${process.version}/bin/orquesta`, '/usr/local/bin/orquesta', '/usr/bin/orquesta',
|
|
807
|
+
// getorquesta.com/install drops the standalone cli here when /usr/local/bin
|
|
808
|
+
// isn't writable and there's no sudo (no-Node install on a non-root box).
|
|
809
|
+
`${home}/.local/bin/orquesta`);
|
|
810
|
+
let best = null;
|
|
811
|
+
const seen = new Set();
|
|
812
|
+
for (const bin of candidates) {
|
|
813
|
+
if (seen.has(bin))
|
|
814
|
+
continue;
|
|
815
|
+
seen.add(bin);
|
|
816
|
+
if (bin !== bundledBin && !fs.existsSync(bin))
|
|
817
|
+
continue;
|
|
818
|
+
const version = probeOrquestaVersion(bin);
|
|
819
|
+
if (version === null)
|
|
820
|
+
continue;
|
|
821
|
+
if (!best || compareSemver(version, best.version) > 0)
|
|
822
|
+
best = { bin, version };
|
|
823
|
+
}
|
|
824
|
+
// Nothing on the candidate list ran — fall back to a bare PATH lookup, which
|
|
825
|
+
// covers layouts we don't enumerate (Windows shims, custom prefixes).
|
|
826
|
+
if (!best) {
|
|
827
|
+
const version = probeOrquestaVersion('orquesta');
|
|
828
|
+
if (version !== null) {
|
|
829
|
+
orquestaCliCache = { available: true, at: now };
|
|
830
|
+
return true;
|
|
779
831
|
}
|
|
832
|
+
orquestaCliCache = { available: false, at: now };
|
|
833
|
+
return false;
|
|
780
834
|
}
|
|
781
|
-
|
|
782
|
-
|
|
835
|
+
prependToPath(path.dirname(best.bin));
|
|
836
|
+
logger.debug(`orquesta-cli: using ${best.bin}${best.version ? ` (v${best.version})` : ''}`);
|
|
837
|
+
orquestaCliCache = { available: true, at: now };
|
|
838
|
+
return true;
|
|
783
839
|
}
|
|
784
840
|
// Resolve a claude binary that ACTUALLY runs — not one that merely exists on
|
|
785
841
|
// PATH. The claude-code npm package's `bin/claude` launcher can be broken: a
|
|
@@ -2414,9 +2470,22 @@ ${userRequestBody}`;
|
|
|
2414
2470
|
promptFinalResult.set(promptId, String(content));
|
|
2415
2471
|
}
|
|
2416
2472
|
}
|
|
2473
|
+
else if (json.event === 'error') {
|
|
2474
|
+
// orquesta-cli emits this when a run ends badly. There was no branch
|
|
2475
|
+
// for it, so the reason a run failed never reached the timeline —
|
|
2476
|
+
// only the (misleading) completion line did.
|
|
2477
|
+
const { message } = json.data;
|
|
2478
|
+
if (message) {
|
|
2479
|
+
output += `\n❌ ${message}\n`;
|
|
2480
|
+
logs.push(createErrorLog(String(message), false, 'error', promptId, json.data?.code));
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2417
2483
|
else if (json.event === 'end') {
|
|
2418
2484
|
const { success, duration_ms, usage } = json.data;
|
|
2419
2485
|
const duration = (duration_ms / 1000).toFixed(1);
|
|
2486
|
+
// Remember the CLI's answer. It knows things the exit code does not.
|
|
2487
|
+
if (success === false && promptId)
|
|
2488
|
+
promptCliReportedFailure.set(promptId, true);
|
|
2420
2489
|
output += `\n${success ? '✅' : '❌'} Completed in ${duration}s\n`;
|
|
2421
2490
|
if (usage) {
|
|
2422
2491
|
output += `📊 Tokens: ${usage.total_tokens || 0}\n`;
|
|
@@ -2839,7 +2908,18 @@ ${userRequestBody}`;
|
|
|
2839
2908
|
addLog(promptId, 'error', 'system', `Claude CLI unavailable (no fallback): ${claudeApiError}`);
|
|
2840
2909
|
sendOutput(channel, commandId, 'stderr', `\n❌ Claude CLI unavailable: ${claudeApiError}\n`);
|
|
2841
2910
|
}
|
|
2842
|
-
|
|
2911
|
+
// A CLI that swallowed a fatal error and still exited 0 is exactly how a
|
|
2912
|
+
// revoked-token run ended up wearing a green "Completed" badge (QA-76).
|
|
2913
|
+
// When the CLI told us in its `end` event that the run failed, that beats
|
|
2914
|
+
// the exit code — same shape as the claudeApiError rule above, which
|
|
2915
|
+
// exists because `claude` also exits 0 on an account-level failure.
|
|
2916
|
+
const cliReportedFailure = promptId ? promptCliReportedFailure.get(promptId) === true : false;
|
|
2917
|
+
if (promptId)
|
|
2918
|
+
promptCliReportedFailure.delete(promptId);
|
|
2919
|
+
if (cliReportedFailure && (code ?? 0) === 0) {
|
|
2920
|
+
logger.warn('CLI reported a failed run but exited 0 — recording it as failed');
|
|
2921
|
+
}
|
|
2922
|
+
const exitCode = (claudeApiError || cliReportedFailure) ? (code || 1) : (code ?? 0);
|
|
2843
2923
|
const duration = Date.now() - startTime;
|
|
2844
2924
|
const status = exitCode === 0 ? 'completed' : 'failed';
|
|
2845
2925
|
if (exitCode === 0) {
|
|
@@ -3722,7 +3802,7 @@ export function listResumableSessions(workingDir, subAgentId, limit = 12) {
|
|
|
3722
3802
|
* The session runs with --dangerously-skip-permissions for uninterrupted interaction.
|
|
3723
3803
|
*/
|
|
3724
3804
|
export async function startSession(options) {
|
|
3725
|
-
const { sessionId, workingDirectory, channel, cols = 120, rows = 40, subAgentId, subAgentName, resume, resumeSessionId } = options;
|
|
3805
|
+
const { sessionId, workingDirectory, channel, cols = 120, rows = 40, subAgentId, subAgentName, resume, resumeSessionId, assisted } = options;
|
|
3726
3806
|
// If this exact sessionId is already live, terminate it before re-creating.
|
|
3727
3807
|
// Sessions on OTHER workstreams are left untouched — they run concurrently.
|
|
3728
3808
|
if (sessions.has(sessionId)) {
|
|
@@ -3851,7 +3931,15 @@ export async function startSession(options) {
|
|
|
3851
3931
|
catch { /* file not found — try next */ }
|
|
3852
3932
|
}
|
|
3853
3933
|
const browserBlockPart = globalBrowserEnabled ? `${BROWSER_TOOLS_PROMPT_BLOCK}\n\n` : '';
|
|
3854
|
-
|
|
3934
|
+
// An assisted session is on a QA branch whose diff a reviewer has to read, so
|
|
3935
|
+
// it gets the same deploy suppression a dispatched assisted prompt gets. It
|
|
3936
|
+
// leads the block rather than trailing it: the operator can type anything
|
|
3937
|
+
// here, and a rule buried under 14KB of capabilities is a rule the model has
|
|
3938
|
+
// already stopped weighting by the time it matters.
|
|
3939
|
+
const assistedBlockPart = assisted
|
|
3940
|
+
? `## Assisted QA run\n\nYou are on branch \`${assisted.branch}\`, working one item of an assisted QA run. Deployment is DISABLED: do NOT deploy, do NOT call the Orquesta Deploy API, and do NOT push to the main branch. A reviewer reads this diff before anything ships.\n\n`
|
|
3941
|
+
: '';
|
|
3942
|
+
const systemPromptBlock = `${assistedBlockPart}${browserBlockPart}${ORQUESTA_CAPABILITIES_PROMPT_BLOCK}${liveCoordination}${projectMdContent}`;
|
|
3855
3943
|
// On Windows the prompt (~38KB) + a big CLAUDE.md can exceed CreateProcess's
|
|
3856
3944
|
// 32767-char command-line cap and the interactive session fails to spawn. Both
|
|
3857
3945
|
// orquesta-cli and claude support --append-system-prompt-file, so we ALWAYS write
|
|
@@ -4025,6 +4113,7 @@ export async function startSession(options) {
|
|
|
4025
4113
|
lastPtyOutputAt: Date.now(),
|
|
4026
4114
|
rogerthatWatcher: null,
|
|
4027
4115
|
transcriptTail: null,
|
|
4116
|
+
assisted,
|
|
4028
4117
|
};
|
|
4029
4118
|
sessions.set(sessionId, session);
|
|
4030
4119
|
ensureSessionReaper(); // reap this session if it's later abandoned without session:end
|
|
@@ -4148,9 +4237,14 @@ export async function startSession(options) {
|
|
|
4148
4237
|
sessions.delete(sessionId);
|
|
4149
4238
|
// Note: do NOT clear rogerthatLogOffsets here — the map is shared with
|
|
4150
4239
|
// one-shot execute() prompts and persists for the agent process lifetime.
|
|
4151
|
-
// Notify index.ts to drain any queued prompts
|
|
4240
|
+
// Notify index.ts to drain any queued prompts — and, when this terminal
|
|
4241
|
+
// was a claimed assisted item, to commit and report its diff.
|
|
4152
4242
|
if (onSessionEndedCallback)
|
|
4153
|
-
onSessionEndedCallback(
|
|
4243
|
+
onSessionEndedCallback({
|
|
4244
|
+
sessionId,
|
|
4245
|
+
workingDirectory: exitingSession.workingDirectory,
|
|
4246
|
+
assisted: exitingSession.assisted,
|
|
4247
|
+
});
|
|
4154
4248
|
}
|
|
4155
4249
|
});
|
|
4156
4250
|
return true;
|
|
@@ -4322,7 +4416,11 @@ export function endSession(sessionId) {
|
|
|
4322
4416
|
// Manually send session:ended — onExit won't do it since we removed the session
|
|
4323
4417
|
sendSessionEnded(ch, sessionId, -1, duration).catch(() => { });
|
|
4324
4418
|
if (onSessionEndedCallback)
|
|
4325
|
-
onSessionEndedCallback(
|
|
4419
|
+
onSessionEndedCallback({
|
|
4420
|
+
sessionId,
|
|
4421
|
+
workingDirectory: sessionRef.workingDirectory,
|
|
4422
|
+
assisted: sessionRef.assisted,
|
|
4423
|
+
});
|
|
4326
4424
|
}
|
|
4327
4425
|
}, 2000);
|
|
4328
4426
|
}
|
|
@@ -4454,6 +4552,14 @@ export function terminateSession(sessionId) {
|
|
|
4454
4552
|
const targets = sessionId
|
|
4455
4553
|
? (sessions.has(sessionId) ? [sessions.get(sessionId)] : [])
|
|
4456
4554
|
: [...sessions.values()];
|
|
4555
|
+
// Captured before the loop kills them: a reaped or force-ended assisted
|
|
4556
|
+
// session still has to report, or its item stays `in_progress` forever and
|
|
4557
|
+
// the whole run is wedged behind a terminal nobody is sitting at.
|
|
4558
|
+
const ended = targets.map(t => ({
|
|
4559
|
+
sessionId: t.sessionId,
|
|
4560
|
+
workingDirectory: t.workingDirectory,
|
|
4561
|
+
assisted: t.assisted,
|
|
4562
|
+
}));
|
|
4457
4563
|
for (const s of targets) {
|
|
4458
4564
|
const { sessionId: sid, channel, startTime, ptyProcess } = s;
|
|
4459
4565
|
const duration = Date.now() - startTime;
|
|
@@ -4477,8 +4583,11 @@ export function terminateSession(sessionId) {
|
|
|
4477
4583
|
// because we already removed the session above
|
|
4478
4584
|
sendSessionEnded(channel, sid, -1, duration).catch(() => { });
|
|
4479
4585
|
}
|
|
4480
|
-
// Drain any queued prompts once
|
|
4481
|
-
|
|
4482
|
-
|
|
4586
|
+
// Drain any queued prompts after terminating, once per session so an
|
|
4587
|
+
// assisted envelope is never dropped when several are killed together.
|
|
4588
|
+
if (onSessionEndedCallback) {
|
|
4589
|
+
for (const info of ended)
|
|
4590
|
+
onSessionEndedCallback(info);
|
|
4591
|
+
}
|
|
4483
4592
|
}
|
|
4484
4593
|
//# sourceMappingURL=executor.js.map
|