nexrall-code 0.5.162 → 0.5.164
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 +198 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12139,11 +12139,11 @@ var require_agentTypes = __commonJS({
|
|
|
12139
12139
|
exports2.parseModel = parseModel;
|
|
12140
12140
|
exports2.parseAgentHooks = parseAgentHooks;
|
|
12141
12141
|
exports2.loadAgentTypes = loadAgentTypes;
|
|
12142
|
-
exports2.loadAgentTypesWithWarnings =
|
|
12142
|
+
exports2.loadAgentTypesWithWarnings = loadAgentTypesWithWarnings3;
|
|
12143
12143
|
exports2.knownToolNames = knownToolNames3;
|
|
12144
12144
|
exports2.builtinAgents = builtinAgents;
|
|
12145
12145
|
exports2.summariseAgents = summariseAgents;
|
|
12146
|
-
exports2.findAgentType =
|
|
12146
|
+
exports2.findAgentType = findAgentType2;
|
|
12147
12147
|
var miniYaml_1 = require_miniYaml();
|
|
12148
12148
|
var fs27 = __importStar(__require("fs"));
|
|
12149
12149
|
var path27 = __importStar(__require("path"));
|
|
@@ -12614,11 +12614,19 @@ var require_agentTypes = __commonJS({
|
|
|
12614
12614
|
throw new Error(`${where}: expected a list of hooks`);
|
|
12615
12615
|
return list.map((h2, i2) => {
|
|
12616
12616
|
const o = h2;
|
|
12617
|
+
const ms = typeof o.timeout_ms === "number" ? o.timeout_ms : typeof o.timeout === "number" ? o.timeout * 1e3 : void 0;
|
|
12618
|
+
const timeout = ms && ms > 0 ? { timeout_ms: ms } : {};
|
|
12619
|
+
if (o && o.type === "http" && typeof o.url === "string" && o.url.trim()) {
|
|
12620
|
+
if (!/^https?:\/\//i.test(o.url.trim()))
|
|
12621
|
+
throw new Error(`${where}[${i2}]: http hooks need an http(s) url`);
|
|
12622
|
+
const headers = o.headers && typeof o.headers === "object" && !Array.isArray(o.headers) ? o.headers : void 0;
|
|
12623
|
+
const allowed = Array.isArray(o.allowedEnvVars) ? o.allowedEnvVars.filter((v2) => typeof v2 === "string") : void 0;
|
|
12624
|
+
return { type: "http", url: o.url.trim(), ...headers ? { headers } : {}, ...allowed ? { allowedEnvVars: allowed } : {}, ...timeout };
|
|
12625
|
+
}
|
|
12617
12626
|
if (!o || o.type !== "command" || typeof o.command !== "string" || !o.command.trim()) {
|
|
12618
|
-
throw new Error(`${where}[${i2}]: each hook needs type: command and a command`);
|
|
12627
|
+
throw new Error(`${where}[${i2}]: each hook needs type: command and a command, or type: http and a url`);
|
|
12619
12628
|
}
|
|
12620
|
-
|
|
12621
|
-
return { type: "command", command: o.command, ...ms && ms > 0 ? { timeout_ms: ms } : {} };
|
|
12629
|
+
return { type: "command", command: o.command, ...timeout };
|
|
12622
12630
|
});
|
|
12623
12631
|
};
|
|
12624
12632
|
const entries = (list, ev) => {
|
|
@@ -12677,9 +12685,9 @@ var require_agentTypes = __commonJS({
|
|
|
12677
12685
|
return out;
|
|
12678
12686
|
}
|
|
12679
12687
|
function loadAgentTypes(workDir) {
|
|
12680
|
-
return
|
|
12688
|
+
return loadAgentTypesWithWarnings3(workDir).types;
|
|
12681
12689
|
}
|
|
12682
|
-
function
|
|
12690
|
+
function loadAgentTypesWithWarnings3(workDir, extra = []) {
|
|
12683
12691
|
const out = /* @__PURE__ */ new Map();
|
|
12684
12692
|
const warnings = [];
|
|
12685
12693
|
loadDir(path27.join(workDir, ".nexrall", "agents"), "project", out, warnings);
|
|
@@ -12734,7 +12742,7 @@ var require_agentTypes = __commonJS({
|
|
|
12734
12742
|
"write_xlsx",
|
|
12735
12743
|
"write_pptx"
|
|
12736
12744
|
]);
|
|
12737
|
-
function
|
|
12745
|
+
function findAgentType2(types3, name) {
|
|
12738
12746
|
if (!name)
|
|
12739
12747
|
return void 0;
|
|
12740
12748
|
const want = name.trim().toLowerCase();
|
|
@@ -107063,6 +107071,42 @@ var require_loop = __commonJS({
|
|
|
107063
107071
|
child.stdin?.end(opts.input ?? "");
|
|
107064
107072
|
});
|
|
107065
107073
|
}
|
|
107074
|
+
async function httpHook(hook, payload, timeoutMs) {
|
|
107075
|
+
const url = String(hook.url ?? "");
|
|
107076
|
+
if (!/^https?:\/\//i.test(url))
|
|
107077
|
+
return { status: 1, stdout: "", stderr: `hook url must be http(s): ${url}` };
|
|
107078
|
+
const headers = { "content-type": "application/json" };
|
|
107079
|
+
const allowed = new Set(hook.allowedEnvVars ?? []);
|
|
107080
|
+
for (const [k, v] of Object.entries(hook.headers ?? {})) {
|
|
107081
|
+
headers[k] = String(v).replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g, (_m, a1, a2) => allowed.has(a1 ?? a2) ? process.env[a1 ?? a2] ?? "" : "");
|
|
107082
|
+
}
|
|
107083
|
+
try {
|
|
107084
|
+
const res = await fetch(url, { method: "POST", headers, body: payload, signal: AbortSignal.timeout(timeoutMs) });
|
|
107085
|
+
const text = (await res.text()).trim();
|
|
107086
|
+
if (res.status < 200 || res.status >= 300) {
|
|
107087
|
+
return { status: 1, stdout: "", stderr: `hook returned HTTP ${res.status}` };
|
|
107088
|
+
}
|
|
107089
|
+
if (!text)
|
|
107090
|
+
return { status: 0, stdout: "", stderr: "" };
|
|
107091
|
+
if (text.startsWith("{"))
|
|
107092
|
+
return { status: 0, stdout: text, stderr: "" };
|
|
107093
|
+
return { status: 1, stdout: "", stderr: "hook returned a non-JSON body" };
|
|
107094
|
+
} catch (err) {
|
|
107095
|
+
return { status: 1, stdout: "", stderr: `hook request failed: ${err.message}` };
|
|
107096
|
+
}
|
|
107097
|
+
}
|
|
107098
|
+
async function runHookHandler(hook, payload, opts) {
|
|
107099
|
+
if (hook.type === "http")
|
|
107100
|
+
return httpHook(hook, payload, opts.timeoutMs);
|
|
107101
|
+
return spawnHook(String(hook.command ?? ""), { cwd: opts.cwd, timeout: opts.timeoutMs, input: payload, env: opts.env });
|
|
107102
|
+
}
|
|
107103
|
+
function hookTimeoutMs(hook, fallbackMs = 6e4) {
|
|
107104
|
+
if (typeof hook.timeout_ms === "number" && hook.timeout_ms > 0)
|
|
107105
|
+
return Math.min(hook.timeout_ms, 6e5);
|
|
107106
|
+
if (typeof hook.timeout === "number" && hook.timeout > 0)
|
|
107107
|
+
return Math.min(hook.timeout * 1e3, 6e5);
|
|
107108
|
+
return fallbackMs;
|
|
107109
|
+
}
|
|
107066
107110
|
function hookMatches(matcher, toolName) {
|
|
107067
107111
|
if (!matcher || matcher === "*")
|
|
107068
107112
|
return true;
|
|
@@ -107085,13 +107129,16 @@ var require_loop = __commonJS({
|
|
|
107085
107129
|
if (!hookMatches(entry.matcher, toolName))
|
|
107086
107130
|
continue;
|
|
107087
107131
|
for (const hook of entry.hooks ?? []) {
|
|
107088
|
-
if (hook.type !== "command"
|
|
107132
|
+
if (hook.type !== "command" && hook.type !== "http")
|
|
107133
|
+
continue;
|
|
107134
|
+
if (hook.type === "command" && !hook.command)
|
|
107089
107135
|
continue;
|
|
107090
|
-
|
|
107091
|
-
|
|
107136
|
+
if (hook.type === "http" && !hook.url)
|
|
107137
|
+
continue;
|
|
107138
|
+
const hookTimeout = hookTimeoutMs(hook, 6e4);
|
|
107139
|
+
const r2 = await runHookHandler(hook, payload, {
|
|
107092
107140
|
cwd: workDir,
|
|
107093
|
-
|
|
107094
|
-
input: payload,
|
|
107141
|
+
timeoutMs: hookTimeout,
|
|
107095
107142
|
env: {
|
|
107096
107143
|
...process.env,
|
|
107097
107144
|
NEXRALL_TOOL_NAME: toolName,
|
|
@@ -107126,9 +107173,13 @@ var require_loop = __commonJS({
|
|
|
107126
107173
|
if (!defs?.length)
|
|
107127
107174
|
return;
|
|
107128
107175
|
for (const hook of defs) {
|
|
107129
|
-
if (hook.type
|
|
107130
|
-
|
|
107131
|
-
|
|
107176
|
+
if (hook.type !== "command" && hook.type !== "http")
|
|
107177
|
+
continue;
|
|
107178
|
+
if (hook.type === "command" && !hook.command)
|
|
107179
|
+
continue;
|
|
107180
|
+
if (hook.type === "http" && !hook.url)
|
|
107181
|
+
continue;
|
|
107182
|
+
await runHookHandler(hook, "", { cwd: workDir, timeoutMs: hookTimeoutMs(hook, 1e4), env: extraEnv ? { ...process.env, ...extraEnv } : void 0 });
|
|
107132
107183
|
}
|
|
107133
107184
|
}
|
|
107134
107185
|
function flattenHookDefs(items, matchValue) {
|
|
@@ -107139,7 +107190,7 @@ var require_loop = __commonJS({
|
|
|
107139
107190
|
if (m2 && m2 !== "*" && matchValue !== void 0 && !m2.split("|").map((x2) => x2.trim()).includes(matchValue))
|
|
107140
107191
|
continue;
|
|
107141
107192
|
out.push(...it.hooks);
|
|
107142
|
-
} else if (it && it.type === "command")
|
|
107193
|
+
} else if (it && (it.type === "command" || it.type === "http"))
|
|
107143
107194
|
out.push(it);
|
|
107144
107195
|
}
|
|
107145
107196
|
return out;
|
|
@@ -107151,10 +107202,14 @@ var require_loop = __commonJS({
|
|
|
107151
107202
|
return outcome;
|
|
107152
107203
|
const input = JSON.stringify({ hook_event_name: event, cwd: workDir, ...payload });
|
|
107153
107204
|
for (const hook of defs) {
|
|
107154
|
-
if (
|
|
107205
|
+
if (hook.type !== "command" && hook.type !== "http")
|
|
107206
|
+
continue;
|
|
107207
|
+
if (hook.type === "command" && !hook.command)
|
|
107155
107208
|
continue;
|
|
107156
|
-
|
|
107157
|
-
|
|
107209
|
+
if (hook.type === "http" && !hook.url)
|
|
107210
|
+
continue;
|
|
107211
|
+
const timeout = hookTimeoutMs(hook, 3e4);
|
|
107212
|
+
const r2 = await runHookHandler(hook, input, { cwd: workDir, timeoutMs: timeout, env: { ...process.env, NEXRALL_HOOK_PHASE: event } });
|
|
107158
107213
|
const out = (r2.stdout ?? "").toString().trim();
|
|
107159
107214
|
if (out.startsWith("{")) {
|
|
107160
107215
|
try {
|
|
@@ -152355,6 +152410,54 @@ function initEventPayload(i2) {
|
|
|
152355
152410
|
function userReplayPayload(text) {
|
|
152356
152411
|
return { type: "user", message: { role: "user", content: [{ type: "text", text }] } };
|
|
152357
152412
|
}
|
|
152413
|
+
function parseAgentsArg(raw, cwd2) {
|
|
152414
|
+
if (raw === void 0)
|
|
152415
|
+
return { ok: true, value: [] };
|
|
152416
|
+
const text = String(raw).trim();
|
|
152417
|
+
if (!text)
|
|
152418
|
+
return { ok: false, error: "--agents: the value is empty." };
|
|
152419
|
+
let json = text;
|
|
152420
|
+
const looksLikePath = text.startsWith("@") || !text.startsWith("{") && fs6.existsSync(path7.resolve(cwd2, text));
|
|
152421
|
+
if (looksLikePath) {
|
|
152422
|
+
const file = text.startsWith("@") ? text.slice(1) : text;
|
|
152423
|
+
try {
|
|
152424
|
+
json = fs6.readFileSync(path7.resolve(cwd2, file), "utf-8");
|
|
152425
|
+
} catch (e2) {
|
|
152426
|
+
return { ok: false, error: `--agents: cannot read ${file}: ${e2.message}` };
|
|
152427
|
+
}
|
|
152428
|
+
}
|
|
152429
|
+
let obj2;
|
|
152430
|
+
try {
|
|
152431
|
+
obj2 = JSON.parse(json);
|
|
152432
|
+
} catch (e2) {
|
|
152433
|
+
return { ok: false, error: `--agents: not valid JSON: ${e2.message}` };
|
|
152434
|
+
}
|
|
152435
|
+
if (!obj2 || typeof obj2 !== "object" || Array.isArray(obj2)) {
|
|
152436
|
+
return { ok: false, error: '--agents: expected an object of { "name": { "description", "prompt" } }.' };
|
|
152437
|
+
}
|
|
152438
|
+
const out = [];
|
|
152439
|
+
for (const [name, v] of Object.entries(obj2)) {
|
|
152440
|
+
const a = v ?? {};
|
|
152441
|
+
if (!/^[A-Za-z0-9._-]+$/.test(name)) {
|
|
152442
|
+
return { ok: false, error: `--agents: "${name}" is not a usable agent name (letters, digits, . _ - only).` };
|
|
152443
|
+
}
|
|
152444
|
+
if (typeof a.description !== "string" || !a.description.trim()) {
|
|
152445
|
+
return { ok: false, error: `--agents: "${name}" needs a description (that is how the model decides to use it).` };
|
|
152446
|
+
}
|
|
152447
|
+
if (typeof a.prompt !== "string" || !a.prompt.trim()) {
|
|
152448
|
+
return { ok: false, error: `--agents: "${name}" needs a prompt (the agent's instructions).` };
|
|
152449
|
+
}
|
|
152450
|
+
const tools = Array.isArray(a.tools) ? a.tools.filter((t2) => typeof t2 === "string" && !!t2.trim()) : void 0;
|
|
152451
|
+
if (a.tools !== void 0 && (!tools || tools.length !== a.tools.length)) {
|
|
152452
|
+
return { ok: false, error: `--agents: "${name}".tools must be a list of tool names.` };
|
|
152453
|
+
}
|
|
152454
|
+
const model = typeof a.model === "string" && a.model.trim() ? a.model.trim() : void 0;
|
|
152455
|
+
out.push({ name, description: a.description.trim(), prompt: a.prompt, ...tools ? { tools } : {}, ...model ? { model } : {} });
|
|
152456
|
+
}
|
|
152457
|
+
if (!out.length)
|
|
152458
|
+
return { ok: false, error: "--agents: no agents defined." };
|
|
152459
|
+
return { ok: true, value: out };
|
|
152460
|
+
}
|
|
152358
152461
|
|
|
152359
152462
|
// src/commands/chat.ts
|
|
152360
152463
|
var import_code_core17 = __toESM(require_dist3(), 1);
|
|
@@ -168246,6 +168349,7 @@ function refreshEnvForTurn(env4, workDir) {
|
|
|
168246
168349
|
};
|
|
168247
168350
|
}
|
|
168248
168351
|
var noDiscovery = false;
|
|
168352
|
+
var _cliAgentTypes = [];
|
|
168249
168353
|
function setNoDiscovery(v) {
|
|
168250
168354
|
noDiscovery = v;
|
|
168251
168355
|
}
|
|
@@ -168958,6 +169062,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
168958
169062
|
},
|
|
168959
169063
|
backgroundAgents: cliBackgroundAgents,
|
|
168960
169064
|
disableHooks: noDiscovery,
|
|
169065
|
+
_extraAgentTypes: _cliAgentTypes,
|
|
168961
169066
|
// The backend streams a cumulative output-token count (routes/code.js's
|
|
168962
169067
|
// sendProgress, throttled to ≤5/s) covering thinking, visible text AND
|
|
168963
169068
|
// tool-argument JSON. This used to be stored in a variable and rendered only
|
|
@@ -169280,6 +169385,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169280
169385
|
worktree: worktreeState,
|
|
169281
169386
|
backgroundAgents: cliBackgroundAgents,
|
|
169282
169387
|
disableHooks: noDiscovery,
|
|
169388
|
+
_extraAgentTypes: _cliAgentTypes,
|
|
169283
169389
|
effort,
|
|
169284
169390
|
abortSignal: _abortSignal,
|
|
169285
169391
|
// `--max-turns`: a hard round cap. autoContinue off, or the loop would extend it.
|
|
@@ -169654,6 +169760,7 @@ function printSessions() {
|
|
|
169654
169760
|
async function startChatSession(options) {
|
|
169655
169761
|
if (options.bare)
|
|
169656
169762
|
setNoDiscovery(true);
|
|
169763
|
+
_cliAgentTypes = (options.agents ?? []).map((a) => ({ ...a, source: "programmatic" }));
|
|
169657
169764
|
(0, import_code_core15.enableAgentTranscriptPersistence)();
|
|
169658
169765
|
const headless = options.outputFormat === "json" || options.outputFormat === "stream-json";
|
|
169659
169766
|
const requestedWorkDir = options.workDir;
|
|
@@ -169750,8 +169857,11 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169750
169857
|
}
|
|
169751
169858
|
const env4 = collectEnv(workDir);
|
|
169752
169859
|
const briefBase = options.systemPrompt?.trim() ?? readNexrallMd(workDir);
|
|
169753
|
-
const
|
|
169754
|
-
|
|
169860
|
+
const agentPrefix = options.selectedAgent?.prompt?.trim();
|
|
169861
|
+
const nexrallMd = [agentPrefix, briefBase, options.appendSystemPrompt?.trim(), addDirNote(options.addDirs ?? []), options.jsonSchema ? schemaInstruction(options.jsonSchema) : ""].filter(Boolean).join("\n\n") || void 0;
|
|
169862
|
+
const agentTools = options.selectedAgent?.tools;
|
|
169863
|
+
const toolAllow = agentTools && options.onlyTools ? options.onlyTools.filter((t2) => agentTools.includes(t2)) : options.onlyTools ?? agentTools;
|
|
169864
|
+
_headlessPolicy = { strict: !!options.strictPermissions, budgetUsd: options.budgetUsd, spent: 0, schema: options.jsonSchema, maxTurns: options.maxTurns, onlyTools: toolAllow ? new Set(toolAllow) : void 0 };
|
|
169755
169865
|
_headlessPolicy.verbose = !!options.verbose;
|
|
169756
169866
|
_headlessPolicy.includePartial = !!options.includePartialMessages;
|
|
169757
169867
|
_headlessPolicy.permissionMode = String(options.initialMode ?? "");
|
|
@@ -172982,6 +173092,17 @@ function killJob(job, dir = bgDir()) {
|
|
|
172982
173092
|
}
|
|
172983
173093
|
}
|
|
172984
173094
|
}
|
|
173095
|
+
function removeJob(job, dir = bgDir()) {
|
|
173096
|
+
if (job.state === "running")
|
|
173097
|
+
return { ok: false, error: `Job ${job.id} is still running \u2014 stop it first (nex kill ${job.id}).` };
|
|
173098
|
+
for (const suffix of [".json", ".log", ".code", ".killed"]) {
|
|
173099
|
+
try {
|
|
173100
|
+
fs25.rmSync(path25.join(dir, job.id + suffix), { force: true });
|
|
173101
|
+
} catch {
|
|
173102
|
+
}
|
|
173103
|
+
}
|
|
173104
|
+
return { ok: true };
|
|
173105
|
+
}
|
|
172985
173106
|
var ago = (t2) => {
|
|
172986
173107
|
const s2 = Math.max(0, Math.round((Date.now() - t2) / 1e3));
|
|
172987
173108
|
return s2 < 90 ? `${s2}s` : s2 < 5400 ? `${Math.round(s2 / 60)}m` : `${Math.round(s2 / 3600)}h`;
|
|
@@ -173357,6 +173478,33 @@ program2.command("attach <id>").description("Watch a background job live, readab
|
|
|
173357
173478
|
}
|
|
173358
173479
|
process.exit(await followLog(r2.job, true, void 0, void 0, true));
|
|
173359
173480
|
});
|
|
173481
|
+
program2.command("stop <id>").description("Stop a running background job (same as kill; matches Claude Code's name)").action((id) => {
|
|
173482
|
+
const r2 = resolveJob(id);
|
|
173483
|
+
if (!r2.ok) {
|
|
173484
|
+
console.error(r2.error);
|
|
173485
|
+
process.exit(1);
|
|
173486
|
+
}
|
|
173487
|
+
if (!killJob(r2.job)) {
|
|
173488
|
+
console.error(`Job ${r2.job.id} is not running (${r2.job.state}).`);
|
|
173489
|
+
process.exit(1);
|
|
173490
|
+
}
|
|
173491
|
+
console.log(`Stopped job ${r2.job.id}`);
|
|
173492
|
+
process.exit(0);
|
|
173493
|
+
});
|
|
173494
|
+
program2.command("rm <id>").description("Delete a finished background job's records (log included)").action((id) => {
|
|
173495
|
+
const r2 = resolveJob(id);
|
|
173496
|
+
if (!r2.ok) {
|
|
173497
|
+
console.error(r2.error);
|
|
173498
|
+
process.exit(1);
|
|
173499
|
+
}
|
|
173500
|
+
const res = removeJob(r2.job);
|
|
173501
|
+
if (!res.ok) {
|
|
173502
|
+
console.error(res.error);
|
|
173503
|
+
process.exit(1);
|
|
173504
|
+
}
|
|
173505
|
+
console.log(`Removed job ${r2.job.id}`);
|
|
173506
|
+
process.exit(0);
|
|
173507
|
+
});
|
|
173360
173508
|
program2.command("kill <id>").description("Stop a background job").action((id) => {
|
|
173361
173509
|
const r2 = resolveJob(id);
|
|
173362
173510
|
if (!r2.ok) {
|
|
@@ -173501,7 +173649,7 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
173501
173649
|
console.log(paint.dim(" nex sessions --events <id> [--json] to follow its event stream"));
|
|
173502
173650
|
console.log();
|
|
173503
173651
|
});
|
|
173504
|
-
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("--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) => {
|
|
173652
|
+
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) => {
|
|
173505
173653
|
if (!(0, import_code_core20.isAuthenticated)()) {
|
|
173506
173654
|
console.error("Not logged in. Run: nex auth");
|
|
173507
173655
|
process.exit(1);
|
|
@@ -173598,6 +173746,32 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173598
173746
|
console.error(headlessErr);
|
|
173599
173747
|
process.exit(1);
|
|
173600
173748
|
}
|
|
173749
|
+
const agentsParsed = parseAgentsArg(options.agents, process.cwd());
|
|
173750
|
+
if (!agentsParsed.ok) {
|
|
173751
|
+
console.error(agentsParsed.error);
|
|
173752
|
+
process.exit(1);
|
|
173753
|
+
}
|
|
173754
|
+
const extraTypes = agentsParsed.value.map((a) => ({
|
|
173755
|
+
name: a.name,
|
|
173756
|
+
description: a.description,
|
|
173757
|
+
prompt: a.prompt,
|
|
173758
|
+
source: "programmatic",
|
|
173759
|
+
...a.tools ? { tools: a.tools } : {},
|
|
173760
|
+
...a.model ? { model: a.model } : {}
|
|
173761
|
+
}));
|
|
173762
|
+
if (options.agent && options.bare) {
|
|
173763
|
+
console.error("--agent needs agent discovery, which --bare/--safe-mode turns off \u2014 drop one of them.");
|
|
173764
|
+
process.exit(1);
|
|
173765
|
+
}
|
|
173766
|
+
let selectedAgent;
|
|
173767
|
+
if (options.agent) {
|
|
173768
|
+
const catalogue = (0, import_code_core21.loadAgentTypesWithWarnings)(process.cwd(), extraTypes).types;
|
|
173769
|
+
selectedAgent = (0, import_code_core21.findAgentType)(catalogue, String(options.agent));
|
|
173770
|
+
if (!selectedAgent) {
|
|
173771
|
+
console.error(`Unknown agent "${options.agent}". Available: ${catalogue.map((t2) => t2.name).join(", ")}`);
|
|
173772
|
+
process.exit(1);
|
|
173773
|
+
}
|
|
173774
|
+
}
|
|
173601
173775
|
const sysPrompt = resolveSystemPrompt({ text: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0, file: options.systemPromptFile, cwd: process.cwd() });
|
|
173602
173776
|
if (!sysPrompt.ok) {
|
|
173603
173777
|
console.error(sysPrompt.error);
|
|
@@ -173756,7 +173930,7 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173756
173930
|
}
|
|
173757
173931
|
effort = lvl;
|
|
173758
173932
|
}
|
|
173759
|
-
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, 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 });
|
|
173933
|
+
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 });
|
|
173760
173934
|
});
|
|
173761
173935
|
program2.parse();
|
|
173762
173936
|
/*! Bundled license information:
|