nexrall-code 0.5.123 → 0.5.124
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 +508 -416
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104964,60 +104964,361 @@ var require_rules = __commonJS({
|
|
|
104964
104964
|
}
|
|
104965
104965
|
});
|
|
104966
104966
|
|
|
104967
|
-
// ../core/dist/
|
|
104968
|
-
var
|
|
104969
|
-
"../core/dist/
|
|
104967
|
+
// ../core/dist/agent/planMode.js
|
|
104968
|
+
var require_planMode = __commonJS({
|
|
104969
|
+
"../core/dist/agent/planMode.js"(exports2) {
|
|
104970
104970
|
"use strict";
|
|
104971
104971
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
104972
|
-
exports2.
|
|
104973
|
-
|
|
104974
|
-
|
|
104975
|
-
|
|
104976
|
-
|
|
104977
|
-
"
|
|
104978
|
-
"
|
|
104979
|
-
"
|
|
104980
|
-
"
|
|
104981
|
-
"
|
|
104982
|
-
|
|
104983
|
-
|
|
104984
|
-
|
|
104985
|
-
"
|
|
104986
|
-
"
|
|
104987
|
-
|
|
104988
|
-
|
|
104989
|
-
|
|
104990
|
-
"
|
|
104991
|
-
"
|
|
104992
|
-
"
|
|
104993
|
-
"
|
|
104994
|
-
|
|
104995
|
-
|
|
104996
|
-
|
|
104997
|
-
|
|
104998
|
-
|
|
104972
|
+
exports2.PLAN_MODE_INSTRUCTIONS = void 0;
|
|
104973
|
+
exports2.isReadOnlyCommand = isReadOnlyCommand;
|
|
104974
|
+
exports2.isReadOnlyPipeline = isReadOnlyPipeline;
|
|
104975
|
+
exports2.checkPlanMode = checkPlanMode;
|
|
104976
|
+
var READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
104977
|
+
"read_file",
|
|
104978
|
+
"search_files",
|
|
104979
|
+
"glob",
|
|
104980
|
+
"list_directory",
|
|
104981
|
+
"notebook_read",
|
|
104982
|
+
// Planning bookkeeping. todo_write persists only to the session's own todo
|
|
104983
|
+
// list, not the repo, so it stays available — a plan mode that cannot draft
|
|
104984
|
+
// a checklist is missing the point of plan mode.
|
|
104985
|
+
"todo_write",
|
|
104986
|
+
"todo_read",
|
|
104987
|
+
// Reading memory is fine; memory_write is NOT here on purpose. Memory is
|
|
104988
|
+
// durable state that survives the session, so writing it is a real mutation
|
|
104989
|
+
// even though no file in the repo changes.
|
|
104990
|
+
"memory_read",
|
|
104991
|
+
"use_skill",
|
|
104992
|
+
"fetch_url",
|
|
104993
|
+
"web_search",
|
|
104994
|
+
// Delegating research is ALLOWED, and this is safe rather than a hole:
|
|
104995
|
+
// runSubTask passes planMode down, so the sub-agent is under the same lock and
|
|
104996
|
+
// its own write tools are refused by this very function one level deeper.
|
|
104997
|
+
//
|
|
104998
|
+
// Worth allowing rather than blanket-refusing, because plan mode exists to
|
|
104999
|
+
// support deep research and the explorer agent is the cheapest way to do bulk
|
|
105000
|
+
// searching without flooding the main context. Blocking `task` would have made
|
|
105001
|
+
// the mode's headline use case worse, for no security gain.
|
|
105002
|
+
"task",
|
|
105003
|
+
// VS Code language server — all pure queries.
|
|
105004
|
+
"get_symbols",
|
|
105005
|
+
"get_workspace_symbols",
|
|
105006
|
+
"find_references",
|
|
105007
|
+
"go_to_definition",
|
|
105008
|
+
"get_hover",
|
|
105009
|
+
"get_diagnostics",
|
|
105010
|
+
// Reading output from an ALREADY-running background shell. Starting one is
|
|
105011
|
+
// gated with the rest of bash below; draining a buffer is not a new effect.
|
|
105012
|
+
"bash_output"
|
|
104999
105013
|
]);
|
|
105000
|
-
|
|
105001
|
-
|
|
105002
|
-
|
|
105003
|
-
|
|
105004
|
-
|
|
105005
|
-
|
|
105006
|
-
|
|
105007
|
-
|
|
105008
|
-
|
|
105009
|
-
|
|
105010
|
-
|
|
105011
|
-
|
|
105012
|
-
|
|
105013
|
-
|
|
105014
|
-
|
|
105014
|
+
var READ_ONLY_BASH = /* @__PURE__ */ new Set([
|
|
105015
|
+
"ls",
|
|
105016
|
+
"cat",
|
|
105017
|
+
"head",
|
|
105018
|
+
"tail",
|
|
105019
|
+
"wc",
|
|
105020
|
+
"file",
|
|
105021
|
+
"stat",
|
|
105022
|
+
"du",
|
|
105023
|
+
"df",
|
|
105024
|
+
"pwd",
|
|
105025
|
+
"which",
|
|
105026
|
+
"type",
|
|
105027
|
+
"echo",
|
|
105028
|
+
"printf",
|
|
105029
|
+
"basename",
|
|
105030
|
+
"dirname",
|
|
105031
|
+
"realpath",
|
|
105032
|
+
"readlink",
|
|
105033
|
+
"grep",
|
|
105034
|
+
"egrep",
|
|
105035
|
+
"fgrep",
|
|
105036
|
+
"rg",
|
|
105037
|
+
"ag",
|
|
105038
|
+
"ack",
|
|
105039
|
+
"find",
|
|
105040
|
+
"fd",
|
|
105041
|
+
"locate",
|
|
105042
|
+
"diff",
|
|
105043
|
+
"comm",
|
|
105044
|
+
"cmp",
|
|
105045
|
+
"sort",
|
|
105046
|
+
"uniq",
|
|
105047
|
+
"cut",
|
|
105048
|
+
"tr",
|
|
105049
|
+
"column",
|
|
105050
|
+
"jq",
|
|
105051
|
+
"yq",
|
|
105052
|
+
"date",
|
|
105053
|
+
"whoami",
|
|
105054
|
+
"hostname",
|
|
105055
|
+
"uname",
|
|
105056
|
+
"env",
|
|
105057
|
+
"printenv",
|
|
105058
|
+
"id",
|
|
105059
|
+
"groups",
|
|
105060
|
+
"ps",
|
|
105061
|
+
"uptime",
|
|
105062
|
+
"free",
|
|
105063
|
+
"node",
|
|
105064
|
+
"python",
|
|
105065
|
+
"python3",
|
|
105066
|
+
// `less`/`more`/`top` are deliberately NOT here: pagers run `!cmd` from inside and
|
|
105067
|
+
// `top` never exits. `env` is listed but only bare — see toolFlagsOk.
|
|
105068
|
+
"tree",
|
|
105069
|
+
"nl",
|
|
105070
|
+
"tac",
|
|
105071
|
+
"strings",
|
|
105072
|
+
"md5sum",
|
|
105073
|
+
"sha256sum",
|
|
105074
|
+
"true",
|
|
105075
|
+
"false",
|
|
105076
|
+
"test",
|
|
105077
|
+
"sleep",
|
|
105078
|
+
"seq",
|
|
105079
|
+
"expr",
|
|
105080
|
+
// Changes this shell's cwd only. Needed so `cd x && ls` is not refused.
|
|
105081
|
+
"cd"
|
|
105082
|
+
]);
|
|
105083
|
+
var SYSTEM_BIN_DIRS = /* @__PURE__ */ new Set([
|
|
105084
|
+
"/bin",
|
|
105085
|
+
"/usr/bin",
|
|
105086
|
+
"/usr/local/bin",
|
|
105087
|
+
"/sbin",
|
|
105088
|
+
"/usr/sbin",
|
|
105089
|
+
"/opt/homebrew/bin"
|
|
105090
|
+
]);
|
|
105091
|
+
var UNSAFE_ENV = /^(PATH|HOME|SHELL|IFS|ENV|BASH_ENV|PAGER|MANPAGER|EDITOR|VISUAL|BROWSER|LD_\w*|DYLD_\w*|GIT_\w*|NODE_\w*|NPM_\w*|npm_\w*|PYTHON\w*|BASH\w*|RUBY\w*|PERL\w*|LESS\w*|XDG_\w*|\w*OPTS?)=/i;
|
|
105092
|
+
var GH_NOUNS = /* @__PURE__ */ new Set(["pr", "issue", "run", "repo", "release", "workflow", "gist", "label"]);
|
|
105093
|
+
var READ_ONLY_SUBCOMMANDS = {
|
|
105094
|
+
git: /* @__PURE__ */ new Set([
|
|
105095
|
+
"log",
|
|
105096
|
+
"show",
|
|
105097
|
+
"diff",
|
|
105098
|
+
"status",
|
|
105099
|
+
"blame",
|
|
105100
|
+
"branch",
|
|
105101
|
+
"tag",
|
|
105102
|
+
"remote",
|
|
105103
|
+
"describe",
|
|
105104
|
+
"rev-parse",
|
|
105105
|
+
"rev-list",
|
|
105106
|
+
"ls-files",
|
|
105107
|
+
"ls-tree",
|
|
105108
|
+
"ls-remote",
|
|
105109
|
+
"cat-file",
|
|
105110
|
+
"shortlog",
|
|
105111
|
+
"reflog",
|
|
105112
|
+
"whatchanged",
|
|
105113
|
+
"grep",
|
|
105114
|
+
"config",
|
|
105115
|
+
"check-ignore",
|
|
105116
|
+
"merge-base",
|
|
105117
|
+
"name-rev",
|
|
105118
|
+
"count-objects",
|
|
105119
|
+
"verify-commit"
|
|
105120
|
+
]),
|
|
105121
|
+
// Package managers: only their query verbs.
|
|
105122
|
+
npm: /* @__PURE__ */ new Set(["ls", "list", "view", "info", "outdated", "why", "config", "ping", "search"]),
|
|
105123
|
+
pnpm: /* @__PURE__ */ new Set(["ls", "list", "view", "info", "outdated", "why", "config"]),
|
|
105124
|
+
yarn: /* @__PURE__ */ new Set(["list", "info", "why", "config"]),
|
|
105125
|
+
cargo: /* @__PURE__ */ new Set(["tree", "metadata", "search"]),
|
|
105126
|
+
go: /* @__PURE__ */ new Set(["list", "version", "env", "vet", "doc"]),
|
|
105127
|
+
docker: /* @__PURE__ */ new Set(["ps", "images", "logs", "inspect", "version", "info", "top", "port", "diff", "stats"]),
|
|
105128
|
+
kubectl: /* @__PURE__ */ new Set(["get", "describe", "logs", "explain", "top", "version", "api-resources", "api-versions"]),
|
|
105129
|
+
// gh: read verbs only. `gh run rerun`, `gh pr merge` etc. are excluded, and
|
|
105130
|
+
// the nested-verb check in isReadOnlyCommand handles `gh pr view` vs `gh pr merge`.
|
|
105131
|
+
gh: /* @__PURE__ */ new Set(["browse"])
|
|
105132
|
+
};
|
|
105133
|
+
var READ_ONLY_NESTED = {
|
|
105134
|
+
gh: /* @__PURE__ */ new Set(["view", "list", "status", "diff", "checks"])
|
|
105135
|
+
};
|
|
105136
|
+
var SHELL_CONTROL = /[\n\r;&|`]|\$\(|>>|>|<\(/;
|
|
105137
|
+
var isShort = (f3) => f3.startsWith("-") && !f3.startsWith("--");
|
|
105138
|
+
var flagName = (f3) => f3.split("=")[0];
|
|
105139
|
+
function toolFlagsOk(verb, args) {
|
|
105140
|
+
const flags = args.filter((a) => a.startsWith("-"));
|
|
105141
|
+
const pos = args.filter((a) => !a.startsWith("-"));
|
|
105142
|
+
switch (verb) {
|
|
105143
|
+
case "env":
|
|
105144
|
+
return args.length === 0;
|
|
105145
|
+
case "sort":
|
|
105146
|
+
return !flags.some((f3) => isShort(f3) && /^-[A-Za-z]*o/.test(f3) || f3.startsWith("--output") || f3.startsWith("--compress-program"));
|
|
105147
|
+
case "uniq":
|
|
105148
|
+
return pos.length <= 1;
|
|
105149
|
+
case "find":
|
|
105150
|
+
return !args.some((a) => ["-exec", "-execdir", "-delete", "-ok", "-okdir", "-fprint", "-fprint0", "-fprintf", "-fls"].includes(a));
|
|
105151
|
+
case "fd":
|
|
105152
|
+
return !flags.some((f3) => f3.startsWith("--exec") || isShort(f3) && /^-[A-Za-z]*[xX]/.test(f3));
|
|
105153
|
+
case "rg":
|
|
105154
|
+
return !flags.some((f3) => flagName(f3) === "--pre" || f3.startsWith("--hostname-bin"));
|
|
105155
|
+
case "ag":
|
|
105156
|
+
case "ack":
|
|
105157
|
+
return !flags.some((f3) => f3.startsWith("--pager"));
|
|
105158
|
+
case "yq":
|
|
105159
|
+
return !flags.some((f3) => isShort(f3) && /^-[A-Za-z]*i/.test(f3) || f3.startsWith("--inplace"));
|
|
105160
|
+
case "tree":
|
|
105161
|
+
return !flags.some((f3) => isShort(f3) && /^-[A-Za-z]*o/.test(f3));
|
|
105162
|
+
case "date":
|
|
105163
|
+
return !flags.some((f3) => isShort(f3) && /^-[A-Za-z]*s/.test(f3) || f3.startsWith("--set"));
|
|
105164
|
+
case "hostname":
|
|
105165
|
+
return pos.length === 0;
|
|
105166
|
+
case "file":
|
|
105167
|
+
return !flags.some((f3) => isShort(f3) && /^-[A-Za-z]*C/.test(f3) || f3.startsWith("--compile"));
|
|
105168
|
+
default:
|
|
105169
|
+
return true;
|
|
105170
|
+
}
|
|
105171
|
+
}
|
|
105172
|
+
function flagsWithin(flags, shorts, longs) {
|
|
105173
|
+
return flags.every((f3) => {
|
|
105174
|
+
if (isShort(f3))
|
|
105175
|
+
return [...f3.slice(1)].every((c) => shorts.includes(c) || /\d/.test(c));
|
|
105176
|
+
return longs.includes(flagName(f3));
|
|
105177
|
+
});
|
|
105178
|
+
}
|
|
105179
|
+
var LISTISH = ["-l", "--list", "--contains", "--no-contains", "--merged", "--no-merged", "--points-at"];
|
|
105180
|
+
function subcommandFlagsOk(verb, sub, args) {
|
|
105181
|
+
const flags = args.filter((a) => a.startsWith("-"));
|
|
105182
|
+
const pos = args.filter((a) => !a.startsWith("-"));
|
|
105183
|
+
const listish = flags.some((f3) => LISTISH.includes(flagName(f3)) || isShort(f3) && f3.includes("l"));
|
|
105184
|
+
if (verb === "git") {
|
|
105185
|
+
if (flags.some((f3) => f3.startsWith("--output") || f3 === "--ext-diff" || f3 === "-O" || f3.startsWith("--open-files-in-pager")))
|
|
105186
|
+
return false;
|
|
105187
|
+
switch (sub) {
|
|
105188
|
+
case "branch":
|
|
105189
|
+
return flagsWithin(flags, "arvlq", ["--all", "--remotes", "--verbose", "--list", "--show-current", "--contains", "--no-contains", "--merged", "--no-merged", "--points-at", "--sort", "--format", "--column", "--no-column", "--color", "--no-color", "--abbrev", "--no-abbrev", "--ignore-case", "--omit-empty"]) && (pos.length <= 1 || listish);
|
|
105190
|
+
case "tag":
|
|
105191
|
+
return flagsWithin(flags, "lnv", ["--list", "--contains", "--no-contains", "--merged", "--no-merged", "--points-at", "--sort", "--format", "--column", "--no-column", "--color", "--no-color", "--verify", "--ignore-case", "--omit-empty"]) && (pos.length <= 1 || listish || flags.some((f3) => f3 === "-v" || f3 === "--verify"));
|
|
105192
|
+
case "remote":
|
|
105193
|
+
return flagsWithin(flags, "vn", ["--verbose"]) && (pos[1] === void 0 || pos[1] === "show" || pos[1] === "get-url");
|
|
105194
|
+
case "config":
|
|
105195
|
+
return flagsWithin(flags, "lz", ["--get", "--get-all", "--get-regexp", "--list", "--show-origin", "--show-scope", "--global", "--local", "--system", "--worktree", "--name-only", "--null", "--includes", "--no-includes", "--type"]) && pos.length <= 2;
|
|
105196
|
+
case "reflog":
|
|
105197
|
+
return pos[1] !== "expire" && pos[1] !== "delete";
|
|
105198
|
+
default:
|
|
105015
105199
|
return true;
|
|
105016
|
-
break;
|
|
105017
105200
|
}
|
|
105018
105201
|
}
|
|
105019
|
-
|
|
105202
|
+
if (sub === "config" && (verb === "npm" || verb === "pnpm" || verb === "yarn")) {
|
|
105203
|
+
return pos[1] === void 0 || pos[1] === "get" || pos[1] === "list" || pos[1] === "ls";
|
|
105204
|
+
}
|
|
105205
|
+
if (verb === "go") {
|
|
105206
|
+
return !flags.some((f3) => {
|
|
105207
|
+
const n = f3.replace(/^--?/, "-");
|
|
105208
|
+
return n === "-w" || n === "-u" || n.startsWith("-vettool") || n.startsWith("-toolexec") || n === "-exec";
|
|
105209
|
+
});
|
|
105210
|
+
}
|
|
105211
|
+
return true;
|
|
105212
|
+
}
|
|
105213
|
+
function firstWords(command) {
|
|
105214
|
+
return command.trim().split(/\s+/).filter(Boolean);
|
|
105215
|
+
}
|
|
105216
|
+
function isReadOnlyCommand(command) {
|
|
105217
|
+
const cmd = command.trim();
|
|
105218
|
+
if (!cmd)
|
|
105219
|
+
return false;
|
|
105220
|
+
if (SHELL_CONTROL.test(cmd))
|
|
105221
|
+
return false;
|
|
105222
|
+
const words = firstWords(cmd);
|
|
105223
|
+
if (!words.length)
|
|
105224
|
+
return false;
|
|
105225
|
+
let i2 = 0;
|
|
105226
|
+
while (i2 < words.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[i2])) {
|
|
105227
|
+
if (UNSAFE_ENV.test(words[i2]))
|
|
105228
|
+
return false;
|
|
105229
|
+
i2++;
|
|
105230
|
+
}
|
|
105231
|
+
if (i2 >= words.length)
|
|
105232
|
+
return false;
|
|
105233
|
+
let verb = words[i2];
|
|
105234
|
+
const slash = verb.lastIndexOf("/");
|
|
105235
|
+
if (slash >= 0) {
|
|
105236
|
+
if (!SYSTEM_BIN_DIRS.has(verb.slice(0, slash)))
|
|
105237
|
+
return false;
|
|
105238
|
+
verb = verb.slice(slash + 1);
|
|
105239
|
+
}
|
|
105240
|
+
if (verb === "sudo" || verb === "doas" || verb === "su")
|
|
105241
|
+
return false;
|
|
105242
|
+
const rest = words.slice(i2 + 1).filter((w) => !w.startsWith("-"));
|
|
105243
|
+
const subs = READ_ONLY_SUBCOMMANDS[verb];
|
|
105244
|
+
if (subs) {
|
|
105245
|
+
const sub = rest[0];
|
|
105246
|
+
if (!sub) {
|
|
105247
|
+
return true;
|
|
105248
|
+
}
|
|
105249
|
+
if (subs.has(sub))
|
|
105250
|
+
return subcommandFlagsOk(verb, sub, words.slice(i2 + 1));
|
|
105251
|
+
const nested = READ_ONLY_NESTED[verb];
|
|
105252
|
+
if (nested && rest[1] && nested.has(rest[1]) && (verb !== "gh" || GH_NOUNS.has(sub)))
|
|
105253
|
+
return true;
|
|
105254
|
+
return false;
|
|
105255
|
+
}
|
|
105256
|
+
if (!READ_ONLY_TOOLS.has(verb) && !READ_ONLY_BASH.has(verb))
|
|
105257
|
+
return false;
|
|
105258
|
+
if (verb === "node" || verb === "python" || verb === "python3") {
|
|
105259
|
+
return words.slice(i2 + 1).every((w) => w === "--version" || w === "-V" || w === "-v");
|
|
105260
|
+
}
|
|
105261
|
+
if (!toolFlagsOk(verb, words.slice(i2 + 1)))
|
|
105262
|
+
return false;
|
|
105263
|
+
return true;
|
|
105264
|
+
}
|
|
105265
|
+
var HARMLESS_REDIRECT = /\s*\d?>\s*&\d\b|\s*\d?>>?\s*\/dev\/null(?=\s|$)/g;
|
|
105266
|
+
function isReadOnlyPipeline(command) {
|
|
105267
|
+
const cmd = command.replace(HARMLESS_REDIRECT, " ").trim();
|
|
105268
|
+
if (!cmd)
|
|
105269
|
+
return false;
|
|
105270
|
+
if (/[>`]|\$\(|<\(/.test(cmd))
|
|
105271
|
+
return false;
|
|
105272
|
+
const segs = cmd.split(/\|\||&&|[;|\n\r]/).map((x2) => x2.trim()).filter(Boolean);
|
|
105273
|
+
if (!segs.length)
|
|
105274
|
+
return false;
|
|
105275
|
+
return segs.every((seg) => !seg.includes("&") && isReadOnlyCommand(seg));
|
|
105020
105276
|
}
|
|
105277
|
+
function checkPlanMode(tool, input) {
|
|
105278
|
+
if (tool === "bash") {
|
|
105279
|
+
const command = typeof input.command === "string" ? input.command : "";
|
|
105280
|
+
if (input.run_in_background === true) {
|
|
105281
|
+
return {
|
|
105282
|
+
reason: "bash-not-read-only",
|
|
105283
|
+
message: "Plan mode is ON: background processes cannot be started. Finish researching and propose your plan; the user will leave plan mode if they want it carried out."
|
|
105284
|
+
};
|
|
105285
|
+
}
|
|
105286
|
+
if (isReadOnlyCommand(command))
|
|
105287
|
+
return null;
|
|
105288
|
+
return {
|
|
105289
|
+
reason: "bash-not-read-only",
|
|
105290
|
+
message: `Plan mode is ON, so \`bash\` is limited to provably read-only commands and this one was not recognised as such (chained commands, redirection and command substitution are always refused). Do NOT ask the user to approve it and do NOT try a variation to get around this \u2014 it is a session-wide lock, not a per-call prompt. Use read-only inspection instead, and put the command in your plan as a step to run once plan mode is off.`
|
|
105291
|
+
};
|
|
105292
|
+
}
|
|
105293
|
+
if (READ_ONLY_TOOLS.has(tool))
|
|
105294
|
+
return null;
|
|
105295
|
+
return {
|
|
105296
|
+
reason: "mutating-tool",
|
|
105297
|
+
message: `Plan mode is ON, so \`${tool}\` is unavailable \u2014 this session may not modify anything yet. Do NOT ask for approval: no answer the user gives at this prompt can unlock it, because it is a session-wide lock they control directly. Research with read-only tools and finish by proposing a concrete plan (files to change, in order, and how to verify). The user will exit plan mode to let you carry it out.`
|
|
105298
|
+
};
|
|
105299
|
+
}
|
|
105300
|
+
exports2.PLAN_MODE_INSTRUCTIONS = [
|
|
105301
|
+
"# PLAN MODE IS ACTIVE",
|
|
105302
|
+
"",
|
|
105303
|
+
"This session is READ-ONLY. You cannot edit files, write files, run mutating commands, or start",
|
|
105304
|
+
"background processes. This is enforced outside your control \u2014 it is not a permission prompt, and",
|
|
105305
|
+
"the user cannot approve an exception from inside this turn.",
|
|
105306
|
+
"",
|
|
105307
|
+
"Therefore:",
|
|
105308
|
+
'- NEVER ask "shall I go ahead and make this change?" \u2014 you cannot, whatever the answer.',
|
|
105309
|
+
'- NEVER attempt a mutating tool "just to see" \u2014 it will be refused and wastes the turn.',
|
|
105310
|
+
"- NEVER try to reach a blocked command another way (a different flag, a script, an interpreter).",
|
|
105311
|
+
"",
|
|
105312
|
+
"Your job is to research thoroughly, then deliver a plan:",
|
|
105313
|
+
"1. What you found \u2014 the specific files, functions and line numbers that matter.",
|
|
105314
|
+
"2. What you propose to change \u2014 file by file, in dependency order.",
|
|
105315
|
+
"3. Risks and unknowns \u2014 what could break, what you could not verify, what you assumed.",
|
|
105316
|
+
"4. How it will be verified \u2014 the exact build/test/lint command that proves it works.",
|
|
105317
|
+
"",
|
|
105318
|
+
'Be concrete. "Update the auth logic" is not a plan; "add a `refreshToken` field to AuthConfig in',
|
|
105319
|
+
'auth/index.ts:42, then thread it through client.ts:118" is. The user will review the plan and',
|
|
105320
|
+
"leave plan mode to have it carried out."
|
|
105321
|
+
].join("\n");
|
|
105021
105322
|
}
|
|
105022
105323
|
});
|
|
105023
105324
|
|
|
@@ -105027,11 +105328,11 @@ var require_modePolicy = __commonJS({
|
|
|
105027
105328
|
"use strict";
|
|
105028
105329
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
105029
105330
|
exports2.BASH_TOOLS = exports2.FILE_MUTATE_TOOLS = exports2.FILE_WRITE_TOOLS = exports2.READ_ONLY_TOOLS = void 0;
|
|
105030
|
-
exports2.isReadOnlyBash =
|
|
105331
|
+
exports2.isReadOnlyBash = isReadOnlyBash2;
|
|
105031
105332
|
exports2.decide = decide;
|
|
105032
105333
|
exports2.describeMode = describeMode2;
|
|
105033
105334
|
exports2.parseMode = parseMode2;
|
|
105034
|
-
var
|
|
105335
|
+
var planMode_1 = require_planMode();
|
|
105035
105336
|
exports2.READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
105036
105337
|
"read_file",
|
|
105037
105338
|
"list_directory",
|
|
@@ -105071,15 +105372,15 @@ var require_modePolicy = __commonJS({
|
|
|
105071
105372
|
"copy_file"
|
|
105072
105373
|
]);
|
|
105073
105374
|
exports2.BASH_TOOLS = /* @__PURE__ */ new Set(["bash", "run_command", "execute_command"]);
|
|
105074
|
-
function
|
|
105075
|
-
return
|
|
105375
|
+
function isReadOnlyBash2(command) {
|
|
105376
|
+
return (0, planMode_1.isReadOnlyPipeline)(command);
|
|
105076
105377
|
}
|
|
105077
105378
|
function decide(req) {
|
|
105078
105379
|
const { tool, mode } = req;
|
|
105079
105380
|
const command = String(req.input.command ?? req.input.cmd ?? "");
|
|
105080
105381
|
if (exports2.READ_ONLY_TOOLS.has(tool))
|
|
105081
105382
|
return "allow";
|
|
105082
|
-
if (exports2.BASH_TOOLS.has(tool) &&
|
|
105383
|
+
if (exports2.BASH_TOOLS.has(tool) && isReadOnlyBash2(command) && !req.destructive)
|
|
105083
105384
|
return "allow";
|
|
105084
105385
|
if (req.destructive)
|
|
105085
105386
|
return "confirm";
|
|
@@ -105310,261 +105611,60 @@ var require_destructive = __commonJS({
|
|
|
105310
105611
|
}
|
|
105311
105612
|
});
|
|
105312
105613
|
|
|
105313
|
-
// ../core/dist/
|
|
105314
|
-
var
|
|
105315
|
-
"../core/dist/
|
|
105614
|
+
// ../core/dist/permissions/bashClassify.js
|
|
105615
|
+
var require_bashClassify = __commonJS({
|
|
105616
|
+
"../core/dist/permissions/bashClassify.js"(exports2) {
|
|
105316
105617
|
"use strict";
|
|
105317
105618
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
105318
|
-
exports2.
|
|
105319
|
-
|
|
105320
|
-
|
|
105321
|
-
|
|
105322
|
-
"
|
|
105323
|
-
"
|
|
105324
|
-
"
|
|
105325
|
-
"
|
|
105326
|
-
"
|
|
105327
|
-
|
|
105328
|
-
|
|
105329
|
-
|
|
105330
|
-
"
|
|
105331
|
-
"
|
|
105332
|
-
|
|
105333
|
-
|
|
105334
|
-
|
|
105335
|
-
"
|
|
105336
|
-
"
|
|
105337
|
-
"
|
|
105338
|
-
"
|
|
105339
|
-
|
|
105340
|
-
|
|
105341
|
-
|
|
105342
|
-
|
|
105343
|
-
|
|
105344
|
-
|
|
105345
|
-
// searching without flooding the main context. Blocking `task` would have made
|
|
105346
|
-
// the mode's headline use case worse, for no security gain.
|
|
105347
|
-
"task",
|
|
105348
|
-
// VS Code language server — all pure queries.
|
|
105349
|
-
"get_symbols",
|
|
105350
|
-
"get_workspace_symbols",
|
|
105351
|
-
"find_references",
|
|
105352
|
-
"go_to_definition",
|
|
105353
|
-
"get_hover",
|
|
105354
|
-
"get_diagnostics",
|
|
105355
|
-
// Reading output from an ALREADY-running background shell. Starting one is
|
|
105356
|
-
// gated with the rest of bash below; draining a buffer is not a new effect.
|
|
105357
|
-
"bash_output"
|
|
105358
|
-
]);
|
|
105359
|
-
var READ_ONLY_BASH = /* @__PURE__ */ new Set([
|
|
105360
|
-
"ls",
|
|
105361
|
-
"cat",
|
|
105362
|
-
"head",
|
|
105363
|
-
"tail",
|
|
105364
|
-
"wc",
|
|
105365
|
-
"file",
|
|
105366
|
-
"stat",
|
|
105367
|
-
"du",
|
|
105368
|
-
"df",
|
|
105369
|
-
"pwd",
|
|
105370
|
-
"which",
|
|
105371
|
-
"type",
|
|
105372
|
-
"echo",
|
|
105373
|
-
"printf",
|
|
105374
|
-
"basename",
|
|
105375
|
-
"dirname",
|
|
105376
|
-
"realpath",
|
|
105377
|
-
"readlink",
|
|
105378
|
-
"grep",
|
|
105379
|
-
"egrep",
|
|
105380
|
-
"fgrep",
|
|
105381
|
-
"rg",
|
|
105382
|
-
"ag",
|
|
105383
|
-
"ack",
|
|
105384
|
-
"find",
|
|
105385
|
-
"fd",
|
|
105386
|
-
"locate",
|
|
105387
|
-
"diff",
|
|
105388
|
-
"comm",
|
|
105389
|
-
"cmp",
|
|
105390
|
-
"sort",
|
|
105391
|
-
"uniq",
|
|
105392
|
-
"cut",
|
|
105393
|
-
"tr",
|
|
105394
|
-
"column",
|
|
105395
|
-
"jq",
|
|
105396
|
-
"yq",
|
|
105397
|
-
"date",
|
|
105398
|
-
"whoami",
|
|
105399
|
-
"hostname",
|
|
105400
|
-
"uname",
|
|
105401
|
-
"env",
|
|
105402
|
-
"printenv",
|
|
105403
|
-
"id",
|
|
105404
|
-
"groups",
|
|
105405
|
-
"ps",
|
|
105406
|
-
"top",
|
|
105407
|
-
"uptime",
|
|
105408
|
-
"free",
|
|
105409
|
-
"node",
|
|
105410
|
-
"python",
|
|
105411
|
-
"python3",
|
|
105412
|
-
"tree",
|
|
105413
|
-
"less",
|
|
105414
|
-
"more",
|
|
105415
|
-
"nl",
|
|
105416
|
-
"tac",
|
|
105417
|
-
"strings",
|
|
105418
|
-
"md5sum",
|
|
105419
|
-
"sha256sum",
|
|
105420
|
-
"true",
|
|
105421
|
-
"false",
|
|
105422
|
-
"test",
|
|
105423
|
-
"sleep",
|
|
105424
|
-
"seq",
|
|
105425
|
-
"expr"
|
|
105619
|
+
exports2.bashNeedsRepoLock = bashNeedsRepoLock;
|
|
105620
|
+
var MUTATING_BASH_VERBS = /* @__PURE__ */ new Set([
|
|
105621
|
+
"git",
|
|
105622
|
+
"npm",
|
|
105623
|
+
"pnpm",
|
|
105624
|
+
"yarn",
|
|
105625
|
+
"bun",
|
|
105626
|
+
"cargo",
|
|
105627
|
+
"go",
|
|
105628
|
+
"pip",
|
|
105629
|
+
"pip3",
|
|
105630
|
+
"poetry",
|
|
105631
|
+
"uv",
|
|
105632
|
+
"bundle",
|
|
105633
|
+
"composer",
|
|
105634
|
+
"gradle",
|
|
105635
|
+
"mvn",
|
|
105636
|
+
"make",
|
|
105637
|
+
"terraform",
|
|
105638
|
+
"helm",
|
|
105639
|
+
"docker",
|
|
105640
|
+
"vsce",
|
|
105641
|
+
"tsc",
|
|
105642
|
+
"pytest",
|
|
105643
|
+
"dotnet",
|
|
105644
|
+
"swift",
|
|
105645
|
+
"gem"
|
|
105426
105646
|
]);
|
|
105427
|
-
|
|
105428
|
-
|
|
105429
|
-
"log",
|
|
105430
|
-
"show",
|
|
105431
|
-
"diff",
|
|
105432
|
-
"status",
|
|
105433
|
-
"blame",
|
|
105434
|
-
"branch",
|
|
105435
|
-
"tag",
|
|
105436
|
-
"remote",
|
|
105437
|
-
"describe",
|
|
105438
|
-
"rev-parse",
|
|
105439
|
-
"rev-list",
|
|
105440
|
-
"ls-files",
|
|
105441
|
-
"ls-tree",
|
|
105442
|
-
"ls-remote",
|
|
105443
|
-
"cat-file",
|
|
105444
|
-
"shortlog",
|
|
105445
|
-
"reflog",
|
|
105446
|
-
"whatchanged",
|
|
105447
|
-
"grep",
|
|
105448
|
-
"config",
|
|
105449
|
-
"check-ignore",
|
|
105450
|
-
"merge-base",
|
|
105451
|
-
"name-rev",
|
|
105452
|
-
"count-objects",
|
|
105453
|
-
"verify-commit"
|
|
105454
|
-
]),
|
|
105455
|
-
// Package managers: only their query verbs.
|
|
105456
|
-
npm: /* @__PURE__ */ new Set(["ls", "list", "view", "info", "outdated", "why", "config", "ping", "search"]),
|
|
105457
|
-
pnpm: /* @__PURE__ */ new Set(["ls", "list", "view", "info", "outdated", "why", "config"]),
|
|
105458
|
-
yarn: /* @__PURE__ */ new Set(["list", "info", "why", "config"]),
|
|
105459
|
-
cargo: /* @__PURE__ */ new Set(["tree", "metadata", "search"]),
|
|
105460
|
-
go: /* @__PURE__ */ new Set(["list", "version", "env", "vet", "doc"]),
|
|
105461
|
-
docker: /* @__PURE__ */ new Set(["ps", "images", "logs", "inspect", "version", "info", "top", "port", "diff", "stats"]),
|
|
105462
|
-
kubectl: /* @__PURE__ */ new Set(["get", "describe", "logs", "explain", "top", "version", "api-resources", "api-versions"]),
|
|
105463
|
-
// gh: read verbs only. `gh run rerun`, `gh pr merge` etc. are excluded, and
|
|
105464
|
-
// the nested-verb check in isReadOnlyCommand handles `gh pr view` vs `gh pr merge`.
|
|
105465
|
-
gh: /* @__PURE__ */ new Set(["browse"])
|
|
105466
|
-
};
|
|
105467
|
-
var READ_ONLY_NESTED = {
|
|
105468
|
-
gh: /* @__PURE__ */ new Set(["view", "list", "status", "diff", "checks"])
|
|
105469
|
-
};
|
|
105470
|
-
var SHELL_CONTROL = /[\n\r;&|`]|\$\(|>>|>|<\(/;
|
|
105471
|
-
function firstWords(command) {
|
|
105472
|
-
return command.trim().split(/\s+/).filter(Boolean);
|
|
105473
|
-
}
|
|
105474
|
-
function isReadOnlyCommand(command) {
|
|
105475
|
-
const cmd = command.trim();
|
|
105476
|
-
if (!cmd)
|
|
105477
|
-
return false;
|
|
105478
|
-
if (SHELL_CONTROL.test(cmd))
|
|
105479
|
-
return false;
|
|
105480
|
-
const words = firstWords(cmd);
|
|
105481
|
-
if (!words.length)
|
|
105482
|
-
return false;
|
|
105483
|
-
let i2 = 0;
|
|
105484
|
-
while (i2 < words.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[i2]))
|
|
105485
|
-
i2++;
|
|
105486
|
-
if (i2 >= words.length)
|
|
105487
|
-
return false;
|
|
105488
|
-
let verb = words[i2];
|
|
105489
|
-
const slash = verb.lastIndexOf("/");
|
|
105490
|
-
if (slash >= 0)
|
|
105491
|
-
verb = verb.slice(slash + 1);
|
|
105492
|
-
if (verb === "sudo" || verb === "doas" || verb === "su")
|
|
105493
|
-
return false;
|
|
105494
|
-
const rest = words.slice(i2 + 1).filter((w) => !w.startsWith("-"));
|
|
105495
|
-
const subs = READ_ONLY_SUBCOMMANDS[verb];
|
|
105496
|
-
if (subs) {
|
|
105497
|
-
const sub = rest[0];
|
|
105498
|
-
if (!sub) {
|
|
105499
|
-
return true;
|
|
105500
|
-
}
|
|
105501
|
-
if (subs.has(sub)) {
|
|
105502
|
-
if (verb === "git" && sub === "config") {
|
|
105503
|
-
const args = words.slice(i2 + 2).filter((w) => !w.startsWith("-"));
|
|
105504
|
-
return args.length <= 1;
|
|
105505
|
-
}
|
|
105506
|
-
return true;
|
|
105507
|
-
}
|
|
105508
|
-
const nested = READ_ONLY_NESTED[verb];
|
|
105509
|
-
if (nested && rest[1] && nested.has(rest[1]))
|
|
105510
|
-
return true;
|
|
105511
|
-
return false;
|
|
105512
|
-
}
|
|
105513
|
-
if (!READ_ONLY_TOOLS.has(verb) && !READ_ONLY_BASH.has(verb))
|
|
105514
|
-
return false;
|
|
105515
|
-
if (verb === "node" || verb === "python" || verb === "python3") {
|
|
105516
|
-
return words.slice(i2 + 1).every((w) => w === "--version" || w === "-V" || w === "-v");
|
|
105517
|
-
}
|
|
105518
|
-
if (verb === "find" && words.some((w) => w === "-exec" || w === "-execdir" || w === "-delete")) {
|
|
105647
|
+
function bashNeedsRepoLock(command) {
|
|
105648
|
+
if (!command)
|
|
105519
105649
|
return false;
|
|
105520
|
-
|
|
105521
|
-
|
|
105522
|
-
|
|
105523
|
-
|
|
105524
|
-
|
|
105525
|
-
|
|
105526
|
-
|
|
105527
|
-
|
|
105528
|
-
|
|
105529
|
-
|
|
105530
|
-
|
|
105650
|
+
const segments = command.split(/\|\||&&|[;|&\n()]|\$\(/);
|
|
105651
|
+
for (const seg of segments) {
|
|
105652
|
+
for (const tokenRaw of seg.trim().split(/\s+/)) {
|
|
105653
|
+
const token = tokenRaw.replace(/^["']|["']$/g, "");
|
|
105654
|
+
if (!token)
|
|
105655
|
+
continue;
|
|
105656
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))
|
|
105657
|
+
continue;
|
|
105658
|
+
if (token === "sudo" || token === "time" || token === "nice" || token === "env")
|
|
105659
|
+
continue;
|
|
105660
|
+
const verb = token.split("/").pop() ?? token;
|
|
105661
|
+
if (MUTATING_BASH_VERBS.has(verb))
|
|
105662
|
+
return true;
|
|
105663
|
+
break;
|
|
105531
105664
|
}
|
|
105532
|
-
if (isReadOnlyCommand(command))
|
|
105533
|
-
return null;
|
|
105534
|
-
return {
|
|
105535
|
-
reason: "bash-not-read-only",
|
|
105536
|
-
message: `Plan mode is ON, so \`bash\` is limited to provably read-only commands and this one was not recognised as such (chained commands, redirection and command substitution are always refused). Do NOT ask the user to approve it and do NOT try a variation to get around this \u2014 it is a session-wide lock, not a per-call prompt. Use read-only inspection instead, and put the command in your plan as a step to run once plan mode is off.`
|
|
105537
|
-
};
|
|
105538
105665
|
}
|
|
105539
|
-
|
|
105540
|
-
return null;
|
|
105541
|
-
return {
|
|
105542
|
-
reason: "mutating-tool",
|
|
105543
|
-
message: `Plan mode is ON, so \`${tool}\` is unavailable \u2014 this session may not modify anything yet. Do NOT ask for approval: no answer the user gives at this prompt can unlock it, because it is a session-wide lock they control directly. Research with read-only tools and finish by proposing a concrete plan (files to change, in order, and how to verify). The user will exit plan mode to let you carry it out.`
|
|
105544
|
-
};
|
|
105666
|
+
return false;
|
|
105545
105667
|
}
|
|
105546
|
-
exports2.PLAN_MODE_INSTRUCTIONS = [
|
|
105547
|
-
"# PLAN MODE IS ACTIVE",
|
|
105548
|
-
"",
|
|
105549
|
-
"This session is READ-ONLY. You cannot edit files, write files, run mutating commands, or start",
|
|
105550
|
-
"background processes. This is enforced outside your control \u2014 it is not a permission prompt, and",
|
|
105551
|
-
"the user cannot approve an exception from inside this turn.",
|
|
105552
|
-
"",
|
|
105553
|
-
"Therefore:",
|
|
105554
|
-
'- NEVER ask "shall I go ahead and make this change?" \u2014 you cannot, whatever the answer.',
|
|
105555
|
-
'- NEVER attempt a mutating tool "just to see" \u2014 it will be refused and wastes the turn.',
|
|
105556
|
-
"- NEVER try to reach a blocked command another way (a different flag, a script, an interpreter).",
|
|
105557
|
-
"",
|
|
105558
|
-
"Your job is to research thoroughly, then deliver a plan:",
|
|
105559
|
-
"1. What you found \u2014 the specific files, functions and line numbers that matter.",
|
|
105560
|
-
"2. What you propose to change \u2014 file by file, in dependency order.",
|
|
105561
|
-
"3. Risks and unknowns \u2014 what could break, what you could not verify, what you assumed.",
|
|
105562
|
-
"4. How it will be verified \u2014 the exact build/test/lint command that proves it works.",
|
|
105563
|
-
"",
|
|
105564
|
-
'Be concrete. "Update the auth logic" is not a plan; "add a `refreshToken` field to AuthConfig in',
|
|
105565
|
-
'auth/index.ts:42, then thread it through client.ts:118" is. The user will review the plan and',
|
|
105566
|
-
"leave plan mode to have it carried out."
|
|
105567
|
-
].join("\n");
|
|
105568
105668
|
}
|
|
105569
105669
|
});
|
|
105570
105670
|
|
|
@@ -145175,7 +145275,7 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
145175
145275
|
var source_default = chalk;
|
|
145176
145276
|
|
|
145177
145277
|
// src/index.ts
|
|
145178
|
-
var
|
|
145278
|
+
var import_code_core10 = __toESM(require_dist3(), 1);
|
|
145179
145279
|
|
|
145180
145280
|
// src/commands/auth.ts
|
|
145181
145281
|
import * as readline from "readline";
|
|
@@ -145392,7 +145492,7 @@ import * as crypto4 from "crypto";
|
|
|
145392
145492
|
import { createRequire } from "module";
|
|
145393
145493
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
145394
145494
|
import { execSync, execFileSync as execFileSync3 } from "child_process";
|
|
145395
|
-
var
|
|
145495
|
+
var import_code_core7 = __toESM(require_dist3(), 1);
|
|
145396
145496
|
|
|
145397
145497
|
// ../../node_modules/.pnpm/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
|
|
145398
145498
|
function ansiRegex({ onlyFirst = false } = {}) {
|
|
@@ -146350,17 +146450,9 @@ function showDiff(filePath, oldContent, newContent) {
|
|
|
146350
146450
|
}
|
|
146351
146451
|
|
|
146352
146452
|
// src/permissions/risk.ts
|
|
146453
|
+
var import_code_core3 = __toESM(require_dist3(), 1);
|
|
146353
146454
|
import * as path from "path";
|
|
146354
146455
|
var HIGH_BASH = /\b(sudo|rm|rmdir|chmod|chown|dd|mkfs|kill|killall|pkill|shutdown|reboot)\b|\b(curl|wget)\b[^|]*\|\s*(sudo\s+)?(ba|z)?sh\b|\b(ssh|scp|rsync)\b|\bgit\s+(push|reset\s+--hard|clean)\b/;
|
|
146355
|
-
var READ_VERBS = /* @__PURE__ */ new Set(["ls", "cat", "head", "tail", "wc", "pwd", "echo", "which", "grep", "rg", "find", "stat", "file", "du", "df", "tree", "diff", "sort", "uniq", "date", "whoami"]);
|
|
146356
|
-
function looksReadOnly(cmd) {
|
|
146357
|
-
if (/[>`]|\$\(|\bfind\b[^|;&]*\s-(delete|exec|execdir)\b/.test(cmd))
|
|
146358
|
-
return false;
|
|
146359
|
-
return cmd.split(/\|\||&&|[;|&\n]/).every((seg) => {
|
|
146360
|
-
const verb = seg.trim().split(/\s+/)[0] ?? "";
|
|
146361
|
-
return verb === "" || READ_VERBS.has(verb.split("/").pop());
|
|
146362
|
-
});
|
|
146363
|
-
}
|
|
146364
146456
|
function outsideProject(p, workDir) {
|
|
146365
146457
|
if (!p)
|
|
146366
146458
|
return false;
|
|
@@ -146376,7 +146468,7 @@ function assessRisk(tool, input, workDir, fileExists) {
|
|
|
146376
146468
|
const cmd = String(input.command ?? input.cmd ?? "");
|
|
146377
146469
|
if (HIGH_BASH.test(cmd))
|
|
146378
146470
|
return { risk: "high", detail: `can delete, overwrite or reach the network${out}` };
|
|
146379
|
-
if (
|
|
146471
|
+
if ((0, import_code_core3.isReadOnlyBash)(cmd))
|
|
146380
146472
|
return { risk: "low", detail: "read-only command" };
|
|
146381
146473
|
return { risk: "medium", detail: "runs code that may change files" };
|
|
146382
146474
|
}
|
|
@@ -146396,18 +146488,18 @@ function assessRisk(tool, input, workDir, fileExists) {
|
|
|
146396
146488
|
}
|
|
146397
146489
|
|
|
146398
146490
|
// src/permissions/handler.ts
|
|
146399
|
-
var
|
|
146491
|
+
var import_code_core4 = __toESM(require_dist3(), 1);
|
|
146400
146492
|
var autoApproved = /* @__PURE__ */ new Set();
|
|
146401
146493
|
var _rules = { allow: [], ask: [], deny: [] };
|
|
146402
146494
|
var _workDir = process.cwd();
|
|
146403
146495
|
var _mode = "ask";
|
|
146404
146496
|
function initPermissions(workDir) {
|
|
146405
146497
|
_workDir = workDir;
|
|
146406
|
-
_rules = (0,
|
|
146498
|
+
_rules = (0, import_code_core4.loadSettings)(workDir).permissions;
|
|
146407
146499
|
return _rules;
|
|
146408
146500
|
}
|
|
146409
146501
|
function setMode(mode) {
|
|
146410
|
-
_mode = (0,
|
|
146502
|
+
_mode = (0, import_code_core4.parseMode)(mode);
|
|
146411
146503
|
}
|
|
146412
146504
|
function setAutoApprove(category) {
|
|
146413
146505
|
autoApproved.add(category);
|
|
@@ -146485,12 +146577,12 @@ function announceAgent(req) {
|
|
|
146485
146577
|
}
|
|
146486
146578
|
async function requestPermission(req) {
|
|
146487
146579
|
const { tool, input } = req;
|
|
146488
|
-
const decision = (0,
|
|
146580
|
+
const decision = (0, import_code_core4.evaluatePermission)(_rules, tool, input, _workDir);
|
|
146489
146581
|
if (decision === "deny") {
|
|
146490
146582
|
console.error(source_default.red(` \u2716 Denied by permission rule: ${tool}`));
|
|
146491
146583
|
return false;
|
|
146492
146584
|
}
|
|
146493
|
-
const destructive = (0,
|
|
146585
|
+
const destructive = (0, import_code_core4.isDestructiveBash)(tool, input);
|
|
146494
146586
|
if (destructive && process.env.NEXRALL_ALLOW_DESTRUCTIVE !== "1") {
|
|
146495
146587
|
return serialisePrompt(async () => {
|
|
146496
146588
|
announceAgent(req);
|
|
@@ -146511,7 +146603,7 @@ async function requestPermission(req) {
|
|
|
146511
146603
|
}
|
|
146512
146604
|
if (decision === "allow")
|
|
146513
146605
|
return true;
|
|
146514
|
-
const verdict = (0,
|
|
146606
|
+
const verdict = (0, import_code_core4.decide)({
|
|
146515
146607
|
tool,
|
|
146516
146608
|
input,
|
|
146517
146609
|
mode: _mode,
|
|
@@ -146671,7 +146763,7 @@ async function askFlow(req) {
|
|
|
146671
146763
|
}
|
|
146672
146764
|
|
|
146673
146765
|
// src/audit.ts
|
|
146674
|
-
var
|
|
146766
|
+
var import_code_core5 = __toESM(require_dist3(), 1);
|
|
146675
146767
|
import * as path2 from "path";
|
|
146676
146768
|
var _state;
|
|
146677
146769
|
var _sinks = /* @__PURE__ */ new Map();
|
|
@@ -146691,7 +146783,7 @@ function currentAudit() {
|
|
|
146691
146783
|
const target = resolveAuditPath(_state);
|
|
146692
146784
|
let sink = _sinks.get(target);
|
|
146693
146785
|
if (!sink) {
|
|
146694
|
-
sink = (0,
|
|
146786
|
+
sink = (0, import_code_core5.createJsonlAuditSink)(target);
|
|
146695
146787
|
_sinks.set(target, sink);
|
|
146696
146788
|
}
|
|
146697
146789
|
const cfg = {
|
|
@@ -146704,14 +146796,14 @@ function currentAudit() {
|
|
|
146704
146796
|
// request that caused it. Same trap as @nexrall/agent's and Desktop's.
|
|
146705
146797
|
sessionId: _state.getSessionId()
|
|
146706
146798
|
};
|
|
146707
|
-
const email = (0,
|
|
146799
|
+
const email = (0, import_code_core5.loadAuth)()?.email;
|
|
146708
146800
|
if (email)
|
|
146709
146801
|
cfg.userId = email;
|
|
146710
146802
|
return cfg;
|
|
146711
146803
|
}
|
|
146712
146804
|
|
|
146713
146805
|
// src/commands/chat.ts
|
|
146714
|
-
var
|
|
146806
|
+
var import_code_core8 = __toESM(require_dist3(), 1);
|
|
146715
146807
|
|
|
146716
146808
|
// src/commands/sessions.ts
|
|
146717
146809
|
import * as fs3 from "fs";
|
|
@@ -147145,7 +147237,7 @@ async function updateCommand(opts) {
|
|
|
147145
147237
|
}
|
|
147146
147238
|
|
|
147147
147239
|
// src/commands/sessionTools.ts
|
|
147148
|
-
var
|
|
147240
|
+
var import_code_core6 = __toESM(require_dist3(), 1);
|
|
147149
147241
|
import { spawnSync, execFileSync } from "child_process";
|
|
147150
147242
|
import fs5 from "fs";
|
|
147151
147243
|
import path6 from "path";
|
|
@@ -147205,7 +147297,7 @@ function nextMode(current) {
|
|
|
147205
147297
|
return MODE_CYCLE[(i2 + 1) % MODE_CYCLE.length];
|
|
147206
147298
|
}
|
|
147207
147299
|
function textOf(m2) {
|
|
147208
|
-
return m2.content.filter((b) => b.type === "text" && !(0,
|
|
147300
|
+
return m2.content.filter((b) => b.type === "text" && !(0, import_code_core6.isRuntimeContextBlock)(b)).map((b) => b.text).join("\n").trim();
|
|
147209
147301
|
}
|
|
147210
147302
|
function lastAssistantText(messages) {
|
|
147211
147303
|
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
@@ -147231,7 +147323,7 @@ function exportMarkdown(messages, meta) {
|
|
|
147231
147323
|
for (const m2 of messages) {
|
|
147232
147324
|
const parts = [];
|
|
147233
147325
|
for (const b of m2.content) {
|
|
147234
|
-
if ((0,
|
|
147326
|
+
if ((0, import_code_core6.isRuntimeContextBlock)(b))
|
|
147235
147327
|
continue;
|
|
147236
147328
|
if (b.type === "text") {
|
|
147237
147329
|
if (b.text.trim())
|
|
@@ -158021,7 +158113,7 @@ var MODEL_COST_MULTIPLIER = {
|
|
|
158021
158113
|
"glm-5.3": 0.6
|
|
158022
158114
|
};
|
|
158023
158115
|
function modelWithCostHint(id) {
|
|
158024
|
-
const mult = (0,
|
|
158116
|
+
const mult = (0, import_code_core7.liveCostMultiplierFor)(id, MODEL_COST_MULTIPLIER[id]);
|
|
158025
158117
|
return mult === void 0 ? id : `${id} (${mult}x)`;
|
|
158026
158118
|
}
|
|
158027
158119
|
var NO_VISION_MODELS = /* @__PURE__ */ new Set(["qwen3.7-max", "glm-5.3"]);
|
|
@@ -158037,13 +158129,13 @@ var NO_PDF_MODELS = /* @__PURE__ */ new Set([
|
|
|
158037
158129
|
...NO_VISION_MODELS
|
|
158038
158130
|
]);
|
|
158039
158131
|
function needsVisionSidecar(model) {
|
|
158040
|
-
return !(0,
|
|
158132
|
+
return !(0, import_code_core7.liveSupportsImageInput)(model, !NO_VISION_MODELS.has(model));
|
|
158041
158133
|
}
|
|
158042
158134
|
function needsPdfSidecar(model) {
|
|
158043
|
-
return !(0,
|
|
158135
|
+
return !(0, import_code_core7.liveSupportsPdfInput)(model, !NO_PDF_MODELS.has(model));
|
|
158044
158136
|
}
|
|
158045
158137
|
function selectableModelIds() {
|
|
158046
|
-
return (0,
|
|
158138
|
+
return (0, import_code_core7.liveSelectableModelIds)() ?? SELECTABLE_MODELS;
|
|
158047
158139
|
}
|
|
158048
158140
|
function normaliseModelId(model) {
|
|
158049
158141
|
const raw = (model ?? "").trim();
|
|
@@ -158104,9 +158196,9 @@ var _BACKEND_STYLE_TO_LOCAL = {
|
|
|
158104
158196
|
};
|
|
158105
158197
|
function effortStyleFor(modelId) {
|
|
158106
158198
|
const id = normaliseModelId(modelId);
|
|
158107
|
-
if ((0,
|
|
158199
|
+
if ((0, import_code_core7.liveVendorFor)(id) === "Anthropic")
|
|
158108
158200
|
return "anthropic";
|
|
158109
|
-
const liveStyle = (0,
|
|
158201
|
+
const liveStyle = (0, import_code_core7.liveReasoningEffortStyle)(id);
|
|
158110
158202
|
if (liveStyle && _BACKEND_STYLE_TO_LOCAL[liveStyle])
|
|
158111
158203
|
return _BACKEND_STYLE_TO_LOCAL[liveStyle];
|
|
158112
158204
|
return MODEL_EFFORT_STYLE[id] ?? "anthropic";
|
|
@@ -158126,7 +158218,7 @@ function defaultEffortForModel(modelId) {
|
|
|
158126
158218
|
}
|
|
158127
158219
|
function resolveModelLabel(alias) {
|
|
158128
158220
|
const id = normaliseModelId(alias);
|
|
158129
|
-
return (0,
|
|
158221
|
+
return (0, import_code_core7.liveLabelFor)(id, MODEL_LABELS[id] ?? id);
|
|
158130
158222
|
}
|
|
158131
158223
|
function tryExec(cmd, cwd2) {
|
|
158132
158224
|
try {
|
|
@@ -158200,7 +158292,7 @@ var tryRead = (p) => {
|
|
|
158200
158292
|
};
|
|
158201
158293
|
function readNexrallMd(workDir) {
|
|
158202
158294
|
const parts = [];
|
|
158203
|
-
const memContent = (0,
|
|
158295
|
+
const memContent = (0, import_code_core7.readAllMemory)(workDir);
|
|
158204
158296
|
if (memContent)
|
|
158205
158297
|
parts.push(memContent);
|
|
158206
158298
|
const globalContent = tryRead(path9.join(os6.homedir(), ".nexrall", "nexrall.md"));
|
|
@@ -158307,7 +158399,7 @@ var Spinner = class {
|
|
|
158307
158399
|
return this.interval !== null;
|
|
158308
158400
|
}
|
|
158309
158401
|
};
|
|
158310
|
-
var cliBackgroundAgents = new
|
|
158402
|
+
var cliBackgroundAgents = new import_code_core7.BackgroundAgentHub();
|
|
158311
158403
|
function nextBackgroundChange() {
|
|
158312
158404
|
return new Promise((resolve6) => {
|
|
158313
158405
|
const off = cliBackgroundAgents.onChange(() => {
|
|
@@ -158319,12 +158411,12 @@ function nextBackgroundChange() {
|
|
|
158319
158411
|
var _mcpManager = null;
|
|
158320
158412
|
var _mcpConfig = null;
|
|
158321
158413
|
async function initMcp(workDir) {
|
|
158322
|
-
_mcpConfig =
|
|
158414
|
+
_mcpConfig = import_code_core7.McpManager.loadConfig(workDir);
|
|
158323
158415
|
if (Object.keys(_mcpConfig.mcpServers).length === 0) {
|
|
158324
158416
|
_mcpManager = null;
|
|
158325
158417
|
return;
|
|
158326
158418
|
}
|
|
158327
|
-
const manager = new
|
|
158419
|
+
const manager = new import_code_core7.McpManager();
|
|
158328
158420
|
await manager.connectAll(_mcpConfig);
|
|
158329
158421
|
_mcpManager = manager;
|
|
158330
158422
|
}
|
|
@@ -158345,10 +158437,10 @@ function formatMcpStatus() {
|
|
|
158345
158437
|
return lines.join("\n");
|
|
158346
158438
|
}
|
|
158347
158439
|
function formatContextUsage(messages, modelAlias) {
|
|
158348
|
-
const window2 = (0,
|
|
158349
|
-
const tokens = (0,
|
|
158350
|
-
const bytes = (0,
|
|
158351
|
-
const { prune, compact } = (0,
|
|
158440
|
+
const window2 = (0, import_code_core7.contextWindowFor)(modelAlias);
|
|
158441
|
+
const tokens = (0, import_code_core7.estimateTokensRough)(messages);
|
|
158442
|
+
const bytes = (0, import_code_core7.estimateBodyBytes)(messages);
|
|
158443
|
+
const { prune, compact } = (0, import_code_core7.compactionThresholds)(window2);
|
|
158352
158444
|
const pct = Math.min(100, tokens / window2 * 100);
|
|
158353
158445
|
const barWidth = 30;
|
|
158354
158446
|
const filled = Math.round(pct / 100 * barWidth);
|
|
@@ -158365,7 +158457,7 @@ function formatContextUsage(messages, modelAlias) {
|
|
|
158365
158457
|
return lines.join("\n");
|
|
158366
158458
|
}
|
|
158367
158459
|
function formatAgentsList(workDir) {
|
|
158368
|
-
const { types: types3, warnings } = (0,
|
|
158460
|
+
const { types: types3, warnings } = (0, import_code_core7.loadAgentTypesWithWarnings)(workDir);
|
|
158369
158461
|
if (!types3.length)
|
|
158370
158462
|
return source_default.dim(" No agent types found (this should not happen \u2014 builtins always register).");
|
|
158371
158463
|
const lines = types3.map((t2) => {
|
|
@@ -158414,7 +158506,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
158414
158506
|
setMode(mode);
|
|
158415
158507
|
console.log();
|
|
158416
158508
|
spinner.start("thinking\u2026", { hint: false });
|
|
158417
|
-
const result = await (0,
|
|
158509
|
+
const result = await (0, import_code_core7.runAgentLoop)(messages, {
|
|
158418
158510
|
workDir,
|
|
158419
158511
|
model: modelAlias,
|
|
158420
158512
|
env: refreshEnvForTurn(env4, workDir),
|
|
@@ -158624,7 +158716,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
158624
158716
|
process.stdout.write(JSON.stringify(obj2) + "\n");
|
|
158625
158717
|
};
|
|
158626
158718
|
emit({ type: "start", model: modelAlias, workDir });
|
|
158627
|
-
const result = await (0,
|
|
158719
|
+
const result = await (0, import_code_core7.runAgentLoop)(messages, {
|
|
158628
158720
|
workDir,
|
|
158629
158721
|
model: modelAlias,
|
|
158630
158722
|
env: refreshEnvForTurn(env4, workDir),
|
|
@@ -158722,7 +158814,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env4
|
|
|
158722
158814
|
// no human to confirm, they are denied unless NEXRALL_ALLOW_DESTRUCTIVE=1 is
|
|
158723
158815
|
// explicitly set for this CI run.
|
|
158724
158816
|
requestPermission: async ({ tool, input }) => {
|
|
158725
|
-
const d = (0,
|
|
158817
|
+
const d = (0, import_code_core7.isDestructiveBash)(tool, input);
|
|
158726
158818
|
if (d && process.env.NEXRALL_ALLOW_DESTRUCTIVE !== "1") {
|
|
158727
158819
|
emit({ type: "error", error: `Destructive command blocked in headless mode (${d.category}): ${d.reason}. Set NEXRALL_ALLOW_DESTRUCTIVE=1 to permit.` });
|
|
158728
158820
|
return false;
|
|
@@ -158838,7 +158930,7 @@ function printSessions() {
|
|
|
158838
158930
|
console.log();
|
|
158839
158931
|
}
|
|
158840
158932
|
async function startChatSession(options) {
|
|
158841
|
-
(0,
|
|
158933
|
+
(0, import_code_core7.enableAgentTranscriptPersistence)();
|
|
158842
158934
|
const headless = options.outputFormat === "json" || options.outputFormat === "stream-json";
|
|
158843
158935
|
const requestedWorkDir = options.workDir;
|
|
158844
158936
|
let workDir = requestedWorkDir;
|
|
@@ -158847,7 +158939,7 @@ async function startChatSession(options) {
|
|
|
158847
158939
|
let peerInbox;
|
|
158848
158940
|
const peerInboxQueue = [];
|
|
158849
158941
|
let modelAlias = options.model;
|
|
158850
|
-
void (0,
|
|
158942
|
+
void (0, import_code_core7.getModelCatalogue)().catch(() => {
|
|
158851
158943
|
});
|
|
158852
158944
|
const canPrompt = !headless && !options.prompt && !options.stdinText && process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
158853
158945
|
if (!trustGrantedByEnv()) {
|
|
@@ -158875,9 +158967,9 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
158875
158967
|
}
|
|
158876
158968
|
if (options.worktree !== void 0) {
|
|
158877
158969
|
const requestedName = typeof options.worktree === "string" ? options.worktree : void 0;
|
|
158878
|
-
const existing = requestedName ? (0,
|
|
158970
|
+
const existing = requestedName ? (0, import_code_core7.findWorktreeByName)(requestedWorkDir, requestedName) : null;
|
|
158879
158971
|
if (existing) {
|
|
158880
|
-
const entered = (0,
|
|
158972
|
+
const entered = (0, import_code_core7.enterWorktree)(existing);
|
|
158881
158973
|
if (!entered.ok) {
|
|
158882
158974
|
process.stderr.write(`Failed to resume worktree "${requestedName}": ${entered.error}
|
|
158883
158975
|
`);
|
|
@@ -158887,7 +158979,7 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
158887
158979
|
if (!headless)
|
|
158888
158980
|
console.log(source_default.dim(` Resumed worktree: ${source_default.bold(existing.name)} (${existing.worktreePath})`));
|
|
158889
158981
|
} else {
|
|
158890
|
-
const created = (0,
|
|
158982
|
+
const created = (0, import_code_core7.createWorktree)(requestedWorkDir, requestedName);
|
|
158891
158983
|
if (!created.ok || !created.state) {
|
|
158892
158984
|
process.stderr.write(`Failed to create worktree: ${created.error ?? "unknown error"}
|
|
158893
158985
|
`);
|
|
@@ -158906,7 +158998,7 @@ Set ${TRUST_ENV_VAR}=1 to confirm non-interactively, or run \`nex\` interactivel
|
|
|
158906
158998
|
process.on("exit", () => {
|
|
158907
158999
|
if (!worktreeState)
|
|
158908
159000
|
return;
|
|
158909
|
-
const hadWork = (0,
|
|
159001
|
+
const hadWork = (0, import_code_core7.worktreeHasWork)(worktreeState);
|
|
158910
159002
|
if (hadWork) {
|
|
158911
159003
|
process.stderr.write(
|
|
158912
159004
|
`
|
|
@@ -158917,7 +159009,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
158917
159009
|
);
|
|
158918
159010
|
return;
|
|
158919
159011
|
}
|
|
158920
|
-
(0,
|
|
159012
|
+
(0, import_code_core7.removeWorktree)(worktreeState);
|
|
158921
159013
|
});
|
|
158922
159014
|
}
|
|
158923
159015
|
const env4 = collectEnv(workDir);
|
|
@@ -158925,8 +159017,8 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
158925
159017
|
const interactive = !headless && !options.prompt && !options.stdinText;
|
|
158926
159018
|
let peerHeartbeatTimer;
|
|
158927
159019
|
if (interactive) {
|
|
158928
|
-
const handle2 = (0,
|
|
158929
|
-
const inbox = (0,
|
|
159020
|
+
const handle2 = (0, import_code_core7.registerPeer)({ clientType: "cli", workDir: requestedWorkDir });
|
|
159021
|
+
const inbox = (0, import_code_core7.startPeerInbox)(handle2.record.id, { onMessage: (m2) => peerInboxQueue.push(m2) });
|
|
158930
159022
|
handle2.record.socketPath = inbox.socketPath;
|
|
158931
159023
|
handle2.heartbeat();
|
|
158932
159024
|
peerHandle = handle2;
|
|
@@ -158996,7 +159088,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
158996
159088
|
const ruleCount = permRules.allow.length + permRules.ask.length + permRules.deny.length;
|
|
158997
159089
|
if (ruleCount && !headless)
|
|
158998
159090
|
console.log(source_default.dim(` ${ruleCount} permission rule(s) loaded`));
|
|
158999
|
-
let skills = (0,
|
|
159091
|
+
let skills = (0, import_code_core7.loadSkills)(workDir);
|
|
159000
159092
|
if (skills.length && !headless)
|
|
159001
159093
|
console.log(source_default.dim(` ${skills.length} skill(s) loaded`));
|
|
159002
159094
|
const mcpStarted = (async () => {
|
|
@@ -159028,7 +159120,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
159028
159120
|
sessionId = stored.id;
|
|
159029
159121
|
sessionTitle = stored.title;
|
|
159030
159122
|
try {
|
|
159031
|
-
const compacted = await (0,
|
|
159123
|
+
const compacted = await (0, import_code_core7.compactMessagesForResume)(messages, {
|
|
159032
159124
|
workDir,
|
|
159033
159125
|
model: modelAlias,
|
|
159034
159126
|
clientType: "cli"
|
|
@@ -159042,7 +159134,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
159042
159134
|
console.log();
|
|
159043
159135
|
}
|
|
159044
159136
|
}
|
|
159045
|
-
const checkpoints = new
|
|
159137
|
+
const checkpoints = new import_code_core7.CheckpointManager(workDir, sessionId);
|
|
159046
159138
|
if (options.audit) {
|
|
159047
159139
|
const auditPath = enableAudit({
|
|
159048
159140
|
filePath: typeof options.audit === "string" ? options.audit : void 0,
|
|
@@ -159060,7 +159152,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
159060
159152
|
sessionTitle = raw.length > 60 ? raw.slice(0, 60) + "\u2026" : raw;
|
|
159061
159153
|
};
|
|
159062
159154
|
const recoverTurn = (err, current) => {
|
|
159063
|
-
const salvaged = (0,
|
|
159155
|
+
const salvaged = (0, import_code_core7.salvageHistory)(err);
|
|
159064
159156
|
console.error("\n" + source_default.red("Error: ") + String(err.message));
|
|
159065
159157
|
if (!salvaged)
|
|
159066
159158
|
return current;
|
|
@@ -159110,7 +159202,7 @@ ${text}` : "");
|
|
|
159110
159202
|
continue;
|
|
159111
159203
|
}
|
|
159112
159204
|
const notes = cliBackgroundAgents.takeNotifications();
|
|
159113
|
-
messages.push({ role: "user", content: [{ type: "text", text: (0,
|
|
159205
|
+
messages.push({ role: "user", content: [{ type: "text", text: (0, import_code_core7.formatBackgroundNotifications)(notes) }] });
|
|
159114
159206
|
result = await runOnce();
|
|
159115
159207
|
messages = result.messages;
|
|
159116
159208
|
}
|
|
@@ -159122,7 +159214,7 @@ ${text}` : "");
|
|
|
159122
159214
|
await new Promise((r2) => setImmediate(r2));
|
|
159123
159215
|
process.exit(0);
|
|
159124
159216
|
} catch (err) {
|
|
159125
|
-
const salvaged = (0,
|
|
159217
|
+
const salvaged = (0, import_code_core7.salvageHistory)(err);
|
|
159126
159218
|
if (salvaged) {
|
|
159127
159219
|
messages = salvaged;
|
|
159128
159220
|
try {
|
|
@@ -159153,11 +159245,11 @@ ${text}` : "");
|
|
|
159153
159245
|
console.log(source_default.dim(" Type a message, /help for commands, or Ctrl+C to exit."));
|
|
159154
159246
|
console.log();
|
|
159155
159247
|
const footerExtras = () => {
|
|
159156
|
-
const win = (0,
|
|
159248
|
+
const win = (0, import_code_core7.contextWindowFor)(modelAlias);
|
|
159157
159249
|
return {
|
|
159158
159250
|
model: resolveModelLabel(modelAlias),
|
|
159159
159251
|
branch: gitBranch(workDir) ?? void 0,
|
|
159160
|
-
ctxPct: messages.length ? Math.min(100, (0,
|
|
159252
|
+
ctxPct: messages.length ? Math.min(100, (0, import_code_core7.estimateTokensRough)(messages) / win * 100) : 0,
|
|
159161
159253
|
costUsd: sessionUsage.costReported ? sessionUsage.cost : void 0
|
|
159162
159254
|
};
|
|
159163
159255
|
};
|
|
@@ -159201,7 +159293,7 @@ ${text}` : "");
|
|
|
159201
159293
|
updateFooter();
|
|
159202
159294
|
const syncSlashMenu = () => {
|
|
159203
159295
|
if (interactive)
|
|
159204
|
-
getInkTerminal().setSlashEntries([...BUILTIN_SLASH_COMMANDS, ...skillEntries((0,
|
|
159296
|
+
getInkTerminal().setSlashEntries([...BUILTIN_SLASH_COMMANDS, ...skillEntries((0, import_code_core7.userInvokableSkills)(skills))]);
|
|
159205
159297
|
};
|
|
159206
159298
|
syncSlashMenu();
|
|
159207
159299
|
if (interactive) {
|
|
@@ -159251,7 +159343,7 @@ ${text}` : "");
|
|
|
159251
159343
|
messages = [];
|
|
159252
159344
|
sessionId = crypto4.randomBytes(8).toString("hex");
|
|
159253
159345
|
sessionTitle = "";
|
|
159254
|
-
(0,
|
|
159346
|
+
(0, import_code_core8.resetSessionSubAgentBudget)();
|
|
159255
159347
|
sessionUsage.reset();
|
|
159256
159348
|
cliBackgroundAgents.stopAll({ dropPending: true });
|
|
159257
159349
|
inputBuffer = "";
|
|
@@ -159291,7 +159383,7 @@ ${text}` : "");
|
|
|
159291
159383
|
sessionTitle = stored.title;
|
|
159292
159384
|
sessionUsage.reset();
|
|
159293
159385
|
try {
|
|
159294
|
-
await (0,
|
|
159386
|
+
await (0, import_code_core7.compactMessagesForResume)(messages, {
|
|
159295
159387
|
workDir,
|
|
159296
159388
|
model: modelAlias,
|
|
159297
159389
|
clientType: "cli"
|
|
@@ -159466,13 +159558,13 @@ ${dirList}`;
|
|
|
159466
159558
|
const sub = arg.trim().toLowerCase();
|
|
159467
159559
|
console.log();
|
|
159468
159560
|
if (sub === "list") {
|
|
159469
|
-
const all = (0,
|
|
159561
|
+
const all = (0, import_code_core7.listWorktrees)(requestedWorkDir);
|
|
159470
159562
|
if (!all.length) {
|
|
159471
159563
|
console.log(source_default.dim(" No worktrees under this project."));
|
|
159472
159564
|
} else {
|
|
159473
159565
|
console.log(source_default.bold(` Worktrees (${all.length})`));
|
|
159474
159566
|
for (const w of all) {
|
|
159475
|
-
const dirty = (0,
|
|
159567
|
+
const dirty = (0, import_code_core7.worktreeHasWork)(w) ? source_default.yellow("dirty") : source_default.dim("clean");
|
|
159476
159568
|
console.log(` ${source_default.cyan(w.name)} ${source_default.dim(w.worktreePath)} [${dirty}]`);
|
|
159477
159569
|
}
|
|
159478
159570
|
console.log();
|
|
@@ -159510,7 +159602,7 @@ ${dirList}`;
|
|
|
159510
159602
|
if (!targetName || !text) {
|
|
159511
159603
|
console.log(source_default.dim(" Usage: /peers send <name> <message>"));
|
|
159512
159604
|
} else {
|
|
159513
|
-
const target = (0,
|
|
159605
|
+
const target = (0, import_code_core7.listPeers)().find((p) => p.name === targetName);
|
|
159514
159606
|
if (!target) {
|
|
159515
159607
|
console.log(source_default.red(` No live session named "${targetName}". Use /peers to list who's reachable.`));
|
|
159516
159608
|
} else if (!target.socketPath) {
|
|
@@ -159527,7 +159619,7 @@ ${dirList}`;
|
|
|
159527
159619
|
console.log(source_default.dim(" Usage: /peers broadcast <message>"));
|
|
159528
159620
|
} else {
|
|
159529
159621
|
const { broadcastPeerMessage } = await Promise.resolve().then(() => __toESM(require_dist3(), 1));
|
|
159530
|
-
const targets = (0,
|
|
159622
|
+
const targets = (0, import_code_core7.listPeers)(peerHandle.record.id).filter((p) => p.id !== peerHandle.record.id && p.socketPath && p.inbound !== "refuse").map((p) => ({ name: p.name, socketPath: p.socketPath }));
|
|
159531
159623
|
if (!targets.length) {
|
|
159532
159624
|
console.log(source_default.dim(" No other reachable Nexrall Code sessions to broadcast to."));
|
|
159533
159625
|
} else {
|
|
@@ -159539,7 +159631,7 @@ ${dirList}`;
|
|
|
159539
159631
|
}
|
|
159540
159632
|
}
|
|
159541
159633
|
} else {
|
|
159542
|
-
const peers = (0,
|
|
159634
|
+
const peers = (0, import_code_core7.listPeers)(peerHandle.record.id);
|
|
159543
159635
|
if (peers.length <= 1) {
|
|
159544
159636
|
console.log(source_default.dim(" No other Nexrall Code sessions are currently discoverable on this machine."));
|
|
159545
159637
|
} else {
|
|
@@ -159569,7 +159661,7 @@ ${dirList}`;
|
|
|
159569
159661
|
const label = memScope === "global" ? "GLOBAL" : "this PROJECT's";
|
|
159570
159662
|
const answer = await new Promise((resolve6) => rl.question(source_default.yellow(` Clear ${label} memory? This cannot be undone. [y/n] `), (a) => resolve6(a.trim())));
|
|
159571
159663
|
if (answer === "y" || answer === "yes") {
|
|
159572
|
-
(0,
|
|
159664
|
+
(0, import_code_core7.clearMemory)(memScope, workDir);
|
|
159573
159665
|
console.log(source_default.green(` ${memScope === "global" ? "Global" : "Project"} memory cleared.`));
|
|
159574
159666
|
} else {
|
|
159575
159667
|
console.log(source_default.dim(" Cancelled."));
|
|
@@ -159580,20 +159672,20 @@ ${dirList}`;
|
|
|
159580
159672
|
}
|
|
159581
159673
|
console.log();
|
|
159582
159674
|
if (wantsGlobalOnly) {
|
|
159583
|
-
const stats = (0,
|
|
159584
|
-
const content = (0,
|
|
159675
|
+
const stats = (0, import_code_core7.memoryStats)("global");
|
|
159676
|
+
const content = (0, import_code_core7.readMemory)("global", void 0, { includeArchived: wantsArchived });
|
|
159585
159677
|
const archivedNote = stats.archived > 0 ? `, ${stats.archived} archived` : "";
|
|
159586
159678
|
console.log(source_default.bold(" Global memory ") + source_default.dim(`(${stats.entries} entries${archivedNote}, ${(stats.bytes / 1024).toFixed(1)}KB) \u2014 ${stats.file}`));
|
|
159587
159679
|
console.log();
|
|
159588
159680
|
console.log(content || source_default.dim(" No global memories saved yet."));
|
|
159589
159681
|
} else {
|
|
159590
|
-
const projStats = (0,
|
|
159591
|
-
const globalStats = (0,
|
|
159682
|
+
const projStats = (0, import_code_core7.memoryStats)("project", workDir);
|
|
159683
|
+
const globalStats = (0, import_code_core7.memoryStats)("global");
|
|
159592
159684
|
const projArchived = projStats.archived > 0 ? `+${projStats.archived} archived ` : "";
|
|
159593
159685
|
const globalArchived = globalStats.archived > 0 ? `+${globalStats.archived} archived ` : "";
|
|
159594
159686
|
console.log(source_default.bold(" Memory") + source_default.dim(` \u2014 project: ${projStats.entries} ${projArchived}entries (${(projStats.bytes / 1024).toFixed(1)}KB) \xB7 global: ${globalStats.entries} ${globalArchived}entries (${(globalStats.bytes / 1024).toFixed(1)}KB)`));
|
|
159595
159687
|
console.log();
|
|
159596
|
-
const merged = (0,
|
|
159688
|
+
const merged = (0, import_code_core7.readAllMemory)(workDir, { includeArchived: wantsArchived });
|
|
159597
159689
|
console.log(merged || source_default.dim(" No memories saved yet."));
|
|
159598
159690
|
}
|
|
159599
159691
|
console.log();
|
|
@@ -159632,12 +159724,12 @@ ${dirList}`;
|
|
|
159632
159724
|
console.log(source_default.dim(` Current: ${source_default.cyan(agentMode)}`));
|
|
159633
159725
|
for (const m2 of ["ask", "edit", "auto", "plan"]) {
|
|
159634
159726
|
const marker = m2 === agentMode ? source_default.cyan("\u276F") : " ";
|
|
159635
|
-
console.log(` ${marker} ${source_default.bold(m2.padEnd(5))} ${source_default.dim((0,
|
|
159727
|
+
console.log(` ${marker} ${source_default.bold(m2.padEnd(5))} ${source_default.dim((0, import_code_core8.describeMode)(m2).replace(`${m2} \u2014 `, ""))}`);
|
|
159636
159728
|
}
|
|
159637
159729
|
} else if (["ask", "edit", "plan", "auto"].includes(modeArg)) {
|
|
159638
159730
|
agentMode = modeArg;
|
|
159639
159731
|
updateFooter();
|
|
159640
|
-
console.log(source_default.green(` Mode \u2192 ${source_default.bold(modeArg)}`) + source_default.dim(` ${(0,
|
|
159732
|
+
console.log(source_default.green(` Mode \u2192 ${source_default.bold(modeArg)}`) + source_default.dim(` ${(0, import_code_core8.describeMode)(modeArg).replace(`${modeArg} \u2014 `, "")}`));
|
|
159641
159733
|
} else {
|
|
159642
159734
|
console.log(source_default.red(` Unknown: ${modeArg}`));
|
|
159643
159735
|
}
|
|
@@ -159675,22 +159767,22 @@ ${dirList}`;
|
|
|
159675
159767
|
if (target === void 0) {
|
|
159676
159768
|
console.log(source_default.red(" Usage: /team use <team id|personal> (/team lists the ids)"));
|
|
159677
159769
|
} else {
|
|
159678
|
-
await (0,
|
|
159770
|
+
await (0, import_code_core7.setBillingTarget)(target);
|
|
159679
159771
|
console.log(source_default.green(` \u2713 Usage will now be billed to ${target === null ? "your personal wallet" : `team ${target}`}.`));
|
|
159680
159772
|
if (target !== null)
|
|
159681
159773
|
console.log(source_default.dim(" This applies to every product and client on this account, not just the CLI."));
|
|
159682
159774
|
}
|
|
159683
159775
|
} else {
|
|
159684
159776
|
try {
|
|
159685
|
-
const orgs = await (0,
|
|
159686
|
-
const pin = (0,
|
|
159777
|
+
const orgs = await (0, import_code_core7.getOrgs)();
|
|
159778
|
+
const pin = (0, import_code_core7.billingOverrideFields)();
|
|
159687
159779
|
for (const l2 of billingLines(orgs, "teamId" in pin ? pin.teamId : void 0)) {
|
|
159688
159780
|
console.log(l2.startsWith("!") ? source_default.yellow(" " + l2) : " " + l2);
|
|
159689
159781
|
}
|
|
159690
159782
|
} catch (orgErr) {
|
|
159691
159783
|
if (cmd === "/team")
|
|
159692
159784
|
throw orgErr;
|
|
159693
|
-
const bal = await (0,
|
|
159785
|
+
const bal = await (0, import_code_core7.getBalance)();
|
|
159694
159786
|
console.log(source_default.dim(" Balance: ") + source_default.cyan(`$${bal.toFixed(4)}`));
|
|
159695
159787
|
}
|
|
159696
159788
|
}
|
|
@@ -159800,7 +159892,7 @@ ${dirList}`;
|
|
|
159800
159892
|
case "/plan": {
|
|
159801
159893
|
agentMode = "plan";
|
|
159802
159894
|
updateFooter();
|
|
159803
|
-
console.log(source_default.green(` Mode \u2192 ${source_default.bold("plan")}`) + source_default.dim(` ${(0,
|
|
159895
|
+
console.log(source_default.green(` Mode \u2192 ${source_default.bold("plan")}`) + source_default.dim(` ${(0, import_code_core8.describeMode)("plan").replace("plan \u2014 ", "")} (/mode auto to leave)`));
|
|
159804
159896
|
rl.prompt();
|
|
159805
159897
|
return;
|
|
159806
159898
|
}
|
|
@@ -159887,7 +159979,7 @@ ${caption}` : `[Attached: ${rel}]`;
|
|
|
159887
159979
|
if (needsSidecar) {
|
|
159888
159980
|
console.log(source_default.dim(` ${resolveModelLabel(modelAlias)} can't read ${isPdf ? "PDFs" : "images"} directly \u2014 describing ${rel} with Claude Sonnet 5.5 first\u2026`));
|
|
159889
159981
|
try {
|
|
159890
|
-
const { text } = await (0,
|
|
159982
|
+
const { text } = await (0, import_code_core7.describeAttachment)(isPdf ? "pdf" : "image", data, mimeType, rel);
|
|
159891
159983
|
content.push({ type: "text", text: `<attachment_description>
|
|
159892
159984
|
${text}
|
|
159893
159985
|
</attachment_description>` });
|
|
@@ -159931,7 +160023,7 @@ ${text}
|
|
|
159931
160023
|
process.exit(0);
|
|
159932
160024
|
}
|
|
159933
160025
|
case "/plugins": {
|
|
159934
|
-
const plugins = (0,
|
|
160026
|
+
const plugins = (0, import_code_core7.loadPlugins)(workDir);
|
|
159935
160027
|
if (!plugins.length) {
|
|
159936
160028
|
console.log(source_default.dim(" No plugins installed. Install one: nex plugin install owner/repo"));
|
|
159937
160029
|
} else {
|
|
@@ -159944,7 +160036,7 @@ ${text}
|
|
|
159944
160036
|
}
|
|
159945
160037
|
console.log();
|
|
159946
160038
|
}
|
|
159947
|
-
skills = (0,
|
|
160039
|
+
skills = (0, import_code_core7.loadSkills)(workDir);
|
|
159948
160040
|
syncSlashMenu();
|
|
159949
160041
|
rl.prompt();
|
|
159950
160042
|
return;
|
|
@@ -160080,9 +160172,9 @@ ${text}
|
|
|
160080
160172
|
}
|
|
160081
160173
|
case "/skills":
|
|
160082
160174
|
case "/commands": {
|
|
160083
|
-
skills = (0,
|
|
160175
|
+
skills = (0, import_code_core7.loadSkills)(workDir);
|
|
160084
160176
|
syncSlashMenu();
|
|
160085
|
-
const invocable = (0,
|
|
160177
|
+
const invocable = (0, import_code_core7.userInvokableSkills)(skills);
|
|
160086
160178
|
if (!invocable.length) {
|
|
160087
160179
|
console.log(source_default.dim(" No skills. Add .nexrall/skills/<name>/SKILL.md (or .nexrall/commands/<name>.md) to create one."));
|
|
160088
160180
|
} else {
|
|
@@ -160099,15 +160191,15 @@ ${text}
|
|
|
160099
160191
|
return;
|
|
160100
160192
|
}
|
|
160101
160193
|
default: {
|
|
160102
|
-
const custom = (0,
|
|
160194
|
+
const custom = (0, import_code_core7.findSkill)(skills, cmd);
|
|
160103
160195
|
if (!custom) {
|
|
160104
160196
|
console.log(source_default.red(` Unknown command: ${cmd}`));
|
|
160105
160197
|
console.log(source_default.dim(" Type /help for built-ins or /skills for custom ones."));
|
|
160106
160198
|
rl.prompt();
|
|
160107
160199
|
return;
|
|
160108
160200
|
}
|
|
160109
|
-
const expanded = (0,
|
|
160110
|
-
const turnModel = (0,
|
|
160201
|
+
const expanded = (0, import_code_core7.expandSkill)(custom, arg, workDir);
|
|
160202
|
+
const turnModel = (0, import_code_core7.resolveSubAgentModel)(custom.model, modelAlias) ?? modelAlias;
|
|
160111
160203
|
const turnMode = custom.mode ?? agentMode;
|
|
160112
160204
|
console.log(source_default.dim(` Running /${custom.name}\u2026`));
|
|
160113
160205
|
checkpoints.beginTurn(`/${custom.name} ${arg}`.trim(), messages.length);
|
|
@@ -160169,7 +160261,7 @@ ${text}
|
|
|
160169
160261
|
return;
|
|
160170
160262
|
const notes = cliBackgroundAgents.takeNotifications();
|
|
160171
160263
|
console.log(source_default.dim(` \u2699 background agent${notes.length > 1 ? "s" : ""} ${notes.map((n) => `"${n.description}"`).join(", ")} finished \u2014 continuing`));
|
|
160172
|
-
rl.emit("line", (0,
|
|
160264
|
+
rl.emit("line", (0, import_code_core7.formatBackgroundNotifications)(notes));
|
|
160173
160265
|
}, 400);
|
|
160174
160266
|
}
|
|
160175
160267
|
cliBackgroundAgents.onChange(() => {
|
|
@@ -160190,7 +160282,7 @@ ${text}
|
|
|
160190
160282
|
|
|
160191
160283
|
// src/commands/plugin.ts
|
|
160192
160284
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
160193
|
-
var
|
|
160285
|
+
var import_code_core9 = __toESM(require_dist3(), 1);
|
|
160194
160286
|
function describeInspection(i2, name, ctx) {
|
|
160195
160287
|
console.log();
|
|
160196
160288
|
console.log(source_default.bold(` Plugin: ${name}`) + (i2.meta.version ? source_default.dim(` v${i2.meta.version}`) : ""));
|
|
@@ -160266,14 +160358,14 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
160266
160358
|
let registryName;
|
|
160267
160359
|
const isShortName = /^[\w.-]+$/.test(spec.trim()) && !spec.includes("/");
|
|
160268
160360
|
if (isShortName) {
|
|
160269
|
-
const alias = (0,
|
|
160361
|
+
const alias = (0, import_code_core9.resolveSourceAlias)(spec.trim(), process.cwd(), { includeProject: true });
|
|
160270
160362
|
if (alias) {
|
|
160271
160363
|
source2 = alias.spec;
|
|
160272
160364
|
console.log(source_default.dim(` Source: ${alias.name} (${alias.tier}) \u2190 ${alias.spec}`));
|
|
160273
160365
|
}
|
|
160274
160366
|
}
|
|
160275
160367
|
if (isShortName && source2 === spec) {
|
|
160276
|
-
const entry = await (0,
|
|
160368
|
+
const entry = await (0, import_code_core9.getRegistryPlugin)(spec.trim()).catch(() => null);
|
|
160277
160369
|
if (entry) {
|
|
160278
160370
|
source2 = entry.source;
|
|
160279
160371
|
registryName = entry.name;
|
|
@@ -160288,7 +160380,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
160288
160380
|
return;
|
|
160289
160381
|
}
|
|
160290
160382
|
}
|
|
160291
|
-
const res = await (0,
|
|
160383
|
+
const res = await (0, import_code_core9.installPlugin)(source2, {
|
|
160292
160384
|
scope,
|
|
160293
160385
|
workDir: process.cwd(),
|
|
160294
160386
|
name: opts.name ?? registryName,
|
|
@@ -160296,7 +160388,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
160296
160388
|
confirm: (i2, name, ctx) => confirmInstall(i2, name, opts.yes === true, ctx)
|
|
160297
160389
|
});
|
|
160298
160390
|
if (registryName)
|
|
160299
|
-
(0,
|
|
160391
|
+
(0, import_code_core9.reportInstall)(registryName);
|
|
160300
160392
|
console.log();
|
|
160301
160393
|
console.log(source_default.green(` \u2713 Installed "${res.name}" (${res.scope}) \u2192 ${res.dir}`) + (res.sha ? source_default.dim(` @ ${res.sha.slice(0, 7)}`) : ""));
|
|
160302
160394
|
if (res.inspection.commands.length) {
|
|
@@ -160310,7 +160402,7 @@ async function pluginInstallCommand(spec, opts) {
|
|
|
160310
160402
|
}
|
|
160311
160403
|
function pluginRemoveCommand(name, opts) {
|
|
160312
160404
|
try {
|
|
160313
|
-
const dir = (0,
|
|
160405
|
+
const dir = (0, import_code_core9.removePlugin)(name, {
|
|
160314
160406
|
scope: opts.project ? "project" : void 0,
|
|
160315
160407
|
// no flag → search both scopes
|
|
160316
160408
|
workDir: process.cwd()
|
|
@@ -160323,14 +160415,14 @@ function pluginRemoveCommand(name, opts) {
|
|
|
160323
160415
|
}
|
|
160324
160416
|
async function pluginUpdateCommand(name, opts) {
|
|
160325
160417
|
const workDir = process.cwd();
|
|
160326
|
-
const targets = name ? [name] : (0,
|
|
160418
|
+
const targets = name ? [name] : (0, import_code_core9.loadPlugins)(workDir).filter((p) => (0, import_code_core9.readReceipt)(p.dir)?.kind === "github").map((p) => p.name);
|
|
160327
160419
|
if (!targets.length) {
|
|
160328
160420
|
console.log(source_default.dim(" No updatable plugins (only GitHub-installed plugins with receipts can update)."));
|
|
160329
160421
|
return;
|
|
160330
160422
|
}
|
|
160331
160423
|
for (const t2 of targets) {
|
|
160332
160424
|
try {
|
|
160333
|
-
const res = await (0,
|
|
160425
|
+
const res = await (0, import_code_core9.updatePlugin)(t2, {
|
|
160334
160426
|
workDir,
|
|
160335
160427
|
confirm: (i2, n, ctx) => confirmInstall(i2, n, opts.yes === true, ctx)
|
|
160336
160428
|
});
|
|
@@ -160347,7 +160439,7 @@ function badgeFor(p) {
|
|
|
160347
160439
|
}
|
|
160348
160440
|
async function pluginSearchCommand(query) {
|
|
160349
160441
|
try {
|
|
160350
|
-
const results = await (0,
|
|
160442
|
+
const results = await (0, import_code_core9.searchRegistry)(query);
|
|
160351
160443
|
if (!results.length) {
|
|
160352
160444
|
console.log(source_default.dim(query ? ` No plugins matching "${query}".` : " Registry is empty."));
|
|
160353
160445
|
return;
|
|
@@ -160370,7 +160462,7 @@ async function pluginSearchCommand(query) {
|
|
|
160370
160462
|
}
|
|
160371
160463
|
async function pluginInfoCommand(name) {
|
|
160372
160464
|
try {
|
|
160373
|
-
const p = await (0,
|
|
160465
|
+
const p = await (0, import_code_core9.getRegistryPlugin)(name);
|
|
160374
160466
|
if (!p) {
|
|
160375
160467
|
console.error(source_default.red(` \u2717 "${name}" not found in the registry.`));
|
|
160376
160468
|
process.exitCode = 1;
|
|
@@ -160406,7 +160498,7 @@ async function pluginInfoCommand(name) {
|
|
|
160406
160498
|
}
|
|
160407
160499
|
}
|
|
160408
160500
|
function pluginListCommand() {
|
|
160409
|
-
const plugins = (0,
|
|
160501
|
+
const plugins = (0, import_code_core9.loadPlugins)(process.cwd());
|
|
160410
160502
|
if (!plugins.length) {
|
|
160411
160503
|
console.log(source_default.dim(" No plugins installed."));
|
|
160412
160504
|
console.log(source_default.dim(" Install one: nex plugin install owner/repo"));
|
|
@@ -160415,10 +160507,10 @@ function pluginListCommand() {
|
|
|
160415
160507
|
console.log();
|
|
160416
160508
|
console.log(source_default.bold(" Installed plugins:"));
|
|
160417
160509
|
for (const p of plugins) {
|
|
160418
|
-
const receipt = (0,
|
|
160510
|
+
const receipt = (0, import_code_core9.readReceipt)(p.dir);
|
|
160419
160511
|
const src = receipt ? source_default.dim(` \u2190 ${receipt.source}`) : source_default.dim(" (manual)");
|
|
160420
160512
|
const at = receipt?.sha ? source_default.dim(` @ ${receipt.sha.slice(0, 7)}`) : "";
|
|
160421
|
-
const insp = (0,
|
|
160513
|
+
const insp = (0, import_code_core9.inspectPluginDir)(p.dir);
|
|
160422
160514
|
const runs = insp.hasHooks || insp.hasMcp ? source_default.yellow(` \u26A0 ${[insp.hasHooks && "hooks", insp.hasMcp && "mcp"].filter(Boolean).join("+")}`) : "";
|
|
160423
160515
|
console.log(
|
|
160424
160516
|
" " + source_default.cyan(p.name.padEnd(24)) + source_default.dim(`${(p.version ?? "").padEnd(10)}${p.scope.padEnd(9)}`) + src + at + runs
|
|
@@ -160428,8 +160520,8 @@ function pluginListCommand() {
|
|
|
160428
160520
|
}
|
|
160429
160521
|
function pluginSourceListCommand() {
|
|
160430
160522
|
const workDir = process.cwd();
|
|
160431
|
-
const sources = (0,
|
|
160432
|
-
const patterns = (0,
|
|
160523
|
+
const sources = (0, import_code_core9.loadDeclaredSources)(workDir, { includeProject: true });
|
|
160524
|
+
const patterns = (0, import_code_core9.allowedSourcePatterns)();
|
|
160433
160525
|
if (patterns) {
|
|
160434
160526
|
console.log();
|
|
160435
160527
|
console.log(source_default.bold(" Organisation policy: ") + source_default.dim(`installs restricted to ${patterns.join(", ")}`));
|
|
@@ -160444,7 +160536,7 @@ function pluginSourceListCommand() {
|
|
|
160444
160536
|
console.log(source_default.bold(" Declared plugin sources:"));
|
|
160445
160537
|
for (const s2 of sources) {
|
|
160446
160538
|
const tier = s2.tier === "project" ? source_default.yellow(s2.tier.padEnd(9)) : source_default.dim(s2.tier.padEnd(9));
|
|
160447
|
-
const blocked = !(0,
|
|
160539
|
+
const blocked = !(0, import_code_core9.isSourceAllowed)(s2.spec, patterns) ? source_default.red(" \u2717 blocked by policy") : "";
|
|
160448
160540
|
console.log(" " + source_default.cyan(s2.name.padEnd(20)) + tier + source_default.white(s2.spec) + blocked);
|
|
160449
160541
|
}
|
|
160450
160542
|
console.log();
|
|
@@ -160454,17 +160546,17 @@ function pluginSourceListCommand() {
|
|
|
160454
160546
|
}
|
|
160455
160547
|
function pluginSourceAddCommand(name, spec, opts) {
|
|
160456
160548
|
try {
|
|
160457
|
-
(0,
|
|
160458
|
-
const patterns = (0,
|
|
160459
|
-
if (patterns && !(0,
|
|
160549
|
+
(0, import_code_core9.parsePluginSource)(spec);
|
|
160550
|
+
const patterns = (0, import_code_core9.allowedSourcePatterns)();
|
|
160551
|
+
if (patterns && !(0, import_code_core9.isSourceAllowed)(spec, patterns)) {
|
|
160460
160552
|
console.error(source_default.red(` \u2717 "${spec}" is not permitted by your organisation's policy.`));
|
|
160461
160553
|
console.error(source_default.dim(` Allowed: ${patterns.join(", ")}`));
|
|
160462
160554
|
process.exitCode = 1;
|
|
160463
160555
|
return;
|
|
160464
160556
|
}
|
|
160465
160557
|
const scope = opts.project ? "project" : "user";
|
|
160466
|
-
const file = (0,
|
|
160467
|
-
(0,
|
|
160558
|
+
const file = (0, import_code_core9.sourcesFileFor)(scope, process.cwd());
|
|
160559
|
+
(0, import_code_core9.writeDeclaredSource)(file, name, spec);
|
|
160468
160560
|
console.log();
|
|
160469
160561
|
console.log(source_default.green(` \u2713 Declared "${name}" \u2192 ${spec}`) + source_default.dim(` (${scope})`));
|
|
160470
160562
|
console.log(source_default.dim(` ${file}`));
|
|
@@ -160478,13 +160570,13 @@ function pluginSourceAddCommand(name, spec, opts) {
|
|
|
160478
160570
|
function pluginSourceRemoveCommand(name, opts) {
|
|
160479
160571
|
const workDir = process.cwd();
|
|
160480
160572
|
const scope = opts.project ? "project" : "user";
|
|
160481
|
-
const file = (0,
|
|
160482
|
-
if ((0,
|
|
160573
|
+
const file = (0, import_code_core9.sourcesFileFor)(scope, workDir);
|
|
160574
|
+
if ((0, import_code_core9.removeDeclaredSource)(file, name)) {
|
|
160483
160575
|
console.log(source_default.green(` \u2713 Removed source "${name}" (${scope})`));
|
|
160484
160576
|
console.log(source_default.dim(" Plugins already installed from it are untouched \u2014 remove them with nex plugin remove <name>"));
|
|
160485
160577
|
return;
|
|
160486
160578
|
}
|
|
160487
|
-
const found = (0,
|
|
160579
|
+
const found = (0, import_code_core9.resolveSourceAlias)(name, workDir, { includeProject: true });
|
|
160488
160580
|
if (found) {
|
|
160489
160581
|
console.error(source_default.red(` \u2717 "${name}" is declared in the ${found.tier} tier, not ${scope}.`));
|
|
160490
160582
|
console.error(source_default.dim(` ${found.file}`));
|
|
@@ -160581,7 +160673,7 @@ program2.command("sessions").description("List or delete saved chat sessions").o
|
|
|
160581
160673
|
console.log();
|
|
160582
160674
|
});
|
|
160583
160675
|
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("-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)").argument("[prompt...]", "One-shot prompt \u2014 if omitted, starts interactive mode").action(async (promptParts, options) => {
|
|
160584
|
-
if (!(0,
|
|
160676
|
+
if (!(0, import_code_core10.isAuthenticated)()) {
|
|
160585
160677
|
console.error("Not logged in. Run: nex auth");
|
|
160586
160678
|
process.exit(1);
|
|
160587
160679
|
}
|