nexrall-code 0.5.55 → 0.5.56
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 +142 -30
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -15902,7 +15902,11 @@ var require_loop = __commonJS({
|
|
|
15902
15902
|
exports.executeAgentMemoryWrite = executeAgentMemoryWrite;
|
|
15903
15903
|
exports.stopReasonNotice = stopReasonNotice;
|
|
15904
15904
|
exports.resolveMaxIterations = resolveMaxIterations;
|
|
15905
|
+
exports.bashNeedsRepoLock = bashNeedsRepoLock;
|
|
15906
|
+
exports.lockPathsFor = lockPathsFor;
|
|
15907
|
+
exports.resolveMaxConcurrentSubtasks = resolveMaxConcurrentSubtasks;
|
|
15905
15908
|
exports.createLimiter = createLimiter;
|
|
15909
|
+
exports._resetSubTaskLimiter = _resetSubTaskLimiter;
|
|
15906
15910
|
exports.resolveSubtaskTimeoutMs = resolveSubtaskTimeoutMs;
|
|
15907
15911
|
exports.extractSubTaskText = extractSubTaskText;
|
|
15908
15912
|
exports.capSubTaskText = capSubTaskText;
|
|
@@ -16144,10 +16148,89 @@ ${ctx.repeatError}
|
|
|
16144
16148
|
_fileLocks.delete(absPath);
|
|
16145
16149
|
}
|
|
16146
16150
|
}
|
|
16147
|
-
|
|
16148
|
-
const
|
|
16149
|
-
|
|
16150
|
-
|
|
16151
|
+
async function withFileLocks(absPaths, fn) {
|
|
16152
|
+
const unique = [...new Set(absPaths.filter(Boolean))].sort();
|
|
16153
|
+
if (unique.length === 0)
|
|
16154
|
+
return fn();
|
|
16155
|
+
const [first, ...rest] = unique;
|
|
16156
|
+
return withFileLock(first, () => rest.length ? withFileLocks(rest, fn) : fn());
|
|
16157
|
+
}
|
|
16158
|
+
var WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
16159
|
+
"write_file",
|
|
16160
|
+
"edit_file",
|
|
16161
|
+
"multi_edit",
|
|
16162
|
+
"delete_file",
|
|
16163
|
+
"move_file",
|
|
16164
|
+
"copy_file",
|
|
16165
|
+
"notebook_edit"
|
|
16166
|
+
]);
|
|
16167
|
+
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
|
+
function lockPathsFor(name, input, workDir) {
|
|
16217
|
+
if (!WRITE_TOOLS.has(name))
|
|
16218
|
+
return [];
|
|
16219
|
+
const raw = [input.path, input.source, input.destination, input.dest].filter((p) => typeof p === "string" && p.length > 0);
|
|
16220
|
+
const abs = raw.map((p) => workDir ? path6.resolve(workDir, p) : p);
|
|
16221
|
+
return abs.length ? abs : [name];
|
|
16222
|
+
}
|
|
16223
|
+
var DEFAULT_MAX_CONCURRENT_SUBTASKS = 4;
|
|
16224
|
+
function resolveMaxConcurrentSubtasks(settingsRaw = {}) {
|
|
16225
|
+
const clamp = (n) => Math.min(Math.floor(n), 16);
|
|
16226
|
+
const fromEnv = Number(process.env.NEXRALL_MAX_CONCURRENT_SUBTASKS);
|
|
16227
|
+
if (Number.isFinite(fromEnv) && fromEnv > 0)
|
|
16228
|
+
return clamp(fromEnv);
|
|
16229
|
+
const fromSettings = Number(settingsRaw.maxConcurrentSubtasks);
|
|
16230
|
+
if (Number.isFinite(fromSettings) && fromSettings > 0)
|
|
16231
|
+
return clamp(fromSettings);
|
|
16232
|
+
return DEFAULT_MAX_CONCURRENT_SUBTASKS;
|
|
16233
|
+
}
|
|
16151
16234
|
function createLimiter(max) {
|
|
16152
16235
|
let active = 0;
|
|
16153
16236
|
const queue = [];
|
|
@@ -16166,7 +16249,20 @@ ${ctx.repeatError}
|
|
|
16166
16249
|
}
|
|
16167
16250
|
};
|
|
16168
16251
|
}
|
|
16169
|
-
var
|
|
16252
|
+
var _subTaskLimitInstance = null;
|
|
16253
|
+
var _subTaskLimitMax = 0;
|
|
16254
|
+
var _inFlightSubTasks = 0;
|
|
16255
|
+
function subTaskLimiter(workDir) {
|
|
16256
|
+
if (!_subTaskLimitInstance) {
|
|
16257
|
+
_subTaskLimitMax = resolveMaxConcurrentSubtasks(workDir ? (0, rules_1.loadSettings)(workDir).raw : {});
|
|
16258
|
+
_subTaskLimitInstance = createLimiter(_subTaskLimitMax);
|
|
16259
|
+
}
|
|
16260
|
+
return { run: _subTaskLimitInstance, max: _subTaskLimitMax };
|
|
16261
|
+
}
|
|
16262
|
+
function _resetSubTaskLimiter() {
|
|
16263
|
+
_subTaskLimitInstance = null;
|
|
16264
|
+
_subTaskLimitMax = 0;
|
|
16265
|
+
}
|
|
16170
16266
|
function humanDescription(name, input) {
|
|
16171
16267
|
switch (name) {
|
|
16172
16268
|
case "read_file":
|
|
@@ -17255,7 +17351,20 @@ ${options.nexrallMd}` : "") : options.nexrallMd;
|
|
|
17255
17351
|
if (!permitted) {
|
|
17256
17352
|
result = { error: deniedReason ?? "Permission denied by user" };
|
|
17257
17353
|
} else if (name === "task") {
|
|
17258
|
-
|
|
17354
|
+
if (depth === 0) {
|
|
17355
|
+
const { run: limitRun, max: limitMax } = subTaskLimiter(options.workDir);
|
|
17356
|
+
if (_inFlightSubTasks >= limitMax) {
|
|
17357
|
+
(options.onNotice ?? options.onText)(`\u23F3 Queued: ${limitMax} sub-agents are already running, so this one starts when a slot frees up (raise "maxConcurrentSubtasks" in .nexrall/settings.json to widen it).`);
|
|
17358
|
+
}
|
|
17359
|
+
_inFlightSubTasks++;
|
|
17360
|
+
try {
|
|
17361
|
+
result = await limitRun(() => runSubTask(input, options, agentTypes));
|
|
17362
|
+
} finally {
|
|
17363
|
+
_inFlightSubTasks--;
|
|
17364
|
+
}
|
|
17365
|
+
} else {
|
|
17366
|
+
result = await runSubTask(input, options, agentTypes);
|
|
17367
|
+
}
|
|
17259
17368
|
} else {
|
|
17260
17369
|
const pre = runToolHooks(hooks.PreToolUse, "PreToolUse", name, input, options.workDir);
|
|
17261
17370
|
if (pre.block) {
|
|
@@ -17275,15 +17384,10 @@ ${options.nexrallMd}` : "") : options.nexrallMd;
|
|
|
17275
17384
|
result = { output: mcpOutput ?? "" };
|
|
17276
17385
|
} else {
|
|
17277
17386
|
options.checkpointManager?.recordBeforeMutation(name, input);
|
|
17278
|
-
const WRITE_TOOLS = /* @__PURE__ */ new Set(["write_file", "edit_file", "multi_edit", "delete_file", "move_file", "copy_file", "notebook_edit"]);
|
|
17279
17387
|
const onStream = options.onToolStreamChunk ? (chunk) => options.onToolStreamChunk(name, chunk) : void 0;
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
result = await withFileLock(absTarget || name, () => (0, executor_1.executeTool)(name, input, options.abortSignal, sandboxCfg, options.workDir, agentScope, onStream));
|
|
17284
|
-
} else {
|
|
17285
|
-
result = await (0, executor_1.executeTool)(name, input, options.abortSignal, sandboxCfg, options.workDir, agentScope, onStream);
|
|
17286
|
-
}
|
|
17388
|
+
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);
|
|
17390
|
+
result = locks.length ? await withFileLocks(locks, run) : await run();
|
|
17287
17391
|
}
|
|
17288
17392
|
} catch (err) {
|
|
17289
17393
|
result = { error: `Tool execution failed: ${err.message}` };
|
|
@@ -54708,22 +54812,30 @@ var _replInterface = null;
|
|
|
54708
54812
|
function setReadlineInterface(rl) {
|
|
54709
54813
|
_replInterface = rl;
|
|
54710
54814
|
}
|
|
54815
|
+
var _promptChain = Promise.resolve();
|
|
54816
|
+
function serialisePrompt(fn) {
|
|
54817
|
+
const next = _promptChain.then(fn, fn);
|
|
54818
|
+
_promptChain = next.catch(() => void 0);
|
|
54819
|
+
return next;
|
|
54820
|
+
}
|
|
54711
54821
|
function askUser(question) {
|
|
54712
|
-
|
|
54713
|
-
|
|
54822
|
+
return serialisePrompt(() => {
|
|
54823
|
+
if (_replInterface) {
|
|
54824
|
+
const rl = _replInterface;
|
|
54825
|
+
return new Promise((resolve3) => {
|
|
54826
|
+
rl.question(question, (answer) => resolve3(answer.trim()));
|
|
54827
|
+
});
|
|
54828
|
+
}
|
|
54714
54829
|
return new Promise((resolve3) => {
|
|
54715
|
-
rl
|
|
54716
|
-
|
|
54717
|
-
|
|
54718
|
-
|
|
54719
|
-
|
|
54720
|
-
|
|
54721
|
-
|
|
54722
|
-
|
|
54723
|
-
|
|
54724
|
-
rl.question(question, (answer) => {
|
|
54725
|
-
rl.close();
|
|
54726
|
-
resolve3(answer.trim());
|
|
54830
|
+
const rl = readline2.createInterface({
|
|
54831
|
+
input: process.stdin,
|
|
54832
|
+
output: process.stderr,
|
|
54833
|
+
terminal: true
|
|
54834
|
+
});
|
|
54835
|
+
rl.question(question, (answer) => {
|
|
54836
|
+
rl.close();
|
|
54837
|
+
resolve3(answer.trim());
|
|
54838
|
+
});
|
|
54727
54839
|
});
|
|
54728
54840
|
});
|
|
54729
54841
|
}
|
|
@@ -64349,7 +64461,7 @@ var InkReadlineAdapter = class extends EventEmitter3 {
|
|
|
64349
64461
|
};
|
|
64350
64462
|
|
|
64351
64463
|
// src/commands/chat.ts
|
|
64352
|
-
var CLI_VERSION = "0.5.
|
|
64464
|
+
var CLI_VERSION = "0.5.56";
|
|
64353
64465
|
var MODEL_LABELS = {
|
|
64354
64466
|
turbo: "Nexrall Turbo",
|
|
64355
64467
|
pro: "Nexrall Pro",
|
|
@@ -66016,7 +66128,7 @@ function pluginSourceRemoveCommand(name, opts) {
|
|
|
66016
66128
|
|
|
66017
66129
|
// src/index.ts
|
|
66018
66130
|
var program2 = new Command();
|
|
66019
|
-
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.
|
|
66131
|
+
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.56").enablePositionalOptions();
|
|
66020
66132
|
program2.command("auth").description("Login to your Nexrall account").action(authCommand);
|
|
66021
66133
|
program2.command("logout").description("Log out of your Nexrall account").action(logoutCommand);
|
|
66022
66134
|
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) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexrall-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.56",
|
|
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.31"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@aws-sdk/client-s3": "^3.600.0",
|