@lannguyensi/harness 0.64.0 → 1.0.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 +64 -0
- package/README.md +46 -42
- package/dist/cli/add/index.js +17 -21
- package/dist/cli/add/index.js.map +1 -1
- package/dist/cli/adopt/derive.d.ts +2 -2
- package/dist/cli/adopt/derive.js +2 -19
- package/dist/cli/adopt/derive.js.map +1 -1
- package/dist/cli/adopt/index.d.ts +1 -1
- package/dist/cli/adopt/index.js +1 -12
- package/dist/cli/adopt/index.js.map +1 -1
- package/dist/cli/apply/apply.d.ts +20 -35
- package/dist/cli/apply/apply.js +61 -136
- package/dist/cli/apply/apply.js.map +1 -1
- package/dist/cli/apply/generate-codex-config.js +10 -58
- package/dist/cli/apply/generate-codex-config.js.map +1 -1
- package/dist/cli/apply/generate-memory-index.js +1 -2
- package/dist/cli/apply/generate-memory-index.js.map +1 -1
- package/dist/cli/apply/generate-opencode-config.d.ts +2 -10
- package/dist/cli/apply/generate-opencode-config.js +74 -113
- package/dist/cli/apply/generate-opencode-config.js.map +1 -1
- package/dist/cli/apply/generate-settings.d.ts +11 -64
- package/dist/cli/apply/generate-settings.js +27 -132
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/apply/index.d.ts +1 -1
- package/dist/cli/apply/index.js +1 -1
- package/dist/cli/apply/index.js.map +1 -1
- package/dist/cli/apply/install-codex-config.d.ts +153 -1
- package/dist/cli/apply/install-codex-config.js +445 -70
- package/dist/cli/apply/install-codex-config.js.map +1 -1
- package/dist/cli/apply/next-steps.d.ts +7 -0
- package/dist/cli/apply/next-steps.js +13 -1
- package/dist/cli/apply/next-steps.js.map +1 -1
- package/dist/cli/bounded-stdin.d.ts +0 -23
- package/dist/cli/bounded-stdin.js +2 -49
- package/dist/cli/bounded-stdin.js.map +1 -1
- package/dist/cli/describe.d.ts +1 -1
- package/dist/cli/describe.js +0 -3
- package/dist/cli/describe.js.map +1 -1
- package/dist/cli/diff/engine.d.ts +0 -11
- package/dist/cli/diff/engine.js +1 -17
- package/dist/cli/diff/engine.js.map +1 -1
- package/dist/cli/diff/index.js +14 -25
- package/dist/cli/diff/index.js.map +1 -1
- package/dist/cli/doctor/claude-mcp.d.ts +4 -19
- package/dist/cli/doctor/claude-mcp.js +11 -22
- package/dist/cli/doctor/claude-mcp.js.map +1 -1
- package/dist/cli/doctor/codex.d.ts +12 -14
- package/dist/cli/doctor/codex.js +31 -144
- package/dist/cli/doctor/codex.js.map +1 -1
- package/dist/cli/doctor/format.js +23 -345
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/hook-liveness.d.ts +56 -0
- package/dist/cli/doctor/hook-liveness.js +455 -0
- package/dist/cli/doctor/hook-liveness.js.map +1 -0
- package/dist/cli/doctor/index.d.ts +13 -87
- package/dist/cli/doctor/index.js +57 -713
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/opencode.d.ts +2 -1
- package/dist/cli/doctor/opencode.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +21 -387
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/drain-stdio.d.ts +31 -0
- package/dist/cli/drain-stdio.js +76 -0
- package/dist/cli/drain-stdio.js.map +1 -0
- package/dist/cli/export.d.ts +3 -1
- package/dist/cli/export.js +7 -16
- package/dist/cli/export.js.map +1 -1
- package/dist/cli/gate/codex-disable.d.ts +29 -0
- package/dist/cli/gate/codex-disable.js +195 -0
- package/dist/cli/gate/codex-disable.js.map +1 -0
- package/dist/cli/gate/codex-enable.d.ts +41 -0
- package/dist/cli/gate/codex-enable.js +127 -0
- package/dist/cli/gate/codex-enable.js.map +1 -0
- package/dist/cli/gate/codex-snapshot.d.ts +208 -0
- package/dist/cli/gate/codex-snapshot.js +402 -0
- package/dist/cli/gate/codex-snapshot.js.map +1 -0
- package/dist/cli/gate/disable.d.ts +9 -0
- package/dist/cli/gate/disable.js +263 -28
- package/dist/cli/gate/disable.js.map +1 -1
- package/dist/cli/gate/enable.d.ts +26 -6
- package/dist/cli/gate/enable.js +152 -80
- package/dist/cli/gate/enable.js.map +1 -1
- package/dist/cli/gate/link-chain.d.ts +53 -0
- package/dist/cli/gate/link-chain.js +122 -0
- package/dist/cli/gate/link-chain.js.map +1 -0
- package/dist/cli/gate/snapshot.d.ts +289 -12
- package/dist/cli/gate/snapshot.js +481 -22
- package/dist/cli/gate/snapshot.js.map +1 -1
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/index.js +9 -2131
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/composer.d.ts +3 -6
- package/dist/cli/init/composer.js +6 -370
- package/dist/cli/init/composer.js.map +1 -1
- package/dist/cli/init/dependencies.d.ts +1 -2
- package/dist/cli/init/dependencies.js +4 -80
- package/dist/cli/init/dependencies.js.map +1 -1
- package/dist/cli/init/detect.js +5 -4
- package/dist/cli/init/detect.js.map +1 -1
- package/dist/cli/init/interactive.d.ts +1 -23
- package/dist/cli/init/interactive.js +33 -247
- package/dist/cli/init/interactive.js.map +1 -1
- package/dist/cli/init/profiles.d.ts +2 -2
- package/dist/cli/init/profiles.js +51 -245
- package/dist/cli/init/profiles.js.map +1 -1
- package/dist/cli/init/templates.d.ts +2 -37
- package/dist/cli/init/templates.js +25 -1237
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/list.d.ts +1 -1
- package/dist/cli/list.js +1 -38
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/loader.d.ts +15 -1
- package/dist/cli/loader.js +56 -39
- package/dist/cli/loader.js.map +1 -1
- package/dist/cli/main.js +7 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/migrate-home/index.js +2 -2
- package/dist/cli/migrate-home/index.js.map +1 -1
- package/dist/cli/pack/add.js +1 -1
- package/dist/cli/pack/add.js.map +1 -1
- package/dist/cli/pack/hook-bootstrap.d.ts +5 -164
- package/dist/cli/pack/hook-bootstrap.js +15 -291
- package/dist/cli/pack/hook-bootstrap.js.map +1 -1
- package/dist/cli/pack/hook-branch-protection.d.ts +28 -21
- package/dist/cli/pack/hook-branch-protection.js +365 -340
- package/dist/cli/pack/hook-branch-protection.js.map +1 -1
- package/dist/cli/pack/index.d.ts +0 -1
- package/dist/cli/pack/index.js +0 -1
- package/dist/cli/pack/index.js.map +1 -1
- package/dist/cli/pack/list.js +1 -6
- package/dist/cli/pack/list.js.map +1 -1
- package/dist/cli/pack/mutate.d.ts +7 -9
- package/dist/cli/pack/mutate.js +6 -9
- package/dist/cli/pack/mutate.js.map +1 -1
- package/dist/cli/pack/reseed.d.ts +2 -2
- package/dist/cli/pack/reseed.js +16 -22
- package/dist/cli/pack/reseed.js.map +1 -1
- package/dist/cli/{delegate/register.d.ts → register-gate-group.d.ts} +1 -1
- package/dist/cli/register-gate-group.js +348 -0
- package/dist/cli/register-gate-group.js.map +1 -0
- package/dist/cli/register-inspect-group.d.ts +6 -0
- package/dist/cli/register-inspect-group.js +189 -0
- package/dist/cli/register-inspect-group.js.map +1 -0
- package/dist/cli/register-operator-lifecycle.d.ts +1 -1
- package/dist/cli/register-operator-lifecycle.js +3 -100
- package/dist/cli/register-operator-lifecycle.js.map +1 -1
- package/dist/cli/register-pack-group.d.ts +5 -0
- package/dist/cli/register-pack-group.js +134 -0
- package/dist/cli/register-pack-group.js.map +1 -0
- package/dist/cli/{register-audit-group.d.ts → register-setup-group.d.ts} +1 -1
- package/dist/cli/register-setup-group.js +495 -0
- package/dist/cli/register-setup-group.js.map +1 -0
- package/dist/cli/remove/index.d.ts +0 -14
- package/dist/cli/remove/index.js +2 -115
- package/dist/cli/remove/index.js.map +1 -1
- package/dist/cli/remove/mutate.d.ts +0 -2
- package/dist/cli/remove/mutate.js +1 -19
- package/dist/cli/remove/mutate.js.map +1 -1
- package/dist/cli/remove/register.js +2 -19
- package/dist/cli/remove/register.js.map +1 -1
- package/dist/cli/shell-quote.d.ts +7 -0
- package/dist/cli/shell-quote.js +17 -0
- package/dist/cli/shell-quote.js.map +1 -0
- package/dist/cli/uninstall/index.d.ts +4 -2
- package/dist/cli/uninstall/index.js +15 -7
- package/dist/cli/uninstall/index.js.map +1 -1
- package/dist/cli/uninstall/register.js +6 -4
- package/dist/cli/uninstall/register.js.map +1 -1
- package/dist/cli/uninstall/snapshot.d.ts +15 -0
- package/dist/cli/uninstall/snapshot.js +38 -0
- package/dist/cli/uninstall/snapshot.js.map +1 -1
- package/dist/cli/validate/checks.d.ts +0 -77
- package/dist/cli/validate/checks.js +3 -1049
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/cli/validate/index.js +19 -15
- package/dist/cli/validate/index.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/io/claude-mcp.d.ts +1 -1
- package/dist/io/claude-mcp.js +27 -14
- package/dist/io/claude-mcp.js.map +1 -1
- package/dist/io/harness-lock.js +2 -2
- package/dist/io/harness-lock.js.map +1 -1
- package/dist/io/lock.d.ts +0 -26
- package/dist/io/lock.js +10 -27
- package/dist/io/lock.js.map +1 -1
- package/dist/io/merge-settings.js +6 -4
- package/dist/io/merge-settings.js.map +1 -1
- package/dist/io/project-name.d.ts +22 -39
- package/dist/io/project-name.js +25 -42
- package/dist/io/project-name.js.map +1 -1
- package/dist/io/read-regular-file.d.ts +103 -40
- package/dist/io/read-regular-file.js +196 -35
- package/dist/io/read-regular-file.js.map +1 -1
- package/dist/io/restart-hints.js +3 -6
- package/dist/io/restart-hints.js.map +1 -1
- package/dist/io/version-compare.d.ts +1 -3
- package/dist/io/version-compare.js +1 -3
- package/dist/io/version-compare.js.map +1 -1
- package/dist/io/write-regular-file.d.ts +30 -0
- package/dist/io/write-regular-file.js +85 -0
- package/dist/io/write-regular-file.js.map +1 -0
- package/dist/overrides/index.d.ts +1 -0
- package/dist/overrides/index.js +1 -0
- package/dist/overrides/index.js.map +1 -1
- package/dist/overrides/merge-layers.d.ts +43 -0
- package/dist/overrides/merge-layers.js +76 -0
- package/dist/overrides/merge-layers.js.map +1 -0
- package/dist/overrides/merge.d.ts +16 -0
- package/dist/overrides/merge.js +21 -8
- package/dist/overrides/merge.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -69
- package/dist/policy-packs/builtin/branch-protection-runtime.js +12 -84
- package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection.d.ts +7 -30
- package/dist/policy-packs/builtin/branch-protection.js +56 -89
- package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
- package/dist/policy-packs/config-check.d.ts +7 -5
- package/dist/policy-packs/config-check.js +2 -2
- package/dist/policy-packs/config-check.js.map +1 -1
- package/dist/policy-packs/expand.d.ts +1 -3
- package/dist/policy-packs/expand.js +5 -42
- package/dist/policy-packs/expand.js.map +1 -1
- package/dist/policy-packs/index.d.ts +3 -3
- package/dist/policy-packs/index.js +2 -2
- package/dist/policy-packs/index.js.map +1 -1
- package/dist/policy-packs/registry.d.ts +9 -38
- package/dist/policy-packs/registry.js +5 -65
- package/dist/policy-packs/registry.js.map +1 -1
- package/dist/policy-packs/runtime.d.ts +0 -4
- package/dist/policy-packs/runtime.js +9 -22
- package/dist/policy-packs/runtime.js.map +1 -1
- package/dist/policy-packs/types.d.ts +0 -19
- package/dist/policy-packs/ux-compare.d.ts +1 -11
- package/dist/policy-packs/ux-compare.js +6 -42
- package/dist/policy-packs/ux-compare.js.map +1 -1
- package/dist/policy-packs/ux-drift-check.d.ts +5 -5
- package/dist/policy-packs/ux-drift-check.js +17 -22
- package/dist/policy-packs/ux-drift-check.js.map +1 -1
- package/dist/policy-packs/version-check.d.ts +5 -26
- package/dist/policy-packs/version-check.js +19 -74
- package/dist/policy-packs/version-check.js.map +1 -1
- package/dist/probes/memory.d.ts +1 -1
- package/dist/probes/memory.js +1 -1
- package/dist/probes/memory.js.map +1 -1
- package/dist/runtime/agent-facing.d.ts +9 -0
- package/dist/runtime/agent-facing.js +28 -14
- package/dist/runtime/agent-facing.js.map +1 -1
- package/dist/runtime/bounded-text.d.ts +15 -0
- package/dist/runtime/bounded-text.js +27 -0
- package/dist/runtime/bounded-text.js.map +1 -0
- package/dist/runtime/git-branch.d.ts +125 -0
- package/dist/runtime/git-branch.js +381 -0
- package/dist/runtime/git-branch.js.map +1 -0
- package/dist/runtime/hermetic-spawn-guard.d.ts +2 -2
- package/dist/runtime/hermetic-spawn-guard.js +24 -34
- package/dist/runtime/hermetic-spawn-guard.js.map +1 -1
- package/dist/runtime/home-dir.js +3 -2
- package/dist/runtime/home-dir.js.map +1 -1
- package/dist/runtime/tool-name-aliases.d.ts +0 -6
- package/dist/runtime/tool-name-aliases.js +5 -18
- package/dist/runtime/tool-name-aliases.js.map +1 -1
- package/dist/schema/grounding.d.ts +7 -54
- package/dist/schema/grounding.js +10 -12
- package/dist/schema/grounding.js.map +1 -1
- package/dist/schema/hooks.d.ts +39 -136
- package/dist/schema/hooks.js +3 -6
- package/dist/schema/hooks.js.map +1 -1
- package/dist/schema/index.d.ts +114 -3828
- package/dist/schema/index.js +41 -80
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/memory.d.ts +54 -131
- package/dist/schema/memory.js +2 -2
- package/dist/schema/memory.js.map +1 -1
- package/dist/schema/policy-packs.d.ts +3 -45
- package/dist/schema/policy-packs.js +7 -13
- package/dist/schema/policy-packs.js.map +1 -1
- package/dist/schema/policy-ux.d.ts +7 -0
- package/dist/schema/policy-ux.js +18 -0
- package/dist/schema/policy-ux.js.map +1 -0
- package/dist/schema/removed-keys.d.ts +185 -0
- package/dist/schema/removed-keys.js +531 -0
- package/dist/schema/removed-keys.js.map +1 -0
- package/dist/schema/tools.d.ts +30 -268
- package/dist/schema/tools.js +4 -4
- package/dist/schema/tools.js.map +1 -1
- package/package.json +5 -16
- package/dist/cli/approve/branch-protection.d.ts +0 -69
- package/dist/cli/approve/branch-protection.js +0 -144
- package/dist/cli/approve/branch-protection.js.map +0 -1
- package/dist/cli/approve/risk.d.ts +0 -112
- package/dist/cli/approve/risk.js +0 -197
- package/dist/cli/approve/risk.js.map +0 -1
- package/dist/cli/approve/stdin-report.d.ts +0 -57
- package/dist/cli/approve/stdin-report.js +0 -145
- package/dist/cli/approve/stdin-report.js.map +0 -1
- package/dist/cli/approve/understanding.d.ts +0 -410
- package/dist/cli/approve/understanding.js +0 -996
- package/dist/cli/approve/understanding.js.map +0 -1
- package/dist/cli/audit.d.ts +0 -80
- package/dist/cli/audit.js +0 -252
- package/dist/cli/audit.js.map +0 -1
- package/dist/cli/delegate/index.d.ts +0 -76
- package/dist/cli/delegate/index.js +0 -444
- package/dist/cli/delegate/index.js.map +0 -1
- package/dist/cli/delegate/register.js +0 -90
- package/dist/cli/delegate/register.js.map +0 -1
- package/dist/cli/doctor/auto-approve-mode.d.ts +0 -37
- package/dist/cli/doctor/auto-approve-mode.js +0 -80
- package/dist/cli/doctor/auto-approve-mode.js.map +0 -1
- package/dist/cli/doctor/bypass-without-auto-approve.d.ts +0 -38
- package/dist/cli/doctor/bypass-without-auto-approve.js +0 -95
- package/dist/cli/doctor/bypass-without-auto-approve.js.map +0 -1
- package/dist/cli/doctor/codex-config-drift.d.ts +0 -28
- package/dist/cli/doctor/codex-config-drift.js +0 -240
- package/dist/cli/doctor/codex-config-drift.js.map +0 -1
- package/dist/cli/doctor/expire-on-tool-match.d.ts +0 -15
- package/dist/cli/doctor/expire-on-tool-match.js +0 -58
- package/dist/cli/doctor/expire-on-tool-match.js.map +0 -1
- package/dist/cli/doctor/rogue-ledger.d.ts +0 -53
- package/dist/cli/doctor/rogue-ledger.js +0 -153
- package/dist/cli/doctor/rogue-ledger.js.map +0 -1
- package/dist/cli/doctor/session-start-preflight-setup-version.d.ts +0 -83
- package/dist/cli/doctor/session-start-preflight-setup-version.js +0 -114
- package/dist/cli/doctor/session-start-preflight-setup-version.js.map +0 -1
- package/dist/cli/doctor/settings-drift.d.ts +0 -25
- package/dist/cli/doctor/settings-drift.js +0 -213
- package/dist/cli/doctor/settings-drift.js.map +0 -1
- package/dist/cli/doctor/toolchain-parity.d.ts +0 -63
- package/dist/cli/doctor/toolchain-parity.js +0 -154
- package/dist/cli/doctor/toolchain-parity.js.map +0 -1
- package/dist/cli/doctor/ug-auto-approvals.d.ts +0 -40
- package/dist/cli/doctor/ug-auto-approvals.js +0 -91
- package/dist/cli/doctor/ug-auto-approvals.js.map +0 -1
- package/dist/cli/doctor/ug-delegations.d.ts +0 -26
- package/dist/cli/doctor/ug-delegations.js +0 -121
- package/dist/cli/doctor/ug-delegations.js.map +0 -1
- package/dist/cli/doctor/ug-inflight.d.ts +0 -35
- package/dist/cli/doctor/ug-inflight.js +0 -57
- package/dist/cli/doctor/ug-inflight.js.map +0 -1
- package/dist/cli/doctor/understanding-mode-env.d.ts +0 -51
- package/dist/cli/doctor/understanding-mode-env.js +0 -98
- package/dist/cli/doctor/understanding-mode-env.js.map +0 -1
- package/dist/cli/dry-run.d.ts +0 -58
- package/dist/cli/dry-run.js +0 -283
- package/dist/cli/dry-run.js.map +0 -1
- package/dist/cli/enriched-event.d.ts +0 -35
- package/dist/cli/enriched-event.js +0 -60
- package/dist/cli/enriched-event.js.map +0 -1
- package/dist/cli/event-input.d.ts +0 -28
- package/dist/cli/event-input.js +0 -73
- package/dist/cli/event-input.js.map +0 -1
- package/dist/cli/explain-action.d.ts +0 -25
- package/dist/cli/explain-action.js +0 -57
- package/dist/cli/explain-action.js.map +0 -1
- package/dist/cli/explain-policy.d.ts +0 -147
- package/dist/cli/explain-policy.js +0 -248
- package/dist/cli/explain-policy.js.map +0 -1
- package/dist/cli/explain.d.ts +0 -31
- package/dist/cli/explain.js +0 -159
- package/dist/cli/explain.js.map +0 -1
- package/dist/cli/gc/index.d.ts +0 -63
- package/dist/cli/gc/index.js +0 -566
- package/dist/cli/gc/index.js.map +0 -1
- package/dist/cli/pack/approve-escape.d.ts +0 -19
- package/dist/cli/pack/approve-escape.js +0 -190
- package/dist/cli/pack/approve-escape.js.map +0 -1
- package/dist/cli/pack/auto-approve-path.d.ts +0 -146
- package/dist/cli/pack/auto-approve-path.js +0 -462
- package/dist/cli/pack/auto-approve-path.js.map +0 -1
- package/dist/cli/pack/hook-codex-post-tool-use.d.ts +0 -25
- package/dist/cli/pack/hook-codex-post-tool-use.js +0 -160
- package/dist/cli/pack/hook-codex-post-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +0 -48
- package/dist/cli/pack/hook-codex-pre-tool-use.js +0 -474
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-codex-stop.d.ts +0 -35
- package/dist/cli/pack/hook-codex-stop.js +0 -329
- package/dist/cli/pack/hook-codex-stop.js.map +0 -1
- package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +0 -24
- package/dist/cli/pack/hook-codex-user-prompt-submit.js +0 -93
- package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +0 -1
- package/dist/cli/pack/hook-post-merge-gate-record.d.ts +0 -37
- package/dist/cli/pack/hook-post-merge-gate-record.js +0 -190
- package/dist/cli/pack/hook-post-merge-gate-record.js.map +0 -1
- package/dist/cli/pack/hook-post-merge-gate.d.ts +0 -34
- package/dist/cli/pack/hook-post-merge-gate.js +0 -277
- package/dist/cli/pack/hook-post-merge-gate.js.map +0 -1
- package/dist/cli/pack/hook-post-tool-use.d.ts +0 -45
- package/dist/cli/pack/hook-post-tool-use.js +0 -137
- package/dist/cli/pack/hook-post-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-pre-tool-use.d.ts +0 -92
- package/dist/cli/pack/hook-pre-tool-use.js +0 -1328
- package/dist/cli/pack/hook-pre-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-runtime-reality.d.ts +0 -63
- package/dist/cli/pack/hook-runtime-reality.js +0 -210
- package/dist/cli/pack/hook-runtime-reality.js.map +0 -1
- package/dist/cli/pack/hook-solution-acceptance-writeguard.d.ts +0 -32
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js +0 -438
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +0 -1
- package/dist/cli/pack/hook-solution-acceptance.d.ts +0 -157
- package/dist/cli/pack/hook-solution-acceptance.js +0 -530
- package/dist/cli/pack/hook-solution-acceptance.js.map +0 -1
- package/dist/cli/pack/hook-stay-in-scope.d.ts +0 -37
- package/dist/cli/pack/hook-stay-in-scope.js +0 -128
- package/dist/cli/pack/hook-stay-in-scope.js.map +0 -1
- package/dist/cli/pack/hook-subagent-start.d.ts +0 -23
- package/dist/cli/pack/hook-subagent-start.js +0 -88
- package/dist/cli/pack/hook-subagent-start.js.map +0 -1
- package/dist/cli/pack/hook-subagent-stop.d.ts +0 -19
- package/dist/cli/pack/hook-subagent-stop.js +0 -41
- package/dist/cli/pack/hook-subagent-stop.js.map +0 -1
- package/dist/cli/pack/hook-track-active-claim.d.ts +0 -27
- package/dist/cli/pack/hook-track-active-claim.js +0 -275
- package/dist/cli/pack/hook-track-active-claim.js.map +0 -1
- package/dist/cli/pack/transcript-report-scan.d.ts +0 -71
- package/dist/cli/pack/transcript-report-scan.js +0 -359
- package/dist/cli/pack/transcript-report-scan.js.map +0 -1
- package/dist/cli/pack/understanding-report-schema-hint.d.ts +0 -26
- package/dist/cli/pack/understanding-report-schema-hint.js +0 -120
- package/dist/cli/pack/understanding-report-schema-hint.js.map +0 -1
- package/dist/cli/pack/upgrade.d.ts +0 -32
- package/dist/cli/pack/upgrade.js +0 -273
- package/dist/cli/pack/upgrade.js.map +0 -1
- package/dist/cli/pause/index.d.ts +0 -113
- package/dist/cli/pause/index.js +0 -251
- package/dist/cli/pause/index.js.map +0 -1
- package/dist/cli/pause-check.d.ts +0 -22
- package/dist/cli/pause-check.js +0 -54
- package/dist/cli/pause-check.js.map +0 -1
- package/dist/cli/policy/intercept.d.ts +0 -233
- package/dist/cli/policy/intercept.js +0 -1022
- package/dist/cli/policy/intercept.js.map +0 -1
- package/dist/cli/policy/risk-envelope-enrichment.d.ts +0 -40
- package/dist/cli/policy/risk-envelope-enrichment.js +0 -110
- package/dist/cli/policy/risk-envelope-enrichment.js.map +0 -1
- package/dist/cli/record/index.d.ts +0 -81
- package/dist/cli/record/index.js +0 -348
- package/dist/cli/record/index.js.map +0 -1
- package/dist/cli/register-audit-group.js +0 -91
- package/dist/cli/register-audit-group.js.map +0 -1
- package/dist/cli/resolve-env.d.ts +0 -32
- package/dist/cli/resolve-env.js +0 -46
- package/dist/cli/resolve-env.js.map +0 -1
- package/dist/cli/session-export/index.d.ts +0 -46
- package/dist/cli/session-export/index.js +0 -169
- package/dist/cli/session-export/index.js.map +0 -1
- package/dist/cli/session-export/redact.d.ts +0 -22
- package/dist/cli/session-export/redact.js +0 -47
- package/dist/cli/session-export/redact.js.map +0 -1
- package/dist/cli/session-export/transcript.d.ts +0 -24
- package/dist/cli/session-export/transcript.js +0 -164
- package/dist/cli/session-export/transcript.js.map +0 -1
- package/dist/cli/session-start/branch-check.d.ts +0 -18
- package/dist/cli/session-start/branch-check.js +0 -140
- package/dist/cli/session-start/branch-check.js.map +0 -1
- package/dist/cli/session-start/index.d.ts +0 -121
- package/dist/cli/session-start/index.js +0 -591
- package/dist/cli/session-start/index.js.map +0 -1
- package/dist/cli/session-start/shared-options.d.ts +0 -103
- package/dist/cli/session-start/shared-options.js +0 -107
- package/dist/cli/session-start/shared-options.js.map +0 -1
- package/dist/cli/session-start/stale-base-check.d.ts +0 -46
- package/dist/cli/session-start/stale-base-check.js +0 -352
- package/dist/cli/session-start/stale-base-check.js.map +0 -1
- package/dist/cli/session-start/toolchain-parity.d.ts +0 -267
- package/dist/cli/session-start/toolchain-parity.js +0 -797
- package/dist/cli/session-start/toolchain-parity.js.map +0 -1
- package/dist/cli/smoke/assertions.d.ts +0 -46
- package/dist/cli/smoke/assertions.js +0 -170
- package/dist/cli/smoke/assertions.js.map +0 -1
- package/dist/cli/smoke/index.d.ts +0 -76
- package/dist/cli/smoke/index.js +0 -245
- package/dist/cli/smoke/index.js.map +0 -1
- package/dist/cli/smoke/runner.d.ts +0 -55
- package/dist/cli/smoke/runner.js +0 -134
- package/dist/cli/smoke/runner.js.map +0 -1
- package/dist/cli/smoke/stream-parser.d.ts +0 -65
- package/dist/cli/smoke/stream-parser.js +0 -115
- package/dist/cli/smoke/stream-parser.js.map +0 -1
- package/dist/cli/test-risk.d.ts +0 -27
- package/dist/cli/test-risk.js +0 -38
- package/dist/cli/test-risk.js.map +0 -1
- package/dist/io/display-path.d.ts +0 -11
- package/dist/io/display-path.js +0 -29
- package/dist/io/display-path.js.map +0 -1
- package/dist/io/duration.d.ts +0 -5
- package/dist/io/duration.js +0 -50
- package/dist/io/duration.js.map +0 -1
- package/dist/io/extract.d.ts +0 -79
- package/dist/io/extract.js +0 -226
- package/dist/io/extract.js.map +0 -1
- package/dist/io/ledger-record.d.ts +0 -83
- package/dist/io/ledger-record.js +0 -301
- package/dist/io/ledger-record.js.map +0 -1
- package/dist/io/read-json-dir-entries.d.ts +0 -36
- package/dist/io/read-json-dir-entries.js +0 -48
- package/dist/io/read-json-dir-entries.js.map +0 -1
- package/dist/io/safe-json-parse.d.ts +0 -5
- package/dist/io/safe-json-parse.js +0 -21
- package/dist/io/safe-json-parse.js.map +0 -1
- package/dist/policies/index.d.ts +0 -5
- package/dist/policies/index.js +0 -6
- package/dist/policies/index.js.map +0 -1
- package/dist/policies/ledger-client.d.ts +0 -113
- package/dist/policies/ledger-client.js +0 -500
- package/dist/policies/ledger-client.js.map +0 -1
- package/dist/policies/producers.d.ts +0 -12
- package/dist/policies/producers.js +0 -61
- package/dist/policies/producers.js.map +0 -1
- package/dist/policies/requires.d.ts +0 -75
- package/dist/policies/requires.js +0 -240
- package/dist/policies/requires.js.map +0 -1
- package/dist/policies/timestamp.d.ts +0 -14
- package/dist/policies/timestamp.js +0 -36
- package/dist/policies/timestamp.js.map +0 -1
- package/dist/policy-packs/builtin/permission-profiles.d.ts +0 -11
- package/dist/policy-packs/builtin/permission-profiles.js +0 -74
- package/dist/policy-packs/builtin/permission-profiles.js.map +0 -1
- package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +0 -286
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js +0 -397
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/post-merge-gate.d.ts +0 -56
- package/dist/policy-packs/builtin/post-merge-gate.js +0 -347
- package/dist/policy-packs/builtin/post-merge-gate.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.d.ts +0 -50
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js +0 -151
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance-runtime.d.ts +0 -323
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js +0 -672
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance.d.ts +0 -45
- package/dist/policy-packs/builtin/solution-acceptance.js +0 -226
- package/dist/policy-packs/builtin/solution-acceptance.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.d.ts +0 -25
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js +0 -94
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +0 -35
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +0 -86
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +0 -210
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +0 -361
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +0 -304
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +0 -734
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.d.ts +0 -36
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js +0 -73
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +0 -19
- package/dist/policy-packs/builtin/understanding-before-execution/index.js +0 -83
- package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.d.ts +0 -135
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js +0 -643
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.d.ts +0 -25
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.js +0 -56
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.d.ts +0 -20
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js +0 -106
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/markers.d.ts +0 -126
- package/dist/policy-packs/builtin/understanding-before-execution/markers.js +0 -245
- package/dist/policy-packs/builtin/understanding-before-execution/markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +0 -29
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +0 -82
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +0 -71
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +0 -175
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +0 -625
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +0 -1076
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.d.ts +0 -128
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js +0 -213
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.d.ts +0 -129
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js +0 -166
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.d.ts +0 -164
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js +0 -275
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +0 -10
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +0 -526
- package/dist/policy-packs/builtin/understanding-before-execution.js +0 -1078
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +0 -1
- package/dist/policy-packs/permission-translator.d.ts +0 -9
- package/dist/policy-packs/permission-translator.js +0 -76
- package/dist/policy-packs/permission-translator.js.map +0 -1
- package/dist/runtime/action-envelope.d.ts +0 -64
- package/dist/runtime/action-envelope.js +0 -46
- package/dist/runtime/action-envelope.js.map +0 -1
- package/dist/runtime/approval-signing.d.ts +0 -111
- package/dist/runtime/approval-signing.js +0 -384
- package/dist/runtime/approval-signing.js.map +0 -1
- package/dist/runtime/bash-match-facts.d.ts +0 -60
- package/dist/runtime/bash-match-facts.js +0 -196
- package/dist/runtime/bash-match-facts.js.map +0 -1
- package/dist/runtime/bash-match-registry.d.ts +0 -112
- package/dist/runtime/bash-match-registry.js +0 -406
- package/dist/runtime/bash-match-registry.js.map +0 -1
- package/dist/runtime/bash-prefix-parse.d.ts +0 -31
- package/dist/runtime/bash-prefix-parse.js +0 -576
- package/dist/runtime/bash-prefix-parse.js.map +0 -1
- package/dist/runtime/command-normalize.d.ts +0 -658
- package/dist/runtime/command-normalize.js +0 -2410
- package/dist/runtime/command-normalize.js.map +0 -1
- package/dist/runtime/deletion-target-resolve.d.ts +0 -28
- package/dist/runtime/deletion-target-resolve.js +0 -1078
- package/dist/runtime/deletion-target-resolve.js.map +0 -1
- package/dist/runtime/destructive-shell-floor.d.ts +0 -19
- package/dist/runtime/destructive-shell-floor.js +0 -611
- package/dist/runtime/destructive-shell-floor.js.map +0 -1
- package/dist/runtime/environment-resolver.d.ts +0 -36
- package/dist/runtime/environment-resolver.js +0 -138
- package/dist/runtime/environment-resolver.js.map +0 -1
- package/dist/runtime/git-context.d.ts +0 -201
- package/dist/runtime/git-context.js +0 -422
- package/dist/runtime/git-context.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -12
- package/dist/runtime/index.js +0 -13
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/intercept.d.ts +0 -623
- package/dist/runtime/intercept.js +0 -1384
- package/dist/runtime/intercept.js.map +0 -1
- package/dist/runtime/kube-context.d.ts +0 -16
- package/dist/runtime/kube-context.js +0 -63
- package/dist/runtime/kube-context.js.map +0 -1
- package/dist/runtime/kubectl-target-parse.d.ts +0 -31
- package/dist/runtime/kubectl-target-parse.js +0 -249
- package/dist/runtime/kubectl-target-parse.js.map +0 -1
- package/dist/runtime/ledger-add.d.ts +0 -16
- package/dist/runtime/ledger-add.js +0 -150
- package/dist/runtime/ledger-add.js.map +0 -1
- package/dist/runtime/ledger-writer.d.ts +0 -27
- package/dist/runtime/ledger-writer.js +0 -46
- package/dist/runtime/ledger-writer.js.map +0 -1
- package/dist/runtime/pause-sentinel.d.ts +0 -60
- package/dist/runtime/pause-sentinel.js +0 -156
- package/dist/runtime/pause-sentinel.js.map +0 -1
- package/dist/runtime/pending-approval.d.ts +0 -23
- package/dist/runtime/pending-approval.js +0 -67
- package/dist/runtime/pending-approval.js.map +0 -1
- package/dist/runtime/read-only-bash.d.ts +0 -141
- package/dist/runtime/read-only-bash.js +0 -2204
- package/dist/runtime/read-only-bash.js.map +0 -1
- package/dist/runtime/recovery-git-commit.d.ts +0 -22
- package/dist/runtime/recovery-git-commit.js +0 -284
- package/dist/runtime/recovery-git-commit.js.map +0 -1
- package/dist/runtime/reject-malformed-session-id.d.ts +0 -8
- package/dist/runtime/reject-malformed-session-id.js +0 -16
- package/dist/runtime/reject-malformed-session-id.js.map +0 -1
- package/dist/runtime/risk-classifier.d.ts +0 -38
- package/dist/runtime/risk-classifier.js +0 -311
- package/dist/runtime/risk-classifier.js.map +0 -1
- package/dist/runtime/session-id.d.ts +0 -113
- package/dist/runtime/session-id.js +0 -193
- package/dist/runtime/session-id.js.map +0 -1
- package/dist/runtime/shell-word.d.ts +0 -62
- package/dist/runtime/shell-word.js +0 -410
- package/dist/runtime/shell-word.js.map +0 -1
- package/dist/runtime/task-providers/agent-tasks.d.ts +0 -105
- package/dist/runtime/task-providers/agent-tasks.js +0 -247
- package/dist/runtime/task-providers/agent-tasks.js.map +0 -1
- package/dist/runtime/when-eval.d.ts +0 -62
- package/dist/runtime/when-eval.js +0 -212
- package/dist/runtime/when-eval.js.map +0 -1
- package/dist/runtime/workflow-policies.d.ts +0 -207
- package/dist/runtime/workflow-policies.js +0 -596
- package/dist/runtime/workflow-policies.js.map +0 -1
- package/dist/schema/audit.d.ts +0 -71
- package/dist/schema/audit.js +0 -32
- package/dist/schema/audit.js.map +0 -1
- package/dist/schema/doctor.d.ts +0 -25
- package/dist/schema/doctor.js +0 -23
- package/dist/schema/doctor.js.map +0 -1
- package/dist/schema/environments.d.ts +0 -215
- package/dist/schema/environments.js +0 -101
- package/dist/schema/environments.js.map +0 -1
- package/dist/schema/extract.d.ts +0 -9
- package/dist/schema/extract.js +0 -86
- package/dist/schema/extract.js.map +0 -1
- package/dist/schema/permission-profiles.d.ts +0 -2292
- package/dist/schema/permission-profiles.js +0 -60
- package/dist/schema/permission-profiles.js.map +0 -1
- package/dist/schema/policies.d.ts +0 -974
- package/dist/schema/policies.js +0 -298
- package/dist/schema/policies.js.map +0 -1
- package/dist/schema/requires.d.ts +0 -131
- package/dist/schema/requires.js +0 -88
- package/dist/schema/requires.js.map +0 -1
- package/dist/schema/risk.d.ts +0 -144
- package/dist/schema/risk.js +0 -194
- package/dist/schema/risk.js.map +0 -1
- package/dist/schema/session-start-preflight.d.ts +0 -10
- package/dist/schema/session-start-preflight.js +0 -106
- package/dist/schema/session-start-preflight.js.map +0 -1
- package/dist/schema/stale-base-check.d.ts +0 -18
- package/dist/schema/stale-base-check.js +0 -37
- package/dist/schema/stale-base-check.js.map +0 -1
- package/dist/schema/toolchain-parity.d.ts +0 -21
- package/dist/schema/toolchain-parity.js +0 -48
- package/dist/schema/toolchain-parity.js.map +0 -1
- package/dist/schema/workflows.d.ts +0 -519
- package/dist/schema/workflows.js +0 -81
- package/dist/schema/workflows.js.map +0 -1
- package/scripts/runtime-reality-docker-probe.mjs +0 -71
|
@@ -33,46 +33,37 @@
|
|
|
33
33
|
* to occupy and against it carrying control characters anywhere
|
|
34
34
|
* downstream.
|
|
35
35
|
*
|
|
36
|
-
* WHAT A REJECTION LOOKS LIKE. `
|
|
37
|
-
*
|
|
38
|
-
* checkout directory whose basename contains a control character now
|
|
39
|
-
* takes the same path a `".."` basename already took: the helper returns
|
|
40
|
-
* `null`, no project override layer is looked up for that repository,
|
|
41
|
-
* and the base/machine value applies unchanged. There is no error and no
|
|
42
|
-
* warning; the operator sees the host-wide value instead of a per-repo
|
|
43
|
-
* one (`harness doctor`'s setup-version finding then carries
|
|
44
|
-
* `projectName: null` and renders no `(project: X)` suffix). An explicit
|
|
45
|
-
* `--project` carrying a control character is instead reported:
|
|
36
|
+
* WHAT A REJECTION LOOKS LIKE. An explicit `--project` carrying a control
|
|
37
|
+
* character or a path-escaping shape is reported, not silently used:
|
|
46
38
|
* `resolvePaths` resolves no project layer for it, and
|
|
47
39
|
* `substituteProject` (`src/probes/memory.ts`) degrades to the "no
|
|
48
40
|
* project supplied" branch, which `harness doctor` surfaces as its
|
|
49
41
|
* rejected-`--project` warn line.
|
|
50
42
|
*
|
|
51
|
-
* Exported (task c88461c1
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `
|
|
56
|
-
*
|
|
57
|
-
* `
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* this function stats, hashes and writes into `harness.lock`.
|
|
43
|
+
* Exported (task c88461c1; task `1c4eb3ea` of the batch-44 follow-up run)
|
|
44
|
+
* so `resolvePaths` (`src/cli/loader.ts`) can apply the SAME guard at
|
|
45
|
+
* its own `path.join` sink, defense in depth: an `opts.project`
|
|
46
|
+
* reaching `resolvePaths` from anywhere (the explicit `--project`
|
|
47
|
+
* flag, a caller building `LoaderOptions` by hand, a future producer)
|
|
48
|
+
* is checked there. Applied a SECOND time at
|
|
49
|
+
* `substituteProject`'s own sink (`src/probes/memory.ts`, task
|
|
50
|
+
* `e904f25a`): an invalid name there degrades to the "no project
|
|
51
|
+
* supplied" branch instead of being interpolated into the `{project}`
|
|
52
|
+
* placeholder. Applied a THIRD time at `buildLockEntries`' own sink
|
|
53
|
+
* (`src/io/harness-lock.ts`, task `b5e6ccb0`): an invalid name there
|
|
54
|
+
* skips the templated directory's lock entry instead of the raw value
|
|
55
|
+
* being interpolated into the path this function stats, hashes and
|
|
56
|
+
* writes into `harness.lock`.
|
|
66
57
|
* `resolvePaths`, `substituteProject` and `buildLockEntries` are now all
|
|
67
58
|
* guarded; one `{project}` sink is NOT: `generate-memory-index.ts`'s own
|
|
68
59
|
* substitution still interpolates an operator-supplied `--project` value
|
|
69
60
|
* into a path unvalidated, left unguarded (reached only via the explicit
|
|
70
|
-
* CLI flag
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
61
|
+
* `--project` CLI flag; see CHANGELOG.md for the reservation/follow-up).
|
|
62
|
+
* That one call site calls this function nowhere, so it inherits NOTHING
|
|
63
|
+
* from the control-character screen above either: a caller reading
|
|
64
|
+
* this comment should not assume this function guards every
|
|
65
|
+
* `{project}`-shaped sink in the codebase, for path escapes or for
|
|
66
|
+
* control characters.
|
|
76
67
|
*/
|
|
77
68
|
export declare function isValidProjectName(name: string): boolean;
|
|
78
69
|
/**
|
|
@@ -96,14 +87,6 @@ export declare function isValidProjectName(name: string): boolean;
|
|
|
96
87
|
* field (`src/cli/list.ts`, and with it the text table derived from
|
|
97
88
|
* it).
|
|
98
89
|
*
|
|
99
|
-
* The `session_start_preflight.setup` finding's `(project: X)` suffix is
|
|
100
|
-
* also wrapped, as defense in depth rather than as an echo of a rejected
|
|
101
|
-
* value: `harness doctor` sets that finding's `projectName` only when
|
|
102
|
-
* `resolvePaths` actually resolved a project layer FILE, which requires
|
|
103
|
-
* the name to have passed {@link isValidProjectName} first. The wrap
|
|
104
|
-
* stays so a hand-built finding or a future producer cannot reintroduce
|
|
105
|
-
* a forged line through that one call site.
|
|
106
|
-
*
|
|
107
90
|
* Strips (rather than escapes) every character in
|
|
108
91
|
* {@link PROJECT_NAME_CONTROL_CHARS}. A name with no control character
|
|
109
92
|
* (`..`, `a/b`, every ordinary shape) passes through unchanged. Report
|
package/dist/io/project-name.js
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
// documents for `src/policies/duration.ts`, `src/policies/extract.ts`,
|
|
11
11
|
// `src/runtime/ledger-record.ts` and `src/runtime/expand-home.ts`: a
|
|
12
12
|
// utility needed below its original layer moves down rather than the
|
|
13
|
-
// importing layer's boundary being relaxed.
|
|
14
|
-
//
|
|
15
|
-
//
|
|
13
|
+
// importing layer's boundary being relaxed. This module is the home of
|
|
14
|
+
// both helpers: every consumer imports them from `src/io/project-name.ts`
|
|
15
|
+
// directly.
|
|
16
16
|
/**
|
|
17
17
|
* Every C0 control character (U+0000 to U+001F, so NUL, LF, CR and ESC
|
|
18
18
|
* among them), DEL (U+007F), and every C1 control character (U+0080 to
|
|
@@ -65,46 +65,37 @@ const PROJECT_NAME_CONTROL_CHARS_GLOBAL = new RegExp(PROJECT_NAME_CONTROL_CHARS.
|
|
|
65
65
|
* to occupy and against it carrying control characters anywhere
|
|
66
66
|
* downstream.
|
|
67
67
|
*
|
|
68
|
-
* WHAT A REJECTION LOOKS LIKE. `
|
|
69
|
-
*
|
|
70
|
-
* checkout directory whose basename contains a control character now
|
|
71
|
-
* takes the same path a `".."` basename already took: the helper returns
|
|
72
|
-
* `null`, no project override layer is looked up for that repository,
|
|
73
|
-
* and the base/machine value applies unchanged. There is no error and no
|
|
74
|
-
* warning; the operator sees the host-wide value instead of a per-repo
|
|
75
|
-
* one (`harness doctor`'s setup-version finding then carries
|
|
76
|
-
* `projectName: null` and renders no `(project: X)` suffix). An explicit
|
|
77
|
-
* `--project` carrying a control character is instead reported:
|
|
68
|
+
* WHAT A REJECTION LOOKS LIKE. An explicit `--project` carrying a control
|
|
69
|
+
* character or a path-escaping shape is reported, not silently used:
|
|
78
70
|
* `resolvePaths` resolves no project layer for it, and
|
|
79
71
|
* `substituteProject` (`src/probes/memory.ts`) degrades to the "no
|
|
80
72
|
* project supplied" branch, which `harness doctor` surfaces as its
|
|
81
73
|
* rejected-`--project` warn line.
|
|
82
74
|
*
|
|
83
|
-
* Exported (task c88461c1
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* `
|
|
88
|
-
*
|
|
89
|
-
* `
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* this function stats, hashes and writes into `harness.lock`.
|
|
75
|
+
* Exported (task c88461c1; task `1c4eb3ea` of the batch-44 follow-up run)
|
|
76
|
+
* so `resolvePaths` (`src/cli/loader.ts`) can apply the SAME guard at
|
|
77
|
+
* its own `path.join` sink, defense in depth: an `opts.project`
|
|
78
|
+
* reaching `resolvePaths` from anywhere (the explicit `--project`
|
|
79
|
+
* flag, a caller building `LoaderOptions` by hand, a future producer)
|
|
80
|
+
* is checked there. Applied a SECOND time at
|
|
81
|
+
* `substituteProject`'s own sink (`src/probes/memory.ts`, task
|
|
82
|
+
* `e904f25a`): an invalid name there degrades to the "no project
|
|
83
|
+
* supplied" branch instead of being interpolated into the `{project}`
|
|
84
|
+
* placeholder. Applied a THIRD time at `buildLockEntries`' own sink
|
|
85
|
+
* (`src/io/harness-lock.ts`, task `b5e6ccb0`): an invalid name there
|
|
86
|
+
* skips the templated directory's lock entry instead of the raw value
|
|
87
|
+
* being interpolated into the path this function stats, hashes and
|
|
88
|
+
* writes into `harness.lock`.
|
|
98
89
|
* `resolvePaths`, `substituteProject` and `buildLockEntries` are now all
|
|
99
90
|
* guarded; one `{project}` sink is NOT: `generate-memory-index.ts`'s own
|
|
100
91
|
* substitution still interpolates an operator-supplied `--project` value
|
|
101
92
|
* into a path unvalidated, left unguarded (reached only via the explicit
|
|
102
|
-
* CLI flag
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
93
|
+
* `--project` CLI flag; see CHANGELOG.md for the reservation/follow-up).
|
|
94
|
+
* That one call site calls this function nowhere, so it inherits NOTHING
|
|
95
|
+
* from the control-character screen above either: a caller reading
|
|
96
|
+
* this comment should not assume this function guards every
|
|
97
|
+
* `{project}`-shaped sink in the codebase, for path escapes or for
|
|
98
|
+
* control characters.
|
|
108
99
|
*/
|
|
109
100
|
export function isValidProjectName(name) {
|
|
110
101
|
if (name.length === 0)
|
|
@@ -136,14 +127,6 @@ export function isValidProjectName(name) {
|
|
|
136
127
|
* field (`src/cli/list.ts`, and with it the text table derived from
|
|
137
128
|
* it).
|
|
138
129
|
*
|
|
139
|
-
* The `session_start_preflight.setup` finding's `(project: X)` suffix is
|
|
140
|
-
* also wrapped, as defense in depth rather than as an echo of a rejected
|
|
141
|
-
* value: `harness doctor` sets that finding's `projectName` only when
|
|
142
|
-
* `resolvePaths` actually resolved a project layer FILE, which requires
|
|
143
|
-
* the name to have passed {@link isValidProjectName} first. The wrap
|
|
144
|
-
* stays so a hand-built finding or a future producer cannot reintroduce
|
|
145
|
-
* a forged line through that one call site.
|
|
146
|
-
*
|
|
147
130
|
* Strips (rather than escapes) every character in
|
|
148
131
|
* {@link PROJECT_NAME_CONTROL_CHARS}. A name with no control character
|
|
149
132
|
* (`..`, `a/b`, every ordinary shape) passes through unchanged. Report
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-name.js","sourceRoot":"","sources":["../../src/io/project-name.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,2EAA2E;AAC3E,+DAA+D;AAC/D,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,
|
|
1
|
+
{"version":3,"file":"project-name.js","sourceRoot":"","sources":["../../src/io/project-name.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,2EAA2E;AAC3E,+DAA+D;AAC/D,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,0EAA0E;AAC1E,YAAY;AAEZ;;;;;;;GAOG;AACH,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,iCAAiC,GAAG,IAAI,MAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Result of a symlink-rejecting regular-file read. The kinds are deliberately
|
|
3
|
-
* fine-grained because the
|
|
4
|
-
* details (missing vs symlink vs not-regular)
|
|
5
|
-
*
|
|
3
|
+
* fine-grained because the readers need to keep their distinct failure
|
|
4
|
+
* details (missing vs symlink vs not-regular); every caller treats
|
|
5
|
+
* `unreadable` (an oversized file included) as fail-closed.
|
|
6
6
|
*/
|
|
7
7
|
export type RegularFileRead = {
|
|
8
8
|
kind: "ok";
|
|
@@ -17,47 +17,110 @@ export type RegularFileRead = {
|
|
|
17
17
|
kind: "unreadable";
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* The most bytes a read returns by default. The current callers read small
|
|
21
|
+
* text records: the harness manifest and its override layers
|
|
22
|
+
* (`src/cli/loader.ts`) and, with a larger bound of their own, the Claude
|
|
23
|
+
* Code user-scope MCP registry (`src/io/claude-mcp.ts`). A file over the
|
|
24
|
+
* cap is refused as `unreadable` (fail-closed in every caller) before any
|
|
25
|
+
* byte is read: a sparse multi-gigabyte file at one of these paths
|
|
26
|
+
* otherwise makes the caller wait on bytes it never asked for, the same
|
|
27
|
+
* stall a FIFO used to cause.
|
|
25
28
|
*/
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
export declare const MAX_REGULAR_FILE_READ_BYTES: number;
|
|
30
|
+
/**
|
|
31
|
+
* Options of the readers below. They default to the strict read this module
|
|
32
|
+
* was built for (the 1 MiB cap, a symlink refused).
|
|
33
|
+
*/
|
|
34
|
+
export interface BoundedReadOptions {
|
|
35
|
+
/**
|
|
36
|
+
* The most bytes the read returns; a file over it is refused as
|
|
37
|
+
* `unreadable` before any byte is read, exactly like the default cap.
|
|
38
|
+
* Defaults to {@link MAX_REGULAR_FILE_READ_BYTES}. A caller
|
|
39
|
+
* with a legitimately larger input (the Claude Code user registry) passes
|
|
40
|
+
* its own, larger bound and justifies
|
|
41
|
+
* it at the call site; there is deliberately no way to ask for no bound.
|
|
42
|
+
*/
|
|
43
|
+
maxBytes?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Follow a symbolic link at the path (the open drops `O_NOFOLLOW`). For a
|
|
46
|
+
* reader of a file the operator legitimately keeps behind a link
|
|
47
|
+
* (a dotfiles-managed manifest); it never weakens the
|
|
48
|
+
* rest: the type of the OPENED descriptor still decides, so a link to a
|
|
49
|
+
* FIFO, a device or a directory is `not-regular` and never blocks.
|
|
50
|
+
* Defaults to `false` (a link is refused as `symlink`).
|
|
51
|
+
*/
|
|
52
|
+
followSymlinks?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export type RegularFileBytesRead = {
|
|
55
|
+
kind: "ok";
|
|
56
|
+
bytes: Buffer;
|
|
57
|
+
} | Exclude<RegularFileRead, {
|
|
58
|
+
kind: "ok";
|
|
59
|
+
}>;
|
|
31
60
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
61
|
+
* The one open-once, type-checked-on-the-descriptor, size-bounded read every
|
|
62
|
+
* by-path reader on a hook path stands on, returning raw bytes (a binary key
|
|
63
|
+
* file needs them, `readRegularFileBounded` decodes them). The cap and the
|
|
64
|
+
* symlink policy are options.
|
|
65
|
+
*
|
|
66
|
+
* The path is opened once, read-only, with `O_NOFOLLOW` (a symlink at the
|
|
67
|
+
* path is refused by the open itself) and `O_NONBLOCK` (opening a FIFO with
|
|
68
|
+
* no writer returns at once instead of waiting for one). The type of the
|
|
69
|
+
* OPENED descriptor then decides (`fstat`, never a separate stat of the
|
|
70
|
+
* path), and the content is read through that same descriptor, so nothing
|
|
71
|
+
* can be swapped in between a check and the read: a writer that replaces the
|
|
72
|
+
* file with a FIFO or a symlink after any earlier look gets `not-regular` /
|
|
73
|
+
* `symlink` back, not a read that blocks the hook past its budget (which the
|
|
74
|
+
* runtime treats as an allow). The descriptor is always closed. The size is
|
|
75
|
+
* bounded too: a file over the cap by `fstat` is refused as `unreadable`
|
|
76
|
+
* without a read, and the read itself stops one byte past the cap, so a file
|
|
77
|
+
* that grows after the `fstat` is bounded as well.
|
|
78
|
+
*
|
|
79
|
+
* Why refuse symlinks at all: defense-in-depth against a symlink at the
|
|
80
|
+
* path pointing at an arbitrary target the agent controls. The gate contract
|
|
81
|
+
* is to assume the agent is hostile, so the refusal is cheap insurance
|
|
38
82
|
* (agent-tasks/d39f160e).
|
|
39
83
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* `
|
|
48
|
-
*
|
|
84
|
+
* Platforms without `O_NOFOLLOW` (Windows): an `lstat` runs first and
|
|
85
|
+
* refuses a symlink or a non-regular node before the open, because the open
|
|
86
|
+
* alone would follow a link. That leaves the old lstat-to-open window on
|
|
87
|
+
* those platforms; there is no FIFO node on the filesystem there to swap in
|
|
88
|
+
* (named pipes live in a separate namespace), and `O_NONBLOCK` is a no-op
|
|
89
|
+
* flag that is simply left out. The descriptor type check still runs.
|
|
90
|
+
*
|
|
91
|
+
* A future defensive fix belongs here and in `classifyOpenFailure` /
|
|
92
|
+
* `lstatOrNull`, and nowhere else.
|
|
93
|
+
*/
|
|
94
|
+
export declare function readRegularFileBytesBounded(filePath: string, opts?: BoundedReadOptions): RegularFileBytesRead;
|
|
95
|
+
/**
|
|
96
|
+
* {@link readRegularFileBytesBounded} decoded as utf8, for the by-path
|
|
97
|
+
* readers of a file a symlink at the path is acceptable for or a larger cap
|
|
98
|
+
* is justified (see {@link BoundedReadOptions}). Same five result kinds as
|
|
99
|
+
* {@link readRegularFileBytesBounded}; `missing` is the one a caller may
|
|
100
|
+
* treat as "legitimately absent", every other non-`ok` kind means something
|
|
101
|
+
* is at the path that must not be read as the file (a FIFO, a device, a
|
|
102
|
+
* directory, an oversized or unreadable file) and is fail-closed or
|
|
103
|
+
* explicitly reported by the caller.
|
|
104
|
+
*/
|
|
105
|
+
export declare function readRegularFileBounded(filePath: string, opts?: BoundedReadOptions): RegularFileRead;
|
|
106
|
+
/**
|
|
107
|
+
* Thrown by {@link readTextFileBoundedOrThrow}. `code` is `ENOENT` for a
|
|
108
|
+
* path that is not there (so a caller's existing `ENOENT` branch keeps
|
|
109
|
+
* meaning "absent") and `E_<KIND>` (`E_SYMLINK`, `E_NOT_REGULAR`,
|
|
110
|
+
* `E_UNREADABLE`) for anything else, which never matches `ENOENT`.
|
|
49
111
|
*/
|
|
50
|
-
export declare
|
|
112
|
+
export declare class BoundedReadError extends Error {
|
|
113
|
+
readonly code: string;
|
|
114
|
+
readonly kind: Exclude<RegularFileRead["kind"], "ok">;
|
|
115
|
+
constructor(filePath: string, kind: Exclude<RegularFileRead["kind"], "ok">);
|
|
116
|
+
}
|
|
51
117
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* neither does this probe. Callers that need the file-type distinction
|
|
60
|
-
* (symlink vs directory vs regular) read the file instead, through
|
|
61
|
-
* `readRegularFileRejectingSymlink`.
|
|
118
|
+
* {@link readRegularFileBounded} for the call sites that already wrap a
|
|
119
|
+
* `fs.readFileSync(path, "utf8")` in a try/catch (and, some of them, branch
|
|
120
|
+
* on `ENOENT`): the same bounded, non-blocking read, thrown as a
|
|
121
|
+
* {@link BoundedReadError} instead of returned, so the existing catch blocks
|
|
122
|
+
* keep their shape and every FIFO, device, directory or oversized file now
|
|
123
|
+
* lands in the catch block it would have reached on any other read error,
|
|
124
|
+
* rather than blocking the process.
|
|
62
125
|
*/
|
|
63
|
-
export declare function
|
|
126
|
+
export declare function readTextFileBoundedOrThrow(filePath: string, opts?: BoundedReadOptions): string;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
/**
|
|
3
|
-
* The single `fs.lstatSync` call
|
|
3
|
+
* The single `fs.lstatSync` call the readers below stand on. Returns `null`
|
|
4
4
|
* on any lstat failure (absent path, or unreachable for another reason:
|
|
5
5
|
* `EACCES`, `ENOTDIR`, ...); lstat cannot distinguish those cases from each
|
|
6
|
-
* other, so
|
|
7
|
-
*
|
|
8
|
-
* this one place and is inherited by both callers.
|
|
6
|
+
* other, so no caller tries to. A future defensive fix here
|
|
7
|
+
* (e.g. `ENOTDIR` handling) lands in this one place.
|
|
9
8
|
*/
|
|
10
9
|
function lstatOrNull(filePath) {
|
|
11
10
|
try {
|
|
@@ -16,25 +15,79 @@ function lstatOrNull(filePath) {
|
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
18
|
+
* Open flags for the reads in this module. `O_NOFOLLOW` makes the open itself
|
|
19
|
+
* refuse a symbolic link at the final path component (`ELOOP`), so no
|
|
20
|
+
* earlier `lstat` is needed for a swap to race. `O_NONBLOCK` keeps an open
|
|
21
|
+
* of a FIFO with no writer from waiting for one: the open returns at once
|
|
22
|
+
* and the descriptor's type then refuses it. `O_NOFOLLOW` covers only the
|
|
23
|
+
* LAST path component; a symlinked parent directory is followed, as it was
|
|
24
|
+
* under the earlier lstat. `O_NOCTTY` is belt and braces for a tty node at
|
|
25
|
+
* the path. All three are POSIX-only flags; `fs.constants` leaves them
|
|
26
|
+
* `undefined` on Windows, where the code falls back to 0 (see
|
|
27
|
+
* `readRegularFileBytesBounded` for that fallback).
|
|
28
|
+
*/
|
|
29
|
+
const O_NOFOLLOW = fs.constants.O_NOFOLLOW;
|
|
30
|
+
const O_NONBLOCK = fs.constants.O_NONBLOCK ?? 0;
|
|
31
|
+
/** A read here must never make a terminal the process's controlling one. */
|
|
32
|
+
const O_NOCTTY = fs.constants.O_NOCTTY ?? 0;
|
|
33
|
+
/**
|
|
34
|
+
* The most bytes a read returns by default. The current callers read small
|
|
35
|
+
* text records: the harness manifest and its override layers
|
|
36
|
+
* (`src/cli/loader.ts`) and, with a larger bound of their own, the Claude
|
|
37
|
+
* Code user-scope MCP registry (`src/io/claude-mcp.ts`). A file over the
|
|
38
|
+
* cap is refused as `unreadable` (fail-closed in every caller) before any
|
|
39
|
+
* byte is read: a sparse multi-gigabyte file at one of these paths
|
|
40
|
+
* otherwise makes the caller wait on bytes it never asked for, the same
|
|
41
|
+
* stall a FIFO used to cause.
|
|
42
|
+
*/
|
|
43
|
+
export const MAX_REGULAR_FILE_READ_BYTES = 1024 * 1024;
|
|
44
|
+
const READ_CHUNK_BYTES = 64 * 1024;
|
|
45
|
+
/**
|
|
46
|
+
* Read the opened descriptor to EOF, never more than `maxBytes + 1` bytes: a
|
|
47
|
+
* file that grows after the `fstat` size check stays bounded too. Returns
|
|
48
|
+
* `null` when the file is over the cap. Any read error propagates to the
|
|
49
|
+
* caller.
|
|
50
|
+
*/
|
|
51
|
+
function readDescriptorBounded(fd, maxBytes) {
|
|
52
|
+
const chunks = [];
|
|
53
|
+
let total = 0;
|
|
54
|
+
for (;;) {
|
|
55
|
+
const want = Math.min(READ_CHUNK_BYTES, maxBytes + 1 - total);
|
|
56
|
+
const chunk = Buffer.allocUnsafe(want);
|
|
57
|
+
const got = fs.readSync(fd, chunk, 0, want, null);
|
|
58
|
+
if (got === 0)
|
|
59
|
+
break;
|
|
60
|
+
total += got;
|
|
61
|
+
if (total > maxBytes)
|
|
62
|
+
return null;
|
|
63
|
+
chunks.push(got === want ? chunk : chunk.subarray(0, got));
|
|
64
|
+
}
|
|
65
|
+
return Buffer.concat(chunks);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Classify a failed open by what `lstat` sees at the path now, so the
|
|
69
|
+
* caller-visible kinds stay what they were when `lstat` came first: an
|
|
70
|
+
* unreachable path (absent, `ENOTDIR`, an unsearchable parent) is `missing`,
|
|
71
|
+
* a symlink (dangling included) is `symlink`, any other non-regular node is
|
|
72
|
+
* `not-regular`, and a regular file the open could not read (`EACCES`, ...)
|
|
73
|
+
* is `unreadable`. A path that raced into a different state between the
|
|
74
|
+
* failed open and this `lstat` still lands on one of the five kinds, never
|
|
75
|
+
* on `ok`.
|
|
36
76
|
*/
|
|
37
|
-
|
|
77
|
+
function classifyOpenFailure(filePath, followSymlinks = false) {
|
|
78
|
+
if (followSymlinks) {
|
|
79
|
+
// A link is followed by this read, so what matters is what it leads to:
|
|
80
|
+
// a dangling link (or an unreachable parent) is absent, exactly as a
|
|
81
|
+
// by-path read of it reports `ENOENT`; a link loop or an unreadable
|
|
82
|
+
// target is something there that cannot be read.
|
|
83
|
+
try {
|
|
84
|
+
return fs.statSync(filePath).isFile() ? { kind: "unreadable" } : { kind: "not-regular" };
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const code = err.code;
|
|
88
|
+
return code === "ENOENT" || code === "ENOTDIR" ? { kind: "missing" } : { kind: "unreadable" };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
38
91
|
const stat = lstatOrNull(filePath);
|
|
39
92
|
if (stat === null)
|
|
40
93
|
return { kind: "missing" };
|
|
@@ -42,26 +95,134 @@ export function readRegularFileRejectingSymlink(filePath) {
|
|
|
42
95
|
return { kind: "symlink" };
|
|
43
96
|
if (!stat.isFile())
|
|
44
97
|
return { kind: "not-regular" };
|
|
98
|
+
return { kind: "unreadable" };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The one open-once, type-checked-on-the-descriptor, size-bounded read every
|
|
102
|
+
* by-path reader on a hook path stands on, returning raw bytes (a binary key
|
|
103
|
+
* file needs them, `readRegularFileBounded` decodes them). The cap and the
|
|
104
|
+
* symlink policy are options.
|
|
105
|
+
*
|
|
106
|
+
* The path is opened once, read-only, with `O_NOFOLLOW` (a symlink at the
|
|
107
|
+
* path is refused by the open itself) and `O_NONBLOCK` (opening a FIFO with
|
|
108
|
+
* no writer returns at once instead of waiting for one). The type of the
|
|
109
|
+
* OPENED descriptor then decides (`fstat`, never a separate stat of the
|
|
110
|
+
* path), and the content is read through that same descriptor, so nothing
|
|
111
|
+
* can be swapped in between a check and the read: a writer that replaces the
|
|
112
|
+
* file with a FIFO or a symlink after any earlier look gets `not-regular` /
|
|
113
|
+
* `symlink` back, not a read that blocks the hook past its budget (which the
|
|
114
|
+
* runtime treats as an allow). The descriptor is always closed. The size is
|
|
115
|
+
* bounded too: a file over the cap by `fstat` is refused as `unreadable`
|
|
116
|
+
* without a read, and the read itself stops one byte past the cap, so a file
|
|
117
|
+
* that grows after the `fstat` is bounded as well.
|
|
118
|
+
*
|
|
119
|
+
* Why refuse symlinks at all: defense-in-depth against a symlink at the
|
|
120
|
+
* path pointing at an arbitrary target the agent controls. The gate contract
|
|
121
|
+
* is to assume the agent is hostile, so the refusal is cheap insurance
|
|
122
|
+
* (agent-tasks/d39f160e).
|
|
123
|
+
*
|
|
124
|
+
* Platforms without `O_NOFOLLOW` (Windows): an `lstat` runs first and
|
|
125
|
+
* refuses a symlink or a non-regular node before the open, because the open
|
|
126
|
+
* alone would follow a link. That leaves the old lstat-to-open window on
|
|
127
|
+
* those platforms; there is no FIFO node on the filesystem there to swap in
|
|
128
|
+
* (named pipes live in a separate namespace), and `O_NONBLOCK` is a no-op
|
|
129
|
+
* flag that is simply left out. The descriptor type check still runs.
|
|
130
|
+
*
|
|
131
|
+
* A future defensive fix belongs here and in `classifyOpenFailure` /
|
|
132
|
+
* `lstatOrNull`, and nowhere else.
|
|
133
|
+
*/
|
|
134
|
+
export function readRegularFileBytesBounded(filePath, opts = {}) {
|
|
135
|
+
const maxBytes = opts.maxBytes ?? MAX_REGULAR_FILE_READ_BYTES;
|
|
136
|
+
const noFollow = opts.followSymlinks !== true;
|
|
137
|
+
if (noFollow && O_NOFOLLOW === undefined) {
|
|
138
|
+
const stat = lstatOrNull(filePath);
|
|
139
|
+
if (stat === null)
|
|
140
|
+
return { kind: "missing" };
|
|
141
|
+
if (stat.isSymbolicLink())
|
|
142
|
+
return { kind: "symlink" };
|
|
143
|
+
if (!stat.isFile())
|
|
144
|
+
return { kind: "not-regular" };
|
|
145
|
+
}
|
|
146
|
+
let fd;
|
|
147
|
+
try {
|
|
148
|
+
fd = fs.openSync(filePath, fs.constants.O_RDONLY | (noFollow ? (O_NOFOLLOW ?? 0) : 0) | O_NONBLOCK | O_NOCTTY);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return classifyOpenFailure(filePath, !noFollow);
|
|
152
|
+
}
|
|
45
153
|
try {
|
|
46
|
-
|
|
154
|
+
const st = fs.fstatSync(fd);
|
|
155
|
+
if (!st.isFile())
|
|
156
|
+
return { kind: "not-regular" };
|
|
157
|
+
if (st.size > maxBytes)
|
|
158
|
+
return { kind: "unreadable" };
|
|
159
|
+
const bytes = readDescriptorBounded(fd, maxBytes);
|
|
160
|
+
if (bytes === null)
|
|
161
|
+
return { kind: "unreadable" };
|
|
162
|
+
return { kind: "ok", bytes };
|
|
47
163
|
}
|
|
48
164
|
catch {
|
|
49
165
|
return { kind: "unreadable" };
|
|
50
166
|
}
|
|
167
|
+
finally {
|
|
168
|
+
try {
|
|
169
|
+
fs.closeSync(fd);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Already gone; nothing left to release.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* {@link readRegularFileBytesBounded} decoded as utf8, for the by-path
|
|
178
|
+
* readers of a file a symlink at the path is acceptable for or a larger cap
|
|
179
|
+
* is justified (see {@link BoundedReadOptions}). Same five result kinds as
|
|
180
|
+
* {@link readRegularFileBytesBounded}; `missing` is the one a caller may
|
|
181
|
+
* treat as "legitimately absent", every other non-`ok` kind means something
|
|
182
|
+
* is at the path that must not be read as the file (a FIFO, a device, a
|
|
183
|
+
* directory, an oversized or unreadable file) and is fail-closed or
|
|
184
|
+
* explicitly reported by the caller.
|
|
185
|
+
*/
|
|
186
|
+
export function readRegularFileBounded(filePath, opts = {}) {
|
|
187
|
+
const read = readRegularFileBytesBounded(filePath, opts);
|
|
188
|
+
return read.kind === "ok" ? { kind: "ok", content: read.bytes.toString("utf8") } : read;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Thrown by {@link readTextFileBoundedOrThrow}. `code` is `ENOENT` for a
|
|
192
|
+
* path that is not there (so a caller's existing `ENOENT` branch keeps
|
|
193
|
+
* meaning "absent") and `E_<KIND>` (`E_SYMLINK`, `E_NOT_REGULAR`,
|
|
194
|
+
* `E_UNREADABLE`) for anything else, which never matches `ENOENT`.
|
|
195
|
+
*/
|
|
196
|
+
export class BoundedReadError extends Error {
|
|
197
|
+
code;
|
|
198
|
+
kind;
|
|
199
|
+
constructor(filePath, kind) {
|
|
200
|
+
const code = kind === "missing" ? "ENOENT" : `E_${kind.toUpperCase().replace(/-/g, "_")}`;
|
|
201
|
+
super(`${code}: ${filePath} ${DESCRIBE_KIND[kind]}`);
|
|
202
|
+
this.name = "BoundedReadError";
|
|
203
|
+
this.code = code;
|
|
204
|
+
this.kind = kind;
|
|
205
|
+
}
|
|
51
206
|
}
|
|
207
|
+
const DESCRIBE_KIND = {
|
|
208
|
+
missing: "does not exist",
|
|
209
|
+
symlink: "is a symbolic link (refused)",
|
|
210
|
+
"not-regular": "is not a regular file (refused without a read)",
|
|
211
|
+
unreadable: "is unreadable or larger than the read cap",
|
|
212
|
+
};
|
|
52
213
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* neither does this probe. Callers that need the file-type distinction
|
|
61
|
-
* (symlink vs directory vs regular) read the file instead, through
|
|
62
|
-
* `readRegularFileRejectingSymlink`.
|
|
214
|
+
* {@link readRegularFileBounded} for the call sites that already wrap a
|
|
215
|
+
* `fs.readFileSync(path, "utf8")` in a try/catch (and, some of them, branch
|
|
216
|
+
* on `ENOENT`): the same bounded, non-blocking read, thrown as a
|
|
217
|
+
* {@link BoundedReadError} instead of returned, so the existing catch blocks
|
|
218
|
+
* keep their shape and every FIFO, device, directory or oversized file now
|
|
219
|
+
* lands in the catch block it would have reached on any other read error,
|
|
220
|
+
* rather than blocking the process.
|
|
63
221
|
*/
|
|
64
|
-
export function
|
|
65
|
-
|
|
222
|
+
export function readTextFileBoundedOrThrow(filePath, opts = {}) {
|
|
223
|
+
const read = readRegularFileBounded(filePath, opts);
|
|
224
|
+
if (read.kind === "ok")
|
|
225
|
+
return read.content;
|
|
226
|
+
throw new BoundedReadError(filePath, read.kind);
|
|
66
227
|
}
|
|
67
228
|
//# sourceMappingURL=read-regular-file.js.map
|