@livx.cc/agentx 0.99.127 → 0.99.128
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/cli.d.ts +2 -1
- package/dist/cli.js +34 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +27 -3
- package/dist/index.js.map +1 -1
- package/dist/{secondChannel-CYU9qqwr.d.ts → secondChannel-D-8AGmAT.d.ts} +6 -1
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { w as RouterState, H as Hooks, c as AgentOptions, x as RunResult, f as ChatUsage, R as ReasoningEffort, d as ChannelMode, b as Agent } from './secondChannel-
|
|
2
|
+
import { w as RouterState, H as Hooks, c as AgentOptions, x as RunResult, f as ChatUsage, R as ReasoningEffort, d as ChannelMode, b as Agent } from './secondChannel-D-8AGmAT.js';
|
|
3
3
|
import { IFilesystem } from '@livx.cc/wcli/core';
|
|
4
4
|
import { M as Message, U as UserQuestion, H as HostBridge, c as ContentPart, o as MessageContent } from './tools-DwfeF8VQ.js';
|
|
5
5
|
|
|
@@ -170,6 +170,7 @@ interface Args {
|
|
|
170
170
|
inputFormat?: 'stream-json';
|
|
171
171
|
allowedTools?: string[];
|
|
172
172
|
disallowedTools?: string[];
|
|
173
|
+
onlyTools?: string[];
|
|
173
174
|
appendSystemPrompt?: string;
|
|
174
175
|
voiceSystemPrompt?: string;
|
|
175
176
|
addDirs?: string[];
|
package/dist/cli.js
CHANGED
|
@@ -4160,16 +4160,19 @@ import { join as join4 } from "path";
|
|
|
4160
4160
|
|
|
4161
4161
|
// src/permissions.ts
|
|
4162
4162
|
init_tools_structured();
|
|
4163
|
+
import { posix } from "path";
|
|
4163
4164
|
function commandMatches(glob, cmd) {
|
|
4164
4165
|
const pattern = glob.split("*").map((s) => s.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
4165
4166
|
return new RegExp("^" + pattern + "$").test(cmd);
|
|
4166
4167
|
}
|
|
4168
|
+
var SHELL_CONTROL = /[;&|`$<>\n\r]/;
|
|
4167
4169
|
function toolMatches(rule, name) {
|
|
4168
4170
|
return rule.includes("*") ? commandMatches(rule, name) : rule === name;
|
|
4169
4171
|
}
|
|
4170
4172
|
var PermissionOptions = class {
|
|
4171
4173
|
rules = [];
|
|
4172
|
-
/** decision when no rule matches.
|
|
4174
|
+
/** decision when no rule matches. 'deny' = an allow-list run (`--onlyTools`): only the allow rules run, an allowed
|
|
4175
|
+
* command glob never matches shell control syntax, and claude-code enforces it by a PreToolUse hook (ccHooks). */
|
|
4173
4176
|
default = "allow";
|
|
4174
4177
|
/** host channel for `ask` (confirm). If absent, `ask` is treated as `deny` (fail-closed). */
|
|
4175
4178
|
host;
|
|
@@ -4182,15 +4185,17 @@ var PermissionPolicy = class {
|
|
|
4182
4185
|
/** Resolve the decision for a tool call (first matching rule, else default). */
|
|
4183
4186
|
decide(call) {
|
|
4184
4187
|
const names = call.name === "McpCall" && typeof call.args?.name === "string" ? [call.name, call.args.name] : [call.name];
|
|
4188
|
+
if (CC_TOOL_ALIAS[call.name]) names.push(CC_TOOL_ALIAS[call.name]);
|
|
4189
|
+
const strict = this.options.default === "deny";
|
|
4185
4190
|
for (const r of this.options.rules) {
|
|
4186
4191
|
if (r.tool && !names.some((n) => toolMatches(r.tool, n))) continue;
|
|
4187
4192
|
if (r.pathGlob) {
|
|
4188
4193
|
const path = typeof call.args?.path === "string" ? call.args.path : null;
|
|
4189
4194
|
const cmd = typeof call.args?.command === "string" ? call.args.command : null;
|
|
4190
4195
|
if (path != null) {
|
|
4191
|
-
if (!globToRegExp(r.pathGlob).test(path.startsWith("/") ? path : `/${path}`)) continue;
|
|
4196
|
+
if (!globToRegExp(r.pathGlob).test(posix.normalize(path.startsWith("/") ? path : `/${path}`))) continue;
|
|
4192
4197
|
} else if (cmd != null) {
|
|
4193
|
-
if (!commandMatches(r.pathGlob, cmd)) continue;
|
|
4198
|
+
if (!commandMatches(r.pathGlob, cmd) || strict && r.decision === "allow" && SHELL_CONTROL.test(cmd)) continue;
|
|
4194
4199
|
} else continue;
|
|
4195
4200
|
}
|
|
4196
4201
|
return r.decision;
|
|
@@ -4202,6 +4207,18 @@ var PermissionPolicy = class {
|
|
|
4202
4207
|
denyRules(explicitOnly = false) {
|
|
4203
4208
|
return this.options.rules.filter((r) => r.decision === "deny" && (!explicitOnly || r.explicit)).map((r) => `${r.tool ?? "*"}${r.pathGlob ? `(${r.pathGlob})` : ""}`);
|
|
4204
4209
|
}
|
|
4210
|
+
/** An allow-list policy (default 'deny') as Claude Code SDK hooks: claude-code runs its own tools, which never reach
|
|
4211
|
+
* {@link hooks}, and `disallowedTools` can't say "everything else". Every tool call (native and MCP) goes through
|
|
4212
|
+
* decide(); `ask` has no host there → deny. undefined for a default-allow policy (its deny rules travel as disallowedTools). */
|
|
4213
|
+
ccHooks() {
|
|
4214
|
+
if (this.options.default !== "deny") return void 0;
|
|
4215
|
+
const gate = async (input) => {
|
|
4216
|
+
const t = input?.tool_input ?? {}, path = t.file_path ?? t.notebook_path ?? t.path;
|
|
4217
|
+
const d = this.decide({ name: String(input?.tool_name ?? ""), args: { ...t, ...typeof path === "string" ? { path } : {} } });
|
|
4218
|
+
return d === "allow" ? {} : { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: `not on this run's tool allow-list (${input?.tool_name})` } };
|
|
4219
|
+
};
|
|
4220
|
+
return { PreToolUse: [{ hooks: [gate] }] };
|
|
4221
|
+
}
|
|
4205
4222
|
/** A preToolUse hook enforcing this policy (deny/ask → block; allow → proceed). */
|
|
4206
4223
|
hooks() {
|
|
4207
4224
|
return {
|
|
@@ -5290,6 +5307,11 @@ var Agent = class _Agent {
|
|
|
5290
5307
|
}
|
|
5291
5308
|
const denyTools = [...claudeCodeDisallowedTools(o.permissions), ...mode.disallow];
|
|
5292
5309
|
if (mode.hooks) po.hooks = mode.hooks;
|
|
5310
|
+
const allowOnly = o.permissions?.ccHooks();
|
|
5311
|
+
if (allowOnly) {
|
|
5312
|
+
const h = po.hooks ?? o.providerOptions?.hooks ?? {};
|
|
5313
|
+
po.hooks = { ...h, PreToolUse: [...h.PreToolUse ?? [], ...allowOnly.PreToolUse] };
|
|
5314
|
+
}
|
|
5293
5315
|
if (this.modeKind && o.providerOptions?.claudeCodeSession) po.claudeCodeSession = `${o.providerOptions.claudeCodeSession}:${this.modeKind}`;
|
|
5294
5316
|
if (denyTools.length) {
|
|
5295
5317
|
const prior = o.providerOptions?.disallowedTools ?? [];
|
|
@@ -5647,6 +5669,8 @@ var Agent = class _Agent {
|
|
|
5647
5669
|
const claudeSteerPo = this.claudeCodePo();
|
|
5648
5670
|
if (this.ccServer) this.ccExec = hostExec;
|
|
5649
5671
|
const cursorDeny = o.model.startsWith("cursor/") ? o.permissions?.denyRules(true) ?? [] : [];
|
|
5672
|
+
if (o.model.startsWith("cursor/") && o.permissions?.options.default === "deny")
|
|
5673
|
+
throw new Error("cursor/* cannot enforce --onlyTools: its native tools bypass it. Refusing to run \u2014 use a claude-code/* or API model.");
|
|
5650
5674
|
if (cursorDeny.length)
|
|
5651
5675
|
throw new Error(`cursor/* cannot enforce --disallowedTools (${cursorDeny.join(", ")}): its native tools bypass them. Refusing to run \u2014 use a claude-code/* or API model, or drop --disallowedTools.`);
|
|
5652
5676
|
const reasonOpts = {
|
|
@@ -19503,6 +19527,7 @@ function parseArgs(argv) {
|
|
|
19503
19527
|
} else if (x === "--think-model") a.thinkModel = val(++i, x);
|
|
19504
19528
|
else if (x === "--no-think") a.thinkModel = false;
|
|
19505
19529
|
else if (x === "--allowedTools" || x === "--allowed-tools") a.allowedTools = val(++i, x).split(",").map((s) => s.trim()).filter(Boolean);
|
|
19530
|
+
else if (x === "--onlyTools" || x === "--only-tools") a.onlyTools = val(++i, x).split(",").map((s) => s.trim()).filter(Boolean);
|
|
19506
19531
|
else if (x === "--disallowedTools" || x === "--disallowed-tools") a.disallowedTools = val(++i, x).split(",").map((s) => s.trim()).filter(Boolean);
|
|
19507
19532
|
else if (x === "--append-system-prompt") a.appendSystemPrompt = val(++i, x);
|
|
19508
19533
|
else if (x === "--voice-system-prompt") a.voiceSystemPrompt = val(++i, x);
|
|
@@ -19588,6 +19613,8 @@ Flags:
|
|
|
19588
19613
|
--verbose, --debug verbose logs (sets DEBUG=* \u2014 tool args, hook decisions, retries)
|
|
19589
19614
|
--allowedTools <l> comma-list of tools to allow w/o asking, e.g. "Edit,Shell(git *)"
|
|
19590
19615
|
--disallowedTools <l> comma-list of tools to deny outright (wins over allow), e.g. "Shell(rm *)"
|
|
19616
|
+
--onlyTools <l> allow-list: ONLY these run, all else is denied (a command glob never matches shell chaining, pipes, $ or redirects),
|
|
19617
|
+
e.g. "Read(/job/**),Write(/job/**),Bash(bun /skill/cli.ts *)" \u2014 cursor/* refuses it
|
|
19591
19618
|
--append-system-prompt <t> extra instructions appended to the system prompt for this run
|
|
19592
19619
|
--call voice call (duplex v3): the main agent (-m, full tools) answers every turn; a fast model
|
|
19593
19620
|
(--voice-model, default Claude Haiku) only fills the wait \u2014 backchannels, fillers, bridges,
|
|
@@ -20369,9 +20396,9 @@ function optsFor(args, ai, cfg = {}, extraTools = []) {
|
|
|
20369
20396
|
const perm = resolvePermMode(args, canPrompt);
|
|
20370
20397
|
if (perm.notice) err(dim(` \u26A0 ${perm.notice}
|
|
20371
20398
|
`));
|
|
20372
|
-
const configRules = parsePermRules(cfg.permissions);
|
|
20373
|
-
const flagRules = [...parsePermRules({ deny: args.disallowedTools }, true), ...parsePermRules({ allow: args.allowedTools }, true)];
|
|
20374
|
-
const askRules = perm.gate === "ask" ? ASK_MUTATING.map((t) => ({ tool: t, decision: "ask" })) : [];
|
|
20399
|
+
const configRules = parsePermRules(cfg.permissions).filter((r) => !args.onlyTools || r.decision !== "allow");
|
|
20400
|
+
const flagRules = [...parsePermRules({ deny: args.disallowedTools }, true), ...parsePermRules({ allow: args.onlyTools ?? args.allowedTools }, true)];
|
|
20401
|
+
const askRules = perm.gate === "ask" && !args.onlyTools ? ASK_MUTATING.map((t) => ({ tool: t, decision: "ask" })) : [];
|
|
20375
20402
|
const rules = [...flagRules, ...configRules, ...askRules];
|
|
20376
20403
|
if (configRules.length) err(dim(` \u2295 ${configRules.length} permission rule(s) from config
|
|
20377
20404
|
`));
|
|
@@ -20397,7 +20424,7 @@ function optsFor(args, ai, cfg = {}, extraTools = []) {
|
|
|
20397
20424
|
stream: args.stream,
|
|
20398
20425
|
host: makeHost(args.outputFormat, { stream: true }),
|
|
20399
20426
|
planMode: args.plan || cfg.planMode || false,
|
|
20400
|
-
permissions: rules.length ? new PermissionPolicy({ rules, default: "allow", host: makeHost(), ask: makeAskResolver(resolve5(args.cwd ?? process.cwd())) }) : void 0,
|
|
20427
|
+
permissions: rules.length || args.onlyTools ? new PermissionPolicy({ rules, default: args.onlyTools ? "deny" : "allow", host: makeHost(), ask: makeAskResolver(resolve5(args.cwd ?? process.cwd())) }) : void 0,
|
|
20401
20428
|
subagents: args.subagents || cfg.subagents || false,
|
|
20402
20429
|
maxSteps: args.maxSteps ?? cfg.maxSteps,
|
|
20403
20430
|
reasoning: args.reasoning ?? cfg.reasoning,
|