nexrall-code 0.5.56 → 0.5.58
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 +229 -111
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9982,7 +9982,7 @@ var require_client = __commonJS({
|
|
|
9982
9982
|
}
|
|
9983
9983
|
var MAX_TOTAL_ATTEMPTS = (MAX_RETRIES + 1) * (MAX_RETRIES + 1);
|
|
9984
9984
|
async function streamChat(messages, options, onEvent) {
|
|
9985
|
-
const { model, env: env3, editorContext, nexrallMd, mode, effort, clientType, abortSignal, extraTools, agents, skills, allowRestartAfterRender, canWriteSharedMemory, hasOwnAgentStore } = options;
|
|
9985
|
+
const { model, env: env3, editorContext, nexrallMd, mode, effort, clientType, abortSignal, extraTools, agents, skills, allowRestartAfterRender, canWriteSharedMemory, hasOwnAgentStore, canSpawnSubAgents } = options;
|
|
9986
9986
|
let turnId = (0, crypto_1.randomUUID)();
|
|
9987
9987
|
const controller = new AbortController();
|
|
9988
9988
|
if (abortSignal?.aborted)
|
|
@@ -10023,7 +10023,7 @@ var require_client = __commonJS({
|
|
|
10023
10023
|
{
|
|
10024
10024
|
method: "POST",
|
|
10025
10025
|
headers: authHeaders(),
|
|
10026
|
-
body: JSON.stringify({ messages, model, env: env3, editorContext, nexrallMd, mode, effort, clientType, extraTools, agents, skills, turnId, canWriteSharedMemory, hasOwnAgentStore }),
|
|
10026
|
+
body: JSON.stringify({ messages, model, env: env3, editorContext, nexrallMd, mode, effort, clientType, extraTools, agents, skills, turnId, canWriteSharedMemory, hasOwnAgentStore, canSpawnSubAgents }),
|
|
10027
10027
|
signal: controller.signal
|
|
10028
10028
|
}
|
|
10029
10029
|
];
|
|
@@ -15061,6 +15061,13 @@ var require_agentTypes = __commonJS({
|
|
|
15061
15061
|
message: `lists unknown tool name(s): ${unknown.join(", ")}. An allowlist only grants, so these silently do nothing and the agent cannot use them. Tool names are lower_snake_case (read_file, search_files, glob, bash).`
|
|
15062
15062
|
});
|
|
15063
15063
|
}
|
|
15064
|
+
if ((tools ?? []).includes("task")) {
|
|
15065
|
+
warnings.push({
|
|
15066
|
+
file: full,
|
|
15067
|
+
agent: name,
|
|
15068
|
+
message: "lists `task`, which cannot be granted: sub-agents are never sent that tool because they cannot spawn further sub-agents. Remove it \u2014 delegation stays with the main agent."
|
|
15069
|
+
});
|
|
15070
|
+
}
|
|
15064
15071
|
const strayKeys = Object.keys(meta).filter((k) => !KNOWN_META_KEYS.has(k));
|
|
15065
15072
|
if (strayKeys.length) {
|
|
15066
15073
|
warnings.push({
|
|
@@ -15375,6 +15382,63 @@ var require_rules = __commonJS({
|
|
|
15375
15382
|
}
|
|
15376
15383
|
});
|
|
15377
15384
|
|
|
15385
|
+
// ../core/dist/permissions/bashClassify.js
|
|
15386
|
+
var require_bashClassify = __commonJS({
|
|
15387
|
+
"../core/dist/permissions/bashClassify.js"(exports) {
|
|
15388
|
+
"use strict";
|
|
15389
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15390
|
+
exports.bashNeedsRepoLock = bashNeedsRepoLock;
|
|
15391
|
+
var MUTATING_BASH_VERBS = /* @__PURE__ */ new Set([
|
|
15392
|
+
"git",
|
|
15393
|
+
"npm",
|
|
15394
|
+
"pnpm",
|
|
15395
|
+
"yarn",
|
|
15396
|
+
"bun",
|
|
15397
|
+
"cargo",
|
|
15398
|
+
"go",
|
|
15399
|
+
"pip",
|
|
15400
|
+
"pip3",
|
|
15401
|
+
"poetry",
|
|
15402
|
+
"uv",
|
|
15403
|
+
"bundle",
|
|
15404
|
+
"composer",
|
|
15405
|
+
"gradle",
|
|
15406
|
+
"mvn",
|
|
15407
|
+
"make",
|
|
15408
|
+
"terraform",
|
|
15409
|
+
"helm",
|
|
15410
|
+
"docker",
|
|
15411
|
+
"vsce",
|
|
15412
|
+
"tsc",
|
|
15413
|
+
"pytest",
|
|
15414
|
+
"dotnet",
|
|
15415
|
+
"swift",
|
|
15416
|
+
"gem"
|
|
15417
|
+
]);
|
|
15418
|
+
function bashNeedsRepoLock(command) {
|
|
15419
|
+
if (!command)
|
|
15420
|
+
return false;
|
|
15421
|
+
const segments = command.split(/\|\||&&|[;|&\n()]|\$\(/);
|
|
15422
|
+
for (const seg of segments) {
|
|
15423
|
+
for (const tokenRaw of seg.trim().split(/\s+/)) {
|
|
15424
|
+
const token = tokenRaw.replace(/^["']|["']$/g, "");
|
|
15425
|
+
if (!token)
|
|
15426
|
+
continue;
|
|
15427
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))
|
|
15428
|
+
continue;
|
|
15429
|
+
if (token === "sudo" || token === "time" || token === "nice" || token === "env")
|
|
15430
|
+
continue;
|
|
15431
|
+
const verb = token.split("/").pop() ?? token;
|
|
15432
|
+
if (MUTATING_BASH_VERBS.has(verb))
|
|
15433
|
+
return true;
|
|
15434
|
+
break;
|
|
15435
|
+
}
|
|
15436
|
+
}
|
|
15437
|
+
return false;
|
|
15438
|
+
}
|
|
15439
|
+
}
|
|
15440
|
+
});
|
|
15441
|
+
|
|
15378
15442
|
// ../core/dist/agent/planMode.js
|
|
15379
15443
|
var require_planMode = __commonJS({
|
|
15380
15444
|
"../core/dist/agent/planMode.js"(exports) {
|
|
@@ -15897,16 +15961,16 @@ var require_loop = __commonJS({
|
|
|
15897
15961
|
};
|
|
15898
15962
|
}();
|
|
15899
15963
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15900
|
-
exports.VERIFY_CMD_RE = exports.WRITE_TOOL_NAMES = exports.ToolNotAllowedError = exports.AGENT_MEMORY_TOOL_SCHEMA = exports.AGENT_MEMORY_TOOL = exports._stallLimits = void 0;
|
|
15964
|
+
exports.VERIFY_CMD_RE = exports.WRITE_TOOL_NAMES = exports.ToolNotAllowedError = exports.NO_NESTED_SUBAGENTS_MSG = exports.AGENT_MEMORY_TOOL_SCHEMA = exports.AGENT_MEMORY_TOOL = exports._stallLimits = exports.bashNeedsRepoLock = void 0;
|
|
15901
15965
|
exports.errorRoundSignature = errorRoundSignature;
|
|
15902
15966
|
exports.executeAgentMemoryWrite = executeAgentMemoryWrite;
|
|
15903
15967
|
exports.stopReasonNotice = stopReasonNotice;
|
|
15904
15968
|
exports.resolveMaxIterations = resolveMaxIterations;
|
|
15905
|
-
exports.bashNeedsRepoLock = bashNeedsRepoLock;
|
|
15906
15969
|
exports.lockPathsFor = lockPathsFor;
|
|
15907
15970
|
exports.resolveMaxConcurrentSubtasks = resolveMaxConcurrentSubtasks;
|
|
15908
15971
|
exports.createLimiter = createLimiter;
|
|
15909
15972
|
exports._resetSubTaskLimiter = _resetSubTaskLimiter;
|
|
15973
|
+
exports.canSpawnSubAgents = canSpawnSubAgents;
|
|
15910
15974
|
exports.resolveSubtaskTimeoutMs = resolveSubtaskTimeoutMs;
|
|
15911
15975
|
exports.extractSubTaskText = extractSubTaskText;
|
|
15912
15976
|
exports.capSubTaskText = capSubTaskText;
|
|
@@ -15932,6 +15996,10 @@ var require_loop = __commonJS({
|
|
|
15932
15996
|
var agentTypes_1 = require_agentTypes();
|
|
15933
15997
|
var skills_1 = require_skills();
|
|
15934
15998
|
var rules_1 = require_rules();
|
|
15999
|
+
var bashClassify_1 = require_bashClassify();
|
|
16000
|
+
Object.defineProperty(exports, "bashNeedsRepoLock", { enumerable: true, get: function() {
|
|
16001
|
+
return bashClassify_1.bashNeedsRepoLock;
|
|
16002
|
+
} });
|
|
15935
16003
|
var planMode_1 = require_planMode();
|
|
15936
16004
|
var agentRegistry_1 = require_agentRegistry();
|
|
15937
16005
|
var sandbox_1 = require_sandbox();
|
|
@@ -16165,54 +16233,6 @@ ${ctx.repeatError}
|
|
|
16165
16233
|
"notebook_edit"
|
|
16166
16234
|
]);
|
|
16167
16235
|
var REPO_STATE_LOCK = "\0repo-state";
|
|
16168
|
-
var MUTATING_BASH_VERBS = /* @__PURE__ */ new Set([
|
|
16169
|
-
"git",
|
|
16170
|
-
"npm",
|
|
16171
|
-
"pnpm",
|
|
16172
|
-
"yarn",
|
|
16173
|
-
"bun",
|
|
16174
|
-
"cargo",
|
|
16175
|
-
"go",
|
|
16176
|
-
"pip",
|
|
16177
|
-
"pip3",
|
|
16178
|
-
"poetry",
|
|
16179
|
-
"uv",
|
|
16180
|
-
"bundle",
|
|
16181
|
-
"composer",
|
|
16182
|
-
"gradle",
|
|
16183
|
-
"mvn",
|
|
16184
|
-
"make",
|
|
16185
|
-
"terraform",
|
|
16186
|
-
"helm",
|
|
16187
|
-
"docker",
|
|
16188
|
-
"vsce",
|
|
16189
|
-
"tsc",
|
|
16190
|
-
"pytest",
|
|
16191
|
-
"dotnet",
|
|
16192
|
-
"swift",
|
|
16193
|
-
"gem"
|
|
16194
|
-
]);
|
|
16195
|
-
function bashNeedsRepoLock(command) {
|
|
16196
|
-
if (!command)
|
|
16197
|
-
return false;
|
|
16198
|
-
const segments = command.split(/\|\||&&|[;|&\n()]|\$\(/);
|
|
16199
|
-
for (const seg of segments) {
|
|
16200
|
-
for (const tokenRaw of seg.trim().split(/\s+/)) {
|
|
16201
|
-
const token = tokenRaw.replace(/^["']|["']$/g, "");
|
|
16202
|
-
if (!token)
|
|
16203
|
-
continue;
|
|
16204
|
-
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))
|
|
16205
|
-
continue;
|
|
16206
|
-
if (token === "sudo" || token === "time" || token === "nice" || token === "env")
|
|
16207
|
-
continue;
|
|
16208
|
-
const verb = token.split("/").pop() ?? token;
|
|
16209
|
-
if (MUTATING_BASH_VERBS.has(verb))
|
|
16210
|
-
return true;
|
|
16211
|
-
break;
|
|
16212
|
-
}
|
|
16213
|
-
}
|
|
16214
|
-
return false;
|
|
16215
|
-
}
|
|
16216
16236
|
function lockPathsFor(name, input, workDir) {
|
|
16217
16237
|
if (!WRITE_TOOLS.has(name))
|
|
16218
16238
|
return [];
|
|
@@ -16345,6 +16365,12 @@ ${ctx.repeatError}
|
|
|
16345
16365
|
}
|
|
16346
16366
|
}
|
|
16347
16367
|
var MAX_TASK_DEPTH = 1;
|
|
16368
|
+
exports.NO_NESTED_SUBAGENTS_MSG = "Sub-agents cannot spawn further sub-agents \u2014 this is a structural limit, not a permission, so no other agent type and no approval can lift it. Do this work directly with the tools you have, or report back so the main agent can delegate it.";
|
|
16369
|
+
function canSpawnSubAgents(depth, allowedTools) {
|
|
16370
|
+
if (depth >= MAX_TASK_DEPTH)
|
|
16371
|
+
return false;
|
|
16372
|
+
return allowedTools ? allowedTools.has("task") : true;
|
|
16373
|
+
}
|
|
16348
16374
|
var _subTaskCounter = 0;
|
|
16349
16375
|
var DEFAULT_SUBTASK_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
16350
16376
|
function resolveSubtaskTimeoutMs(settingsRaw) {
|
|
@@ -16473,7 +16499,7 @@ ${body}`);
|
|
|
16473
16499
|
return { error: "task tool requires a non-empty prompt" };
|
|
16474
16500
|
const depth = options._depth ?? 0;
|
|
16475
16501
|
if (depth >= MAX_TASK_DEPTH) {
|
|
16476
|
-
return { error:
|
|
16502
|
+
return { error: exports.NO_NESTED_SUBAGENTS_MSG };
|
|
16477
16503
|
}
|
|
16478
16504
|
const resumeId = typeof input.resume_agent_id === "string" ? input.resume_agent_id.trim() : "";
|
|
16479
16505
|
const resumed = resumeId ? (0, agentRegistry_1.getAgent)(resumeId) : void 0;
|
|
@@ -16524,6 +16550,9 @@ ${inheritedMd}` : "") : options.nexrallMd;
|
|
|
16524
16550
|
if (req.tool === exports.AGENT_MEMORY_TOOL && !(agent && memoryScope)) {
|
|
16525
16551
|
throw new ToolNotAllowedError(`\`${exports.AGENT_MEMORY_TOOL}\` is only available to a sub-agent whose definition declares a \`memory:\` scope (project, user or local). Report anything worth remembering in your final message instead \u2014 the main agent decides what to persist.`);
|
|
16526
16552
|
}
|
|
16553
|
+
if (req.tool === "task") {
|
|
16554
|
+
throw new ToolNotAllowedError(exports.NO_NESTED_SUBAGENTS_MSG);
|
|
16555
|
+
}
|
|
16527
16556
|
if (allowed && !allowed.has(req.tool)) {
|
|
16528
16557
|
throw new ToolNotAllowedError(`The "${agent.name}" sub-agent is not allowed to use \`${req.tool}\` \u2014 it is not in that agent's tool allowlist. This is a restriction of the agent definition, NOT a user decision: do not ask for approval, use one of the tools you do have, or report back that the task needs a different agent.`);
|
|
16529
16558
|
}
|
|
@@ -17058,7 +17087,8 @@ Continue the work from here.` }] });
|
|
|
17058
17087
|
const agentScope = options._agentScope ?? "root";
|
|
17059
17088
|
const settings = (0, rules_1.loadSettings)(options.workDir);
|
|
17060
17089
|
const agentTypes = (0, agentTypes_1.loadAgentTypes)(options.workDir).filter((t2) => (0, rules_1.evaluatePermission)(settings.permissions, "task", { subagent_type: t2.name }, options.workDir) !== "deny");
|
|
17061
|
-
const
|
|
17090
|
+
const maySpawn = canSpawnSubAgents(depth, options._allowedTools);
|
|
17091
|
+
const agentsCatalogue = maySpawn ? (0, agentTypes_1.summariseAgents)(agentTypes) : "";
|
|
17062
17092
|
const skillsCatalogue = (0, skills_1.summariseSkills)((0, skills_1.loadSkills)(options.workDir));
|
|
17063
17093
|
const planAwareNexrallMd = options.planMode ? planMode_1.PLAN_MODE_INSTRUCTIONS + (options.nexrallMd ? `
|
|
17064
17094
|
|
|
@@ -17208,6 +17238,9 @@ ${options.nexrallMd}` : "") : options.nexrallMd;
|
|
|
17208
17238
|
canWriteSharedMemory: options._allowedTools ? options._allowedTools.has("memory_write") : true,
|
|
17209
17239
|
// no allowlist = main agent = may write
|
|
17210
17240
|
hasOwnAgentStore: !!options._agentMemory,
|
|
17241
|
+
// Withholds the `task` schema and its instructions when this run cannot
|
|
17242
|
+
// delegate — see canSpawnSubAgents.
|
|
17243
|
+
canSpawnSubAgents: maySpawn,
|
|
17211
17244
|
agents: agentsCatalogue || void 0,
|
|
17212
17245
|
skills: skillsCatalogue || void 0,
|
|
17213
17246
|
// Only allow a post-render restart when the caller actually implements the
|
|
@@ -17386,7 +17419,7 @@ ${options.nexrallMd}` : "") : options.nexrallMd;
|
|
|
17386
17419
|
options.checkpointManager?.recordBeforeMutation(name, input);
|
|
17387
17420
|
const onStream = options.onToolStreamChunk ? (chunk) => options.onToolStreamChunk(name, chunk) : void 0;
|
|
17388
17421
|
const run = () => (0, executor_1.executeTool)(name, input, options.abortSignal, sandboxCfg, options.workDir, agentScope, onStream);
|
|
17389
|
-
const locks = name === "bash" ? bashNeedsRepoLock(String(input.command ?? "")) ? [REPO_STATE_LOCK] : [] : lockPathsFor(name, input, options.workDir);
|
|
17422
|
+
const locks = name === "bash" ? (0, bashClassify_1.bashNeedsRepoLock)(String(input.command ?? "")) ? [REPO_STATE_LOCK] : [] : lockPathsFor(name, input, options.workDir);
|
|
17390
17423
|
result = locks.length ? await withFileLocks(locks, run) : await run();
|
|
17391
17424
|
}
|
|
17392
17425
|
} catch (err) {
|
|
@@ -18616,6 +18649,95 @@ var require_manager2 = __commonJS({
|
|
|
18616
18649
|
}
|
|
18617
18650
|
});
|
|
18618
18651
|
|
|
18652
|
+
// ../core/dist/permissions/modePolicy.js
|
|
18653
|
+
var require_modePolicy = __commonJS({
|
|
18654
|
+
"../core/dist/permissions/modePolicy.js"(exports) {
|
|
18655
|
+
"use strict";
|
|
18656
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18657
|
+
exports.BASH_TOOLS = exports.FILE_MUTATE_TOOLS = exports.FILE_WRITE_TOOLS = exports.READ_ONLY_TOOLS = void 0;
|
|
18658
|
+
exports.isReadOnlyBash = isReadOnlyBash;
|
|
18659
|
+
exports.decide = decide;
|
|
18660
|
+
exports.describeMode = describeMode2;
|
|
18661
|
+
exports.parseMode = parseMode2;
|
|
18662
|
+
var bashClassify_1 = require_bashClassify();
|
|
18663
|
+
exports.READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
18664
|
+
"read_file",
|
|
18665
|
+
"list_directory",
|
|
18666
|
+
"search_files",
|
|
18667
|
+
"glob",
|
|
18668
|
+
"grep",
|
|
18669
|
+
"fetch_url",
|
|
18670
|
+
"web_search",
|
|
18671
|
+
"bash_output",
|
|
18672
|
+
"kill_shell",
|
|
18673
|
+
"todo_read",
|
|
18674
|
+
"todo_write",
|
|
18675
|
+
"memory_read",
|
|
18676
|
+
"use_skill",
|
|
18677
|
+
"notebook_read",
|
|
18678
|
+
"get_diagnostics",
|
|
18679
|
+
"go_to_definition",
|
|
18680
|
+
"find_references",
|
|
18681
|
+
"get_symbols",
|
|
18682
|
+
"get_workspace_symbols",
|
|
18683
|
+
"get_hover"
|
|
18684
|
+
]);
|
|
18685
|
+
exports.FILE_WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
18686
|
+
"write_file",
|
|
18687
|
+
"create_file",
|
|
18688
|
+
"edit_file",
|
|
18689
|
+
"multi_edit",
|
|
18690
|
+
"notebook_edit"
|
|
18691
|
+
]);
|
|
18692
|
+
exports.FILE_MUTATE_TOOLS = /* @__PURE__ */ new Set([
|
|
18693
|
+
"delete_file",
|
|
18694
|
+
"move_file",
|
|
18695
|
+
"copy_file"
|
|
18696
|
+
]);
|
|
18697
|
+
exports.BASH_TOOLS = /* @__PURE__ */ new Set(["bash", "run_command", "execute_command"]);
|
|
18698
|
+
function isReadOnlyBash(command) {
|
|
18699
|
+
return !(0, bashClassify_1.bashNeedsRepoLock)(command);
|
|
18700
|
+
}
|
|
18701
|
+
function decide(req) {
|
|
18702
|
+
const { tool, mode } = req;
|
|
18703
|
+
const command = String(req.input.command ?? req.input.cmd ?? "");
|
|
18704
|
+
if (exports.READ_ONLY_TOOLS.has(tool))
|
|
18705
|
+
return "allow";
|
|
18706
|
+
if (exports.BASH_TOOLS.has(tool) && isReadOnlyBash(command) && !req.destructive)
|
|
18707
|
+
return "allow";
|
|
18708
|
+
if (req.destructive)
|
|
18709
|
+
return "confirm";
|
|
18710
|
+
if (mode === "plan")
|
|
18711
|
+
return "deny";
|
|
18712
|
+
if (req.bypass)
|
|
18713
|
+
return "allow";
|
|
18714
|
+
if (exports.FILE_WRITE_TOOLS.has(tool) || exports.FILE_MUTATE_TOOLS.has(tool)) {
|
|
18715
|
+
return mode === "ask" ? "ask" : "allow";
|
|
18716
|
+
}
|
|
18717
|
+
if (exports.BASH_TOOLS.has(tool)) {
|
|
18718
|
+
return mode === "auto" ? "allow" : "ask";
|
|
18719
|
+
}
|
|
18720
|
+
return "ask";
|
|
18721
|
+
}
|
|
18722
|
+
function describeMode2(mode) {
|
|
18723
|
+
switch (mode) {
|
|
18724
|
+
case "plan":
|
|
18725
|
+
return "plan \u2014 read-only, produces a plan for approval";
|
|
18726
|
+
case "ask":
|
|
18727
|
+
return "ask \u2014 approves reads; asks before edits and commands";
|
|
18728
|
+
case "edit":
|
|
18729
|
+
return "edit \u2014 edits files freely; asks before shell commands";
|
|
18730
|
+
case "auto":
|
|
18731
|
+
return "auto \u2014 edits and runs commands; still confirms irreversible actions";
|
|
18732
|
+
}
|
|
18733
|
+
}
|
|
18734
|
+
function parseMode2(raw) {
|
|
18735
|
+
const s2 = String(raw ?? "").trim().toLowerCase();
|
|
18736
|
+
return s2 === "plan" || s2 === "ask" || s2 === "edit" || s2 === "auto" ? s2 : "ask";
|
|
18737
|
+
}
|
|
18738
|
+
}
|
|
18739
|
+
});
|
|
18740
|
+
|
|
18619
18741
|
// ../core/dist/permissions/destructive.js
|
|
18620
18742
|
var require_destructive = __commonJS({
|
|
18621
18743
|
"../core/dist/permissions/destructive.js"(exports) {
|
|
@@ -19378,6 +19500,8 @@ var require_dist2 = __commonJS({
|
|
|
19378
19500
|
__exportStar(require_planMode(), exports);
|
|
19379
19501
|
__exportStar(require_agentRegistry(), exports);
|
|
19380
19502
|
__exportStar(require_rules(), exports);
|
|
19503
|
+
__exportStar(require_modePolicy(), exports);
|
|
19504
|
+
__exportStar(require_bashClassify(), exports);
|
|
19381
19505
|
__exportStar(require_destructive(), exports);
|
|
19382
19506
|
__exportStar(require_plugins(), exports);
|
|
19383
19507
|
__exportStar(require_installer(), exports);
|
|
@@ -53703,7 +53827,7 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
53703
53827
|
var source_default = chalk;
|
|
53704
53828
|
|
|
53705
53829
|
// src/index.ts
|
|
53706
|
-
var
|
|
53830
|
+
var import_code_core6 = __toESM(require_dist2(), 1);
|
|
53707
53831
|
|
|
53708
53832
|
// src/commands/auth.ts
|
|
53709
53833
|
import * as readline from "readline";
|
|
@@ -54790,14 +54914,14 @@ var import_code_core2 = __toESM(require_dist2(), 1);
|
|
|
54790
54914
|
var autoApproved = /* @__PURE__ */ new Set();
|
|
54791
54915
|
var _rules = { allow: [], ask: [], deny: [] };
|
|
54792
54916
|
var _workDir = process.cwd();
|
|
54793
|
-
var _mode = "
|
|
54917
|
+
var _mode = "ask";
|
|
54794
54918
|
function initPermissions(workDir) {
|
|
54795
54919
|
_workDir = workDir;
|
|
54796
54920
|
_rules = (0, import_code_core2.loadSettings)(workDir).permissions;
|
|
54797
54921
|
return _rules;
|
|
54798
54922
|
}
|
|
54799
54923
|
function setMode(mode) {
|
|
54800
|
-
_mode = mode
|
|
54924
|
+
_mode = (0, import_code_core2.parseMode)(mode);
|
|
54801
54925
|
}
|
|
54802
54926
|
function setAutoApprove(category) {
|
|
54803
54927
|
autoApproved.add(category);
|
|
@@ -54864,31 +54988,18 @@ async function requestPermission(req) {
|
|
|
54864
54988
|
}
|
|
54865
54989
|
if (decision === "allow")
|
|
54866
54990
|
return true;
|
|
54867
|
-
const
|
|
54868
|
-
|
|
54869
|
-
|
|
54870
|
-
|
|
54871
|
-
"
|
|
54872
|
-
|
|
54873
|
-
"
|
|
54874
|
-
|
|
54875
|
-
|
|
54876
|
-
|
|
54877
|
-
"memory_read",
|
|
54878
|
-
"memory_write",
|
|
54879
|
-
"use_skill",
|
|
54880
|
-
"notebook_read",
|
|
54881
|
-
"get_diagnostics",
|
|
54882
|
-
"go_to_definition",
|
|
54883
|
-
"find_references",
|
|
54884
|
-
"get_symbols",
|
|
54885
|
-
"get_workspace_symbols",
|
|
54886
|
-
"get_hover",
|
|
54887
|
-
"open_in_browser"
|
|
54888
|
-
];
|
|
54889
|
-
if (readOnlyTools.includes(tool))
|
|
54991
|
+
const verdict = (0, import_code_core2.decide)({
|
|
54992
|
+
tool,
|
|
54993
|
+
input,
|
|
54994
|
+
mode: _mode,
|
|
54995
|
+
bypass: isAutoApproved("all"),
|
|
54996
|
+
// The destructive case was already handled above with the strong confirm flow
|
|
54997
|
+
// (type "yes", no "approve all"), so it must not be re-triggered here.
|
|
54998
|
+
destructive: false
|
|
54999
|
+
});
|
|
55000
|
+
if (verdict === "allow")
|
|
54890
55001
|
return true;
|
|
54891
|
-
if (
|
|
55002
|
+
if (verdict === "deny") {
|
|
54892
55003
|
console.error(source_default.yellow(` \u2298 Plan mode \u2014 refused ${tool} (read-only until you switch mode).`));
|
|
54893
55004
|
return false;
|
|
54894
55005
|
}
|
|
@@ -55038,6 +55149,9 @@ async function requestPermission(req) {
|
|
|
55038
55149
|
return answer === "y" || answer === "yes";
|
|
55039
55150
|
}
|
|
55040
55151
|
|
|
55152
|
+
// src/commands/chat.ts
|
|
55153
|
+
var import_code_core4 = __toESM(require_dist2(), 1);
|
|
55154
|
+
|
|
55041
55155
|
// src/commands/sessions.ts
|
|
55042
55156
|
import * as fs3 from "fs";
|
|
55043
55157
|
import * as path from "path";
|
|
@@ -64461,7 +64575,7 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64461
64575
|
};
|
|
64462
64576
|
|
|
64463
64577
|
// src/commands/chat.ts
|
|
64464
|
-
var CLI_VERSION = "0.5.
|
|
64578
|
+
var CLI_VERSION = "0.5.58";
|
|
64465
64579
|
var MODEL_LABELS = {
|
|
64466
64580
|
turbo: "Nexrall Turbo",
|
|
64467
64581
|
pro: "Nexrall Pro",
|
|
@@ -65524,11 +65638,15 @@ ${dirList}`;
|
|
|
65524
65638
|
case "/mode": {
|
|
65525
65639
|
const modeArg = arg.toLowerCase();
|
|
65526
65640
|
if (!modeArg) {
|
|
65527
|
-
console.log(source_default.dim(` Current: ${source_default.cyan(agentMode)}
|
|
65641
|
+
console.log(source_default.dim(` Current: ${source_default.cyan(agentMode)}`));
|
|
65642
|
+
for (const m2 of ["ask", "edit", "auto", "plan"]) {
|
|
65643
|
+
const marker = m2 === agentMode ? source_default.cyan("\u276F") : " ";
|
|
65644
|
+
console.log(` ${marker} ${source_default.bold(m2.padEnd(5))} ${source_default.dim((0, import_code_core4.describeMode)(m2).replace(`${m2} \u2014 `, ""))}`);
|
|
65645
|
+
}
|
|
65528
65646
|
} else if (["ask", "edit", "plan", "auto"].includes(modeArg)) {
|
|
65529
65647
|
agentMode = modeArg;
|
|
65530
65648
|
updateFooter();
|
|
65531
|
-
console.log(source_default.green(` Mode \u2192 ${source_default.bold(modeArg)}`));
|
|
65649
|
+
console.log(source_default.green(` Mode \u2192 ${source_default.bold(modeArg)}`) + source_default.dim(` ${(0, import_code_core4.describeMode)(modeArg).replace(`${modeArg} \u2014 `, "")}`));
|
|
65532
65650
|
} else {
|
|
65533
65651
|
console.log(source_default.red(` Unknown: ${modeArg}`));
|
|
65534
65652
|
}
|
|
@@ -65818,7 +65936,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
65818
65936
|
|
|
65819
65937
|
// src/commands/plugin.ts
|
|
65820
65938
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
65821
|
-
var
|
|
65939
|
+
var import_code_core5 = __toESM(require_dist2(), 1);
|
|
65822
65940
|
function describeInspection(i2, name, ctx) {
|
|
65823
65941
|
console.log();
|
|
65824
65942
|
console.log(source_default.bold(` Plugin: ${name}`) + (i2.meta.version ? source_default.dim(` v${i2.meta.version}`) : ""));
|
|
@@ -65894,14 +66012,14 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
65894
66012
|
let registryName;
|
|
65895
66013
|
const isShortName = /^[\w.-]+$/.test(spec.trim()) && !spec.includes("/");
|
|
65896
66014
|
if (isShortName) {
|
|
65897
|
-
const alias = (0,
|
|
66015
|
+
const alias = (0, import_code_core5.resolveSourceAlias)(spec.trim(), process.cwd(), { includeProject: true });
|
|
65898
66016
|
if (alias) {
|
|
65899
66017
|
source2 = alias.spec;
|
|
65900
66018
|
console.log(source_default.dim(` Source: ${alias.name} (${alias.tier}) \u2190 ${alias.spec}`));
|
|
65901
66019
|
}
|
|
65902
66020
|
}
|
|
65903
66021
|
if (isShortName && source2 === spec) {
|
|
65904
|
-
const entry = await (0,
|
|
66022
|
+
const entry = await (0, import_code_core5.getRegistryPlugin)(spec.trim()).catch(() => null);
|
|
65905
66023
|
if (entry) {
|
|
65906
66024
|
source2 = entry.source;
|
|
65907
66025
|
registryName = entry.name;
|
|
@@ -65916,7 +66034,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
65916
66034
|
return;
|
|
65917
66035
|
}
|
|
65918
66036
|
}
|
|
65919
|
-
const res = await (0,
|
|
66037
|
+
const res = await (0, import_code_core5.installPlugin)(source2, {
|
|
65920
66038
|
scope,
|
|
65921
66039
|
workDir: process.cwd(),
|
|
65922
66040
|
name: opts.name ?? registryName,
|
|
@@ -65924,7 +66042,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
65924
66042
|
confirm: (i2, name, ctx) => confirmInstall(i2, name, opts.yes === true, ctx)
|
|
65925
66043
|
});
|
|
65926
66044
|
if (registryName)
|
|
65927
|
-
(0,
|
|
66045
|
+
(0, import_code_core5.reportInstall)(registryName);
|
|
65928
66046
|
console.log();
|
|
65929
66047
|
console.log(source_default.green(` \u2713 Installed "${res.name}" (${res.scope}) \u2192 ${res.dir}`) + (res.sha ? source_default.dim(` @ ${res.sha.slice(0, 7)}`) : ""));
|
|
65930
66048
|
if (res.inspection.commands.length) {
|
|
@@ -65938,7 +66056,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
65938
66056
|
}
|
|
65939
66057
|
function pluginRemoveCommand(name, opts) {
|
|
65940
66058
|
try {
|
|
65941
|
-
const dir = (0,
|
|
66059
|
+
const dir = (0, import_code_core5.removePlugin)(name, {
|
|
65942
66060
|
scope: opts.project ? "project" : void 0,
|
|
65943
66061
|
// no flag → search both scopes
|
|
65944
66062
|
workDir: process.cwd()
|
|
@@ -65951,14 +66069,14 @@ function pluginRemoveCommand(name, opts) {
|
|
|
65951
66069
|
}
|
|
65952
66070
|
async function pluginUpdateCommand(name, opts) {
|
|
65953
66071
|
const workDir = process.cwd();
|
|
65954
|
-
const targets = name ? [name] : (0,
|
|
66072
|
+
const targets = name ? [name] : (0, import_code_core5.loadPlugins)(workDir).filter((p) => (0, import_code_core5.readReceipt)(p.dir)?.kind === "github").map((p) => p.name);
|
|
65955
66073
|
if (!targets.length) {
|
|
65956
66074
|
console.log(source_default.dim(" No updatable plugins (only GitHub-installed plugins with receipts can update)."));
|
|
65957
66075
|
return;
|
|
65958
66076
|
}
|
|
65959
66077
|
for (const t2 of targets) {
|
|
65960
66078
|
try {
|
|
65961
|
-
const res = await (0,
|
|
66079
|
+
const res = await (0, import_code_core5.updatePlugin)(t2, {
|
|
65962
66080
|
workDir,
|
|
65963
66081
|
confirm: (i2, n, ctx) => confirmInstall(i2, n, opts.yes === true, ctx)
|
|
65964
66082
|
});
|
|
@@ -65975,7 +66093,7 @@ function badgeFor(p) {
|
|
|
65975
66093
|
}
|
|
65976
66094
|
async function pluginSearchCommand(query) {
|
|
65977
66095
|
try {
|
|
65978
|
-
const results = await (0,
|
|
66096
|
+
const results = await (0, import_code_core5.searchRegistry)(query);
|
|
65979
66097
|
if (!results.length) {
|
|
65980
66098
|
console.log(source_default.dim(query ? ` No plugins matching "${query}".` : " Registry is empty."));
|
|
65981
66099
|
return;
|
|
@@ -65998,7 +66116,7 @@ async function pluginSearchCommand(query) {
|
|
|
65998
66116
|
}
|
|
65999
66117
|
async function pluginInfoCommand(name) {
|
|
66000
66118
|
try {
|
|
66001
|
-
const p = await (0,
|
|
66119
|
+
const p = await (0, import_code_core5.getRegistryPlugin)(name);
|
|
66002
66120
|
if (!p) {
|
|
66003
66121
|
console.error(source_default.red(` \u2717 "${name}" not found in the registry.`));
|
|
66004
66122
|
process.exitCode = 1;
|
|
@@ -66034,7 +66152,7 @@ async function pluginInfoCommand(name) {
|
|
|
66034
66152
|
}
|
|
66035
66153
|
}
|
|
66036
66154
|
function pluginListCommand() {
|
|
66037
|
-
const plugins = (0,
|
|
66155
|
+
const plugins = (0, import_code_core5.loadPlugins)(process.cwd());
|
|
66038
66156
|
if (!plugins.length) {
|
|
66039
66157
|
console.log(source_default.dim(" No plugins installed."));
|
|
66040
66158
|
console.log(source_default.dim(" Install one: nex plugin install owner/repo"));
|
|
@@ -66043,10 +66161,10 @@ function pluginListCommand() {
|
|
|
66043
66161
|
console.log();
|
|
66044
66162
|
console.log(source_default.bold(" Installed plugins:"));
|
|
66045
66163
|
for (const p of plugins) {
|
|
66046
|
-
const receipt = (0,
|
|
66164
|
+
const receipt = (0, import_code_core5.readReceipt)(p.dir);
|
|
66047
66165
|
const src = receipt ? source_default.dim(` \u2190 ${receipt.source}`) : source_default.dim(" (manual)");
|
|
66048
66166
|
const at = receipt?.sha ? source_default.dim(` @ ${receipt.sha.slice(0, 7)}`) : "";
|
|
66049
|
-
const insp = (0,
|
|
66167
|
+
const insp = (0, import_code_core5.inspectPluginDir)(p.dir);
|
|
66050
66168
|
const runs = insp.hasHooks || insp.hasMcp ? source_default.yellow(` \u26A0 ${[insp.hasHooks && "hooks", insp.hasMcp && "mcp"].filter(Boolean).join("+")}`) : "";
|
|
66051
66169
|
console.log(
|
|
66052
66170
|
" " + source_default.cyan(p.name.padEnd(24)) + source_default.dim(`${(p.version ?? "").padEnd(10)}${p.scope.padEnd(9)}`) + src + at + runs
|
|
@@ -66056,8 +66174,8 @@ function pluginListCommand() {
|
|
|
66056
66174
|
}
|
|
66057
66175
|
function pluginSourceListCommand() {
|
|
66058
66176
|
const workDir = process.cwd();
|
|
66059
|
-
const sources = (0,
|
|
66060
|
-
const patterns = (0,
|
|
66177
|
+
const sources = (0, import_code_core5.loadDeclaredSources)(workDir, { includeProject: true });
|
|
66178
|
+
const patterns = (0, import_code_core5.allowedSourcePatterns)();
|
|
66061
66179
|
if (patterns) {
|
|
66062
66180
|
console.log();
|
|
66063
66181
|
console.log(source_default.bold(" Organisation policy: ") + source_default.dim(`installs restricted to ${patterns.join(", ")}`));
|
|
@@ -66072,7 +66190,7 @@ function pluginSourceListCommand() {
|
|
|
66072
66190
|
console.log(source_default.bold(" Declared plugin sources:"));
|
|
66073
66191
|
for (const s2 of sources) {
|
|
66074
66192
|
const tier = s2.tier === "project" ? source_default.yellow(s2.tier.padEnd(9)) : source_default.dim(s2.tier.padEnd(9));
|
|
66075
|
-
const blocked = !(0,
|
|
66193
|
+
const blocked = !(0, import_code_core5.isSourceAllowed)(s2.spec, patterns) ? source_default.red(" \u2717 blocked by policy") : "";
|
|
66076
66194
|
console.log(" " + source_default.cyan(s2.name.padEnd(20)) + tier + source_default.white(s2.spec) + blocked);
|
|
66077
66195
|
}
|
|
66078
66196
|
console.log();
|
|
@@ -66082,17 +66200,17 @@ function pluginSourceListCommand() {
|
|
|
66082
66200
|
}
|
|
66083
66201
|
function pluginSourceAddCommand(name, spec, opts) {
|
|
66084
66202
|
try {
|
|
66085
|
-
(0,
|
|
66086
|
-
const patterns = (0,
|
|
66087
|
-
if (patterns && !(0,
|
|
66203
|
+
(0, import_code_core5.parsePluginSource)(spec);
|
|
66204
|
+
const patterns = (0, import_code_core5.allowedSourcePatterns)();
|
|
66205
|
+
if (patterns && !(0, import_code_core5.isSourceAllowed)(spec, patterns)) {
|
|
66088
66206
|
console.error(source_default.red(` \u2717 "${spec}" is not permitted by your organisation's policy.`));
|
|
66089
66207
|
console.error(source_default.dim(` Allowed: ${patterns.join(", ")}`));
|
|
66090
66208
|
process.exitCode = 1;
|
|
66091
66209
|
return;
|
|
66092
66210
|
}
|
|
66093
66211
|
const scope = opts.project ? "project" : "user";
|
|
66094
|
-
const file = (0,
|
|
66095
|
-
(0,
|
|
66212
|
+
const file = (0, import_code_core5.sourcesFileFor)(scope, process.cwd());
|
|
66213
|
+
(0, import_code_core5.writeDeclaredSource)(file, name, spec);
|
|
66096
66214
|
console.log();
|
|
66097
66215
|
console.log(source_default.green(` \u2713 Declared "${name}" \u2192 ${spec}`) + source_default.dim(` (${scope})`));
|
|
66098
66216
|
console.log(source_default.dim(` ${file}`));
|
|
@@ -66106,13 +66224,13 @@ function pluginSourceAddCommand(name, spec, opts) {
|
|
|
66106
66224
|
function pluginSourceRemoveCommand(name, opts) {
|
|
66107
66225
|
const workDir = process.cwd();
|
|
66108
66226
|
const scope = opts.project ? "project" : "user";
|
|
66109
|
-
const file = (0,
|
|
66110
|
-
if ((0,
|
|
66227
|
+
const file = (0, import_code_core5.sourcesFileFor)(scope, workDir);
|
|
66228
|
+
if ((0, import_code_core5.removeDeclaredSource)(file, name)) {
|
|
66111
66229
|
console.log(source_default.green(` \u2713 Removed source "${name}" (${scope})`));
|
|
66112
66230
|
console.log(source_default.dim(" Plugins already installed from it are untouched \u2014 remove them with nex plugin remove <name>"));
|
|
66113
66231
|
return;
|
|
66114
66232
|
}
|
|
66115
|
-
const found = (0,
|
|
66233
|
+
const found = (0, import_code_core5.resolveSourceAlias)(name, workDir, { includeProject: true });
|
|
66116
66234
|
if (found) {
|
|
66117
66235
|
console.error(source_default.red(` \u2717 "${name}" is declared in the ${found.tier} tier, not ${scope}.`));
|
|
66118
66236
|
console.error(source_default.dim(` ${found.file}`));
|
|
@@ -66128,7 +66246,7 @@ function pluginSourceRemoveCommand(name, opts) {
|
|
|
66128
66246
|
|
|
66129
66247
|
// src/index.ts
|
|
66130
66248
|
var program2 = new Command();
|
|
66131
|
-
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.
|
|
66249
|
+
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.58").enablePositionalOptions();
|
|
66132
66250
|
program2.command("auth").description("Login to your Nexrall account").action(authCommand);
|
|
66133
66251
|
program2.command("logout").description("Log out of your Nexrall account").action(logoutCommand);
|
|
66134
66252
|
program2.command("update").description("Update nex to the latest version").option("-c, --check", "Check for updates without installing").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
|
|
@@ -66200,7 +66318,7 @@ program2.command("sessions").description("List or delete saved chat sessions").o
|
|
|
66200
66318
|
console.log();
|
|
66201
66319
|
});
|
|
66202
66320
|
program2.option("-p, --pro", "Use Nexrall Pro (Claude Opus, most capable)").option("-t, --turbo", "Use Nexrall Turbo (Claude Sonnet, fast)").option("-u, --ultra", "Use Ultra (Claude Fable 5, 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: turbo | pro | ultra").option("-r, --resume [id]", "Resume last session, or a specific session id").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)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
66203
|
-
if (!(0,
|
|
66321
|
+
if (!(0, import_code_core6.isAuthenticated)()) {
|
|
66204
66322
|
console.error("Not logged in. Run: nex auth");
|
|
66205
66323
|
process.exit(1);
|
|
66206
66324
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexrall-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.58",
|
|
4
4
|
"description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"react": "^19.2.8",
|
|
42
42
|
"readline": "^1.3.0",
|
|
43
43
|
"string-width": "^7.2.0",
|
|
44
|
-
"@nexrall/code-core": "1.4.
|
|
44
|
+
"@nexrall/code-core": "1.4.33"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@aws-sdk/client-s3": "^3.600.0",
|