@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,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage-and-commit, the one mutating git operation the implementer role needs.
|
|
3
|
+
*
|
|
4
|
+
* Separate from gitTool because buildGitArgv cannot express it: that builder
|
|
5
|
+
* terminates with `--` and pathspecs and refuses any element beginning with
|
|
6
|
+
* "-", so `commit -m <message>` is not representable in it. Splitting the tool
|
|
7
|
+
* also lets a stage be granted the read verbs without the write one.
|
|
8
|
+
*
|
|
9
|
+
* The message is an argv ELEMENT, never parsed. A message that looks like a
|
|
10
|
+
* flag is inert because it sits after `-m` in an argv array that never reaches
|
|
11
|
+
* a shell -- a test pins that position.
|
|
12
|
+
*/
|
|
13
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { gitlinkSafeAdd, hasStagedChanges } from "#src/internal/git-add";
|
|
17
|
+
import { gitWithTimeout } from "#src/internal/git-exec";
|
|
18
|
+
import { gitIgnorePatternsOf } from "./protected-paths.js";
|
|
19
|
+
export function buildCommitArgvs(input) {
|
|
20
|
+
const message = input.message;
|
|
21
|
+
if (typeof message !== "string" || message.trim() === "") {
|
|
22
|
+
return { error: "message must be a non-empty string" };
|
|
23
|
+
}
|
|
24
|
+
const paths = Array.isArray(input.paths) ? input.paths : [];
|
|
25
|
+
if (paths.length === 0)
|
|
26
|
+
return { error: "paths must name at least one file" };
|
|
27
|
+
const add = ["add", "--"];
|
|
28
|
+
for (const path of paths) {
|
|
29
|
+
if (typeof path !== "string")
|
|
30
|
+
return { error: "paths must be strings" };
|
|
31
|
+
if (path.startsWith("-"))
|
|
32
|
+
return { error: `path "${path}" may not begin with "-"` };
|
|
33
|
+
add.push(path);
|
|
34
|
+
}
|
|
35
|
+
return { add, commit: ["commit", "-m", message] };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Split `paths` into ones GitCommit may stage and ones it must refuse, per the
|
|
39
|
+
* caller-supplied `ignorePatterns` (nax passes `NAX_GITIGNORE_ENTRIES` -- the
|
|
40
|
+
* same SSOT `nax init`, `WorktreeManager`, and
|
|
41
|
+
* `scripts/check-nax-artifacts-untracked.ts` all enforce).
|
|
42
|
+
*
|
|
43
|
+
* A real run staged its own `.nax/scratchpad/*.md` files through this exact
|
|
44
|
+
* tool (no filter existed at all): the ignore-file reconcile in
|
|
45
|
+
* `src/execution/lifecycle/gitignore-reconcile.ts` closes this for `git add -A`
|
|
46
|
+
* and human adds, but is per-clone -- a fresh clone or CI has no local
|
|
47
|
+
* `.git/info/exclude` yet, so this tool needs its own, independent check.
|
|
48
|
+
*
|
|
49
|
+
* The `ignorePatterns` are gitignore PATTERNS (`**\/.nax/scratchpad/`), not
|
|
50
|
+
* literal paths -- hand-rolled substring/glob matching has bitten this repo
|
|
51
|
+
* before (see the comment in `src/worktree/manager.ts` on `/foo/runs/` wrongly
|
|
52
|
+
* "containing" `runs/`). Delegate to `git check-ignore` itself, exactly as
|
|
53
|
+
* `scripts/check-nax-artifacts-untracked.ts` delegates to `git ls-files` --
|
|
54
|
+
* both feed `NAX_GITIGNORE_ENTRIES` to git via a temp exclude file rather than
|
|
55
|
+
* re-implementing pattern matching. `--no-index` is required: a path GitCommit
|
|
56
|
+
* is being asked to stage for the first time is not yet in the index, and
|
|
57
|
+
* `check-ignore` without it can decline to answer for such a path.
|
|
58
|
+
*
|
|
59
|
+
* THREE-STATE, fail-closed (code review, post-Fix-3): `git check-ignore`
|
|
60
|
+
* exits 0 (ignored), 1 (not ignored) or 128 (fatal -- e.g. path outside the
|
|
61
|
+
* repo, or not a git repo at all). `gitWithTimeout` additionally collapses a
|
|
62
|
+
* hung subprocess to `exitCode: 1` with `timedOut: true` -- so `exitCode ===
|
|
63
|
+
* 1` ALONE is not "not ignored", it is ALSO what a timeout looks like. Reading
|
|
64
|
+
* it as "not ignored" without checking `timedOut` first put a nax-owned path
|
|
65
|
+
* straight into `kept` on any error or timeout: fail-OPEN, silently, exactly
|
|
66
|
+
* the class of bug this tool exists to prevent -- and under exactly the
|
|
67
|
+
* contention (parallel worktrees stressing git) most likely to produce one.
|
|
68
|
+
* A path that cannot be classified goes to neither `kept` nor `skipped`; it
|
|
69
|
+
* is reported by the caller, loudly, as its own category.
|
|
70
|
+
*
|
|
71
|
+
* One `check-ignore` subprocess per path (not batched into one call): batching
|
|
72
|
+
* would collapse this exact three-state distinction, since git's exit code for
|
|
73
|
+
* a multi-path invocation reflects "at least one path matched", not a per-path
|
|
74
|
+
* verdict, and a single fatal path (exit 128) would poison every other path in
|
|
75
|
+
* the batch as unknown even when they are perfectly answerable individually.
|
|
76
|
+
* Fine for the batch sizes a single commit call names.
|
|
77
|
+
*/
|
|
78
|
+
export async function partitionNaxOwnedPaths(root, paths, ignorePatterns) {
|
|
79
|
+
if (paths.length === 0)
|
|
80
|
+
return { kept: [], skipped: [], unknown: [] };
|
|
81
|
+
// Fail CLOSED on an absent policy (S1 spec port 6): `ToolRunContext.protectedPaths`
|
|
82
|
+
// is optional, so a runtime built without one hands us an empty list. Writing
|
|
83
|
+
// that list to the exclude file makes `check-ignore` exit 1 for EVERY path --
|
|
84
|
+
// which reads as "not ignored" and would put nax-owned run artifacts straight
|
|
85
|
+
// back into `kept`, silently, exactly the incident this tool exists to prevent.
|
|
86
|
+
// Refusing every path keeps the failure loud and puts it in the category the
|
|
87
|
+
// caller already reports.
|
|
88
|
+
if (ignorePatterns.length === 0) {
|
|
89
|
+
return {
|
|
90
|
+
kept: [],
|
|
91
|
+
skipped: [],
|
|
92
|
+
unknown: paths.map((path) => ({ path, reason: "no protected-paths ignore patterns were supplied" })),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const excludeDir = mkdtempSync(join(tmpdir(), "nax-commit-filter-"));
|
|
96
|
+
const excludeFile = join(excludeDir, "exclude");
|
|
97
|
+
try {
|
|
98
|
+
writeFileSync(excludeFile, `${ignorePatterns.join("\n")}\n`, "utf8");
|
|
99
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
100
|
+
// `check-ignore` has no `--exclude-from` of its own (unlike `ls-files`,
|
|
101
|
+
// which `scripts/check-nax-artifacts-untracked.ts` uses) -- pointing
|
|
102
|
+
// `core.excludesFile` at the temp file via `-c` is the documented way
|
|
103
|
+
// to feed it an arbitrary pattern list.
|
|
104
|
+
const { exitCode, timedOut, stderr } = await gitWithTimeout(["-c", `core.excludesFile=${excludeFile}`, "check-ignore", "--no-index", "-q", "--", path], root);
|
|
105
|
+
if (timedOut)
|
|
106
|
+
return { path, status: "unknown", reason: "git check-ignore timed out" };
|
|
107
|
+
if (exitCode === 0)
|
|
108
|
+
return { path, status: "ignored" };
|
|
109
|
+
if (exitCode === 1)
|
|
110
|
+
return { path, status: "not-ignored" };
|
|
111
|
+
const detail = stderr.trim();
|
|
112
|
+
return {
|
|
113
|
+
path,
|
|
114
|
+
status: "unknown",
|
|
115
|
+
reason: `git check-ignore exited ${exitCode}${detail ? `: ${detail}` : ""}`,
|
|
116
|
+
};
|
|
117
|
+
}));
|
|
118
|
+
const kept = [];
|
|
119
|
+
const skipped = [];
|
|
120
|
+
const unknown = [];
|
|
121
|
+
for (const result of results) {
|
|
122
|
+
if (result.status === "ignored")
|
|
123
|
+
skipped.push(result.path);
|
|
124
|
+
else if (result.status === "not-ignored")
|
|
125
|
+
kept.push(result.path);
|
|
126
|
+
else
|
|
127
|
+
unknown.push({ path: result.path, reason: result.reason });
|
|
128
|
+
}
|
|
129
|
+
return { kept, skipped, unknown };
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
rmSync(excludeDir, { recursive: true, force: true });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export const gitCommitTool = {
|
|
136
|
+
name: "GitCommit",
|
|
137
|
+
description: "Stage the named files and commit them. Supply the message as text and the files as an array; this is not a command line.",
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: "object",
|
|
140
|
+
properties: {
|
|
141
|
+
message: { type: "string", description: "Commit message. May contain a blank line and a body." },
|
|
142
|
+
paths: {
|
|
143
|
+
type: "array",
|
|
144
|
+
items: { type: "string" },
|
|
145
|
+
description: "Files to stage, relative to the repository root",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
required: ["message", "paths"],
|
|
149
|
+
},
|
|
150
|
+
scope: { pathFields: [], arrayPathFields: ["paths"] },
|
|
151
|
+
async run(input, ctx) {
|
|
152
|
+
// Fix 3: filter nax-owned artifacts out of the caller's paths BEFORE
|
|
153
|
+
// building argv, so they can never reach `git add`. Only attempted when
|
|
154
|
+
// every supplied path is a plain string -- otherwise buildCommitArgvs's
|
|
155
|
+
// own type validation below must see the original, unfiltered input so
|
|
156
|
+
// its error message stays accurate.
|
|
157
|
+
const rawPaths = Array.isArray(input.paths) ? input.paths : [];
|
|
158
|
+
let effectiveInput = input;
|
|
159
|
+
let skipped = [];
|
|
160
|
+
let unknown = [];
|
|
161
|
+
if (rawPaths.length > 0 && rawPaths.every((path) => typeof path === "string")) {
|
|
162
|
+
const partition = await partitionNaxOwnedPaths(ctx.root, rawPaths, gitIgnorePatternsOf(ctx));
|
|
163
|
+
skipped = partition.skipped;
|
|
164
|
+
unknown = partition.unknown;
|
|
165
|
+
// Fail CLOSED: an unresolved path is refused, exactly like a nax-owned
|
|
166
|
+
// one -- it never reaches `kept`, so it can never reach `git add`.
|
|
167
|
+
if (partition.kept.length === 0) {
|
|
168
|
+
const refusals = [];
|
|
169
|
+
if (skipped.length > 0) {
|
|
170
|
+
refusals.push(`${skipped.length} nax-owned run artifact(s), not staged: ${skipped.join(", ")}`);
|
|
171
|
+
}
|
|
172
|
+
if (unknown.length > 0) {
|
|
173
|
+
refusals.push(`${unknown.length} path(s) whose ignore status could not be determined, refused to stage them: ${unknown
|
|
174
|
+
.map((u) => `${u.path} (${u.reason})`)
|
|
175
|
+
.join("; ")}`);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
content: `Nothing was staged -- every supplied path was refused: ${refusals.join("; ")}`,
|
|
179
|
+
isError: true,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
effectiveInput = { ...input, paths: partition.kept };
|
|
183
|
+
}
|
|
184
|
+
const built = buildCommitArgvs(effectiveInput);
|
|
185
|
+
if ("error" in built)
|
|
186
|
+
return { content: built.error, isError: true };
|
|
187
|
+
// Through gitlinkSafeAdd: a bare `git add` would run git inside any gitlink
|
|
188
|
+
// the paths cover, under that nested repo's own config (#2210).
|
|
189
|
+
const pathspecs = built.add.slice(built.add.indexOf("--") + 1);
|
|
190
|
+
const staged = await gitlinkSafeAdd(gitWithTimeout, ctx.root, { pathspecs, timeoutMs: 30_000 });
|
|
191
|
+
if (staged.exitCode !== 0) {
|
|
192
|
+
return { content: `git add failed: ${staged.stderr.trim() || `exit ${staged.exitCode}`}`, isError: true };
|
|
193
|
+
}
|
|
194
|
+
// The agent chooses the paths, so it can make the add a no-op; a commit with
|
|
195
|
+
// nothing staged would print status, which can recurse into a gitlink (#2210).
|
|
196
|
+
const hasStaged = await hasStagedChanges(gitWithTimeout, ctx.root, 30_000);
|
|
197
|
+
if (hasStaged !== true) {
|
|
198
|
+
const why = hasStaged === false ? "nothing is staged" : "could not tell whether anything is staged";
|
|
199
|
+
return { content: `git commit not run: ${why}`, isError: true };
|
|
200
|
+
}
|
|
201
|
+
const committed = await gitWithTimeout(built.commit, ctx.root, 30_000);
|
|
202
|
+
if (committed.exitCode !== 0) {
|
|
203
|
+
return {
|
|
204
|
+
content: `git commit failed: ${committed.stderr.trim() || `exit ${committed.exitCode}`}`,
|
|
205
|
+
isError: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const notes = [];
|
|
209
|
+
if (skipped.length > 0) {
|
|
210
|
+
notes.push(`[nax] Skipped ${skipped.length} nax-owned run artifact(s) -- not staged: ${skipped.join(", ")}`);
|
|
211
|
+
}
|
|
212
|
+
if (unknown.length > 0) {
|
|
213
|
+
notes.push(`[nax] REFUSED to stage ${unknown.length} path(s) with an unresolved ignore status (fail-closed): ${unknown
|
|
214
|
+
.map((u) => `${u.path} (${u.reason})`)
|
|
215
|
+
.join("; ")}`);
|
|
216
|
+
}
|
|
217
|
+
const skipNote = notes.length > 0 ? `\n\n${notes.join("\n")}` : "";
|
|
218
|
+
return { content: committed.stdout.trim().slice(0, ctx.maxBytes) + skipNote };
|
|
219
|
+
},
|
|
220
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git global options nax refuses to let any caller introduce.
|
|
3
|
+
*
|
|
4
|
+
* A leaf module with NO imports, deliberately. `src/tools/git.ts` imports
|
|
5
|
+
* `@/utils/git`, so anything `src/utils/git.ts` reaches must not lead back to
|
|
6
|
+
* `src/tools/git.ts` — see check-import-cycles (baseline 0).
|
|
7
|
+
*
|
|
8
|
+
* `-c` is here because `-c core.pager=<cmd>` is arbitrary code execution.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GIT_ESCAPE_FLAGS: readonly string[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git global options nax refuses to let any caller introduce.
|
|
3
|
+
*
|
|
4
|
+
* A leaf module with NO imports, deliberately. `src/tools/git.ts` imports
|
|
5
|
+
* `@/utils/git`, so anything `src/utils/git.ts` reaches must not lead back to
|
|
6
|
+
* `src/tools/git.ts` — see check-import-cycles (baseline 0).
|
|
7
|
+
*
|
|
8
|
+
* `-c` is here because `-c core.pager=<cmd>` is arbitrary code execution.
|
|
9
|
+
*/
|
|
10
|
+
export const GIT_ESCAPE_FLAGS = ["-C", "--git-dir", "--work-tree", "--exec-path", "-c"];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only git, for reviewers that need a real diff rather than one pushed
|
|
3
|
+
* into the prompt.
|
|
4
|
+
*
|
|
5
|
+
* This spawns a subprocess, which ADR-029 section 3 severed for Bash. The
|
|
6
|
+
* distinction, written down rather than assumed: git is a FIXED binary invoked
|
|
7
|
+
* with an argv nax constructs entirely, with no shell. The model supplies
|
|
8
|
+
* structure — a subcommand, refs, pathspecs — never a command string. Bash
|
|
9
|
+
* inverts that, which is why it needs a sandbox and a threat model instead of
|
|
10
|
+
* an allowlist.
|
|
11
|
+
*
|
|
12
|
+
* Reuses gitWithTimeout, which already provides the argv-array spawn, the
|
|
13
|
+
* explicit cwd, the SIGKILL timeout, and concurrent pipe draining — the last of
|
|
14
|
+
* which matters here because `git log -p` is exactly the output that fills a
|
|
15
|
+
* 64KB pipe buffer and deadlocks a naive implementation.
|
|
16
|
+
*/
|
|
17
|
+
import type { CodingTool } from "./registry.ts";
|
|
18
|
+
/**
|
|
19
|
+
* Read-only verbs. Mutating verbs are not representable in the input type.
|
|
20
|
+
*
|
|
21
|
+
* Note what bounds these: the argv shape below, not the verb list. A read-only
|
|
22
|
+
* verb still spans the whole repository unless its scope is stated.
|
|
23
|
+
*/
|
|
24
|
+
export declare const GIT_READ_VERBS: readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* Typed flag fields, and the verbs each one is valid on.
|
|
27
|
+
*
|
|
28
|
+
* nax emits every one of these flags itself: a boolean or a closed enum comes
|
|
29
|
+
* in, a fixed string goes out. The model never supplies flag text, so the
|
|
30
|
+
* property the header comment defends — the model supplies structure, nax
|
|
31
|
+
* constructs the argv — is unchanged by their existence. That is the whole
|
|
32
|
+
* reason they are typed fields rather than a passthrough list.
|
|
33
|
+
*
|
|
34
|
+
* They exist because `git diff --name-only --diff-filter=A` is step 1 of the
|
|
35
|
+
* adversarial reviewer's test-audit workflow and was not expressible at all:
|
|
36
|
+
* the only way to ask for it was to put the flags in `refs`/`paths`, where
|
|
37
|
+
* `looksLikeFlag` refuses them (#1818). A field is gated to the verbs it
|
|
38
|
+
* applies to so a wrong pairing is a nax error the model can act on, rather
|
|
39
|
+
* than a git usage error it has to interpret.
|
|
40
|
+
*/
|
|
41
|
+
export declare const GIT_DIFF_FILTERS: readonly string[];
|
|
42
|
+
/**
|
|
43
|
+
* Commit bound applied to a `log` that does not supply its own.
|
|
44
|
+
*
|
|
45
|
+
* `log` was the one read verb with no bound on how much it returns: a pathspec
|
|
46
|
+
* selects WHICH commits to show, then each selected commit prints in full. With
|
|
47
|
+
* `nameOnly` that compounds, because `--name-only` lists every file in each
|
|
48
|
+
* matching commit rather than the path that selected it -- nax#2009 measured
|
|
49
|
+
* 79KB from 7 commits on a single-file pathspec, the largest call in a
|
|
50
|
+
* 267-call session.
|
|
51
|
+
*
|
|
52
|
+
* Applied ONLY to a `log` that names no `refs`. A ref range is a scope the
|
|
53
|
+
* caller already chose, and capping on top of it discards commits they asked
|
|
54
|
+
* for with no marker. A commit cap appends nothing, so the model cannot tell
|
|
55
|
+
* 12 commits from 200-capped-to-20. The reviewer prompt asks for a story's
|
|
56
|
+
* history as `log <ref>..HEAD --oneline`
|
|
57
|
+
* (`src/prompts/sections/protocol-region.ts`), and `--max-count` keeps the
|
|
58
|
+
* NEWEST n -- a default there would have silently dropped the initial
|
|
59
|
+
* implementation commits. An unscoped `log` walks the whole history of HEAD
|
|
60
|
+
* and is the shape with no bound at all.
|
|
61
|
+
*/
|
|
62
|
+
export declare const DEFAULT_LOG_MAX_COUNT = 20;
|
|
63
|
+
/**
|
|
64
|
+
* Compact commit rendering for `log`.
|
|
65
|
+
*
|
|
66
|
+
* `format:` rather than `tformat:` or the bare form: it places the separator
|
|
67
|
+
* BETWEEN commits, so each --name-only file list stays grouped with the commit
|
|
68
|
+
* that produced it instead of being orphaned after a blank line. Observed
|
|
69
|
+
* against a real repo, `format:%h %ad %s --name-only` renders the file list on
|
|
70
|
+
* the line directly after its commit's header; `tformat:` (which is what a bare
|
|
71
|
+
* `--format=` means) leaves a blank line between the two.
|
|
72
|
+
*
|
|
73
|
+
* `--date=short` pairs with it: `%ad` renders in whatever form `--date`
|
|
74
|
+
* selects, and the default is the raw commit timestamp
|
|
75
|
+
* (`Thu Apr 7 15:13:13 2005 -0700`) -- more noise than the compact line is
|
|
76
|
+
* meant to carry. (`%ai`/`%as` would be the ISO-8601 spellings; neither is
|
|
77
|
+
* used here.)
|
|
78
|
+
*/
|
|
79
|
+
export declare const DEFAULT_LOG_FORMAT = "format:%h %ad %s";
|
|
80
|
+
export { GIT_ESCAPE_FLAGS } from "#src/tools/git-flags/index";
|
|
81
|
+
/**
|
|
82
|
+
* `defaultExcludes`: pathspecs appended to an unscoped call (the host's own
|
|
83
|
+
* state, nax#2007); none by default.
|
|
84
|
+
*/
|
|
85
|
+
export declare function buildGitArgv(input: Record<string, unknown>, defaultExcludes?: readonly string[]): string[] | {
|
|
86
|
+
error: string;
|
|
87
|
+
};
|
|
88
|
+
export declare const gitTool: CodingTool;
|