orquesta-agent 0.2.156 → 0.2.158
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 +30 -5
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +148 -76
- package/dist/executor.js.map +1 -1
- package/dist/index.js +54 -31
- package/dist/index.js.map +1 -1
- package/dist/socketio-transport.d.ts +2 -0
- package/dist/socketio-transport.d.ts.map +1 -1
- package/dist/supabase.d.ts +27 -13
- package/dist/supabase.d.ts.map +1 -1
- package/dist/supabase.js +5 -1
- package/dist/supabase.js.map +1 -1
- package/dist/ws-client.d.ts +2 -0
- package/dist/ws-client.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/executor.d.ts
CHANGED
|
@@ -134,6 +134,9 @@ export interface StartSessionOptions {
|
|
|
134
134
|
channel: BroadcastChannel;
|
|
135
135
|
cols?: number;
|
|
136
136
|
rows?: number;
|
|
137
|
+
/** Workstream (sub-agent) this session belongs to. undefined = default slot. */
|
|
138
|
+
subAgentId?: string;
|
|
139
|
+
subAgentName?: string;
|
|
137
140
|
}
|
|
138
141
|
/**
|
|
139
142
|
* Start an interactive Claude CLI session.
|
|
@@ -157,15 +160,36 @@ export declare function endSession(sessionId: string): boolean;
|
|
|
157
160
|
*/
|
|
158
161
|
export declare function resizeSession(sessionId: string, cols: number, rows: number): boolean;
|
|
159
162
|
/**
|
|
160
|
-
* Check if there's
|
|
163
|
+
* Check if there's ANY active interactive session.
|
|
161
164
|
*/
|
|
162
165
|
export declare function hasActiveSession(): boolean;
|
|
163
166
|
/**
|
|
164
|
-
*
|
|
167
|
+
* Check if there's an active interactive session bound to a given workstream
|
|
168
|
+
* slot (undefined/'' = the default slot). Prompt-queue gating uses this so a
|
|
169
|
+
* session in workstream A doesn't block prompts targeting workstream B.
|
|
170
|
+
*/
|
|
171
|
+
export declare function hasActiveSessionFor(subAgentId?: string | null): boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Get the first active session ID, if any (back-compat single-session callers).
|
|
165
174
|
*/
|
|
166
175
|
export declare function getActiveSessionId(): string | null;
|
|
176
|
+
export interface SessionInfo {
|
|
177
|
+
sessionId: string;
|
|
178
|
+
subAgentId: string | null;
|
|
179
|
+
subAgentName: string | null;
|
|
180
|
+
workingDirectory: string;
|
|
181
|
+
uptime: number;
|
|
182
|
+
cliType?: 'claude' | 'orquesta';
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* List every active interactive session — the dashboard renders these so each
|
|
186
|
+
* user can see which workstreams are busy and attach to one (or start a new one
|
|
187
|
+
* elsewhere).
|
|
188
|
+
*/
|
|
189
|
+
export declare function getSessionList(): SessionInfo[];
|
|
167
190
|
/**
|
|
168
|
-
* Get full session status for dashboard status queries.
|
|
191
|
+
* Get full session status for dashboard status queries. Returns the first
|
|
192
|
+
* active session for back-compat, plus the full list under `sessions`.
|
|
169
193
|
*/
|
|
170
194
|
export declare function getSessionStatus(): {
|
|
171
195
|
active: boolean;
|
|
@@ -173,10 +197,11 @@ export declare function getSessionStatus(): {
|
|
|
173
197
|
workingDirectory: string | null;
|
|
174
198
|
uptime: number | null;
|
|
175
199
|
cliType?: 'claude' | 'orquesta';
|
|
200
|
+
sessions: SessionInfo[];
|
|
176
201
|
};
|
|
177
202
|
/**
|
|
178
|
-
* Force terminate
|
|
203
|
+
* Force terminate a session (for cleanup). With no sessionId, terminates ALL.
|
|
179
204
|
* Sends session:ended back to the dashboard so it can update UI state.
|
|
180
205
|
*/
|
|
181
|
-
export declare function terminateSession(): void;
|
|
206
|
+
export declare function terminateSession(sessionId?: string): void;
|
|
182
207
|
//# sourceMappingURL=executor.d.ts.map
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -2505,8 +2505,11 @@ export async function generatePlanItems(options) {
|
|
|
2505
2505
|
async function sendViaFreshChannel(_channelName, channel, generationId, planId, items, error) {
|
|
2506
2506
|
await sendPlanItemsGenerated(channel, generationId, planId, items, error);
|
|
2507
2507
|
}
|
|
2508
|
-
// Track active interactive
|
|
2509
|
-
|
|
2508
|
+
// Track active interactive sessions, keyed by sessionId. The agent runs one PTY
|
|
2509
|
+
// per workstream concurrently, so several sessions can be live at once.
|
|
2510
|
+
const sessions = new Map();
|
|
2511
|
+
// Helper: normalize a slot key (undefined/'' both mean the default slot).
|
|
2512
|
+
function slotKey(subAgentId) { return subAgentId || ''; }
|
|
2510
2513
|
// Callback fired when a session ends — allows index.ts to drain the prompt queue
|
|
2511
2514
|
let onSessionEndedCallback = null;
|
|
2512
2515
|
// Per-file byte offset into /tmp/rr-*.log (rogerthat-handoff listener inboxes).
|
|
@@ -2614,36 +2617,38 @@ function readNewRogerthatMessages() {
|
|
|
2614
2617
|
const PHONE_IDLE_THRESHOLD_MS = 1500;
|
|
2615
2618
|
/** Internal helper — try to flush buffered phone messages into the PTY. */
|
|
2616
2619
|
function tryFlushPhoneToPty(sessionId) {
|
|
2617
|
-
|
|
2620
|
+
const s = sessions.get(sessionId);
|
|
2621
|
+
if (!s || !s.isActive)
|
|
2618
2622
|
return;
|
|
2619
|
-
if (
|
|
2620
|
-
clearTimeout(
|
|
2621
|
-
|
|
2623
|
+
if (s.pendingPhoneTimer) {
|
|
2624
|
+
clearTimeout(s.pendingPhoneTimer);
|
|
2625
|
+
s.pendingPhoneTimer = null;
|
|
2622
2626
|
}
|
|
2623
|
-
const block =
|
|
2627
|
+
const block = s.pendingPhoneBlock || '';
|
|
2624
2628
|
if (!block)
|
|
2625
2629
|
return;
|
|
2626
|
-
const lastOut =
|
|
2630
|
+
const lastOut = s.lastPtyOutputAt ?? 0;
|
|
2627
2631
|
const idleFor = Date.now() - lastOut;
|
|
2628
2632
|
if (idleFor >= PHONE_IDLE_THRESHOLD_MS) {
|
|
2629
|
-
|
|
2633
|
+
s.pendingPhoneBlock = '';
|
|
2630
2634
|
logger.info(`[Session] Flushing ${block.length} chars of buffered phone messages to PTY (idle ${idleFor}ms)`);
|
|
2631
2635
|
writeSessionText(sessionId, block);
|
|
2632
2636
|
}
|
|
2633
2637
|
else {
|
|
2634
2638
|
const waitMs = PHONE_IDLE_THRESHOLD_MS - idleFor + 100;
|
|
2635
|
-
|
|
2639
|
+
s.pendingPhoneTimer = setTimeout(() => tryFlushPhoneToPty(sessionId), waitMs);
|
|
2636
2640
|
}
|
|
2637
2641
|
}
|
|
2638
2642
|
/** Internal helper — called when fs.watch notifies us about /tmp/rr-*.log changes. */
|
|
2639
2643
|
function onRogerthatLogChange(sessionId) {
|
|
2640
|
-
|
|
2644
|
+
const s = sessions.get(sessionId);
|
|
2645
|
+
if (!s || !s.isActive)
|
|
2641
2646
|
return;
|
|
2642
2647
|
const block = readNewRogerthatMessages();
|
|
2643
2648
|
if (!block)
|
|
2644
2649
|
return;
|
|
2645
|
-
|
|
2646
|
-
if (!
|
|
2650
|
+
s.pendingPhoneBlock = (s.pendingPhoneBlock || '') + block;
|
|
2651
|
+
if (!s.pendingPhoneTimer)
|
|
2647
2652
|
tryFlushPhoneToPty(sessionId);
|
|
2648
2653
|
}
|
|
2649
2654
|
/**
|
|
@@ -2684,11 +2689,12 @@ export function setOnSessionEnded(cb) {
|
|
|
2684
2689
|
* The session runs with --dangerously-skip-permissions for uninterrupted interaction.
|
|
2685
2690
|
*/
|
|
2686
2691
|
export async function startSession(options) {
|
|
2687
|
-
const { sessionId, workingDirectory, channel, cols = 120, rows = 40 } = options;
|
|
2688
|
-
//
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
+
const { sessionId, workingDirectory, channel, cols = 120, rows = 40, subAgentId, subAgentName } = options;
|
|
2693
|
+
// If this exact sessionId is already live, terminate it before re-creating.
|
|
2694
|
+
// Sessions on OTHER workstreams are left untouched — they run concurrently.
|
|
2695
|
+
if (sessions.has(sessionId)) {
|
|
2696
|
+
logger.warn(`Restarting existing session ${sessionId}`);
|
|
2697
|
+
terminateSession(sessionId);
|
|
2692
2698
|
}
|
|
2693
2699
|
const cwd = workingDirectory || process.cwd();
|
|
2694
2700
|
const startTime = Date.now();
|
|
@@ -2797,12 +2803,14 @@ export async function startSession(options) {
|
|
|
2797
2803
|
}
|
|
2798
2804
|
logger.success(`Session started with PID: ${ptyProcess.pid}`);
|
|
2799
2805
|
// Create session object
|
|
2800
|
-
|
|
2806
|
+
const session = {
|
|
2801
2807
|
sessionId,
|
|
2802
2808
|
ptyProcess,
|
|
2803
2809
|
channel,
|
|
2804
2810
|
workingDirectory: cwd,
|
|
2805
2811
|
startTime,
|
|
2812
|
+
subAgentId,
|
|
2813
|
+
subAgentName,
|
|
2806
2814
|
cliType: cliCommand === 'orquesta' ? 'orquesta' : 'claude',
|
|
2807
2815
|
isActive: true,
|
|
2808
2816
|
pendingPhoneBlock: '',
|
|
@@ -2810,10 +2818,11 @@ export async function startSession(options) {
|
|
|
2810
2818
|
lastPtyOutputAt: Date.now(),
|
|
2811
2819
|
rogerthatWatcher: null,
|
|
2812
2820
|
};
|
|
2821
|
+
sessions.set(sessionId, session);
|
|
2813
2822
|
// Arm the live phone-message monitor — pushes new /tmp/rr-*.log content into
|
|
2814
2823
|
// the PTY as if the operator had typed it, so they can hold a full
|
|
2815
2824
|
// conversation from the phone without touching the dashboard.
|
|
2816
|
-
|
|
2825
|
+
session.rogerthatWatcher = startRogerthatMonitor(sessionId);
|
|
2817
2826
|
// Send session:started only after Claude produces its first output.
|
|
2818
2827
|
// This ensures the UI doesn't activate the input field before Claude is
|
|
2819
2828
|
// actually ready — early input would otherwise be silently ignored.
|
|
@@ -2830,7 +2839,7 @@ export async function startSession(options) {
|
|
|
2830
2839
|
const FLUSH_INTERVAL_MS = 80;
|
|
2831
2840
|
const flushOutput = () => {
|
|
2832
2841
|
flushTimer = null;
|
|
2833
|
-
if (!outputBuffer || !
|
|
2842
|
+
if (!outputBuffer || !sessions.get(sessionId)?.isActive)
|
|
2834
2843
|
return;
|
|
2835
2844
|
const data = outputBuffer;
|
|
2836
2845
|
outputBuffer = '';
|
|
@@ -2846,13 +2855,14 @@ export async function startSession(options) {
|
|
|
2846
2855
|
logger.output('stdout', data.slice(0, 100).replace(/[\x00-\x1f]/g, '·') + (data.length > 100 ? '...' : ''));
|
|
2847
2856
|
// Mark the PTY as recently active — the rogerthat live monitor uses this
|
|
2848
2857
|
// to decide whether Claude is idle enough to receive injected phone input.
|
|
2849
|
-
|
|
2850
|
-
|
|
2858
|
+
const liveSession = sessions.get(sessionId);
|
|
2859
|
+
if (liveSession) {
|
|
2860
|
+
liveSession.lastPtyOutputAt = Date.now();
|
|
2851
2861
|
}
|
|
2852
2862
|
// Confirm session is ready on first output from Claude
|
|
2853
2863
|
if (!sessionStartedSent) {
|
|
2854
2864
|
sessionStartedSent = true;
|
|
2855
|
-
sendSessionStarted(channel, sessionId, cwd, cliCommand === 'orquesta' ? 'orquesta' : 'claude');
|
|
2865
|
+
sendSessionStarted(channel, sessionId, cwd, cliCommand === 'orquesta' ? 'orquesta' : 'claude', { id: subAgentId, name: subAgentName });
|
|
2856
2866
|
}
|
|
2857
2867
|
// Append to buffer; schedule flush if not already pending
|
|
2858
2868
|
outputBuffer += data;
|
|
@@ -2865,7 +2875,7 @@ export async function startSession(options) {
|
|
|
2865
2875
|
if (!sessionStartedSent) {
|
|
2866
2876
|
sessionStartedSent = true;
|
|
2867
2877
|
logger.warn('[Session] No initial output after 5s, sending session:started anyway');
|
|
2868
|
-
sendSessionStarted(channel, sessionId, cwd, cliCommand === 'orquesta' ? 'orquesta' : 'claude');
|
|
2878
|
+
sendSessionStarted(channel, sessionId, cwd, cliCommand === 'orquesta' ? 'orquesta' : 'claude', { id: subAgentId, name: subAgentName });
|
|
2869
2879
|
}
|
|
2870
2880
|
}, 5000);
|
|
2871
2881
|
// Handle PTY exit
|
|
@@ -2890,18 +2900,19 @@ export async function startSession(options) {
|
|
|
2890
2900
|
logger.error(`[Session] Early exit detected: ${hint}`);
|
|
2891
2901
|
sendSessionError(channel, sessionId, hint);
|
|
2892
2902
|
}
|
|
2893
|
-
|
|
2903
|
+
const exitingSession = sessions.get(sessionId);
|
|
2904
|
+
if (exitingSession) {
|
|
2894
2905
|
// Tear down the rogerthat live monitor before clearing the session
|
|
2895
2906
|
try {
|
|
2896
|
-
|
|
2907
|
+
exitingSession.rogerthatWatcher?.close();
|
|
2897
2908
|
}
|
|
2898
2909
|
catch { /* already closed */ }
|
|
2899
|
-
if (
|
|
2900
|
-
clearTimeout(
|
|
2901
|
-
|
|
2910
|
+
if (exitingSession.pendingPhoneTimer) {
|
|
2911
|
+
clearTimeout(exitingSession.pendingPhoneTimer);
|
|
2912
|
+
exitingSession.pendingPhoneTimer = null;
|
|
2902
2913
|
}
|
|
2903
2914
|
sendSessionEnded(channel, sessionId, exitCode ?? 0, duration);
|
|
2904
|
-
|
|
2915
|
+
sessions.delete(sessionId);
|
|
2905
2916
|
// Note: do NOT clear rogerthatLogOffsets here — the map is shared with
|
|
2906
2917
|
// one-shot execute() prompts and persists for the agent process lifetime.
|
|
2907
2918
|
// Notify index.ts to drain any queued prompts
|
|
@@ -2919,14 +2930,15 @@ export async function startSession(options) {
|
|
|
2919
2930
|
* their absolute paths are appended to the message text so Claude can Read them.
|
|
2920
2931
|
*/
|
|
2921
2932
|
export function sendSessionInput(sessionId, input, raw = false, attachments) {
|
|
2922
|
-
|
|
2933
|
+
const s = sessions.get(sessionId);
|
|
2934
|
+
if (!s) {
|
|
2923
2935
|
logger.warn(`No active session with ID: ${sessionId}`);
|
|
2924
2936
|
return false;
|
|
2925
2937
|
}
|
|
2926
2938
|
try {
|
|
2927
2939
|
if (raw) {
|
|
2928
2940
|
// Send raw bytes directly (e.g. ESC=\x1b, Ctrl+C=\x03)
|
|
2929
|
-
|
|
2941
|
+
s.ptyProcess.write(input);
|
|
2930
2942
|
logger.info(`Session raw input sent: 0x${Buffer.from(input).toString('hex')}`);
|
|
2931
2943
|
return true;
|
|
2932
2944
|
}
|
|
@@ -2982,10 +2994,11 @@ export function sendSessionInput(sessionId, input, raw = false, attachments) {
|
|
|
2982
2994
|
* before Enter arrives.
|
|
2983
2995
|
*/
|
|
2984
2996
|
function writeSessionText(sessionId, input) {
|
|
2985
|
-
|
|
2997
|
+
const s = sessions.get(sessionId);
|
|
2998
|
+
if (!s || !s.isActive)
|
|
2986
2999
|
return;
|
|
2987
3000
|
const text = input.endsWith('\r') ? input.slice(0, -1) : input;
|
|
2988
|
-
const isOrquesta =
|
|
3001
|
+
const isOrquesta = s.cliType === 'orquesta';
|
|
2989
3002
|
// Bracketed paste for non-trivial inputs. Claude's TUI uses it to treat a long
|
|
2990
3003
|
// block as a coherent paste. But orquesta-cli's Ink stack SWALLOWS the
|
|
2991
3004
|
// \x1b[200~…\x1b[201~ sequence at its own stdin layer — the text never reaches
|
|
@@ -2994,7 +3007,7 @@ function writeSessionText(sessionId, input) {
|
|
|
2994
3007
|
// fine; the separate \r below submits).
|
|
2995
3008
|
const usePasteMarkers = text.length > 200 && !isOrquesta;
|
|
2996
3009
|
const payload = usePasteMarkers ? `\x1b[200~${text}\x1b[201~` : text;
|
|
2997
|
-
|
|
3010
|
+
s.ptyProcess.write(payload);
|
|
2998
3011
|
if (isOrquesta) {
|
|
2999
3012
|
// orquesta-cli (Ink) drops stdin events while it is rendering / processing.
|
|
3000
3013
|
// If we fire \r during an active turn the Enter is queued and only surfaces
|
|
@@ -3008,12 +3021,13 @@ function writeSessionText(sessionId, input) {
|
|
|
3008
3021
|
const MAX_WAIT_MS = 5000;
|
|
3009
3022
|
const startAt = Date.now();
|
|
3010
3023
|
const trySubmit = () => {
|
|
3011
|
-
|
|
3024
|
+
const cur = sessions.get(sessionId);
|
|
3025
|
+
if (!cur || !cur.isActive)
|
|
3012
3026
|
return;
|
|
3013
3027
|
const elapsed = Date.now() - startAt;
|
|
3014
|
-
const idleFor = Date.now() - (
|
|
3028
|
+
const idleFor = Date.now() - (cur.lastPtyOutputAt ?? startAt);
|
|
3015
3029
|
if (idleFor >= IDLE_THRESHOLD_MS || elapsed >= MAX_WAIT_MS) {
|
|
3016
|
-
|
|
3030
|
+
cur.ptyProcess.write('\r');
|
|
3017
3031
|
logger.info(`Session input submitted (${text.length} chars, idle=${idleFor}ms, elapsed=${elapsed}ms)`);
|
|
3018
3032
|
}
|
|
3019
3033
|
else {
|
|
@@ -3028,8 +3042,9 @@ function writeSessionText(sessionId, input) {
|
|
|
3028
3042
|
const newlineCount = (text.match(/\n/g) || []).length;
|
|
3029
3043
|
const delayMs = Math.min(800, 50 + Math.floor(text.length / 20) + newlineCount * 80);
|
|
3030
3044
|
setTimeout(() => {
|
|
3031
|
-
|
|
3032
|
-
|
|
3045
|
+
const cur = sessions.get(sessionId);
|
|
3046
|
+
if (cur?.isActive) {
|
|
3047
|
+
cur.ptyProcess.write('\r');
|
|
3033
3048
|
}
|
|
3034
3049
|
}, delayMs);
|
|
3035
3050
|
}
|
|
@@ -3039,7 +3054,8 @@ function writeSessionText(sessionId, input) {
|
|
|
3039
3054
|
* End the active interactive session.
|
|
3040
3055
|
*/
|
|
3041
3056
|
export function endSession(sessionId) {
|
|
3042
|
-
|
|
3057
|
+
const sessionRef = sessions.get(sessionId);
|
|
3058
|
+
if (!sessionRef) {
|
|
3043
3059
|
logger.warn(`No active session with ID: ${sessionId}`);
|
|
3044
3060
|
return false;
|
|
3045
3061
|
}
|
|
@@ -3048,8 +3064,7 @@ export function endSession(sessionId) {
|
|
|
3048
3064
|
// Try graceful shutdown — send /exit to Claude CLI.
|
|
3049
3065
|
// Must split text and \r into two separate writes (same reason as sendSessionInput):
|
|
3050
3066
|
// Ink misprocesses `/exit\r` as a cursor-move when both arrive in the same PTY chunk.
|
|
3051
|
-
|
|
3052
|
-
const sessionRef = activeSession;
|
|
3067
|
+
sessionRef.ptyProcess.write('/exit');
|
|
3053
3068
|
setTimeout(() => {
|
|
3054
3069
|
try {
|
|
3055
3070
|
sessionRef.ptyProcess.write('\r');
|
|
@@ -3057,27 +3072,27 @@ export function endSession(sessionId) {
|
|
|
3057
3072
|
catch (_) { /* already dead */ }
|
|
3058
3073
|
}, 50);
|
|
3059
3074
|
// Mark as inactive so no more output is forwarded
|
|
3060
|
-
|
|
3075
|
+
sessionRef.isActive = false;
|
|
3061
3076
|
// Give Claude a moment to exit gracefully before forcing termination
|
|
3062
3077
|
setTimeout(() => {
|
|
3063
|
-
if (
|
|
3078
|
+
if (sessions.get(sessionId) === sessionRef) {
|
|
3064
3079
|
logger.warn('Session did not exit gracefully, forcing termination');
|
|
3065
3080
|
try {
|
|
3066
3081
|
sessionRef.ptyProcess.kill('SIGTERM');
|
|
3067
3082
|
}
|
|
3068
3083
|
catch (_) { /* already dead */ }
|
|
3069
3084
|
setTimeout(() => {
|
|
3070
|
-
if (
|
|
3071
|
-
const { channel: ch, startTime: st } =
|
|
3085
|
+
if (sessions.get(sessionId) === sessionRef) {
|
|
3086
|
+
const { channel: ch, startTime: st } = sessionRef;
|
|
3072
3087
|
const duration = Date.now() - st;
|
|
3073
3088
|
logger.warn(`Session ${sessionId} did not respond to SIGTERM, sending SIGKILL`);
|
|
3074
|
-
|
|
3075
|
-
|
|
3089
|
+
sessionRef.isActive = false;
|
|
3090
|
+
sessions.delete(sessionId); // delete BEFORE kill so onExit doesn't double-send
|
|
3076
3091
|
try {
|
|
3077
3092
|
sessionRef.ptyProcess.kill('SIGKILL');
|
|
3078
3093
|
}
|
|
3079
3094
|
catch (_) { /* already dead */ }
|
|
3080
|
-
// Manually send session:ended — onExit won't do it since we
|
|
3095
|
+
// Manually send session:ended — onExit won't do it since we removed the session
|
|
3081
3096
|
sendSessionEnded(ch, sessionId, -1, duration).catch(() => { });
|
|
3082
3097
|
if (onSessionEndedCallback)
|
|
3083
3098
|
onSessionEndedCallback();
|
|
@@ -3096,10 +3111,11 @@ export function endSession(sessionId) {
|
|
|
3096
3111
|
* Resize the active interactive session PTY to match the frontend terminal dimensions.
|
|
3097
3112
|
*/
|
|
3098
3113
|
export function resizeSession(sessionId, cols, rows) {
|
|
3099
|
-
|
|
3114
|
+
const s = sessions.get(sessionId);
|
|
3115
|
+
if (!s)
|
|
3100
3116
|
return false;
|
|
3101
3117
|
try {
|
|
3102
|
-
|
|
3118
|
+
s.ptyProcess.resize(cols, rows);
|
|
3103
3119
|
logger.debug(`[Session] Resized PTY to ${cols}x${rows}`);
|
|
3104
3120
|
return true;
|
|
3105
3121
|
}
|
|
@@ -3109,54 +3125,110 @@ export function resizeSession(sessionId, cols, rows) {
|
|
|
3109
3125
|
}
|
|
3110
3126
|
}
|
|
3111
3127
|
/**
|
|
3112
|
-
* Check if there's
|
|
3128
|
+
* Check if there's ANY active interactive session.
|
|
3113
3129
|
*/
|
|
3114
3130
|
export function hasActiveSession() {
|
|
3115
|
-
|
|
3131
|
+
for (const s of sessions.values())
|
|
3132
|
+
if (s.isActive)
|
|
3133
|
+
return true;
|
|
3134
|
+
return false;
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* Check if there's an active interactive session bound to a given workstream
|
|
3138
|
+
* slot (undefined/'' = the default slot). Prompt-queue gating uses this so a
|
|
3139
|
+
* session in workstream A doesn't block prompts targeting workstream B.
|
|
3140
|
+
*/
|
|
3141
|
+
export function hasActiveSessionFor(subAgentId) {
|
|
3142
|
+
const key = slotKey(subAgentId);
|
|
3143
|
+
for (const s of sessions.values()) {
|
|
3144
|
+
if (s.isActive && slotKey(s.subAgentId) === key)
|
|
3145
|
+
return true;
|
|
3146
|
+
}
|
|
3147
|
+
return false;
|
|
3116
3148
|
}
|
|
3117
3149
|
/**
|
|
3118
|
-
* Get the
|
|
3150
|
+
* Get the first active session ID, if any (back-compat single-session callers).
|
|
3119
3151
|
*/
|
|
3120
3152
|
export function getActiveSessionId() {
|
|
3121
|
-
|
|
3153
|
+
for (const s of sessions.values())
|
|
3154
|
+
if (s.isActive)
|
|
3155
|
+
return s.sessionId;
|
|
3156
|
+
return null;
|
|
3122
3157
|
}
|
|
3123
3158
|
/**
|
|
3124
|
-
*
|
|
3159
|
+
* List every active interactive session — the dashboard renders these so each
|
|
3160
|
+
* user can see which workstreams are busy and attach to one (or start a new one
|
|
3161
|
+
* elsewhere).
|
|
3162
|
+
*/
|
|
3163
|
+
export function getSessionList() {
|
|
3164
|
+
const now = Date.now();
|
|
3165
|
+
const list = [];
|
|
3166
|
+
for (const s of sessions.values()) {
|
|
3167
|
+
if (!s.isActive)
|
|
3168
|
+
continue;
|
|
3169
|
+
list.push({
|
|
3170
|
+
sessionId: s.sessionId,
|
|
3171
|
+
subAgentId: s.subAgentId ?? null,
|
|
3172
|
+
subAgentName: s.subAgentName ?? null,
|
|
3173
|
+
workingDirectory: s.workingDirectory,
|
|
3174
|
+
uptime: now - s.startTime,
|
|
3175
|
+
cliType: s.cliType,
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
return list;
|
|
3179
|
+
}
|
|
3180
|
+
/**
|
|
3181
|
+
* Get full session status for dashboard status queries. Returns the first
|
|
3182
|
+
* active session for back-compat, plus the full list under `sessions`.
|
|
3125
3183
|
*/
|
|
3126
3184
|
export function getSessionStatus() {
|
|
3127
|
-
|
|
3185
|
+
const list = getSessionList();
|
|
3186
|
+
const first = list[0];
|
|
3187
|
+
if (first) {
|
|
3128
3188
|
return {
|
|
3129
3189
|
active: true,
|
|
3130
|
-
sessionId:
|
|
3131
|
-
workingDirectory:
|
|
3132
|
-
uptime:
|
|
3190
|
+
sessionId: first.sessionId,
|
|
3191
|
+
workingDirectory: first.workingDirectory,
|
|
3192
|
+
uptime: first.uptime,
|
|
3133
3193
|
// Lets the dashboard re-attach with the right controls (PLAN vs Mode).
|
|
3134
|
-
cliType:
|
|
3194
|
+
cliType: first.cliType,
|
|
3195
|
+
sessions: list,
|
|
3135
3196
|
};
|
|
3136
3197
|
}
|
|
3137
|
-
return { active: false, sessionId: null, workingDirectory: null, uptime: null };
|
|
3198
|
+
return { active: false, sessionId: null, workingDirectory: null, uptime: null, sessions: [] };
|
|
3138
3199
|
}
|
|
3139
3200
|
/**
|
|
3140
|
-
* Force terminate
|
|
3201
|
+
* Force terminate a session (for cleanup). With no sessionId, terminates ALL.
|
|
3141
3202
|
* Sends session:ended back to the dashboard so it can update UI state.
|
|
3142
3203
|
*/
|
|
3143
|
-
export function terminateSession() {
|
|
3144
|
-
|
|
3145
|
-
|
|
3204
|
+
export function terminateSession(sessionId) {
|
|
3205
|
+
const targets = sessionId
|
|
3206
|
+
? (sessions.has(sessionId) ? [sessions.get(sessionId)] : [])
|
|
3207
|
+
: [...sessions.values()];
|
|
3208
|
+
for (const s of targets) {
|
|
3209
|
+
const { sessionId: sid, channel, startTime, ptyProcess } = s;
|
|
3146
3210
|
const duration = Date.now() - startTime;
|
|
3147
|
-
logger.warn(`Force terminating active session: ${
|
|
3148
|
-
|
|
3149
|
-
|
|
3211
|
+
logger.warn(`Force terminating active session: ${sid}`);
|
|
3212
|
+
s.isActive = false;
|
|
3213
|
+
try {
|
|
3214
|
+
s.rogerthatWatcher?.close();
|
|
3215
|
+
}
|
|
3216
|
+
catch { /* already closed */ }
|
|
3217
|
+
if (s.pendingPhoneTimer) {
|
|
3218
|
+
clearTimeout(s.pendingPhoneTimer);
|
|
3219
|
+
s.pendingPhoneTimer = null;
|
|
3220
|
+
}
|
|
3221
|
+
sessions.delete(sid); // delete BEFORE kill so onExit doesn't double-send
|
|
3150
3222
|
try {
|
|
3151
3223
|
ptyProcess.kill('SIGKILL');
|
|
3152
3224
|
}
|
|
3153
3225
|
catch (_) { /* already dead */ }
|
|
3154
3226
|
// Notify dashboard — the onExit handler won't fire session:ended
|
|
3155
|
-
// because we already
|
|
3156
|
-
sendSessionEnded(channel,
|
|
3157
|
-
// Drain any queued prompts
|
|
3158
|
-
if (onSessionEndedCallback)
|
|
3159
|
-
onSessionEndedCallback();
|
|
3227
|
+
// because we already removed the session above
|
|
3228
|
+
sendSessionEnded(channel, sid, -1, duration).catch(() => { });
|
|
3160
3229
|
}
|
|
3230
|
+
// Drain any queued prompts once after terminating
|
|
3231
|
+
if (targets.length > 0 && onSessionEndedCallback)
|
|
3232
|
+
onSessionEndedCallback();
|
|
3161
3233
|
}
|
|
3162
3234
|
//# sourceMappingURL=executor.js.map
|