nexrall-code 0.5.161 → 0.5.162
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 +501 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3186,7 +3186,7 @@ var require_auth = __commonJS({
|
|
|
3186
3186
|
}();
|
|
3187
3187
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3188
3188
|
exports2.saveAuth = saveAuth2;
|
|
3189
|
-
exports2.loadAuth =
|
|
3189
|
+
exports2.loadAuth = loadAuth3;
|
|
3190
3190
|
exports2.clearAuth = clearAuth2;
|
|
3191
3191
|
exports2.isAuthenticated = isAuthenticated4;
|
|
3192
3192
|
exports2.getToken = getToken2;
|
|
@@ -3207,7 +3207,7 @@ var require_auth = __commonJS({
|
|
|
3207
3207
|
ensureConfigDir();
|
|
3208
3208
|
fs27.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 384 });
|
|
3209
3209
|
}
|
|
3210
|
-
function
|
|
3210
|
+
function loadAuth3() {
|
|
3211
3211
|
const envToken = process.env.NEXRALL_TOKEN;
|
|
3212
3212
|
if (envToken && envToken.trim().length > 0) {
|
|
3213
3213
|
return { token: envToken.trim() };
|
|
@@ -3235,19 +3235,19 @@ var require_auth = __commonJS({
|
|
|
3235
3235
|
}
|
|
3236
3236
|
}
|
|
3237
3237
|
function isAuthenticated4() {
|
|
3238
|
-
const
|
|
3239
|
-
return
|
|
3238
|
+
const auth2 = loadAuth3();
|
|
3239
|
+
return auth2 !== null && auth2.token.length > 0;
|
|
3240
3240
|
}
|
|
3241
3241
|
function getToken2() {
|
|
3242
|
-
const
|
|
3243
|
-
return
|
|
3242
|
+
const auth2 = loadAuth3();
|
|
3243
|
+
return auth2?.token ?? null;
|
|
3244
3244
|
}
|
|
3245
3245
|
function getRefreshToken() {
|
|
3246
3246
|
const envToken = process.env.NEXRALL_TOKEN;
|
|
3247
3247
|
if (envToken && envToken.trim().length > 0)
|
|
3248
3248
|
return null;
|
|
3249
|
-
const
|
|
3250
|
-
const rt =
|
|
3249
|
+
const auth2 = loadAuth3();
|
|
3250
|
+
const rt = auth2?.refreshToken;
|
|
3251
3251
|
return typeof rt === "string" && rt.length > 0 ? rt : null;
|
|
3252
3252
|
}
|
|
3253
3253
|
function updateTokens(token, refreshToken) {
|
|
@@ -12140,7 +12140,7 @@ var require_agentTypes = __commonJS({
|
|
|
12140
12140
|
exports2.parseAgentHooks = parseAgentHooks;
|
|
12141
12141
|
exports2.loadAgentTypes = loadAgentTypes;
|
|
12142
12142
|
exports2.loadAgentTypesWithWarnings = loadAgentTypesWithWarnings2;
|
|
12143
|
-
exports2.knownToolNames =
|
|
12143
|
+
exports2.knownToolNames = knownToolNames3;
|
|
12144
12144
|
exports2.builtinAgents = builtinAgents;
|
|
12145
12145
|
exports2.summariseAgents = summariseAgents;
|
|
12146
12146
|
exports2.findAgentType = findAgentType;
|
|
@@ -12706,7 +12706,7 @@ var require_agentTypes = __commonJS({
|
|
|
12706
12706
|
});
|
|
12707
12707
|
return { types: types3, warnings };
|
|
12708
12708
|
}
|
|
12709
|
-
function
|
|
12709
|
+
function knownToolNames3() {
|
|
12710
12710
|
return [...KNOWN_TOOL_NAMES].sort();
|
|
12711
12711
|
}
|
|
12712
12712
|
function builtinAgents() {
|
|
@@ -104672,6 +104672,8 @@ var require_rules = __commonJS({
|
|
|
104672
104672
|
}();
|
|
104673
104673
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
104674
104674
|
exports2.setSessionRules = setSessionRules2;
|
|
104675
|
+
exports2.setSessionSettings = setSessionSettings2;
|
|
104676
|
+
exports2.getSessionSettings = getSessionSettings;
|
|
104675
104677
|
exports2.loadSettings = loadSettings5;
|
|
104676
104678
|
exports2.evaluatePermission = evaluatePermission4;
|
|
104677
104679
|
var fs27 = __importStar(__require("fs"));
|
|
@@ -104700,6 +104702,13 @@ var require_rules = __commonJS({
|
|
|
104700
104702
|
function setSessionRules2(r2) {
|
|
104701
104703
|
sessionRules = { allow: [...r2.allow ?? []], ask: [...r2.ask ?? []], deny: [...r2.deny ?? []] };
|
|
104702
104704
|
}
|
|
104705
|
+
var sessionSettings = null;
|
|
104706
|
+
function setSessionSettings2(obj2) {
|
|
104707
|
+
sessionSettings = obj2;
|
|
104708
|
+
}
|
|
104709
|
+
function getSessionSettings() {
|
|
104710
|
+
return sessionSettings;
|
|
104711
|
+
}
|
|
104703
104712
|
function loadSettings5(workDir) {
|
|
104704
104713
|
const tiers = [
|
|
104705
104714
|
managedSettingsPath(),
|
|
@@ -104719,6 +104728,13 @@ var require_rules = __commonJS({
|
|
|
104719
104728
|
merged.ask.push(...r2.ask);
|
|
104720
104729
|
merged.deny.push(...r2.deny);
|
|
104721
104730
|
}
|
|
104731
|
+
if (sessionSettings) {
|
|
104732
|
+
Object.assign(raw, sessionSettings);
|
|
104733
|
+
const r2 = extractRules(sessionSettings);
|
|
104734
|
+
merged.allow.push(...r2.allow);
|
|
104735
|
+
merged.ask.push(...r2.ask);
|
|
104736
|
+
merged.deny.push(...r2.deny);
|
|
104737
|
+
}
|
|
104722
104738
|
merged.allow.push(...sessionRules.allow);
|
|
104723
104739
|
merged.ask.push(...sessionRules.ask);
|
|
104724
104740
|
merged.deny.push(...sessionRules.deny);
|
|
@@ -106887,7 +106903,9 @@ var require_loop = __commonJS({
|
|
|
106887
106903
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
106888
106904
|
exports2.VERIFY_CMD_RE = exports2.WRITE_TOOL_NAMES = exports2.ToolNotAllowedError = exports2.AGENT_MEMORY_TOOL_SCHEMA = exports2.AGENT_MEMORY_TOOL = exports2._stallLimits = exports2._emptyTurnRetry = exports2.bashNeedsRepoLock = void 0;
|
|
106889
106905
|
exports2.runLifecycleHooks = runLifecycleHooks;
|
|
106906
|
+
exports2.runPermissionRequestHooks = runPermissionRequestHooks2;
|
|
106890
106907
|
exports2.fireNotificationHooks = fireNotificationHooks2;
|
|
106908
|
+
exports2.fireManualPostCompactHook = fireManualPostCompactHook2;
|
|
106891
106909
|
exports2.fireManualPreCompactHook = fireManualPreCompactHook2;
|
|
106892
106910
|
exports2.emptyTurnBackoffMs = emptyTurnBackoffMs;
|
|
106893
106911
|
exports2.shouldRetryEmptyTurn = shouldRetryEmptyTurn;
|
|
@@ -106981,6 +106999,15 @@ var require_loop = __commonJS({
|
|
|
106981
106999
|
fromSettings = JSON.parse(fs27.readFileSync(p, "utf-8")).hooks ?? {};
|
|
106982
107000
|
} catch {
|
|
106983
107001
|
}
|
|
107002
|
+
const sess = (0, rules_1.getSessionSettings)()?.hooks;
|
|
107003
|
+
if (sess && typeof sess === "object") {
|
|
107004
|
+
const base = { ...fromSettings };
|
|
107005
|
+
for (const [phase, list] of Object.entries(sess)) {
|
|
107006
|
+
if (Array.isArray(list))
|
|
107007
|
+
base[phase] = [...base[phase] ?? [], ...list];
|
|
107008
|
+
}
|
|
107009
|
+
fromSettings = base;
|
|
107010
|
+
}
|
|
106984
107011
|
const fromPlugins = (0, index_1.pluginHooks)(workDir);
|
|
106985
107012
|
const merged = { ...fromSettings };
|
|
106986
107013
|
for (const phase of Object.keys(fromPlugins)) {
|
|
@@ -107132,6 +107159,15 @@ var require_loop = __commonJS({
|
|
|
107132
107159
|
if (out.startsWith("{")) {
|
|
107133
107160
|
try {
|
|
107134
107161
|
const j = JSON.parse(out);
|
|
107162
|
+
if (event === "PermissionRequest") {
|
|
107163
|
+
const d = j.hookSpecificOutput?.decision?.behavior ?? (typeof j.decision === "string" ? j.decision : j.decision?.behavior);
|
|
107164
|
+
if (d === "allow" || d === "approve")
|
|
107165
|
+
outcome.allow = true;
|
|
107166
|
+
else if (d === "deny" || d === "block") {
|
|
107167
|
+
outcome.block = true;
|
|
107168
|
+
outcome.reason = j.reason ?? j.hookSpecificOutput?.decision?.message ?? outcome.reason ?? "Denied by PermissionRequest hook";
|
|
107169
|
+
}
|
|
107170
|
+
}
|
|
107135
107171
|
if (j.decision === "block") {
|
|
107136
107172
|
outcome.block = true;
|
|
107137
107173
|
outcome.reason = j.reason ?? outcome.reason ?? `Blocked by ${event} hook`;
|
|
@@ -107150,6 +107186,20 @@ var require_loop = __commonJS({
|
|
|
107150
107186
|
}
|
|
107151
107187
|
return outcome;
|
|
107152
107188
|
}
|
|
107189
|
+
async function runPermissionRequestHooks2(workDir, tool, input, sessionId = "") {
|
|
107190
|
+
try {
|
|
107191
|
+
const items = loadHooks(workDir).PermissionRequest;
|
|
107192
|
+
if (!items?.length)
|
|
107193
|
+
return { answer: null };
|
|
107194
|
+
const o = await runLifecycleHooks(items, "PermissionRequest", workDir, { session_id: sessionId, tool_name: tool, tool_input: input }, tool);
|
|
107195
|
+
if (o.block)
|
|
107196
|
+
return { answer: "deny", reason: o.reason };
|
|
107197
|
+
if (o.allow)
|
|
107198
|
+
return { answer: "allow" };
|
|
107199
|
+
} catch {
|
|
107200
|
+
}
|
|
107201
|
+
return { answer: null };
|
|
107202
|
+
}
|
|
107153
107203
|
function fireNotificationHooks2(workDir, message, type = "permission_prompt") {
|
|
107154
107204
|
try {
|
|
107155
107205
|
const items = loadHooks(workDir).Notification;
|
|
@@ -107160,6 +107210,15 @@ var require_loop = __commonJS({
|
|
|
107160
107210
|
} catch {
|
|
107161
107211
|
}
|
|
107162
107212
|
}
|
|
107213
|
+
async function fireManualPostCompactHook2(workDir, sessionId, messagesSummarized) {
|
|
107214
|
+
try {
|
|
107215
|
+
const items = loadHooks(workDir).PostCompact;
|
|
107216
|
+
if (!items?.length)
|
|
107217
|
+
return;
|
|
107218
|
+
await runLifecycleHooks(items, "PostCompact", workDir, { trigger: "manual", session_id: sessionId, messages_summarized: messagesSummarized }, "manual");
|
|
107219
|
+
} catch {
|
|
107220
|
+
}
|
|
107221
|
+
}
|
|
107163
107222
|
async function fireManualPreCompactHook2(workDir, sessionId, messagesToSummarize) {
|
|
107164
107223
|
try {
|
|
107165
107224
|
const items = loadHooks(workDir).PreCompact;
|
|
@@ -107971,6 +108030,23 @@ ${stats}${isoNote}`;
|
|
|
107971
108030
|
try {
|
|
107972
108031
|
if (started)
|
|
107973
108032
|
started.value = true;
|
|
108033
|
+
{
|
|
108034
|
+
const subAgentName = agent?.name ?? (typeof input.subagent_type === "string" && input.subagent_type ? input.subagent_type : "general-purpose");
|
|
108035
|
+
const startItems = loadHooks(options.workDir).SubagentStart;
|
|
108036
|
+
if (startItems?.length) {
|
|
108037
|
+
const o = await runLifecycleHooks(startItems, "SubagentStart", options.workDir, { session_id: options.sessionId ?? "", agent_type: subAgentName, description: String(input.description ?? "") }, subAgentName).catch(() => ({ block: false }));
|
|
108038
|
+
if (o.context) {
|
|
108039
|
+
const last = subMessages[subMessages.length - 1];
|
|
108040
|
+
if (last && Array.isArray(last.content)) {
|
|
108041
|
+
subMessages[subMessages.length - 1] = { ...last, content: [...last.content, { type: "text", text: `
|
|
108042
|
+
|
|
108043
|
+
<hook-context>
|
|
108044
|
+
${o.context}
|
|
108045
|
+
</hook-context>` }] };
|
|
108046
|
+
}
|
|
108047
|
+
}
|
|
108048
|
+
}
|
|
108049
|
+
}
|
|
107974
108050
|
const childRun = runAgentLoop2(subMessages, {
|
|
107975
108051
|
...options,
|
|
107976
108052
|
_depth: depth + 1,
|
|
@@ -108522,6 +108598,11 @@ Do NOT call any tools and do NOT continue the task. Reply with text only: a conc
|
|
|
108522
108598
|
}
|
|
108523
108599
|
const toSummarize = messages.slice(0, cut);
|
|
108524
108600
|
const kept = messages.slice(cut);
|
|
108601
|
+
const firePostCompact = async () => {
|
|
108602
|
+
if ((options._depth ?? 0) !== 0)
|
|
108603
|
+
return;
|
|
108604
|
+
await runLifecycleHooks(loadHooks(options.workDir).PostCompact, "PostCompact", options.workDir, { trigger: "auto", session_id: options.sessionId ?? "", messages_summarized: cut }, "auto").catch(() => void 0);
|
|
108605
|
+
};
|
|
108525
108606
|
const originalTask = originalTaskText(toSummarize);
|
|
108526
108607
|
const summaryPrompt = `Summarize this coding-session transcript into concise bullet points the assistant needs to continue the work: key decisions, files changed (and how), commands run, unresolved problems, and user preferences. Max 400 words.
|
|
108527
108608
|
|
|
@@ -108590,6 +108671,7 @@ ${taskBlock}${ledgerBlock}Summary of the earlier conversation so far:
|
|
|
108590
108671
|
${summary}
|
|
108591
108672
|
|
|
108592
108673
|
Continue the work from here.` }] });
|
|
108674
|
+
await firePostCompact();
|
|
108593
108675
|
return true;
|
|
108594
108676
|
}
|
|
108595
108677
|
async function maybeCompactMemory(scope, options) {
|
|
@@ -108766,7 +108848,7 @@ Continue the work from here.` }] });
|
|
|
108766
108848
|
async function runAgentLoop2(initialMessages, options) {
|
|
108767
108849
|
const messages = [...initialMessages];
|
|
108768
108850
|
const model = options.model ?? "turbo";
|
|
108769
|
-
const hooks = withAgentHooks(loadHooks(options.workDir), options._agentHooks);
|
|
108851
|
+
const hooks = options.disableHooks ? withAgentHooks({}, options._agentHooks) : withAgentHooks(loadHooks(options.workDir), options._agentHooks);
|
|
108770
108852
|
const depth = options._depth ?? 0;
|
|
108771
108853
|
const agentScope = options._agentScope ?? "root";
|
|
108772
108854
|
const isMainAgent = depth === 0;
|
|
@@ -109303,6 +109385,15 @@ ${ctx}
|
|
|
109303
109385
|
void maybeCompactMemory(scope, options);
|
|
109304
109386
|
}
|
|
109305
109387
|
const post = await runToolHooks(hooks.PostToolUse, "PostToolUse", name, input, options.workDir, result);
|
|
109388
|
+
if (result.error !== void 0 && (hooks.PostToolUseFailure?.length ?? 0) > 0) {
|
|
109389
|
+
const f3 = await runLifecycleHooks(hooks.PostToolUseFailure, "PostToolUseFailure", options.workDir, { session_id: options.sessionId ?? "", tool_name: name, tool_input: input, error: String(result.error).slice(0, 4e3) }, name).catch(() => ({ block: false }));
|
|
109390
|
+
if (f3.context)
|
|
109391
|
+
post.context = [post.context, f3.context].filter(Boolean).join("\n");
|
|
109392
|
+
if (f3.block) {
|
|
109393
|
+
post.block = true;
|
|
109394
|
+
post.reason = [post.reason, f3.reason].filter(Boolean).join("; ");
|
|
109395
|
+
}
|
|
109396
|
+
}
|
|
109306
109397
|
const injected = [pre.context, post.context].filter(Boolean).join("\n");
|
|
109307
109398
|
if (injected) {
|
|
109308
109399
|
if (result.error !== void 0)
|
|
@@ -109430,6 +109521,9 @@ ${result.output}` : `Error: ${result.error}` : result.output ?? "",
|
|
|
109430
109521
|
throw err;
|
|
109431
109522
|
throw new types_1.AgentTurnError(err?.message || "The turn ended unexpectedly", trimToResumableBoundary(messages), completedRounds, err);
|
|
109432
109523
|
} finally {
|
|
109524
|
+
if (depth === 0 && (hooks.SessionEnd?.length ?? 0) > 0) {
|
|
109525
|
+
await runLifecycleHooks(hooks.SessionEnd, "SessionEnd", options.workDir, { session_id: options.sessionId ?? "", reason: stopReason }, stopReason).catch(() => void 0);
|
|
109526
|
+
}
|
|
109433
109527
|
if (depth === 0)
|
|
109434
109528
|
await runSimpleHooks(hooks.OnStop, options.workDir);
|
|
109435
109529
|
else
|
|
@@ -151573,6 +151667,13 @@ async function requestPermissionInner(req) {
|
|
|
151573
151667
|
console.error(paint.yellow(` \u2298 Plan mode \u2014 refused ${tool} (read-only until you switch mode).`));
|
|
151574
151668
|
return false;
|
|
151575
151669
|
}
|
|
151670
|
+
const hook = await (0, import_code_core5.runPermissionRequestHooks)(_workDir, tool, input);
|
|
151671
|
+
if (hook.answer === "allow")
|
|
151672
|
+
return true;
|
|
151673
|
+
if (hook.answer === "deny") {
|
|
151674
|
+
console.error(paint.red(` \u2716 Denied by PermissionRequest hook: ${hook.reason ?? tool}`));
|
|
151675
|
+
return false;
|
|
151676
|
+
}
|
|
151576
151677
|
return serialisePrompt(() => askFlow(req));
|
|
151577
151678
|
}
|
|
151578
151679
|
async function requestPermission(req) {
|
|
@@ -151908,6 +152009,8 @@ function checkHeadlessOnly(f3) {
|
|
|
151908
152009
|
return "--max-budget-usd only works with --output-format (a one-shot, non-interactive run).";
|
|
151909
152010
|
if (f3.noSessionPersistence)
|
|
151910
152011
|
return "--no-session-persistence only works with --output-format (a one-shot, non-interactive run).";
|
|
152012
|
+
if (f3.maxTurns !== void 0)
|
|
152013
|
+
return "--max-turns only works with --output-format (a one-shot, non-interactive run).";
|
|
151911
152014
|
return null;
|
|
151912
152015
|
}
|
|
151913
152016
|
function headlessVerdict(i2) {
|
|
@@ -152076,6 +152179,182 @@ function validateJsonSchema(value, schema, at = "$") {
|
|
|
152076
152179
|
}
|
|
152077
152180
|
return errs;
|
|
152078
152181
|
}
|
|
152182
|
+
function parseMaxTurns(raw) {
|
|
152183
|
+
const s2 = String(raw).trim();
|
|
152184
|
+
const n = Number(s2);
|
|
152185
|
+
if (!/^\d+$/.test(s2) || !Number.isSafeInteger(n) || n < 1) {
|
|
152186
|
+
return { ok: false, error: `Invalid --max-turns "${raw}". Use a whole number of 1 or more, e.g. 10` };
|
|
152187
|
+
}
|
|
152188
|
+
return { ok: true, value: n };
|
|
152189
|
+
}
|
|
152190
|
+
function readPromptFile(file, cwd2, flag = "--append-system-prompt-file") {
|
|
152191
|
+
const abs = path7.resolve(cwd2, file);
|
|
152192
|
+
let text;
|
|
152193
|
+
try {
|
|
152194
|
+
text = fs6.readFileSync(abs, "utf-8");
|
|
152195
|
+
} catch {
|
|
152196
|
+
return { ok: false, error: `${flag}: cannot read "${file}"` };
|
|
152197
|
+
}
|
|
152198
|
+
if (!text.trim())
|
|
152199
|
+
return { ok: false, error: `${flag}: "${file}" is empty` };
|
|
152200
|
+
return { ok: true, value: text.trim() };
|
|
152201
|
+
}
|
|
152202
|
+
var CLAUDE_TOOL_ALIASES = {
|
|
152203
|
+
Read: ["read_file", "list_directory", "search_files", "glob", "notebook_read"],
|
|
152204
|
+
Edit: ["edit_file", "multi_edit", "notebook_edit"],
|
|
152205
|
+
Write: ["write_file", "write_docx", "write_xlsx", "write_pptx"],
|
|
152206
|
+
Bash: ["bash", "bash_output", "kill_shell"],
|
|
152207
|
+
Glob: ["glob"],
|
|
152208
|
+
Grep: ["search_files"],
|
|
152209
|
+
WebFetch: ["fetch_url"],
|
|
152210
|
+
WebSearch: ["web_search"],
|
|
152211
|
+
Task: ["task"],
|
|
152212
|
+
TodoWrite: ["todo_write", "todo_read"],
|
|
152213
|
+
NotebookEdit: ["notebook_edit"]
|
|
152214
|
+
};
|
|
152215
|
+
function parseToolsFlag(raw, known) {
|
|
152216
|
+
const out = /* @__PURE__ */ new Set();
|
|
152217
|
+
const trimmed = String(raw).trim();
|
|
152218
|
+
if (trimmed === "")
|
|
152219
|
+
return { ok: true, value: [] };
|
|
152220
|
+
if (trimmed.toLowerCase() === "default")
|
|
152221
|
+
return { ok: true, value: [...known] };
|
|
152222
|
+
for (const piece of parseToolList(trimmed)) {
|
|
152223
|
+
if (CLAUDE_TOOL_ALIASES[piece]) {
|
|
152224
|
+
CLAUDE_TOOL_ALIASES[piece].forEach((t2) => out.add(t2));
|
|
152225
|
+
continue;
|
|
152226
|
+
}
|
|
152227
|
+
if (known.includes(piece) || piece.startsWith("mcp__")) {
|
|
152228
|
+
out.add(piece);
|
|
152229
|
+
continue;
|
|
152230
|
+
}
|
|
152231
|
+
return { ok: false, error: `--tools: unknown tool "${piece}". Known: ${[...Object.keys(CLAUDE_TOOL_ALIASES), ...known].join(", ")}` };
|
|
152232
|
+
}
|
|
152233
|
+
return { ok: true, value: [...out] };
|
|
152234
|
+
}
|
|
152235
|
+
function parseSessionId(raw) {
|
|
152236
|
+
const s2 = String(raw).trim();
|
|
152237
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(s2)) {
|
|
152238
|
+
return { ok: false, error: `Invalid --session-id "${raw}". Use letters, digits, "-" or "_" (max 64), e.g. a UUID` };
|
|
152239
|
+
}
|
|
152240
|
+
return { ok: true, value: s2 };
|
|
152241
|
+
}
|
|
152242
|
+
function parseSessionName(raw) {
|
|
152243
|
+
const s2 = String(raw).replace(/\s+/g, " ").trim();
|
|
152244
|
+
if (!s2)
|
|
152245
|
+
return { ok: false, error: "Invalid --name: it is empty" };
|
|
152246
|
+
return { ok: true, value: s2.slice(0, 80) };
|
|
152247
|
+
}
|
|
152248
|
+
function checkSessionIdentityFlags(f3) {
|
|
152249
|
+
const resuming = f3.resume !== void 0 || !!f3.continue;
|
|
152250
|
+
if (f3.fork && !resuming)
|
|
152251
|
+
return "--fork-session needs --resume <id> or --continue (there is nothing to fork otherwise).";
|
|
152252
|
+
if (f3.sessionId && resuming && !f3.fork)
|
|
152253
|
+
return "--session-id starts a new conversation; with --resume/--continue add --fork-session to branch it under that id.";
|
|
152254
|
+
return null;
|
|
152255
|
+
}
|
|
152256
|
+
function matchSessionByName(sessions, name) {
|
|
152257
|
+
const want = name.trim().toLowerCase();
|
|
152258
|
+
const hits = sessions.filter((s2) => s2.title.trim().toLowerCase() === want).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
152259
|
+
return hits[0] ?? null;
|
|
152260
|
+
}
|
|
152261
|
+
function parseSettingsArg(spec, cwd2) {
|
|
152262
|
+
const s2 = String(spec).trim();
|
|
152263
|
+
let text = s2;
|
|
152264
|
+
if (!s2.startsWith("{")) {
|
|
152265
|
+
try {
|
|
152266
|
+
text = fs6.readFileSync(path7.resolve(cwd2, s2), "utf-8");
|
|
152267
|
+
} catch {
|
|
152268
|
+
return { ok: false, error: `--settings: cannot read "${s2}"` };
|
|
152269
|
+
}
|
|
152270
|
+
}
|
|
152271
|
+
let v;
|
|
152272
|
+
try {
|
|
152273
|
+
v = JSON.parse(text);
|
|
152274
|
+
} catch {
|
|
152275
|
+
return { ok: false, error: `--settings: ${s2.startsWith("{") ? "the inline value" : `"${s2}"`} is not valid JSON` };
|
|
152276
|
+
}
|
|
152277
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
152278
|
+
return { ok: false, error: "--settings: expected a JSON object" };
|
|
152279
|
+
return { ok: true, value: v };
|
|
152280
|
+
}
|
|
152281
|
+
function authStatusReport(a, env4) {
|
|
152282
|
+
if (!a || !a.token)
|
|
152283
|
+
return { loggedIn: false, source: null };
|
|
152284
|
+
const fromEnv = !!env4.NEXRALL_TOKEN && env4.NEXRALL_TOKEN.trim().length > 0;
|
|
152285
|
+
return { loggedIn: true, source: fromEnv ? "env" : "login", ...a.email ? { email: a.email } : {} };
|
|
152286
|
+
}
|
|
152287
|
+
function isFallbackWorthy(message) {
|
|
152288
|
+
const m2 = String(message);
|
|
152289
|
+
if (/\b(401|402|403|400|404|413|422)\b/.test(m2) && !/\b(429|5\d\d)\b/.test(m2))
|
|
152290
|
+
return false;
|
|
152291
|
+
return /\b(429|500|502|503|504|529)\b|overload|rate.?limit|ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|socket hang up|fetch failed|stream (failed|stalled|ended)|timed? ?out/i.test(m2);
|
|
152292
|
+
}
|
|
152293
|
+
function parseFallbackModel(raw, primary) {
|
|
152294
|
+
const s2 = String(raw).trim();
|
|
152295
|
+
if (!s2)
|
|
152296
|
+
return { ok: false, error: "Invalid --fallback-model: it is empty" };
|
|
152297
|
+
if (s2 === primary)
|
|
152298
|
+
return { ok: false, error: `--fallback-model "${s2}" is the same as the main model; pick a different one` };
|
|
152299
|
+
return { ok: true, value: s2 };
|
|
152300
|
+
}
|
|
152301
|
+
function resolveSystemPrompt(f3) {
|
|
152302
|
+
if (f3.text !== void 0 && f3.file !== void 0) {
|
|
152303
|
+
return { ok: false, error: "--system-prompt and --system-prompt-file are mutually exclusive \u2014 pick one." };
|
|
152304
|
+
}
|
|
152305
|
+
if (f3.file !== void 0) {
|
|
152306
|
+
const r2 = readPromptFile(f3.file, f3.cwd, "--system-prompt-file");
|
|
152307
|
+
if (!r2.ok)
|
|
152308
|
+
return r2;
|
|
152309
|
+
if (!r2.value.trim())
|
|
152310
|
+
return { ok: false, error: `--system-prompt-file: ${f3.file} is empty.` };
|
|
152311
|
+
return { ok: true, value: r2.value };
|
|
152312
|
+
}
|
|
152313
|
+
if (f3.text !== void 0) {
|
|
152314
|
+
if (!f3.text.trim())
|
|
152315
|
+
return { ok: false, error: "--system-prompt: the value is empty." };
|
|
152316
|
+
return { ok: true, value: f3.text };
|
|
152317
|
+
}
|
|
152318
|
+
return { ok: true, value: void 0 };
|
|
152319
|
+
}
|
|
152320
|
+
function checkPartialMessages(f3) {
|
|
152321
|
+
if (!f3.includePartial)
|
|
152322
|
+
return null;
|
|
152323
|
+
if (f3.outputFormat !== "stream-json") {
|
|
152324
|
+
return "--include-partial-messages needs --output-format stream-json (it streams model deltas as they arrive).";
|
|
152325
|
+
}
|
|
152326
|
+
return null;
|
|
152327
|
+
}
|
|
152328
|
+
function checkReplayUserMessages(f3) {
|
|
152329
|
+
if (!f3.replay)
|
|
152330
|
+
return null;
|
|
152331
|
+
if (f3.inputFormat !== "stream-json") {
|
|
152332
|
+
return "--replay-user-messages needs --input-format stream-json (there is nothing to replay otherwise).";
|
|
152333
|
+
}
|
|
152334
|
+
if (f3.outputFormat !== "stream-json") {
|
|
152335
|
+
return "--replay-user-messages needs --output-format stream-json (the echo is written as an output event).";
|
|
152336
|
+
}
|
|
152337
|
+
return null;
|
|
152338
|
+
}
|
|
152339
|
+
function streamEventPayload(kind, chunk, extra = {}) {
|
|
152340
|
+
const delta = kind === "text" ? { type: "text_delta", text: chunk } : kind === "thinking" ? { type: "thinking_delta", thinking: chunk } : { type: "input_json_delta", partial_json: chunk };
|
|
152341
|
+
return { type: "stream_event", event: { type: "content_block_delta", delta }, ...extra };
|
|
152342
|
+
}
|
|
152343
|
+
function initEventPayload(i2) {
|
|
152344
|
+
return {
|
|
152345
|
+
type: "system",
|
|
152346
|
+
subtype: "init",
|
|
152347
|
+
session_id: i2.sessionId ?? "",
|
|
152348
|
+
cwd: i2.cwd,
|
|
152349
|
+
model: i2.model,
|
|
152350
|
+
tools: i2.tools,
|
|
152351
|
+
...i2.mcpServers ? { mcp_servers: i2.mcpServers } : {},
|
|
152352
|
+
...i2.permissionMode ? { permission_mode: i2.permissionMode } : {}
|
|
152353
|
+
};
|
|
152354
|
+
}
|
|
152355
|
+
function userReplayPayload(text) {
|
|
152356
|
+
return { type: "user", message: { role: "user", content: [{ type: "text", text }] } };
|
|
152357
|
+
}
|
|
152079
152358
|
|
|
152080
152359
|
// src/commands/chat.ts
|
|
152081
152360
|
var import_code_core17 = __toESM(require_dist3(), 1);
|
|
@@ -167966,6 +168245,10 @@ function refreshEnvForTurn(env4, workDir) {
|
|
|
167966
168245
|
...collectGitEnv(workDir)
|
|
167967
168246
|
};
|
|
167968
168247
|
}
|
|
168248
|
+
var noDiscovery = false;
|
|
168249
|
+
function setNoDiscovery(v) {
|
|
168250
|
+
noDiscovery = v;
|
|
168251
|
+
}
|
|
167969
168252
|
var NEXRALL_MD_CANDIDATES = [
|
|
167970
168253
|
"nexrall.md",
|
|
167971
168254
|
"NEXRALL.md",
|
|
@@ -167980,6 +168263,8 @@ var tryRead = (p) => {
|
|
|
167980
168263
|
}
|
|
167981
168264
|
};
|
|
167982
168265
|
function readNexrallMd(workDir) {
|
|
168266
|
+
if (noDiscovery)
|
|
168267
|
+
return void 0;
|
|
167983
168268
|
const parts = [];
|
|
167984
168269
|
const memContent = (0, import_code_core15.readAllMemory)(workDir);
|
|
167985
168270
|
if (memContent)
|
|
@@ -168228,6 +168513,11 @@ var _mcpManager = null;
|
|
|
168228
168513
|
var _mcpConfig = null;
|
|
168229
168514
|
var sessionTouched = [];
|
|
168230
168515
|
async function initMcp(workDir, override, strict) {
|
|
168516
|
+
if (noDiscovery && !override) {
|
|
168517
|
+
_mcpConfig = { mcpServers: {} };
|
|
168518
|
+
_mcpManager = null;
|
|
168519
|
+
return;
|
|
168520
|
+
}
|
|
168231
168521
|
_mcpConfig = strict && override ? { mcpServers: {} } : import_code_core15.McpManager.loadConfig(workDir);
|
|
168232
168522
|
if (override)
|
|
168233
168523
|
Object.assign(_mcpConfig.mcpServers, override.mcpServers);
|
|
@@ -168599,6 +168889,7 @@ function printErrorReport(err, aborted) {
|
|
|
168599
168889
|
for (const l2 of errorReportLines(err, aborted))
|
|
168600
168890
|
console.error(l2);
|
|
168601
168891
|
}
|
|
168892
|
+
var activeSessionIdGetter = () => void 0;
|
|
168602
168893
|
async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrallMd, mode, effort, checkpointManager, onProgress, takePendingInput, worktreeState, peerCtx) {
|
|
168603
168894
|
let lastUsage;
|
|
168604
168895
|
turnStats = freshTurnStats();
|
|
@@ -168633,6 +168924,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
168633
168924
|
spinner.start("thinking\u2026", { hint: false, verbs: true });
|
|
168634
168925
|
const result = await (0, import_code_core15.runAgentLoop)(messages, {
|
|
168635
168926
|
workDir,
|
|
168927
|
+
sessionId: activeSessionIdGetter(),
|
|
168636
168928
|
model: modelAlias,
|
|
168637
168929
|
env: refreshEnvForTurn(env4, workDir),
|
|
168638
168930
|
nexrallMd,
|
|
@@ -168665,6 +168957,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
168665
168957
|
onInjectedInput: () => {
|
|
168666
168958
|
},
|
|
168667
168959
|
backgroundAgents: cliBackgroundAgents,
|
|
168960
|
+
disableHooks: noDiscovery,
|
|
168668
168961
|
// The backend streams a cumulative output-token count (routes/code.js's
|
|
168669
168962
|
// sendProgress, throttled to ≤5/s) covering thinking, visible text AND
|
|
168670
168963
|
// tool-argument JSON. This used to be stored in a variable and rendered only
|
|
@@ -168958,13 +169251,27 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
168958
169251
|
let resultText = "";
|
|
168959
169252
|
let toolCallCount = 0;
|
|
168960
169253
|
let budgetHit = false;
|
|
169254
|
+
let turnsHit = false;
|
|
168961
169255
|
const emit = (obj2) => {
|
|
168962
169256
|
if (format === "stream-json")
|
|
168963
169257
|
process.stdout.write(JSON.stringify(obj2) + "\n");
|
|
168964
169258
|
};
|
|
169259
|
+
const verbose = (line) => {
|
|
169260
|
+
if (_headlessPolicy.verbose)
|
|
169261
|
+
process.stderr.write(line + "\n");
|
|
169262
|
+
};
|
|
169263
|
+
emit(initEventPayload({
|
|
169264
|
+
sessionId: activeSessionIdGetter(),
|
|
169265
|
+
cwd: workDir,
|
|
169266
|
+
model: modelAlias,
|
|
169267
|
+
tools: _headlessPolicy.onlyTools ? [..._headlessPolicy.onlyTools].sort() : (0, import_code_core15.knownToolNames)(),
|
|
169268
|
+
permissionMode: _headlessPolicy.permissionMode
|
|
169269
|
+
}));
|
|
168965
169270
|
emit({ type: "start", model: modelAlias, workDir });
|
|
169271
|
+
verbose(`[verbose] model=${modelAlias} cwd=${workDir} mode=${mode} session=${activeSessionIdGetter() ?? "-"}`);
|
|
168966
169272
|
const result = await (0, import_code_core15.runAgentLoop)(messages, {
|
|
168967
169273
|
workDir,
|
|
169274
|
+
sessionId: activeSessionIdGetter(),
|
|
168968
169275
|
model: modelAlias,
|
|
168969
169276
|
env: refreshEnvForTurn(env4, workDir),
|
|
168970
169277
|
nexrallMd,
|
|
@@ -168972,11 +169279,26 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
168972
169279
|
planMode: mode === "plan",
|
|
168973
169280
|
worktree: worktreeState,
|
|
168974
169281
|
backgroundAgents: cliBackgroundAgents,
|
|
169282
|
+
disableHooks: noDiscovery,
|
|
168975
169283
|
effort,
|
|
168976
169284
|
abortSignal: _abortSignal,
|
|
169285
|
+
// `--max-turns`: a hard round cap. autoContinue off, or the loop would extend it.
|
|
169286
|
+
..._headlessPolicy.maxTurns !== void 0 ? { maxIterations: _headlessPolicy.maxTurns, autoContinue: false } : {},
|
|
169287
|
+
// `--tools`: the allowlist is the same one sub-agents use, so removed tools are not even offered.
|
|
169288
|
+
..._headlessPolicy.onlyTools ? { _allowedTools: _headlessPolicy.onlyTools } : {},
|
|
169289
|
+
// Setting this callback makes the loop stop printing its own stop notice, so re-emit it —
|
|
169290
|
+
// otherwise every stop reason (stalled, no balance…) would go silent in headless runs.
|
|
169291
|
+
_onStopReason: (reason, notice) => {
|
|
169292
|
+
if (reason === "budget" && _headlessPolicy.maxTurns !== void 0)
|
|
169293
|
+
turnsHit = true;
|
|
169294
|
+
if (notice)
|
|
169295
|
+
emit({ type: "notice", text: notice });
|
|
169296
|
+
},
|
|
168977
169297
|
onText: (text) => {
|
|
168978
169298
|
resultText += text;
|
|
168979
169299
|
emit({ type: "text", text });
|
|
169300
|
+
if (_headlessPolicy.includePartial)
|
|
169301
|
+
emit(streamEventPayload("text", text));
|
|
168980
169302
|
},
|
|
168981
169303
|
// ── Reasoning-phase liveness ──────────────────────────────────────
|
|
168982
169304
|
// These used to be UNWIRED here while runTurn() (interactive) wired all
|
|
@@ -169007,6 +169329,8 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169007
169329
|
// dropped on the floor for every headless run.
|
|
169008
169330
|
onThinking: (text) => {
|
|
169009
169331
|
emit({ type: "thinking", text });
|
|
169332
|
+
if (_headlessPolicy.includePartial)
|
|
169333
|
+
emit(streamEventPayload("thinking", text));
|
|
169010
169334
|
},
|
|
169011
169335
|
// onThinkingDelta is intentionally NOT wired. Its chunks concatenate to the
|
|
169012
169336
|
// same string `onThinking` emits in full above, so emitting both would
|
|
@@ -169023,6 +169347,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169023
169347
|
onToolUse: (name, input, isSubTask, meta) => {
|
|
169024
169348
|
debugLog("tool_use", { tool: name, sub: !!isSubTask });
|
|
169025
169349
|
emit({ type: "tool_use", tool: name, input, ...toolIds(isSubTask, meta) });
|
|
169350
|
+
verbose(`[verbose] -> ${name}${isSubTask ? " (sub-agent)" : ""} ${toolTarget(name, input)}`);
|
|
169026
169351
|
},
|
|
169027
169352
|
// Live bash progress for scripted/CI consumers — lets a wrapper tail a
|
|
169028
169353
|
// long-running build/test command instead of blocking silently until
|
|
@@ -169030,12 +169355,15 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169030
169355
|
// which is head/tail-capped), so a chatty command can emit many of these.
|
|
169031
169356
|
onToolStreamChunk: (name, chunk, isSubTask, meta) => {
|
|
169032
169357
|
emit({ type: "tool_stream", tool: name, chunk, ...toolIds(isSubTask, meta) });
|
|
169358
|
+
if (_headlessPolicy.includePartial)
|
|
169359
|
+
emit(streamEventPayload("tool", chunk, { tool: name, ...toolIds(isSubTask, meta) }));
|
|
169033
169360
|
},
|
|
169034
169361
|
onToolResult: (name, res, isSubTask, meta) => {
|
|
169035
169362
|
if (!isSubTask)
|
|
169036
169363
|
toolCallCount++;
|
|
169037
169364
|
debugLog("tool_result", { tool: name, ok: res.error === void 0, error: res.error, sub: !!isSubTask });
|
|
169038
169365
|
emit({ type: "tool_result", tool: name, ok: res.error === void 0, ...res.error ? { error: res.error } : {}, ...toolIds(isSubTask, meta) });
|
|
169366
|
+
verbose(`[verbose] <- ${name} ${res.error === void 0 ? "ok" : "FAILED: " + String(res.error).slice(0, 200)}`);
|
|
169039
169367
|
},
|
|
169040
169368
|
// Headless consumers get the partial report too — tagged, so a script can account
|
|
169041
169369
|
// for the real cost of a restarted turn — but it never becomes `lastUsage`, which
|
|
@@ -169076,6 +169404,10 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169076
169404
|
// no human to confirm, they are denied unless NEXRALL_ALLOW_DESTRUCTIVE=1 is
|
|
169077
169405
|
// explicitly set for this CI run.
|
|
169078
169406
|
requestPermission: async ({ tool, input }) => {
|
|
169407
|
+
if (_headlessPolicy.onlyTools && !_headlessPolicy.onlyTools.has(tool) && !tool.startsWith("mcp__")) {
|
|
169408
|
+
emit({ type: "permission_denied", tool, reason: "tools" });
|
|
169409
|
+
return false;
|
|
169410
|
+
}
|
|
169079
169411
|
const d = (0, import_code_core15.isDestructiveBash)(tool, input);
|
|
169080
169412
|
const v = headlessVerdict({
|
|
169081
169413
|
rule: (0, import_code_core17.evaluatePermission)((0, import_code_core17.loadSettings)(workDir).permissions, tool, input, workDir),
|
|
@@ -169115,6 +169447,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169115
169447
|
}
|
|
169116
169448
|
const extra = {
|
|
169117
169449
|
..._headlessPolicy.budgetUsd !== void 0 ? { cost_usd: _headlessPolicy.spent, ...budgetHit ? { stopped: "budget" } : {} } : {},
|
|
169450
|
+
...turnsHit ? { stopped: "max_turns", max_turns: _headlessPolicy.maxTurns } : {},
|
|
169118
169451
|
...structured ? { structured_output: structured.value } : {},
|
|
169119
169452
|
...schemaError ? { schema_error: schemaError } : {}
|
|
169120
169453
|
};
|
|
@@ -169137,6 +169470,8 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
169137
169470
|
}
|
|
169138
169471
|
if (budgetHit)
|
|
169139
169472
|
process.exitCode = 2;
|
|
169473
|
+
else if (turnsHit)
|
|
169474
|
+
process.exitCode = 4;
|
|
169140
169475
|
return { messages: result, usage: lastUsage };
|
|
169141
169476
|
}
|
|
169142
169477
|
function kbKey(action) {
|
|
@@ -169317,6 +169652,8 @@ function printSessions() {
|
|
|
169317
169652
|
console.log();
|
|
169318
169653
|
}
|
|
169319
169654
|
async function startChatSession(options) {
|
|
169655
|
+
if (options.bare)
|
|
169656
|
+
setNoDiscovery(true);
|
|
169320
169657
|
(0, import_code_core15.enableAgentTranscriptPersistence)();
|
|
169321
169658
|
const headless = options.outputFormat === "json" || options.outputFormat === "stream-json";
|
|
169322
169659
|
const requestedWorkDir = options.workDir;
|
|
@@ -169412,8 +169749,12 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169412
169749
|
});
|
|
169413
169750
|
}
|
|
169414
169751
|
const env4 = collectEnv(workDir);
|
|
169415
|
-
const
|
|
169416
|
-
|
|
169752
|
+
const briefBase = options.systemPrompt?.trim() ?? readNexrallMd(workDir);
|
|
169753
|
+
const nexrallMd = [briefBase, options.appendSystemPrompt?.trim(), addDirNote(options.addDirs ?? []), options.jsonSchema ? schemaInstruction(options.jsonSchema) : ""].filter(Boolean).join("\n\n") || void 0;
|
|
169754
|
+
_headlessPolicy = { strict: !!options.strictPermissions, budgetUsd: options.budgetUsd, spent: 0, schema: options.jsonSchema, maxTurns: options.maxTurns, onlyTools: options.onlyTools ? new Set(options.onlyTools) : void 0 };
|
|
169755
|
+
_headlessPolicy.verbose = !!options.verbose;
|
|
169756
|
+
_headlessPolicy.includePartial = !!options.includePartialMessages;
|
|
169757
|
+
_headlessPolicy.permissionMode = String(options.initialMode ?? "");
|
|
169417
169758
|
const saveSession2 = options.noSessionPersistence ? () => {
|
|
169418
169759
|
} : saveSession;
|
|
169419
169760
|
const interactive = !headless && !options.prompt && !options.stdinText;
|
|
@@ -169489,8 +169830,9 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169489
169830
|
));
|
|
169490
169831
|
}
|
|
169491
169832
|
let messages = [];
|
|
169492
|
-
let sessionId = crypto6.randomBytes(8).toString("hex");
|
|
169493
|
-
|
|
169833
|
+
let sessionId = options.newSessionId ?? crypto6.randomBytes(8).toString("hex");
|
|
169834
|
+
activeSessionIdGetter = () => sessionId;
|
|
169835
|
+
let sessionTitle = options.sessionName ?? "";
|
|
169494
169836
|
const modeLocked = options.lockMode === true;
|
|
169495
169837
|
let agentMode = modeLocked ? "plan" : options.initialMode ?? "auto";
|
|
169496
169838
|
const refuseIfLocked = (what) => {
|
|
@@ -169512,7 +169854,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169512
169854
|
for (const n of themeConfig.notes)
|
|
169513
169855
|
console.log(paint.dim(" theme: " + n));
|
|
169514
169856
|
}
|
|
169515
|
-
let skills = (0, import_code_core15.loadSkills)(workDir);
|
|
169857
|
+
let skills = noDiscovery ? [] : (0, import_code_core15.loadSkills)(workDir);
|
|
169516
169858
|
if (skills.length && !headless)
|
|
169517
169859
|
console.log(paint.dim(` ${skills.length} skill(s) loaded`));
|
|
169518
169860
|
let contextSet = loadContextSet(workDir);
|
|
@@ -169542,7 +169884,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169542
169884
|
process.exit(1);
|
|
169543
169885
|
}
|
|
169544
169886
|
if (options.debug) {
|
|
169545
|
-
const dbgPath = enableDebug();
|
|
169887
|
+
const dbgPath = enableDebug(options.debugFile);
|
|
169546
169888
|
if (dbgPath) {
|
|
169547
169889
|
debugLog("start", { version: CLI_VERSION, node: process.version, platform: process.platform, model: modelAlias, mode: agentMode, locked: modeLocked, headless, interactive });
|
|
169548
169890
|
if (!headless)
|
|
@@ -169555,7 +169897,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169555
169897
|
}
|
|
169556
169898
|
}
|
|
169557
169899
|
if (options.resume || options.continueLast) {
|
|
169558
|
-
const stored = options.continueLast ? lastSessionForDir(workDir) : options.resume === "last" ? lastSession() : loadSession(options.resume);
|
|
169900
|
+
const stored = options.continueLast ? lastSessionForDir(workDir) : options.resume === "last" ? lastSession() : loadSession(options.resume) ?? matchSessionByName(listSessions(), options.resume);
|
|
169559
169901
|
if (!stored) {
|
|
169560
169902
|
if (options.continueLast) {
|
|
169561
169903
|
console.error(paint.red(" No conversation to continue in this folder."));
|
|
@@ -169569,7 +169911,13 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169569
169911
|
messages = stored.messages;
|
|
169570
169912
|
sessionId = stored.id;
|
|
169571
169913
|
sessionTitle = stored.title;
|
|
169572
|
-
|
|
169914
|
+
if (options.forkSession) {
|
|
169915
|
+
sessionId = options.newSessionId ?? crypto6.randomBytes(8).toString("hex");
|
|
169916
|
+
sessionTitle = options.sessionName ?? forkTitle(stored.title, "");
|
|
169917
|
+
} else if (options.sessionName) {
|
|
169918
|
+
sessionTitle = options.sessionName;
|
|
169919
|
+
}
|
|
169920
|
+
startSessionLog(sessionId, true, options.forkSession ? { workDir, forkOf: stored.id } : { workDir });
|
|
169573
169921
|
try {
|
|
169574
169922
|
const compacted = await (0, import_code_core15.compactMessagesForResume)(messages, {
|
|
169575
169923
|
workDir,
|
|
@@ -169643,6 +169991,9 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
169643
169991
|
${text}` : "");
|
|
169644
169992
|
}
|
|
169645
169993
|
checkpoints.beginTurn(text, messages.length);
|
|
169994
|
+
if (options.replayUserMessages && options.inputFormatWasStreamJson && options.outputFormat === "stream-json") {
|
|
169995
|
+
process.stdout.write(JSON.stringify(userReplayPayload(text)) + "\n");
|
|
169996
|
+
}
|
|
169646
169997
|
messages.push({ role: "user", content: [{ type: "text", text }] });
|
|
169647
169998
|
const abortSignal2 = { aborted: false };
|
|
169648
169999
|
const onSigint = () => {
|
|
@@ -169651,8 +170002,31 @@ ${text}` : "");
|
|
|
169651
170002
|
process.once("SIGINT", onSigint);
|
|
169652
170003
|
try {
|
|
169653
170004
|
const fmt = options.outputFormat;
|
|
170005
|
+
const replay = (text2) => {
|
|
170006
|
+
if (options.replayUserMessages && fmt === "stream-json")
|
|
170007
|
+
process.stdout.write(JSON.stringify(userReplayPayload(text2)) + "\n");
|
|
170008
|
+
};
|
|
169654
170009
|
const runOnce = () => fmt === "json" || fmt === "stream-json" ? runTurnHeadless(messages, modelAlias, workDir, abortSignal2, env4, nexrallMd, agentMode, effortLevel, fmt, checkpoints, saveProgress, worktreeState) : runTurn(messages, modelAlias, workDir, abortSignal2, env4, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress, void 0, worktreeState, peerCtx);
|
|
169655
|
-
|
|
170010
|
+
const runWithFallback = async () => {
|
|
170011
|
+
try {
|
|
170012
|
+
return await runOnce();
|
|
170013
|
+
} catch (e2) {
|
|
170014
|
+
if (!options.fallbackModel || modelAlias === options.fallbackModel || abortSignal2.aborted || !isFallbackWorthy(String(e2.message)))
|
|
170015
|
+
throw e2;
|
|
170016
|
+
const from = modelAlias;
|
|
170017
|
+
modelAlias = options.fallbackModel;
|
|
170018
|
+
const salvagedMsgs = (0, import_code_core15.salvageHistory)(e2);
|
|
170019
|
+
if (salvagedMsgs)
|
|
170020
|
+
messages = salvagedMsgs;
|
|
170021
|
+
const note = `Model ${from} failed (${String(e2.message).slice(0, 120)}); retrying on ${modelAlias}`;
|
|
170022
|
+
if (fmt === "stream-json")
|
|
170023
|
+
process.stdout.write(JSON.stringify({ type: "notice", text: note }) + "\n");
|
|
170024
|
+
else
|
|
170025
|
+
console.error(note);
|
|
170026
|
+
return await runOnce();
|
|
170027
|
+
}
|
|
170028
|
+
};
|
|
170029
|
+
let result = await runWithFallback();
|
|
169656
170030
|
messages = result.messages;
|
|
169657
170031
|
while (!abortSignal2.aborted && (cliBackgroundAgents.runningCount() > 0 || cliBackgroundAgents.hasPending())) {
|
|
169658
170032
|
if (!cliBackgroundAgents.hasPending()) {
|
|
@@ -169669,6 +170043,7 @@ ${text}` : "");
|
|
|
169669
170043
|
break;
|
|
169670
170044
|
commitCheckpoint();
|
|
169671
170045
|
checkpoints.beginTurn(follow, messages.length);
|
|
170046
|
+
replay(follow);
|
|
169672
170047
|
messages.push({ role: "user", content: [{ type: "text", text: follow }] });
|
|
169673
170048
|
result = await runOnce();
|
|
169674
170049
|
messages = result.messages;
|
|
@@ -170576,6 +170951,7 @@ ${summaryText}` }] },
|
|
|
170576
170951
|
saveSession2(sessionId, sessionTitle || "Untitled", workDir, messages);
|
|
170577
170952
|
console.log(paint.green(` Compacted ${toSummarize.length} messages \u2192 ${messages.length} messages.`));
|
|
170578
170953
|
emitEvent("context.compacted", { where: "manual", before: toSummarize.length + KEEP, after: messages.length });
|
|
170954
|
+
await (0, import_code_core16.fireManualPostCompactHook)(workDir, sessionId, toSummarize.length);
|
|
170579
170955
|
if (pin.attachments.length)
|
|
170580
170956
|
console.log(paint.dim(` ${pin.attachments.length} pinned file(s) re-attached.`));
|
|
170581
170957
|
for (const n of pin.notes)
|
|
@@ -172916,7 +173292,17 @@ var require3 = createRequire2(import.meta.url);
|
|
|
172916
173292
|
var NEX_VERSION = require3("../package.json").version;
|
|
172917
173293
|
var program2 = new Command();
|
|
172918
173294
|
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version(NEX_VERSION).enablePositionalOptions();
|
|
172919
|
-
program2.command("auth").description("Login to your Nexrall account").action(authCommand);
|
|
173295
|
+
var auth = program2.command("auth").description("Login to your Nexrall account").action(authCommand);
|
|
173296
|
+
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) => {
|
|
173297
|
+
const r2 = authStatusReport((0, import_code_core21.loadAuth)(), process.env);
|
|
173298
|
+
if (opts.json)
|
|
173299
|
+
console.log(JSON.stringify(r2));
|
|
173300
|
+
else if (!r2.loggedIn)
|
|
173301
|
+
console.log("Not logged in. Run: nex auth");
|
|
173302
|
+
else
|
|
173303
|
+
console.log(`Logged in${r2.email ? ` as ${r2.email}` : ""} (${r2.source === "env" ? "NEXRALL_TOKEN" : "saved login"})`);
|
|
173304
|
+
process.exit(r2.loggedIn ? 0 : 1);
|
|
173305
|
+
});
|
|
172920
173306
|
program2.command("logout").description("Log out of your Nexrall account").action(logoutCommand);
|
|
172921
173307
|
program2.command("doctor").description("Check Node, sign-in, network, terminal, MCP and storage, with a fix for each problem").option("-d, --dir <path>", "Project folder to check (default: current directory)").action(async (opts) => {
|
|
172922
173308
|
const workDir = opts.dir ? path26.resolve(opts.dir) : process.cwd();
|
|
@@ -173115,7 +173501,7 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
173115
173501
|
console.log(paint.dim(" nex sessions --events <id> [--json] to follow its event stream"));
|
|
173116
173502
|
console.log();
|
|
173117
173503
|
});
|
|
173118
|
-
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)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
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) => {
|
|
173119
173505
|
if (!(0, import_code_core20.isAuthenticated)()) {
|
|
173120
173506
|
console.error("Not logged in. Run: nex auth");
|
|
173121
173507
|
process.exit(1);
|
|
@@ -173147,8 +173533,43 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173147
173533
|
console.error(sessErr);
|
|
173148
173534
|
process.exit(1);
|
|
173149
173535
|
}
|
|
173536
|
+
let newSessionId;
|
|
173537
|
+
let sessionName;
|
|
173538
|
+
if (options.sessionId !== void 0) {
|
|
173539
|
+
const r2 = parseSessionId(options.sessionId);
|
|
173540
|
+
if (!r2.ok) {
|
|
173541
|
+
console.error(r2.error);
|
|
173542
|
+
process.exit(1);
|
|
173543
|
+
}
|
|
173544
|
+
newSessionId = r2.value;
|
|
173545
|
+
}
|
|
173546
|
+
if (options.name !== void 0) {
|
|
173547
|
+
const r2 = parseSessionName(options.name);
|
|
173548
|
+
if (!r2.ok) {
|
|
173549
|
+
console.error(r2.error);
|
|
173550
|
+
process.exit(1);
|
|
173551
|
+
}
|
|
173552
|
+
sessionName = r2.value;
|
|
173553
|
+
}
|
|
173554
|
+
const identErr = checkSessionIdentityFlags({ sessionId: newSessionId, resume: options.resume, continue: options.continue, fork: options.forkSession });
|
|
173555
|
+
if (identErr) {
|
|
173556
|
+
console.error(identErr);
|
|
173557
|
+
process.exit(1);
|
|
173558
|
+
}
|
|
173559
|
+
if (newSessionId && loadSession(newSessionId) && !options.forkSession) {
|
|
173560
|
+
console.error(`--session-id "${newSessionId}" already exists. Resume it with: nex --resume ${newSessionId}`);
|
|
173561
|
+
process.exit(1);
|
|
173562
|
+
}
|
|
173150
173563
|
if (options.yolo || permBypass)
|
|
173151
173564
|
setAutoApprove("all");
|
|
173565
|
+
if (options.settings !== void 0) {
|
|
173566
|
+
const st = parseSettingsArg(options.settings, process.cwd());
|
|
173567
|
+
if (!st.ok) {
|
|
173568
|
+
console.error(st.error);
|
|
173569
|
+
process.exit(1);
|
|
173570
|
+
}
|
|
173571
|
+
(0, import_code_core21.setSessionSettings)(st.value);
|
|
173572
|
+
}
|
|
173152
173573
|
const allowRules = parseToolList(options.allowedTools);
|
|
173153
173574
|
const denyRules = parseToolList(options.disallowedTools);
|
|
173154
173575
|
(0, import_code_core21.setSessionRules)({ allow: allowRules, deny: denyRules });
|
|
@@ -173163,11 +173584,57 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173163
173584
|
}
|
|
173164
173585
|
if (options.sessionPersistence === false)
|
|
173165
173586
|
process.env.NEXRALL_EVENTS = "off";
|
|
173166
|
-
|
|
173587
|
+
let maxTurns;
|
|
173588
|
+
if (options.maxTurns !== void 0) {
|
|
173589
|
+
const t2 = parseMaxTurns(options.maxTurns);
|
|
173590
|
+
if (!t2.ok) {
|
|
173591
|
+
console.error(t2.error);
|
|
173592
|
+
process.exit(1);
|
|
173593
|
+
}
|
|
173594
|
+
maxTurns = t2.value;
|
|
173595
|
+
}
|
|
173596
|
+
const headlessErr = checkHeadlessOnly({ outputFormat: options.outputFormat, budget: budgetUsd, noSessionPersistence: options.sessionPersistence === false, maxTurns });
|
|
173167
173597
|
if (headlessErr) {
|
|
173168
173598
|
console.error(headlessErr);
|
|
173169
173599
|
process.exit(1);
|
|
173170
173600
|
}
|
|
173601
|
+
const sysPrompt = resolveSystemPrompt({ text: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0, file: options.systemPromptFile, cwd: process.cwd() });
|
|
173602
|
+
if (!sysPrompt.ok) {
|
|
173603
|
+
console.error(sysPrompt.error);
|
|
173604
|
+
process.exit(1);
|
|
173605
|
+
}
|
|
173606
|
+
let appendSystemPrompt = options.appendSystemPrompt;
|
|
173607
|
+
if (options.appendSystemPromptFile !== void 0) {
|
|
173608
|
+
const f3 = readPromptFile(options.appendSystemPromptFile, process.cwd());
|
|
173609
|
+
if (!f3.ok) {
|
|
173610
|
+
console.error(f3.error);
|
|
173611
|
+
process.exit(1);
|
|
173612
|
+
}
|
|
173613
|
+
appendSystemPrompt = [appendSystemPrompt, f3.value].filter(Boolean).join("\n\n");
|
|
173614
|
+
}
|
|
173615
|
+
let onlyTools;
|
|
173616
|
+
if (options.tools !== void 0) {
|
|
173617
|
+
const t2 = parseToolsFlag(options.tools === true ? "" : options.tools, (0, import_code_core21.knownToolNames)());
|
|
173618
|
+
if (!t2.ok) {
|
|
173619
|
+
console.error(t2.error);
|
|
173620
|
+
process.exit(1);
|
|
173621
|
+
}
|
|
173622
|
+
onlyTools = t2.value;
|
|
173623
|
+
}
|
|
173624
|
+
let fallbackModel;
|
|
173625
|
+
if (options.fallbackModel !== void 0) {
|
|
173626
|
+
if (!options.outputFormat) {
|
|
173627
|
+
console.error("--fallback-model only works with --output-format (a one-shot, non-interactive run).");
|
|
173628
|
+
process.exit(1);
|
|
173629
|
+
}
|
|
173630
|
+
const f3 = parseFallbackModel(options.fallbackModel, model);
|
|
173631
|
+
if (!f3.ok) {
|
|
173632
|
+
console.error(f3.error);
|
|
173633
|
+
process.exit(1);
|
|
173634
|
+
}
|
|
173635
|
+
fallbackModel = f3.value;
|
|
173636
|
+
}
|
|
173637
|
+
const debugFile = options.debugFile !== void 0 ? path26.resolve(String(options.debugFile)) : void 0;
|
|
173171
173638
|
let mcpOverride;
|
|
173172
173639
|
if (options.mcpConfig) {
|
|
173173
173640
|
const m2 = parseMcpConfigs(options.mcpConfig, process.cwd());
|
|
@@ -173260,6 +173727,16 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173260
173727
|
}
|
|
173261
173728
|
outputFormat = fmt;
|
|
173262
173729
|
}
|
|
173730
|
+
const partialErr = checkPartialMessages({ includePartial: !!options.includePartialMessages, outputFormat });
|
|
173731
|
+
if (partialErr) {
|
|
173732
|
+
console.error(partialErr);
|
|
173733
|
+
process.exit(1);
|
|
173734
|
+
}
|
|
173735
|
+
const replayErr = checkReplayUserMessages({ replay: !!options.replayUserMessages, inputFormat: options.inputFormat, outputFormat });
|
|
173736
|
+
if (replayErr) {
|
|
173737
|
+
console.error(replayErr);
|
|
173738
|
+
process.exit(1);
|
|
173739
|
+
}
|
|
173263
173740
|
const fsErr = checkFullscreenFlag({
|
|
173264
173741
|
fullscreen: !!options.fullscreen,
|
|
173265
173742
|
isTTY: !!process.stdout.isTTY,
|
|
@@ -173279,7 +173756,7 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173279
173756
|
}
|
|
173280
173757
|
effort = lvl;
|
|
173281
173758
|
}
|
|
173282
|
-
await startChatSession({ model, workDir, prompt: prompt2, resume, continueLast: !!options.continue, initialMode: modeRes.mode, lockMode: modeRes.locked, debug: !!options.debug, stdinText, stdinFollowUps, showBanner, outputFormat, effort, audit: options.audit, worktree, fullscreen: !!options.fullscreen, strictPermissions: options.permissionMode !== void 0, budgetUsd, appendSystemPrompt: options.
|
|
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 });
|
|
173283
173760
|
});
|
|
173284
173761
|
program2.parse();
|
|
173285
173762
|
/*! Bundled license information:
|