oh-my-opencode-slim 2.2.2 → 2.2.3
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.ja-JP.md +3 -3
- package/README.ko-KR.md +3 -3
- package/README.md +15 -4
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +36 -40
- package/dist/cli/system.d.ts +2 -2
- package/dist/config/constants.d.ts +0 -1
- package/dist/config/schema.d.ts +3 -0
- package/dist/council/council-manager.d.ts +1 -3
- package/dist/hooks/task-session-manager/index.d.ts +3 -0
- package/dist/hooks/task-session-manager/pending-call-tracker.d.ts +2 -0
- package/dist/index-event.d.ts +17 -0
- package/dist/index.js +457 -130
- package/dist/multiplexer/index.d.ts +1 -0
- package/dist/multiplexer/kitty/index.d.ts +58 -0
- package/dist/multiplexer/shared.d.ts +28 -0
- package/dist/multiplexer/types.d.ts +2 -2
- package/dist/tui.js +1 -1
- package/oh-my-opencode-slim.schema.json +1 -0
- package/package.json +2 -1
- package/src/skills/deepwork/SKILL.md +2 -0
- package/dist/utils/subagent-depth.d.ts +0 -35
package/dist/index.js
CHANGED
|
@@ -18495,7 +18495,6 @@ var DEFAULT_MODELS = {
|
|
|
18495
18495
|
};
|
|
18496
18496
|
var POLL_INTERVAL_BACKGROUND_MS = 2000;
|
|
18497
18497
|
var MAX_POLL_TIME_MS = 5 * 60 * 1000;
|
|
18498
|
-
var DEFAULT_MAX_SUBAGENT_DEPTH = 3;
|
|
18499
18498
|
var PHASE_REMINDER_TEXT = `!IMPORTANT! Scheduler workflow: First choose the lightest workflow that fits the work. If direct execution is justified, complete it and verify proportionately. Otherwise: plan lanes/dependencies → dispatch background specialists → track task IDs → wait for hook-driven completion → reconcile terminal results → verify. Do not poll running jobs, consume running-job output, or advance dependent work. !END!`;
|
|
18500
18499
|
function formatSystemReminder(text) {
|
|
18501
18500
|
return `<system-reminder>
|
|
@@ -18746,6 +18745,7 @@ var MultiplexerTypeSchema = z2.enum([
|
|
|
18746
18745
|
"tmux",
|
|
18747
18746
|
"zellij",
|
|
18748
18747
|
"herdr",
|
|
18748
|
+
"kitty",
|
|
18749
18749
|
"cmux",
|
|
18750
18750
|
"none"
|
|
18751
18751
|
]);
|
|
@@ -19188,7 +19188,7 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
19188
19188
|
}
|
|
19189
19189
|
await Promise.race(racers);
|
|
19190
19190
|
} catch (error) {
|
|
19191
|
-
if (error
|
|
19191
|
+
if (isPromptCancellationError(error)) {
|
|
19192
19192
|
try {
|
|
19193
19193
|
await abortSessionWithTimeout(client, sessionId);
|
|
19194
19194
|
} catch {}
|
|
@@ -19200,6 +19200,11 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
19200
19200
|
signal?.removeEventListener("abort", onAbort);
|
|
19201
19201
|
}
|
|
19202
19202
|
}
|
|
19203
|
+
function isPromptCancellationError(error) {
|
|
19204
|
+
if (error instanceof OperationTimeoutError)
|
|
19205
|
+
return true;
|
|
19206
|
+
return error instanceof Error && error.message === "Prompt cancelled";
|
|
19207
|
+
}
|
|
19203
19208
|
async function extractSessionResult(client, sessionId, options) {
|
|
19204
19209
|
const includeReasoning = options?.includeReasoning ?? true;
|
|
19205
19210
|
const messagesResult = await client.session.messages({
|
|
@@ -21287,17 +21292,15 @@ class CouncilManager {
|
|
|
21287
21292
|
client;
|
|
21288
21293
|
directory;
|
|
21289
21294
|
config;
|
|
21290
|
-
depthTracker;
|
|
21291
21295
|
tmuxEnabled;
|
|
21292
21296
|
deprecatedFields;
|
|
21293
21297
|
legacyMasterModel;
|
|
21294
|
-
constructor(ctx, config,
|
|
21298
|
+
constructor(ctx, config, tmuxEnabled = false) {
|
|
21295
21299
|
this.client = ctx.client;
|
|
21296
21300
|
this.directory = ctx.directory;
|
|
21297
21301
|
this.config = config;
|
|
21298
21302
|
this.deprecatedFields = config?.council?._deprecated;
|
|
21299
21303
|
this.legacyMasterModel = config?.council?._legacyMasterModel;
|
|
21300
|
-
this.depthTracker = depthTracker;
|
|
21301
21304
|
this.tmuxEnabled = tmuxEnabled;
|
|
21302
21305
|
}
|
|
21303
21306
|
getDeprecatedFields() {
|
|
@@ -21307,21 +21310,6 @@ class CouncilManager {
|
|
|
21307
21310
|
return this.legacyMasterModel;
|
|
21308
21311
|
}
|
|
21309
21312
|
async runCouncil(prompt, presetName, parentSessionId) {
|
|
21310
|
-
if (this.depthTracker) {
|
|
21311
|
-
const parentDepth = this.depthTracker.getDepth(parentSessionId);
|
|
21312
|
-
if (parentDepth + 1 > this.depthTracker.maxDepth) {
|
|
21313
|
-
log("[council-manager] spawn blocked: max depth exceeded", {
|
|
21314
|
-
parentSessionId,
|
|
21315
|
-
parentDepth,
|
|
21316
|
-
maxDepth: this.depthTracker.maxDepth
|
|
21317
|
-
});
|
|
21318
|
-
return {
|
|
21319
|
-
success: false,
|
|
21320
|
-
error: "Subagent depth exceeded",
|
|
21321
|
-
councillorResults: []
|
|
21322
|
-
};
|
|
21323
|
-
}
|
|
21324
|
-
}
|
|
21325
21313
|
const councilConfig = this.config?.council;
|
|
21326
21314
|
if (!councilConfig) {
|
|
21327
21315
|
log("[council-manager] Council configuration not found");
|
|
@@ -21413,12 +21401,6 @@ class CouncilManager {
|
|
|
21413
21401
|
throw new Error("Failed to create session");
|
|
21414
21402
|
}
|
|
21415
21403
|
sessionId = session.data.id;
|
|
21416
|
-
if (this.depthTracker) {
|
|
21417
|
-
const registered = this.depthTracker.registerChild(options.parentSessionId, sessionId);
|
|
21418
|
-
if (!registered) {
|
|
21419
|
-
throw new Error("Subagent depth exceeded");
|
|
21420
|
-
}
|
|
21421
|
-
}
|
|
21422
21404
|
if (this.tmuxEnabled) {
|
|
21423
21405
|
await new Promise((r) => setTimeout(r, TMUX_SPAWN_DELAY_MS));
|
|
21424
21406
|
}
|
|
@@ -21457,9 +21439,6 @@ class CouncilManager {
|
|
|
21457
21439
|
} finally {
|
|
21458
21440
|
if (sessionId) {
|
|
21459
21441
|
this.client.session.abort({ path: { id: sessionId } }).catch(() => {});
|
|
21460
|
-
if (this.depthTracker) {
|
|
21461
|
-
this.depthTracker.cleanup(sessionId);
|
|
21462
|
-
}
|
|
21463
21442
|
}
|
|
21464
21443
|
}
|
|
21465
21444
|
}
|
|
@@ -25434,6 +25413,7 @@ function activationPrompt(task2) {
|
|
|
25434
25413
|
"Deepwork requirements:",
|
|
25435
25414
|
"- before planning, delegation, or creating state, inspect existing `.gitignore` and `.ignore`; add only missing entries without duplicates: `.gitignore` must contain `.slim/deepwork/`, and `.ignore` must contain `!.slim/deepwork/` and `!.slim/deepwork/**`; this keeps state git-local yet OpenCode-readable;",
|
|
25436
25415
|
"- create/update a `.slim/deepwork/` progress file;",
|
|
25416
|
+
"- save code/doc deliverables to project paths (e.g. `src/`, `docs/`); reserve `.slim/deepwork/` strictly for progress files;",
|
|
25437
25417
|
"- keep OpenCode todos synced with the current phase;",
|
|
25438
25418
|
"- draft a plan and get `@oracle` review before implementation;",
|
|
25439
25419
|
"- create and review a phased implementation/delegation plan;",
|
|
@@ -26421,23 +26401,21 @@ function createPhaseReminderHook(options = {}) {
|
|
|
26421
26401
|
if (agent !== "orchestrator" || !sessionID || options.shouldInject && !options.shouldInject(sessionID)) {
|
|
26422
26402
|
return;
|
|
26423
26403
|
}
|
|
26424
|
-
const
|
|
26425
|
-
|
|
26426
|
-
|
|
26427
|
-
|
|
26428
|
-
|
|
26429
|
-
|
|
26430
|
-
|
|
26431
|
-
|
|
26432
|
-
|
|
26433
|
-
|
|
26404
|
+
for (const message of messages) {
|
|
26405
|
+
if (!isUserMessageWithParts(message) || message.info.agent !== "orchestrator" || message.info.sessionID !== sessionID) {
|
|
26406
|
+
continue;
|
|
26407
|
+
}
|
|
26408
|
+
const textPart = message.parts.find((part) => part.type === "text" && part.text !== undefined);
|
|
26409
|
+
if (!textPart || isInternalInitiatorPart(textPart) || message.parts.some(hasPhaseReminder)) {
|
|
26410
|
+
continue;
|
|
26411
|
+
}
|
|
26412
|
+
message.parts.push({
|
|
26413
|
+
type: "text",
|
|
26414
|
+
synthetic: true,
|
|
26415
|
+
text: PHASE_REMINDER,
|
|
26416
|
+
metadata: { [PHASE_REMINDER_METADATA_KEY]: true }
|
|
26417
|
+
});
|
|
26434
26418
|
}
|
|
26435
|
-
lastUserMessage.parts.push({
|
|
26436
|
-
type: "text",
|
|
26437
|
-
synthetic: true,
|
|
26438
|
-
text: PHASE_REMINDER,
|
|
26439
|
-
metadata: { [PHASE_REMINDER_METADATA_KEY]: true }
|
|
26440
|
-
});
|
|
26441
26419
|
}
|
|
26442
26420
|
};
|
|
26443
26421
|
}
|
|
@@ -26611,6 +26589,13 @@ function createPendingCallTracker() {
|
|
|
26611
26589
|
pendingCalls.delete(callId);
|
|
26612
26590
|
return pending;
|
|
26613
26591
|
},
|
|
26592
|
+
peekByParent(parentSessionId) {
|
|
26593
|
+
for (const call of pendingCalls.values()) {
|
|
26594
|
+
if (call.parentSessionId === parentSessionId)
|
|
26595
|
+
return call;
|
|
26596
|
+
}
|
|
26597
|
+
return;
|
|
26598
|
+
},
|
|
26614
26599
|
clearSession(sessionId) {
|
|
26615
26600
|
for (const [callId, pending] of pendingCalls.entries()) {
|
|
26616
26601
|
if (pending.parentSessionId === sessionId) {
|
|
@@ -26706,7 +26691,7 @@ var BACKGROUND_COMPLETION_FAILED = /^Background task failed: /;
|
|
|
26706
26691
|
var MAX_PROCESSED_INJECTED_COMPLETIONS = 500;
|
|
26707
26692
|
var RAW_SESSION_ID_PATTERN = /^ses_[A-Za-z0-9_-]+$/;
|
|
26708
26693
|
var IDLE_RECONCILE_DELAY_MS = 2000;
|
|
26709
|
-
var
|
|
26694
|
+
var CONTINUATION_NUDGE = "Continue coordinating the remaining incomplete todos. Do not finalize while work remains.";
|
|
26710
26695
|
function djb2Hash(str) {
|
|
26711
26696
|
let hash = 5381;
|
|
26712
26697
|
for (let i = 0;i < str.length; i++) {
|
|
@@ -26747,8 +26732,137 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
26747
26732
|
const processedInjectedCompletions = new Set;
|
|
26748
26733
|
const processedInjectedCompletionOrder = [];
|
|
26749
26734
|
const terminalJobsInjectedByParent = new Map;
|
|
26735
|
+
const idleReconcileTimers = new Map;
|
|
26736
|
+
const continuationSessionTokens = new Map;
|
|
26737
|
+
const activeContinuationEvaluations = new Map;
|
|
26738
|
+
const continuationConsumed = new Set;
|
|
26739
|
+
const idleReconcileDelayMs = options.idleReconcileDelayMs ?? IDLE_RECONCILE_DELAY_MS;
|
|
26740
|
+
const sessionSdk = _ctx.client.session;
|
|
26741
|
+
function getContinuationSessionToken(sessionID) {
|
|
26742
|
+
const existing = continuationSessionTokens.get(sessionID);
|
|
26743
|
+
if (existing)
|
|
26744
|
+
return existing;
|
|
26745
|
+
const token = Symbol(sessionID);
|
|
26746
|
+
continuationSessionTokens.set(sessionID, token);
|
|
26747
|
+
return token;
|
|
26748
|
+
}
|
|
26749
|
+
function isCurrentContinuation(sessionID, sessionToken, evaluationToken) {
|
|
26750
|
+
return continuationSessionTokens.get(sessionID) === sessionToken && (evaluationToken === undefined || activeContinuationEvaluations.get(sessionID)?.has(evaluationToken) === true);
|
|
26751
|
+
}
|
|
26752
|
+
function invalidateContinuation(sessionID) {
|
|
26753
|
+
const timer = idleReconcileTimers.get(sessionID);
|
|
26754
|
+
if (timer) {
|
|
26755
|
+
clearTimeout(timer);
|
|
26756
|
+
idleReconcileTimers.delete(sessionID);
|
|
26757
|
+
}
|
|
26758
|
+
continuationSessionTokens.delete(sessionID);
|
|
26759
|
+
activeContinuationEvaluations.delete(sessionID);
|
|
26760
|
+
}
|
|
26761
|
+
function clearContinuation(sessionID) {
|
|
26762
|
+
invalidateContinuation(sessionID);
|
|
26763
|
+
continuationConsumed.delete(sessionID);
|
|
26764
|
+
}
|
|
26765
|
+
function isActiveStatus(status, sessionID) {
|
|
26766
|
+
return Object.hasOwn(status, sessionID);
|
|
26767
|
+
}
|
|
26768
|
+
async function evaluateContinuation(parentSessionID, sessionToken) {
|
|
26769
|
+
const evaluationToken = Symbol(parentSessionID);
|
|
26770
|
+
const activeEvaluations = activeContinuationEvaluations.get(parentSessionID) ?? new Set;
|
|
26771
|
+
activeEvaluations.add(evaluationToken);
|
|
26772
|
+
activeContinuationEvaluations.set(parentSessionID, activeEvaluations);
|
|
26773
|
+
if (continuationConsumed.has(parentSessionID) || !isCurrentContinuation(parentSessionID, sessionToken, evaluationToken) || options.isFallbackInProgress?.(parentSessionID) || backgroundJobBoard.hasTerminalUnreconciled(parentSessionID) || !sessionSdk?.todo || !sessionSdk.children || !sessionSdk.status || !sessionSdk.promptAsync) {
|
|
26774
|
+
activeEvaluations.delete(evaluationToken);
|
|
26775
|
+
if (activeEvaluations.size === 0) {
|
|
26776
|
+
activeContinuationEvaluations.delete(parentSessionID);
|
|
26777
|
+
}
|
|
26778
|
+
return;
|
|
26779
|
+
}
|
|
26780
|
+
try {
|
|
26781
|
+
const [todoResponse, childrenResponse, statusResponse] = await Promise.all([
|
|
26782
|
+
sessionSdk.todo({
|
|
26783
|
+
path: { id: parentSessionID },
|
|
26784
|
+
throwOnError: true
|
|
26785
|
+
}),
|
|
26786
|
+
sessionSdk.children({
|
|
26787
|
+
path: { id: parentSessionID },
|
|
26788
|
+
throwOnError: true
|
|
26789
|
+
}),
|
|
26790
|
+
sessionSdk.status({ throwOnError: true })
|
|
26791
|
+
]);
|
|
26792
|
+
if (!Array.isArray(todoResponse.data) || !Array.isArray(childrenResponse.data) || !isRecord2(statusResponse.data)) {
|
|
26793
|
+
return;
|
|
26794
|
+
}
|
|
26795
|
+
const todos = todoResponse.data;
|
|
26796
|
+
const children = childrenResponse.data;
|
|
26797
|
+
const status = statusResponse.data;
|
|
26798
|
+
if (!todos.every((todo) => isRecord2(todo) && typeof todo.status === "string") || !children.every((child) => isRecord2(child) && typeof child.id === "string")) {
|
|
26799
|
+
return;
|
|
26800
|
+
}
|
|
26801
|
+
if (!todos.some((todo) => todo.status !== "completed" && todo.status !== "cancelled")) {
|
|
26802
|
+
return;
|
|
26803
|
+
}
|
|
26804
|
+
const childIDs = children.map((child) => child.id);
|
|
26805
|
+
if (isActiveStatus(status, parentSessionID) || childIDs.some((childID) => isActiveStatus(status, childID))) {
|
|
26806
|
+
return;
|
|
26807
|
+
}
|
|
26808
|
+
const [latestChildrenResponse, latestStatusResponse] = await Promise.all([
|
|
26809
|
+
sessionSdk.children({
|
|
26810
|
+
path: { id: parentSessionID },
|
|
26811
|
+
throwOnError: true
|
|
26812
|
+
}),
|
|
26813
|
+
sessionSdk.status({ throwOnError: true })
|
|
26814
|
+
]);
|
|
26815
|
+
if (!Array.isArray(latestChildrenResponse.data) || !isRecord2(latestStatusResponse.data) || !latestChildrenResponse.data.every((child) => isRecord2(child) && typeof child.id === "string") || continuationConsumed.has(parentSessionID) || !isCurrentContinuation(parentSessionID, sessionToken, evaluationToken) || options.isFallbackInProgress?.(parentSessionID) || backgroundJobBoard.hasTerminalUnreconciled(parentSessionID)) {
|
|
26816
|
+
return;
|
|
26817
|
+
}
|
|
26818
|
+
const latestChildIDs = latestChildrenResponse.data.map((child) => child.id);
|
|
26819
|
+
const latestStatus = latestStatusResponse.data;
|
|
26820
|
+
if (isActiveStatus(latestStatus, parentSessionID) || latestChildIDs.some((childID) => isActiveStatus(latestStatus, childID))) {
|
|
26821
|
+
return;
|
|
26822
|
+
}
|
|
26823
|
+
if (continuationConsumed.has(parentSessionID) || !isCurrentContinuation(parentSessionID, sessionToken, evaluationToken) || options.isFallbackInProgress?.(parentSessionID) || backgroundJobBoard.hasTerminalUnreconciled(parentSessionID)) {
|
|
26824
|
+
return;
|
|
26825
|
+
}
|
|
26826
|
+
continuationConsumed.add(parentSessionID);
|
|
26827
|
+
await sessionSdk.promptAsync({
|
|
26828
|
+
path: { id: parentSessionID },
|
|
26829
|
+
body: { parts: [createInternalAgentTextPart(CONTINUATION_NUDGE)] },
|
|
26830
|
+
throwOnError: true
|
|
26831
|
+
});
|
|
26832
|
+
} catch (error) {
|
|
26833
|
+
log("[task-session-manager] continuation nudge suppressed after SDK error", {
|
|
26834
|
+
parentSessionID,
|
|
26835
|
+
error: error instanceof Error ? error.message : String(error)
|
|
26836
|
+
});
|
|
26837
|
+
} finally {
|
|
26838
|
+
const evaluations = activeContinuationEvaluations.get(parentSessionID);
|
|
26839
|
+
evaluations?.delete(evaluationToken);
|
|
26840
|
+
if (evaluations?.size === 0) {
|
|
26841
|
+
activeContinuationEvaluations.delete(parentSessionID);
|
|
26842
|
+
}
|
|
26843
|
+
}
|
|
26844
|
+
}
|
|
26845
|
+
function scheduleIdleReconciliation(parentSessionID) {
|
|
26846
|
+
if (idleReconcileTimers.has(parentSessionID) || options.isFallbackInProgress?.(parentSessionID)) {
|
|
26847
|
+
return;
|
|
26848
|
+
}
|
|
26849
|
+
const sessionToken = getContinuationSessionToken(parentSessionID);
|
|
26850
|
+
const timer = setTimeout(() => {
|
|
26851
|
+
idleReconcileTimers.delete(parentSessionID);
|
|
26852
|
+
if (!isCurrentContinuation(parentSessionID, sessionToken)) {
|
|
26853
|
+
return;
|
|
26854
|
+
}
|
|
26855
|
+
const hadTerminalUnreconciled = backgroundJobBoard.hasTerminalUnreconciled(parentSessionID);
|
|
26856
|
+
reconcileInjectedTerminalJobs(parentSessionID);
|
|
26857
|
+
if (!hadTerminalUnreconciled) {
|
|
26858
|
+
evaluateContinuation(parentSessionID, sessionToken);
|
|
26859
|
+
}
|
|
26860
|
+
}, idleReconcileDelayMs).unref?.();
|
|
26861
|
+
idleReconcileTimers.set(parentSessionID, timer);
|
|
26862
|
+
}
|
|
26750
26863
|
if (options.coordinator) {
|
|
26751
26864
|
options.coordinator.onSessionDeleted((sessionId) => {
|
|
26865
|
+
clearContinuation(sessionId);
|
|
26752
26866
|
if (!options.isFallbackInProgress?.(sessionId)) {
|
|
26753
26867
|
backgroundJobBoard.drop(sessionId);
|
|
26754
26868
|
backgroundJobBoard.clearParent(sessionId);
|
|
@@ -26908,6 +27022,18 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
26908
27022
|
terminalJobsInjectedByParent.delete(parentSessionID);
|
|
26909
27023
|
}
|
|
26910
27024
|
return {
|
|
27025
|
+
observeChatMessage: (input, output) => {
|
|
27026
|
+
const inputMessage = isRecord2(input) ? input : undefined;
|
|
27027
|
+
const outputRecord = isRecord2(output) ? output : undefined;
|
|
27028
|
+
const outputMessage = isRecord2(outputRecord?.message) ? outputRecord.message : undefined;
|
|
27029
|
+
const sessionID = typeof outputMessage?.sessionID === "string" ? outputMessage.sessionID : typeof inputMessage?.sessionID === "string" ? inputMessage.sessionID : undefined;
|
|
27030
|
+
const parts = Array.isArray(outputRecord?.parts) ? outputRecord.parts : inputMessage?.parts;
|
|
27031
|
+
if (!sessionID || typeof outputMessage?.role === "string" && outputMessage.role !== "user" || !options.shouldManageSession(sessionID) || !Array.isArray(parts) || !parts.some((part) => isRecord2(part) && part.type === "text" && typeof part.text === "string" && part.synthetic !== true && !isInternalInitiatorPart(part))) {
|
|
27032
|
+
return;
|
|
27033
|
+
}
|
|
27034
|
+
invalidateContinuation(sessionID);
|
|
27035
|
+
continuationConsumed.delete(sessionID);
|
|
27036
|
+
},
|
|
26911
27037
|
"tool.execute.before": async (input, output) => {
|
|
26912
27038
|
const toolName = input.tool.toLowerCase();
|
|
26913
27039
|
if (toolName !== "task")
|
|
@@ -27133,6 +27259,34 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
27133
27259
|
});
|
|
27134
27260
|
if (info?.id && info.parentID && options.shouldManageSession(info.parentID)) {
|
|
27135
27261
|
taskContextTracker.pendingManagedTaskIds.add(info.id);
|
|
27262
|
+
const pending = pendingCallTracker.peekByParent(info.parentID);
|
|
27263
|
+
if (pending && !pending.resumedTaskId && !backgroundJobBoard.get(info.id)) {
|
|
27264
|
+
const record = backgroundJobBoard.registerLaunch({
|
|
27265
|
+
taskID: info.id,
|
|
27266
|
+
parentSessionID: pending.parentSessionId,
|
|
27267
|
+
agent: pending.agentType,
|
|
27268
|
+
description: pending.label,
|
|
27269
|
+
objective: pending.label
|
|
27270
|
+
});
|
|
27271
|
+
log("[task-session-manager] early board registration from session.created", {
|
|
27272
|
+
taskID: record.taskID,
|
|
27273
|
+
alias: record.alias,
|
|
27274
|
+
parentSessionID: record.parentSessionID,
|
|
27275
|
+
agent: record.agent
|
|
27276
|
+
});
|
|
27277
|
+
}
|
|
27278
|
+
}
|
|
27279
|
+
return;
|
|
27280
|
+
}
|
|
27281
|
+
if (input.event.type === "server.instance.disposed") {
|
|
27282
|
+
const continuationSessionIDs = new Set([
|
|
27283
|
+
...idleReconcileTimers.keys(),
|
|
27284
|
+
...continuationSessionTokens.keys(),
|
|
27285
|
+
...activeContinuationEvaluations.keys(),
|
|
27286
|
+
...continuationConsumed
|
|
27287
|
+
]);
|
|
27288
|
+
for (const sessionID of continuationSessionIDs) {
|
|
27289
|
+
clearContinuation(sessionID);
|
|
27136
27290
|
}
|
|
27137
27291
|
return;
|
|
27138
27292
|
}
|
|
@@ -27146,11 +27300,7 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
27146
27300
|
runningJobForSession: job?.state === "running" || false
|
|
27147
27301
|
});
|
|
27148
27302
|
if (sessionId2 && options.shouldManageSession(sessionId2)) {
|
|
27149
|
-
|
|
27150
|
-
idleReconcileTimers.delete(sessionId2);
|
|
27151
|
-
reconcileInjectedTerminalJobs(sessionId2);
|
|
27152
|
-
}, IDLE_RECONCILE_DELAY_MS).unref?.();
|
|
27153
|
-
idleReconcileTimers.set(sessionId2, timer2);
|
|
27303
|
+
scheduleIdleReconciliation(sessionId2);
|
|
27154
27304
|
}
|
|
27155
27305
|
if (job && sessionId2 && job.state === "running" && !options.isFallbackInProgress?.(sessionId2)) {
|
|
27156
27306
|
log("[task-session-manager] reconciled running job from idle", {
|
|
@@ -27172,13 +27322,8 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
27172
27322
|
}
|
|
27173
27323
|
if (input.event.type === "session.error") {
|
|
27174
27324
|
const sessionId2 = input.event.properties?.info?.id || input.event.properties?.sessionID;
|
|
27175
|
-
if (sessionId2)
|
|
27176
|
-
|
|
27177
|
-
if (timer2) {
|
|
27178
|
-
clearTimeout(timer2);
|
|
27179
|
-
idleReconcileTimers.delete(sessionId2);
|
|
27180
|
-
}
|
|
27181
|
-
}
|
|
27325
|
+
if (sessionId2)
|
|
27326
|
+
invalidateContinuation(sessionId2);
|
|
27182
27327
|
if (sessionId2 && options.shouldManageSession(sessionId2)) {
|
|
27183
27328
|
const props = input.event.properties;
|
|
27184
27329
|
if (!props?.error || !isFailoverError(props.error)) {
|
|
@@ -27187,14 +27332,13 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
27187
27332
|
}
|
|
27188
27333
|
return;
|
|
27189
27334
|
}
|
|
27190
|
-
if (input.event.type === "session.status"
|
|
27335
|
+
if (input.event.type === "session.status") {
|
|
27191
27336
|
const sessionId2 = input.event.properties?.info?.id || input.event.properties?.sessionID;
|
|
27192
|
-
|
|
27193
|
-
|
|
27194
|
-
|
|
27195
|
-
|
|
27196
|
-
|
|
27197
|
-
}
|
|
27337
|
+
const statusType = input.event.properties?.status?.type;
|
|
27338
|
+
if (sessionId2)
|
|
27339
|
+
invalidateContinuation(sessionId2);
|
|
27340
|
+
if (statusType !== "busy") {
|
|
27341
|
+
return;
|
|
27198
27342
|
}
|
|
27199
27343
|
const before = sessionId2 ? backgroundJobBoard.get(sessionId2) : undefined;
|
|
27200
27344
|
const updated = sessionId2 ? backgroundJobBoard.markRunningFromLiveSession(sessionId2) : undefined;
|
|
@@ -27225,11 +27369,7 @@ function createTaskSessionManagerHook(_ctx, options) {
|
|
|
27225
27369
|
const sessionId = input.event.properties?.info?.id || input.event.properties?.sessionID;
|
|
27226
27370
|
if (!sessionId)
|
|
27227
27371
|
return;
|
|
27228
|
-
|
|
27229
|
-
if (timer) {
|
|
27230
|
-
clearTimeout(timer);
|
|
27231
|
-
idleReconcileTimers.delete(sessionId);
|
|
27232
|
-
}
|
|
27372
|
+
clearContinuation(sessionId);
|
|
27233
27373
|
log("[task-session-manager] session.deleted observed", {
|
|
27234
27374
|
sessionID: sessionId
|
|
27235
27375
|
});
|
|
@@ -27275,6 +27415,15 @@ function formatCancelledTaskStatusOutput(taskID, summary = "cancelled") {
|
|
|
27275
27415
|
].join(`
|
|
27276
27416
|
`);
|
|
27277
27417
|
}
|
|
27418
|
+
// src/index-event.ts
|
|
27419
|
+
async function handleTaskSessionEvent(input, invalidateTaskSessions, handleMultiplexerEvent, cleanupInstance) {
|
|
27420
|
+
await invalidateTaskSessions(input);
|
|
27421
|
+
await handleMultiplexerEvent();
|
|
27422
|
+
if (input.event.type === "server.instance.disposed") {
|
|
27423
|
+
await cleanupInstance();
|
|
27424
|
+
}
|
|
27425
|
+
}
|
|
27426
|
+
|
|
27278
27427
|
// src/interview/dashboard.ts
|
|
27279
27428
|
import crypto2 from "node:crypto";
|
|
27280
27429
|
import * as fsSync2 from "node:fs";
|
|
@@ -32317,6 +32466,42 @@ function buildOpencodeAttachCommand(sessionId, serverUrl, directory, executable
|
|
|
32317
32466
|
quoteShellArg(attachDir)
|
|
32318
32467
|
].join(" ");
|
|
32319
32468
|
}
|
|
32469
|
+
function resolveOpencodeExecutable() {
|
|
32470
|
+
return resolveHostOpencodeBinary() ?? "opencode";
|
|
32471
|
+
}
|
|
32472
|
+
function buildShellLaunchArgs(command) {
|
|
32473
|
+
const shell = process.env.SHELL || "/bin/sh";
|
|
32474
|
+
const name = (shell.split(/[/\\]/).at(-1) ?? "sh").replace(/\.(exe|EXE)$/, "");
|
|
32475
|
+
if (name === "nu" || name === "fish") {
|
|
32476
|
+
return [shell, "-c", command];
|
|
32477
|
+
}
|
|
32478
|
+
if (name === "zsh") {
|
|
32479
|
+
return [
|
|
32480
|
+
shell,
|
|
32481
|
+
"-l",
|
|
32482
|
+
"-c",
|
|
32483
|
+
`[[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1
|
|
32484
|
+
${command}`
|
|
32485
|
+
];
|
|
32486
|
+
}
|
|
32487
|
+
if (name === "bash") {
|
|
32488
|
+
return [
|
|
32489
|
+
shell,
|
|
32490
|
+
"-l",
|
|
32491
|
+
"-c",
|
|
32492
|
+
`shopt -s expand_aliases
|
|
32493
|
+
[[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
|
|
32494
|
+
${command}`
|
|
32495
|
+
];
|
|
32496
|
+
}
|
|
32497
|
+
if (name === "cmd") {
|
|
32498
|
+
return [shell, "/c", command];
|
|
32499
|
+
}
|
|
32500
|
+
if (name === "pwsh" || name === "powershell") {
|
|
32501
|
+
return [shell, "-NoProfile", "-Command", command];
|
|
32502
|
+
}
|
|
32503
|
+
return [shell, "-c", command];
|
|
32504
|
+
}
|
|
32320
32505
|
function resolveHostOpencodeBinary(options = {}) {
|
|
32321
32506
|
const pathExists = options.pathExists ?? existsSync9;
|
|
32322
32507
|
for (const candidate of [
|
|
@@ -32393,13 +32578,15 @@ async function gracefulClosePane(binary, paneId, options) {
|
|
|
32393
32578
|
try {
|
|
32394
32579
|
const ctrlCProc = crossSpawn([binary, ...options.ctrlC], {
|
|
32395
32580
|
stdout: "ignore",
|
|
32396
|
-
stderr: "ignore"
|
|
32581
|
+
stderr: "ignore",
|
|
32582
|
+
env: options.env
|
|
32397
32583
|
});
|
|
32398
32584
|
await ctrlCProc.exited;
|
|
32399
32585
|
await new Promise((r) => setTimeout(r, GRACEFUL_SHUTDOWN_DELAY_MS));
|
|
32400
32586
|
const proc = crossSpawn([binary, ...options.close], {
|
|
32401
32587
|
stdout: "ignore",
|
|
32402
|
-
stderr: "ignore"
|
|
32588
|
+
stderr: "ignore",
|
|
32589
|
+
env: options.env
|
|
32403
32590
|
});
|
|
32404
32591
|
const exitCode = await proc.exited;
|
|
32405
32592
|
if (exitCode === 0)
|
|
@@ -33130,6 +33317,189 @@ function getPaneDirection(layout) {
|
|
|
33130
33317
|
}
|
|
33131
33318
|
}
|
|
33132
33319
|
|
|
33320
|
+
// src/multiplexer/kitty/index.ts
|
|
33321
|
+
init_compat();
|
|
33322
|
+
class KittyMultiplexer {
|
|
33323
|
+
type = "kitty";
|
|
33324
|
+
binaryPath = null;
|
|
33325
|
+
hasChecked = false;
|
|
33326
|
+
storedLayout;
|
|
33327
|
+
appliedLayout = null;
|
|
33328
|
+
constructor(layout = "main-vertical", mainPaneSize = 60) {
|
|
33329
|
+
this.storedLayout = layout;
|
|
33330
|
+
}
|
|
33331
|
+
async isAvailable() {
|
|
33332
|
+
if (this.hasChecked) {
|
|
33333
|
+
return this.binaryPath !== null;
|
|
33334
|
+
}
|
|
33335
|
+
this.binaryPath = await findBinary("kitten") ?? await findBinary("kitty");
|
|
33336
|
+
this.hasChecked = true;
|
|
33337
|
+
return this.binaryPath !== null;
|
|
33338
|
+
}
|
|
33339
|
+
isInsideSession() {
|
|
33340
|
+
return !!process.env.KITTY_PID || !!process.env.KITTY_WINDOW_ID;
|
|
33341
|
+
}
|
|
33342
|
+
hasListenOn() {
|
|
33343
|
+
return !!process.env.KITTY_LISTEN_ON;
|
|
33344
|
+
}
|
|
33345
|
+
async spawnPane(sessionId, description, serverUrl, directory) {
|
|
33346
|
+
const kitten = await this.getBinary();
|
|
33347
|
+
if (!kitten) {
|
|
33348
|
+
log("[kitty] spawnPane: kitten/kitty binary not found");
|
|
33349
|
+
return { success: false };
|
|
33350
|
+
}
|
|
33351
|
+
if (!this.isInsideSession()) {
|
|
33352
|
+
log("[kitty] spawnPane: OpenCode is not running inside a kitty session; " + "set multiplexer.type to a different backend or run OpenCode inside kitty");
|
|
33353
|
+
return { success: false };
|
|
33354
|
+
}
|
|
33355
|
+
if (!this.hasListenOn()) {
|
|
33356
|
+
log("[kitty] spawnPane: KITTY_LISTEN_ON is not set. Add `listen_on " + "unix:/tmp/kitty-rc-$(USER)` to kitty.conf and restart kitty so the " + "plugin can drive kitty via the socket.");
|
|
33357
|
+
return { success: false };
|
|
33358
|
+
}
|
|
33359
|
+
const { kittyLayout, location } = getKittyLayoutConfig(this.storedLayout);
|
|
33360
|
+
await this.ensureLayout(kittyLayout);
|
|
33361
|
+
try {
|
|
33362
|
+
const opencodeCmd = buildOpencodeAttachCommand(sessionId, serverUrl, directory, resolveOpencodeExecutable());
|
|
33363
|
+
const attachDir = normalizePathForShell(directory);
|
|
33364
|
+
const shellArgs = buildShellLaunchArgs(opencodeCmd);
|
|
33365
|
+
const args = [
|
|
33366
|
+
"@",
|
|
33367
|
+
"launch",
|
|
33368
|
+
"--type=window",
|
|
33369
|
+
`--location=${location}`,
|
|
33370
|
+
`--title=${description.slice(0, 60)}`,
|
|
33371
|
+
`--cwd=${attachDir}`,
|
|
33372
|
+
"--keep-focus",
|
|
33373
|
+
"--",
|
|
33374
|
+
...shellArgs
|
|
33375
|
+
];
|
|
33376
|
+
log("[kitty] spawnPane: executing", { kitten, args });
|
|
33377
|
+
const proc = crossSpawn([kitten, ...args], {
|
|
33378
|
+
stdout: "pipe",
|
|
33379
|
+
stderr: "pipe",
|
|
33380
|
+
env: this.kittyEnv()
|
|
33381
|
+
});
|
|
33382
|
+
const exitCode = await proc.exited;
|
|
33383
|
+
const stdout = await proc.stdout();
|
|
33384
|
+
const stderr = await proc.stderr();
|
|
33385
|
+
const lines = stdout.trim().split(`
|
|
33386
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
33387
|
+
const windowId = lines.length > 0 ? lines[lines.length - 1] : "";
|
|
33388
|
+
log("[kitty] spawnPane: result", {
|
|
33389
|
+
exitCode,
|
|
33390
|
+
windowId,
|
|
33391
|
+
stderr: stderr.trim()
|
|
33392
|
+
});
|
|
33393
|
+
if (exitCode === 0 && windowId) {
|
|
33394
|
+
log("[kitty] spawnPane: SUCCESS", { windowId });
|
|
33395
|
+
return { success: true, paneId: windowId };
|
|
33396
|
+
}
|
|
33397
|
+
return { success: false };
|
|
33398
|
+
} catch (err) {
|
|
33399
|
+
log("[kitty] spawnPane: exception", { error: String(err) });
|
|
33400
|
+
return { success: false };
|
|
33401
|
+
}
|
|
33402
|
+
}
|
|
33403
|
+
async closePane(paneId) {
|
|
33404
|
+
if (!this.isInsideSession()) {
|
|
33405
|
+
log("[kitty] closePane: OpenCode is not running inside a kitty session; " + "cannot target a kitty instance");
|
|
33406
|
+
return false;
|
|
33407
|
+
}
|
|
33408
|
+
if (!this.hasListenOn()) {
|
|
33409
|
+
log("[kitty] closePane: KITTY_LISTEN_ON is not set; cannot target kitty. " + "Add `listen_on` to kitty.conf and restart kitty.");
|
|
33410
|
+
return false;
|
|
33411
|
+
}
|
|
33412
|
+
const kitten = await this.getBinary();
|
|
33413
|
+
return await gracefulClosePane(kitten, paneId, {
|
|
33414
|
+
ctrlC: ["@", "send-key", "--match", `id:${paneId}`, "ctrl+c"],
|
|
33415
|
+
close: ["@", "close-window", "--match", `id:${paneId}`],
|
|
33416
|
+
acceptExitCode1: true,
|
|
33417
|
+
emptyPaneReturnsTrue: true,
|
|
33418
|
+
env: this.kittyEnv()
|
|
33419
|
+
});
|
|
33420
|
+
}
|
|
33421
|
+
async applyLayout(layout, mainPaneSize) {
|
|
33422
|
+
if (!this.isInsideSession()) {
|
|
33423
|
+
log("[kitty] applyLayout: OpenCode is not running inside a kitty session; " + "cannot target a kitty instance");
|
|
33424
|
+
return;
|
|
33425
|
+
}
|
|
33426
|
+
if (!this.hasListenOn()) {
|
|
33427
|
+
log("[kitty] applyLayout: KITTY_LISTEN_ON is not set; cannot target kitty. " + "Add `listen_on` to kitty.conf and restart kitty.");
|
|
33428
|
+
return;
|
|
33429
|
+
}
|
|
33430
|
+
this.storedLayout = layout;
|
|
33431
|
+
const { kittyLayout } = getKittyLayoutConfig(layout);
|
|
33432
|
+
await this.ensureLayout(kittyLayout);
|
|
33433
|
+
}
|
|
33434
|
+
async runKitty(kitten, args) {
|
|
33435
|
+
const proc = crossSpawn([kitten, ...args], {
|
|
33436
|
+
stdout: "pipe",
|
|
33437
|
+
stderr: "pipe",
|
|
33438
|
+
env: this.kittyEnv()
|
|
33439
|
+
});
|
|
33440
|
+
const [exitCode, , stderr] = await Promise.all([
|
|
33441
|
+
proc.exited,
|
|
33442
|
+
proc.stdout(),
|
|
33443
|
+
proc.stderr()
|
|
33444
|
+
]);
|
|
33445
|
+
if (exitCode !== 0) {
|
|
33446
|
+
log("[kitty] command failed", {
|
|
33447
|
+
command: args[1],
|
|
33448
|
+
args: [kitten, ...args],
|
|
33449
|
+
exitCode,
|
|
33450
|
+
stderr: stderr.trim()
|
|
33451
|
+
});
|
|
33452
|
+
}
|
|
33453
|
+
return exitCode;
|
|
33454
|
+
}
|
|
33455
|
+
async ensureLayout(kittyLayout) {
|
|
33456
|
+
if (this.appliedLayout === kittyLayout)
|
|
33457
|
+
return;
|
|
33458
|
+
const kitten = await this.getBinary();
|
|
33459
|
+
if (!kitten)
|
|
33460
|
+
return;
|
|
33461
|
+
try {
|
|
33462
|
+
const exitCode = await this.runKitty(kitten, [
|
|
33463
|
+
"@",
|
|
33464
|
+
"goto-layout",
|
|
33465
|
+
kittyLayout
|
|
33466
|
+
]);
|
|
33467
|
+
if (exitCode === 0)
|
|
33468
|
+
this.appliedLayout = kittyLayout;
|
|
33469
|
+
} catch (err) {
|
|
33470
|
+
log("[kitty] ensureLayout: exception", { error: String(err) });
|
|
33471
|
+
}
|
|
33472
|
+
}
|
|
33473
|
+
async getBinary() {
|
|
33474
|
+
await this.isAvailable();
|
|
33475
|
+
return this.binaryPath;
|
|
33476
|
+
}
|
|
33477
|
+
kittyEnv() {
|
|
33478
|
+
const listenOn = process.env.KITTY_LISTEN_ON;
|
|
33479
|
+
if (!listenOn)
|
|
33480
|
+
return;
|
|
33481
|
+
return { ...process.env, KITTY_LISTEN_ON: listenOn };
|
|
33482
|
+
}
|
|
33483
|
+
}
|
|
33484
|
+
function getKittyLayoutConfig(layout) {
|
|
33485
|
+
switch (layout) {
|
|
33486
|
+
case "main-vertical":
|
|
33487
|
+
return { kittyLayout: "tall", location: "after" };
|
|
33488
|
+
case "main-horizontal":
|
|
33489
|
+
return { kittyLayout: "fat", location: "after" };
|
|
33490
|
+
case "tiled":
|
|
33491
|
+
return { kittyLayout: "grid", location: "after" };
|
|
33492
|
+
case "even-horizontal":
|
|
33493
|
+
return { kittyLayout: "horizontal", location: "after" };
|
|
33494
|
+
case "even-vertical":
|
|
33495
|
+
return { kittyLayout: "vertical", location: "after" };
|
|
33496
|
+
default: {
|
|
33497
|
+
const _exhaustive = layout;
|
|
33498
|
+
return _exhaustive;
|
|
33499
|
+
}
|
|
33500
|
+
}
|
|
33501
|
+
}
|
|
33502
|
+
|
|
33133
33503
|
// src/multiplexer/tmux/index.ts
|
|
33134
33504
|
init_compat();
|
|
33135
33505
|
var TMUX_LAYOUT_DEBOUNCE_MS = 150;
|
|
@@ -33677,6 +34047,10 @@ function getMultiplexer(config) {
|
|
|
33677
34047
|
multiplexer = new CmuxMultiplexer;
|
|
33678
34048
|
actualType = "cmux";
|
|
33679
34049
|
break;
|
|
34050
|
+
case "kitty":
|
|
34051
|
+
multiplexer = new KittyMultiplexer(config.layout, config.main_pane_size);
|
|
34052
|
+
actualType = "kitty";
|
|
34053
|
+
break;
|
|
33680
34054
|
case "auto": {
|
|
33681
34055
|
if (process.env.CMUX_SOCKET_PATH && process.env.CMUX_WORKSPACE_ID && process.env.CMUX_SURFACE_ID) {
|
|
33682
34056
|
multiplexer = new CmuxMultiplexer;
|
|
@@ -33690,6 +34064,9 @@ function getMultiplexer(config) {
|
|
|
33690
34064
|
} else if (process.env.HERDR_ENV || process.env.HERDR_PANE_ID) {
|
|
33691
34065
|
multiplexer = new HerdrMultiplexer(config.layout, config.main_pane_size);
|
|
33692
34066
|
actualType = "herdr";
|
|
34067
|
+
} else if (process.env.KITTY_PID || process.env.KITTY_WINDOW_ID) {
|
|
34068
|
+
multiplexer = new KittyMultiplexer(config.layout, config.main_pane_size);
|
|
34069
|
+
actualType = "kitty";
|
|
33693
34070
|
} else {
|
|
33694
34071
|
log("[multiplexer] auto: not inside any session, disabling");
|
|
33695
34072
|
return null;
|
|
@@ -38834,47 +39211,6 @@ function isPluginDisabledByEnv(env = process.env) {
|
|
|
38834
39211
|
return isTruthyEnvValue(env[PLUGIN_DISABLE_ENV]);
|
|
38835
39212
|
}
|
|
38836
39213
|
|
|
38837
|
-
// src/utils/subagent-depth.ts
|
|
38838
|
-
class SubagentDepthTracker {
|
|
38839
|
-
depthBySession = new Map;
|
|
38840
|
-
_maxDepth;
|
|
38841
|
-
constructor(maxDepth = DEFAULT_MAX_SUBAGENT_DEPTH) {
|
|
38842
|
-
this._maxDepth = maxDepth;
|
|
38843
|
-
}
|
|
38844
|
-
get maxDepth() {
|
|
38845
|
-
return this._maxDepth;
|
|
38846
|
-
}
|
|
38847
|
-
getDepth(sessionId) {
|
|
38848
|
-
return this.depthBySession.get(sessionId) ?? 0;
|
|
38849
|
-
}
|
|
38850
|
-
registerChild(parentSessionId, childSessionId) {
|
|
38851
|
-
const parentDepth = this.getDepth(parentSessionId);
|
|
38852
|
-
const childDepth = parentDepth + 1;
|
|
38853
|
-
if (childDepth > this.maxDepth) {
|
|
38854
|
-
log("[subagent-depth] spawn blocked: max depth exceeded", {
|
|
38855
|
-
parentSessionId,
|
|
38856
|
-
parentDepth,
|
|
38857
|
-
childDepth,
|
|
38858
|
-
maxDepth: this.maxDepth
|
|
38859
|
-
});
|
|
38860
|
-
return false;
|
|
38861
|
-
}
|
|
38862
|
-
this.depthBySession.set(childSessionId, childDepth);
|
|
38863
|
-
log("[subagent-depth] child registered", {
|
|
38864
|
-
parentSessionId,
|
|
38865
|
-
childSessionId,
|
|
38866
|
-
childDepth
|
|
38867
|
-
});
|
|
38868
|
-
return true;
|
|
38869
|
-
}
|
|
38870
|
-
cleanup(sessionId) {
|
|
38871
|
-
this.depthBySession.delete(sessionId);
|
|
38872
|
-
}
|
|
38873
|
-
cleanupAll() {
|
|
38874
|
-
this.depthBySession.clear();
|
|
38875
|
-
}
|
|
38876
|
-
}
|
|
38877
|
-
|
|
38878
39214
|
// src/utils/system-collapse.ts
|
|
38879
39215
|
function collapseSystemInPlace(system2) {
|
|
38880
39216
|
if (system2.length === 0) {
|
|
@@ -38938,7 +39274,6 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
38938
39274
|
let runtimeChains;
|
|
38939
39275
|
let multiplexerConfig;
|
|
38940
39276
|
let multiplexerEnabled;
|
|
38941
|
-
let depthTracker;
|
|
38942
39277
|
let multiplexerSessionManager;
|
|
38943
39278
|
let autoUpdateChecker;
|
|
38944
39279
|
let sessionAgentMap;
|
|
@@ -39010,8 +39345,7 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
39010
39345
|
if (multiplexerEnabled) {
|
|
39011
39346
|
startAvailabilityCheck(multiplexerConfig);
|
|
39012
39347
|
}
|
|
39013
|
-
|
|
39014
|
-
councilTools = config.council ? createCouncilTool(ctx, new CouncilManager(ctx, config, depthTracker, multiplexerEnabled)) : {};
|
|
39348
|
+
councilTools = config.council ? createCouncilTool(ctx, new CouncilManager(ctx, config, multiplexerEnabled)) : {};
|
|
39015
39349
|
mcps = createBuiltinMcps(config.disabled_mcps, config.websearch);
|
|
39016
39350
|
acpRunTools = Object.keys(config.acpAgents ?? {}).length > 0 ? { acp_run: createAcpRunTool(config.acpAgents) } : {};
|
|
39017
39351
|
webfetch = createWebfetchTool(ctx);
|
|
@@ -39383,27 +39717,22 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
39383
39717
|
}
|
|
39384
39718
|
}
|
|
39385
39719
|
if (event.type === "session.created") {
|
|
39386
|
-
const childSessionId = event.properties?.info?.id;
|
|
39387
|
-
const parentSessionId = event.properties?.info?.parentID;
|
|
39388
|
-
if (depthTracker && childSessionId && parentSessionId) {
|
|
39389
|
-
depthTracker.registerChild(parentSessionId, childSessionId);
|
|
39390
|
-
}
|
|
39391
39720
|
const createdSessionId = event.properties?.info?.id;
|
|
39392
39721
|
const createdSessionDir = event.properties?.info?.directory;
|
|
39393
39722
|
if (createdSessionId && createdSessionDir) {
|
|
39394
39723
|
sessionDirectories.set(createdSessionId, createdSessionDir);
|
|
39395
39724
|
}
|
|
39396
39725
|
}
|
|
39397
|
-
await
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
|
|
39726
|
+
await handleTaskSessionEvent(input, taskSessionManagerHook.event, async () => {
|
|
39727
|
+
await multiplexerSessionManager.onSessionCreated(event);
|
|
39728
|
+
await multiplexerSessionManager.onSessionStatus(event);
|
|
39729
|
+
await multiplexerSessionManager.onSessionDeleted(event);
|
|
39730
|
+
}, async () => {
|
|
39401
39731
|
await multiplexerSessionManager.cleanupOnInstanceDisposed();
|
|
39402
|
-
}
|
|
39732
|
+
});
|
|
39403
39733
|
await foregroundFallback.handleEvent(input.event);
|
|
39404
39734
|
await autoUpdateChecker.event(input);
|
|
39405
39735
|
await interviewManager.handleEvent(input);
|
|
39406
|
-
await taskSessionManagerHook.event(input);
|
|
39407
39736
|
if (event.type === "permission.asked" || event.type === "question.asked") {
|
|
39408
39737
|
companionManager.onWaitingInput();
|
|
39409
39738
|
}
|
|
@@ -39426,9 +39755,6 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
39426
39755
|
sessionLifecycle.dispatchSessionDeleted(sessionID);
|
|
39427
39756
|
}
|
|
39428
39757
|
companionManager.onSessionDeleted(sessionID);
|
|
39429
|
-
if (depthTracker && sessionID) {
|
|
39430
|
-
depthTracker.cleanup(sessionID);
|
|
39431
|
-
}
|
|
39432
39758
|
if (sessionID) {
|
|
39433
39759
|
sessionAgentMap.delete(sessionID);
|
|
39434
39760
|
sessionDirectories.delete(sessionID);
|
|
@@ -39462,6 +39788,7 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
39462
39788
|
status: "busy"
|
|
39463
39789
|
});
|
|
39464
39790
|
}
|
|
39791
|
+
taskSessionManagerHook.observeChatMessage(input, output);
|
|
39465
39792
|
},
|
|
39466
39793
|
"experimental.chat.system.transform": async (input, output) => {
|
|
39467
39794
|
const agentName = input.sessionID ? sessionAgentMap.get(input.sessionID) : undefined;
|