opencode-matrixx 2.6.5 → 2.6.6
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/agents/oracle/behavioral-summary.d.ts +1 -1
- package/dist/agents/oracle/high-accuracy-mode.d.ts +1 -1
- package/dist/agents/oracle/interview-mode.d.ts +1 -1
- package/dist/agents/oracle/plan-generation.d.ts +1 -1
- package/dist/agents/oracle/plan-template.d.ts +1 -1
- package/dist/agents/oracle/system-prompt.d.ts +1 -1
- package/dist/cli.js +14 -6
- package/dist/config/schema/hooks.d.ts +1 -0
- package/dist/config/schema/matrixx-config.d.ts +1 -0
- package/dist/create-hooks.d.ts +1 -0
- package/dist/features/background-agent/handle-index.d.ts +63 -0
- package/dist/features/background-agent/handle-index.test.d.ts +1 -0
- package/dist/features/background-agent/index.d.ts +1 -0
- package/dist/features/background-agent/manager-handles.test.d.ts +1 -0
- package/dist/features/background-agent/manager.d.ts +12 -0
- package/dist/hooks/background-task-blocker/hook.d.ts +10 -0
- package/dist/hooks/background-task-blocker/index.d.ts +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.js +278 -54
- package/dist/matrixx.schema.json +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
- package/dist/shared/context-mode-prompt.d.ts +12 -0
- package/dist/shared/context-mode-prompt.test.d.ts +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/tools/background-task/constants.d.ts +0 -1
- package/dist/tools/background-task/index.d.ts +1 -1
- package/dist/tools/background-task/tools.d.ts +0 -1
- package/dist/tools/background-task/types.d.ts +0 -5
- package/dist/tools/delegate-task/sync-task.test.d.ts +1 -0
- package/dist/tools/delegate-task/timing.test.d.ts +1 -0
- package/package.json +1 -1
- package/dist/tools/background-task/create-background-task.d.ts +0 -3
package/dist/index.js
CHANGED
|
@@ -44411,11 +44411,14 @@ var ModelFallbackEntrySchema = exports_external.object({
|
|
|
44411
44411
|
variant: exports_external.string().optional()
|
|
44412
44412
|
});
|
|
44413
44413
|
var complexityDowngradeValueSchema = exports_external.string().refine((s) => {
|
|
44414
|
-
if (s.includes("/"))
|
|
44415
|
-
|
|
44416
|
-
|
|
44417
|
-
|
|
44418
|
-
|
|
44414
|
+
if (!s.includes("/"))
|
|
44415
|
+
return false;
|
|
44416
|
+
if (s.startsWith("/") || s.endsWith("/"))
|
|
44417
|
+
return false;
|
|
44418
|
+
if (s.includes("//"))
|
|
44419
|
+
return false;
|
|
44420
|
+
const parts = s.split("/");
|
|
44421
|
+
return parts.length >= 2 && parts.every((p) => p.length > 0);
|
|
44419
44422
|
}, { message: "Must be <provider>/<model>" });
|
|
44420
44423
|
var ComplexityDowngradesSchema = exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), complexityDowngradeValueSchema));
|
|
44421
44424
|
var AgentModelRequirementsSchema = exports_external.object({
|
|
@@ -48413,8 +48416,11 @@ function getPlanProgress(planPath) {
|
|
|
48413
48416
|
const content = readFileSync10(planPath, "utf-8");
|
|
48414
48417
|
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
48415
48418
|
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
48416
|
-
const
|
|
48417
|
-
const
|
|
48419
|
+
const numberedUnchecked = content.match(/^[-*]\s*\[\s*\]\s*\d+\./gm) || [];
|
|
48420
|
+
const numberedChecked = content.match(/^[-*]\s*\[[xX]\]\s*\d+\./gm) || [];
|
|
48421
|
+
const useNumbered = numberedUnchecked.length + numberedChecked.length > 0;
|
|
48422
|
+
const total = useNumbered ? numberedUnchecked.length + numberedChecked.length : uncheckedMatches.length + checkedMatches.length;
|
|
48423
|
+
const completed = useNumbered ? numberedChecked.length : checkedMatches.length;
|
|
48418
48424
|
return {
|
|
48419
48425
|
total,
|
|
48420
48426
|
completed,
|
|
@@ -52632,6 +52638,16 @@ function createBackgroundNotificationHook(manager) {
|
|
|
52632
52638
|
event: eventHandler
|
|
52633
52639
|
};
|
|
52634
52640
|
}
|
|
52641
|
+
// src/hooks/background-task-blocker/hook.ts
|
|
52642
|
+
function createBackgroundTaskBlockerHook() {
|
|
52643
|
+
return {
|
|
52644
|
+
"tool.execute.before": async (input, _output) => {
|
|
52645
|
+
if (input.tool === "background_task") {
|
|
52646
|
+
throw new Error('Tool "background_task" is disabled. Use the "task" tool with category/subagent_type and run_in_background=true for agent delegation.');
|
|
52647
|
+
}
|
|
52648
|
+
}
|
|
52649
|
+
};
|
|
52650
|
+
}
|
|
52635
52651
|
// src/hooks/bash-file-read-guard.ts
|
|
52636
52652
|
var WARNING_MESSAGE = "Prefer the Read tool over `cat`/`head`/`tail` for reading file contents. " + "The Read tool provides line numbers and hash anchors for precise editing.";
|
|
52637
52653
|
var FILE_READ_PATTERNS = [
|
|
@@ -88724,8 +88740,6 @@ function createBackgroundOutput(manager, client2) {
|
|
|
88724
88740
|
}
|
|
88725
88741
|
});
|
|
88726
88742
|
}
|
|
88727
|
-
// src/tools/background-task/create-background-task.ts
|
|
88728
|
-
init_logger();
|
|
88729
88743
|
// src/tools/assembly/constants.ts
|
|
88730
88744
|
var DEFAULT_VOTERS = 3;
|
|
88731
88745
|
var DEFAULT_ROUNDS = 2;
|
|
@@ -91354,7 +91368,7 @@ async function pollSyncSession(ctx, client2, input) {
|
|
|
91354
91368
|
let idleStallCount = 0;
|
|
91355
91369
|
let lastMsgCount = 0;
|
|
91356
91370
|
let stableIdlePolls = 0;
|
|
91357
|
-
log("[task] Starting poll loop", { sessionID: input.sessionID, agentToUse: input.agentToUse });
|
|
91371
|
+
log("[task] Starting poll loop", { sessionID: input.sessionID, agentToUse: input.agentToUse, maxPollTimeMs });
|
|
91358
91372
|
while (Date.now() - pollStart < maxPollTimeMs) {
|
|
91359
91373
|
if (ctx.abort?.aborted) {
|
|
91360
91374
|
log("[task] Aborted by user", { sessionID: input.sessionID });
|
|
@@ -91732,6 +91746,7 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
|
|
|
91732
91746
|
const toastManager = getTaskToastManager();
|
|
91733
91747
|
let taskId;
|
|
91734
91748
|
let syncSessionID;
|
|
91749
|
+
let pollTimedOut = false;
|
|
91735
91750
|
try {
|
|
91736
91751
|
const createSessionResult = await deps.createSyncSession(client2, {
|
|
91737
91752
|
parentSessionID: parentContext.sessionID,
|
|
@@ -91814,6 +91829,7 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
|
|
|
91814
91829
|
}
|
|
91815
91830
|
});
|
|
91816
91831
|
if (pollError) {
|
|
91832
|
+
pollTimedOut = pollError.startsWith("Poll timeout reached");
|
|
91817
91833
|
return pollError;
|
|
91818
91834
|
}
|
|
91819
91835
|
const result = await deps.fetchSyncResult(client2, sessionID, undefined, {
|
|
@@ -91851,9 +91867,11 @@ session_id: ${sessionID}
|
|
|
91851
91867
|
} finally {
|
|
91852
91868
|
if (syncSessionID) {
|
|
91853
91869
|
unregisterSubagentSession(syncSessionID);
|
|
91854
|
-
|
|
91855
|
-
|
|
91856
|
-
|
|
91870
|
+
if (!pollTimedOut) {
|
|
91871
|
+
client2.session.abort({ path: { id: syncSessionID } }).catch((err) => {
|
|
91872
|
+
log("[delegate-task] Sync session abort failed:", err);
|
|
91873
|
+
});
|
|
91874
|
+
}
|
|
91857
91875
|
}
|
|
91858
91876
|
}
|
|
91859
91877
|
}
|
|
@@ -93096,6 +93114,7 @@ function createToolGuardHooks(args) {
|
|
|
93096
93114
|
const { ctx, pluginConfig, isHookEnabled, safeHookEnabled } = args;
|
|
93097
93115
|
const evolutionEnabled = pluginConfig.evolution?.enabled === true;
|
|
93098
93116
|
const safeHook = (hookName, factory) => safeCreateHook(hookName, factory, { enabled: safeHookEnabled });
|
|
93117
|
+
const backgroundTaskBlocker = isHookEnabled("background-task-blocker") ? safeHook("background-task-blocker", () => createBackgroundTaskBlockerHook()) : null;
|
|
93099
93118
|
const commentChecker = isHookEnabled("comment-checker") ? safeHook("comment-checker", () => createCommentCheckerHooks(pluginConfig.comment_checker)) : null;
|
|
93100
93119
|
const toolOutputTruncator = isHookEnabled("tool-output-truncator") ? safeHook("tool-output-truncator", () => createToolOutputTruncatorHook(ctx, { experimental: pluginConfig.experimental })) : null;
|
|
93101
93120
|
let directoryAgentsInjector = null;
|
|
@@ -93129,6 +93148,7 @@ function createToolGuardHooks(args) {
|
|
|
93129
93148
|
const taskEditGuard = isHookEnabled("task-edit-guard") ? safeHook("task-edit-guard", () => createTaskEditGuardHook(ctx)) : null;
|
|
93130
93149
|
const evolutionWatcher = evolutionEnabled && isHookEnabled("evolution-watcher") ? safeHook("evolution-watcher", () => createEvolutionWatcherHook(ctx, pluginConfig.evolution)) : null;
|
|
93131
93150
|
return {
|
|
93151
|
+
backgroundTaskBlocker,
|
|
93132
93152
|
commentChecker,
|
|
93133
93153
|
toolOutputTruncator,
|
|
93134
93154
|
directoryAgentsInjector,
|
|
@@ -93488,6 +93508,10 @@ class ConcurrencyManager {
|
|
|
93488
93508
|
return this.queues.get(model)?.length ?? 0;
|
|
93489
93509
|
}
|
|
93490
93510
|
}
|
|
93511
|
+
// src/features/background-agent/handle-index.ts
|
|
93512
|
+
import { existsSync as existsSync73, mkdirSync as mkdirSync19, readdirSync as readdirSync25, readFileSync as readFileSync43, renameSync as renameSync5, unlinkSync as unlinkSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
93513
|
+
import { dirname as dirname19, join as join77 } from "path";
|
|
93514
|
+
|
|
93491
93515
|
// src/features/background-agent/constants.ts
|
|
93492
93516
|
var TASK_TTL_MS = 30 * 60 * 1000;
|
|
93493
93517
|
var MIN_STABILITY_TIME_MS2 = 10 * 1000;
|
|
@@ -93502,6 +93526,126 @@ var POLLING_INTERVAL_MS = 3000;
|
|
|
93502
93526
|
var PRUNE_THROTTLE_MS = 30000;
|
|
93503
93527
|
var TASK_CLEANUP_DELAY_MS = 10 * 60 * 1000;
|
|
93504
93528
|
|
|
93529
|
+
// src/features/background-agent/handle-index.ts
|
|
93530
|
+
var BG_HANDLE_DIR_NAME = "bg-handles";
|
|
93531
|
+
var BG_HANDLE_FILE_PREFIX = "bg_";
|
|
93532
|
+
var BgHandleSchema = exports_external.object({
|
|
93533
|
+
taskId: exports_external.string(),
|
|
93534
|
+
parentSessionID: exports_external.string(),
|
|
93535
|
+
parentMessageID: exports_external.string(),
|
|
93536
|
+
description: exports_external.string(),
|
|
93537
|
+
agent: exports_external.string(),
|
|
93538
|
+
status: exports_external.enum(["pending", "running", "completed", "error", "cancelled", "interrupt"]),
|
|
93539
|
+
model: exports_external.object({
|
|
93540
|
+
providerID: exports_external.string(),
|
|
93541
|
+
modelID: exports_external.string(),
|
|
93542
|
+
variant: exports_external.string().optional(),
|
|
93543
|
+
temperature: exports_external.number().optional()
|
|
93544
|
+
}).optional(),
|
|
93545
|
+
category: exports_external.string().optional(),
|
|
93546
|
+
concurrencyGroup: exports_external.string().optional(),
|
|
93547
|
+
queuedAt: exports_external.number().optional(),
|
|
93548
|
+
startedAt: exports_external.number().optional(),
|
|
93549
|
+
completedAt: exports_external.number().optional()
|
|
93550
|
+
}).strict();
|
|
93551
|
+
function getBgHandleDir(directory) {
|
|
93552
|
+
return join77(directory, ".matrixx", BG_HANDLE_DIR_NAME);
|
|
93553
|
+
}
|
|
93554
|
+
function getHandlePath(directory, taskId) {
|
|
93555
|
+
return join77(getBgHandleDir(directory), `${taskId}.json`);
|
|
93556
|
+
}
|
|
93557
|
+
function ensureDir3(dirPath) {
|
|
93558
|
+
if (!existsSync73(dirPath)) {
|
|
93559
|
+
mkdirSync19(dirPath, { recursive: true });
|
|
93560
|
+
}
|
|
93561
|
+
}
|
|
93562
|
+
function toHandle(task) {
|
|
93563
|
+
return {
|
|
93564
|
+
taskId: task.id,
|
|
93565
|
+
parentSessionID: task.parentSessionID,
|
|
93566
|
+
parentMessageID: task.parentMessageID,
|
|
93567
|
+
description: task.description,
|
|
93568
|
+
agent: task.agent,
|
|
93569
|
+
status: task.status,
|
|
93570
|
+
model: task.model,
|
|
93571
|
+
category: task.category,
|
|
93572
|
+
concurrencyGroup: task.concurrencyGroup,
|
|
93573
|
+
queuedAt: task.queuedAt?.getTime(),
|
|
93574
|
+
startedAt: task.startedAt?.getTime(),
|
|
93575
|
+
completedAt: task.completedAt?.getTime()
|
|
93576
|
+
};
|
|
93577
|
+
}
|
|
93578
|
+
function writeHandle(directory, task) {
|
|
93579
|
+
const filePath = getHandlePath(directory, task.id);
|
|
93580
|
+
ensureDir3(dirname19(filePath));
|
|
93581
|
+
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
93582
|
+
try {
|
|
93583
|
+
writeFileSync26(tempPath, JSON.stringify(toHandle(task), null, 2), "utf-8");
|
|
93584
|
+
renameSync5(tempPath, filePath);
|
|
93585
|
+
} catch (error95) {
|
|
93586
|
+
try {
|
|
93587
|
+
if (existsSync73(tempPath)) {
|
|
93588
|
+
unlinkSync12(tempPath);
|
|
93589
|
+
}
|
|
93590
|
+
} catch {}
|
|
93591
|
+
throw error95;
|
|
93592
|
+
}
|
|
93593
|
+
}
|
|
93594
|
+
function readHandleFile(filePath) {
|
|
93595
|
+
try {
|
|
93596
|
+
if (!existsSync73(filePath)) {
|
|
93597
|
+
return null;
|
|
93598
|
+
}
|
|
93599
|
+
const parsed = JSON.parse(readFileSync43(filePath, "utf-8"));
|
|
93600
|
+
const result = BgHandleSchema.safeParse(parsed);
|
|
93601
|
+
return result.success ? result.data : null;
|
|
93602
|
+
} catch {
|
|
93603
|
+
return null;
|
|
93604
|
+
}
|
|
93605
|
+
}
|
|
93606
|
+
function readHandles(directory) {
|
|
93607
|
+
const dir = getBgHandleDir(directory);
|
|
93608
|
+
if (!existsSync73(dir)) {
|
|
93609
|
+
return [];
|
|
93610
|
+
}
|
|
93611
|
+
const handles = [];
|
|
93612
|
+
for (const name of readdirSync25(dir)) {
|
|
93613
|
+
if (!name.startsWith(BG_HANDLE_FILE_PREFIX) || !name.endsWith(".json")) {
|
|
93614
|
+
continue;
|
|
93615
|
+
}
|
|
93616
|
+
const handle = readHandleFile(join77(dir, name));
|
|
93617
|
+
if (handle) {
|
|
93618
|
+
handles.push(handle);
|
|
93619
|
+
}
|
|
93620
|
+
}
|
|
93621
|
+
return handles;
|
|
93622
|
+
}
|
|
93623
|
+
function sweepStaleHandles(directory, ttlMs = TASK_TTL_MS, now = Date.now()) {
|
|
93624
|
+
const dir = getBgHandleDir(directory);
|
|
93625
|
+
if (!existsSync73(dir)) {
|
|
93626
|
+
return 0;
|
|
93627
|
+
}
|
|
93628
|
+
let removed = 0;
|
|
93629
|
+
for (const name of readdirSync25(dir)) {
|
|
93630
|
+
if (!name.startsWith(BG_HANDLE_FILE_PREFIX) || !name.endsWith(".json")) {
|
|
93631
|
+
continue;
|
|
93632
|
+
}
|
|
93633
|
+
const filePath = join77(dir, name);
|
|
93634
|
+
const handle = readHandleFile(filePath);
|
|
93635
|
+
const timestamp = handle?.completedAt ?? handle?.startedAt ?? handle?.queuedAt;
|
|
93636
|
+
if (handle && timestamp !== undefined && now - timestamp <= ttlMs) {
|
|
93637
|
+
continue;
|
|
93638
|
+
}
|
|
93639
|
+
try {
|
|
93640
|
+
unlinkSync12(filePath);
|
|
93641
|
+
removed++;
|
|
93642
|
+
} catch {}
|
|
93643
|
+
}
|
|
93644
|
+
if (removed > 0) {
|
|
93645
|
+
log(`[bg-handles] Swept ${removed} stale handle file(s) from ${dir}`);
|
|
93646
|
+
}
|
|
93647
|
+
return removed;
|
|
93648
|
+
}
|
|
93505
93649
|
// src/features/background-agent/error-helpers.ts
|
|
93506
93650
|
function getErrorText(error95) {
|
|
93507
93651
|
if (!error95)
|
|
@@ -93604,19 +93748,19 @@ function detectRepetitiveToolUse(window2) {
|
|
|
93604
93748
|
}
|
|
93605
93749
|
|
|
93606
93750
|
// src/features/background-agent/message-dir.ts
|
|
93607
|
-
import { existsSync as
|
|
93608
|
-
import { join as
|
|
93751
|
+
import { existsSync as existsSync74, readdirSync as readdirSync26, readFileSync as readFileSync44 } from "fs";
|
|
93752
|
+
import { join as join78 } from "path";
|
|
93609
93753
|
var MESSAGE_DIR_CACHE_CAP = 1000;
|
|
93610
93754
|
var messageDirCache = new Map;
|
|
93611
93755
|
function computeMessageDir(sessionID) {
|
|
93612
|
-
if (!
|
|
93756
|
+
if (!existsSync74(MESSAGE_STORAGE))
|
|
93613
93757
|
return null;
|
|
93614
|
-
const directPath =
|
|
93615
|
-
if (
|
|
93758
|
+
const directPath = join78(MESSAGE_STORAGE, sessionID);
|
|
93759
|
+
if (existsSync74(directPath))
|
|
93616
93760
|
return directPath;
|
|
93617
|
-
for (const dir of
|
|
93618
|
-
const sessionPath =
|
|
93619
|
-
if (
|
|
93761
|
+
for (const dir of readdirSync26(MESSAGE_STORAGE)) {
|
|
93762
|
+
const sessionPath = join78(MESSAGE_STORAGE, dir, sessionID);
|
|
93763
|
+
if (existsSync74(sessionPath))
|
|
93620
93764
|
return sessionPath;
|
|
93621
93765
|
}
|
|
93622
93766
|
return null;
|
|
@@ -93650,11 +93794,11 @@ function hasPartialAgentOrModel(message) {
|
|
|
93650
93794
|
}
|
|
93651
93795
|
function findNearestMessageExcludingCompaction(messageDir) {
|
|
93652
93796
|
try {
|
|
93653
|
-
const files =
|
|
93797
|
+
const files = readdirSync26(messageDir).filter((name) => name.endsWith(".json")).sort().reverse();
|
|
93654
93798
|
const parsedByFile = new Map;
|
|
93655
93799
|
for (const file3 of files) {
|
|
93656
93800
|
try {
|
|
93657
|
-
const content =
|
|
93801
|
+
const content = readFileSync44(join78(messageDir, file3), "utf-8");
|
|
93658
93802
|
const parsed = JSON.parse(content);
|
|
93659
93803
|
parsedByFile.set(file3, parsed);
|
|
93660
93804
|
if (hasFullAgentAndModel(parsed)) {
|
|
@@ -93802,6 +93946,25 @@ class TaskHistory {
|
|
|
93802
93946
|
}
|
|
93803
93947
|
|
|
93804
93948
|
// src/features/background-agent/manager.ts
|
|
93949
|
+
function restoreTaskFromHandle(handle) {
|
|
93950
|
+
const interrupted = handle.status === "running" || handle.status === "pending";
|
|
93951
|
+
return {
|
|
93952
|
+
id: handle.taskId,
|
|
93953
|
+
parentSessionID: handle.parentSessionID,
|
|
93954
|
+
parentMessageID: handle.parentMessageID,
|
|
93955
|
+
description: handle.description,
|
|
93956
|
+
prompt: "",
|
|
93957
|
+
agent: handle.agent,
|
|
93958
|
+
status: interrupted ? "interrupt" : handle.status,
|
|
93959
|
+
queuedAt: handle.queuedAt !== undefined ? new Date(handle.queuedAt) : undefined,
|
|
93960
|
+
startedAt: handle.startedAt !== undefined ? new Date(handle.startedAt) : undefined,
|
|
93961
|
+
completedAt: handle.completedAt !== undefined ? new Date(handle.completedAt) : undefined,
|
|
93962
|
+
model: handle.model,
|
|
93963
|
+
category: handle.category,
|
|
93964
|
+
concurrencyGroup: handle.concurrencyGroup
|
|
93965
|
+
};
|
|
93966
|
+
}
|
|
93967
|
+
|
|
93805
93968
|
class BackgroundManager {
|
|
93806
93969
|
static cleanupManagers = new Set;
|
|
93807
93970
|
static cleanupRegistered = false;
|
|
@@ -93842,6 +94005,28 @@ class BackgroundManager {
|
|
|
93842
94005
|
this.enableParentSessionNotifications = options?.enableParentSessionNotifications ?? true;
|
|
93843
94006
|
this.registerProcessCleanup();
|
|
93844
94007
|
}
|
|
94008
|
+
persistHandle(task) {
|
|
94009
|
+
try {
|
|
94010
|
+
writeHandle(this.directory, task);
|
|
94011
|
+
} catch (error95) {
|
|
94012
|
+
log("[background-agent] Failed to persist background handle:", { taskId: task.id, error: error95 });
|
|
94013
|
+
}
|
|
94014
|
+
}
|
|
94015
|
+
async restoreHandles() {
|
|
94016
|
+
const swept = sweepStaleHandles(this.directory);
|
|
94017
|
+
const handles = readHandles(this.directory);
|
|
94018
|
+
let restored = 0;
|
|
94019
|
+
for (const handle of handles) {
|
|
94020
|
+
if (this.tasks.has(handle.taskId)) {
|
|
94021
|
+
continue;
|
|
94022
|
+
}
|
|
94023
|
+
this.tasks.set(handle.taskId, restoreTaskFromHandle(handle));
|
|
94024
|
+
restored++;
|
|
94025
|
+
}
|
|
94026
|
+
if (restored > 0 || swept > 0) {
|
|
94027
|
+
log("[background-agent] Restored background handles:", { restored, swept });
|
|
94028
|
+
}
|
|
94029
|
+
}
|
|
93845
94030
|
async launch(input) {
|
|
93846
94031
|
log("[background-agent] launch() called with:", {
|
|
93847
94032
|
agent: input.agent,
|
|
@@ -93993,6 +94178,7 @@ class BackgroundManager {
|
|
|
93993
94178
|
};
|
|
93994
94179
|
task.concurrencyKey = concurrencyKey;
|
|
93995
94180
|
task.concurrencyGroup = concurrencyKey;
|
|
94181
|
+
this.persistHandle(task);
|
|
93996
94182
|
this.taskHistory.record(input.parentSessionID, { id: task.id, sessionID, agent: input.agent, description: input.description, status: "running", category: input.category, startedAt: task.startedAt });
|
|
93997
94183
|
this.startPolling();
|
|
93998
94184
|
log("[background-agent] Launching task:", { taskId: task.id, sessionID, agent: input.agent });
|
|
@@ -94044,6 +94230,7 @@ class BackgroundManager {
|
|
|
94044
94230
|
existingTask.error = errorMessage;
|
|
94045
94231
|
}
|
|
94046
94232
|
existingTask.completedAt = new Date;
|
|
94233
|
+
this.persistHandle(existingTask);
|
|
94047
94234
|
if (existingTask.concurrencyKey) {
|
|
94048
94235
|
this.concurrencyManager.release(existingTask.concurrencyKey);
|
|
94049
94236
|
existingTask.concurrencyKey = undefined;
|
|
@@ -94146,6 +94333,7 @@ class BackgroundManager {
|
|
|
94146
94333
|
concurrencyGroup
|
|
94147
94334
|
};
|
|
94148
94335
|
this.tasks.set(task.id, task);
|
|
94336
|
+
this.persistHandle(task);
|
|
94149
94337
|
registerSubagentSession(input.sessionID, input.parentSessionID);
|
|
94150
94338
|
this.startPolling();
|
|
94151
94339
|
this.taskHistory.record(input.parentSessionID, { id: task.id, sessionID: input.sessionID, agent: input.agent || "task", description: input.description, status: "running", startedAt: task.startedAt });
|
|
@@ -94192,6 +94380,7 @@ class BackgroundManager {
|
|
|
94192
94380
|
existingTask.parentTools = input.parentTools;
|
|
94193
94381
|
}
|
|
94194
94382
|
existingTask.startedAt = new Date;
|
|
94383
|
+
this.persistHandle(existingTask);
|
|
94195
94384
|
existingTask.progress = {
|
|
94196
94385
|
toolCalls: existingTask.progress?.toolCalls ?? 0,
|
|
94197
94386
|
lastUpdate: new Date
|
|
@@ -94247,6 +94436,7 @@ class BackgroundManager {
|
|
|
94247
94436
|
const errorMessage = error95 instanceof Error ? error95.message : String(error95);
|
|
94248
94437
|
existingTask.error = errorMessage;
|
|
94249
94438
|
existingTask.completedAt = new Date;
|
|
94439
|
+
this.persistHandle(existingTask);
|
|
94250
94440
|
if (existingTask.concurrencyKey) {
|
|
94251
94441
|
this.concurrencyManager.release(existingTask.concurrencyKey);
|
|
94252
94442
|
existingTask.concurrencyKey = undefined;
|
|
@@ -94411,6 +94601,7 @@ class BackgroundManager {
|
|
|
94411
94601
|
task.status = "error";
|
|
94412
94602
|
task.error = errorMessage ?? "Session error";
|
|
94413
94603
|
task.completedAt = new Date;
|
|
94604
|
+
this.persistHandle(task);
|
|
94414
94605
|
this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt });
|
|
94415
94606
|
if (task.concurrencyKey) {
|
|
94416
94607
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
@@ -94579,6 +94770,7 @@ class BackgroundManager {
|
|
|
94579
94770
|
}
|
|
94580
94771
|
task.status = "cancelled";
|
|
94581
94772
|
task.completedAt = new Date;
|
|
94773
|
+
this.persistHandle(task);
|
|
94582
94774
|
if (reason) {
|
|
94583
94775
|
task.error = reason;
|
|
94584
94776
|
}
|
|
@@ -94701,6 +94893,7 @@ class BackgroundManager {
|
|
|
94701
94893
|
}
|
|
94702
94894
|
task.status = "completed";
|
|
94703
94895
|
task.completedAt = new Date;
|
|
94896
|
+
this.persistHandle(task);
|
|
94704
94897
|
this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "completed", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt });
|
|
94705
94898
|
if (task.concurrencyKey) {
|
|
94706
94899
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
@@ -94833,6 +95026,7 @@ class BackgroundManager {
|
|
|
94833
95026
|
task.status = "error";
|
|
94834
95027
|
task.error = errorMessage;
|
|
94835
95028
|
task.completedAt = new Date;
|
|
95029
|
+
this.persistHandle(task);
|
|
94836
95030
|
if (task.concurrencyKey) {
|
|
94837
95031
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
94838
95032
|
task.concurrencyKey = undefined;
|
|
@@ -94917,6 +95111,7 @@ class BackgroundManager {
|
|
|
94917
95111
|
task.status = "cancelled";
|
|
94918
95112
|
task.error = `Stale timeout (no activity for ${staleMinutes2}min since start)`;
|
|
94919
95113
|
task.completedAt = new Date;
|
|
95114
|
+
this.persistHandle(task);
|
|
94920
95115
|
if (task.concurrencyKey) {
|
|
94921
95116
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
94922
95117
|
task.concurrencyKey = undefined;
|
|
@@ -94945,6 +95140,7 @@ class BackgroundManager {
|
|
|
94945
95140
|
task.status = "cancelled";
|
|
94946
95141
|
task.error = `Stale timeout (no activity for ${staleMinutes}min)`;
|
|
94947
95142
|
task.completedAt = new Date;
|
|
95143
|
+
this.persistHandle(task);
|
|
94948
95144
|
if (task.concurrencyKey) {
|
|
94949
95145
|
this.concurrencyManager.release(task.concurrencyKey);
|
|
94950
95146
|
task.concurrencyKey = undefined;
|
|
@@ -95836,9 +96032,9 @@ class TmuxSessionManager {
|
|
|
95836
96032
|
var SESSION_TIMEOUT_MS3 = 10 * 60 * 1000;
|
|
95837
96033
|
var MIN_STABILITY_TIME_MS4 = 10 * 1000;
|
|
95838
96034
|
// src/agents/dynamic-agent-prompt-builder.ts
|
|
95839
|
-
import { existsSync as
|
|
96035
|
+
import { existsSync as existsSync75, readFileSync as readFileSync45 } from "fs";
|
|
95840
96036
|
import { homedir as homedir11 } from "os";
|
|
95841
|
-
import { join as
|
|
96037
|
+
import { join as join79 } from "path";
|
|
95842
96038
|
init_logger();
|
|
95843
96039
|
function categorizeTools(toolNames) {
|
|
95844
96040
|
return toolNames.map((name) => {
|
|
@@ -96200,24 +96396,24 @@ function exploreCtxPart(hasGrepGlob) {
|
|
|
96200
96396
|
function resolveContextModeDisciplinePath() {
|
|
96201
96397
|
try {
|
|
96202
96398
|
const resolved = __require.resolve("context-mode/configs/opencode/AGENTS.md");
|
|
96203
|
-
if (
|
|
96399
|
+
if (existsSync75(resolved))
|
|
96204
96400
|
return resolved;
|
|
96205
96401
|
} catch {}
|
|
96206
96402
|
try {
|
|
96207
96403
|
const cacheDir = getOpenCodeCacheDir();
|
|
96208
|
-
const p =
|
|
96209
|
-
if (
|
|
96404
|
+
const p = join79(cacheDir, "packages/context-mode@latest/node_modules/context-mode/configs/opencode/AGENTS.md");
|
|
96405
|
+
if (existsSync75(p))
|
|
96210
96406
|
return p;
|
|
96211
96407
|
} catch {}
|
|
96212
96408
|
try {
|
|
96213
|
-
const base = process.env.XDG_CACHE_HOME ??
|
|
96214
|
-
const p =
|
|
96215
|
-
if (
|
|
96409
|
+
const base = process.env.XDG_CACHE_HOME ?? join79(homedir11(), ".cache");
|
|
96410
|
+
const p = join79(base, "opencode/packages/context-mode@latest/node_modules/context-mode/configs/opencode/AGENTS.md");
|
|
96411
|
+
if (existsSync75(p))
|
|
96216
96412
|
return p;
|
|
96217
96413
|
} catch {}
|
|
96218
96414
|
try {
|
|
96219
|
-
const p2 =
|
|
96220
|
-
if (
|
|
96415
|
+
const p2 = join79(homedir11(), ".cache/opencode/packages/context-mode@latest/node_modules/context-mode/configs/opencode/AGENTS.md");
|
|
96416
|
+
if (existsSync75(p2))
|
|
96221
96417
|
return p2;
|
|
96222
96418
|
} catch {}
|
|
96223
96419
|
return null;
|
|
@@ -96235,11 +96431,11 @@ function loadContextModeDiscipline(hasGrepGlob = true) {
|
|
|
96235
96431
|
const p = resolveContextModeDisciplinePath();
|
|
96236
96432
|
if (!p)
|
|
96237
96433
|
throw new Error("discipline file not found");
|
|
96238
|
-
const raw =
|
|
96434
|
+
const raw = readFileSync45(p, "utf8");
|
|
96239
96435
|
let version4 = "1.0.169";
|
|
96240
96436
|
try {
|
|
96241
96437
|
const pkgResolved = __require.resolve("context-mode/package.json");
|
|
96242
|
-
const pkgRaw =
|
|
96438
|
+
const pkgRaw = readFileSync45(pkgResolved, "utf8");
|
|
96243
96439
|
const pkg = JSON.parse(pkgRaw);
|
|
96244
96440
|
if (pkg.version)
|
|
96245
96441
|
version4 = pkg.version;
|
|
@@ -96286,11 +96482,11 @@ function loadCompactContextDiscipline(hasGrepGlob = true) {
|
|
|
96286
96482
|
const p = resolveContextModeDisciplinePath();
|
|
96287
96483
|
if (!p)
|
|
96288
96484
|
throw new Error("discipline file not found");
|
|
96289
|
-
const raw =
|
|
96485
|
+
const raw = readFileSync45(p, "utf8");
|
|
96290
96486
|
let version4 = "1.0.169";
|
|
96291
96487
|
try {
|
|
96292
96488
|
const pkgResolved = __require.resolve("context-mode/package.json");
|
|
96293
|
-
const pkgRaw =
|
|
96489
|
+
const pkgRaw = readFileSync45(pkgResolved, "utf8");
|
|
96294
96490
|
const pkg = JSON.parse(pkgRaw);
|
|
96295
96491
|
if (pkg.version)
|
|
96296
96492
|
version4 = pkg.version;
|
|
@@ -97359,7 +97555,7 @@ function createBddContractAgent(model) {
|
|
|
97359
97555
|
createBddContractAgent.mode = MODE2;
|
|
97360
97556
|
|
|
97361
97557
|
// src/agents/builtin-agents/resolve-file-uri.ts
|
|
97362
|
-
import { existsSync as
|
|
97558
|
+
import { existsSync as existsSync76, readFileSync as readFileSync46 } from "fs";
|
|
97363
97559
|
import { homedir as homedir12 } from "os";
|
|
97364
97560
|
import { isAbsolute as isAbsolute6, resolve as resolve10 } from "path";
|
|
97365
97561
|
function resolvePromptAppend(promptAppend, configDir) {
|
|
@@ -97374,11 +97570,11 @@ function resolvePromptAppend(promptAppend, configDir) {
|
|
|
97374
97570
|
} catch {
|
|
97375
97571
|
return `[WARNING: Malformed file URI (invalid percent-encoding): ${promptAppend}]`;
|
|
97376
97572
|
}
|
|
97377
|
-
if (!
|
|
97573
|
+
if (!existsSync76(filePath)) {
|
|
97378
97574
|
return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
|
|
97379
97575
|
}
|
|
97380
97576
|
try {
|
|
97381
|
-
return
|
|
97577
|
+
return readFileSync46(filePath, "utf8");
|
|
97382
97578
|
} catch {
|
|
97383
97579
|
return `[WARNING: Could not read file: ${promptAppend}]`;
|
|
97384
97580
|
}
|
|
@@ -99394,8 +99590,8 @@ Step 2: Get commit SHA for permalinks
|
|
|
99394
99590
|
cd \${TMPDIR:-/tmp}/repo-name && git rev-parse HEAD
|
|
99395
99591
|
|
|
99396
99592
|
Step 3: Find the implementation
|
|
99397
|
-
-
|
|
99398
|
-
- read
|
|
99593
|
+
- ctx_search / ast_grep_search for function/class \u2014 NOT grep (blocked under enforce:true)
|
|
99594
|
+
- ctx_execute_file for analysis (or read for targeted sections)
|
|
99399
99595
|
- git blame for context if needed
|
|
99400
99596
|
|
|
99401
99597
|
Step 4: Construct permalink
|
|
@@ -100544,8 +100740,8 @@ Your response has **FAILED** if:
|
|
|
100544
100740
|
Use the right tool for the job:
|
|
100545
100741
|
- **Semantic search** (definitions, references): LSP tools
|
|
100546
100742
|
- **Structural patterns** (function shapes, class structures): ast_grep_search
|
|
100547
|
-
- **Text patterns** (strings, comments, logs):
|
|
100548
|
-
- **File patterns** (find by name/extension):
|
|
100743
|
+
- **Text patterns** (strings, comments, logs): ctx_search (indexed KB) -> ctx_batch_execute / ctx_execute for multi-file analysis. ast_grep_search for structural patterns. grep/glob only as fallback when ctx_* unavailable.
|
|
100744
|
+
- **File patterns** (find by name/extension): ctx_search (indexed KB) -> LSP / ast_grep_search. glob only as fallback when ctx_* unavailable.
|
|
100549
100745
|
- **History/evolution** (when added, who changed): git commands
|
|
100550
100746
|
|
|
100551
100747
|
Flood with parallel calls. Cross-validate findings across multiple tools.`
|
|
@@ -100743,6 +100939,13 @@ This will:
|
|
|
100743
100939
|
5. **Seraph Before Plan** - Always catch gaps before committing to plan
|
|
100744
100940
|
6. **Choice-Based Handoff** - Present "Start Work" vs "High Accuracy Review" choice after plan
|
|
100745
100941
|
7. **Draft as External Memory** - Continuously record to draft; delete after plan complete
|
|
100942
|
+
8. **Background-First Delegation** - Default to \`run_in_background=true\` for every delegation; never nest a blocking subagent call inside an already-blocking session
|
|
100943
|
+
|
|
100944
|
+
### Delegation Policy (MANDATORY)
|
|
100945
|
+
|
|
100946
|
+
- **Default to background mode**: every Oracle delegation passes \`run_in_background=true\`.
|
|
100947
|
+
- **Never nest a blocking subagent call** (\`run_in_background=false\`) inside an already-blocking session. Oracle may itself run under a fixed poll budget (default 600s); a nested blocking call consumes that budget and stalls at the timeout.
|
|
100948
|
+
- **Use sequential top-level calls instead**: fire the delegation in background, return to your work, then collect the result with \`background_output(task_id=...)\`.
|
|
100746
100949
|
|
|
100747
100950
|
---
|
|
100748
100951
|
|
|
@@ -100776,12 +100979,14 @@ var ORACLE_HIGH_ACCURACY_MODE = `# PHASE 3: PLAN GENERATION
|
|
|
100776
100979
|
\`\`\`typescript
|
|
100777
100980
|
// After generating initial plan
|
|
100778
100981
|
while (true) {
|
|
100779
|
-
|
|
100982
|
+
// Fire Smith in background (never a blocking nested call), then collect its verdict.
|
|
100983
|
+
const smithTask = task(
|
|
100780
100984
|
subagent_type="smith",
|
|
100781
100985
|
load_skills=[],
|
|
100782
100986
|
prompt=".matrixx/plans/{name}.md",
|
|
100783
|
-
run_in_background=
|
|
100987
|
+
run_in_background=true
|
|
100784
100988
|
)
|
|
100989
|
+
const result = background_output(task_id=smithTask.task_id)
|
|
100785
100990
|
|
|
100786
100991
|
if (result.verdict === "OKAY") {
|
|
100787
100992
|
break // Plan approved - exit loop
|
|
@@ -101386,7 +101591,7 @@ task(subagent_type="operator", load_skills=[], prompt="I'm designing architectur
|
|
|
101386
101591
|
|
|
101387
101592
|
**Oracle Consultation** (recommend when stakes are high):
|
|
101388
101593
|
\`\`\`typescript
|
|
101389
|
-
task(subagent_type="oracle", load_skills=[], prompt="Architecture consultation needed: [context]...", run_in_background=
|
|
101594
|
+
task(subagent_type="oracle", load_skills=[], prompt="Architecture consultation needed: [context]...", run_in_background=true)
|
|
101390
101595
|
\`\`\`
|
|
101391
101596
|
|
|
101392
101597
|
**Interview Focus:**
|
|
@@ -101548,12 +101753,14 @@ todoWrite([
|
|
|
101548
101753
|
|
|
101549
101754
|
> **Edge \u2014 Trivial/Simple bypass:** If complexity is 1-2 (Trivial/Simple) and the request is ambiguous but single-scope (one domain, no architectural keywords), **bypass Seraph** and ask directly per Morpheus Phase 0 (ask ONE clarifying question).
|
|
101550
101755
|
|
|
101551
|
-
If gate **passes**, summon Seraph:
|
|
101756
|
+
If gate **passes**, summon Seraph in **background mode** (never blocking \u2014 see policy below):
|
|
101552
101757
|
|
|
101553
101758
|
\`\`\`typescript
|
|
101554
|
-
|
|
101759
|
+
// Fire Seraph in background \u2014 NEVER run_in_background=false from this session.
|
|
101760
|
+
const seraphTask = task(
|
|
101555
101761
|
subagent_type="seraph",
|
|
101556
101762
|
load_skills=[],
|
|
101763
|
+
run_in_background=true,
|
|
101557
101764
|
prompt=\`Review this planning session before I generate the work plan:
|
|
101558
101765
|
|
|
101559
101766
|
**User's Goal**: {summarize what user wants}
|
|
@@ -101573,11 +101780,18 @@ task(
|
|
|
101573
101780
|
3. Potential scope creep areas to lock down
|
|
101574
101781
|
4. Assumptions I'm making that need validation
|
|
101575
101782
|
5. Missing acceptance criteria
|
|
101576
|
-
6. Edge cases not addressed
|
|
101577
|
-
run_in_background=false
|
|
101783
|
+
6. Edge cases not addressed\`
|
|
101578
101784
|
)
|
|
101785
|
+
|
|
101786
|
+
// Continue drafting/other work, then collect once when needed:
|
|
101787
|
+
const seraphReview = background_output(task_id=seraphTask.task_id)
|
|
101579
101788
|
\`\`\`
|
|
101580
101789
|
|
|
101790
|
+
> **NO-BLOCKING-NESTING POLICY (MANDATORY \u2014 applies to EVERY Oracle delegation):**
|
|
101791
|
+
> - **Default to background mode**: always pass \`run_in_background=true\`. Oracle's own invocations default to background; blocking is never the default.
|
|
101792
|
+
> - **Never nest a blocking subagent call** (\`run_in_background=false\`) inside your own session. Oracle may itself be running inside a fixed poll budget (default 600s); a blocking nested call consumes that same budget and stalls at the timeout.
|
|
101793
|
+
> - **Use sequential top-level calls instead**: fire the delegation in background, return to your work, then collect the result with \`background_output(task_id=...)\`. If a result is required before proceeding, collect it once and continue \u2014 never block on a nested subagent.
|
|
101794
|
+
|
|
101581
101795
|
If gate **does NOT pass**, skip Seraph and proceed directly to plan generation (note \`Seraph bypassed: complexity=X / no multi-component signal\` in summary).
|
|
101582
101796
|
|
|
101583
101797
|
## Post-Seraph: Auto-Generate Plan and Summarize
|
|
@@ -101923,7 +102137,7 @@ Parallel Speedup: ~40% faster than sequential
|
|
|
101923
102137
|
|
|
101924
102138
|
| Wave | Tasks | Recommended Agents |
|
|
101925
102139
|
|------|-------|-------------------|
|
|
101926
|
-
| 1 | 1, 5 | task(category="...", load_skills=[...], run_in_background=
|
|
102140
|
+
| 1 | 1, 5 | task(category="...", load_skills=[...], run_in_background=true) |
|
|
101927
102141
|
| 2 | 2, 3, 6 | dispatch parallel after Wave 1 completes |
|
|
101928
102142
|
| 3 | 4 | final integration task |
|
|
101929
102143
|
|
|
@@ -103268,6 +103482,9 @@ function createManagers(args) {
|
|
|
103268
103482
|
},
|
|
103269
103483
|
enableParentSessionNotifications: backgroundNotificationHookEnabled
|
|
103270
103484
|
});
|
|
103485
|
+
backgroundManager.restoreHandles().catch((error95) => {
|
|
103486
|
+
log("[index] Failed to restore background handles:", error95);
|
|
103487
|
+
});
|
|
103271
103488
|
initTaskToastManager(ctx.client);
|
|
103272
103489
|
const configHandler = createConfigHandler({
|
|
103273
103490
|
ctx: { directory: ctx.directory, client: ctx.client },
|
|
@@ -103809,6 +104026,7 @@ var HookNameEnum = exports_external.enum([
|
|
|
103809
104026
|
"preemptive-compaction",
|
|
103810
104027
|
"rules-injector",
|
|
103811
104028
|
"background-notification",
|
|
104029
|
+
"background-task-blocker",
|
|
103812
104030
|
"auto-update-checker",
|
|
103813
104031
|
"startup-toast",
|
|
103814
104032
|
"keyword-detector",
|
|
@@ -103878,8 +104096,12 @@ var MatrixxSelfConfigSkillConfigSchema = exports_external.object({
|
|
|
103878
104096
|
var providerModelSchema = exports_external.string().refine((s) => {
|
|
103879
104097
|
if (!s.includes("/"))
|
|
103880
104098
|
return false;
|
|
104099
|
+
if (s.startsWith("/") || s.endsWith("/"))
|
|
104100
|
+
return false;
|
|
104101
|
+
if (s.includes("//"))
|
|
104102
|
+
return false;
|
|
103881
104103
|
const parts = s.split("/");
|
|
103882
|
-
return parts.length
|
|
104104
|
+
return parts.length >= 2 && parts.every((p) => p.length > 0);
|
|
103883
104105
|
}, { message: "Must be <provider>/<model>" });
|
|
103884
104106
|
var ModelPresetEntrySchema = exports_external.object({
|
|
103885
104107
|
model: providerModelSchema,
|
|
@@ -104794,6 +105016,7 @@ function createToolExecuteBeforeHandler2(args) {
|
|
|
104794
105016
|
const taskEditGuardHook = hooks2.taskEditGuard?.["tool.execute.before"];
|
|
104795
105017
|
const tasksTodowriteDisablerHook = hooks2.tasksTodowriteDisabler?.["tool.execute.before"];
|
|
104796
105018
|
const oracleMdOnlyHook = hooks2.oracleMdOnly?.["tool.execute.before"];
|
|
105019
|
+
const backgroundTaskBlockerHook = hooks2.backgroundTaskBlocker?.["tool.execute.before"];
|
|
104797
105020
|
const contextModeEnforcerHook = hooks2.contextModeEnforcer?.["tool.execute.before"];
|
|
104798
105021
|
const nonInteractiveEnvHook = hooks2.nonInteractiveEnv?.["tool.execute.before"];
|
|
104799
105022
|
const bashFileReadGuardHook = hooks2.bashFileReadGuard?.["tool.execute.before"];
|
|
@@ -104814,7 +105037,8 @@ function createToolExecuteBeforeHandler2(args) {
|
|
|
104814
105037
|
taskEditGuardHook?.(input, output),
|
|
104815
105038
|
tasksTodowriteDisablerHook?.(input, output),
|
|
104816
105039
|
oracleMdOnlyHook?.(input, output),
|
|
104817
|
-
contextModeEnforcerHook?.(input, output)
|
|
105040
|
+
contextModeEnforcerHook?.(input, output),
|
|
105041
|
+
backgroundTaskBlockerHook?.(input, output)
|
|
104818
105042
|
]);
|
|
104819
105043
|
let resolvePromise;
|
|
104820
105044
|
if (input.tool === "task") {
|