nexrall-code 0.5.177 → 0.5.179
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/index.js +1049 -71
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14343,6 +14343,7 @@ var require_sharedTasks = __commonJS({
|
|
|
14343
14343
|
exports2.createSharedTask = createSharedTask;
|
|
14344
14344
|
exports2.claimTask = claimTask;
|
|
14345
14345
|
exports2.updateSharedTaskStatus = updateSharedTaskStatus;
|
|
14346
|
+
exports2.deleteSharedTask = deleteSharedTask;
|
|
14346
14347
|
var fs32 = __importStar(__require("fs"));
|
|
14347
14348
|
var os20 = __importStar(__require("os"));
|
|
14348
14349
|
var path32 = __importStar(__require("path"));
|
|
@@ -14476,6 +14477,14 @@ var require_sharedTasks = __commonJS({
|
|
|
14476
14477
|
}, workDir);
|
|
14477
14478
|
}
|
|
14478
14479
|
exports2._sharedTasksInternal = { tasksRoot, scopeDir, taskPath, isClaimAbandoned, isUnblocked, CLAIM_STALE_MS, MIN_CLAIM_AGE_FOR_DEATH_CHECK_MS };
|
|
14480
|
+
function deleteSharedTask(workDir, taskId) {
|
|
14481
|
+
try {
|
|
14482
|
+
fs32.unlinkSync(taskPath(workDir, taskId));
|
|
14483
|
+
return true;
|
|
14484
|
+
} catch {
|
|
14485
|
+
return false;
|
|
14486
|
+
}
|
|
14487
|
+
}
|
|
14479
14488
|
}
|
|
14480
14489
|
});
|
|
14481
14490
|
|
|
@@ -106697,6 +106706,16 @@ var require_hooks = __commonJS({
|
|
|
106697
106706
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
106698
106707
|
exports2.withAgentHooks = withAgentHooks;
|
|
106699
106708
|
exports2.loadHooks = loadHooks2;
|
|
106709
|
+
exports2.setHookWakeListener = setHookWakeListener2;
|
|
106710
|
+
exports2.setHookStatusListener = setHookStatusListener2;
|
|
106711
|
+
exports2.drainHookDeliveries = drainHookDeliveries;
|
|
106712
|
+
exports2.takeHookWakes = takeHookWakes2;
|
|
106713
|
+
exports2.hasPendingHookWake = hasPendingHookWake2;
|
|
106714
|
+
exports2.formatHookDeliveries = formatHookDeliveries2;
|
|
106715
|
+
exports2.resetHookOnceState = resetHookOnceState2;
|
|
106716
|
+
exports2.setHookMcpCaller = setHookMcpCaller2;
|
|
106717
|
+
exports2.setHookEventListener = setHookEventListener2;
|
|
106718
|
+
exports2.hasHookEventListener = hasHookEventListener;
|
|
106700
106719
|
exports2.parsePromptHookReply = parsePromptHookReply;
|
|
106701
106720
|
exports2.hookRunOptsFor = hookRunOptsFor;
|
|
106702
106721
|
exports2.classifyStopFailure = classifyStopFailure;
|
|
@@ -106705,6 +106724,8 @@ var require_hooks = __commonJS({
|
|
|
106705
106724
|
exports2.runSimpleHooks = runSimpleHooks;
|
|
106706
106725
|
exports2.runLifecycleHooks = runLifecycleHooks;
|
|
106707
106726
|
exports2.runPermissionRequestHooks = runPermissionRequestHooks3;
|
|
106727
|
+
exports2.runElicitationHooks = runElicitationHooks2;
|
|
106728
|
+
exports2.runElicitationResultHooks = runElicitationResultHooks2;
|
|
106708
106729
|
exports2.fireObserverHook = fireObserverHook3;
|
|
106709
106730
|
exports2.fireNotificationHooks = fireNotificationHooks2;
|
|
106710
106731
|
exports2.fireManualPostCompactHook = fireManualPostCompactHook2;
|
|
@@ -106786,7 +106807,12 @@ var require_hooks = __commonJS({
|
|
|
106786
106807
|
"ConfigChange",
|
|
106787
106808
|
"WorktreeCreate",
|
|
106788
106809
|
"WorktreeRemove",
|
|
106789
|
-
"Setup"
|
|
106810
|
+
"Setup",
|
|
106811
|
+
"PostToolBatch",
|
|
106812
|
+
"TaskCreated",
|
|
106813
|
+
"TaskCompleted",
|
|
106814
|
+
"Elicitation",
|
|
106815
|
+
"ElicitationResult"
|
|
106790
106816
|
];
|
|
106791
106817
|
function toHookEntries(list) {
|
|
106792
106818
|
return list.map((it) => {
|
|
@@ -106795,11 +106821,206 @@ var require_hooks = __commonJS({
|
|
|
106795
106821
|
return { matcher: e2.matcher, hooks: e2.hooks };
|
|
106796
106822
|
const { matcher, ...rest } = e2;
|
|
106797
106823
|
const hook = { ...rest };
|
|
106798
|
-
if (!isKnownHandlerType(hook.type))
|
|
106799
|
-
hook.type = "command";
|
|
106824
|
+
if (!isKnownHandlerType(hook.type)) {
|
|
106825
|
+
hook.type = !hook.command && !hook.url && !hook.prompt && hook.server && hook.tool ? "mcp_tool" : "command";
|
|
106826
|
+
}
|
|
106800
106827
|
return { matcher, hooks: [hook] };
|
|
106801
106828
|
});
|
|
106802
106829
|
}
|
|
106830
|
+
var _hookDeliveries = [];
|
|
106831
|
+
var _hookWakeListener = null;
|
|
106832
|
+
var _hookStatusListener = null;
|
|
106833
|
+
function setHookWakeListener2(fn) {
|
|
106834
|
+
_hookWakeListener = fn;
|
|
106835
|
+
}
|
|
106836
|
+
function setHookStatusListener2(fn) {
|
|
106837
|
+
_hookStatusListener = fn;
|
|
106838
|
+
}
|
|
106839
|
+
function drainHookDeliveries() {
|
|
106840
|
+
return _hookDeliveries.splice(0);
|
|
106841
|
+
}
|
|
106842
|
+
function takeHookWakes2() {
|
|
106843
|
+
const out = _hookDeliveries.filter((d) => d.kind === "wake");
|
|
106844
|
+
for (let i2 = _hookDeliveries.length - 1; i2 >= 0; i2--)
|
|
106845
|
+
if (_hookDeliveries[i2].kind === "wake")
|
|
106846
|
+
_hookDeliveries.splice(i2, 1);
|
|
106847
|
+
return out;
|
|
106848
|
+
}
|
|
106849
|
+
function hasPendingHookWake2() {
|
|
106850
|
+
return _hookDeliveries.some((d) => d.kind === "wake");
|
|
106851
|
+
}
|
|
106852
|
+
function formatHookDeliveries2(list) {
|
|
106853
|
+
return list.map((d) => `<hook-context source="${d.source}">
|
|
106854
|
+
${d.text}
|
|
106855
|
+
</hook-context>`).join("\n\n");
|
|
106856
|
+
}
|
|
106857
|
+
var _hookOnceDone = /* @__PURE__ */ new Set();
|
|
106858
|
+
function hookIdentity(event, hook, matcher, dir) {
|
|
106859
|
+
const body = hook.command ?? hook.url ?? hook.prompt ?? `${hook.server ?? ""}__${hook.tool ?? ""}`;
|
|
106860
|
+
return `${dir ?? ""}|${event}|${matcher ?? ""}|${body}`;
|
|
106861
|
+
}
|
|
106862
|
+
function resetHookOnceState2() {
|
|
106863
|
+
_hookOnceDone.clear();
|
|
106864
|
+
}
|
|
106865
|
+
var _activeStatuses = /* @__PURE__ */ new Map();
|
|
106866
|
+
var _statusSeq = 0;
|
|
106867
|
+
function hookStatusBegin(message) {
|
|
106868
|
+
const id = ++_statusSeq;
|
|
106869
|
+
_activeStatuses.set(id, message);
|
|
106870
|
+
_hookStatusListener?.(message);
|
|
106871
|
+
return id;
|
|
106872
|
+
}
|
|
106873
|
+
function hookStatusEnd(id) {
|
|
106874
|
+
if (!_activeStatuses.delete(id))
|
|
106875
|
+
return;
|
|
106876
|
+
if (!_activeStatuses.size) {
|
|
106877
|
+
_hookStatusListener?.(null);
|
|
106878
|
+
return;
|
|
106879
|
+
}
|
|
106880
|
+
_hookStatusListener?.([..._activeStatuses.values()].pop() ?? null);
|
|
106881
|
+
}
|
|
106882
|
+
var _hookMcpCaller = null;
|
|
106883
|
+
function setHookMcpCaller2(fn) {
|
|
106884
|
+
_hookMcpCaller = fn;
|
|
106885
|
+
}
|
|
106886
|
+
var _hookEventListener = null;
|
|
106887
|
+
function setHookEventListener2(fn) {
|
|
106888
|
+
_hookEventListener = fn;
|
|
106889
|
+
}
|
|
106890
|
+
function hasHookEventListener() {
|
|
106891
|
+
return _hookEventListener !== null;
|
|
106892
|
+
}
|
|
106893
|
+
var _hookIdSeq = 0;
|
|
106894
|
+
function emitHookLifecycle(evt) {
|
|
106895
|
+
try {
|
|
106896
|
+
_hookEventListener?.(evt);
|
|
106897
|
+
} catch {
|
|
106898
|
+
}
|
|
106899
|
+
}
|
|
106900
|
+
function hookDisplayName(hook) {
|
|
106901
|
+
if (hook.type === "http")
|
|
106902
|
+
return String(hook.url ?? "http");
|
|
106903
|
+
if (hook.type === "mcp_tool")
|
|
106904
|
+
return `${String(hook.server ?? "")}:${String(hook.tool ?? "")}`;
|
|
106905
|
+
if (hook.type === "prompt" || hook.type === "agent")
|
|
106906
|
+
return hook.type;
|
|
106907
|
+
return String(hook.command ?? "command");
|
|
106908
|
+
}
|
|
106909
|
+
var HOOK_PROGRESS_AFTER_MS = 1e3;
|
|
106910
|
+
var HOOK_PROGRESS_FLUSH_MS = 250;
|
|
106911
|
+
async function runWithHookEvents(hook, event, run) {
|
|
106912
|
+
if (!_hookEventListener)
|
|
106913
|
+
return run(void 0);
|
|
106914
|
+
const hookId = `hook_${Date.now().toString(36)}_${(++_hookIdSeq).toString(36)}`;
|
|
106915
|
+
const hookName = hookDisplayName(hook);
|
|
106916
|
+
const startedAt = Date.now();
|
|
106917
|
+
emitHookLifecycle({ kind: "started", hookId, hookName, hookEvent: event });
|
|
106918
|
+
let pendingOut = "";
|
|
106919
|
+
let pendingErr = "";
|
|
106920
|
+
let lastFlush = 0;
|
|
106921
|
+
let flushTimer = null;
|
|
106922
|
+
const flush = () => {
|
|
106923
|
+
flushTimer = null;
|
|
106924
|
+
if (!pendingOut && !pendingErr)
|
|
106925
|
+
return;
|
|
106926
|
+
const stdout2 = pendingOut, stderr2 = pendingErr;
|
|
106927
|
+
pendingOut = "";
|
|
106928
|
+
pendingErr = "";
|
|
106929
|
+
lastFlush = Date.now();
|
|
106930
|
+
emitHookLifecycle({ kind: "progress", hookId, hookName, hookEvent: event, stdout: stdout2, stderr: stderr2, output: stdout2 + stderr2 });
|
|
106931
|
+
};
|
|
106932
|
+
const onData = (d) => {
|
|
106933
|
+
if (Date.now() - startedAt < HOOK_PROGRESS_AFTER_MS)
|
|
106934
|
+
return;
|
|
106935
|
+
if (d.stdout)
|
|
106936
|
+
pendingOut += d.stdout;
|
|
106937
|
+
if (d.stderr)
|
|
106938
|
+
pendingErr += d.stderr;
|
|
106939
|
+
if (!pendingOut && !pendingErr)
|
|
106940
|
+
return;
|
|
106941
|
+
const since = Date.now() - lastFlush;
|
|
106942
|
+
if (since >= HOOK_PROGRESS_FLUSH_MS)
|
|
106943
|
+
flush();
|
|
106944
|
+
else if (!flushTimer)
|
|
106945
|
+
flushTimer = setTimeout(flush, HOOK_PROGRESS_FLUSH_MS - since);
|
|
106946
|
+
};
|
|
106947
|
+
let r2;
|
|
106948
|
+
try {
|
|
106949
|
+
r2 = await run(onData);
|
|
106950
|
+
} catch (err) {
|
|
106951
|
+
if (flushTimer)
|
|
106952
|
+
clearTimeout(flushTimer);
|
|
106953
|
+
const message = err?.message ?? String(err);
|
|
106954
|
+
emitHookLifecycle({ kind: "response", hookId, hookName, hookEvent: event, stdout: "", stderr: message, output: message, outcome: "error" });
|
|
106955
|
+
throw err;
|
|
106956
|
+
}
|
|
106957
|
+
if (flushTimer)
|
|
106958
|
+
clearTimeout(flushTimer);
|
|
106959
|
+
const stdout = r2.stdout ?? "";
|
|
106960
|
+
const stderr = r2.stderr ?? "";
|
|
106961
|
+
emitHookLifecycle({
|
|
106962
|
+
kind: "response",
|
|
106963
|
+
hookId,
|
|
106964
|
+
hookName,
|
|
106965
|
+
hookEvent: event,
|
|
106966
|
+
stdout,
|
|
106967
|
+
stderr,
|
|
106968
|
+
output: [stdout.trim(), stderr.trim()].filter(Boolean).join("\n"),
|
|
106969
|
+
// status null = killed / never exited (spawnHook's timeout path) — there is no exit code to report.
|
|
106970
|
+
...r2.status === null ? {} : { exitCode: r2.status },
|
|
106971
|
+
outcome: r2.status === 0 ? "success" : r2.status === null ? "cancelled" : "error"
|
|
106972
|
+
});
|
|
106973
|
+
return r2;
|
|
106974
|
+
}
|
|
106975
|
+
function isBackgroundHook(hook) {
|
|
106976
|
+
return hook.type === "command" && (hook.async === true || hook.asyncRewake === true);
|
|
106977
|
+
}
|
|
106978
|
+
function hookGate(hook, event, matcher, dir) {
|
|
106979
|
+
const key = hook.once ? hookIdentity(event, hook, matcher, dir) : void 0;
|
|
106980
|
+
if (key && _hookOnceDone.has(key))
|
|
106981
|
+
return { skip: true };
|
|
106982
|
+
if (isBackgroundHook(hook))
|
|
106983
|
+
return { background: true, key };
|
|
106984
|
+
return { key, statusId: hook.statusMessage ? hookStatusBegin(hook.statusMessage) : void 0 };
|
|
106985
|
+
}
|
|
106986
|
+
function startBackgroundHook(hook, payload, opts) {
|
|
106987
|
+
const statusId = hook.statusMessage ? hookStatusBegin(hook.statusMessage) : void 0;
|
|
106988
|
+
const done = (r2) => {
|
|
106989
|
+
if (statusId !== void 0)
|
|
106990
|
+
hookStatusEnd(statusId);
|
|
106991
|
+
if (r2.status === 0 && opts.key)
|
|
106992
|
+
_hookOnceDone.add(opts.key);
|
|
106993
|
+
const out = (r2.stdout ?? "").toString().trim();
|
|
106994
|
+
if (hook.asyncRewake && r2.status === 2) {
|
|
106995
|
+
const text = (r2.stderr ?? "").toString().trim() || out;
|
|
106996
|
+
_hookDeliveries.push({ kind: "wake", text: text || "Hook asked the session to wake (exit 2).", source: opts.eventLabel });
|
|
106997
|
+
try {
|
|
106998
|
+
_hookWakeListener?.();
|
|
106999
|
+
} catch {
|
|
107000
|
+
}
|
|
107001
|
+
return;
|
|
107002
|
+
}
|
|
107003
|
+
const context = directiveContext(out);
|
|
107004
|
+
if (context)
|
|
107005
|
+
_hookDeliveries.push({ kind: "context", text: context, source: opts.eventLabel });
|
|
107006
|
+
};
|
|
107007
|
+
void runHookHandler(hook, payload, { cwd: opts.cwd, timeoutMs: opts.timeoutMs, env: opts.env, event: opts.event }).then(done, () => done({ status: null, stdout: "", stderr: "" }));
|
|
107008
|
+
}
|
|
107009
|
+
function directiveContext(out) {
|
|
107010
|
+
if (!out.startsWith("{"))
|
|
107011
|
+
return "";
|
|
107012
|
+
try {
|
|
107013
|
+
const j = JSON.parse(out);
|
|
107014
|
+
const parts = [];
|
|
107015
|
+
if (typeof j.additionalContext === "string" && j.additionalContext)
|
|
107016
|
+
parts.push(j.additionalContext);
|
|
107017
|
+
if (typeof j.systemMessage === "string" && j.systemMessage)
|
|
107018
|
+
parts.push(j.systemMessage);
|
|
107019
|
+
return parts.join("\n");
|
|
107020
|
+
} catch {
|
|
107021
|
+
return "";
|
|
107022
|
+
}
|
|
107023
|
+
}
|
|
106803
107024
|
function spawnHook(command, opts) {
|
|
106804
107025
|
return new Promise((resolve12) => {
|
|
106805
107026
|
let stdout = "";
|
|
@@ -106809,7 +107030,8 @@ var require_hooks = __commonJS({
|
|
|
106809
107030
|
if (settled)
|
|
106810
107031
|
return;
|
|
106811
107032
|
settled = true;
|
|
106812
|
-
|
|
107033
|
+
if (timer)
|
|
107034
|
+
clearTimeout(timer);
|
|
106813
107035
|
resolve12({ status, stdout, stderr });
|
|
106814
107036
|
};
|
|
106815
107037
|
let child;
|
|
@@ -106819,7 +107041,7 @@ var require_hooks = __commonJS({
|
|
|
106819
107041
|
resolve12({ status: null, stdout: "", stderr: "" });
|
|
106820
107042
|
return;
|
|
106821
107043
|
}
|
|
106822
|
-
const timer = setTimeout(() => {
|
|
107044
|
+
const timer = opts.timeout === null ? null : setTimeout(() => {
|
|
106823
107045
|
try {
|
|
106824
107046
|
child.kill("SIGTERM");
|
|
106825
107047
|
} catch {
|
|
@@ -106828,12 +107050,16 @@ var require_hooks = __commonJS({
|
|
|
106828
107050
|
}, opts.timeout);
|
|
106829
107051
|
const cap = 16 * 1024 * 1024;
|
|
106830
107052
|
child.stdout?.on("data", (d) => {
|
|
107053
|
+
const s2 = d.toString("utf-8");
|
|
106831
107054
|
if (stdout.length < cap)
|
|
106832
|
-
stdout +=
|
|
107055
|
+
stdout += s2;
|
|
107056
|
+
opts.onData?.({ stdout: s2 });
|
|
106833
107057
|
});
|
|
106834
107058
|
child.stderr?.on("data", (d) => {
|
|
107059
|
+
const s2 = d.toString("utf-8");
|
|
106835
107060
|
if (stderr.length < cap)
|
|
106836
|
-
stderr +=
|
|
107061
|
+
stderr += s2;
|
|
107062
|
+
opts.onData?.({ stderr: s2 });
|
|
106837
107063
|
});
|
|
106838
107064
|
child.on("error", () => done(null));
|
|
106839
107065
|
child.on("close", (code) => done(code));
|
|
@@ -106866,13 +107092,91 @@ var require_hooks = __commonJS({
|
|
|
106866
107092
|
return { status: 1, stdout: "", stderr: `hook request failed: ${err.message}` };
|
|
106867
107093
|
}
|
|
106868
107094
|
}
|
|
106869
|
-
async function
|
|
106870
|
-
|
|
106871
|
-
|
|
106872
|
-
|
|
106873
|
-
|
|
107095
|
+
async function mcpToolHook(hook, payload) {
|
|
107096
|
+
const caller = _hookMcpCaller;
|
|
107097
|
+
const server = String(hook.server ?? "");
|
|
107098
|
+
const tool = String(hook.tool ?? "");
|
|
107099
|
+
if (!caller) {
|
|
107100
|
+
return { status: 1, stdout: "", stderr: `mcp_tool hook "${server}:${tool}" needs a connected MCP client` };
|
|
107101
|
+
}
|
|
107102
|
+
try {
|
|
107103
|
+
const res = await caller(server, tool, mcpHookInput(hook.input, payload));
|
|
107104
|
+
if ("error" in res)
|
|
107105
|
+
return { status: 1, stdout: "", stderr: res.error };
|
|
107106
|
+
const text = (res.text ?? "").trim();
|
|
107107
|
+
if (!text)
|
|
107108
|
+
return { status: 0, stdout: "", stderr: "" };
|
|
107109
|
+
return { status: 0, stdout: text.startsWith("{") ? text : JSON.stringify({ additionalContext: text }), stderr: "" };
|
|
107110
|
+
} catch (err) {
|
|
107111
|
+
return { status: 1, stdout: "", stderr: `mcp_tool hook ${server}:${tool} failed: ${err.message}` };
|
|
106874
107112
|
}
|
|
106875
|
-
|
|
107113
|
+
}
|
|
107114
|
+
function mcpHookInput(input, payload) {
|
|
107115
|
+
if (!input)
|
|
107116
|
+
return {};
|
|
107117
|
+
let root = {};
|
|
107118
|
+
try {
|
|
107119
|
+
const j = JSON.parse(payload);
|
|
107120
|
+
if (j && typeof j === "object" && !Array.isArray(j))
|
|
107121
|
+
root = j;
|
|
107122
|
+
} catch {
|
|
107123
|
+
}
|
|
107124
|
+
const nav = (parts) => {
|
|
107125
|
+
let cur = root;
|
|
107126
|
+
for (const p of parts) {
|
|
107127
|
+
if (cur === null || typeof cur !== "object")
|
|
107128
|
+
return void 0;
|
|
107129
|
+
cur = cur[p];
|
|
107130
|
+
}
|
|
107131
|
+
return cur;
|
|
107132
|
+
};
|
|
107133
|
+
const lookup = (path33) => {
|
|
107134
|
+
const parts = path33.split(".").map((s2) => s2.trim()).filter(Boolean);
|
|
107135
|
+
if (!parts.length)
|
|
107136
|
+
return void 0;
|
|
107137
|
+
const candidates = [parts];
|
|
107138
|
+
if (parts[0] === "tool_input" || parts[0] === "input") {
|
|
107139
|
+
const rest = parts.slice(1);
|
|
107140
|
+
candidates.unshift(rest, ["input", ...rest], ["tool_input", ...rest]);
|
|
107141
|
+
}
|
|
107142
|
+
for (const c of candidates) {
|
|
107143
|
+
const v = nav(c);
|
|
107144
|
+
if (v !== void 0)
|
|
107145
|
+
return v;
|
|
107146
|
+
}
|
|
107147
|
+
return void 0;
|
|
107148
|
+
};
|
|
107149
|
+
const subst = (v) => {
|
|
107150
|
+
if (typeof v !== "string")
|
|
107151
|
+
return v;
|
|
107152
|
+
const whole = v.match(/^\$\{([^}]+)\}$/);
|
|
107153
|
+
if (whole) {
|
|
107154
|
+
const hit = lookup(whole[1]);
|
|
107155
|
+
return hit === void 0 ? "" : hit;
|
|
107156
|
+
}
|
|
107157
|
+
return v.replace(/\$\{([^}]+)\}/g, (_m, p) => {
|
|
107158
|
+
const hit = lookup(p);
|
|
107159
|
+
if (hit === void 0)
|
|
107160
|
+
return "";
|
|
107161
|
+
return typeof hit === "string" ? hit : JSON.stringify(hit);
|
|
107162
|
+
});
|
|
107163
|
+
};
|
|
107164
|
+
const out = {};
|
|
107165
|
+
for (const [k, val] of Object.entries(input))
|
|
107166
|
+
out[k] = subst(val);
|
|
107167
|
+
return out;
|
|
107168
|
+
}
|
|
107169
|
+
async function runHookHandler(hook, payload, opts) {
|
|
107170
|
+
return runWithHookEvents(hook, opts.event ?? "hook", (onData) => {
|
|
107171
|
+
if (hook.type === "http")
|
|
107172
|
+
return httpHook(hook, payload, opts.timeoutMs ?? 6e4);
|
|
107173
|
+
if (hook.type === "mcp_tool")
|
|
107174
|
+
return mcpToolHook(hook, payload);
|
|
107175
|
+
if (hook.type === "prompt" || hook.type === "agent") {
|
|
107176
|
+
return promptHook(hook, payload, { ...opts, timeoutMs: opts.timeoutMs ?? 6e4, envCtx: opts.hookEnv });
|
|
107177
|
+
}
|
|
107178
|
+
return spawnHook(String(hook.command ?? ""), { cwd: opts.cwd, timeout: opts.timeoutMs, input: payload, env: opts.env, onData });
|
|
107179
|
+
});
|
|
106876
107180
|
}
|
|
106877
107181
|
var HOOK_AGENT_TOOLS = [
|
|
106878
107182
|
{
|
|
@@ -107094,22 +107398,38 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107094
107398
|
input,
|
|
107095
107399
|
...result ? { result: { output: result.output, error: result.error } } : {}
|
|
107096
107400
|
});
|
|
107401
|
+
const eventLabel = `${phase} (${toolName})`;
|
|
107402
|
+
const hookEnv = {
|
|
107403
|
+
...process.env,
|
|
107404
|
+
NEXRALL_TOOL_NAME: toolName,
|
|
107405
|
+
NEXRALL_TOOL_INPUT: JSON.stringify(input),
|
|
107406
|
+
NEXRALL_HOOK_PHASE: phase
|
|
107407
|
+
};
|
|
107097
107408
|
for (const entry of entries) {
|
|
107098
107409
|
if (!hookMatches(entry.matcher, toolName))
|
|
107099
107410
|
continue;
|
|
107100
107411
|
for (const hook of entry.hooks ?? []) {
|
|
107101
107412
|
if (!isRunnableHook(hook))
|
|
107102
107413
|
continue;
|
|
107103
|
-
const
|
|
107414
|
+
const gate = hookGate(hook, phase, entry.matcher, workDir);
|
|
107415
|
+
if (gate.skip)
|
|
107416
|
+
continue;
|
|
107417
|
+
if (gate.background) {
|
|
107418
|
+
startBackgroundHook(hook, payload, {
|
|
107419
|
+
cwd: workDir,
|
|
107420
|
+
env: hookEnv,
|
|
107421
|
+
eventLabel,
|
|
107422
|
+
event: phase,
|
|
107423
|
+
timeoutMs: hook.asyncRewake ? hookTimeoutMs(hook, 6e4) : null,
|
|
107424
|
+
key: gate.key
|
|
107425
|
+
});
|
|
107426
|
+
continue;
|
|
107427
|
+
}
|
|
107104
107428
|
const r2 = await runHookHandler(hook, payload, {
|
|
107105
107429
|
cwd: workDir,
|
|
107106
|
-
timeoutMs:
|
|
107107
|
-
env:
|
|
107108
|
-
|
|
107109
|
-
NEXRALL_TOOL_NAME: toolName,
|
|
107110
|
-
NEXRALL_TOOL_INPUT: JSON.stringify(input),
|
|
107111
|
-
NEXRALL_HOOK_PHASE: phase
|
|
107112
|
-
},
|
|
107430
|
+
timeoutMs: hookTimeoutMs(hook, 6e4),
|
|
107431
|
+
env: hookEnv,
|
|
107432
|
+
event: phase,
|
|
107113
107433
|
...hookOpts
|
|
107114
107434
|
});
|
|
107115
107435
|
const out = (r2.stdout ?? "").toString().trim();
|
|
@@ -107131,17 +107451,33 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107131
107451
|
const err = (r2.stderr ?? "").toString().trim();
|
|
107132
107452
|
outcome.reason = err || outcome.reason || `Blocked by ${phase} hook`;
|
|
107133
107453
|
}
|
|
107454
|
+
if (gate.statusId !== void 0)
|
|
107455
|
+
hookStatusEnd(gate.statusId);
|
|
107456
|
+
if (r2.status === 0 && gate.key)
|
|
107457
|
+
_hookOnceDone.add(gate.key);
|
|
107134
107458
|
}
|
|
107135
107459
|
}
|
|
107136
107460
|
return outcome;
|
|
107137
107461
|
}
|
|
107138
|
-
async function runSimpleHooks(defs, workDir, extraEnv, hookOpts) {
|
|
107462
|
+
async function runSimpleHooks(defs, workDir, extraEnv, hookOpts, event = "hook") {
|
|
107139
107463
|
if (!defs?.length)
|
|
107140
107464
|
return;
|
|
107465
|
+
const env4 = extraEnv ? { ...process.env, ...extraEnv } : void 0;
|
|
107141
107466
|
for (const hook of defs) {
|
|
107142
107467
|
if (!isRunnableHook(hook))
|
|
107143
107468
|
continue;
|
|
107144
|
-
|
|
107469
|
+
const gate = hookGate(hook, event, void 0, workDir);
|
|
107470
|
+
if (gate.skip)
|
|
107471
|
+
continue;
|
|
107472
|
+
if (gate.background) {
|
|
107473
|
+
startBackgroundHook(hook, "", { cwd: workDir, env: env4, eventLabel: event, event, timeoutMs: hook.asyncRewake ? hookTimeoutMs(hook, 1e4) : null, key: gate.key });
|
|
107474
|
+
continue;
|
|
107475
|
+
}
|
|
107476
|
+
const r2 = await runHookHandler(hook, "", { cwd: workDir, timeoutMs: hookTimeoutMs(hook, 1e4), env: env4, event, ...hookOpts });
|
|
107477
|
+
if (gate.statusId !== void 0)
|
|
107478
|
+
hookStatusEnd(gate.statusId);
|
|
107479
|
+
if (r2.status === 0 && gate.key)
|
|
107480
|
+
_hookOnceDone.add(gate.key);
|
|
107145
107481
|
}
|
|
107146
107482
|
}
|
|
107147
107483
|
function flattenHookDefs(items, matchValue) {
|
|
@@ -107158,7 +107494,7 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107158
107494
|
return out;
|
|
107159
107495
|
}
|
|
107160
107496
|
function isKnownHandlerType(t2) {
|
|
107161
|
-
return t2 === "command" || t2 === "http" || t2 === "prompt" || t2 === "agent";
|
|
107497
|
+
return t2 === "command" || t2 === "http" || t2 === "prompt" || t2 === "agent" || t2 === "mcp_tool";
|
|
107162
107498
|
}
|
|
107163
107499
|
function isRunnableHook(hook) {
|
|
107164
107500
|
if (!isKnownHandlerType(hook.type))
|
|
@@ -107167,6 +107503,8 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107167
107503
|
return !!hook.command;
|
|
107168
107504
|
if (hook.type === "http")
|
|
107169
107505
|
return !!hook.url;
|
|
107506
|
+
if (hook.type === "mcp_tool")
|
|
107507
|
+
return !!hook.server && !!hook.tool;
|
|
107170
107508
|
return !!hook.prompt;
|
|
107171
107509
|
}
|
|
107172
107510
|
async function runLifecycleHooks(items, event, workDir, payload, matchValue, hookOpts) {
|
|
@@ -107178,8 +107516,22 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107178
107516
|
for (const hook of defs) {
|
|
107179
107517
|
if (!isRunnableHook(hook))
|
|
107180
107518
|
continue;
|
|
107519
|
+
const gate = hookGate(hook, event, matchValue, workDir);
|
|
107520
|
+
if (gate.skip)
|
|
107521
|
+
continue;
|
|
107522
|
+
if (gate.background) {
|
|
107523
|
+
startBackgroundHook(hook, input, {
|
|
107524
|
+
cwd: workDir,
|
|
107525
|
+
env: { ...process.env, NEXRALL_HOOK_PHASE: event },
|
|
107526
|
+
eventLabel: event,
|
|
107527
|
+
event,
|
|
107528
|
+
timeoutMs: hook.asyncRewake ? hookTimeoutMs(hook, 6e4) : null,
|
|
107529
|
+
key: gate.key
|
|
107530
|
+
});
|
|
107531
|
+
continue;
|
|
107532
|
+
}
|
|
107181
107533
|
const timeout = hookTimeoutMs(hook, hook.type === "agent" ? 6e4 : hook.type === "prompt" ? 3e4 : 3e4);
|
|
107182
|
-
const r2 = await runHookHandler(hook, input, { cwd: workDir, timeoutMs: timeout, env: { ...process.env, NEXRALL_HOOK_PHASE: event }, ...hookOpts });
|
|
107534
|
+
const r2 = await runHookHandler(hook, input, { cwd: workDir, timeoutMs: timeout, env: { ...process.env, NEXRALL_HOOK_PHASE: event }, event, ...hookOpts });
|
|
107183
107535
|
const out = (r2.stdout ?? "").toString().trim();
|
|
107184
107536
|
if (out.startsWith("{")) {
|
|
107185
107537
|
try {
|
|
@@ -107212,6 +107564,10 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107212
107564
|
outcome.block = true;
|
|
107213
107565
|
outcome.reason = (r2.stderr ?? "").toString().trim() || outcome.reason || `Blocked by ${event} hook`;
|
|
107214
107566
|
}
|
|
107567
|
+
if (gate.statusId !== void 0)
|
|
107568
|
+
hookStatusEnd(gate.statusId);
|
|
107569
|
+
if (r2.status === 0 && gate.key)
|
|
107570
|
+
_hookOnceDone.add(gate.key);
|
|
107215
107571
|
}
|
|
107216
107572
|
return outcome;
|
|
107217
107573
|
}
|
|
@@ -107229,6 +107585,106 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107229
107585
|
}
|
|
107230
107586
|
return { answer: null };
|
|
107231
107587
|
}
|
|
107588
|
+
function parseElicitationAnswer(stdout) {
|
|
107589
|
+
const out = stdout.trim();
|
|
107590
|
+
if (!out.startsWith("{"))
|
|
107591
|
+
return null;
|
|
107592
|
+
try {
|
|
107593
|
+
const j = JSON.parse(out);
|
|
107594
|
+
const src = j.hookSpecificOutput ?? j;
|
|
107595
|
+
if (src.action !== "accept" && src.action !== "decline" && src.action !== "cancel")
|
|
107596
|
+
return null;
|
|
107597
|
+
const content = src.content && typeof src.content === "object" && !Array.isArray(src.content) ? src.content : void 0;
|
|
107598
|
+
return content ? { action: src.action, content } : { action: src.action };
|
|
107599
|
+
} catch {
|
|
107600
|
+
return null;
|
|
107601
|
+
}
|
|
107602
|
+
}
|
|
107603
|
+
async function runElicitationHooks2(workDir, server, input, sessionId = "") {
|
|
107604
|
+
try {
|
|
107605
|
+
const items = loadHooks2(workDir).Elicitation;
|
|
107606
|
+
if (!items?.length)
|
|
107607
|
+
return null;
|
|
107608
|
+
const defs = flattenHookDefs(items, server);
|
|
107609
|
+
if (!defs.length)
|
|
107610
|
+
return null;
|
|
107611
|
+
const payload = JSON.stringify({ session_id: sessionId, cwd: workDir, hook_event_name: "Elicitation", mcp_server_name: server, ...input });
|
|
107612
|
+
for (const hook of defs) {
|
|
107613
|
+
if (!isRunnableHook(hook))
|
|
107614
|
+
continue;
|
|
107615
|
+
const gate = hookGate(hook, "Elicitation", server, workDir);
|
|
107616
|
+
if (gate.skip)
|
|
107617
|
+
continue;
|
|
107618
|
+
if (gate.background) {
|
|
107619
|
+
startBackgroundHook(hook, payload, { cwd: workDir, env: { ...process.env, NEXRALL_HOOK_PHASE: "Elicitation" }, eventLabel: "Elicitation", event: "Elicitation", timeoutMs: hook.asyncRewake ? hookTimeoutMs(hook, 6e4) : null, key: gate.key });
|
|
107620
|
+
continue;
|
|
107621
|
+
}
|
|
107622
|
+
const r2 = await runHookHandler(hook, payload, { cwd: workDir, timeoutMs: hookTimeoutMs(hook, 3e4), env: { ...process.env, NEXRALL_HOOK_PHASE: "Elicitation" }, event: "Elicitation" });
|
|
107623
|
+
if (gate.statusId !== void 0)
|
|
107624
|
+
hookStatusEnd(gate.statusId);
|
|
107625
|
+
if (r2.status === 0 && gate.key)
|
|
107626
|
+
_hookOnceDone.add(gate.key);
|
|
107627
|
+
if (r2.status === 2)
|
|
107628
|
+
return { action: "decline" };
|
|
107629
|
+
const answer = parseElicitationAnswer((r2.stdout ?? "").toString());
|
|
107630
|
+
if (answer)
|
|
107631
|
+
return answer;
|
|
107632
|
+
}
|
|
107633
|
+
} catch {
|
|
107634
|
+
}
|
|
107635
|
+
return null;
|
|
107636
|
+
}
|
|
107637
|
+
async function runElicitationResultHooks2(workDir, server, answer, meta = {}) {
|
|
107638
|
+
try {
|
|
107639
|
+
const items = loadHooks2(workDir).ElicitationResult;
|
|
107640
|
+
if (!items?.length)
|
|
107641
|
+
return answer;
|
|
107642
|
+
const defs = flattenHookDefs(items, server);
|
|
107643
|
+
if (!defs.length)
|
|
107644
|
+
return answer;
|
|
107645
|
+
let current = answer;
|
|
107646
|
+
for (const hook of defs) {
|
|
107647
|
+
if (!isRunnableHook(hook))
|
|
107648
|
+
continue;
|
|
107649
|
+
const gate = hookGate(hook, "ElicitationResult", server, workDir);
|
|
107650
|
+
if (gate.skip)
|
|
107651
|
+
continue;
|
|
107652
|
+
const payload = JSON.stringify({
|
|
107653
|
+
session_id: meta.sessionId ?? "",
|
|
107654
|
+
cwd: workDir,
|
|
107655
|
+
hook_event_name: "ElicitationResult",
|
|
107656
|
+
mcp_server_name: server,
|
|
107657
|
+
action: current.action,
|
|
107658
|
+
content: current.content,
|
|
107659
|
+
mode: meta.mode,
|
|
107660
|
+
elicitation_id: meta.elicitationId
|
|
107661
|
+
});
|
|
107662
|
+
if (gate.background) {
|
|
107663
|
+
startBackgroundHook(hook, payload, { cwd: workDir, env: { ...process.env, NEXRALL_HOOK_PHASE: "ElicitationResult" }, eventLabel: "ElicitationResult", event: "ElicitationResult", timeoutMs: hook.asyncRewake ? hookTimeoutMs(hook, 6e4) : null, key: gate.key });
|
|
107664
|
+
continue;
|
|
107665
|
+
}
|
|
107666
|
+
const r2 = await runHookHandler(hook, payload, { cwd: workDir, timeoutMs: hookTimeoutMs(hook, 3e4), env: { ...process.env, NEXRALL_HOOK_PHASE: "ElicitationResult" }, event: "ElicitationResult" });
|
|
107667
|
+
if (gate.statusId !== void 0)
|
|
107668
|
+
hookStatusEnd(gate.statusId);
|
|
107669
|
+
if (r2.status === 0 && gate.key)
|
|
107670
|
+
_hookOnceDone.add(gate.key);
|
|
107671
|
+
if (r2.status === 2)
|
|
107672
|
+
return { action: "decline" };
|
|
107673
|
+
const override = parseElicitationAnswer((r2.stdout ?? "").toString());
|
|
107674
|
+
if (override) {
|
|
107675
|
+
if (override.action === "accept") {
|
|
107676
|
+
const content = override.content ?? (current.action === "accept" ? current.content : void 0);
|
|
107677
|
+
current = content ? { action: "accept", content } : { action: "accept" };
|
|
107678
|
+
} else {
|
|
107679
|
+
current = { action: override.action };
|
|
107680
|
+
}
|
|
107681
|
+
}
|
|
107682
|
+
}
|
|
107683
|
+
return current;
|
|
107684
|
+
} catch {
|
|
107685
|
+
return answer;
|
|
107686
|
+
}
|
|
107687
|
+
}
|
|
107232
107688
|
async function fireObserverHook3(workDir, event, payload, matchValue) {
|
|
107233
107689
|
try {
|
|
107234
107690
|
const items = loadHooks2(workDir)[event];
|
|
@@ -107923,6 +108379,11 @@ var require_iterationPolicy = __commonJS({
|
|
|
107923
108379
|
\u{1F6D1} Stopped: the same tool error repeated ${exports2.REPEAT_STALL_LIMIT} rounds in a row, so the agent was looping without making progress.` + (ctx.repeatError ? ` The recurring error was:
|
|
107924
108380
|
${ctx.repeatError}
|
|
107925
108381
|
` : "\n") + `Fix that underlying cause (or grant the needed permission) and send "continue".
|
|
108382
|
+
`;
|
|
108383
|
+
case "hook-blocked":
|
|
108384
|
+
return `
|
|
108385
|
+
\u26D4 A PostToolBatch hook stopped the turn before the next model call` + (ctx.hookReason ? `: ${ctx.hookReason}` : ".") + `
|
|
108386
|
+
The reason is in the conversation, so send "continue" once the cause is handled.
|
|
107926
108387
|
`;
|
|
107927
108388
|
case "budget":
|
|
107928
108389
|
return `
|
|
@@ -108523,7 +108984,10 @@ ${body}`);
|
|
|
108523
108984
|
"no-balance",
|
|
108524
108985
|
"no-team-budget",
|
|
108525
108986
|
"team-unavailable",
|
|
108526
|
-
"reported-elsewhere"
|
|
108987
|
+
"reported-elsewhere",
|
|
108988
|
+
// A hook stopping the batch means the sub-agent stopped short of its report, so the
|
|
108989
|
+
// parent must not read the result as a finished one.
|
|
108990
|
+
"hook-blocked"
|
|
108527
108991
|
]);
|
|
108528
108992
|
exports2.SUBAGENT_PREAMBLE = [
|
|
108529
108993
|
"# You are a sub-agent",
|
|
@@ -109232,8 +109696,8 @@ var require_loop = __commonJS({
|
|
|
109232
109696
|
"../core/dist/agent/loop.js"(exports2) {
|
|
109233
109697
|
"use strict";
|
|
109234
109698
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
109235
|
-
exports2.
|
|
109236
|
-
exports2.lastToolResults = exports2.summariseSubTaskProgress = exports2.capSubTaskText = exports2.extractSubTaskText = exports2.ToolNotAllowedError = void 0;
|
|
109699
|
+
exports2.resolveMaxIterations = exports2.stopReasonNotice = exports2.executeAgentMemoryWrite = exports2.AGENT_MEMORY_TOOL_SCHEMA = exports2.AGENT_MEMORY_TOOL = exports2._stallLimits = exports2.errorRoundSignature = exports2._emptyTurnRetry = exports2.shouldRetryEmptyTurn = exports2.emptyTurnBackoffMs = exports2.compactMessagesForResume = exports2.estimateTokensRough = exports2.makeCachedSummarizer = exports2.pruneOldToolResults = exports2.ledgerSummary = exports2.ledgerRecord = exports2.createLedger = exports2.transcriptOf = exports2.persistRuntimeContext = exports2.findSafeCutIndex = exports2.VERIFY_CMD_RE = exports2.allowsTestOnlyWrite = exports2.WRITE_TOOL_NAMES = exports2.estimateBodyBytes = exports2.pruneReclaimFloor = exports2.compactionThresholds = exports2.compactionLimits = exports2.contextWindowFor = exports2.runElicitationResultHooks = exports2.runElicitationHooks = exports2.hasHookEventListener = exports2.setHookEventListener = exports2.resetHookOnceState = exports2.setHookMcpCaller = exports2.setHookStatusListener = exports2.setHookWakeListener = exports2.formatHookDeliveries = exports2.hasPendingHookWake = exports2.takeHookWakes = exports2.drainHookDeliveries = exports2.fireObserverHook = exports2.fireManualPreCompactHook = exports2.fireManualPostCompactHook = exports2.fireNotificationHooks = exports2.runPermissionRequestHooks = exports2.runLifecycleHooks = exports2.classifyStopFailure = exports2.parsePromptHookReply = exports2.loadHooks = exports2.bashNeedsRepoLock = void 0;
|
|
109700
|
+
exports2.lastToolResults = exports2.summariseSubTaskProgress = exports2.capSubTaskText = exports2.extractSubTaskText = exports2.ToolNotAllowedError = exports2.resolveSubtaskTimeoutMs = exports2.canSpawnSubAgents = exports2.intersectAllowlists = exports2.noSpawnReason = exports2.resolveMaxSubagentDepth = exports2._sessionSubAgentCount = exports2.resetSessionSubAgentBudget = exports2._resetSubTaskLimiter = exports2.createLimiter = exports2.resolveMaxSubagentsPerSession = exports2.resolveMaxConcurrentSubtasks = exports2.lockPathsFor = void 0;
|
|
109237
109701
|
exports2.dispatchSubAgent = dispatchSubAgent;
|
|
109238
109702
|
exports2.dispatchBackgroundSubAgent = dispatchBackgroundSubAgent;
|
|
109239
109703
|
exports2.runAgentLoop = runAgentLoop2;
|
|
@@ -109244,6 +109708,7 @@ var require_loop = __commonJS({
|
|
|
109244
109708
|
var types_1 = require_types();
|
|
109245
109709
|
var client_1 = require_client();
|
|
109246
109710
|
var executor_1 = require_executor();
|
|
109711
|
+
var sharedTasks_1 = require_sharedTasks();
|
|
109247
109712
|
var agentTypes_1 = require_agentTypes();
|
|
109248
109713
|
var skills_1 = require_skills();
|
|
109249
109714
|
var rules_1 = require_rules();
|
|
@@ -109291,6 +109756,42 @@ var require_loop = __commonJS({
|
|
|
109291
109756
|
Object.defineProperty(exports2, "fireObserverHook", { enumerable: true, get: function() {
|
|
109292
109757
|
return hooks_2.fireObserverHook;
|
|
109293
109758
|
} });
|
|
109759
|
+
Object.defineProperty(exports2, "drainHookDeliveries", { enumerable: true, get: function() {
|
|
109760
|
+
return hooks_2.drainHookDeliveries;
|
|
109761
|
+
} });
|
|
109762
|
+
Object.defineProperty(exports2, "takeHookWakes", { enumerable: true, get: function() {
|
|
109763
|
+
return hooks_2.takeHookWakes;
|
|
109764
|
+
} });
|
|
109765
|
+
Object.defineProperty(exports2, "hasPendingHookWake", { enumerable: true, get: function() {
|
|
109766
|
+
return hooks_2.hasPendingHookWake;
|
|
109767
|
+
} });
|
|
109768
|
+
Object.defineProperty(exports2, "formatHookDeliveries", { enumerable: true, get: function() {
|
|
109769
|
+
return hooks_2.formatHookDeliveries;
|
|
109770
|
+
} });
|
|
109771
|
+
Object.defineProperty(exports2, "setHookWakeListener", { enumerable: true, get: function() {
|
|
109772
|
+
return hooks_2.setHookWakeListener;
|
|
109773
|
+
} });
|
|
109774
|
+
Object.defineProperty(exports2, "setHookStatusListener", { enumerable: true, get: function() {
|
|
109775
|
+
return hooks_2.setHookStatusListener;
|
|
109776
|
+
} });
|
|
109777
|
+
Object.defineProperty(exports2, "setHookMcpCaller", { enumerable: true, get: function() {
|
|
109778
|
+
return hooks_2.setHookMcpCaller;
|
|
109779
|
+
} });
|
|
109780
|
+
Object.defineProperty(exports2, "resetHookOnceState", { enumerable: true, get: function() {
|
|
109781
|
+
return hooks_2.resetHookOnceState;
|
|
109782
|
+
} });
|
|
109783
|
+
Object.defineProperty(exports2, "setHookEventListener", { enumerable: true, get: function() {
|
|
109784
|
+
return hooks_2.setHookEventListener;
|
|
109785
|
+
} });
|
|
109786
|
+
Object.defineProperty(exports2, "hasHookEventListener", { enumerable: true, get: function() {
|
|
109787
|
+
return hooks_2.hasHookEventListener;
|
|
109788
|
+
} });
|
|
109789
|
+
Object.defineProperty(exports2, "runElicitationHooks", { enumerable: true, get: function() {
|
|
109790
|
+
return hooks_2.runElicitationHooks;
|
|
109791
|
+
} });
|
|
109792
|
+
Object.defineProperty(exports2, "runElicitationResultHooks", { enumerable: true, get: function() {
|
|
109793
|
+
return hooks_2.runElicitationResultHooks;
|
|
109794
|
+
} });
|
|
109294
109795
|
var compaction_1 = require_compaction();
|
|
109295
109796
|
var compaction_2 = require_compaction();
|
|
109296
109797
|
Object.defineProperty(exports2, "contextWindowFor", { enumerable: true, get: function() {
|
|
@@ -109465,6 +109966,27 @@ var require_loop = __commonJS({
|
|
|
109465
109966
|
subAgentBudget_1._inFlightByDepth.delete(childDepth);
|
|
109466
109967
|
}
|
|
109467
109968
|
}
|
|
109969
|
+
async function taskHookVeto(entries, event, input, options, extra = {}) {
|
|
109970
|
+
if (!entries?.length)
|
|
109971
|
+
return null;
|
|
109972
|
+
const taskId = typeof input.task_id === "string" ? input.task_id : "";
|
|
109973
|
+
const task = extra.task_subject ? null : (0, sharedTasks_1.listSharedTasks)(options.workDir).find((t2) => t2.id === taskId);
|
|
109974
|
+
const payload = {
|
|
109975
|
+
session_id: options.sessionId ?? "",
|
|
109976
|
+
...taskId ? { task_id: taskId } : {},
|
|
109977
|
+
...task ? { task_subject: task.content, task_description: task.content } : {},
|
|
109978
|
+
...extra,
|
|
109979
|
+
tool_input: input
|
|
109980
|
+
};
|
|
109981
|
+
try {
|
|
109982
|
+
const outcome = await (0, hooks_1.runLifecycleHooks)(entries, event, options.workDir, payload, void 0, (0, hooks_1.hookRunOptsFor)(options));
|
|
109983
|
+
if (!outcome.block)
|
|
109984
|
+
return null;
|
|
109985
|
+
return `Refused by ${event} hook${outcome.reason ? `: ${outcome.reason}` : ""}`;
|
|
109986
|
+
} catch {
|
|
109987
|
+
return null;
|
|
109988
|
+
}
|
|
109989
|
+
}
|
|
109468
109990
|
function dispatchBackgroundSubAgent(input, options, agentTypes, hub) {
|
|
109469
109991
|
const overBudget = (0, subAgentBudget_1.claimSessionSubAgentSlot)(options.workDir, options.onNotice ?? options.onText, options.sessionId);
|
|
109470
109992
|
if (overBudget)
|
|
@@ -109668,6 +110190,7 @@ ${ctx}
|
|
|
109668
110190
|
let repeatedErrorRounds = 0;
|
|
109669
110191
|
let lastErrorSignature = "";
|
|
109670
110192
|
let stalledRepeatError = null;
|
|
110193
|
+
let hookBlockedReason = null;
|
|
109671
110194
|
let budget = maxIterations;
|
|
109672
110195
|
let iteration = 0;
|
|
109673
110196
|
let emptyTurnRetries = 0;
|
|
@@ -109851,7 +110374,8 @@ ${ctx}
|
|
|
109851
110374
|
const queued = options.takePendingInput?.() ?? [];
|
|
109852
110375
|
const peerMsgs = options.drainPeerMessages?.() ?? [];
|
|
109853
110376
|
const bgDone = drainBackgroundNotifications();
|
|
109854
|
-
|
|
110377
|
+
const hookMsgs = (0, hooks_1.drainHookDeliveries)();
|
|
110378
|
+
if (queued.length || peerMsgs.length || bgDone.length || hookMsgs.length) {
|
|
109855
110379
|
const parts = [];
|
|
109856
110380
|
if (queued.length) {
|
|
109857
110381
|
parts.push(queued.join("\n\n"));
|
|
@@ -109863,6 +110387,8 @@ ${ctx}
|
|
|
109863
110387
|
}
|
|
109864
110388
|
if (bgDone.length)
|
|
109865
110389
|
parts.push((0, backgroundAgents_1.formatBackgroundNotifications)(bgDone));
|
|
110390
|
+
if (hookMsgs.length)
|
|
110391
|
+
parts.push((0, hooks_1.formatHookDeliveries)(hookMsgs));
|
|
109866
110392
|
messages.push({ role: "user", content: [{ type: "text", text: parts.join("\n\n") }] });
|
|
109867
110393
|
continue;
|
|
109868
110394
|
}
|
|
@@ -109895,7 +110421,8 @@ ${ctx}
|
|
|
109895
110421
|
const queued = options.takePendingInput?.() ?? [];
|
|
109896
110422
|
const peerMsgs = options.drainPeerMessages?.() ?? [];
|
|
109897
110423
|
const bgDone = drainBackgroundNotifications();
|
|
109898
|
-
|
|
110424
|
+
const hookMsgs = (0, hooks_1.drainHookDeliveries)();
|
|
110425
|
+
if (queued.length || peerMsgs.length || bgDone.length || hookMsgs.length) {
|
|
109899
110426
|
const parts = [];
|
|
109900
110427
|
if (queued.length) {
|
|
109901
110428
|
parts.push(queued.join("\n\n"));
|
|
@@ -109907,6 +110434,8 @@ ${ctx}
|
|
|
109907
110434
|
}
|
|
109908
110435
|
if (bgDone.length)
|
|
109909
110436
|
parts.push((0, backgroundAgents_1.formatBackgroundNotifications)(bgDone));
|
|
110437
|
+
if (hookMsgs.length)
|
|
110438
|
+
parts.push((0, hooks_1.formatHookDeliveries)(hookMsgs));
|
|
109910
110439
|
messages.push({ role: "user", content: [{ type: "text", text: parts.join("\n\n") }] });
|
|
109911
110440
|
continue;
|
|
109912
110441
|
}
|
|
@@ -110065,7 +110594,16 @@ ${ctx}
|
|
|
110065
110594
|
if (pre.block) {
|
|
110066
110595
|
result = { error: `Blocked by PreToolUse hook: ${pre.reason}` };
|
|
110067
110596
|
} else {
|
|
110597
|
+
const taskIdsBefore = name === "create_shared_task" ? new Set((0, sharedTasks_1.listSharedTasks)(options.workDir).map((t2) => t2.id)) : null;
|
|
110068
110598
|
try {
|
|
110599
|
+
if (name === "update_shared_task_status" && String(input.status ?? "") === "completed") {
|
|
110600
|
+
const veto = await taskHookVeto(hooks.TaskCompleted, "TaskCompleted", input, options);
|
|
110601
|
+
if (veto) {
|
|
110602
|
+
result = { error: veto };
|
|
110603
|
+
options.onToolResult(name, result, void 0, toolMeta);
|
|
110604
|
+
return { block: { ...block, id }, result };
|
|
110605
|
+
}
|
|
110606
|
+
}
|
|
110069
110607
|
if (name === iterationPolicy_1.AGENT_MEMORY_TOOL) {
|
|
110070
110608
|
result = await (0, iterationPolicy_1.executeAgentMemoryWrite)(input, options._agentMemory, options.workDir);
|
|
110071
110609
|
options.onToolResult(name, result, void 0, toolMeta);
|
|
@@ -110103,6 +110641,21 @@ ${ctx}
|
|
|
110103
110641
|
} catch (err) {
|
|
110104
110642
|
result = { error: `Tool execution failed: ${err.message}` };
|
|
110105
110643
|
}
|
|
110644
|
+
if (name === "create_shared_task" && result.error === void 0 && taskIdsBefore) {
|
|
110645
|
+
const created = (0, sharedTasks_1.listSharedTasks)(options.workDir).filter((t2) => !taskIdsBefore.has(t2.id) && typeof input.content === "string" && t2.content === input.content);
|
|
110646
|
+
const task = created[created.length - 1];
|
|
110647
|
+
if (task) {
|
|
110648
|
+
const veto = await taskHookVeto(hooks.TaskCreated, "TaskCreated", input, options, {
|
|
110649
|
+
task_id: task.id,
|
|
110650
|
+
task_subject: task.content,
|
|
110651
|
+
task_description: task.content
|
|
110652
|
+
});
|
|
110653
|
+
if (veto) {
|
|
110654
|
+
(0, sharedTasks_1.deleteSharedTask)(options.workDir, task.id);
|
|
110655
|
+
result = { error: veto };
|
|
110656
|
+
}
|
|
110657
|
+
}
|
|
110658
|
+
}
|
|
110106
110659
|
if (name === "memory_write" && result.error === void 0) {
|
|
110107
110660
|
const scope = input.scope === "global" ? "global" : "project";
|
|
110108
110661
|
void (0, compaction_1.maybeCompactMemory)(scope, options);
|
|
@@ -110194,6 +110747,32 @@ ${result.output}` : `Error: ${result.error}` : result.output ?? "",
|
|
|
110194
110747
|
if (bgFinished.length) {
|
|
110195
110748
|
toolResultContent.push({ type: "text", text: (0, backgroundAgents_1.formatBackgroundNotifications)(bgFinished) });
|
|
110196
110749
|
}
|
|
110750
|
+
const hookDeliveries = (0, hooks_1.drainHookDeliveries)();
|
|
110751
|
+
if (hookDeliveries.length) {
|
|
110752
|
+
toolResultContent.push({ type: "text", text: (0, hooks_1.formatHookDeliveries)(hookDeliveries) });
|
|
110753
|
+
}
|
|
110754
|
+
let postBatchStop = null;
|
|
110755
|
+
if (hooks.PostToolBatch?.length) {
|
|
110756
|
+
const batch = await (0, hooks_1.runLifecycleHooks)(hooks.PostToolBatch, "PostToolBatch", options.workDir, {
|
|
110757
|
+
tool_calls: toolResults.map(({ block: b, result: r2 }) => ({
|
|
110758
|
+
tool_name: b.name,
|
|
110759
|
+
tool_input: b.input,
|
|
110760
|
+
tool_use_id: b.id,
|
|
110761
|
+
tool_response: r2.error !== void 0 ? r2.output ? `Error: ${r2.error}
|
|
110762
|
+
|
|
110763
|
+
${r2.output}` : `Error: ${r2.error}` : r2.output ?? ""
|
|
110764
|
+
}))
|
|
110765
|
+
}, void 0, (0, hooks_1.hookRunOptsFor)(options));
|
|
110766
|
+
if (batch.context)
|
|
110767
|
+
toolResultContent.push({ type: "text", text: batch.context });
|
|
110768
|
+
if (batch.block) {
|
|
110769
|
+
postBatchStop = batch.reason?.trim() || "a PostToolBatch hook stopped the turn";
|
|
110770
|
+
toolResultContent.push({
|
|
110771
|
+
type: "text",
|
|
110772
|
+
text: `A PostToolBatch hook stopped the turn before the next model call: ${postBatchStop}`
|
|
110773
|
+
});
|
|
110774
|
+
}
|
|
110775
|
+
}
|
|
110197
110776
|
const toolResultMessage = {
|
|
110198
110777
|
role: "user",
|
|
110199
110778
|
content: toolResultContent
|
|
@@ -110201,6 +110780,11 @@ ${result.output}` : `Error: ${result.error}` : result.output ?? "",
|
|
|
110201
110780
|
messages.push(toolResultMessage);
|
|
110202
110781
|
completedRounds++;
|
|
110203
110782
|
options.onProgress?.(messages);
|
|
110783
|
+
if (postBatchStop) {
|
|
110784
|
+
stopReason = "hook-blocked";
|
|
110785
|
+
hookBlockedReason = postBatchStop;
|
|
110786
|
+
break;
|
|
110787
|
+
}
|
|
110204
110788
|
const errored = toolResults.filter(({ result }) => result.error !== void 0);
|
|
110205
110789
|
const allErrored = toolResults.length > 0 && errored.length === toolResults.length;
|
|
110206
110790
|
consecutiveErrorRounds = allErrored ? consecutiveErrorRounds + 1 : 0;
|
|
@@ -110234,7 +110818,7 @@ ${result.output}` : `Error: ${result.error}` : result.output ?? "",
|
|
|
110234
110818
|
const apiFailure = (0, hooks_1.apiFailureForStopReason)(stopReason);
|
|
110235
110819
|
if (apiFailure)
|
|
110236
110820
|
await fireStopFailure(apiFailure);
|
|
110237
|
-
const notice = (0, iterationPolicy_1.stopReasonNotice)(stopReason, { budget, repeatError: stalledRepeatError });
|
|
110821
|
+
const notice = (0, iterationPolicy_1.stopReasonNotice)(stopReason, { budget, repeatError: stalledRepeatError, hookReason: hookBlockedReason });
|
|
110238
110822
|
if (options._onStopReason)
|
|
110239
110823
|
options._onStopReason(stopReason, notice || null);
|
|
110240
110824
|
else if (notice)
|
|
@@ -110525,9 +111109,12 @@ var require_client2 = __commonJS({
|
|
|
110525
111109
|
"../core/dist/mcp/client.js"(exports2) {
|
|
110526
111110
|
"use strict";
|
|
110527
111111
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
110528
|
-
exports2.McpClient = void 0;
|
|
111112
|
+
exports2.McpClient = exports2.MCP_ELICITATION_CAPABILITY = void 0;
|
|
110529
111113
|
exports2.flattenResourceContents = flattenResourceContents;
|
|
110530
111114
|
exports2.flattenPromptMessages = flattenPromptMessages;
|
|
111115
|
+
exports2.elicitationCapability = elicitationCapability;
|
|
111116
|
+
exports2.normalizeElicitationRequest = normalizeElicitationRequest;
|
|
111117
|
+
exports2.serverRequestReply = serverRequestReply;
|
|
110531
111118
|
var child_process_1 = __require("child_process");
|
|
110532
111119
|
function flattenResourceContents(result, maxChars = 1e5) {
|
|
110533
111120
|
const contents = result?.contents ?? [];
|
|
@@ -110567,6 +111154,39 @@ var require_client2 = __commonJS({
|
|
|
110567
111154
|
return text.length > maxChars ? text.slice(0, maxChars) + `
|
|
110568
111155
|
\u2026 [truncated, ${text.length - maxChars} more characters]` : text;
|
|
110569
111156
|
}
|
|
111157
|
+
exports2.MCP_ELICITATION_CAPABILITY = { elicitation: { form: {}, url: {} } };
|
|
111158
|
+
function elicitationCapability(bare) {
|
|
111159
|
+
return bare ? { elicitation: {} } : { elicitation: { form: {}, url: {} } };
|
|
111160
|
+
}
|
|
111161
|
+
function normalizeElicitationRequest(params) {
|
|
111162
|
+
const p = params ?? {};
|
|
111163
|
+
const url = typeof p.url === "string" ? p.url : void 0;
|
|
111164
|
+
const schema = p.requestedSchema ?? p.schema;
|
|
111165
|
+
return {
|
|
111166
|
+
message: typeof p.message === "string" && p.message.trim() ? p.message : "An MCP server is asking for input.",
|
|
111167
|
+
mode: p.mode === "url" || !p.mode && url ? "url" : "form",
|
|
111168
|
+
requestedSchema: schema && typeof schema === "object" ? schema : void 0,
|
|
111169
|
+
url,
|
|
111170
|
+
elicitationId: typeof p.elicitationId === "string" ? p.elicitationId : typeof p.elicitation_id === "string" ? p.elicitation_id : void 0
|
|
111171
|
+
};
|
|
111172
|
+
}
|
|
111173
|
+
async function serverRequestReply(server, handler, method, params) {
|
|
111174
|
+
if (method === "elicitation/create") {
|
|
111175
|
+
let resp = { action: "decline" };
|
|
111176
|
+
const request = normalizeElicitationRequest(params);
|
|
111177
|
+
try {
|
|
111178
|
+
if (handler)
|
|
111179
|
+
resp = await handler(server, request);
|
|
111180
|
+
} catch {
|
|
111181
|
+
resp = { action: "decline" };
|
|
111182
|
+
}
|
|
111183
|
+
const result = { action: resp.action };
|
|
111184
|
+
if (resp.action === "accept" && resp.content)
|
|
111185
|
+
result.content = resp.content;
|
|
111186
|
+
return { result };
|
|
111187
|
+
}
|
|
111188
|
+
return { error: { code: -32601, message: `Method not found: ${method}` } };
|
|
111189
|
+
}
|
|
110570
111190
|
var McpClient = class {
|
|
110571
111191
|
constructor(name, config) {
|
|
110572
111192
|
this.config = config;
|
|
@@ -110575,11 +111195,15 @@ var require_client2 = __commonJS({
|
|
|
110575
111195
|
this._pending = /* @__PURE__ */ new Map();
|
|
110576
111196
|
this._buf = "";
|
|
110577
111197
|
this._tools = [];
|
|
111198
|
+
this._elicitationHandler = null;
|
|
110578
111199
|
this.name = name;
|
|
110579
111200
|
}
|
|
110580
111201
|
get tools() {
|
|
110581
111202
|
return this._tools;
|
|
110582
111203
|
}
|
|
111204
|
+
setElicitationHandler(handler) {
|
|
111205
|
+
this._elicitationHandler = handler;
|
|
111206
|
+
}
|
|
110583
111207
|
async connect() {
|
|
110584
111208
|
if (!this.config.command)
|
|
110585
111209
|
throw new Error(`MCP server "${this.name}" has no command (stdio transport requires one).`);
|
|
@@ -110607,7 +111231,7 @@ var require_client2 = __commonJS({
|
|
|
110607
111231
|
});
|
|
110608
111232
|
await this._request("initialize", {
|
|
110609
111233
|
protocolVersion: "2024-11-05",
|
|
110610
|
-
capabilities:
|
|
111234
|
+
capabilities: elicitationCapability(this.config.bareElicitationCapability),
|
|
110611
111235
|
clientInfo: { name: "nexrall-code", version: "1.0" }
|
|
110612
111236
|
});
|
|
110613
111237
|
this._notify("notifications/initialized");
|
|
@@ -110688,6 +111312,10 @@ var require_client2 = __commonJS({
|
|
|
110688
111312
|
} catch {
|
|
110689
111313
|
return;
|
|
110690
111314
|
}
|
|
111315
|
+
if (typeof msg.method === "string" && msg.id != null) {
|
|
111316
|
+
void this._handleServerRequest(msg.id, msg.method, msg.params);
|
|
111317
|
+
return;
|
|
111318
|
+
}
|
|
110691
111319
|
if (msg.id == null)
|
|
110692
111320
|
return;
|
|
110693
111321
|
const pending = this._pending.get(msg.id);
|
|
@@ -110700,6 +111328,11 @@ var require_client2 = __commonJS({
|
|
|
110700
111328
|
pending.resolve(msg.result);
|
|
110701
111329
|
}
|
|
110702
111330
|
}
|
|
111331
|
+
/** Answer a server→client request. Errors are swallowed — the server must get SOME reply. */
|
|
111332
|
+
async _handleServerRequest(id, method, params) {
|
|
111333
|
+
const reply = await serverRequestReply(this.name, this._elicitationHandler, method, params);
|
|
111334
|
+
this._send({ jsonrpc: "2.0", id, ...reply });
|
|
111335
|
+
}
|
|
110703
111336
|
_rejectAll(err) {
|
|
110704
111337
|
for (const { reject } of this._pending.values())
|
|
110705
111338
|
reject(err);
|
|
@@ -110738,17 +111371,21 @@ var require_httpClient = __commonJS({
|
|
|
110738
111371
|
this._nextId = 1;
|
|
110739
111372
|
this._tools = [];
|
|
110740
111373
|
this._sessionId = null;
|
|
111374
|
+
this._elicitationHandler = null;
|
|
110741
111375
|
this.name = name;
|
|
110742
111376
|
}
|
|
110743
111377
|
get tools() {
|
|
110744
111378
|
return this._tools;
|
|
110745
111379
|
}
|
|
111380
|
+
setElicitationHandler(handler) {
|
|
111381
|
+
this._elicitationHandler = handler;
|
|
111382
|
+
}
|
|
110746
111383
|
async connect() {
|
|
110747
111384
|
if (!this.config.url)
|
|
110748
111385
|
throw new Error(`MCP server "${this.name}" has no url (http/sse transport requires one).`);
|
|
110749
111386
|
await this._rpc("initialize", {
|
|
110750
111387
|
protocolVersion: "2024-11-05",
|
|
110751
|
-
capabilities:
|
|
111388
|
+
capabilities: (0, client_1.elicitationCapability)(this.config.bareElicitationCapability),
|
|
110752
111389
|
clientInfo: { name: "nexrall-code", version: "1.0" }
|
|
110753
111390
|
});
|
|
110754
111391
|
await this._notify("notifications/initialized");
|
|
@@ -110843,29 +111480,106 @@ var require_httpClient = __commonJS({
|
|
|
110843
111480
|
throw new Error(`MCP HTTP ${resp.status} ${resp.statusText}${body ? `: ${body.slice(0, 200)}` : ""}`);
|
|
110844
111481
|
}
|
|
110845
111482
|
const contentType = resp.headers.get("content-type") ?? "";
|
|
111483
|
+
if (contentType.includes("text/event-stream"))
|
|
111484
|
+
return await this._consumeSse(resp, id);
|
|
110846
111485
|
const text = await resp.text();
|
|
110847
111486
|
if (!text.trim())
|
|
110848
111487
|
return null;
|
|
110849
|
-
const
|
|
111488
|
+
const msg = JSON.parse(text);
|
|
111489
|
+
if (msg.error)
|
|
111490
|
+
throw new Error(`MCP error ${msg.error.code}: ${msg.error.message}`);
|
|
111491
|
+
return msg.result ?? null;
|
|
111492
|
+
}
|
|
111493
|
+
/**
|
|
111494
|
+
* Read an SSE reply frame by frame. A server request (elicitation) is answered on the
|
|
111495
|
+
* spot: the server WAITS for that answer before it sends our own result, so buffering
|
|
111496
|
+
* the whole stream first would deadlock until the request timeout. As soon as our id
|
|
111497
|
+
* arrives we stop and cancel the body (the stream may stay open for the session).
|
|
111498
|
+
* Falls back to a buffered parse when the runtime hands us no readable body.
|
|
111499
|
+
*/
|
|
111500
|
+
async _consumeSse(resp, id) {
|
|
111501
|
+
const state = { have: false };
|
|
111502
|
+
const handle2 = (msg) => {
|
|
111503
|
+
if (typeof msg.method === "string" && msg.id != null) {
|
|
111504
|
+
this._answerServerRequest(msg.id, msg.method, msg.params);
|
|
111505
|
+
return;
|
|
111506
|
+
}
|
|
111507
|
+
if (msg.id !== id)
|
|
111508
|
+
return;
|
|
110850
111509
|
if (msg.error)
|
|
110851
|
-
|
|
110852
|
-
|
|
111510
|
+
state.failure = new Error(`MCP error ${msg.error.code}: ${msg.error.message}`);
|
|
111511
|
+
else {
|
|
111512
|
+
state.result = msg.result ?? null;
|
|
111513
|
+
state.have = true;
|
|
111514
|
+
}
|
|
110853
111515
|
};
|
|
110854
|
-
|
|
110855
|
-
|
|
110856
|
-
|
|
111516
|
+
const body = resp.body;
|
|
111517
|
+
if (body && typeof body[Symbol.asyncIterator] === "function") {
|
|
111518
|
+
let buf = "";
|
|
111519
|
+
const dataLines = [];
|
|
111520
|
+
const flush = () => {
|
|
110857
111521
|
if (!dataLines.length)
|
|
111522
|
+
return;
|
|
111523
|
+
const data = dataLines.join("\n");
|
|
111524
|
+
dataLines.length = 0;
|
|
111525
|
+
try {
|
|
111526
|
+
handle2(JSON.parse(data));
|
|
111527
|
+
} catch {
|
|
111528
|
+
}
|
|
111529
|
+
};
|
|
111530
|
+
try {
|
|
111531
|
+
for await (const chunk of body) {
|
|
111532
|
+
buf += Buffer.from(chunk).toString("utf-8");
|
|
111533
|
+
let nl;
|
|
111534
|
+
while ((nl = buf.indexOf("\n")) !== -1) {
|
|
111535
|
+
let line = buf.slice(0, nl);
|
|
111536
|
+
buf = buf.slice(nl + 1);
|
|
111537
|
+
if (line.endsWith("\r"))
|
|
111538
|
+
line = line.slice(0, -1);
|
|
111539
|
+
if (!line) {
|
|
111540
|
+
flush();
|
|
111541
|
+
if (state.have || state.failure)
|
|
111542
|
+
break;
|
|
111543
|
+
continue;
|
|
111544
|
+
}
|
|
111545
|
+
if (line.startsWith("data:"))
|
|
111546
|
+
dataLines.push(line.slice(5).replace(/^ /, ""));
|
|
111547
|
+
}
|
|
111548
|
+
if (state.have || state.failure)
|
|
111549
|
+
break;
|
|
111550
|
+
}
|
|
111551
|
+
flush();
|
|
111552
|
+
} catch {
|
|
111553
|
+
}
|
|
111554
|
+
try {
|
|
111555
|
+
await body.cancel?.();
|
|
111556
|
+
} catch {
|
|
111557
|
+
}
|
|
111558
|
+
} else {
|
|
111559
|
+
const text = await resp.text();
|
|
111560
|
+
for (const frame of text.split(/\r?\n\r?\n/)) {
|
|
111561
|
+
const data = frame.split(/\r?\n/).filter((l2) => l2.startsWith("data:")).map((l2) => l2.slice(5).trim()).join("\n");
|
|
111562
|
+
if (!data)
|
|
110858
111563
|
continue;
|
|
110859
111564
|
try {
|
|
110860
|
-
|
|
110861
|
-
if (msg.id === id)
|
|
110862
|
-
return consume(msg);
|
|
111565
|
+
handle2(JSON.parse(data));
|
|
110863
111566
|
} catch {
|
|
110864
111567
|
}
|
|
110865
111568
|
}
|
|
110866
|
-
throw new Error("No matching JSON-RPC response found in SSE stream");
|
|
110867
111569
|
}
|
|
110868
|
-
|
|
111570
|
+
if (state.failure)
|
|
111571
|
+
throw state.failure;
|
|
111572
|
+
if (!state.have)
|
|
111573
|
+
throw new Error("No matching JSON-RPC response found in SSE stream");
|
|
111574
|
+
return state.result;
|
|
111575
|
+
}
|
|
111576
|
+
/** Reply to a server→client request. Fire-and-forget: the in-flight reader must not block. */
|
|
111577
|
+
_answerServerRequest(id, method, params) {
|
|
111578
|
+
void (async () => {
|
|
111579
|
+
const reply = await (0, client_1.serverRequestReply)(this.name, this._elicitationHandler, method, params);
|
|
111580
|
+
await this._post({ jsonrpc: "2.0", id, ...reply });
|
|
111581
|
+
})().catch(() => {
|
|
111582
|
+
});
|
|
110869
111583
|
}
|
|
110870
111584
|
};
|
|
110871
111585
|
exports2.McpHttpClient = McpHttpClient;
|
|
@@ -110897,18 +111611,22 @@ var require_sseClient = __commonJS({
|
|
|
110897
111611
|
this._closed = false;
|
|
110898
111612
|
this._pending = /* @__PURE__ */ new Map();
|
|
110899
111613
|
this._endpointWaiter = null;
|
|
111614
|
+
this._elicitationHandler = null;
|
|
110900
111615
|
this.name = name;
|
|
110901
111616
|
}
|
|
110902
111617
|
get tools() {
|
|
110903
111618
|
return this._tools;
|
|
110904
111619
|
}
|
|
111620
|
+
setElicitationHandler(handler) {
|
|
111621
|
+
this._elicitationHandler = handler;
|
|
111622
|
+
}
|
|
110905
111623
|
async connect() {
|
|
110906
111624
|
if (!this.config.url)
|
|
110907
111625
|
throw new Error(`MCP server "${this.name}" has no url (sse transport requires one).`);
|
|
110908
111626
|
await this._openStream();
|
|
110909
111627
|
await this._rpc("initialize", {
|
|
110910
111628
|
protocolVersion: "2024-11-05",
|
|
110911
|
-
capabilities:
|
|
111629
|
+
capabilities: (0, client_1.elicitationCapability)(this.config.bareElicitationCapability),
|
|
110912
111630
|
clientInfo: { name: "nexrall-code", version: "1.0" }
|
|
110913
111631
|
});
|
|
110914
111632
|
await this._notify("notifications/initialized");
|
|
@@ -111061,6 +111779,17 @@ var require_sseClient = __commonJS({
|
|
|
111061
111779
|
} catch {
|
|
111062
111780
|
return;
|
|
111063
111781
|
}
|
|
111782
|
+
if (typeof msg.method === "string" && msg.id != null) {
|
|
111783
|
+
const method = msg.method;
|
|
111784
|
+
const params = msg.params;
|
|
111785
|
+
const reqId = msg.id;
|
|
111786
|
+
void (async () => {
|
|
111787
|
+
const reply = await (0, client_1.serverRequestReply)(this.name, this._elicitationHandler, method, params);
|
|
111788
|
+
await this._postMessage({ jsonrpc: "2.0", id: reqId, ...reply });
|
|
111789
|
+
})().catch(() => {
|
|
111790
|
+
});
|
|
111791
|
+
return;
|
|
111792
|
+
}
|
|
111064
111793
|
if (typeof msg.id === "number" && this._pending.has(msg.id)) {
|
|
111065
111794
|
const { resolve: resolve12, reject, timer } = this._pending.get(msg.id);
|
|
111066
111795
|
clearTimeout(timer);
|
|
@@ -111069,6 +111798,7 @@ var require_sseClient = __commonJS({
|
|
|
111069
111798
|
reject(new Error(`MCP error ${msg.error.code}: ${msg.error.message}`));
|
|
111070
111799
|
else
|
|
111071
111800
|
resolve12(msg.result ?? null);
|
|
111801
|
+
return;
|
|
111072
111802
|
}
|
|
111073
111803
|
}
|
|
111074
111804
|
_rpc(method, params) {
|
|
@@ -111290,6 +112020,17 @@ var require_manager = __commonJS({
|
|
|
111290
112020
|
this._needsAuth = /* @__PURE__ */ new Map();
|
|
111291
112021
|
this._disabled = /* @__PURE__ */ new Set();
|
|
111292
112022
|
this.stats = new stats_1.ToolStats();
|
|
112023
|
+
this._elicitationHandler = null;
|
|
112024
|
+
}
|
|
112025
|
+
/**
|
|
112026
|
+
* Route every server's elicitation (`elicitation/create`) through this handler —
|
|
112027
|
+
* including servers that connect later, which is why it is also re-applied in
|
|
112028
|
+
* connectAll/enable. Pass null to restore auto-decline.
|
|
112029
|
+
*/
|
|
112030
|
+
setElicitationHandler(handler) {
|
|
112031
|
+
this._elicitationHandler = handler;
|
|
112032
|
+
for (const client of this._clients.values())
|
|
112033
|
+
client.setElicitationHandler(handler);
|
|
111293
112034
|
}
|
|
111294
112035
|
/** Pick the transport for a server config: stdio (command), Streamable HTTP, or legacy SSE. */
|
|
111295
112036
|
static makeClient(name, cfg) {
|
|
@@ -111335,6 +112076,7 @@ var require_manager = __commonJS({
|
|
|
111335
112076
|
return;
|
|
111336
112077
|
}
|
|
111337
112078
|
const client = _McpManager.makeClient(name, serverCfg);
|
|
112079
|
+
client.setElicitationHandler(this._elicitationHandler);
|
|
111338
112080
|
try {
|
|
111339
112081
|
await client.connect();
|
|
111340
112082
|
this._clients.set(name, client);
|
|
@@ -111594,6 +112336,7 @@ var require_manager = __commonJS({
|
|
|
111594
112336
|
return `no server named "${name}" is configured`;
|
|
111595
112337
|
this._dropClient(name);
|
|
111596
112338
|
const client = _McpManager.makeClient(name, cfg);
|
|
112339
|
+
client.setElicitationHandler(this._elicitationHandler);
|
|
111597
112340
|
try {
|
|
111598
112341
|
await client.connect();
|
|
111599
112342
|
} catch (err) {
|
|
@@ -152779,6 +153522,14 @@ function checkPartialMessages(f3) {
|
|
|
152779
153522
|
}
|
|
152780
153523
|
return null;
|
|
152781
153524
|
}
|
|
153525
|
+
function checkHookEvents(f3) {
|
|
153526
|
+
if (!f3.includeHookEvents)
|
|
153527
|
+
return null;
|
|
153528
|
+
if (f3.outputFormat !== "stream-json") {
|
|
153529
|
+
return "--include-hook-events needs --output-format stream-json (hook lifecycle events are part of the JSON stream).";
|
|
153530
|
+
}
|
|
153531
|
+
return null;
|
|
153532
|
+
}
|
|
152782
153533
|
function checkReplayUserMessages(f3) {
|
|
152783
153534
|
if (!f3.replay)
|
|
152784
153535
|
return null;
|
|
@@ -152809,6 +153560,29 @@ function initEventPayload(i2) {
|
|
|
152809
153560
|
function userReplayPayload(text) {
|
|
152810
153561
|
return { type: "user", message: { role: "user", content: [{ type: "text", text }] } };
|
|
152811
153562
|
}
|
|
153563
|
+
function hookEventPayload(e2) {
|
|
153564
|
+
const base = {
|
|
153565
|
+
type: "system",
|
|
153566
|
+
subtype: `hook_${e2.kind}`,
|
|
153567
|
+
hook_id: e2.hookId,
|
|
153568
|
+
hook_name: e2.hookName,
|
|
153569
|
+
hook_event: e2.hookEvent,
|
|
153570
|
+
uuid: e2.uuid,
|
|
153571
|
+
session_id: e2.sessionId
|
|
153572
|
+
};
|
|
153573
|
+
if (e2.kind === "started")
|
|
153574
|
+
return base;
|
|
153575
|
+
if (e2.kind === "progress")
|
|
153576
|
+
return { ...base, stdout: e2.stdout ?? "", stderr: e2.stderr ?? "", output: e2.output ?? "" };
|
|
153577
|
+
return {
|
|
153578
|
+
...base,
|
|
153579
|
+
output: e2.output ?? "",
|
|
153580
|
+
stdout: e2.stdout ?? "",
|
|
153581
|
+
stderr: e2.stderr ?? "",
|
|
153582
|
+
...e2.exitCode !== void 0 ? { exit_code: e2.exitCode } : {},
|
|
153583
|
+
outcome: e2.outcome ?? "error"
|
|
153584
|
+
};
|
|
153585
|
+
}
|
|
152812
153586
|
function parseAgentsArg(raw, cwd2) {
|
|
152813
153587
|
if (raw === void 0)
|
|
152814
153588
|
return { ok: true, value: [] };
|
|
@@ -155286,7 +156060,7 @@ import * as os18 from "os";
|
|
|
155286
156060
|
import * as crypto7 from "crypto";
|
|
155287
156061
|
import { createRequire } from "module";
|
|
155288
156062
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
155289
|
-
import {
|
|
156063
|
+
import { execFile as execFile2, execFileSync as execFileSync5 } from "child_process";
|
|
155290
156064
|
|
|
155291
156065
|
// src/permissions/handler.ts
|
|
155292
156066
|
import * as readline2 from "readline";
|
|
@@ -156268,6 +157042,117 @@ function currentAudit() {
|
|
|
156268
157042
|
|
|
156269
157043
|
// src/commands/chat.ts
|
|
156270
157044
|
var import_code_core19 = __toESM(require_dist3(), 1);
|
|
157045
|
+
|
|
157046
|
+
// src/ui/mcpElicit.ts
|
|
157047
|
+
function fieldsOf(schema) {
|
|
157048
|
+
const props = schema?.properties ?? {};
|
|
157049
|
+
const required = new Set(Array.isArray(schema?.required) ? schema.required.map(String) : []);
|
|
157050
|
+
return Object.entries(props).map(([name, p]) => ({
|
|
157051
|
+
name,
|
|
157052
|
+
title: typeof p.title === "string" ? p.title : name,
|
|
157053
|
+
description: typeof p.description === "string" ? p.description : void 0,
|
|
157054
|
+
type: typeof p.type === "string" ? p.type : "string",
|
|
157055
|
+
enumValues: Array.isArray(p.enum) ? p.enum : void 0,
|
|
157056
|
+
required: required.has(name)
|
|
157057
|
+
}));
|
|
157058
|
+
}
|
|
157059
|
+
function coerce(raw, type) {
|
|
157060
|
+
if (type === "number" || type === "integer") {
|
|
157061
|
+
const n = type === "integer" ? parseInt(raw, 10) : Number(raw);
|
|
157062
|
+
return Number.isFinite(n) ? { ok: true, value: n } : { ok: false };
|
|
157063
|
+
}
|
|
157064
|
+
return { ok: true, value: raw };
|
|
157065
|
+
}
|
|
157066
|
+
async function elicitForm(server, req, io) {
|
|
157067
|
+
const fields = fieldsOf(req.requestedSchema);
|
|
157068
|
+
io.print(paint.dim(` ${server} asks: ${truncateCells(req.message, 300)}`));
|
|
157069
|
+
if (!fields.length) {
|
|
157070
|
+
const idx = await io.choose({
|
|
157071
|
+
title: `${server} is asking for your confirmation`,
|
|
157072
|
+
// The 'n'-keyed option is what Esc / Ctrl+C resolve to (choiceBox.denyIndex).
|
|
157073
|
+
options: [{ key: "y", label: "Continue" }, { key: "n", label: "Decline" }, { key: "c", label: "Cancel" }]
|
|
157074
|
+
});
|
|
157075
|
+
if (idx < 0)
|
|
157076
|
+
return { action: "decline" };
|
|
157077
|
+
return idx === 0 ? { action: "accept", content: {} } : { action: idx === 1 ? "decline" : "cancel" };
|
|
157078
|
+
}
|
|
157079
|
+
const content = {};
|
|
157080
|
+
for (const f3 of fields) {
|
|
157081
|
+
const label = f3.title + (f3.required ? "" : " (optional)");
|
|
157082
|
+
if (f3.enumValues?.length) {
|
|
157083
|
+
const options = f3.enumValues.map((v, i2) => ({ key: String(i2 + 1), label: String(v) }));
|
|
157084
|
+
options.push({ key: "n", label: "\u2014 decline \u2014" }, { key: "c", label: "\u2014 cancel \u2014" });
|
|
157085
|
+
const idx = await io.choose({ title: `${server}: ${label}`, detail: f3.description, options });
|
|
157086
|
+
if (idx < 0)
|
|
157087
|
+
return { action: "decline" };
|
|
157088
|
+
if (idx === f3.enumValues.length)
|
|
157089
|
+
return { action: "decline" };
|
|
157090
|
+
if (idx === f3.enumValues.length + 1)
|
|
157091
|
+
return { action: "cancel" };
|
|
157092
|
+
content[f3.name] = f3.enumValues[idx];
|
|
157093
|
+
continue;
|
|
157094
|
+
}
|
|
157095
|
+
if (f3.type === "boolean") {
|
|
157096
|
+
const idx = await io.choose({
|
|
157097
|
+
title: `${server}: ${label}`,
|
|
157098
|
+
detail: f3.description,
|
|
157099
|
+
// Esc means "leave the form", NOT "answer false" — a silent wrong answer is worse
|
|
157100
|
+
// than a dismissal, so 'n' is the decline sentinel here too.
|
|
157101
|
+
options: [
|
|
157102
|
+
{ key: "y", label: "Yes" },
|
|
157103
|
+
{ key: "f", label: "No" },
|
|
157104
|
+
{ key: "n", label: "\u2014 decline \u2014" },
|
|
157105
|
+
{ key: "c", label: "\u2014 cancel \u2014" }
|
|
157106
|
+
]
|
|
157107
|
+
});
|
|
157108
|
+
if (idx < 0 || idx === 2)
|
|
157109
|
+
return { action: "decline" };
|
|
157110
|
+
if (idx === 3)
|
|
157111
|
+
return { action: "cancel" };
|
|
157112
|
+
content[f3.name] = idx === 0;
|
|
157113
|
+
continue;
|
|
157114
|
+
}
|
|
157115
|
+
const raw = (await io.line(` ${server}: ${label}${f3.description ? ` \u2014 ${f3.description}` : ""}: `)).trim();
|
|
157116
|
+
if (!raw) {
|
|
157117
|
+
if (f3.required)
|
|
157118
|
+
return { action: "decline" };
|
|
157119
|
+
continue;
|
|
157120
|
+
}
|
|
157121
|
+
const c = coerce(raw, f3.type);
|
|
157122
|
+
if (!c.ok) {
|
|
157123
|
+
io.print(paint.yellow(` ${server}: "${raw}" is not a ${f3.type} \u2014 declining.`));
|
|
157124
|
+
return { action: "decline" };
|
|
157125
|
+
}
|
|
157126
|
+
content[f3.name] = c.value;
|
|
157127
|
+
}
|
|
157128
|
+
return { action: "accept", content };
|
|
157129
|
+
}
|
|
157130
|
+
async function elicitUrl(server, req, io) {
|
|
157131
|
+
if (!req.url)
|
|
157132
|
+
return { action: "decline" };
|
|
157133
|
+
io.print(paint.dim(` ${server} asks: ${truncateCells(req.message, 300)}`));
|
|
157134
|
+
const idx = await io.choose({
|
|
157135
|
+
title: `${server} needs you to open a page`,
|
|
157136
|
+
detail: truncateCells(req.url, 120),
|
|
157137
|
+
options: [{ key: "o", label: "Open in browser" }, { key: "n", label: "Decline" }, { key: "c", label: "Cancel" }]
|
|
157138
|
+
});
|
|
157139
|
+
if (idx < 0)
|
|
157140
|
+
return { action: "decline" };
|
|
157141
|
+
if (idx === 0) {
|
|
157142
|
+
io.openUrl(req.url);
|
|
157143
|
+
return { action: "accept" };
|
|
157144
|
+
}
|
|
157145
|
+
return { action: idx === 1 ? "decline" : "cancel" };
|
|
157146
|
+
}
|
|
157147
|
+
async function elicit(server, req, io) {
|
|
157148
|
+
try {
|
|
157149
|
+
return req.mode === "url" ? await elicitUrl(server, req, io) : await elicitForm(server, req, io);
|
|
157150
|
+
} catch {
|
|
157151
|
+
return { action: "decline" };
|
|
157152
|
+
}
|
|
157153
|
+
}
|
|
157154
|
+
|
|
157155
|
+
// src/commands/chat.ts
|
|
156271
157156
|
var import_code_core20 = __toESM(require_dist3(), 1);
|
|
156272
157157
|
|
|
156273
157158
|
// src/debugLog.ts
|
|
@@ -172348,12 +173233,16 @@ function resolveModelLabel(alias) {
|
|
|
172348
173233
|
const id = normaliseModelId(alias);
|
|
172349
173234
|
return (0, import_code_core18.liveLabelFor)(id, MODEL_LABELS[id] ?? id);
|
|
172350
173235
|
}
|
|
172351
|
-
function
|
|
172352
|
-
|
|
172353
|
-
|
|
172354
|
-
|
|
172355
|
-
|
|
172356
|
-
|
|
173236
|
+
async function tryExecAsync(file, args, cwd2) {
|
|
173237
|
+
return new Promise((resolve12) => {
|
|
173238
|
+
try {
|
|
173239
|
+
execFile2(file, args, { cwd: cwd2, encoding: "utf-8" }, (err, stdout) => {
|
|
173240
|
+
resolve12(err ? void 0 : String(stdout).trim() || void 0);
|
|
173241
|
+
});
|
|
173242
|
+
} catch {
|
|
173243
|
+
resolve12(void 0);
|
|
173244
|
+
}
|
|
173245
|
+
});
|
|
172357
173246
|
}
|
|
172358
173247
|
var BILLING_URL = "https://app.nexrall.com/?settings=billing";
|
|
172359
173248
|
function hyperlink(label, url) {
|
|
@@ -172381,28 +173270,29 @@ function currentUserLabel() {
|
|
|
172381
173270
|
return "there";
|
|
172382
173271
|
}
|
|
172383
173272
|
}
|
|
172384
|
-
function collectEnv(workDir) {
|
|
173273
|
+
async function collectEnv(workDir) {
|
|
172385
173274
|
return {
|
|
172386
173275
|
cwd: workDir,
|
|
172387
173276
|
platform: `${os18.platform()} ${os18.release()}`,
|
|
172388
173277
|
shell: process.env.SHELL ?? process.env.ComSpec ?? "unknown",
|
|
172389
173278
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
172390
|
-
...collectGitEnv(workDir)
|
|
173279
|
+
...await collectGitEnv(workDir)
|
|
172391
173280
|
};
|
|
172392
173281
|
}
|
|
172393
|
-
function collectGitEnv(workDir) {
|
|
172394
|
-
|
|
172395
|
-
|
|
172396
|
-
|
|
172397
|
-
|
|
172398
|
-
|
|
172399
|
-
|
|
173282
|
+
async function collectGitEnv(workDir) {
|
|
173283
|
+
const [gitBranch2, gitStatus, gitDiff, recentCommits] = await Promise.all([
|
|
173284
|
+
tryExecAsync("git", ["branch", "--show-current"], workDir),
|
|
173285
|
+
tryExecAsync("git", ["status", "--short"], workDir),
|
|
173286
|
+
tryExecAsync("git", ["diff", "--stat", "HEAD"], workDir),
|
|
173287
|
+
tryExecAsync("git", ["log", "--oneline", "-5"], workDir)
|
|
173288
|
+
]);
|
|
173289
|
+
return { gitBranch: gitBranch2, gitStatus, gitDiff, recentCommits };
|
|
172400
173290
|
}
|
|
172401
|
-
function refreshEnvForTurn(env4, workDir) {
|
|
173291
|
+
async function refreshEnvForTurn(env4, workDir) {
|
|
172402
173292
|
return {
|
|
172403
173293
|
...env4,
|
|
172404
173294
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
172405
|
-
...collectGitEnv(workDir)
|
|
173295
|
+
...await collectGitEnv(workDir)
|
|
172406
173296
|
};
|
|
172407
173297
|
}
|
|
172408
173298
|
var noDiscovery = false;
|
|
@@ -172586,6 +173476,10 @@ var Spinner = class {
|
|
|
172586
173476
|
verbIdx = 0;
|
|
172587
173477
|
thinkTokens = 0;
|
|
172588
173478
|
thinkText = "";
|
|
173479
|
+
// A running hook's `statusMessage` (Claude Code). While set it REPLACES the label —
|
|
173480
|
+
// the whole point is telling the user which hook is producing the wait — and the
|
|
173481
|
+
// normal label returns the moment the hook finishes (listener sends null).
|
|
173482
|
+
hookStatus = "";
|
|
172589
173483
|
start(text, opts) {
|
|
172590
173484
|
this.stop();
|
|
172591
173485
|
this.baseText = text;
|
|
@@ -172640,13 +173534,24 @@ var Spinner = class {
|
|
|
172640
173534
|
return;
|
|
172641
173535
|
this.baseText = text;
|
|
172642
173536
|
}
|
|
173537
|
+
/**
|
|
173538
|
+
* A hook with `statusMessage` started (message) or finished (null). Renders immediately
|
|
173539
|
+
* rather than on the next tick: the whole point of the message is that a long hook is
|
|
173540
|
+
* RUNNING, and waiting up to 100ms to admit that is the kind of silence it exists to fix.
|
|
173541
|
+
* No-op while the spinner is stopped — an idle session keeps its prompt, not a status line.
|
|
173542
|
+
*/
|
|
173543
|
+
setHookStatus(message) {
|
|
173544
|
+
this.hookStatus = message ?? "";
|
|
173545
|
+
if (this.interval !== null)
|
|
173546
|
+
this.render();
|
|
173547
|
+
}
|
|
172643
173548
|
render() {
|
|
172644
173549
|
const elapsedSec = Math.floor((Date.now() - this.startedAt) / 1e3);
|
|
172645
173550
|
if (this.verbs && elapsedSec > 0 && elapsedSec % VERB_ROTATE_SEC === 0 && this.lastRotateSec !== elapsedSec) {
|
|
172646
173551
|
this.lastRotateSec = elapsedSec;
|
|
172647
173552
|
this.verbIdx++;
|
|
172648
173553
|
}
|
|
172649
|
-
const label = this.verbs ? `${WORKING_VERBS[this.verbIdx % WORKING_VERBS.length]}\u2026` : this.baseText;
|
|
173554
|
+
const label = this.hookStatus || (this.verbs ? `${WORKING_VERBS[this.verbIdx % WORKING_VERBS.length]}\u2026` : this.baseText);
|
|
172650
173555
|
const status = composeStatusLine({
|
|
172651
173556
|
frame: this.frames[this.i % this.frames.length],
|
|
172652
173557
|
text: label,
|
|
@@ -172689,12 +173594,14 @@ function nextBackgroundChange() {
|
|
|
172689
173594
|
}
|
|
172690
173595
|
var _mcpManager = null;
|
|
172691
173596
|
var _askIO = null;
|
|
173597
|
+
var _elicitationHandler = null;
|
|
172692
173598
|
var _mcpConfig = null;
|
|
172693
173599
|
var sessionTouched = [];
|
|
172694
173600
|
async function initMcp(workDir, override, strict) {
|
|
172695
173601
|
if (noDiscovery && !override) {
|
|
172696
173602
|
_mcpConfig = { mcpServers: {} };
|
|
172697
173603
|
_mcpManager = null;
|
|
173604
|
+
wireHookMcpCaller();
|
|
172698
173605
|
return;
|
|
172699
173606
|
}
|
|
172700
173607
|
_mcpConfig = strict && override ? { mcpServers: {} } : import_code_core18.McpManager.loadConfig(workDir);
|
|
@@ -172702,6 +173609,7 @@ async function initMcp(workDir, override, strict) {
|
|
|
172702
173609
|
Object.assign(_mcpConfig.mcpServers, override.mcpServers);
|
|
172703
173610
|
if (Object.keys(_mcpConfig.mcpServers).length === 0) {
|
|
172704
173611
|
_mcpManager = null;
|
|
173612
|
+
wireHookMcpCaller();
|
|
172705
173613
|
return;
|
|
172706
173614
|
}
|
|
172707
173615
|
try {
|
|
@@ -172709,8 +173617,48 @@ async function initMcp(workDir, override, strict) {
|
|
|
172709
173617
|
} catch {
|
|
172710
173618
|
}
|
|
172711
173619
|
const manager = new import_code_core18.McpManager();
|
|
173620
|
+
manager.setElicitationHandler(_elicitationHandler);
|
|
172712
173621
|
await manager.connectAll(_mcpConfig);
|
|
172713
173622
|
_mcpManager = manager;
|
|
173623
|
+
wireHookMcpCaller();
|
|
173624
|
+
}
|
|
173625
|
+
function wireHookMcpCaller() {
|
|
173626
|
+
const mgr = _mcpManager;
|
|
173627
|
+
if (!mgr) {
|
|
173628
|
+
(0, import_code_core19.setHookMcpCaller)(null);
|
|
173629
|
+
return;
|
|
173630
|
+
}
|
|
173631
|
+
(0, import_code_core19.setHookMcpCaller)(async (server, tool, input) => {
|
|
173632
|
+
const text = await mgr.callTool(`${server}__${tool}`, input);
|
|
173633
|
+
return text === null ? { error: `MCP server "${server}" has no tool "${tool}" (or the server is not connected)` } : { text };
|
|
173634
|
+
});
|
|
173635
|
+
}
|
|
173636
|
+
async function handleElicitation(server, req, workDir, getSessionId, interactive) {
|
|
173637
|
+
const hookAnswer = await (0, import_code_core19.runElicitationHooks)(workDir, server, {
|
|
173638
|
+
message: req.message,
|
|
173639
|
+
mode: req.mode,
|
|
173640
|
+
url: req.url,
|
|
173641
|
+
elicitation_id: req.elicitationId,
|
|
173642
|
+
requested_schema: req.requestedSchema
|
|
173643
|
+
}, getSessionId());
|
|
173644
|
+
let answer;
|
|
173645
|
+
if (hookAnswer)
|
|
173646
|
+
answer = hookAnswer;
|
|
173647
|
+
else if (!interactive || !_askIO)
|
|
173648
|
+
answer = { action: "decline" };
|
|
173649
|
+
else {
|
|
173650
|
+
answer = await elicit(server, req, {
|
|
173651
|
+
choose: _askIO.choose,
|
|
173652
|
+
line: _askIO.line,
|
|
173653
|
+
print: (t2) => console.log(t2),
|
|
173654
|
+
openUrl: (url) => openInBrowser(url)
|
|
173655
|
+
});
|
|
173656
|
+
}
|
|
173657
|
+
return await (0, import_code_core19.runElicitationResultHooks)(workDir, server, answer, {
|
|
173658
|
+
sessionId: getSessionId(),
|
|
173659
|
+
mode: req.mode,
|
|
173660
|
+
elicitationId: req.elicitationId
|
|
173661
|
+
});
|
|
172714
173662
|
}
|
|
172715
173663
|
function formatAgentsList(workDir) {
|
|
172716
173664
|
const { types: types3, warnings } = (0, import_code_core18.loadAgentTypesWithWarnings)(workDir);
|
|
@@ -173086,6 +174034,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
173086
174034
|
const turnStart = Date.now();
|
|
173087
174035
|
userActiveThisTurn = false;
|
|
173088
174036
|
const spinner = new Spinner();
|
|
174037
|
+
(0, import_code_core19.setHookStatusListener)((m2) => spinner.setHookStatus(m2));
|
|
173089
174038
|
const mdRender = new MarkdownStreamRenderer();
|
|
173090
174039
|
const toolStream = new ToolStreamPrinter(PREVIEW_LINES);
|
|
173091
174040
|
let toolStartTime = 0;
|
|
@@ -173112,7 +174061,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
173112
174061
|
workDir,
|
|
173113
174062
|
sessionId: activeSessionIdGetter(),
|
|
173114
174063
|
model: modelAlias,
|
|
173115
|
-
env: refreshEnvForTurn(env4, workDir),
|
|
174064
|
+
env: await refreshEnvForTurn(env4, workDir),
|
|
173116
174065
|
nexrallMd,
|
|
173117
174066
|
mode,
|
|
173118
174067
|
// `/mode plan` previously only hinted to the backend — the footer said "plan
|
|
@@ -173465,7 +174414,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
173465
174414
|
workDir,
|
|
173466
174415
|
sessionId: activeSessionIdGetter(),
|
|
173467
174416
|
model: modelAlias,
|
|
173468
|
-
env: refreshEnvForTurn(env4, workDir),
|
|
174417
|
+
env: await refreshEnvForTurn(env4, workDir),
|
|
173469
174418
|
nexrallMd,
|
|
173470
174419
|
mode,
|
|
173471
174420
|
planMode: mode === "plan",
|
|
@@ -173991,7 +174940,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
173991
174940
|
void (0, import_code_core19.fireObserverHook)(requestedWorkDir, "WorktreeRemove", { name: worktreeState.name, path: worktreeState.worktreePath }, worktreeState.name);
|
|
173992
174941
|
});
|
|
173993
174942
|
}
|
|
173994
|
-
const env4 = collectEnv(workDir);
|
|
174943
|
+
const env4 = await collectEnv(workDir);
|
|
173995
174944
|
let briefBase = options.systemPrompt?.trim() ?? readNexrallMd(workDir);
|
|
173996
174945
|
const agentPrefix = options.selectedAgent?.prompt?.trim();
|
|
173997
174946
|
const briefParts = [agentPrefix, briefBase, options.appendSystemPrompt?.trim(), addDirNote(options.addDirs ?? []), options.jsonSchema ? schemaInstruction(options.jsonSchema) : ""];
|
|
@@ -174005,6 +174954,13 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
174005
174954
|
_headlessPolicy.verbose = !!options.verbose;
|
|
174006
174955
|
_headlessPolicy.includePartial = !!options.includePartialMessages;
|
|
174007
174956
|
_headlessPolicy.permissionMode = String(options.initialMode ?? "");
|
|
174957
|
+
const streamHookEvents = options.outputFormat === "stream-json";
|
|
174958
|
+
const allHookEvents = !!options.includeHookEvents;
|
|
174959
|
+
(0, import_code_core19.setHookEventListener)(streamHookEvents ? (evt) => {
|
|
174960
|
+
if (!allHookEvents && evt.hookEvent !== "SessionStart" && evt.hookEvent !== "Setup")
|
|
174961
|
+
return;
|
|
174962
|
+
process.stdout.write(JSON.stringify(hookEventPayload({ ...evt, sessionId: activeSessionIdGetter() ?? "", uuid: crypto7.randomUUID() })) + "\n");
|
|
174963
|
+
} : null);
|
|
174008
174964
|
const saveSession2 = options.noSessionPersistence ? () => {
|
|
174009
174965
|
} : saveSession;
|
|
174010
174966
|
const interactive = !headless && !options.prompt && !options.stdinText;
|
|
@@ -174127,6 +175083,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
174127
175083
|
setExcludedPatterns(contextSet.excluded);
|
|
174128
175084
|
console.log((edit.ok ? paint.green : paint.yellow)(" " + edit.message));
|
|
174129
175085
|
};
|
|
175086
|
+
_elicitationHandler = (server, req) => handleElicitation(server, req, workDir, () => sessionId, interactive);
|
|
174130
175087
|
const mcpStarted = (async () => {
|
|
174131
175088
|
try {
|
|
174132
175089
|
await initMcp(workDir, options.mcpOverride, options.strictMcp);
|
|
@@ -175114,6 +176071,7 @@ ${text}` : "");
|
|
|
175114
176071
|
activeGoal = null;
|
|
175115
176072
|
criteriaLastLine = "";
|
|
175116
176073
|
cliBackgroundAgents.stopAll({ dropPending: true });
|
|
176074
|
+
(0, import_code_core19.resetHookOnceState)();
|
|
175117
176075
|
inputBuffer = "";
|
|
175118
176076
|
if (interactive)
|
|
175119
176077
|
await getInkTerminal().clearTranscript();
|
|
@@ -175320,7 +176278,7 @@ ${summaryText}` }] },
|
|
|
175320
176278
|
}
|
|
175321
176279
|
const readme = tryRead(path29.join(workDir, "README.md"))?.slice(0, 2e3) ?? "";
|
|
175322
176280
|
const pkgJson = tryRead(path29.join(workDir, "package.json"))?.slice(0, 1e3) ?? "";
|
|
175323
|
-
const dirList =
|
|
176281
|
+
const dirList = (await tryExecAsync("ls", ["-la"], workDir))?.slice(0, 500) ?? "";
|
|
175324
176282
|
const initPrompt = `Analyze this project and write a concise nexrall.md (project-specific instructions for an AI coding assistant).
|
|
175325
176283
|
Include: project overview, tech stack, coding conventions, important files/folders, what to avoid.
|
|
175326
176284
|
Keep it under 400 words. Use markdown. Be specific and actionable.
|
|
@@ -177246,6 +178204,7 @@ ${text}
|
|
|
177246
178204
|
rl.resume();
|
|
177247
178205
|
rl.prompt();
|
|
177248
178206
|
deliverBackgroundWhenIdle();
|
|
178207
|
+
deliverHookWakeWhenIdle();
|
|
177249
178208
|
});
|
|
177250
178209
|
async function runGoalLoop() {
|
|
177251
178210
|
while (activeGoal) {
|
|
@@ -177326,6 +178285,20 @@ ${text}
|
|
|
177326
178285
|
bgLastCount = n;
|
|
177327
178286
|
deliverBackgroundWhenIdle();
|
|
177328
178287
|
});
|
|
178288
|
+
let hookWakeTimer = null;
|
|
178289
|
+
function deliverHookWakeWhenIdle() {
|
|
178290
|
+
if (hookWakeTimer || agentRunning || !(0, import_code_core19.hasPendingHookWake)())
|
|
178291
|
+
return;
|
|
178292
|
+
hookWakeTimer = setTimeout(() => {
|
|
178293
|
+
hookWakeTimer = null;
|
|
178294
|
+
if (agentRunning || !(0, import_code_core19.hasPendingHookWake)())
|
|
178295
|
+
return;
|
|
178296
|
+
const wakes = (0, import_code_core19.takeHookWakes)();
|
|
178297
|
+
console.log(paint.dim(` \u2699 hook wake \u2014 continuing`));
|
|
178298
|
+
rl.emit("line", (0, import_code_core19.formatHookDeliveries)(wakes));
|
|
178299
|
+
}, 400);
|
|
178300
|
+
}
|
|
178301
|
+
(0, import_code_core19.setHookWakeListener)(deliverHookWakeWhenIdle);
|
|
177329
178302
|
const loopTimer = setInterval(() => {
|
|
177330
178303
|
if (loopScheduler.size === 0)
|
|
177331
178304
|
return;
|
|
@@ -178138,7 +179111,7 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
178138
179111
|
console.log(paint.dim(" nex sessions --events <id> [--json] to follow its event stream"));
|
|
178139
179112
|
console.log();
|
|
178140
179113
|
});
|
|
178141
|
-
program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, --turbo", "Use Claude Sonnet 5.5 (fast)").option("-u, --ultra", "Use Claude Fable 5.1 (most powerful)").option("-y, --yolo", "Auto-approve all tool calls (no permission prompts)").option("-d, --dir <path>", "Set working directory (default: current directory)").option("-m, --model <name>", "Explicit model, e.g. claude-opus-5-5 | gpt-5.4 | gpt-4.1").option("-r, --resume [id]", "Resume last session, or a specific session id").option("-c, --continue", "Continue the latest conversation in this folder").option("--plan", "Start in plan mode (read-only; /mode or Shift+Tab can leave it)").option("--readonly", "Read-only for the whole session: plan mode that cannot be switched off").option("--auto", "Start in auto mode (the default \u2014 edits and commands run without asking)").option("--mode <mode>", "Starting permission mode: ask | edit | auto | plan").option("--fullscreen", "Draw the whole session on the terminal's alternate screen: the transcript re-wraps on resize and PgUp/PgDn page through it (no terminal scrollback while it is on; /fullscreen toggles it)").option("--bg", "Run the prompt in the background (headless); returns a job id. See: nex jobs | logs | attach | kill").option("--debug", "Write request timing, retries and errors to a debug log file").option("--no-color", "Disable colored output (also honours NO_COLOR)").option("-w, --worktree [name]", "Isolate this session in its own worktree \u2014 a separate directory (and, in a git repo, its own branch) so it can never overwrite files another session (or you) are touching in the main checkout. Omit a name for an auto-generated one; pass an existing name to resume that same worktree.").option("-e, --effort <level>", "Thinking effort \u2014 real levels depend on the model (e.g. DeepSeek: low|high|max, Qwen: low|high); run `nex --model <id>` then `/effort` with no argument to see a model's scale").option("--no-banner", "Skip the ASCII banner (useful in scripts/pipes)").option("--print", "One-shot, non-interactive run that prints the answer and exits (same as --output-format text). Claude Code's `-p` is spelled --print here because `-p` already means --pro").option("--output-format <fmt>", "One-shot output format: text | json | stream-json (implies auto-approve)").option("--audit [path]", "Log every tool call (and refusal) to a JSONL trail (default: .nexrall/audit/<session>.jsonl)").option("--permission-mode <mode>", "Permission mode: ask | edit | auto | plan (also Claude Code names: default | acceptEdits | dontAsk | bypassPermissions). With --output-format, anything that would prompt is DENIED instead of auto-approved").option("--allowedTools, --allowed-tools <tools...>", 'Tools/rules to allow without asking, e.g. "Bash(git *)" Edit (comma or space separated; put the prompt BEFORE this flag)').option("--disallowedTools, --disallowed-tools <tools...>", 'Tools/rules to deny, e.g. "Bash(rm *)" (deny always wins)').option("--append-system-prompt <text>", "Extra instructions appended to the project brief for this run").option("--max-budget-usd <amount>", "Stop a one-shot run once it has spent this many dollars (needs --output-format)").option("--mcp-config <configs...>", 'Load MCP servers from JSON files or inline JSON ({"mcpServers":{\u2026}}) for this run').option("--strict-mcp-config", "With --mcp-config: use ONLY those servers, ignoring ~/.nexrall/mcp.json and the project one").option("--add-dir <dirs...>", "Extra directories the agent may read and edit besides the project folder").option("--input-format <format>", "text (default) | stream-json \u2014 read the prompt as Claude-Code-style NDJSON user messages on stdin").option("--json-schema <schema>", 'JSON Schema (inline or file) the final answer must satisfy; needs --output-format. Result gains "structured_output"; exit 3 if it does not validate').option("--no-session-persistence", "Do not save this run to disk (needs --output-format; it cannot be resumed)").option("--max-turns <n>", "Stop a headless run after N agent rounds (needs --output-format; exit 4 when it hits the limit)").option("--permission-prompt-tool <t>", "MCP tool (mcp__server__tool) that answers permission prompts in non-interactive runs \u2014 instead of nex denying them").option("--append-system-prompt-file <path>", "Like --append-system-prompt, read from a file").option("--system-prompt <text>", "REPLACE the project brief (nexrall.md + memory + global instructions) with this text for this run").option("--system-prompt-file <path>", "Like --system-prompt, read from a file").option("--verbose", "Print progress detail (tool calls, timings, usage) to stderr while a one-shot run works").option("--include-partial-messages", "Stream model deltas as they arrive (needs --output-format stream-json)").option("--replay-user-messages", "Echo each stdin message back on stdout as it is consumed (needs --input-format stream-json --output-format stream-json)").option("--agents <json-or-file>", 'Define extra sub-agents for this run: a JSON object { "name": { "description", "prompt", "tools", "model" } } or @file.json').option("--agent <name>", "Run this session AS that agent (its prompt, tools and model), from .nexrall/agents, a plugin, --agents or a builtin").option("--bare", "Start without discovery: no nexrall.md/memory, skills, plugins, hooks or MCP config files").option("--safe-mode", "Same as --bare (Claude Code's troubleshooting name)").option("--tools <list>", 'Exactly these built-in tools ("Bash,Read,Edit", "default", or "" for none); the rest are removed, not just unapproved').option("--session-id <id>", "Use this id for a NEW conversation (letters, digits, - _), so a script can find it again").option("-n, --name <name>", "Name the conversation; `nex -r <name>` resumes it by that name").option("--fork-session", "With --resume/--continue: branch into a new session instead of continuing the original").option("--fallback-model <name>", "If the main model is overloaded or unreachable, retry the turn once on this model (needs --output-format)").option("--settings <file|json>", "Settings (permissions, hooks\u2026) for this run only: a JSON file or an inline JSON object; merged over the user/project settings").option("--debug-file <path>", "Write the --debug diagnostics log to this file (implies --debug)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
179114
|
+
program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, --turbo", "Use Claude Sonnet 5.5 (fast)").option("-u, --ultra", "Use Claude Fable 5.1 (most powerful)").option("-y, --yolo", "Auto-approve all tool calls (no permission prompts)").option("-d, --dir <path>", "Set working directory (default: current directory)").option("-m, --model <name>", "Explicit model, e.g. claude-opus-5-5 | gpt-5.4 | gpt-4.1").option("-r, --resume [id]", "Resume last session, or a specific session id").option("-c, --continue", "Continue the latest conversation in this folder").option("--plan", "Start in plan mode (read-only; /mode or Shift+Tab can leave it)").option("--readonly", "Read-only for the whole session: plan mode that cannot be switched off").option("--auto", "Start in auto mode (the default \u2014 edits and commands run without asking)").option("--mode <mode>", "Starting permission mode: ask | edit | auto | plan").option("--fullscreen", "Draw the whole session on the terminal's alternate screen: the transcript re-wraps on resize and PgUp/PgDn page through it (no terminal scrollback while it is on; /fullscreen toggles it)").option("--bg", "Run the prompt in the background (headless); returns a job id. See: nex jobs | logs | attach | kill").option("--debug", "Write request timing, retries and errors to a debug log file").option("--no-color", "Disable colored output (also honours NO_COLOR)").option("-w, --worktree [name]", "Isolate this session in its own worktree \u2014 a separate directory (and, in a git repo, its own branch) so it can never overwrite files another session (or you) are touching in the main checkout. Omit a name for an auto-generated one; pass an existing name to resume that same worktree.").option("-e, --effort <level>", "Thinking effort \u2014 real levels depend on the model (e.g. DeepSeek: low|high|max, Qwen: low|high); run `nex --model <id>` then `/effort` with no argument to see a model's scale").option("--no-banner", "Skip the ASCII banner (useful in scripts/pipes)").option("--print", "One-shot, non-interactive run that prints the answer and exits (same as --output-format text). Claude Code's `-p` is spelled --print here because `-p` already means --pro").option("--output-format <fmt>", "One-shot output format: text | json | stream-json (implies auto-approve)").option("--audit [path]", "Log every tool call (and refusal) to a JSONL trail (default: .nexrall/audit/<session>.jsonl)").option("--permission-mode <mode>", "Permission mode: ask | edit | auto | plan (also Claude Code names: default | acceptEdits | dontAsk | bypassPermissions). With --output-format, anything that would prompt is DENIED instead of auto-approved").option("--allowedTools, --allowed-tools <tools...>", 'Tools/rules to allow without asking, e.g. "Bash(git *)" Edit (comma or space separated; put the prompt BEFORE this flag)').option("--disallowedTools, --disallowed-tools <tools...>", 'Tools/rules to deny, e.g. "Bash(rm *)" (deny always wins)').option("--append-system-prompt <text>", "Extra instructions appended to the project brief for this run").option("--max-budget-usd <amount>", "Stop a one-shot run once it has spent this many dollars (needs --output-format)").option("--mcp-config <configs...>", 'Load MCP servers from JSON files or inline JSON ({"mcpServers":{\u2026}}) for this run').option("--strict-mcp-config", "With --mcp-config: use ONLY those servers, ignoring ~/.nexrall/mcp.json and the project one").option("--add-dir <dirs...>", "Extra directories the agent may read and edit besides the project folder").option("--input-format <format>", "text (default) | stream-json \u2014 read the prompt as Claude-Code-style NDJSON user messages on stdin").option("--json-schema <schema>", 'JSON Schema (inline or file) the final answer must satisfy; needs --output-format. Result gains "structured_output"; exit 3 if it does not validate').option("--no-session-persistence", "Do not save this run to disk (needs --output-format; it cannot be resumed)").option("--max-turns <n>", "Stop a headless run after N agent rounds (needs --output-format; exit 4 when it hits the limit)").option("--permission-prompt-tool <t>", "MCP tool (mcp__server__tool) that answers permission prompts in non-interactive runs \u2014 instead of nex denying them").option("--append-system-prompt-file <path>", "Like --append-system-prompt, read from a file").option("--system-prompt <text>", "REPLACE the project brief (nexrall.md + memory + global instructions) with this text for this run").option("--system-prompt-file <path>", "Like --system-prompt, read from a file").option("--verbose", "Print progress detail (tool calls, timings, usage) to stderr while a one-shot run works").option("--include-partial-messages", "Stream model deltas as they arrive (needs --output-format stream-json)").option("--include-hook-events", "Include hook lifecycle events in the stream-json output (system: hook_started / hook_progress / hook_response)").option("--replay-user-messages", "Echo each stdin message back on stdout as it is consumed (needs --input-format stream-json --output-format stream-json)").option("--agents <json-or-file>", 'Define extra sub-agents for this run: a JSON object { "name": { "description", "prompt", "tools", "model" } } or @file.json').option("--agent <name>", "Run this session AS that agent (its prompt, tools and model), from .nexrall/agents, a plugin, --agents or a builtin").option("--bare", "Start without discovery: no nexrall.md/memory, skills, plugins, hooks or MCP config files").option("--safe-mode", "Same as --bare (Claude Code's troubleshooting name)").option("--tools <list>", 'Exactly these built-in tools ("Bash,Read,Edit", "default", or "" for none); the rest are removed, not just unapproved').option("--session-id <id>", "Use this id for a NEW conversation (letters, digits, - _), so a script can find it again").option("-n, --name <name>", "Name the conversation; `nex -r <name>` resumes it by that name").option("--fork-session", "With --resume/--continue: branch into a new session instead of continuing the original").option("--fallback-model <name>", "If the main model is overloaded or unreachable, retry the turn once on this model (needs --output-format)").option("--settings <file|json>", "Settings (permissions, hooks\u2026) for this run only: a JSON file or an inline JSON object; merged over the user/project settings").option("--debug-file <path>", "Write the --debug diagnostics log to this file (implies --debug)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
178142
179115
|
if (!(0, import_code_core22.isAuthenticated)()) {
|
|
178143
179116
|
console.error("Not logged in. Run: nex auth");
|
|
178144
179117
|
process.exit(1);
|
|
@@ -178410,6 +179383,11 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
178410
179383
|
console.error(partialErr);
|
|
178411
179384
|
process.exit(1);
|
|
178412
179385
|
}
|
|
179386
|
+
const hookEventsErr = checkHookEvents({ includeHookEvents: !!options.includeHookEvents, outputFormat });
|
|
179387
|
+
if (hookEventsErr) {
|
|
179388
|
+
console.error(hookEventsErr);
|
|
179389
|
+
process.exit(1);
|
|
179390
|
+
}
|
|
178413
179391
|
const replayErr = checkReplayUserMessages({ replay: !!options.replayUserMessages, inputFormat: options.inputFormat, outputFormat });
|
|
178414
179392
|
if (replayErr) {
|
|
178415
179393
|
console.error(replayErr);
|
|
@@ -178434,7 +179412,7 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
178434
179412
|
}
|
|
178435
179413
|
effort = lvl;
|
|
178436
179414
|
}
|
|
178437
|
-
await startChatSession({ model, workDir, prompt: prompt2, resume, continueLast: !!options.continue, initialMode: modeRes.mode, lockMode: modeRes.locked, debug: !!options.debug || debugFile !== void 0, debugFile, fallbackModel, maxTurns, onlyTools, newSessionId, sessionName, forkSession: !!options.forkSession, stdinText, stdinFollowUps, showBanner, outputFormat, effort, audit: options.audit, worktree, fullscreen: !!options.fullscreen, strictPermissions: options.permissionMode !== void 0, budgetUsd, appendSystemPrompt, mcpOverride, strictMcp: !!options.strictMcpConfig, systemPrompt: sysPrompt.value, verbose: !!options.verbose, includePartialMessages: !!options.includePartialMessages, agents: agentsParsed.value, selectedAgent: selectedAgent ? { name: selectedAgent.name, prompt: selectedAgent.prompt, tools: selectedAgent.tools, model: selectedAgent.model } : void 0, replayUserMessages: !!options.replayUserMessages, inputFormatWasStreamJson: options.inputFormat !== void 0 && String(options.inputFormat).toLowerCase() === "stream-json", bare: !!(options.bare || options.safeMode), noSessionPersistence: options.sessionPersistence === false, addDirs: addDirs.value, jsonSchema, permissionPromptTool });
|
|
179415
|
+
await startChatSession({ model, workDir, prompt: prompt2, resume, continueLast: !!options.continue, initialMode: modeRes.mode, lockMode: modeRes.locked, debug: !!options.debug || debugFile !== void 0, debugFile, fallbackModel, maxTurns, onlyTools, newSessionId, sessionName, forkSession: !!options.forkSession, stdinText, stdinFollowUps, showBanner, outputFormat, effort, audit: options.audit, worktree, fullscreen: !!options.fullscreen, strictPermissions: options.permissionMode !== void 0, budgetUsd, appendSystemPrompt, mcpOverride, strictMcp: !!options.strictMcpConfig, systemPrompt: sysPrompt.value, verbose: !!options.verbose, includePartialMessages: !!options.includePartialMessages, includeHookEvents: !!options.includeHookEvents, agents: agentsParsed.value, selectedAgent: selectedAgent ? { name: selectedAgent.name, prompt: selectedAgent.prompt, tools: selectedAgent.tools, model: selectedAgent.model } : void 0, replayUserMessages: !!options.replayUserMessages, inputFormatWasStreamJson: options.inputFormat !== void 0 && String(options.inputFormat).toLowerCase() === "stream-json", bare: !!(options.bare || options.safeMode), noSessionPersistence: options.sessionPersistence === false, addDirs: addDirs.value, jsonSchema, permissionPromptTool });
|
|
178438
179416
|
});
|
|
178439
179417
|
program2.parse();
|
|
178440
179418
|
/*! Bundled license information:
|