@nathapp/nax-agent 0.1.0
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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/coding-tools/coding-tool-bash.d.ts +46 -0
- package/dist/coding-tools/coding-tool-bash.js +44 -0
- package/dist/coding-tools/coding-tool-extras.d.ts +35 -0
- package/dist/coding-tools/coding-tool-extras.js +56 -0
- package/dist/coding-tools/coding-tool-sandbox.d.ts +74 -0
- package/dist/coding-tools/coding-tool-sandbox.js +215 -0
- package/dist/coding-tools/coding-tool-support.d.ts +132 -0
- package/dist/coding-tools/coding-tool-support.js +159 -0
- package/dist/coding-tools/universal-coding-tools.d.ts +11 -0
- package/dist/coding-tools/universal-coding-tools.js +5 -0
- package/dist/command-interceptor/index.d.ts +55 -0
- package/dist/command-interceptor/index.js +60 -0
- package/dist/command-interceptor/shell.d.ts +36 -0
- package/dist/command-interceptor/shell.js +137 -0
- package/dist/command-safety/build.d.ts +19 -0
- package/dist/command-safety/build.js +47 -0
- package/dist/command-safety/guard.d.ts +32 -0
- package/dist/command-safety/guard.js +179 -0
- package/dist/command-safety/identifiers.d.ts +24 -0
- package/dist/command-safety/identifiers.js +20 -0
- package/dist/command-safety/index.d.ts +17 -0
- package/dist/command-safety/index.js +11 -0
- package/dist/command-safety/questions.d.ts +19 -0
- package/dist/command-safety/questions.js +60 -0
- package/dist/command-safety/row.d.ts +2 -0
- package/dist/command-safety/row.js +14 -0
- package/dist/command-safety/rule-scorer.d.ts +9 -0
- package/dist/command-safety/rule-scorer.js +391 -0
- package/dist/command-safety/shadow.d.ts +33 -0
- package/dist/command-safety/shadow.js +188 -0
- package/dist/command-safety/systemone-client.d.ts +16 -0
- package/dist/command-safety/systemone-client.js +92 -0
- package/dist/command-safety/tap.d.ts +37 -0
- package/dist/command-safety/tap.js +77 -0
- package/dist/command-safety/temp-only.d.ts +6 -0
- package/dist/command-safety/temp-only.js +215 -0
- package/dist/command-safety/tmp-write.d.ts +2 -0
- package/dist/command-safety/tmp-write.js +112 -0
- package/dist/command-safety/types.d.ts +185 -0
- package/dist/command-safety/types.js +21 -0
- package/dist/config/bash-approval.d.ts +33 -0
- package/dist/config/bash-approval.js +30 -0
- package/dist/config/catalog-overrides.d.ts +94 -0
- package/dist/config/catalog-overrides.js +7 -0
- package/dist/config/native-agent/index.d.ts +8 -0
- package/dist/config/native-agent/index.js +8 -0
- package/dist/config/schemas-sandbox.d.ts +31 -0
- package/dist/config/schemas-sandbox.js +45 -0
- package/dist/cost/core/index.d.ts +8 -0
- package/dist/cost/core/index.js +7 -0
- package/dist/cost/estimate.d.ts +34 -0
- package/dist/cost/estimate.js +65 -0
- package/dist/cost/model-spec.d.ts +28 -0
- package/dist/cost/model-spec.js +29 -0
- package/dist/cost/standard-types.d.ts +9 -0
- package/dist/cost/standard-types.js +1 -0
- package/dist/cost/usage-math.d.ts +18 -0
- package/dist/cost/usage-math.js +46 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +21 -0
- package/dist/infra/agent-logger.d.ts +22 -0
- package/dist/infra/agent-logger.js +19 -0
- package/dist/infra/credentials-config.d.ts +20 -0
- package/dist/infra/credentials-config.js +15 -0
- package/dist/infra/errors.d.ts +9 -0
- package/dist/infra/errors.js +11 -0
- package/dist/infra/index.d.ts +7 -0
- package/dist/infra/index.js +7 -0
- package/dist/infra/nax-error.d.ts +10 -0
- package/dist/infra/nax-error.js +16 -0
- package/dist/infra/spin-breaker/hash.d.ts +2 -0
- package/dist/infra/spin-breaker/hash.js +5 -0
- package/dist/infra/spin-breaker/index.d.ts +120 -0
- package/dist/infra/spin-breaker/index.js +340 -0
- package/dist/internal/agent-output-env.d.ts +44 -0
- package/dist/internal/agent-output-env.js +57 -0
- package/dist/internal/argv-exec.d.ts +58 -0
- package/dist/internal/argv-exec.js +224 -0
- package/dist/internal/bounded-io.d.ts +24 -0
- package/dist/internal/bounded-io.js +51 -0
- package/dist/internal/command-spec/index.d.ts +29 -0
- package/dist/internal/command-spec/index.js +36 -0
- package/dist/internal/describe-value-type.d.ts +8 -0
- package/dist/internal/describe-value-type.js +14 -0
- package/dist/internal/exec-framing.d.ts +18 -0
- package/dist/internal/exec-framing.js +22 -0
- package/dist/internal/file-lock.d.ts +91 -0
- package/dist/internal/file-lock.js +212 -0
- package/dist/internal/file-size.d.ts +2 -0
- package/dist/internal/file-size.js +12 -0
- package/dist/internal/git-add.d.ts +43 -0
- package/dist/internal/git-add.js +59 -0
- package/dist/internal/git-env.d.ts +59 -0
- package/dist/internal/git-env.js +93 -0
- package/dist/internal/git-exec.d.ts +58 -0
- package/dist/internal/git-exec.js +115 -0
- package/dist/internal/path-file-lock.d.ts +23 -0
- package/dist/internal/path-file-lock.js +25 -0
- package/dist/internal/process-alive.d.ts +42 -0
- package/dist/internal/process-alive.js +56 -0
- package/dist/internal/process-kill.d.ts +27 -0
- package/dist/internal/process-kill.js +54 -0
- package/dist/internal/realpath.d.ts +29 -0
- package/dist/internal/realpath.js +52 -0
- package/dist/internal/redact.d.ts +40 -0
- package/dist/internal/redact.js +161 -0
- package/dist/internal/shell-quote.d.ts +2 -0
- package/dist/internal/shell-quote.js +4 -0
- package/dist/internal/sort.d.ts +20 -0
- package/dist/internal/sort.js +20 -0
- package/dist/internal/strip-control-chars.d.ts +19 -0
- package/dist/internal/strip-control-chars.js +38 -0
- package/dist/internal/thenable.d.ts +10 -0
- package/dist/internal/thenable.js +15 -0
- package/dist/internal.d.ts +91 -0
- package/dist/internal.js +91 -0
- package/dist/native/adapter-deps.d.ts +46 -0
- package/dist/native/adapter-deps.js +43 -0
- package/dist/native/auth-types.d.ts +70 -0
- package/dist/native/auth-types.js +13 -0
- package/dist/native/auth.d.ts +133 -0
- package/dist/native/auth.js +362 -0
- package/dist/native/client.d.ts +50 -0
- package/dist/native/client.js +174 -0
- package/dist/native/complete.d.ts +33 -0
- package/dist/native/complete.js +88 -0
- package/dist/native/credentials/chained-store.d.ts +30 -0
- package/dist/native/credentials/chained-store.js +68 -0
- package/dist/native/credentials/change-guard.d.ts +51 -0
- package/dist/native/credentials/change-guard.js +136 -0
- package/dist/native/credentials/exec-source.d.ts +50 -0
- package/dist/native/credentials/exec-source.js +222 -0
- package/dist/native/credentials/fingerprint.d.ts +26 -0
- package/dist/native/credentials/fingerprint.js +174 -0
- package/dist/native/credentials/helper-process.d.ts +79 -0
- package/dist/native/credentials/helper-process.js +259 -0
- package/dist/native/credentials/helper-protocol.d.ts +36 -0
- package/dist/native/credentials/helper-protocol.js +79 -0
- package/dist/native/credentials/index.d.ts +60 -0
- package/dist/native/credentials/index.js +184 -0
- package/dist/native/errors.d.ts +34 -0
- package/dist/native/errors.js +109 -0
- package/dist/native/index.d.ts +25 -0
- package/dist/native/index.js +23 -0
- package/dist/native/model-resolver.d.ts +57 -0
- package/dist/native/model-resolver.js +73 -0
- package/dist/native/models.d.ts +116 -0
- package/dist/native/models.js +183 -0
- package/dist/native/session/ask-human.d.ts +15 -0
- package/dist/native/session/ask-human.js +22 -0
- package/dist/native/session/compaction.d.ts +94 -0
- package/dist/native/session/compaction.js +170 -0
- package/dist/native/session/handle-invalid-tool-call.d.ts +111 -0
- package/dist/native/session/handle-invalid-tool-call.js +159 -0
- package/dist/native/session/loop-events/cache-boundary.d.ts +11 -0
- package/dist/native/session/loop-events/cache-boundary.js +29 -0
- package/dist/native/session/loop-events/external-handler.d.ts +38 -0
- package/dist/native/session/loop-events/external-handler.js +193 -0
- package/dist/native/session/loop-events/index.d.ts +16 -0
- package/dist/native/session/loop-events/index.js +15 -0
- package/dist/native/session/loop-events/payload-guard.d.ts +9 -0
- package/dist/native/session/loop-events/payload-guard.js +31 -0
- package/dist/native/session/loop-events/registry.d.ts +84 -0
- package/dist/native/session/loop-events/registry.js +305 -0
- package/dist/native/session/loop-events/types.d.ts +251 -0
- package/dist/native/session/loop-events/types.js +14 -0
- package/dist/native/session/loop-handlers.d.ts +73 -0
- package/dist/native/session/loop-handlers.js +137 -0
- package/dist/native/session/nudge.d.ts +29 -0
- package/dist/native/session/nudge.js +35 -0
- package/dist/native/session/rate-provenance.d.ts +17 -0
- package/dist/native/session/rate-provenance.js +39 -0
- package/dist/native/session/session.d.ts +139 -0
- package/dist/native/session/session.js +208 -0
- package/dist/native/session/tool-input-exemplar.d.ts +2 -0
- package/dist/native/session/tool-input-exemplar.js +66 -0
- package/dist/native/session/tool-input-validation.d.ts +15 -0
- package/dist/native/session/tool-input-validation.js +146 -0
- package/dist/native/session/tool-mapping.d.ts +18 -0
- package/dist/native/session/tool-mapping.js +27 -0
- package/dist/native/session/tool-result.d.ts +37 -0
- package/dist/native/session/tool-result.js +25 -0
- package/dist/native/session/transcript-store.d.ts +77 -0
- package/dist/native/session/transcript-store.js +200 -0
- package/dist/native/session/truncation-handler.d.ts +47 -0
- package/dist/native/session/truncation-handler.js +83 -0
- package/dist/native/session/turn-accumulator.d.ts +45 -0
- package/dist/native/session/turn-accumulator.js +67 -0
- package/dist/native/session/turn-ask-human.d.ts +23 -0
- package/dist/native/session/turn-ask-human.js +41 -0
- package/dist/native/session/turn-compaction-step.d.ts +74 -0
- package/dist/native/session/turn-compaction-step.js +128 -0
- package/dist/native/session/turn-complete-step.d.ts +77 -0
- package/dist/native/session/turn-complete-step.js +159 -0
- package/dist/native/session/turn-end-event.d.ts +3 -0
- package/dist/native/session/turn-end-event.js +17 -0
- package/dist/native/session/turn-events.d.ts +63 -0
- package/dist/native/session/turn-events.js +48 -0
- package/dist/native/session/turn-loop-round-trip.d.ts +116 -0
- package/dist/native/session/turn-loop-round-trip.js +318 -0
- package/dist/native/session/turn-loop.d.ts +23 -0
- package/dist/native/session/turn-loop.js +250 -0
- package/dist/native/session/turn-result.d.ts +39 -0
- package/dist/native/session/turn-result.js +64 -0
- package/dist/native/session/turn-retry.d.ts +120 -0
- package/dist/native/session/turn-retry.js +182 -0
- package/dist/native/session/turn-tool-batch.d.ts +61 -0
- package/dist/native/session/turn-tool-batch.js +259 -0
- package/dist/native/session/turn-types.d.ts +164 -0
- package/dist/native/session/turn-types.js +36 -0
- package/dist/native/session-adapter.d.ts +56 -0
- package/dist/native/session-adapter.js +369 -0
- package/dist/native/session-affinity.d.ts +36 -0
- package/dist/native/session-affinity.js +43 -0
- package/dist/native/tier-providers.d.ts +18 -0
- package/dist/native/tier-providers.js +20 -0
- package/dist/permissions/approval-audit.d.ts +10 -0
- package/dist/permissions/approval-audit.js +22 -0
- package/dist/permissions/approvals-link.d.ts +20 -0
- package/dist/permissions/approvals-link.js +62 -0
- package/dist/permissions/approvals-store.d.ts +168 -0
- package/dist/permissions/approvals-store.js +259 -0
- package/dist/permissions/approvals-taint.d.ts +33 -0
- package/dist/permissions/approvals-taint.js +138 -0
- package/dist/permissions/ask-chain.d.ts +69 -0
- package/dist/permissions/ask-chain.js +32 -0
- package/dist/permissions/ask.d.ts +23 -0
- package/dist/permissions/ask.js +25 -0
- package/dist/permissions/bash-lex.d.ts +59 -0
- package/dist/permissions/bash-lex.js +279 -0
- package/dist/permissions/grammar.d.ts +12 -0
- package/dist/permissions/grammar.js +24 -0
- package/dist/permissions/index.d.ts +11 -0
- package/dist/permissions/index.js +9 -0
- package/dist/permissions/secret-spans.d.ts +19 -0
- package/dist/permissions/secret-spans.js +88 -0
- package/dist/permissions/types.d.ts +85 -0
- package/dist/permissions/types.js +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/node-glob.d.ts +3 -0
- package/dist/runtime/node-glob.js +83 -0
- package/dist/runtime/node-runtime.d.ts +3 -0
- package/dist/runtime/node-runtime.js +126 -0
- package/dist/runtime/slot.d.ts +11 -0
- package/dist/runtime/slot.js +17 -0
- package/dist/runtime/types.d.ts +51 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/which.d.ts +8 -0
- package/dist/runtime/which.js +32 -0
- package/dist/sandbox/argv-quote.d.ts +11 -0
- package/dist/sandbox/argv-quote.js +13 -0
- package/dist/sandbox/defaults.d.ts +27 -0
- package/dist/sandbox/defaults.js +47 -0
- package/dist/sandbox/git-guards.d.ts +64 -0
- package/dist/sandbox/git-guards.js +161 -0
- package/dist/sandbox/index.d.ts +11 -0
- package/dist/sandbox/index.js +10 -0
- package/dist/sandbox/launcher.d.ts +37 -0
- package/dist/sandbox/launcher.js +160 -0
- package/dist/sandbox/messages.d.ts +17 -0
- package/dist/sandbox/messages.js +46 -0
- package/dist/sandbox/policy-builder.d.ts +44 -0
- package/dist/sandbox/policy-builder.js +149 -0
- package/dist/sandbox/policy-inputs.d.ts +53 -0
- package/dist/sandbox/policy-inputs.js +76 -0
- package/dist/sandbox/probe.d.ts +8 -0
- package/dist/sandbox/probe.js +66 -0
- package/dist/sandbox/registry.d.ts +17 -0
- package/dist/sandbox/registry.js +57 -0
- package/dist/sandbox/session-tmp.d.ts +20 -0
- package/dist/sandbox/session-tmp.js +95 -0
- package/dist/sandbox/srt-backend.d.ts +21 -0
- package/dist/sandbox/srt-backend.js +99 -0
- package/dist/sandbox/types.d.ts +102 -0
- package/dist/sandbox/types.js +1 -0
- package/dist/session/adapter-failure.d.ts +60 -0
- package/dist/session/adapter-failure.js +11 -0
- package/dist/session/agent-stream-events.d.ts +103 -0
- package/dist/session/agent-stream-events.js +6 -0
- package/dist/session/interaction-handler.d.ts +53 -0
- package/dist/session/interaction-handler.js +2 -0
- package/dist/session/no-op-interaction-handler.d.ts +9 -0
- package/dist/session/no-op-interaction-handler.js +11 -0
- package/dist/session/protocol-types.d.ts +12 -0
- package/dist/session/protocol-types.js +1 -0
- package/dist/session/session-types.d.ts +456 -0
- package/dist/session/session-types.js +64 -0
- package/dist/session/tool-descriptor.d.ts +23 -0
- package/dist/session/tool-descriptor.js +5 -0
- package/dist/session/turn-deadline.d.ts +17 -0
- package/dist/session/turn-deadline.js +23 -0
- package/dist/tools/ask-request.d.ts +35 -0
- package/dist/tools/ask-request.js +57 -0
- package/dist/tools/bash-cwd.d.ts +82 -0
- package/dist/tools/bash-cwd.js +55 -0
- package/dist/tools/bash.d.ts +69 -0
- package/dist/tools/bash.js +283 -0
- package/dist/tools/delete.d.ts +57 -0
- package/dist/tools/delete.js +154 -0
- package/dist/tools/denial-redirect.d.ts +42 -0
- package/dist/tools/denial-redirect.js +266 -0
- package/dist/tools/deny-paths.d.ts +35 -0
- package/dist/tools/deny-paths.js +76 -0
- package/dist/tools/edit-region.d.ts +50 -0
- package/dist/tools/edit-region.js +90 -0
- package/dist/tools/edit.d.ts +25 -0
- package/dist/tools/edit.js +114 -0
- package/dist/tools/exec-allowlist-text.d.ts +18 -0
- package/dist/tools/exec-allowlist-text.js +24 -0
- package/dist/tools/exec-guard.d.ts +69 -0
- package/dist/tools/exec-guard.js +151 -0
- package/dist/tools/git-commit.d.ts +59 -0
- package/dist/tools/git-commit.js +220 -0
- package/dist/tools/git-flags/index.d.ts +10 -0
- package/dist/tools/git-flags/index.js +10 -0
- package/dist/tools/git.d.ts +88 -0
- package/dist/tools/git.js +397 -0
- package/dist/tools/glob.d.ts +29 -0
- package/dist/tools/glob.js +153 -0
- package/dist/tools/grep.d.ts +21 -0
- package/dist/tools/grep.js +162 -0
- package/dist/tools/index.d.ts +36 -0
- package/dist/tools/index.js +28 -0
- package/dist/tools/narrow-grants.d.ts +19 -0
- package/dist/tools/narrow-grants.js +54 -0
- package/dist/tools/nax-owned-writes.d.ts +135 -0
- package/dist/tools/nax-owned-writes.js +259 -0
- package/dist/tools/package-managers-table.d.ts +146 -0
- package/dist/tools/package-managers-table.js +325 -0
- package/dist/tools/package-managers-types.d.ts +36 -0
- package/dist/tools/package-managers-types.js +6 -0
- package/dist/tools/package-managers.d.ts +85 -0
- package/dist/tools/package-managers.js +391 -0
- package/dist/tools/path-list.d.ts +38 -0
- package/dist/tools/path-list.js +62 -0
- package/dist/tools/policy-bash-raw.d.ts +19 -0
- package/dist/tools/policy-bash-raw.js +210 -0
- package/dist/tools/policy-bash.d.ts +64 -0
- package/dist/tools/policy-bash.js +232 -0
- package/dist/tools/policy-command-branch.d.ts +32 -0
- package/dist/tools/policy-command-branch.js +63 -0
- package/dist/tools/policy-input.d.ts +2 -0
- package/dist/tools/policy-input.js +10 -0
- package/dist/tools/policy-match.d.ts +75 -0
- package/dist/tools/policy-match.js +117 -0
- package/dist/tools/policy-paths-branch.d.ts +97 -0
- package/dist/tools/policy-paths-branch.js +314 -0
- package/dist/tools/policy.d.ts +65 -0
- package/dist/tools/policy.js +232 -0
- package/dist/tools/protected-paths.d.ts +26 -0
- package/dist/tools/protected-paths.js +8 -0
- package/dist/tools/provider-adapt.d.ts +4 -0
- package/dist/tools/provider-adapt.js +32 -0
- package/dist/tools/provider-advertise.d.ts +39 -0
- package/dist/tools/provider-advertise.js +50 -0
- package/dist/tools/provider-grants.d.ts +36 -0
- package/dist/tools/provider-grants.js +72 -0
- package/dist/tools/provider-sanitize.d.ts +19 -0
- package/dist/tools/provider-sanitize.js +53 -0
- package/dist/tools/provider-types.d.ts +41 -0
- package/dist/tools/provider-types.js +26 -0
- package/dist/tools/read-continuation.d.ts +147 -0
- package/dist/tools/read-continuation.js +176 -0
- package/dist/tools/read-file.d.ts +32 -0
- package/dist/tools/read-file.js +85 -0
- package/dist/tools/read.d.ts +25 -0
- package/dist/tools/read.js +182 -0
- package/dist/tools/registry.d.ts +125 -0
- package/dist/tools/registry.js +67 -0
- package/dist/tools/request-capability.d.ts +13 -0
- package/dist/tools/request-capability.js +23 -0
- package/dist/tools/run-command-exec.d.ts +14 -0
- package/dist/tools/run-command-exec.js +161 -0
- package/dist/tools/run-command.d.ts +107 -0
- package/dist/tools/run-command.js +398 -0
- package/dist/tools/runtime-calltool.d.ts +146 -0
- package/dist/tools/runtime-calltool.js +223 -0
- package/dist/tools/runtime.d.ts +149 -0
- package/dist/tools/runtime.js +345 -0
- package/dist/tools/scratchpad.d.ts +20 -0
- package/dist/tools/scratchpad.js +197 -0
- package/dist/tools/spill.d.ts +81 -0
- package/dist/tools/spill.js +251 -0
- package/dist/tools/tool-audit.d.ts +171 -0
- package/dist/tools/tool-audit.js +183 -0
- package/dist/tools/truncate.d.ts +98 -0
- package/dist/tools/truncate.js +297 -0
- package/dist/tools/types.d.ts +145 -0
- package/dist/tools/types.js +24 -0
- package/dist/tools/verb-denial-argv-hint.d.ts +35 -0
- package/dist/tools/verb-denial-argv-hint.js +40 -0
- package/dist/tools/write.d.ts +9 -0
- package/dist/tools/write.js +45 -0
- package/package.json +54 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Name-to-tool registry, mirroring PULL_TOOL_REGISTRY in the context engine.
|
|
3
|
+
*
|
|
4
|
+
* Open to third-party registration, with two rules that make that safe:
|
|
5
|
+
* built-in names are reserved (a registered "Write" would shadow the gated
|
|
6
|
+
* implementation), and a verb-gated tool must declare the verbs it permits so
|
|
7
|
+
* the policy can never be granted a subcommand the tool itself disallows.
|
|
8
|
+
*
|
|
9
|
+
* Registration is in-process — another nax module or plugin. This is an
|
|
10
|
+
* extension point, not a plugin download path.
|
|
11
|
+
*/
|
|
12
|
+
import type { CommandInterceptor } from "#src/command-interceptor/index";
|
|
13
|
+
import type { JSONSchema } from "#src/session/tool-descriptor";
|
|
14
|
+
import type { SandboxRecord } from "../sandbox/index.ts";
|
|
15
|
+
import type { ProtectedPathsPolicy } from "./protected-paths.ts";
|
|
16
|
+
import type { CodingToolName, ToolScope } from "./types.ts";
|
|
17
|
+
export interface ToolResult {
|
|
18
|
+
readonly content: string;
|
|
19
|
+
readonly isError?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Set only by RunCommand's argv branch (`Exec`), which is the one call
|
|
22
|
+
* shape whose executed argv can differ from what the model requested
|
|
23
|
+
* (normalization scopes it to a workspace member and may append a
|
|
24
|
+
* no-scripts mechanism). Returned here rather than re-derived by the
|
|
25
|
+
* runtime so the ledger records the argv that actually ran. Task 7 reads
|
|
26
|
+
* this to write `executed`/`target` onto the ledger row; this task only
|
|
27
|
+
* defines and returns it.
|
|
28
|
+
*
|
|
29
|
+
* The `Git` tool also sets `audit` when a command interceptor rewrote its
|
|
30
|
+
* argv — there `target` is absent, because the repoRoot/package distinction
|
|
31
|
+
* does not apply to a git read.
|
|
32
|
+
*/
|
|
33
|
+
readonly audit?: {
|
|
34
|
+
readonly executed: readonly string[];
|
|
35
|
+
readonly target?: "repoRoot" | "package";
|
|
36
|
+
/** Exec only: the directory the argv ran in. Read by the command-safety shadow, not the ledger. */
|
|
37
|
+
readonly cwd?: string;
|
|
38
|
+
/** P4: how an agent-authored Bash/Exec command ran; absent for every other tool. */
|
|
39
|
+
readonly sandbox?: SandboxRecord;
|
|
40
|
+
/**
|
|
41
|
+
* Bash only: the shell's exit code, present when nax did NOT kill the
|
|
42
|
+
* process group -- absent under `timedOut` (deadline kill) and `aborted`
|
|
43
|
+
* (turn cancellation), present under `orphansKilled` (the shell exited by
|
|
44
|
+
* itself; only background processes were reaped). What N means depends on
|
|
45
|
+
* the command in `executed` (exit 1 is "no match" for grep, "failures" for
|
|
46
|
+
* a test runner), and N >= 128 may still be a signal nax did not send.
|
|
47
|
+
*/
|
|
48
|
+
readonly exitCode?: number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Result size in bytes BEFORE the tool truncated to `ctx.maxBytes`. Set by
|
|
52
|
+
* tools whose payload is unbounded by nature — an MCP graph query can return
|
|
53
|
+
* megabytes. `resultBytes` on the ledger is measured after the slice, so
|
|
54
|
+
* without this a 2 MB result and a 40 KB one are indistinguishable and "how
|
|
55
|
+
* much did we discard" is unanswerable.
|
|
56
|
+
*/
|
|
57
|
+
readonly resultBytesPreTruncation?: number;
|
|
58
|
+
}
|
|
59
|
+
export interface ToolRunContext {
|
|
60
|
+
/** Absolute, symlink-resolved permitted root. */
|
|
61
|
+
readonly root: string;
|
|
62
|
+
/** Paths the policy already resolved and approved, in pathFields order. */
|
|
63
|
+
readonly resolvedPaths: readonly string[];
|
|
64
|
+
/** Output ceiling in bytes; the tool truncates rather than the caller. */
|
|
65
|
+
readonly maxBytes: number;
|
|
66
|
+
/**
|
|
67
|
+
* Largest file this tool may read whole or write. Bounds the work, where
|
|
68
|
+
* maxBytes bounds only what the model is told -- see src/tools/bounded.ts.
|
|
69
|
+
*/
|
|
70
|
+
readonly maxFileBytes: number;
|
|
71
|
+
/**
|
|
72
|
+
* Tool-layer I/O bound. Optional so existing `ToolRunContext` literals
|
|
73
|
+
* compile unchanged; resolves to `READ_CEILING` when absent. Distinct
|
|
74
|
+
* from `maxFileBytes` (whole-file Edit/Write cap) and `maxBytes` (the
|
|
75
|
+
* model-facing ceiling owned by `after_tool`).
|
|
76
|
+
*/
|
|
77
|
+
readonly readCeiling?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Repo-configurable glob denylist (nax#1972, `execution.denyPaths` in
|
|
80
|
+
* config), narrowing what a tool may act on beyond containment and grants.
|
|
81
|
+
* Currently consumed by Delete only -- see src/tools/deny-paths.ts. Absent
|
|
82
|
+
* or empty means no additional narrowing.
|
|
83
|
+
*/
|
|
84
|
+
readonly denyPaths?: readonly string[];
|
|
85
|
+
/**
|
|
86
|
+
* Aborts the turn's process execution; Bash and Exec forward it to the
|
|
87
|
+
* launcher and runArgv, which SIGKILL the process group. US-001.
|
|
88
|
+
*/
|
|
89
|
+
readonly signal?: AbortSignal;
|
|
90
|
+
/**
|
|
91
|
+
* The run's command interceptor (US-003; S1 spec section 4.2, port 7). The
|
|
92
|
+
* same object for every tool of a run, so the Git and Bash sites share one
|
|
93
|
+
* binary probe and one mode. Absent when the run installed none: interception
|
|
94
|
+
* then does not apply, the fail-safe both sites state.
|
|
95
|
+
*/
|
|
96
|
+
readonly interceptor?: CommandInterceptor;
|
|
97
|
+
/** Host-owned paths (S1 spec port 6). Absent: the Git tools exclude and skip nothing extra. */
|
|
98
|
+
readonly protectedPaths?: ProtectedPathsPolicy;
|
|
99
|
+
}
|
|
100
|
+
export interface CodingTool {
|
|
101
|
+
readonly name: string;
|
|
102
|
+
readonly description: string;
|
|
103
|
+
readonly inputSchema: JSONSchema;
|
|
104
|
+
readonly scope: ToolScope;
|
|
105
|
+
/**
|
|
106
|
+
* True when an `isError` result is a routine part of using this tool rather
|
|
107
|
+
* than a fault worth an operator's attention. Only `RunCommand` sets it: a
|
|
108
|
+
* non-zero exit from a project command is the agent's own red/green loop, and
|
|
109
|
+
* on the acpx transport that loop runs inside the spawned agent where nax
|
|
110
|
+
* never observes it. Such calls are recorded at debug — the JSONL and the
|
|
111
|
+
* audit sink still get them, the console does not. Everything else defaults
|
|
112
|
+
* to false, so a malformed Read or a failed GitCommit stays visible.
|
|
113
|
+
*/
|
|
114
|
+
readonly routineErrors?: boolean;
|
|
115
|
+
run(input: Record<string, unknown>, ctx: ToolRunContext): Promise<ToolResult>;
|
|
116
|
+
}
|
|
117
|
+
/** Built-in names may never be re-registered. */
|
|
118
|
+
export declare const RESERVED_TOOL_NAMES: readonly CodingToolName[];
|
|
119
|
+
export declare function registerCodingTool(tool: CodingTool): void;
|
|
120
|
+
/** Register a nax built-in, bypassing the reserved-name check by design. */
|
|
121
|
+
export declare function registerBuiltinTool(tool: CodingTool): void;
|
|
122
|
+
export declare function getCodingTool(name: string): CodingTool | undefined;
|
|
123
|
+
export declare function listCodingTools(): readonly CodingTool[];
|
|
124
|
+
/** @internal Test-only: clears registrations between cases. */
|
|
125
|
+
export declare function _resetRegistryForTest(): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Name-to-tool registry, mirroring PULL_TOOL_REGISTRY in the context engine.
|
|
3
|
+
*
|
|
4
|
+
* Open to third-party registration, with two rules that make that safe:
|
|
5
|
+
* built-in names are reserved (a registered "Write" would shadow the gated
|
|
6
|
+
* implementation), and a verb-gated tool must declare the verbs it permits so
|
|
7
|
+
* the policy can never be granted a subcommand the tool itself disallows.
|
|
8
|
+
*
|
|
9
|
+
* Registration is in-process — another nax module or plugin. This is an
|
|
10
|
+
* extension point, not a plugin download path.
|
|
11
|
+
*/
|
|
12
|
+
import { NaxError } from "#src/infra/index";
|
|
13
|
+
/** Built-in names may never be re-registered. */
|
|
14
|
+
export const RESERVED_TOOL_NAMES = [
|
|
15
|
+
"Read",
|
|
16
|
+
"Glob",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Write",
|
|
19
|
+
"Edit",
|
|
20
|
+
"Delete",
|
|
21
|
+
"Git",
|
|
22
|
+
"GitCommit",
|
|
23
|
+
"RunCommand",
|
|
24
|
+
"RequestCapability",
|
|
25
|
+
"Exec",
|
|
26
|
+
"Bash",
|
|
27
|
+
"ScratchpadWrite",
|
|
28
|
+
"ScratchpadRead",
|
|
29
|
+
"ScratchpadList",
|
|
30
|
+
];
|
|
31
|
+
const registry = new Map();
|
|
32
|
+
export function registerCodingTool(tool) {
|
|
33
|
+
if (RESERVED_TOOL_NAMES.includes(tool.name) && !internalRegistration) {
|
|
34
|
+
throw new NaxError(`Tool name "${tool.name}" is reserved for a nax built-in and cannot be re-registered.`, "TOOL_NAME_RESERVED", { stage: "tools", tool: tool.name });
|
|
35
|
+
}
|
|
36
|
+
if (registry.has(tool.name)) {
|
|
37
|
+
throw new NaxError(`Tool "${tool.name}" is already registered.`, "TOOL_ALREADY_REGISTERED", {
|
|
38
|
+
stage: "tools",
|
|
39
|
+
tool: tool.name,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (tool.scope.verbField !== undefined && tool.scope.allowedVerbs === undefined) {
|
|
43
|
+
throw new NaxError(`Tool "${tool.name}" declares verbField but no allowedVerbs; the policy would have no bound to enforce.`, "TOOL_SCOPE_INCOMPLETE", { stage: "tools", tool: tool.name });
|
|
44
|
+
}
|
|
45
|
+
registry.set(tool.name, tool);
|
|
46
|
+
}
|
|
47
|
+
let internalRegistration = false;
|
|
48
|
+
/** Register a nax built-in, bypassing the reserved-name check by design. */
|
|
49
|
+
export function registerBuiltinTool(tool) {
|
|
50
|
+
internalRegistration = true;
|
|
51
|
+
try {
|
|
52
|
+
registerCodingTool(tool);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
internalRegistration = false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function getCodingTool(name) {
|
|
59
|
+
return registry.get(name);
|
|
60
|
+
}
|
|
61
|
+
export function listCodingTools() {
|
|
62
|
+
return [...registry.values()];
|
|
63
|
+
}
|
|
64
|
+
/** @internal Test-only: clears registrations between cases. */
|
|
65
|
+
export function _resetRegistryForTest() {
|
|
66
|
+
registry.clear();
|
|
67
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declares a capability the model wanted and could not reach. Runs nothing.
|
|
3
|
+
*
|
|
4
|
+
* A denial is only produced if the model attempts a call, and a model told it
|
|
5
|
+
* has no shell will not attempt one -- so the absence of denials would be
|
|
6
|
+
* indistinguishable from the absence of need. Issue #1800 is the worked
|
|
7
|
+
* example: a reviewer said in prose "I have no file/shell access tool in this
|
|
8
|
+
* environment" and then returned a pass, and nothing structured captured it.
|
|
9
|
+
*
|
|
10
|
+
* The refusal is the point. The value is the row it leaves behind.
|
|
11
|
+
*/
|
|
12
|
+
import type { CodingTool } from "./registry.ts";
|
|
13
|
+
export declare const requestCapabilityTool: CodingTool;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const requestCapabilityTool = {
|
|
2
|
+
name: "RequestCapability",
|
|
3
|
+
description: "Declare a capability you need but do not have (for example a shell command you would have run). This grants nothing and runs nothing; it records the need so the tool set can be widened later.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
capability: { type: "string", description: "What you would have run or reached, verbatim" },
|
|
8
|
+
reason: { type: "string", description: "Why you needed it, in one sentence" },
|
|
9
|
+
},
|
|
10
|
+
required: ["capability"],
|
|
11
|
+
},
|
|
12
|
+
scope: { pathFields: [] },
|
|
13
|
+
async run(input, _ctx) {
|
|
14
|
+
const capability = input.capability;
|
|
15
|
+
if (typeof capability !== "string" || capability.trim() === "") {
|
|
16
|
+
return { content: "capability must be a non-empty string", isError: true };
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
content: `Recorded: "${capability}" is not available on this path. Continue without it, or stop and say you cannot proceed.`,
|
|
20
|
+
isError: true,
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ToolResult, ToolRunContext } from "./registry.ts";
|
|
2
|
+
import type { RunCommandToolOptions } from "./run-command.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Deadline for the argv branch's spawn (`runExecBranch`).
|
|
5
|
+
*
|
|
6
|
+
* Deliberately longer than the declared branch's own default deadline
|
|
7
|
+
* (120_000ms, in the project's quality-command runner): a declared quality
|
|
8
|
+
* command runs entirely on code already on disk, while an install-shaped
|
|
9
|
+
* argv call here talks to a package registry over the network and may run
|
|
10
|
+
* a vendor postinstall script — both routinely take longer than a
|
|
11
|
+
* project's own test/lint/typecheck command.
|
|
12
|
+
*/
|
|
13
|
+
export declare const EXEC_TIMEOUT_MS = 300000;
|
|
14
|
+
export declare function runExecBranch(input: Record<string, unknown>, ctx: ToolRunContext, opts: RunCommandToolOptions): Promise<ToolResult>;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunCommand's second, allowlisted call shape (`Exec`): a model-authored argv
|
|
3
|
+
* rather than a declared command key.
|
|
4
|
+
*
|
|
5
|
+
* Split out of run-command.ts (fix round 1, Minor) so the no-shell guarantee
|
|
6
|
+
* is structural rather than a comment pinned to file layout: this file must
|
|
7
|
+
* never import the declared branch's shell-templated command executor
|
|
8
|
+
* (the RunCommand sibling module resolves and spawns those through a real
|
|
9
|
+
* shell) or its shell-argument quoting helper (there is no shell string
|
|
10
|
+
* here to quote). `test/unit/tools/run-command-exec.test.ts` reads this
|
|
11
|
+
* file WHOLE and asserts neither one appears anywhere in it — a whole-file
|
|
12
|
+
* check that cannot be defeated by moving functions around within it,
|
|
13
|
+
* unlike the prior slice-from-a-known-function-name guard.
|
|
14
|
+
*
|
|
15
|
+
* Order matters and is fixed: `validateArgv` (shape/metacharacters) runs
|
|
16
|
+
* before `runExecBranch` is even reached — the runtime's policy check
|
|
17
|
+
* already ran it against the raw argv before `run()` was called at all, see
|
|
18
|
+
* `src/tools/policy.ts`. It is re-checked here too, because this function
|
|
19
|
+
* must also be safe to call directly, bypassing the runtime (as this file's
|
|
20
|
+
* own tests do). Then `deniedFlag` (source/destination-redirecting flags a
|
|
21
|
+
* verb-prefix grant cannot see), then `normalizeExec` (install-shaped
|
|
22
|
+
* hardening and workspace scoping), then `runArgv`.
|
|
23
|
+
*/
|
|
24
|
+
import { relative } from "node:path";
|
|
25
|
+
import { agentOutputOverlay } from "#src/internal/agent-output-env";
|
|
26
|
+
import { runArgv } from "#src/internal/argv-exec";
|
|
27
|
+
import { formatExecBody } from "#src/internal/exec-framing";
|
|
28
|
+
import { deniedFlag, validateArgv } from "./exec-guard.js";
|
|
29
|
+
import { normalizeExec } from "./package-managers.js";
|
|
30
|
+
import { cutToByteCap, READ_CEILING } from "./truncate.js";
|
|
31
|
+
/**
|
|
32
|
+
* Deadline for the argv branch's spawn (`runExecBranch`).
|
|
33
|
+
*
|
|
34
|
+
* Deliberately longer than the declared branch's own default deadline
|
|
35
|
+
* (120_000ms, in the project's quality-command runner): a declared quality
|
|
36
|
+
* command runs entirely on code already on disk, while an install-shaped
|
|
37
|
+
* argv call here talks to a package registry over the network and may run
|
|
38
|
+
* a vendor postinstall script — both routinely take longer than a
|
|
39
|
+
* project's own test/lint/typecheck command.
|
|
40
|
+
*/
|
|
41
|
+
export const EXEC_TIMEOUT_MS = 300_000;
|
|
42
|
+
/**
|
|
43
|
+
* Layer the AGENT=1 overlay onto an existing Exec env (or build a fresh env
|
|
44
|
+
* with just the overlay). Returns undefined when both inputs are undefined
|
|
45
|
+
* so the caller can omit the `env` key entirely and let `Bun.spawn` inherit
|
|
46
|
+
* the parent's environment on its own — the same shape `withAgentOutputEnv`
|
|
47
|
+
* applied via `normalizeEnvironment` in the verification runner, but here the
|
|
48
|
+
* inputs are partial: the Exec env is optional and the overlay may also be
|
|
49
|
+
* undefined when a marker is inherited or AGENT is stripped.
|
|
50
|
+
*/
|
|
51
|
+
function mergedExecEnv(execEnv, strippedVars) {
|
|
52
|
+
const agentOverlay = agentOutputOverlay(strippedVars);
|
|
53
|
+
if (agentOverlay === undefined)
|
|
54
|
+
return execEnv !== undefined ? { ...execEnv } : undefined;
|
|
55
|
+
return { ...(execEnv ?? {}), ...agentOverlay };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Spawn the normalized argv through the launcher when one is configured and
|
|
59
|
+
* fall back to a direct `runArgv` call otherwise. The launcher branch carries
|
|
60
|
+
* the `stripEnvVars` as a shared array (Bun.spawn reads it once), while the
|
|
61
|
+
* direct branch spreads it so the deps seam sees the same shape every other
|
|
62
|
+
* `_argvExecDeps.spawn` test stubs.
|
|
63
|
+
*/
|
|
64
|
+
async function launchExec(req) {
|
|
65
|
+
if (req.launcher !== undefined) {
|
|
66
|
+
return await req.launcher.run({
|
|
67
|
+
spec: { kind: "argv", argv: req.argv },
|
|
68
|
+
root: req.root,
|
|
69
|
+
cwd: req.cwd,
|
|
70
|
+
timeoutMs: EXEC_TIMEOUT_MS,
|
|
71
|
+
stripEnvVars: req.stripEnvVars,
|
|
72
|
+
...(req.mergedEnv !== undefined ? { env: req.mergedEnv } : {}),
|
|
73
|
+
...(req.signal !== undefined ? { signal: req.signal } : {}),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
...(await runArgv({
|
|
78
|
+
argv: req.argv,
|
|
79
|
+
cwd: req.cwd,
|
|
80
|
+
timeoutMs: EXEC_TIMEOUT_MS,
|
|
81
|
+
stripEnvVars: [...req.stripEnvVars],
|
|
82
|
+
// Yarn 2+ carries its no-scripts mechanism here rather than in argv.
|
|
83
|
+
...(req.mergedEnv !== undefined ? { env: req.mergedEnv } : {}),
|
|
84
|
+
...(req.signal !== undefined ? { signal: req.signal } : {}),
|
|
85
|
+
})),
|
|
86
|
+
sandbox: undefined,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export async function runExecBranch(input, ctx, opts) {
|
|
90
|
+
if (opts.exec === undefined)
|
|
91
|
+
return { content: "argv is not available on this path", isError: true };
|
|
92
|
+
const invalid = validateArgv(input.argv);
|
|
93
|
+
if (invalid !== undefined)
|
|
94
|
+
return { content: invalid, isError: true };
|
|
95
|
+
const argv = input.argv;
|
|
96
|
+
// Real narrowing, not a cast: validateArgv above already rejected an
|
|
97
|
+
// empty argv, so this destructure cannot actually miss -- kept as a
|
|
98
|
+
// defensive fallback (matching package-managers.ts's own "unreachable"
|
|
99
|
+
// comments) rather than a postfix `!` or an `as string`.
|
|
100
|
+
const [binary] = argv;
|
|
101
|
+
if (binary === undefined)
|
|
102
|
+
return { content: "argv must not be empty", isError: true };
|
|
103
|
+
const flag = deniedFlag(argv);
|
|
104
|
+
if (flag !== undefined)
|
|
105
|
+
return { content: `flag ${flag} is not permitted`, isError: true };
|
|
106
|
+
const target = input.target === "repoRoot" ? "repoRoot" : "package";
|
|
107
|
+
const packageRelPath = relative(opts.exec.repoRoot, opts.exec.packageWorkdir);
|
|
108
|
+
const normalized = normalizeExec({
|
|
109
|
+
argv,
|
|
110
|
+
target,
|
|
111
|
+
repoRoot: opts.exec.repoRoot,
|
|
112
|
+
packageWorkdir: opts.exec.packageWorkdir,
|
|
113
|
+
packageRelPath,
|
|
114
|
+
allowScripts: opts.exec.allowScripts,
|
|
115
|
+
...(opts.exec.packageName !== undefined ? { packageName: opts.exec.packageName } : {}),
|
|
116
|
+
});
|
|
117
|
+
if ("error" in normalized)
|
|
118
|
+
return { content: normalized.error, isError: true };
|
|
119
|
+
// US-004: opt the child into agent-friendly output. The Exec branch never
|
|
120
|
+
// rewrites the argv (that's the model's command), and the overlay is only
|
|
121
|
+
// `AGENT=1` — same rule the quality and verification runners apply. An
|
|
122
|
+
// inherited marker (`CLAUDECODE`/`REPL_ID`) speaks for itself, and a
|
|
123
|
+
// stripped AGENT stays stripped. The overlay is layered on top of any Exec
|
|
124
|
+
// env (the Yarn no-scripts key) so the latter survives wrapping alongside.
|
|
125
|
+
const mergedEnv = mergedExecEnv(normalized.env, opts.stripEnvVars ?? []);
|
|
126
|
+
try {
|
|
127
|
+
const launched = await launchExec({
|
|
128
|
+
argv: normalized.argv,
|
|
129
|
+
root: ctx.root,
|
|
130
|
+
cwd: normalized.cwd,
|
|
131
|
+
launcher: opts.exec.launcher,
|
|
132
|
+
mergedEnv,
|
|
133
|
+
stripEnvVars: opts.stripEnvVars ?? [],
|
|
134
|
+
signal: ctx.signal,
|
|
135
|
+
});
|
|
136
|
+
// US-001: match Bash's framing so an aborted Exec is rendered as an
|
|
137
|
+
// error with the cancellation banner (AC14 mirror) and an orphansKilled
|
|
138
|
+
// Exec appends the same `[nax]` footer (AC15 mirror).
|
|
139
|
+
const text = formatExecBody(launched, EXEC_TIMEOUT_MS);
|
|
140
|
+
return {
|
|
141
|
+
content: cutToByteCap(text, ctx.readCeiling ?? READ_CEILING),
|
|
142
|
+
isError: launched.timedOut || launched.exitCode !== 0 || launched.aborted === true,
|
|
143
|
+
// Task 7 reads this to write `executed` and `target` onto the ledger
|
|
144
|
+
// row. Returning it here, rather than re-deriving it in the runtime,
|
|
145
|
+
// keeps the recorded argv the one that actually ran.
|
|
146
|
+
audit: {
|
|
147
|
+
executed: normalized.argv,
|
|
148
|
+
target,
|
|
149
|
+
cwd: normalized.cwd,
|
|
150
|
+
...(launched.sandbox !== undefined ? { sandbox: launched.sandbox } : {}),
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
// A spawn-time failure (e.g. an unresolvable cwd) throws rather than
|
|
156
|
+
// resolving with a non-zero exit; surfaced as a normal tool error so it
|
|
157
|
+
// is indistinguishable, to the caller, from any other refusal above.
|
|
158
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
159
|
+
return { content: message, isError: true };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { QualityCommandSpec } from "#src/internal/command-spec/index";
|
|
2
|
+
import { type CommandLauncher } from "../sandbox/index.ts";
|
|
3
|
+
import type { CodingTool } from "./registry.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Context for RunCommand's allowlisted, model-authored argv branch (`Exec`).
|
|
6
|
+
*
|
|
7
|
+
* Populated only when the operation declared the `Exec` marker
|
|
8
|
+
* (`buildCodingToolSupport` in `src/agents/coding-tool-support.ts`).
|
|
9
|
+
*/
|
|
10
|
+
export interface RunCommandExecOptions {
|
|
11
|
+
readonly repoRoot: string;
|
|
12
|
+
readonly packageWorkdir: string;
|
|
13
|
+
/** Manifest name, required by yarn/cargo's package-scoping form; absent when unresolvable. */
|
|
14
|
+
readonly packageName?: string;
|
|
15
|
+
readonly allowScripts: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The Exec tool's compiled grant patterns, as `resolvePermissions` produced
|
|
18
|
+
* them for THIS project/stage -- not `BUILT_IN_EXEC_PATTERNS` imported
|
|
19
|
+
* directly, because a project's own `Exec(...)` expression REPLACES that
|
|
20
|
+
* built-in list rather than extending it (see the comment on
|
|
21
|
+
* `BUILT_IN_EXEC_PATTERNS` in src/config/permissions.ts). Read only to
|
|
22
|
+
* render the tool description (#1937): the policy check itself still runs
|
|
23
|
+
* against the runtime's own compiled grant in policy.ts, so this field
|
|
24
|
+
* being stale or absent could make the description wrong but can never
|
|
25
|
+
* widen what actually executes.
|
|
26
|
+
*/
|
|
27
|
+
readonly patterns: readonly string[];
|
|
28
|
+
/** P4: how the argv runs. Absent = direct runArgv (unit tests). */
|
|
29
|
+
readonly launcher?: CommandLauncher;
|
|
30
|
+
}
|
|
31
|
+
/** What RunCommand hands the runner for one declared command. */
|
|
32
|
+
export interface DeclaredCommandRequest {
|
|
33
|
+
readonly commandName: string;
|
|
34
|
+
readonly command: QualityCommandSpec;
|
|
35
|
+
readonly workdir: string;
|
|
36
|
+
readonly stripEnvVars: string[];
|
|
37
|
+
readonly origin: "agent-tool";
|
|
38
|
+
}
|
|
39
|
+
/** What RunCommand reads back. */
|
|
40
|
+
export interface DeclaredCommandResult {
|
|
41
|
+
readonly success: boolean;
|
|
42
|
+
readonly exitCode: number;
|
|
43
|
+
readonly output: string;
|
|
44
|
+
}
|
|
45
|
+
/** Runs one declared command; nax supplies `runQualityCommand` (S1 spec port 7). */
|
|
46
|
+
export type DeclaredCommandRunner = (request: DeclaredCommandRequest) => Promise<DeclaredCommandResult>;
|
|
47
|
+
export interface RunCommandToolOptions {
|
|
48
|
+
/** Secret environment variables excluded from agent-triggered commands. */
|
|
49
|
+
readonly stripEnvVars?: readonly string[];
|
|
50
|
+
/** See `RunCommandExecOptions`. */
|
|
51
|
+
readonly exec?: RunCommandExecOptions;
|
|
52
|
+
/**
|
|
53
|
+
* Execution cwd for the DECLARED (non-Exec) branch below, independent of
|
|
54
|
+
* `ctx.root` (tool containment). Falls back to `ctx.root` when absent —
|
|
55
|
+
* post-PR2 (single-frame redesign) `ctx.root` is the story's repo-rooted
|
|
56
|
+
* execution root, so an omitted `commandCwd` runs the declared command at
|
|
57
|
+
* the repo root, NOT the package dir. Every production caller threads
|
|
58
|
+
* `commandCwd` (see the `buildCodingToolSupport` producer below); the
|
|
59
|
+
* fallback is effectively unreachable in production and only fires from
|
|
60
|
+
* tests that bypass the support seam — see the use site for the exact
|
|
61
|
+
* behavior.
|
|
62
|
+
*
|
|
63
|
+
* PRODUCER: src/agents/coding-tool-support.ts (`buildCodingToolSupport`'s
|
|
64
|
+
* `commandCwd` arg).
|
|
65
|
+
*/
|
|
66
|
+
readonly commandCwd?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Runs a DECLARED (non-Exec) command (S1 spec section 4.2, port 7). nax
|
|
69
|
+
* supplies `runQualityCommand` through `resolveCodingToolSupport`; absent,
|
|
70
|
+
* the tool answers `exit 1` and spawns nothing.
|
|
71
|
+
*/
|
|
72
|
+
readonly runDeclaredCommand?: DeclaredCommandRunner;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* An ARRAY value is quoted per element and joined; a string value is quoted
|
|
76
|
+
* whole. The distinction carries the element boundaries through substitution,
|
|
77
|
+
* which a pre-joined string cannot: the join would be re-split and a path
|
|
78
|
+
* under `/tmp/my dir/` would become two arguments (nax#1998).
|
|
79
|
+
*/
|
|
80
|
+
export declare function substituteCommand(template: string, values: Record<string, string | readonly string[]>): string | {
|
|
81
|
+
error: string;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Apply placeholder substitution across a spec. A list substitutes into every
|
|
85
|
+
* entry and fails as a whole if any entry fails, so a partially-substituted
|
|
86
|
+
* list can never reach the shell.
|
|
87
|
+
*
|
|
88
|
+
* Each entry only receives the subset of `values` it actually declares
|
|
89
|
+
* placeholders for -- list entries commonly have different placeholder needs
|
|
90
|
+
* (e.g. `["tsc --noEmit", "bun test {{files}}"]`), and `substituteCommand`
|
|
91
|
+
* rejects a value that isn't a placeholder in the template it's checking, by
|
|
92
|
+
* design (it's what stops a value silently going nowhere). Passing the full
|
|
93
|
+
* shared `values` object to every entry would make every entry without
|
|
94
|
+
* {{files}} fail that check.
|
|
95
|
+
*
|
|
96
|
+
* But per-entry filtering alone would let a value that no entry in the whole
|
|
97
|
+
* spec declares vanish silently (every entry's filtered set would just be
|
|
98
|
+
* empty, and every entry would substitute cleanly) -- so before filtering
|
|
99
|
+
* per entry, every key in `values` is checked against the UNION of
|
|
100
|
+
* placeholders declared across the whole spec, and rejected with the same
|
|
101
|
+
* "unrecognized value" contract `substituteCommand` gives the single-string
|
|
102
|
+
* case if it isn't declared anywhere.
|
|
103
|
+
*/
|
|
104
|
+
export declare function substituteCommandSpec(spec: QualityCommandSpec, values: Record<string, string | readonly string[]>): QualityCommandSpec | {
|
|
105
|
+
error: string;
|
|
106
|
+
};
|
|
107
|
+
export declare function createRunCommandTool(declared: ReadonlyMap<string, QualityCommandSpec>, opts?: RunCommandToolOptions): CodingTool;
|