nexrall-code 0.5.168 → 0.5.169
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 +425 -208
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -106914,7 +106914,7 @@ var require_loop = __commonJS({
|
|
|
106914
106914
|
exports2.parsePromptHookReply = parsePromptHookReply;
|
|
106915
106915
|
exports2.classifyStopFailure = classifyStopFailure;
|
|
106916
106916
|
exports2.runLifecycleHooks = runLifecycleHooks;
|
|
106917
|
-
exports2.runPermissionRequestHooks =
|
|
106917
|
+
exports2.runPermissionRequestHooks = runPermissionRequestHooks3;
|
|
106918
106918
|
exports2.fireNotificationHooks = fireNotificationHooks2;
|
|
106919
106919
|
exports2.fireManualPostCompactHook = fireManualPostCompactHook2;
|
|
106920
106920
|
exports2.fireManualPreCompactHook = fireManualPreCompactHook2;
|
|
@@ -107030,8 +107030,42 @@ var require_loop = __commonJS({
|
|
|
107030
107030
|
...extra
|
|
107031
107031
|
];
|
|
107032
107032
|
}
|
|
107033
|
+
for (const phase of ENTRY_LIST_PHASES) {
|
|
107034
|
+
const list = merged[phase];
|
|
107035
|
+
if (Array.isArray(list) && list.length) {
|
|
107036
|
+
merged[phase] = toHookEntries(list);
|
|
107037
|
+
}
|
|
107038
|
+
}
|
|
107033
107039
|
return merged;
|
|
107034
107040
|
}
|
|
107041
|
+
var ENTRY_LIST_PHASES = [
|
|
107042
|
+
"PreToolUse",
|
|
107043
|
+
"PostToolUse",
|
|
107044
|
+
"SessionStart",
|
|
107045
|
+
"UserPromptSubmit",
|
|
107046
|
+
"PreCompact",
|
|
107047
|
+
"PermissionRequest",
|
|
107048
|
+
"Notification",
|
|
107049
|
+
"PostToolUseFailure",
|
|
107050
|
+
"SubagentStart",
|
|
107051
|
+
"PostCompact",
|
|
107052
|
+
"SessionEnd",
|
|
107053
|
+
"FileChanged",
|
|
107054
|
+
"InstructionsLoaded",
|
|
107055
|
+
"StopFailure"
|
|
107056
|
+
];
|
|
107057
|
+
function toHookEntries(list) {
|
|
107058
|
+
return list.map((it) => {
|
|
107059
|
+
const e2 = it;
|
|
107060
|
+
if (Array.isArray(e2.hooks))
|
|
107061
|
+
return { matcher: e2.matcher, hooks: e2.hooks };
|
|
107062
|
+
const { matcher, ...rest } = e2;
|
|
107063
|
+
const hook = { ...rest };
|
|
107064
|
+
if (!isKnownHandlerType(hook.type))
|
|
107065
|
+
hook.type = "command";
|
|
107066
|
+
return { matcher, hooks: [hook] };
|
|
107067
|
+
});
|
|
107068
|
+
}
|
|
107035
107069
|
function spawnHook(command, opts) {
|
|
107036
107070
|
return new Promise((resolve11) => {
|
|
107037
107071
|
let stdout = "";
|
|
@@ -107447,7 +107481,7 @@ ${out.output}` : `Error: ${out.error}` : out.output ?? "",
|
|
|
107447
107481
|
}
|
|
107448
107482
|
return outcome;
|
|
107449
107483
|
}
|
|
107450
|
-
async function
|
|
107484
|
+
async function runPermissionRequestHooks3(workDir, tool, input, sessionId = "") {
|
|
107451
107485
|
try {
|
|
107452
107486
|
const items = loadHooks(workDir).PermissionRequest;
|
|
107453
107487
|
if (!items?.length)
|
|
@@ -109562,7 +109596,8 @@ ${ctx}
|
|
|
109562
109596
|
}
|
|
109563
109597
|
const prefetchSafe = prefetchOn && (0, toolPrefetch_1.isPrefetchSafeMessage)(toolUseBlocks.map((b) => b.name));
|
|
109564
109598
|
const toolResults = await Promise.all(toolUseBlocks.map(async (block) => {
|
|
109565
|
-
const { id, name
|
|
109599
|
+
const { id, name } = block;
|
|
109600
|
+
let input = block.input;
|
|
109566
109601
|
const toolMeta = { id };
|
|
109567
109602
|
options.onToolUse(name, input, void 0, toolMeta);
|
|
109568
109603
|
let result;
|
|
@@ -109593,7 +109628,31 @@ ${ctx}
|
|
|
109593
109628
|
let permitted;
|
|
109594
109629
|
let deniedReason = null;
|
|
109595
109630
|
try {
|
|
109596
|
-
|
|
109631
|
+
const pd = await options.requestPermission({ tool: name, input, description });
|
|
109632
|
+
if (typeof pd === "boolean") {
|
|
109633
|
+
permitted = pd;
|
|
109634
|
+
} else {
|
|
109635
|
+
permitted = pd.granted;
|
|
109636
|
+
if (permitted && pd.updatedInput && typeof pd.updatedInput === "object") {
|
|
109637
|
+
input = pd.updatedInput;
|
|
109638
|
+
if (options.planMode) {
|
|
109639
|
+
const r2 = (0, planMode_1.checkPlanMode)(name, input);
|
|
109640
|
+
if (r2) {
|
|
109641
|
+
permitted = false;
|
|
109642
|
+
deniedReason = r2.message;
|
|
109643
|
+
}
|
|
109644
|
+
}
|
|
109645
|
+
if (permitted && options.worktree) {
|
|
109646
|
+
const r2 = (0, worktreeEnforcement_1.checkWorktreeIsolation)(name, input, options.worktree, options.workDir);
|
|
109647
|
+
if (r2) {
|
|
109648
|
+
permitted = false;
|
|
109649
|
+
deniedReason = r2.message;
|
|
109650
|
+
}
|
|
109651
|
+
}
|
|
109652
|
+
}
|
|
109653
|
+
if (!permitted && pd.message)
|
|
109654
|
+
deniedReason = deniedReason ?? pd.message;
|
|
109655
|
+
}
|
|
109597
109656
|
} catch (err) {
|
|
109598
109657
|
permitted = false;
|
|
109599
109658
|
if (err instanceof ToolNotAllowedError)
|
|
@@ -109891,6 +109950,7 @@ var require_lifecycleHost = __commonJS({
|
|
|
109891
109950
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
109892
109951
|
exports2.fireInstructionsLoadedHooks = fireInstructionsLoadedHooks2;
|
|
109893
109952
|
exports2.startFileChangedWatcher = startFileChangedWatcher2;
|
|
109953
|
+
exports2.filesChangedSinceSnapshot = filesChangedSinceSnapshot;
|
|
109894
109954
|
var fs28 = __importStar(__require("fs"));
|
|
109895
109955
|
var path28 = __importStar(__require("path"));
|
|
109896
109956
|
var loop_1 = require_loop();
|
|
@@ -109953,8 +110013,63 @@ var require_lifecycleHost = __commonJS({
|
|
|
109953
110013
|
}
|
|
109954
110014
|
};
|
|
109955
110015
|
seedKnown(staticNames);
|
|
110016
|
+
const stamp = (name) => {
|
|
110017
|
+
try {
|
|
110018
|
+
const st = fs28.statSync(path28.join(workDir, name));
|
|
110019
|
+
return `${st.mtimeMs}:${st.size}`;
|
|
110020
|
+
} catch {
|
|
110021
|
+
return "";
|
|
110022
|
+
}
|
|
110023
|
+
};
|
|
110024
|
+
const seen = /* @__PURE__ */ new Map();
|
|
110025
|
+
const snapshot = (names) => {
|
|
110026
|
+
for (const n of names)
|
|
110027
|
+
seen.set(n, stamp(n));
|
|
110028
|
+
};
|
|
110029
|
+
snapshot(staticNames);
|
|
109956
110030
|
const pending = /* @__PURE__ */ new Map();
|
|
109957
110031
|
let closed = false;
|
|
110032
|
+
const scheduleFire = (name) => {
|
|
110033
|
+
const prev = pending.get(name);
|
|
110034
|
+
if (prev)
|
|
110035
|
+
clearTimeout(prev);
|
|
110036
|
+
pending.set(name, setTimeout(() => {
|
|
110037
|
+
pending.delete(name);
|
|
110038
|
+
let exists = true;
|
|
110039
|
+
try {
|
|
110040
|
+
exists = fs28.existsSync(path28.join(workDir, name));
|
|
110041
|
+
} catch {
|
|
110042
|
+
exists = false;
|
|
110043
|
+
}
|
|
110044
|
+
const event = !exists ? "unlink" : known.has(name) ? "change" : "add";
|
|
110045
|
+
if (exists)
|
|
110046
|
+
known.add(name);
|
|
110047
|
+
else
|
|
110048
|
+
known.delete(name);
|
|
110049
|
+
seen.set(name, stamp(name));
|
|
110050
|
+
void fireChanged(workDir, sessionId, name, event, items, dynamicNames.has(name)).then((o) => {
|
|
110051
|
+
if (!o)
|
|
110052
|
+
return;
|
|
110053
|
+
if (o.systemMessage && opts?.onSystemMessage) {
|
|
110054
|
+
try {
|
|
110055
|
+
opts.onSystemMessage(o.systemMessage);
|
|
110056
|
+
} catch {
|
|
110057
|
+
}
|
|
110058
|
+
}
|
|
110059
|
+
if (o.watchPaths) {
|
|
110060
|
+
dynamicNames.clear();
|
|
110061
|
+
for (const p of o.watchPaths) {
|
|
110062
|
+
const n = isWatchableName(path28.basename(p)) ? path28.basename(p) : "";
|
|
110063
|
+
if (n)
|
|
110064
|
+
dynamicNames.add(n);
|
|
110065
|
+
}
|
|
110066
|
+
seedKnown(dynamicNames);
|
|
110067
|
+
snapshot(dynamicNames);
|
|
110068
|
+
}
|
|
110069
|
+
}).catch(() => {
|
|
110070
|
+
});
|
|
110071
|
+
}, 250));
|
|
110072
|
+
};
|
|
109958
110073
|
let watcher = null;
|
|
109959
110074
|
try {
|
|
109960
110075
|
watcher = fs28.watch(workDir, { persistent: false }, (_eventType, filename) => {
|
|
@@ -109963,52 +110078,25 @@ var require_lifecycleHost = __commonJS({
|
|
|
109963
110078
|
const name = filename ? path28.basename(String(filename)) : "";
|
|
109964
110079
|
if (!name || !watched().has(name))
|
|
109965
110080
|
return;
|
|
109966
|
-
|
|
109967
|
-
if (prev)
|
|
109968
|
-
clearTimeout(prev);
|
|
109969
|
-
pending.set(name, setTimeout(() => {
|
|
109970
|
-
pending.delete(name);
|
|
109971
|
-
let exists = true;
|
|
109972
|
-
try {
|
|
109973
|
-
exists = fs28.existsSync(path28.join(workDir, name));
|
|
109974
|
-
} catch {
|
|
109975
|
-
exists = false;
|
|
109976
|
-
}
|
|
109977
|
-
const event = !exists ? "unlink" : known.has(name) ? "change" : "add";
|
|
109978
|
-
if (exists)
|
|
109979
|
-
known.add(name);
|
|
109980
|
-
else
|
|
109981
|
-
known.delete(name);
|
|
109982
|
-
void fireChanged(workDir, sessionId, name, event, items, dynamicNames.has(name)).then((o) => {
|
|
109983
|
-
if (!o)
|
|
109984
|
-
return;
|
|
109985
|
-
if (o.systemMessage && opts?.onSystemMessage) {
|
|
109986
|
-
try {
|
|
109987
|
-
opts.onSystemMessage(o.systemMessage);
|
|
109988
|
-
} catch {
|
|
109989
|
-
}
|
|
109990
|
-
}
|
|
109991
|
-
if (o.watchPaths) {
|
|
109992
|
-
dynamicNames.clear();
|
|
109993
|
-
for (const p of o.watchPaths) {
|
|
109994
|
-
const n = isWatchableName(path28.basename(p)) ? path28.basename(p) : "";
|
|
109995
|
-
if (n)
|
|
109996
|
-
dynamicNames.add(n);
|
|
109997
|
-
}
|
|
109998
|
-
seedKnown(dynamicNames);
|
|
109999
|
-
}
|
|
110000
|
-
}).catch(() => {
|
|
110001
|
-
});
|
|
110002
|
-
}, 250));
|
|
110081
|
+
scheduleFire(name);
|
|
110003
110082
|
});
|
|
110004
110083
|
watcher.on("error", () => {
|
|
110005
110084
|
});
|
|
110006
110085
|
} catch {
|
|
110007
110086
|
return null;
|
|
110008
110087
|
}
|
|
110088
|
+
const armGraceMs = opts?.armGraceMs ?? 400;
|
|
110089
|
+
const reconcileTimer = armGraceMs > 0 ? setTimeout(() => {
|
|
110090
|
+
if (closed)
|
|
110091
|
+
return;
|
|
110092
|
+
for (const n of filesChangedSinceSnapshot(watched(), seen, stamp))
|
|
110093
|
+
scheduleFire(n);
|
|
110094
|
+
}, armGraceMs) : null;
|
|
110009
110095
|
return {
|
|
110010
110096
|
stop() {
|
|
110011
110097
|
closed = true;
|
|
110098
|
+
if (reconcileTimer)
|
|
110099
|
+
clearTimeout(reconcileTimer);
|
|
110012
110100
|
for (const t2 of pending.values())
|
|
110013
110101
|
clearTimeout(t2);
|
|
110014
110102
|
pending.clear();
|
|
@@ -110026,12 +110114,20 @@ var require_lifecycleHost = __commonJS({
|
|
|
110026
110114
|
dynamicNames.add(n);
|
|
110027
110115
|
}
|
|
110028
110116
|
seedKnown(dynamicNames);
|
|
110117
|
+
snapshot(dynamicNames);
|
|
110029
110118
|
},
|
|
110030
110119
|
watchedFiles() {
|
|
110031
110120
|
return [...watched()].sort();
|
|
110032
110121
|
}
|
|
110033
110122
|
};
|
|
110034
110123
|
}
|
|
110124
|
+
function filesChangedSinceSnapshot(names, seen, stamp) {
|
|
110125
|
+
const out = [];
|
|
110126
|
+
for (const n of names)
|
|
110127
|
+
if (stamp(n) !== (seen.get(n) ?? ""))
|
|
110128
|
+
out.push(n);
|
|
110129
|
+
return out;
|
|
110130
|
+
}
|
|
110035
110131
|
async function fireChanged(workDir, sessionId, name, event, items, isDynamic) {
|
|
110036
110132
|
const abs = path28.join(workDir, name);
|
|
110037
110133
|
try {
|
|
@@ -146132,7 +146228,7 @@ var {
|
|
|
146132
146228
|
} = import_index.default;
|
|
146133
146229
|
|
|
146134
146230
|
// src/index.ts
|
|
146135
|
-
var
|
|
146231
|
+
var import_code_core21 = __toESM(require_dist3(), 1);
|
|
146136
146232
|
import * as path27 from "path";
|
|
146137
146233
|
import * as fs27 from "fs";
|
|
146138
146234
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -152041,7 +152137,7 @@ function confirmMatches(env4, typed) {
|
|
|
152041
152137
|
}
|
|
152042
152138
|
|
|
152043
152139
|
// src/commands/chat.ts
|
|
152044
|
-
var
|
|
152140
|
+
var import_code_core17 = __toESM(require_dist3(), 1);
|
|
152045
152141
|
import * as os15 from "os";
|
|
152046
152142
|
import * as crypto7 from "crypto";
|
|
152047
152143
|
import { createRequire } from "module";
|
|
@@ -152951,8 +153047,82 @@ async function askFlow(req) {
|
|
|
152951
153047
|
return await choose({ title: `Allow ${tool}?`, risk: riskOf(tool, input), alwaysLabel: null }) !== "n";
|
|
152952
153048
|
}
|
|
152953
153049
|
|
|
152954
|
-
// src/
|
|
153050
|
+
// src/permissions/promptTool.ts
|
|
153051
|
+
function parsePromptToolAnswer(raw) {
|
|
153052
|
+
if (raw === null)
|
|
153053
|
+
return { error: "the permission tool is not connected (check `nex mcp list`)" };
|
|
153054
|
+
const text = String(raw).trim();
|
|
153055
|
+
let j;
|
|
153056
|
+
try {
|
|
153057
|
+
j = JSON.parse(text);
|
|
153058
|
+
} catch {
|
|
153059
|
+
return { error: `the permission tool returned non-JSON: ${text.slice(0, 200) || "(empty)"}` };
|
|
153060
|
+
}
|
|
153061
|
+
if (!j || typeof j !== "object" || Array.isArray(j)) {
|
|
153062
|
+
return { error: `the permission tool returned JSON that is not an object: ${text.slice(0, 200)}` };
|
|
153063
|
+
}
|
|
153064
|
+
const o = j;
|
|
153065
|
+
const behavior = o.behavior === "allow" || o.behavior === "deny" ? o.behavior : o.decision === "allow" || o.decision === "deny" ? o.decision : null;
|
|
153066
|
+
if (!behavior) {
|
|
153067
|
+
return { error: `the permission tool did not return a behavior/decision of "allow" or "deny": ${text.slice(0, 200)}` };
|
|
153068
|
+
}
|
|
153069
|
+
const message = typeof o.message === "string" && o.message ? o.message : typeof o.reason === "string" && o.reason ? o.reason : void 0;
|
|
153070
|
+
if (behavior === "allow" && o.updatedInput !== void 0) {
|
|
153071
|
+
if (!o.updatedInput || typeof o.updatedInput !== "object" || Array.isArray(o.updatedInput)) {
|
|
153072
|
+
return { error: `the permission tool returned an updatedInput that is not an object: ${text.slice(0, 200)}` };
|
|
153073
|
+
}
|
|
153074
|
+
return { behavior, updatedInput: o.updatedInput, message };
|
|
153075
|
+
}
|
|
153076
|
+
return { behavior, message };
|
|
153077
|
+
}
|
|
153078
|
+
async function askPermissionPromptTool(host, toolName, req, abortSignal) {
|
|
153079
|
+
if (!host)
|
|
153080
|
+
return { error: `--permission-prompt-tool "${toolName}" needs MCP, but no MCP servers are configured for this run` };
|
|
153081
|
+
if (!host.isMcpTool(toolName)) {
|
|
153082
|
+
return { error: `--permission-prompt-tool "${toolName}" is not a tool of any connected MCP server (check \`nex mcp list\`)` };
|
|
153083
|
+
}
|
|
153084
|
+
let raw;
|
|
153085
|
+
try {
|
|
153086
|
+
raw = await host.callTool(toolName, {
|
|
153087
|
+
tool_name: req.tool,
|
|
153088
|
+
input: req.input,
|
|
153089
|
+
...req.description ? { description: req.description } : {},
|
|
153090
|
+
cwd: req.cwd,
|
|
153091
|
+
permission_mode: req.mode,
|
|
153092
|
+
...req.sessionId ? { session_id: req.sessionId } : {}
|
|
153093
|
+
}, abortSignal);
|
|
153094
|
+
} catch (err) {
|
|
153095
|
+
return { error: `the permission tool failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
153096
|
+
}
|
|
153097
|
+
return parsePromptToolAnswer(raw);
|
|
153098
|
+
}
|
|
153099
|
+
|
|
153100
|
+
// src/permissions/headlessHook.ts
|
|
152955
153101
|
var import_code_core7 = __toESM(require_dist3(), 1);
|
|
153102
|
+
async function runHeadlessPermissionHooks(ctx, emit, emitEvent2) {
|
|
153103
|
+
const locked = ctx.policyDeny || ctx.reason === "rule";
|
|
153104
|
+
const destructive = ctx.reason === "destructive" && !!ctx.destructive;
|
|
153105
|
+
if (locked || destructive)
|
|
153106
|
+
return { handled: null };
|
|
153107
|
+
const hook = await (0, import_code_core7.runPermissionRequestHooks)(ctx.workDir, ctx.tool, ctx.input, ctx.sessionId);
|
|
153108
|
+
if (hook.answer === "allow") {
|
|
153109
|
+
emit({ type: "permission_granted", tool: ctx.tool, reason: "hook" });
|
|
153110
|
+
emitEvent2("permission.granted", { tool: ctx.tool, reason: "hook" });
|
|
153111
|
+
return { handled: "allow" };
|
|
153112
|
+
}
|
|
153113
|
+
if (hook.answer === "deny") {
|
|
153114
|
+
emit({ type: "permission_denied", tool: ctx.tool, reason: "hook" });
|
|
153115
|
+
emitEvent2("permission.denied", { tool: ctx.tool, reason: "hook" });
|
|
153116
|
+
return {
|
|
153117
|
+
handled: "deny",
|
|
153118
|
+
message: hook.reason ? `Permission denied by hook: ${hook.reason}` : "Permission denied by hook"
|
|
153119
|
+
};
|
|
153120
|
+
}
|
|
153121
|
+
return { handled: null };
|
|
153122
|
+
}
|
|
153123
|
+
|
|
153124
|
+
// src/audit.ts
|
|
153125
|
+
var import_code_core8 = __toESM(require_dist3(), 1);
|
|
152956
153126
|
import * as path7 from "path";
|
|
152957
153127
|
var _state;
|
|
152958
153128
|
var _sinks = /* @__PURE__ */ new Map();
|
|
@@ -152972,7 +153142,7 @@ function currentAudit() {
|
|
|
152972
153142
|
const target = resolveAuditPath(_state);
|
|
152973
153143
|
let sink = _sinks.get(target);
|
|
152974
153144
|
if (!sink) {
|
|
152975
|
-
sink = (0,
|
|
153145
|
+
sink = (0, import_code_core8.createJsonlAuditSink)(target);
|
|
152976
153146
|
_sinks.set(target, sink);
|
|
152977
153147
|
}
|
|
152978
153148
|
const cfg = {
|
|
@@ -152985,14 +153155,14 @@ function currentAudit() {
|
|
|
152985
153155
|
// request that caused it. Same trap as @nexrall/agent's and Desktop's.
|
|
152986
153156
|
sessionId: _state.getSessionId()
|
|
152987
153157
|
};
|
|
152988
|
-
const email = (0,
|
|
153158
|
+
const email = (0, import_code_core8.loadAuth)()?.email;
|
|
152989
153159
|
if (email)
|
|
152990
153160
|
cfg.userId = email;
|
|
152991
153161
|
return cfg;
|
|
152992
153162
|
}
|
|
152993
153163
|
|
|
152994
153164
|
// src/commands/chat.ts
|
|
152995
|
-
var
|
|
153165
|
+
var import_code_core18 = __toESM(require_dist3(), 1);
|
|
152996
153166
|
|
|
152997
153167
|
// src/headlessFlags.ts
|
|
152998
153168
|
import * as fs7 from "fs";
|
|
@@ -153138,6 +153308,8 @@ function checkHeadlessOnly(f3) {
|
|
|
153138
153308
|
return "--no-session-persistence only works with --output-format (a one-shot, non-interactive run).";
|
|
153139
153309
|
if (f3.maxTurns !== void 0)
|
|
153140
153310
|
return "--max-turns only works with --output-format (a one-shot, non-interactive run).";
|
|
153311
|
+
if (f3.permissionPromptTool !== void 0)
|
|
153312
|
+
return "--permission-prompt-tool only works with --output-format (a one-shot, non-interactive run).";
|
|
153141
153313
|
return null;
|
|
153142
153314
|
}
|
|
153143
153315
|
function headlessVerdict(i2) {
|
|
@@ -153326,6 +153498,15 @@ function readPromptFile(file, cwd2, flag = "--append-system-prompt-file") {
|
|
|
153326
153498
|
return { ok: false, error: `${flag}: "${file}" is empty` };
|
|
153327
153499
|
return { ok: true, value: text.trim() };
|
|
153328
153500
|
}
|
|
153501
|
+
function normalizePermissionPromptTool(raw) {
|
|
153502
|
+
let name = String(raw).trim();
|
|
153503
|
+
if (name.startsWith("mcp__"))
|
|
153504
|
+
name = name.slice("mcp__".length);
|
|
153505
|
+
if (!name || !name.includes("__")) {
|
|
153506
|
+
return { ok: false, error: `--permission-prompt-tool: "${raw}" is not an MCP tool name. Use mcp__server__tool (the name shown in /mcp or \`nex mcp list\`)` };
|
|
153507
|
+
}
|
|
153508
|
+
return { ok: true, value: name };
|
|
153509
|
+
}
|
|
153329
153510
|
var CLAUDE_TOOL_ALIASES = {
|
|
153330
153511
|
Read: ["read_file", "list_directory", "search_files", "glob", "notebook_read"],
|
|
153331
153512
|
Edit: ["edit_file", "multi_edit", "notebook_edit"],
|
|
@@ -153532,7 +153713,7 @@ function parseAgentsArg(raw, cwd2) {
|
|
|
153532
153713
|
}
|
|
153533
153714
|
|
|
153534
153715
|
// src/commands/chat.ts
|
|
153535
|
-
var
|
|
153716
|
+
var import_code_core19 = __toESM(require_dist3(), 1);
|
|
153536
153717
|
|
|
153537
153718
|
// src/debugLog.ts
|
|
153538
153719
|
import fs8 from "fs";
|
|
@@ -153579,14 +153760,14 @@ function debugLog(event, fields) {
|
|
|
153579
153760
|
}
|
|
153580
153761
|
|
|
153581
153762
|
// src/commands/doctor.ts
|
|
153582
|
-
var
|
|
153763
|
+
var import_code_core10 = __toESM(require_dist3(), 1);
|
|
153583
153764
|
import fs10 from "fs";
|
|
153584
153765
|
import os4 from "os";
|
|
153585
153766
|
import path11 from "path";
|
|
153586
153767
|
import { spawnSync as spawnSync2, execFileSync as execFileSync2 } from "child_process";
|
|
153587
153768
|
|
|
153588
153769
|
// src/commands/sessionTools.ts
|
|
153589
|
-
var
|
|
153770
|
+
var import_code_core9 = __toESM(require_dist3(), 1);
|
|
153590
153771
|
import { spawnSync, execFileSync } from "child_process";
|
|
153591
153772
|
import fs9 from "fs";
|
|
153592
153773
|
import path10 from "path";
|
|
@@ -153635,7 +153816,7 @@ function nextMode(current) {
|
|
|
153635
153816
|
return MODE_CYCLE[(i2 + 1) % MODE_CYCLE.length];
|
|
153636
153817
|
}
|
|
153637
153818
|
function textOf(m2) {
|
|
153638
|
-
return m2.content.filter((b) => b.type === "text" && !(0,
|
|
153819
|
+
return m2.content.filter((b) => b.type === "text" && !(0, import_code_core9.isRuntimeContextBlock)(b)).map((b) => b.text).join("\n").trim();
|
|
153639
153820
|
}
|
|
153640
153821
|
function lastAssistantText(messages) {
|
|
153641
153822
|
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
@@ -153661,7 +153842,7 @@ function exportMarkdown(messages, meta) {
|
|
|
153661
153842
|
for (const m2 of messages) {
|
|
153662
153843
|
const parts = [];
|
|
153663
153844
|
for (const b of m2.content) {
|
|
153664
|
-
if ((0,
|
|
153845
|
+
if ((0, import_code_core9.isRuntimeContextBlock)(b))
|
|
153665
153846
|
continue;
|
|
153666
153847
|
if (b.type === "text") {
|
|
153667
153848
|
if (b.text.trim())
|
|
@@ -154019,17 +154200,17 @@ function realProbes(c) {
|
|
|
154019
154200
|
return { inRepo: false };
|
|
154020
154201
|
}
|
|
154021
154202
|
},
|
|
154022
|
-
hasToken: () => !!(0,
|
|
154203
|
+
hasToken: () => !!(0, import_code_core10.getToken)(),
|
|
154023
154204
|
verifyAuth: async () => {
|
|
154024
154205
|
try {
|
|
154025
|
-
await (0,
|
|
154206
|
+
await (0, import_code_core10.getBalance)();
|
|
154026
154207
|
return { ok: true, detail: "signed in, token accepted" };
|
|
154027
154208
|
} catch (e2) {
|
|
154028
154209
|
return { ok: false, detail: `token rejected \u2014 ${e2.message.slice(0, 120)}` };
|
|
154029
154210
|
}
|
|
154030
154211
|
},
|
|
154031
|
-
reach: () => reachHost(
|
|
154032
|
-
apiBase:
|
|
154212
|
+
reach: () => reachHost(import_code_core10.API_BASE),
|
|
154213
|
+
apiBase: import_code_core10.API_BASE,
|
|
154033
154214
|
isTTY: !!process.stdout.isTTY,
|
|
154034
154215
|
columns: process.stdout.columns,
|
|
154035
154216
|
rows: process.stdout.rows,
|
|
@@ -154037,7 +154218,7 @@ function realProbes(c) {
|
|
|
154037
154218
|
mcp: () => {
|
|
154038
154219
|
let configured = 0;
|
|
154039
154220
|
try {
|
|
154040
|
-
configured = Object.keys(
|
|
154221
|
+
configured = Object.keys(import_code_core10.McpManager.loadConfig(c.workDir).mcpServers).length;
|
|
154041
154222
|
} catch {
|
|
154042
154223
|
}
|
|
154043
154224
|
return { configured, rows: c.mcpRows ?? [] };
|
|
@@ -163895,7 +164076,7 @@ var useBoxMetrics = (ref) => {
|
|
|
163895
164076
|
var use_box_metrics_default = useBoxMetrics;
|
|
163896
164077
|
|
|
163897
164078
|
// src/ui/themeSettings.ts
|
|
163898
|
-
var
|
|
164079
|
+
var import_code_core11 = __toESM(require_dist3(), 1);
|
|
163899
164080
|
import * as fs17 from "fs";
|
|
163900
164081
|
import * as os9 from "os";
|
|
163901
164082
|
import * as path17 from "path";
|
|
@@ -163929,13 +164110,13 @@ function applyThemeConfig(cfg, opts = {}) {
|
|
|
163929
164110
|
return { resolved, notes };
|
|
163930
164111
|
}
|
|
163931
164112
|
function applyTrustedTheme(env4 = process.env) {
|
|
163932
|
-
const settings = (0,
|
|
164113
|
+
const settings = (0, import_code_core11.loadSettings)(os9.homedir());
|
|
163933
164114
|
const cfg = readThemeConfig(settings.raw);
|
|
163934
164115
|
const { resolved, notes } = applyThemeConfig(cfg, { env: env4 });
|
|
163935
164116
|
return { ...cfg, resolved, notes };
|
|
163936
164117
|
}
|
|
163937
164118
|
function loadAndApplyTheme(workDir, env4 = process.env) {
|
|
163938
|
-
const settings = (0,
|
|
164119
|
+
const settings = (0, import_code_core11.loadSettings)(workDir);
|
|
163939
164120
|
const cfg = readThemeConfig(settings.raw);
|
|
163940
164121
|
const { resolved, notes } = applyThemeConfig(cfg, { env: env4 });
|
|
163941
164122
|
return { ...cfg, resolved, notes };
|
|
@@ -167651,7 +167832,7 @@ function orderByRecents(entries, recents) {
|
|
|
167651
167832
|
}
|
|
167652
167833
|
|
|
167653
167834
|
// src/ui/memoryNote.ts
|
|
167654
|
-
var
|
|
167835
|
+
var import_code_core12 = __toESM(require_dist3(), 1);
|
|
167655
167836
|
function stripEscape(line) {
|
|
167656
167837
|
return line.startsWith("\\#") ? line.slice(1) : line;
|
|
167657
167838
|
}
|
|
@@ -167668,7 +167849,7 @@ function parseMemoryNote(line) {
|
|
|
167668
167849
|
return text ? { scope: "project", text } : null;
|
|
167669
167850
|
}
|
|
167670
167851
|
async function saveNote(note, workDir) {
|
|
167671
|
-
const r2 = await (0,
|
|
167852
|
+
const r2 = await (0, import_code_core12.writeMemory)(note.text, note.scope, workDir, { source: "cli" });
|
|
167672
167853
|
return { ok: r2.ok, already: r2.already, superseded: r2.superseded === true, scope: r2.scope, file: r2.file, text: note.text };
|
|
167673
167854
|
}
|
|
167674
167855
|
function parseMemoryAdd(arg) {
|
|
@@ -167690,7 +167871,7 @@ function interpretPrompt(line) {
|
|
|
167690
167871
|
}
|
|
167691
167872
|
|
|
167692
167873
|
// src/ui/mcpPanel.ts
|
|
167693
|
-
var
|
|
167874
|
+
var import_code_core13 = __toESM(require_dist3(), 1);
|
|
167694
167875
|
function parseMcpArgs(arg) {
|
|
167695
167876
|
const parts = arg.trim().split(/\s+/).filter(Boolean);
|
|
167696
167877
|
if (parts.length === 0)
|
|
@@ -167791,7 +167972,7 @@ function formatMcpDetail(input) {
|
|
|
167791
167972
|
const desc = (t2.description ?? "").split("\n")[0].trim();
|
|
167792
167973
|
const head = ` ${t2.name.padEnd(nameWidth)}`;
|
|
167793
167974
|
const maxSuffix = Math.max(0, budget - head.length);
|
|
167794
|
-
let suffix = (0,
|
|
167975
|
+
let suffix = (0, import_code_core13.describeStats)(byTool.get(t2.name));
|
|
167795
167976
|
if (suffix) {
|
|
167796
167977
|
suffix = ` ${suffix}`;
|
|
167797
167978
|
if (suffix.length > maxSuffix) {
|
|
@@ -168005,9 +168186,9 @@ function planModelSwitch(next, effort, clamp) {
|
|
|
168005
168186
|
}
|
|
168006
168187
|
|
|
168007
168188
|
// src/ui/keybindingsStore.ts
|
|
168008
|
-
var
|
|
168189
|
+
var import_code_core14 = __toESM(require_dist3(), 1);
|
|
168009
168190
|
function loadAndApplyKeybindings(workDir) {
|
|
168010
|
-
const settings = (0,
|
|
168191
|
+
const settings = (0, import_code_core14.loadSettings)(workDir);
|
|
168011
168192
|
const raw = settings.raw.keybindings;
|
|
168012
168193
|
const result = parseKeybindings(raw);
|
|
168013
168194
|
setBindings(result);
|
|
@@ -168057,7 +168238,7 @@ function resetKeybindings(workDir, scope = "user") {
|
|
|
168057
168238
|
return result;
|
|
168058
168239
|
}
|
|
168059
168240
|
function readRawBlock(workDir) {
|
|
168060
|
-
const settings = (0,
|
|
168241
|
+
const settings = (0, import_code_core14.loadSettings)(workDir);
|
|
168061
168242
|
const raw = settings.raw.keybindings;
|
|
168062
168243
|
return raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {};
|
|
168063
168244
|
}
|
|
@@ -168257,7 +168438,7 @@ function formatTaskGraph(input) {
|
|
|
168257
168438
|
}
|
|
168258
168439
|
|
|
168259
168440
|
// src/ui/contextPanel.ts
|
|
168260
|
-
var
|
|
168441
|
+
var import_code_core15 = __toESM(require_dist3(), 1);
|
|
168261
168442
|
var KIND_LABEL2 = {
|
|
168262
168443
|
tool_result: "tool results",
|
|
168263
168444
|
reply: "model replies",
|
|
@@ -168332,8 +168513,8 @@ function textHead(block) {
|
|
|
168332
168513
|
var TOP_DEFAULT = 3;
|
|
168333
168514
|
var TOP_ALL = 10;
|
|
168334
168515
|
function measureContext(messages, topN = TOP_DEFAULT) {
|
|
168335
|
-
const bytes = (0,
|
|
168336
|
-
const tokens = (0,
|
|
168516
|
+
const bytes = (0, import_code_core15.estimateBodyBytes)(messages);
|
|
168517
|
+
const tokens = (0, import_code_core15.estimateTokensRough)(messages);
|
|
168337
168518
|
const toolNames = /* @__PURE__ */ new Map();
|
|
168338
168519
|
const buckets = /* @__PURE__ */ new Map();
|
|
168339
168520
|
const all = [];
|
|
@@ -168513,7 +168694,7 @@ function formatContextPanel(input) {
|
|
|
168513
168694
|
}
|
|
168514
168695
|
|
|
168515
168696
|
// src/ui/permDashboard.ts
|
|
168516
|
-
var
|
|
168697
|
+
var import_code_core16 = __toESM(require_dist3(), 1);
|
|
168517
168698
|
var DASHBOARD_ACTIONS = [
|
|
168518
168699
|
{ group: "Filesystem", label: "read a project file", tool: "read_file", input: { path: "src/app.ts" } },
|
|
168519
168700
|
{ group: "Filesystem", label: "edit a project file", tool: "edit_file", input: { path: "src/app.ts", old_string: "a", new_string: "b" } },
|
|
@@ -168544,15 +168725,15 @@ var NOT_A_READ = /* @__PURE__ */ new Set(["todo_write", "use_skill"]);
|
|
|
168544
168725
|
function capOf(tool) {
|
|
168545
168726
|
if (tool === "task")
|
|
168546
168727
|
return "delegate";
|
|
168547
|
-
if (
|
|
168728
|
+
if (import_code_core16.BASH_TOOLS.has(tool))
|
|
168548
168729
|
return "shell";
|
|
168549
|
-
if (
|
|
168730
|
+
if (import_code_core16.FILE_WRITE_TOOLS.has(tool) || import_code_core16.FILE_MUTATE_TOOLS.has(tool))
|
|
168550
168731
|
return "write";
|
|
168551
168732
|
if (NETWORK_TOOLS.has(tool))
|
|
168552
168733
|
return "network";
|
|
168553
168734
|
if (tool === "bash_output" || tool === "kill_shell")
|
|
168554
168735
|
return "shell";
|
|
168555
|
-
if (
|
|
168736
|
+
if (import_code_core16.READ_ONLY_TOOLS.has(tool) && !NOT_A_READ.has(tool))
|
|
168556
168737
|
return "read";
|
|
168557
168738
|
return null;
|
|
168558
168739
|
}
|
|
@@ -168580,19 +168761,19 @@ function capPhrase(caps) {
|
|
|
168580
168761
|
return parts.length ? parts.join(", ") : "nothing";
|
|
168581
168762
|
}
|
|
168582
168763
|
function explainAction(rules, mode, workDir, action, opts = {}) {
|
|
168583
|
-
const rule = (0,
|
|
168764
|
+
const rule = (0, import_code_core16.evaluatePermission)(rules, action.tool, action.input, workDir);
|
|
168584
168765
|
if (rule === "deny")
|
|
168585
168766
|
return { mark: "\u2717", reason: "denied by a permission rule" };
|
|
168586
|
-
if ((0,
|
|
168767
|
+
if ((0, import_code_core16.isDestructiveBash)(action.tool, action.input) && !opts.allowDestructive) {
|
|
168587
168768
|
return { mark: "\u26A0", reason: 'irreversible \u2014 always asks (type "yes")' };
|
|
168588
168769
|
}
|
|
168589
168770
|
if (rule === "allow")
|
|
168590
168771
|
return { mark: "\u2713", reason: "allowed by a permission rule" };
|
|
168591
|
-
const verdict = (0,
|
|
168772
|
+
const verdict = (0, import_code_core16.decide)({ tool: action.tool, input: action.input, mode, bypass: opts.yolo, destructive: false });
|
|
168592
168773
|
if (verdict === "allow") {
|
|
168593
168774
|
if (capOf(action.tool) === "read")
|
|
168594
168775
|
return { mark: "\u2713", reason: "read-only \u2014 allowed in every mode" };
|
|
168595
|
-
if (
|
|
168776
|
+
if (import_code_core16.BASH_TOOLS.has(action.tool) && (0, import_code_core16.isReadOnlyBash)(String(action.input.command ?? ""))) {
|
|
168596
168777
|
return { mark: "\u2713", reason: "read-only command \u2014 allowed in every mode" };
|
|
168597
168778
|
}
|
|
168598
168779
|
if (action.tool === "fetch_url" || action.tool === "web_search") {
|
|
@@ -169050,7 +169231,7 @@ function agentTypeModel(type, workDir) {
|
|
|
169050
169231
|
if (!agentTypeCache || agentTypeCache.workDir !== workDir || now - agentTypeCache.at > 1e3) {
|
|
169051
169232
|
const models = /* @__PURE__ */ new Map();
|
|
169052
169233
|
try {
|
|
169053
|
-
for (const t2 of (0,
|
|
169234
|
+
for (const t2 of (0, import_code_core17.loadAgentTypesWithWarnings)(workDir).types)
|
|
169054
169235
|
if (t2.model)
|
|
169055
169236
|
models.set(t2.name, t2.model);
|
|
169056
169237
|
} catch {
|
|
@@ -169115,13 +169296,13 @@ function agentPanelContext(v, cols, now) {
|
|
|
169115
169296
|
}
|
|
169116
169297
|
let maxConcurrent;
|
|
169117
169298
|
try {
|
|
169118
|
-
maxConcurrent = (0,
|
|
169299
|
+
maxConcurrent = (0, import_code_core19.resolveMaxConcurrentSubtasks)((0, import_code_core19.loadSettings)(v.workDir).raw);
|
|
169119
169300
|
} catch {
|
|
169120
169301
|
maxConcurrent = void 0;
|
|
169121
169302
|
}
|
|
169122
169303
|
const types3 = (() => {
|
|
169123
169304
|
try {
|
|
169124
|
-
return (0,
|
|
169305
|
+
return (0, import_code_core17.loadAgentTypesWithWarnings)(v.workDir).types.map((t2) => ({
|
|
169125
169306
|
name: t2.name,
|
|
169126
169307
|
description: t2.description,
|
|
169127
169308
|
...t2.model ? { model: t2.model } : {},
|
|
@@ -169221,7 +169402,7 @@ function printMergeReview(dir, cols) {
|
|
|
169221
169402
|
function printTaskGraph(workDir, cols) {
|
|
169222
169403
|
let tasks = [];
|
|
169223
169404
|
try {
|
|
169224
|
-
tasks = (0,
|
|
169405
|
+
tasks = (0, import_code_core19.listSharedTasks)(workDir);
|
|
169225
169406
|
} catch (e2) {
|
|
169226
169407
|
console.log(paint.red(" Could not read the shared task list: " + e2.message));
|
|
169227
169408
|
return;
|
|
@@ -169336,13 +169517,13 @@ var NO_PDF_MODELS = /* @__PURE__ */ new Set([
|
|
|
169336
169517
|
...NO_VISION_MODELS
|
|
169337
169518
|
]);
|
|
169338
169519
|
function needsVisionSidecar(model) {
|
|
169339
|
-
return !(0,
|
|
169520
|
+
return !(0, import_code_core17.liveSupportsImageInput)(model, !NO_VISION_MODELS.has(model));
|
|
169340
169521
|
}
|
|
169341
169522
|
function needsPdfSidecar(model) {
|
|
169342
|
-
return !(0,
|
|
169523
|
+
return !(0, import_code_core17.liveSupportsPdfInput)(model, !NO_PDF_MODELS.has(model));
|
|
169343
169524
|
}
|
|
169344
169525
|
function selectableModelIds() {
|
|
169345
|
-
return (0,
|
|
169526
|
+
return (0, import_code_core17.liveSelectableModelIds)() ?? SELECTABLE_MODELS;
|
|
169346
169527
|
}
|
|
169347
169528
|
function normaliseModelId(model) {
|
|
169348
169529
|
const raw = (model ?? "").trim();
|
|
@@ -169403,9 +169584,9 @@ var _BACKEND_STYLE_TO_LOCAL = {
|
|
|
169403
169584
|
};
|
|
169404
169585
|
function effortStyleFor(modelId) {
|
|
169405
169586
|
const id = normaliseModelId(modelId);
|
|
169406
|
-
if ((0,
|
|
169587
|
+
if ((0, import_code_core17.liveVendorFor)(id) === "Anthropic")
|
|
169407
169588
|
return "anthropic";
|
|
169408
|
-
const liveStyle = (0,
|
|
169589
|
+
const liveStyle = (0, import_code_core17.liveReasoningEffortStyle)(id);
|
|
169409
169590
|
if (liveStyle && _BACKEND_STYLE_TO_LOCAL[liveStyle])
|
|
169410
169591
|
return _BACKEND_STYLE_TO_LOCAL[liveStyle];
|
|
169411
169592
|
return MODEL_EFFORT_STYLE[id] ?? "anthropic";
|
|
@@ -169425,7 +169606,7 @@ function defaultEffortForModel(modelId) {
|
|
|
169425
169606
|
}
|
|
169426
169607
|
function resolveModelLabel(alias) {
|
|
169427
169608
|
const id = normaliseModelId(alias);
|
|
169428
|
-
return (0,
|
|
169609
|
+
return (0, import_code_core17.liveLabelFor)(id, MODEL_LABELS[id] ?? id);
|
|
169429
169610
|
}
|
|
169430
169611
|
function tryExec(cmd, cwd2) {
|
|
169431
169612
|
try {
|
|
@@ -169515,12 +169696,12 @@ function readNexrallMd(workDir) {
|
|
|
169515
169696
|
} catch {
|
|
169516
169697
|
}
|
|
169517
169698
|
};
|
|
169518
|
-
const memContent = (0,
|
|
169699
|
+
const memContent = (0, import_code_core17.readAllMemory)(workDir);
|
|
169519
169700
|
if (memContent) {
|
|
169520
169701
|
parts.push(memContent);
|
|
169521
|
-
noteLoaded((0,
|
|
169702
|
+
noteLoaded((0, import_code_core17.memoryFilePath)("global"), "User");
|
|
169522
169703
|
if (workDir)
|
|
169523
|
-
noteLoaded((0,
|
|
169704
|
+
noteLoaded((0, import_code_core17.memoryFilePath)("project", workDir), "Project");
|
|
169524
169705
|
}
|
|
169525
169706
|
const globalNexrall = path25.join(os15.homedir(), ".nexrall", "nexrall.md");
|
|
169526
169707
|
const globalContent = tryRead(globalNexrall);
|
|
@@ -169757,7 +169938,7 @@ var Spinner = class {
|
|
|
169757
169938
|
return this.interval !== null;
|
|
169758
169939
|
}
|
|
169759
169940
|
};
|
|
169760
|
-
var cliBackgroundAgents = new
|
|
169941
|
+
var cliBackgroundAgents = new import_code_core17.BackgroundAgentHub();
|
|
169761
169942
|
function nextBackgroundChange() {
|
|
169762
169943
|
return new Promise((resolve11) => {
|
|
169763
169944
|
const off = cliBackgroundAgents.onChange(() => {
|
|
@@ -169775,7 +169956,7 @@ async function initMcp(workDir, override, strict) {
|
|
|
169775
169956
|
_mcpManager = null;
|
|
169776
169957
|
return;
|
|
169777
169958
|
}
|
|
169778
|
-
_mcpConfig = strict && override ? { mcpServers: {} } :
|
|
169959
|
+
_mcpConfig = strict && override ? { mcpServers: {} } : import_code_core17.McpManager.loadConfig(workDir);
|
|
169779
169960
|
if (override)
|
|
169780
169961
|
Object.assign(_mcpConfig.mcpServers, override.mcpServers);
|
|
169781
169962
|
if (Object.keys(_mcpConfig.mcpServers).length === 0) {
|
|
@@ -169786,12 +169967,12 @@ async function initMcp(workDir, override, strict) {
|
|
|
169786
169967
|
await injectMcpTokens(_mcpConfig);
|
|
169787
169968
|
} catch {
|
|
169788
169969
|
}
|
|
169789
|
-
const manager = new
|
|
169970
|
+
const manager = new import_code_core17.McpManager();
|
|
169790
169971
|
await manager.connectAll(_mcpConfig);
|
|
169791
169972
|
_mcpManager = manager;
|
|
169792
169973
|
}
|
|
169793
169974
|
function formatAgentsList(workDir) {
|
|
169794
|
-
const { types: types3, warnings } = (0,
|
|
169975
|
+
const { types: types3, warnings } = (0, import_code_core17.loadAgentTypesWithWarnings)(workDir);
|
|
169795
169976
|
if (!types3.length)
|
|
169796
169977
|
return paint.dim(" No agent types found (this should not happen \u2014 builtins always register).");
|
|
169797
169978
|
const lines = types3.map((t2) => {
|
|
@@ -169976,7 +170157,7 @@ function startSessionLog(id, resumed, extra = {}) {
|
|
|
169976
170157
|
}
|
|
169977
170158
|
var failureLedger = new FailureLedger();
|
|
169978
170159
|
var networkLedger = new NetworkLedger();
|
|
169979
|
-
var networkApiHost = hostOf(
|
|
170160
|
+
var networkApiHost = hostOf(import_code_core19.API_BASE) ?? import_code_core19.API_BASE;
|
|
169980
170161
|
var notifier = new Notifier({ env: process.env, isTTY: Boolean(process.stdout.isTTY) });
|
|
169981
170162
|
var userActiveThisTurn = false;
|
|
169982
170163
|
var failureBannerShown = "";
|
|
@@ -170183,7 +170364,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
170183
170364
|
setMode(mode);
|
|
170184
170365
|
console.log();
|
|
170185
170366
|
spinner.start("thinking\u2026", { hint: false, verbs: true });
|
|
170186
|
-
const result = await (0,
|
|
170367
|
+
const result = await (0, import_code_core17.runAgentLoop)(messages, {
|
|
170187
170368
|
workDir,
|
|
170188
170369
|
sessionId: activeSessionIdGetter(),
|
|
170189
170370
|
model: modelAlias,
|
|
@@ -170527,12 +170708,12 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
170527
170708
|
sessionId: activeSessionIdGetter(),
|
|
170528
170709
|
cwd: workDir,
|
|
170529
170710
|
model: modelAlias,
|
|
170530
|
-
tools: _headlessPolicy.onlyTools ? [..._headlessPolicy.onlyTools].sort() : (0,
|
|
170711
|
+
tools: _headlessPolicy.onlyTools ? [..._headlessPolicy.onlyTools].sort() : (0, import_code_core17.knownToolNames)(),
|
|
170531
170712
|
permissionMode: _headlessPolicy.permissionMode
|
|
170532
170713
|
}));
|
|
170533
170714
|
emit({ type: "start", model: modelAlias, workDir });
|
|
170534
170715
|
verbose(`[verbose] model=${modelAlias} cwd=${workDir} mode=${mode} session=${activeSessionIdGetter() ?? "-"}`);
|
|
170535
|
-
const result = await (0,
|
|
170716
|
+
const result = await (0, import_code_core17.runAgentLoop)(messages, {
|
|
170536
170717
|
workDir,
|
|
170537
170718
|
sessionId: activeSessionIdGetter(),
|
|
170538
170719
|
model: modelAlias,
|
|
@@ -170673,16 +170854,43 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
170673
170854
|
emit({ type: "permission_denied", tool, reason: "tools" });
|
|
170674
170855
|
return false;
|
|
170675
170856
|
}
|
|
170676
|
-
const d = (0,
|
|
170857
|
+
const d = (0, import_code_core17.isDestructiveBash)(tool, input);
|
|
170858
|
+
const policy = (0, import_code_core18.decide)({ tool, input, mode: (0, import_code_core19.parseMode)(mode), bypass: isYoloMode(), destructive: !!d });
|
|
170677
170859
|
const v = headlessVerdict({
|
|
170678
|
-
rule: (0,
|
|
170860
|
+
rule: (0, import_code_core19.evaluatePermission)((0, import_code_core19.loadSettings)(workDir).permissions, tool, input, workDir),
|
|
170679
170861
|
destructive: !!d,
|
|
170680
170862
|
allowDestructive: process.env.NEXRALL_ALLOW_DESTRUCTIVE === "1",
|
|
170681
170863
|
strict: _headlessPolicy.strict,
|
|
170682
|
-
policy
|
|
170864
|
+
policy
|
|
170683
170865
|
});
|
|
170684
170866
|
if (v.verdict === "allow")
|
|
170685
170867
|
return true;
|
|
170868
|
+
const hookGate = await runHeadlessPermissionHooks(
|
|
170869
|
+
{ tool, input, workDir, sessionId: activeSessionIdGetter() ?? "", reason: v.reason, policyDeny: policy === "deny", destructive: d },
|
|
170870
|
+
emit,
|
|
170871
|
+
emitEvent
|
|
170872
|
+
);
|
|
170873
|
+
if (hookGate.handled === "allow")
|
|
170874
|
+
return true;
|
|
170875
|
+
if (hookGate.handled === "deny")
|
|
170876
|
+
return { granted: false, message: hookGate.message };
|
|
170877
|
+
const toolFlag = _headlessPolicy.permissionPromptTool;
|
|
170878
|
+
if (toolFlag && v.reason !== "rule" && !(policy === "deny")) {
|
|
170879
|
+
const ans = await askPermissionPromptTool(_mcpManager, toolFlag, { tool, input, cwd: workDir, mode, sessionId: activeSessionIdGetter() ?? void 0 }, _abortSignal);
|
|
170880
|
+
if ("error" in ans) {
|
|
170881
|
+
emit({ type: "error", error: `--permission-prompt-tool ${toolFlag}: ${ans.error}` });
|
|
170882
|
+
emitEvent("permission.denied", { tool, reason: "prompt-tool-error" });
|
|
170883
|
+
return { granted: false, message: `Permission denied: ${ans.error}` };
|
|
170884
|
+
}
|
|
170885
|
+
if (ans.behavior === "allow") {
|
|
170886
|
+
emit({ type: "permission_granted", tool, reason: "prompt-tool" });
|
|
170887
|
+
emitEvent("permission.granted", { tool, reason: "prompt-tool" });
|
|
170888
|
+
return ans.updatedInput ? { granted: true, updatedInput: ans.updatedInput } : true;
|
|
170889
|
+
}
|
|
170890
|
+
emit({ type: "permission_denied", tool, reason: "prompt-tool" });
|
|
170891
|
+
emitEvent("permission.denied", { tool, reason: "prompt-tool" });
|
|
170892
|
+
return { granted: false, message: ans.message ? `Permission denied by ${toolFlag}: ${ans.message}` : `Permission denied by ${toolFlag}` };
|
|
170893
|
+
}
|
|
170686
170894
|
if (v.reason === "destructive" && d) {
|
|
170687
170895
|
emit({ type: "error", error: `Destructive command blocked in headless mode (${d.category}): ${d.reason}. Set NEXRALL_ALLOW_DESTRUCTIVE=1 to permit.` });
|
|
170688
170896
|
} else {
|
|
@@ -170920,7 +171128,7 @@ async function startChatSession(options) {
|
|
|
170920
171128
|
if (options.bare)
|
|
170921
171129
|
setNoDiscovery(true);
|
|
170922
171130
|
_cliAgentTypes = (options.agents ?? []).map((a) => ({ ...a, source: "programmatic" }));
|
|
170923
|
-
(0,
|
|
171131
|
+
(0, import_code_core17.enableAgentTranscriptPersistence)();
|
|
170924
171132
|
const headless = options.outputFormat === "json" || options.outputFormat === "stream-json";
|
|
170925
171133
|
const requestedWorkDir = options.workDir;
|
|
170926
171134
|
let workDir = requestedWorkDir;
|
|
@@ -170929,7 +171137,7 @@ async function startChatSession(options) {
|
|
|
170929
171137
|
let peerInbox;
|
|
170930
171138
|
const peerInboxQueue = [];
|
|
170931
171139
|
let modelAlias = options.model;
|
|
170932
|
-
void (0,
|
|
171140
|
+
void (0, import_code_core17.getModelCatalogue)().catch(() => {
|
|
170933
171141
|
});
|
|
170934
171142
|
const canPrompt = !headless && !options.prompt && !options.stdinText && process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
170935
171143
|
if (!trustGrantedByEnv()) {
|
|
@@ -170957,21 +171165,21 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
170957
171165
|
}
|
|
170958
171166
|
const themeConfig = loadAndApplyTheme(workDir);
|
|
170959
171167
|
const keyConfig = loadAndApplyKeybindings(workDir);
|
|
170960
|
-
liveDiffEnabled = readLiveDiffSetting((0,
|
|
170961
|
-
mouseEnabled = readMouseSetting((0,
|
|
170962
|
-
notifier.setMode(readNotifySetting((0,
|
|
171168
|
+
liveDiffEnabled = readLiveDiffSetting((0, import_code_core19.loadSettings)(workDir).raw);
|
|
171169
|
+
mouseEnabled = readMouseSetting((0, import_code_core19.loadSettings)(workDir).raw);
|
|
171170
|
+
notifier.setMode(readNotifySetting((0, import_code_core19.loadSettings)(workDir).raw));
|
|
170963
171171
|
setAskNotifier((what) => {
|
|
170964
171172
|
notifier.notify(needsYouNote(what));
|
|
170965
171173
|
emitEvent("permission.requested", { what });
|
|
170966
|
-
(0,
|
|
171174
|
+
(0, import_code_core18.fireNotificationHooks)(workDir, `Nexrall needs your permission: ${what}`);
|
|
170967
171175
|
});
|
|
170968
171176
|
setPermissionObserver((tool, granted) => emitEvent(granted ? "permission.granted" : "permission.denied", { tool }));
|
|
170969
171177
|
let activeThemeName = themeConfig.theme;
|
|
170970
171178
|
if (options.worktree !== void 0) {
|
|
170971
171179
|
const requestedName = typeof options.worktree === "string" ? options.worktree : void 0;
|
|
170972
|
-
const existing = requestedName ? (0,
|
|
171180
|
+
const existing = requestedName ? (0, import_code_core17.findWorktreeByName)(requestedWorkDir, requestedName) : null;
|
|
170973
171181
|
if (existing) {
|
|
170974
|
-
const entered = (0,
|
|
171182
|
+
const entered = (0, import_code_core17.enterWorktree)(existing);
|
|
170975
171183
|
if (!entered.ok) {
|
|
170976
171184
|
process.stderr.write(`Failed to resume worktree "${requestedName}": ${entered.error}
|
|
170977
171185
|
`);
|
|
@@ -170981,7 +171189,7 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
170981
171189
|
if (!headless)
|
|
170982
171190
|
console.log(paint.dim(` Resumed worktree: ${paint.bold(existing.name)} (${existing.worktreePath})`));
|
|
170983
171191
|
} else {
|
|
170984
|
-
const created = (0,
|
|
171192
|
+
const created = (0, import_code_core17.createWorktree)(requestedWorkDir, requestedName);
|
|
170985
171193
|
if (!created.ok || !created.state) {
|
|
170986
171194
|
process.stderr.write(`Failed to create worktree: ${created.error ?? "unknown error"}
|
|
170987
171195
|
`);
|
|
@@ -171000,7 +171208,7 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
171000
171208
|
process.on("exit", () => {
|
|
171001
171209
|
if (!worktreeState)
|
|
171002
171210
|
return;
|
|
171003
|
-
const hadWork = (0,
|
|
171211
|
+
const hadWork = (0, import_code_core17.worktreeHasWork)(worktreeState);
|
|
171004
171212
|
if (hadWork) {
|
|
171005
171213
|
process.stderr.write(
|
|
171006
171214
|
`
|
|
@@ -171011,7 +171219,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171011
171219
|
);
|
|
171012
171220
|
return;
|
|
171013
171221
|
}
|
|
171014
|
-
(0,
|
|
171222
|
+
(0, import_code_core17.removeWorktree)(worktreeState);
|
|
171015
171223
|
});
|
|
171016
171224
|
}
|
|
171017
171225
|
const env4 = collectEnv(workDir);
|
|
@@ -171020,7 +171228,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171020
171228
|
const nexrallMd = [agentPrefix, briefBase, options.appendSystemPrompt?.trim(), addDirNote(options.addDirs ?? []), options.jsonSchema ? schemaInstruction(options.jsonSchema) : ""].filter(Boolean).join("\n\n") || void 0;
|
|
171021
171229
|
const agentTools = options.selectedAgent?.tools;
|
|
171022
171230
|
const toolAllow = agentTools && options.onlyTools ? options.onlyTools.filter((t2) => agentTools.includes(t2)) : options.onlyTools ?? agentTools;
|
|
171023
|
-
_headlessPolicy = { strict: !!options.strictPermissions, budgetUsd: options.budgetUsd, spent: 0, schema: options.jsonSchema, maxTurns: options.maxTurns, onlyTools: toolAllow ? new Set(toolAllow) : void 0 };
|
|
171231
|
+
_headlessPolicy = { strict: !!options.strictPermissions, budgetUsd: options.budgetUsd, spent: 0, schema: options.jsonSchema, maxTurns: options.maxTurns, onlyTools: toolAllow ? new Set(toolAllow) : void 0, permissionPromptTool: options.permissionPromptTool };
|
|
171024
171232
|
_headlessPolicy.verbose = !!options.verbose;
|
|
171025
171233
|
_headlessPolicy.includePartial = !!options.includePartialMessages;
|
|
171026
171234
|
_headlessPolicy.permissionMode = String(options.initialMode ?? "");
|
|
@@ -171029,8 +171237,8 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171029
171237
|
const interactive = !headless && !options.prompt && !options.stdinText;
|
|
171030
171238
|
let peerHeartbeatTimer;
|
|
171031
171239
|
if (interactive) {
|
|
171032
|
-
const handle2 = (0,
|
|
171033
|
-
const inbox = (0,
|
|
171240
|
+
const handle2 = (0, import_code_core17.registerPeer)({ clientType: "cli", workDir: requestedWorkDir });
|
|
171241
|
+
const inbox = (0, import_code_core17.startPeerInbox)(handle2.record.id, { onMessage: (m2) => peerInboxQueue.push(m2) });
|
|
171034
171242
|
handle2.record.socketPath = inbox.socketPath;
|
|
171035
171243
|
handle2.heartbeat();
|
|
171036
171244
|
peerHandle = handle2;
|
|
@@ -171102,7 +171310,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171102
171310
|
let sessionId = options.newSessionId ?? crypto7.randomBytes(8).toString("hex");
|
|
171103
171311
|
activeSessionIdGetter = () => sessionId;
|
|
171104
171312
|
let sessionTitle = options.sessionName ?? "";
|
|
171105
|
-
const fileWatcher = noDiscovery ? null : (0,
|
|
171313
|
+
const fileWatcher = noDiscovery ? null : (0, import_code_core17.startFileChangedWatcher)(workDir, sessionId, {
|
|
171106
171314
|
// A hook's {"systemMessage":"…"} is the event's one user-visible field.
|
|
171107
171315
|
onSystemMessage: (m2) => console.log(paint.dim(` ${m2}`))
|
|
171108
171316
|
});
|
|
@@ -171113,7 +171321,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171113
171321
|
if (options.verbose)
|
|
171114
171322
|
process.stderr.write("[verbose] FileChanged hook: " + watching.join(", ") + "\n");
|
|
171115
171323
|
}
|
|
171116
|
-
void (0,
|
|
171324
|
+
void (0, import_code_core17.fireInstructionsLoadedHooks)(workDir, sessionId, lastLoadedInstructions);
|
|
171117
171325
|
const modeLocked = options.lockMode === true;
|
|
171118
171326
|
let agentMode = modeLocked ? "plan" : options.initialMode ?? "auto";
|
|
171119
171327
|
const refuseIfLocked = (what) => {
|
|
@@ -171135,7 +171343,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171135
171343
|
for (const n of themeConfig.notes)
|
|
171136
171344
|
console.log(paint.dim(" theme: " + n));
|
|
171137
171345
|
}
|
|
171138
|
-
let skills = noDiscovery ? [] : (0,
|
|
171346
|
+
let skills = noDiscovery ? [] : (0, import_code_core17.loadSkills)(workDir);
|
|
171139
171347
|
if (skills.length && !headless)
|
|
171140
171348
|
console.log(paint.dim(` ${skills.length} skill(s) loaded`));
|
|
171141
171349
|
let contextSet = loadContextSet(workDir);
|
|
@@ -171200,7 +171408,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171200
171408
|
}
|
|
171201
171409
|
startSessionLog(sessionId, true, options.forkSession ? { workDir, forkOf: stored.id } : { workDir });
|
|
171202
171410
|
try {
|
|
171203
|
-
const compacted = await (0,
|
|
171411
|
+
const compacted = await (0, import_code_core17.compactMessagesForResume)(messages, {
|
|
171204
171412
|
workDir,
|
|
171205
171413
|
model: modelAlias,
|
|
171206
171414
|
clientType: "cli"
|
|
@@ -171216,7 +171424,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171216
171424
|
}
|
|
171217
171425
|
if (!(options.resume || options.continueLast))
|
|
171218
171426
|
startSessionLog(sessionId, false, { workDir });
|
|
171219
|
-
const checkpoints = new
|
|
171427
|
+
const checkpoints = new import_code_core17.CheckpointManager(workDir, sessionId);
|
|
171220
171428
|
const commitCheckpoint = () => {
|
|
171221
171429
|
checkpoints.commitTurn();
|
|
171222
171430
|
emitEvent("checkpoint.created", { turns: checkpoints.list().length });
|
|
@@ -171238,7 +171446,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
171238
171446
|
sessionTitle = raw.length > 60 ? raw.slice(0, 60) + "\u2026" : raw;
|
|
171239
171447
|
};
|
|
171240
171448
|
const recoverTurn = (err, current) => {
|
|
171241
|
-
const salvaged = (0,
|
|
171449
|
+
const salvaged = (0, import_code_core17.salvageHistory)(err);
|
|
171242
171450
|
printErrorReport(err, abortSignal.aborted);
|
|
171243
171451
|
printTurnSummary(abortSignal.aborted ? "interrupted" : "failed");
|
|
171244
171452
|
if (!salvaged)
|
|
@@ -171296,7 +171504,7 @@ ${text}` : "");
|
|
|
171296
171504
|
throw e2;
|
|
171297
171505
|
const from = modelAlias;
|
|
171298
171506
|
modelAlias = options.fallbackModel;
|
|
171299
|
-
const salvagedMsgs = (0,
|
|
171507
|
+
const salvagedMsgs = (0, import_code_core17.salvageHistory)(e2);
|
|
171300
171508
|
if (salvagedMsgs)
|
|
171301
171509
|
messages = salvagedMsgs;
|
|
171302
171510
|
const note = `Model ${from} failed (${String(e2.message).slice(0, 120)}); retrying on ${modelAlias}`;
|
|
@@ -171315,7 +171523,7 @@ ${text}` : "");
|
|
|
171315
171523
|
continue;
|
|
171316
171524
|
}
|
|
171317
171525
|
const notes = cliBackgroundAgents.takeNotifications();
|
|
171318
|
-
messages.push({ role: "user", content: [{ type: "text", text: (0,
|
|
171526
|
+
messages.push({ role: "user", content: [{ type: "text", text: (0, import_code_core17.formatBackgroundNotifications)(notes) }] });
|
|
171319
171527
|
result = await runOnce();
|
|
171320
171528
|
messages = result.messages;
|
|
171321
171529
|
}
|
|
@@ -171333,7 +171541,7 @@ ${text}` : "");
|
|
|
171333
171541
|
await nextBackgroundChange();
|
|
171334
171542
|
continue;
|
|
171335
171543
|
}
|
|
171336
|
-
messages.push({ role: "user", content: [{ type: "text", text: (0,
|
|
171544
|
+
messages.push({ role: "user", content: [{ type: "text", text: (0, import_code_core17.formatBackgroundNotifications)(cliBackgroundAgents.takeNotifications()) }] });
|
|
171337
171545
|
result = await runOnce();
|
|
171338
171546
|
messages = result.messages;
|
|
171339
171547
|
}
|
|
@@ -171346,7 +171554,7 @@ ${text}` : "");
|
|
|
171346
171554
|
await new Promise((r2) => setImmediate(r2));
|
|
171347
171555
|
process.exit(process.exitCode ?? 0);
|
|
171348
171556
|
} catch (err) {
|
|
171349
|
-
const salvaged = (0,
|
|
171557
|
+
const salvaged = (0, import_code_core17.salvageHistory)(err);
|
|
171350
171558
|
if (salvaged) {
|
|
171351
171559
|
messages = salvaged;
|
|
171352
171560
|
try {
|
|
@@ -171379,12 +171587,12 @@ ${text}` : "");
|
|
|
171379
171587
|
console.log(paint.dim(" Type a message, /help for commands, or Ctrl+C to exit."));
|
|
171380
171588
|
console.log();
|
|
171381
171589
|
const footerExtras = () => {
|
|
171382
|
-
const win = (0,
|
|
171590
|
+
const win = (0, import_code_core17.contextWindowFor)(modelAlias);
|
|
171383
171591
|
return {
|
|
171384
171592
|
nav: transcriptNav ? navLabel(transcriptNav) : void 0,
|
|
171385
171593
|
model: resolveModelLabel(modelAlias),
|
|
171386
171594
|
branch: gitBranch(workDir) ?? void 0,
|
|
171387
|
-
ctxPct: messages.length ? Math.min(100, (0,
|
|
171595
|
+
ctxPct: messages.length ? Math.min(100, (0, import_code_core17.estimateTokensRough)(messages) / win * 100) : 0,
|
|
171388
171596
|
costUsd: sessionUsage.costReported ? sessionUsage.cost : void 0,
|
|
171389
171597
|
// Live sub-agents (spec §37). Recomputed per footer render, which is also what
|
|
171390
171598
|
// retires a background agent's row the moment the hub drops it.
|
|
@@ -171454,7 +171662,7 @@ ${text}` : "");
|
|
|
171454
171662
|
console.log(paint.green(` \u2713 Saved to ${saved.scope} memory`) + paint.dim(` \u2014 ${saved.file}`) + (saved.superseded ? paint.dim(" (the older fact moved to Superseded)") : ""));
|
|
171455
171663
|
}
|
|
171456
171664
|
};
|
|
171457
|
-
const allSlashEntries = () => [...BUILTIN_SLASH_COMMANDS, ...skillEntries((0,
|
|
171665
|
+
const allSlashEntries = () => [...BUILTIN_SLASH_COMMANDS, ...skillEntries((0, import_code_core17.userInvokableSkills)(skills))];
|
|
171458
171666
|
let slashRecents = loadRecents();
|
|
171459
171667
|
const syncSlashMenu = () => {
|
|
171460
171668
|
if (interactive)
|
|
@@ -171496,7 +171704,7 @@ ${text}` : "");
|
|
|
171496
171704
|
};
|
|
171497
171705
|
const modelPickerNote = (id) => {
|
|
171498
171706
|
const parts = [];
|
|
171499
|
-
const mult = (0,
|
|
171707
|
+
const mult = (0, import_code_core17.liveCostMultiplierFor)(id, MODEL_COST_MULTIPLIER[id]);
|
|
171500
171708
|
if (mult !== void 0 && mult !== 1)
|
|
171501
171709
|
parts.push(`${mult}x`);
|
|
171502
171710
|
if (needsVisionSidecar(id))
|
|
@@ -171691,7 +171899,7 @@ ${text}` : "");
|
|
|
171691
171899
|
return;
|
|
171692
171900
|
}
|
|
171693
171901
|
const row2 = matches[0];
|
|
171694
|
-
const scope =
|
|
171902
|
+
const scope = import_code_core17.McpManager.serverScope(workDir, row2.name);
|
|
171695
171903
|
if (action.kind === "detail") {
|
|
171696
171904
|
const st = _mcpManager?.getStatus().find((x2) => x2.name === row2.name);
|
|
171697
171905
|
const tools = (st?.tools ?? []).map((t2) => ({ name: t2.name, description: t2.description }));
|
|
@@ -171715,7 +171923,7 @@ ${text}` : "");
|
|
|
171715
171923
|
let signedIn = false;
|
|
171716
171924
|
let attempted = false;
|
|
171717
171925
|
if (!plan.refuse && plan.persist) {
|
|
171718
|
-
|
|
171926
|
+
import_code_core17.McpManager.setServerDisabled(workDir, row2.name, plan.persist.disabled, plan.persist.scope);
|
|
171719
171927
|
noteDisabledInConfig(row2.name, plan.persist.disabled);
|
|
171720
171928
|
}
|
|
171721
171929
|
if (!plan.refuse) {
|
|
@@ -171900,12 +172108,12 @@ ${text}` : "");
|
|
|
171900
172108
|
rl.prompt();
|
|
171901
172109
|
return;
|
|
171902
172110
|
}
|
|
171903
|
-
if ((0,
|
|
172111
|
+
if ((0, import_code_core19.evaluatePermission)(permRules, "bash", { command: cmd }, workDir) === "deny") {
|
|
171904
172112
|
console.log(paint.red(" \u2716 Denied by permission rule: bash"));
|
|
171905
172113
|
rl.prompt();
|
|
171906
172114
|
return;
|
|
171907
172115
|
}
|
|
171908
|
-
if (modeLocked && !(0,
|
|
172116
|
+
if (modeLocked && !(0, import_code_core19.isReadOnlyBash)(cmd)) {
|
|
171909
172117
|
console.log(paint.yellow(" \u2298 Read-only session (--readonly): only read-only commands can run with !."));
|
|
171910
172118
|
rl.prompt();
|
|
171911
172119
|
return;
|
|
@@ -172060,7 +172268,7 @@ ${text}` : "");
|
|
|
172060
172268
|
emitEvent("session.completed", { id: liveSessionId, reason: "clear" });
|
|
172061
172269
|
sessionId = crypto7.randomBytes(8).toString("hex");
|
|
172062
172270
|
sessionTitle = "";
|
|
172063
|
-
(0,
|
|
172271
|
+
(0, import_code_core19.resetSessionSubAgentBudget)();
|
|
172064
172272
|
sessionUsage.reset();
|
|
172065
172273
|
sessionStartedAt = Date.now();
|
|
172066
172274
|
sessionToolCalls = 0;
|
|
@@ -172156,7 +172364,7 @@ ${text}` : "");
|
|
|
172156
172364
|
startSessionLog(sessionId, true, { workDir });
|
|
172157
172365
|
const beforeCompact = messages.length;
|
|
172158
172366
|
try {
|
|
172159
|
-
await (0,
|
|
172367
|
+
await (0, import_code_core17.compactMessagesForResume)(messages, {
|
|
172160
172368
|
workDir,
|
|
172161
172369
|
model: modelAlias,
|
|
172162
172370
|
clientType: "cli"
|
|
@@ -172210,7 +172418,7 @@ ${text}` : "");
|
|
|
172210
172418
|
}
|
|
172211
172419
|
rl.pause();
|
|
172212
172420
|
console.log(paint.dim(" Compacting conversation\u2026"));
|
|
172213
|
-
await (0,
|
|
172421
|
+
await (0, import_code_core18.fireManualPreCompactHook)(workDir, sessionId, Math.max(0, messages.length - 4));
|
|
172214
172422
|
const KEEP = 4;
|
|
172215
172423
|
const toSummarize = messages.slice(0, -KEEP);
|
|
172216
172424
|
const kept = messages.slice(-KEEP);
|
|
@@ -172256,7 +172464,7 @@ ${summaryText}` }] },
|
|
|
172256
172464
|
saveSession2(sessionId, sessionTitle || "Untitled", workDir, messages);
|
|
172257
172465
|
console.log(paint.green(` Compacted ${toSummarize.length} messages \u2192 ${messages.length} messages.`));
|
|
172258
172466
|
emitEvent("context.compacted", { where: "manual", before: toSummarize.length + KEEP, after: messages.length });
|
|
172259
|
-
await (0,
|
|
172467
|
+
await (0, import_code_core18.fireManualPostCompactHook)(workDir, sessionId, toSummarize.length);
|
|
172260
172468
|
if (pin.attachments.length)
|
|
172261
172469
|
console.log(paint.dim(` ${pin.attachments.length} pinned file(s) re-attached.`));
|
|
172262
172470
|
for (const n of pin.notes)
|
|
@@ -172332,13 +172540,13 @@ ${dirList}`;
|
|
|
172332
172540
|
const sub = arg.trim().toLowerCase();
|
|
172333
172541
|
console.log();
|
|
172334
172542
|
if (sub === "list") {
|
|
172335
|
-
const all = (0,
|
|
172543
|
+
const all = (0, import_code_core17.listWorktrees)(requestedWorkDir);
|
|
172336
172544
|
if (!all.length) {
|
|
172337
172545
|
console.log(paint.dim(" No worktrees under this project."));
|
|
172338
172546
|
} else {
|
|
172339
172547
|
console.log(paint.bold(` Worktrees (${all.length})`));
|
|
172340
172548
|
for (const w of all) {
|
|
172341
|
-
const dirty = (0,
|
|
172549
|
+
const dirty = (0, import_code_core17.worktreeHasWork)(w) ? paint.yellow("dirty") : paint.dim("clean");
|
|
172342
172550
|
console.log(` ${paint.cyan(w.name)} ${paint.dim(w.worktreePath)} [${dirty}]`);
|
|
172343
172551
|
}
|
|
172344
172552
|
console.log();
|
|
@@ -172376,7 +172584,7 @@ ${dirList}`;
|
|
|
172376
172584
|
if (!targetName || !text) {
|
|
172377
172585
|
console.log(paint.dim(" Usage: /peers send <name> <message>"));
|
|
172378
172586
|
} else {
|
|
172379
|
-
const target = (0,
|
|
172587
|
+
const target = (0, import_code_core17.listPeers)().find((p) => p.name === targetName);
|
|
172380
172588
|
if (!target) {
|
|
172381
172589
|
console.log(paint.red(` No live session named "${targetName}". Use /peers to list who's reachable.`));
|
|
172382
172590
|
} else if (!target.socketPath) {
|
|
@@ -172393,7 +172601,7 @@ ${dirList}`;
|
|
|
172393
172601
|
console.log(paint.dim(" Usage: /peers broadcast <message>"));
|
|
172394
172602
|
} else {
|
|
172395
172603
|
const { broadcastPeerMessage } = await Promise.resolve().then(() => __toESM(require_dist3(), 1));
|
|
172396
|
-
const targets = (0,
|
|
172604
|
+
const targets = (0, import_code_core17.listPeers)(peerHandle.record.id).filter((p) => p.id !== peerHandle.record.id && p.socketPath && p.inbound !== "refuse").map((p) => ({ name: p.name, socketPath: p.socketPath }));
|
|
172397
172605
|
if (!targets.length) {
|
|
172398
172606
|
console.log(paint.dim(" No other reachable Nexrall Code sessions to broadcast to."));
|
|
172399
172607
|
} else {
|
|
@@ -172405,7 +172613,7 @@ ${dirList}`;
|
|
|
172405
172613
|
}
|
|
172406
172614
|
}
|
|
172407
172615
|
} else {
|
|
172408
|
-
const peers = (0,
|
|
172616
|
+
const peers = (0, import_code_core17.listPeers)(peerHandle.record.id);
|
|
172409
172617
|
if (peers.length <= 1) {
|
|
172410
172618
|
console.log(paint.dim(" No other Nexrall Code sessions are currently discoverable on this machine."));
|
|
172411
172619
|
} else {
|
|
@@ -172447,7 +172655,7 @@ ${dirList}`;
|
|
|
172447
172655
|
const label = memScope === "global" ? "GLOBAL" : "this PROJECT's";
|
|
172448
172656
|
const answer = await new Promise((resolve11) => rl.question(paint.yellow(` Clear ${label} memory? This cannot be undone. [y/n] `), (a) => resolve11(a.trim())));
|
|
172449
172657
|
if (answer === "y" || answer === "yes") {
|
|
172450
|
-
(0,
|
|
172658
|
+
(0, import_code_core17.clearMemory)(memScope, workDir);
|
|
172451
172659
|
console.log(paint.green(` ${memScope === "global" ? "Global" : "Project"} memory cleared.`));
|
|
172452
172660
|
} else {
|
|
172453
172661
|
console.log(paint.dim(" Cancelled."));
|
|
@@ -172458,20 +172666,20 @@ ${dirList}`;
|
|
|
172458
172666
|
}
|
|
172459
172667
|
console.log();
|
|
172460
172668
|
if (wantsGlobalOnly) {
|
|
172461
|
-
const stats = (0,
|
|
172462
|
-
const content = (0,
|
|
172669
|
+
const stats = (0, import_code_core17.memoryStats)("global");
|
|
172670
|
+
const content = (0, import_code_core17.readMemory)("global", void 0, { includeArchived: wantsArchived });
|
|
172463
172671
|
const archivedNote = stats.archived > 0 ? `, ${stats.archived} archived` : "";
|
|
172464
172672
|
console.log(paint.bold(" Global memory ") + paint.dim(`(${stats.entries} entries${archivedNote}, ${(stats.bytes / 1024).toFixed(1)}KB) \u2014 ${stats.file}`));
|
|
172465
172673
|
console.log();
|
|
172466
172674
|
console.log(content || paint.dim(" No global memories saved yet."));
|
|
172467
172675
|
} else {
|
|
172468
|
-
const projStats = (0,
|
|
172469
|
-
const globalStats = (0,
|
|
172676
|
+
const projStats = (0, import_code_core17.memoryStats)("project", workDir);
|
|
172677
|
+
const globalStats = (0, import_code_core17.memoryStats)("global");
|
|
172470
172678
|
const projArchived = projStats.archived > 0 ? `+${projStats.archived} archived ` : "";
|
|
172471
172679
|
const globalArchived = globalStats.archived > 0 ? `+${globalStats.archived} archived ` : "";
|
|
172472
172680
|
console.log(paint.bold(" Memory") + paint.dim(` \u2014 project: ${projStats.entries} ${projArchived}entries (${(projStats.bytes / 1024).toFixed(1)}KB) \xB7 global: ${globalStats.entries} ${globalArchived}entries (${(globalStats.bytes / 1024).toFixed(1)}KB)`));
|
|
172473
172681
|
console.log();
|
|
172474
|
-
const merged = (0,
|
|
172682
|
+
const merged = (0, import_code_core17.readAllMemory)(workDir, { includeArchived: wantsArchived });
|
|
172475
172683
|
console.log(merged || paint.dim(" No memories saved yet."));
|
|
172476
172684
|
}
|
|
172477
172685
|
console.log();
|
|
@@ -172506,12 +172714,12 @@ ${dirList}`;
|
|
|
172506
172714
|
console.log(paint.dim(` Current: ${paint.cyan(agentMode)}`));
|
|
172507
172715
|
for (const m2 of ["ask", "edit", "auto", "plan"]) {
|
|
172508
172716
|
const marker = m2 === agentMode ? paint.cyan("\u276F") : " ";
|
|
172509
|
-
console.log(` ${marker} ${paint.bold(m2.padEnd(5))} ${paint.dim((0,
|
|
172717
|
+
console.log(` ${marker} ${paint.bold(m2.padEnd(5))} ${paint.dim((0, import_code_core19.describeMode)(m2).replace(`${m2} \u2014 `, ""))}`);
|
|
172510
172718
|
}
|
|
172511
172719
|
} else if (["ask", "edit", "plan", "auto"].includes(modeArg)) {
|
|
172512
172720
|
agentMode = modeArg;
|
|
172513
172721
|
updateFooter();
|
|
172514
|
-
console.log(paint.green(` Mode \u2192 ${paint.bold(modeArg)}`) + paint.dim(` ${(0,
|
|
172722
|
+
console.log(paint.green(` Mode \u2192 ${paint.bold(modeArg)}`) + paint.dim(` ${(0, import_code_core19.describeMode)(modeArg).replace(`${modeArg} \u2014 `, "")}`));
|
|
172515
172723
|
} else {
|
|
172516
172724
|
console.log(paint.red(` Unknown: ${modeArg}`));
|
|
172517
172725
|
}
|
|
@@ -172552,22 +172760,22 @@ ${dirList}`;
|
|
|
172552
172760
|
if (target === void 0) {
|
|
172553
172761
|
console.log(paint.red(" Usage: /team use <team id|personal> (/team lists the ids)"));
|
|
172554
172762
|
} else {
|
|
172555
|
-
await (0,
|
|
172763
|
+
await (0, import_code_core17.setBillingTarget)(target);
|
|
172556
172764
|
console.log(paint.green(` \u2713 Usage will now be billed to ${target === null ? "your personal wallet" : `team ${target}`}.`));
|
|
172557
172765
|
if (target !== null)
|
|
172558
172766
|
console.log(paint.dim(" This applies to every product and client on this account, not just the CLI."));
|
|
172559
172767
|
}
|
|
172560
172768
|
} else {
|
|
172561
172769
|
try {
|
|
172562
|
-
const orgs = await (0,
|
|
172563
|
-
const pin = (0,
|
|
172770
|
+
const orgs = await (0, import_code_core17.getOrgs)();
|
|
172771
|
+
const pin = (0, import_code_core17.billingOverrideFields)();
|
|
172564
172772
|
for (const l2 of billingLines(orgs, "teamId" in pin ? pin.teamId : void 0)) {
|
|
172565
172773
|
console.log(l2.startsWith("!") ? paint.yellow(" " + l2) : " " + l2);
|
|
172566
172774
|
}
|
|
172567
172775
|
} catch (orgErr) {
|
|
172568
172776
|
if (cmd === "/team")
|
|
172569
172777
|
throw orgErr;
|
|
172570
|
-
const bal = await (0,
|
|
172778
|
+
const bal = await (0, import_code_core17.getBalance)();
|
|
172571
172779
|
console.log(paint.dim(" Balance: ") + paint.cyan(`$${bal.toFixed(4)}`));
|
|
172572
172780
|
}
|
|
172573
172781
|
}
|
|
@@ -172961,7 +173169,7 @@ ${dirList}`;
|
|
|
172961
173169
|
}
|
|
172962
173170
|
agentMode = "plan";
|
|
172963
173171
|
updateFooter();
|
|
172964
|
-
console.log(paint.green(` Mode \u2192 ${paint.bold("plan")}`) + paint.dim(` ${(0,
|
|
173172
|
+
console.log(paint.green(` Mode \u2192 ${paint.bold("plan")}`) + paint.dim(` ${(0, import_code_core19.describeMode)("plan").replace("plan \u2014 ", "")} (/mode auto to leave)`));
|
|
172965
173173
|
rl.prompt();
|
|
172966
173174
|
return;
|
|
172967
173175
|
}
|
|
@@ -172969,7 +173177,7 @@ ${dirList}`;
|
|
|
172969
173177
|
const parts2 = arg.trim().split(/\s+/).filter(Boolean);
|
|
172970
173178
|
const scope = parts2.includes("--project") ? "project" : "user";
|
|
172971
173179
|
const want = (parts2.find((x2) => x2 !== "--project") ?? "").toLowerCase();
|
|
172972
|
-
const customColorsNow = () => readThemeConfig((0,
|
|
173180
|
+
const customColorsNow = () => readThemeConfig((0, import_code_core19.loadSettings)(workDir).raw).custom;
|
|
172973
173181
|
const switchTheme = (name, persist) => {
|
|
172974
173182
|
const out = applyThemeConfig({ theme: name, custom: name === "custom" ? customColorsNow() : {}, errors: [] });
|
|
172975
173183
|
activeThemeName = name;
|
|
@@ -172987,7 +173195,7 @@ ${dirList}`;
|
|
|
172987
173195
|
const w = clearThemeKeys(workDir, scope);
|
|
172988
173196
|
if (!w.ok)
|
|
172989
173197
|
console.log(paint.yellow(` Could not write ${w.path}: ${w.error}`));
|
|
172990
|
-
const after = readThemeConfig((0,
|
|
173198
|
+
const after = readThemeConfig((0, import_code_core19.loadSettings)(workDir).raw);
|
|
172991
173199
|
const out = applyThemeConfig(after);
|
|
172992
173200
|
activeThemeName = after.theme;
|
|
172993
173201
|
console.log(" " + paint.green(`Theme reset: ${out.resolved}`) + paint.dim(` \xB7 removed theme/themeColors from ${settingsPath(workDir, scope)}`));
|
|
@@ -173078,7 +173286,7 @@ ${dirList}`;
|
|
|
173078
173286
|
}
|
|
173079
173287
|
const types3 = (() => {
|
|
173080
173288
|
try {
|
|
173081
|
-
return (0,
|
|
173289
|
+
return (0, import_code_core17.loadAgentTypesWithWarnings)(workDir).types.map((t2) => ({
|
|
173082
173290
|
name: t2.name,
|
|
173083
173291
|
description: t2.description,
|
|
173084
173292
|
...t2.tools ? { tools: t2.tools } : {},
|
|
@@ -173091,7 +173299,7 @@ ${dirList}`;
|
|
|
173091
173299
|
for (const l2 of formatPermissions({
|
|
173092
173300
|
rules: permRules,
|
|
173093
173301
|
workDir,
|
|
173094
|
-
mode: (0,
|
|
173302
|
+
mode: (0, import_code_core19.parseMode)(agentMode),
|
|
173095
173303
|
yolo: isYoloMode(),
|
|
173096
173304
|
agents: types3,
|
|
173097
173305
|
// The guard the dashboard describes is the one the handler actually runs, so the
|
|
@@ -173296,7 +173504,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
173296
173504
|
if (needsSidecar) {
|
|
173297
173505
|
console.log(paint.dim(` ${resolveModelLabel(modelAlias)} can't read ${isPdf ? "PDFs" : "images"} directly \u2014 describing ${rel} with Claude Sonnet 5.5 first\u2026`));
|
|
173298
173506
|
try {
|
|
173299
|
-
const { text } = await (0,
|
|
173507
|
+
const { text } = await (0, import_code_core17.describeAttachment)(isPdf ? "pdf" : "image", data, mimeType, rel);
|
|
173300
173508
|
content.push({ type: "text", text: `<attachment_description>
|
|
173301
173509
|
${text}
|
|
173302
173510
|
</attachment_description>` });
|
|
@@ -173340,7 +173548,7 @@ ${text}
|
|
|
173340
173548
|
process.exit(0);
|
|
173341
173549
|
}
|
|
173342
173550
|
case "/plugins": {
|
|
173343
|
-
const plugins = (0,
|
|
173551
|
+
const plugins = (0, import_code_core17.loadPlugins)(workDir);
|
|
173344
173552
|
if (!plugins.length) {
|
|
173345
173553
|
console.log(paint.dim(" No plugins installed. Install one: nex plugin install owner/repo"));
|
|
173346
173554
|
} else {
|
|
@@ -173353,7 +173561,7 @@ ${text}
|
|
|
173353
173561
|
}
|
|
173354
173562
|
console.log();
|
|
173355
173563
|
}
|
|
173356
|
-
skills = (0,
|
|
173564
|
+
skills = (0, import_code_core17.loadSkills)(workDir);
|
|
173357
173565
|
syncSlashMenu();
|
|
173358
173566
|
rl.prompt();
|
|
173359
173567
|
return;
|
|
@@ -173544,7 +173752,7 @@ ${text}
|
|
|
173544
173752
|
return;
|
|
173545
173753
|
}
|
|
173546
173754
|
case "/handoff": {
|
|
173547
|
-
const types3 = (0,
|
|
173755
|
+
const types3 = (0, import_code_core17.loadAgentTypesWithWarnings)(workDir).types.map((t2) => t2.name);
|
|
173548
173756
|
const parsed = parseHandoffArgs(arg, types3);
|
|
173549
173757
|
if ("error" in parsed) {
|
|
173550
173758
|
console.log(paint.red(" " + parsed.error));
|
|
@@ -173577,8 +173785,8 @@ ${text}
|
|
|
173577
173785
|
return;
|
|
173578
173786
|
}
|
|
173579
173787
|
const measure = measureContext(messages, parsed.all ? TOP_ALL : TOP_DEFAULT);
|
|
173580
|
-
const window2 = (0,
|
|
173581
|
-
const thresholds = (0,
|
|
173788
|
+
const window2 = (0, import_code_core17.contextWindowFor)(modelAlias);
|
|
173789
|
+
const thresholds = (0, import_code_core17.compactionThresholds)(window2);
|
|
173582
173790
|
for (const line of formatContextPanel({
|
|
173583
173791
|
measure,
|
|
173584
173792
|
window: window2,
|
|
@@ -173595,9 +173803,9 @@ ${text}
|
|
|
173595
173803
|
}
|
|
173596
173804
|
case "/skills":
|
|
173597
173805
|
case "/commands": {
|
|
173598
|
-
skills = (0,
|
|
173806
|
+
skills = (0, import_code_core17.loadSkills)(workDir);
|
|
173599
173807
|
syncSlashMenu();
|
|
173600
|
-
const invocable = (0,
|
|
173808
|
+
const invocable = (0, import_code_core17.userInvokableSkills)(skills);
|
|
173601
173809
|
if (!invocable.length) {
|
|
173602
173810
|
console.log(paint.dim(" No skills. Add .nexrall/skills/<name>/SKILL.md (or .nexrall/commands/<name>.md) to create one."));
|
|
173603
173811
|
} else {
|
|
@@ -173773,15 +173981,15 @@ ${text}
|
|
|
173773
173981
|
return;
|
|
173774
173982
|
}
|
|
173775
173983
|
default: {
|
|
173776
|
-
const custom = (0,
|
|
173984
|
+
const custom = (0, import_code_core17.findSkill)(skills, cmd);
|
|
173777
173985
|
if (!custom) {
|
|
173778
173986
|
console.log(paint.red(` Unknown command: ${cmd}`));
|
|
173779
173987
|
console.log(paint.dim(" Type /help for built-ins or /skills for custom ones."));
|
|
173780
173988
|
rl.prompt();
|
|
173781
173989
|
return;
|
|
173782
173990
|
}
|
|
173783
|
-
const expanded = (0,
|
|
173784
|
-
const turnModel = (0,
|
|
173991
|
+
const expanded = (0, import_code_core17.expandSkill)(custom, arg, workDir);
|
|
173992
|
+
const turnModel = (0, import_code_core17.resolveSubAgentModel)(custom.model, modelAlias) ?? modelAlias;
|
|
173785
173993
|
const turnMode = modeLocked ? "plan" : custom.mode ?? agentMode;
|
|
173786
173994
|
console.log(paint.dim(` Running /${custom.name}\u2026`));
|
|
173787
173995
|
checkpoints.beginTurn(`/${custom.name} ${arg}`.trim(), messages.length);
|
|
@@ -173816,7 +174024,7 @@ ${text}
|
|
|
173816
174024
|
}
|
|
173817
174025
|
checkpoints.beginTurn(userInput, messages.length);
|
|
173818
174026
|
const mentions = expandMentions(userInput, workDir, {
|
|
173819
|
-
isDenied: (abs) => (0,
|
|
174027
|
+
isDenied: (abs) => (0, import_code_core19.evaluatePermission)(permRules, "read_file", { path: abs }, workDir) === "deny"
|
|
173820
174028
|
});
|
|
173821
174029
|
for (const a of mentions.attachments) {
|
|
173822
174030
|
console.log(paint.dim(` + ${a.kind === "dir" ? a.rel + "/" : a.rel} (${a.lines} ${a.kind === "dir" ? "entries" : "lines"}${a.truncated ? ", truncated" : ""})`));
|
|
@@ -173857,7 +174065,7 @@ ${text}
|
|
|
173857
174065
|
const notes = cliBackgroundAgents.takeNotifications();
|
|
173858
174066
|
console.log(paint.dim(` \u2699 background agent${notes.length > 1 ? "s" : ""} ${notes.map((n) => `"${n.description}"`).join(", ")} finished \u2014 continuing`));
|
|
173859
174067
|
notifier.notify(bgAgentNote(notes.map((n) => n.description)));
|
|
173860
|
-
rl.emit("line", (0,
|
|
174068
|
+
rl.emit("line", (0, import_code_core17.formatBackgroundNotifications)(notes));
|
|
173861
174069
|
}, 400);
|
|
173862
174070
|
}
|
|
173863
174071
|
cliBackgroundAgents.onChange(() => {
|
|
@@ -173879,7 +174087,7 @@ ${text}
|
|
|
173879
174087
|
|
|
173880
174088
|
// src/commands/plugin.ts
|
|
173881
174089
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
173882
|
-
var
|
|
174090
|
+
var import_code_core20 = __toESM(require_dist3(), 1);
|
|
173883
174091
|
function describeInspection(i2, name, ctx) {
|
|
173884
174092
|
console.log();
|
|
173885
174093
|
console.log(paint.bold(` Plugin: ${name}`) + (i2.meta.version ? paint.dim(` v${i2.meta.version}`) : ""));
|
|
@@ -173955,14 +174163,14 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
173955
174163
|
let registryName;
|
|
173956
174164
|
const isShortName = /^[\w.-]+$/.test(spec.trim()) && !spec.includes("/");
|
|
173957
174165
|
if (isShortName) {
|
|
173958
|
-
const alias = (0,
|
|
174166
|
+
const alias = (0, import_code_core20.resolveSourceAlias)(spec.trim(), process.cwd(), { includeProject: true });
|
|
173959
174167
|
if (alias) {
|
|
173960
174168
|
source2 = alias.spec;
|
|
173961
174169
|
console.log(paint.dim(` Source: ${alias.name} (${alias.tier}) \u2190 ${alias.spec}`));
|
|
173962
174170
|
}
|
|
173963
174171
|
}
|
|
173964
174172
|
if (isShortName && source2 === spec) {
|
|
173965
|
-
const entry = await (0,
|
|
174173
|
+
const entry = await (0, import_code_core20.getRegistryPlugin)(spec.trim()).catch(() => null);
|
|
173966
174174
|
if (entry) {
|
|
173967
174175
|
source2 = entry.source;
|
|
173968
174176
|
registryName = entry.name;
|
|
@@ -173977,7 +174185,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
173977
174185
|
return;
|
|
173978
174186
|
}
|
|
173979
174187
|
}
|
|
173980
|
-
const res = await (0,
|
|
174188
|
+
const res = await (0, import_code_core20.installPlugin)(source2, {
|
|
173981
174189
|
scope,
|
|
173982
174190
|
workDir: process.cwd(),
|
|
173983
174191
|
name: opts.name ?? registryName,
|
|
@@ -173985,7 +174193,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
173985
174193
|
confirm: (i2, name, ctx) => confirmInstall(i2, name, opts.yes === true, ctx)
|
|
173986
174194
|
});
|
|
173987
174195
|
if (registryName)
|
|
173988
|
-
(0,
|
|
174196
|
+
(0, import_code_core20.reportInstall)(registryName);
|
|
173989
174197
|
console.log();
|
|
173990
174198
|
console.log(paint.green(` \u2713 Installed "${res.name}" (${res.scope}) \u2192 ${res.dir}`) + (res.sha ? paint.dim(` @ ${res.sha.slice(0, 7)}`) : ""));
|
|
173991
174199
|
if (res.inspection.commands.length) {
|
|
@@ -173999,7 +174207,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
173999
174207
|
}
|
|
174000
174208
|
function pluginRemoveCommand(name, opts) {
|
|
174001
174209
|
try {
|
|
174002
|
-
const dir = (0,
|
|
174210
|
+
const dir = (0, import_code_core20.removePlugin)(name, {
|
|
174003
174211
|
scope: opts.project ? "project" : void 0,
|
|
174004
174212
|
// no flag → search both scopes
|
|
174005
174213
|
workDir: process.cwd()
|
|
@@ -174012,14 +174220,14 @@ function pluginRemoveCommand(name, opts) {
|
|
|
174012
174220
|
}
|
|
174013
174221
|
async function pluginUpdateCommand(name, opts) {
|
|
174014
174222
|
const workDir = process.cwd();
|
|
174015
|
-
const targets = name ? [name] : (0,
|
|
174223
|
+
const targets = name ? [name] : (0, import_code_core20.loadPlugins)(workDir).filter((p) => (0, import_code_core20.readReceipt)(p.dir)?.kind === "github").map((p) => p.name);
|
|
174016
174224
|
if (!targets.length) {
|
|
174017
174225
|
console.log(paint.dim(" No updatable plugins (only GitHub-installed plugins with receipts can update)."));
|
|
174018
174226
|
return;
|
|
174019
174227
|
}
|
|
174020
174228
|
for (const t2 of targets) {
|
|
174021
174229
|
try {
|
|
174022
|
-
const res = await (0,
|
|
174230
|
+
const res = await (0, import_code_core20.updatePlugin)(t2, {
|
|
174023
174231
|
workDir,
|
|
174024
174232
|
confirm: (i2, n, ctx) => confirmInstall(i2, n, opts.yes === true, ctx)
|
|
174025
174233
|
});
|
|
@@ -174036,7 +174244,7 @@ function badgeFor(p) {
|
|
|
174036
174244
|
}
|
|
174037
174245
|
async function pluginSearchCommand(query) {
|
|
174038
174246
|
try {
|
|
174039
|
-
const results = await (0,
|
|
174247
|
+
const results = await (0, import_code_core20.searchRegistry)(query);
|
|
174040
174248
|
if (!results.length) {
|
|
174041
174249
|
console.log(paint.dim(query ? ` No plugins matching "${query}".` : " Registry is empty."));
|
|
174042
174250
|
return;
|
|
@@ -174059,7 +174267,7 @@ async function pluginSearchCommand(query) {
|
|
|
174059
174267
|
}
|
|
174060
174268
|
async function pluginInfoCommand(name) {
|
|
174061
174269
|
try {
|
|
174062
|
-
const p = await (0,
|
|
174270
|
+
const p = await (0, import_code_core20.getRegistryPlugin)(name);
|
|
174063
174271
|
if (!p) {
|
|
174064
174272
|
console.error(paint.red(` \u2717 "${name}" not found in the registry.`));
|
|
174065
174273
|
process.exitCode = 1;
|
|
@@ -174095,7 +174303,7 @@ async function pluginInfoCommand(name) {
|
|
|
174095
174303
|
}
|
|
174096
174304
|
}
|
|
174097
174305
|
function pluginListCommand() {
|
|
174098
|
-
const plugins = (0,
|
|
174306
|
+
const plugins = (0, import_code_core20.loadPlugins)(process.cwd());
|
|
174099
174307
|
if (!plugins.length) {
|
|
174100
174308
|
console.log(paint.dim(" No plugins installed."));
|
|
174101
174309
|
console.log(paint.dim(" Install one: nex plugin install owner/repo"));
|
|
@@ -174104,10 +174312,10 @@ function pluginListCommand() {
|
|
|
174104
174312
|
console.log();
|
|
174105
174313
|
console.log(paint.bold(" Installed plugins:"));
|
|
174106
174314
|
for (const p of plugins) {
|
|
174107
|
-
const receipt = (0,
|
|
174315
|
+
const receipt = (0, import_code_core20.readReceipt)(p.dir);
|
|
174108
174316
|
const src = receipt ? paint.dim(` \u2190 ${receipt.source}`) : paint.dim(" (manual)");
|
|
174109
174317
|
const at = receipt?.sha ? paint.dim(` @ ${receipt.sha.slice(0, 7)}`) : "";
|
|
174110
|
-
const insp = (0,
|
|
174318
|
+
const insp = (0, import_code_core20.inspectPluginDir)(p.dir);
|
|
174111
174319
|
const runs2 = insp.hasHooks || insp.hasMcp ? paint.yellow(` \u26A0 ${[insp.hasHooks && "hooks", insp.hasMcp && "mcp"].filter(Boolean).join("+")}`) : "";
|
|
174112
174320
|
console.log(
|
|
174113
174321
|
" " + paint.cyan(p.name.padEnd(24)) + paint.dim(`${(p.version ?? "").padEnd(10)}${p.scope.padEnd(9)}`) + src + at + runs2
|
|
@@ -174117,8 +174325,8 @@ function pluginListCommand() {
|
|
|
174117
174325
|
}
|
|
174118
174326
|
function pluginSourceListCommand() {
|
|
174119
174327
|
const workDir = process.cwd();
|
|
174120
|
-
const sources = (0,
|
|
174121
|
-
const patterns = (0,
|
|
174328
|
+
const sources = (0, import_code_core20.loadDeclaredSources)(workDir, { includeProject: true });
|
|
174329
|
+
const patterns = (0, import_code_core20.allowedSourcePatterns)();
|
|
174122
174330
|
if (patterns) {
|
|
174123
174331
|
console.log();
|
|
174124
174332
|
console.log(paint.bold(" Organisation policy: ") + paint.dim(`installs restricted to ${patterns.join(", ")}`));
|
|
@@ -174133,7 +174341,7 @@ function pluginSourceListCommand() {
|
|
|
174133
174341
|
console.log(paint.bold(" Declared plugin sources:"));
|
|
174134
174342
|
for (const s2 of sources) {
|
|
174135
174343
|
const tier2 = s2.tier === "project" ? paint.yellow(s2.tier.padEnd(9)) : paint.dim(s2.tier.padEnd(9));
|
|
174136
|
-
const blocked = !(0,
|
|
174344
|
+
const blocked = !(0, import_code_core20.isSourceAllowed)(s2.spec, patterns) ? paint.red(" \u2717 blocked by policy") : "";
|
|
174137
174345
|
console.log(" " + paint.cyan(s2.name.padEnd(20)) + tier2 + paint.white(s2.spec) + blocked);
|
|
174138
174346
|
}
|
|
174139
174347
|
console.log();
|
|
@@ -174143,17 +174351,17 @@ function pluginSourceListCommand() {
|
|
|
174143
174351
|
}
|
|
174144
174352
|
function pluginSourceAddCommand(name, spec, opts) {
|
|
174145
174353
|
try {
|
|
174146
|
-
(0,
|
|
174147
|
-
const patterns = (0,
|
|
174148
|
-
if (patterns && !(0,
|
|
174354
|
+
(0, import_code_core20.parsePluginSource)(spec);
|
|
174355
|
+
const patterns = (0, import_code_core20.allowedSourcePatterns)();
|
|
174356
|
+
if (patterns && !(0, import_code_core20.isSourceAllowed)(spec, patterns)) {
|
|
174149
174357
|
console.error(paint.red(` \u2717 "${spec}" is not permitted by your organisation's policy.`));
|
|
174150
174358
|
console.error(paint.dim(` Allowed: ${patterns.join(", ")}`));
|
|
174151
174359
|
process.exitCode = 1;
|
|
174152
174360
|
return;
|
|
174153
174361
|
}
|
|
174154
174362
|
const scope = opts.project ? "project" : "user";
|
|
174155
|
-
const file = (0,
|
|
174156
|
-
(0,
|
|
174363
|
+
const file = (0, import_code_core20.sourcesFileFor)(scope, process.cwd());
|
|
174364
|
+
(0, import_code_core20.writeDeclaredSource)(file, name, spec);
|
|
174157
174365
|
console.log();
|
|
174158
174366
|
console.log(paint.green(` \u2713 Declared "${name}" \u2192 ${spec}`) + paint.dim(` (${scope})`));
|
|
174159
174367
|
console.log(paint.dim(` ${file}`));
|
|
@@ -174167,13 +174375,13 @@ function pluginSourceAddCommand(name, spec, opts) {
|
|
|
174167
174375
|
function pluginSourceRemoveCommand(name, opts) {
|
|
174168
174376
|
const workDir = process.cwd();
|
|
174169
174377
|
const scope = opts.project ? "project" : "user";
|
|
174170
|
-
const file = (0,
|
|
174171
|
-
if ((0,
|
|
174378
|
+
const file = (0, import_code_core20.sourcesFileFor)(scope, workDir);
|
|
174379
|
+
if ((0, import_code_core20.removeDeclaredSource)(file, name)) {
|
|
174172
174380
|
console.log(paint.green(` \u2713 Removed source "${name}" (${scope})`));
|
|
174173
174381
|
console.log(paint.dim(" Plugins already installed from it are untouched \u2014 remove them with nex plugin remove <name>"));
|
|
174174
174382
|
return;
|
|
174175
174383
|
}
|
|
174176
|
-
const found = (0,
|
|
174384
|
+
const found = (0, import_code_core20.resolveSourceAlias)(name, workDir, { includeProject: true });
|
|
174177
174385
|
if (found) {
|
|
174178
174386
|
console.error(paint.red(` \u2717 "${name}" is declared in the ${found.tier} tier, not ${scope}.`));
|
|
174179
174387
|
console.error(paint.dim(` ${found.file}`));
|
|
@@ -174188,7 +174396,7 @@ function pluginSourceRemoveCommand(name, opts) {
|
|
|
174188
174396
|
}
|
|
174189
174397
|
|
|
174190
174398
|
// src/index.ts
|
|
174191
|
-
var
|
|
174399
|
+
var import_code_core22 = __toESM(require_dist3(), 1);
|
|
174192
174400
|
|
|
174193
174401
|
// src/commands/bgJobs.ts
|
|
174194
174402
|
import * as fs26 from "node:fs";
|
|
@@ -174417,7 +174625,7 @@ var program2 = new Command();
|
|
|
174417
174625
|
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version(NEX_VERSION).enablePositionalOptions();
|
|
174418
174626
|
var auth = program2.command("auth").description("Login to your Nexrall account").action(authCommand);
|
|
174419
174627
|
auth.command("status").description("Show whether you are logged in (exit 0 = yes, 1 = no). --json for scripts; the token is never printed").option("--json", "Machine-readable output").action((opts) => {
|
|
174420
|
-
const r2 = authStatusReport((0,
|
|
174628
|
+
const r2 = authStatusReport((0, import_code_core22.loadAuth)(), process.env);
|
|
174421
174629
|
if (opts.json)
|
|
174422
174630
|
console.log(JSON.stringify(r2));
|
|
174423
174631
|
else if (!r2.loggedIn)
|
|
@@ -174663,8 +174871,8 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
174663
174871
|
console.log(paint.dim(" nex sessions --events <id> [--json] to follow its event stream"));
|
|
174664
174872
|
console.log();
|
|
174665
174873
|
});
|
|
174666
|
-
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("--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 | 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("--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) => {
|
|
174667
|
-
if (!(0,
|
|
174874
|
+
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("--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 | 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) => {
|
|
174875
|
+
if (!(0, import_code_core21.isAuthenticated)()) {
|
|
174668
174876
|
console.error("Not logged in. Run: nex auth");
|
|
174669
174877
|
process.exit(1);
|
|
174670
174878
|
}
|
|
@@ -174730,11 +174938,11 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
174730
174938
|
console.error(st.error);
|
|
174731
174939
|
process.exit(1);
|
|
174732
174940
|
}
|
|
174733
|
-
(0,
|
|
174941
|
+
(0, import_code_core22.setSessionSettings)(st.value);
|
|
174734
174942
|
}
|
|
174735
174943
|
const allowRules = parseToolList(options.allowedTools);
|
|
174736
174944
|
const denyRules = parseToolList(options.disallowedTools);
|
|
174737
|
-
(0,
|
|
174945
|
+
(0, import_code_core22.setSessionRules)({ allow: allowRules, deny: denyRules });
|
|
174738
174946
|
let budgetUsd;
|
|
174739
174947
|
if (options.maxBudgetUsd !== void 0) {
|
|
174740
174948
|
const b = parseBudget(options.maxBudgetUsd);
|
|
@@ -174755,7 +174963,16 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
174755
174963
|
}
|
|
174756
174964
|
maxTurns = t2.value;
|
|
174757
174965
|
}
|
|
174758
|
-
|
|
174966
|
+
let permissionPromptTool;
|
|
174967
|
+
if (options.permissionPromptTool !== void 0) {
|
|
174968
|
+
const t2 = normalizePermissionPromptTool(options.permissionPromptTool);
|
|
174969
|
+
if (!t2.ok) {
|
|
174970
|
+
console.error(t2.error);
|
|
174971
|
+
process.exit(1);
|
|
174972
|
+
}
|
|
174973
|
+
permissionPromptTool = t2.value;
|
|
174974
|
+
}
|
|
174975
|
+
const headlessErr = checkHeadlessOnly({ outputFormat: options.outputFormat, budget: budgetUsd, noSessionPersistence: options.sessionPersistence === false, maxTurns, permissionPromptTool });
|
|
174759
174976
|
if (headlessErr) {
|
|
174760
174977
|
console.error(headlessErr);
|
|
174761
174978
|
process.exit(1);
|
|
@@ -174779,8 +174996,8 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
174779
174996
|
}
|
|
174780
174997
|
let selectedAgent;
|
|
174781
174998
|
if (options.agent) {
|
|
174782
|
-
const catalogue = (0,
|
|
174783
|
-
selectedAgent = (0,
|
|
174999
|
+
const catalogue = (0, import_code_core22.loadAgentTypesWithWarnings)(process.cwd(), extraTypes).types;
|
|
175000
|
+
selectedAgent = (0, import_code_core22.findAgentType)(catalogue, String(options.agent));
|
|
174784
175001
|
if (!selectedAgent) {
|
|
174785
175002
|
console.error(`Unknown agent "${options.agent}". Available: ${catalogue.map((t2) => t2.name).join(", ")}`);
|
|
174786
175003
|
process.exit(1);
|
|
@@ -174802,7 +175019,7 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
174802
175019
|
}
|
|
174803
175020
|
let onlyTools;
|
|
174804
175021
|
if (options.tools !== void 0) {
|
|
174805
|
-
const t2 = parseToolsFlag(options.tools === true ? "" : options.tools, (0,
|
|
175022
|
+
const t2 = parseToolsFlag(options.tools === true ? "" : options.tools, (0, import_code_core22.knownToolNames)());
|
|
174806
175023
|
if (!t2.ok) {
|
|
174807
175024
|
console.error(t2.error);
|
|
174808
175025
|
process.exit(1);
|
|
@@ -174944,7 +175161,7 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
174944
175161
|
}
|
|
174945
175162
|
effort = lvl;
|
|
174946
175163
|
}
|
|
174947
|
-
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 });
|
|
175164
|
+
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 });
|
|
174948
175165
|
});
|
|
174949
175166
|
program2.parse();
|
|
174950
175167
|
/*! Bundled license information:
|