salmon-loop 0.2.3
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/LICENSE +21 -0
- package/README.md +144 -0
- package/README.zh-CN.md +144 -0
- package/dist/cli/argv/headless-detection.js +60 -0
- package/dist/cli/argv/print-mode.js +60 -0
- package/dist/cli/authorization/allowlist.js +908 -0
- package/dist/cli/authorization/non-interactive.js +166 -0
- package/dist/cli/authorization/provider.js +416 -0
- package/dist/cli/chat-interface.js +83 -0
- package/dist/cli/chat.js +492 -0
- package/dist/cli/cli-runtime-context.js +12 -0
- package/dist/cli/commander-error-adapter.js +35 -0
- package/dist/cli/commander-error-meta.js +13 -0
- package/dist/cli/commands/allowlist.js +270 -0
- package/dist/cli/commands/chat.js +120 -0
- package/dist/cli/commands/config.js +250 -0
- package/dist/cli/commands/context.js +57 -0
- package/dist/cli/commands/dispatcher.js +53 -0
- package/dist/cli/commands/exit.js +9 -0
- package/dist/cli/commands/llm-output.js +135 -0
- package/dist/cli/commands/log-mode.js +143 -0
- package/dist/cli/commands/mode.js +136 -0
- package/dist/cli/commands/new.js +18 -0
- package/dist/cli/commands/parallel.js +256 -0
- package/dist/cli/commands/queue.js +130 -0
- package/dist/cli/commands/registry.js +85 -0
- package/dist/cli/commands/restore.js +26 -0
- package/dist/cli/commands/run/assistant-message.js +14 -0
- package/dist/cli/commands/run/config-resolution.js +37 -0
- package/dist/cli/commands/run/early-errors.js +108 -0
- package/dist/cli/commands/run/execute.js +73 -0
- package/dist/cli/commands/run/extensions-resolution.js +22 -0
- package/dist/cli/commands/run/handler.js +434 -0
- package/dist/cli/commands/run/headless-error-writer.js +182 -0
- package/dist/cli/commands/run/instruction-guard.js +24 -0
- package/dist/cli/commands/run/loop-params.js +46 -0
- package/dist/cli/commands/run/mode.js +8 -0
- package/dist/cli/commands/run/parse-options.js +67 -0
- package/dist/cli/commands/run/persist-session.js +35 -0
- package/dist/cli/commands/run/preflight.js +156 -0
- package/dist/cli/commands/run/reporter-factory.js +52 -0
- package/dist/cli/commands/run/runtime-llm.js +56 -0
- package/dist/cli/commands/run/runtime-options.js +30 -0
- package/dist/cli/commands/run/session.js +19 -0
- package/dist/cli/commands/run/structured-output.js +106 -0
- package/dist/cli/commands/run/types.js +2 -0
- package/dist/cli/commands/run/validate-options.js +28 -0
- package/dist/cli/commands/run/verbose.js +36 -0
- package/dist/cli/commands/run.js +2 -0
- package/dist/cli/commands/serve.js +323 -0
- package/dist/cli/commands/session.js +77 -0
- package/dist/cli/commands/snapshot-interactive.js +165 -0
- package/dist/cli/commands/snapshot.js +159 -0
- package/dist/cli/commands/status.js +17 -0
- package/dist/cli/commands/subagent.js +178 -0
- package/dist/cli/commands/subcommand-suggestions.js +63 -0
- package/dist/cli/commands/tool-names.js +155 -0
- package/dist/cli/commands/types.js +2 -0
- package/dist/cli/commands/utils.js +42 -0
- package/dist/cli/config.js +16 -0
- package/dist/cli/crash-reporter.js +5 -0
- package/dist/cli/headless/anthropic-stream-normalized-encoder.js +164 -0
- package/dist/cli/headless/anthropic-stream-protocol.js +62 -0
- package/dist/cli/headless/json-protocol.js +124 -0
- package/dist/cli/headless/native-stream-normalized-encoder.js +206 -0
- package/dist/cli/headless/openai-responses-canonical-applier.js +94 -0
- package/dist/cli/headless/openai-responses-state.js +294 -0
- package/dist/cli/headless/openai-stream-encoder.js +152 -0
- package/dist/cli/headless/stdout-writer.js +9 -0
- package/dist/cli/headless/stream-json-protocol.js +136 -0
- package/dist/cli/index.js +8 -0
- package/dist/cli/locales/en.js +409 -0
- package/dist/cli/locales/index.js +7 -0
- package/dist/cli/program-bootstrap.js +14 -0
- package/dist/cli/program-commands.js +106 -0
- package/dist/cli/program-options.js +15 -0
- package/dist/cli/program-output-mode.js +11 -0
- package/dist/cli/program-parse.js +24 -0
- package/dist/cli/reporters/anthropic-stream.js +77 -0
- package/dist/cli/reporters/base.js +2 -0
- package/dist/cli/reporters/json.js +69 -0
- package/dist/cli/reporters/openai-stream.js +72 -0
- package/dist/cli/reporters/standard.js +226 -0
- package/dist/cli/reporters/stderr-log-reporter.js +71 -0
- package/dist/cli/reporters/stream-json.js +111 -0
- package/dist/cli/run-cli.js +25 -0
- package/dist/cli/slash/runtime.js +240 -0
- package/dist/cli/ui/App.js +273 -0
- package/dist/cli/ui/authorization/bus.js +35 -0
- package/dist/cli/ui/components/CommandInput.js +200 -0
- package/dist/cli/ui/components/CommandSuggestionList.js +20 -0
- package/dist/cli/ui/components/Markdown.js +423 -0
- package/dist/cli/ui/components/MessageList.js +34 -0
- package/dist/cli/ui/components/StatusBannerLine.js +7 -0
- package/dist/cli/ui/components/TodoDrawer.js +60 -0
- package/dist/cli/ui/components/WelcomeMessage.js +14 -0
- package/dist/cli/ui/components/animations/StretchingThinking.js +51 -0
- package/dist/cli/ui/components/animations/ThinkingWave.js +15 -0
- package/dist/cli/ui/components/animations/TypeIndicator.js +30 -0
- package/dist/cli/ui/components/layout/SplitPane.js +11 -0
- package/dist/cli/ui/components/messageList/MessageItem.js +27 -0
- package/dist/cli/ui/components/messageList/QueuePreviewList.js +11 -0
- package/dist/cli/ui/components/messageList/items/EmphasisMessageItem.js +20 -0
- package/dist/cli/ui/components/messageList/items/InterruptMessageItem.js +10 -0
- package/dist/cli/ui/components/messageList/items/LightweightMessageItem.js +12 -0
- package/dist/cli/ui/components/messageList/items/StandardMessageItem.js +23 -0
- package/dist/cli/ui/components/messageList/items/WelcomeMessageItem.js +7 -0
- package/dist/cli/ui/components/messageList/messageListLayout.js +27 -0
- package/dist/cli/ui/components/messageList/streaming.js +51 -0
- package/dist/cli/ui/components/messageList/types.js +2 -0
- package/dist/cli/ui/components/messageList/utils.js +7 -0
- package/dist/cli/ui/components/sidebar/FileContext.js +8 -0
- package/dist/cli/ui/components/sidebar/MissionControl.js +8 -0
- package/dist/cli/ui/config.js +59 -0
- package/dist/cli/ui/hooks/useCommandLifecycle.js +110 -0
- package/dist/cli/ui/hooks/useCommandSuggestions.js +87 -0
- package/dist/cli/ui/hooks/useInputHistory.js +57 -0
- package/dist/cli/ui/hooks/useLoopEvents.js +382 -0
- package/dist/cli/ui/hooks/useLoopState.js +73 -0
- package/dist/cli/ui/hooks/useOnionExit.js +31 -0
- package/dist/cli/ui/hooks/useTerminalDimensions.js +34 -0
- package/dist/cli/ui/index.js +136 -0
- package/dist/cli/ui/selection/bus.js +35 -0
- package/dist/cli/ui/status/formatStatusBanner.js +8 -0
- package/dist/cli/ui/store/context.js +17 -0
- package/dist/cli/ui/store/reducer.js +264 -0
- package/dist/cli/ui/store/types.js +81 -0
- package/dist/cli/ui/styles/theme.js +295 -0
- package/dist/cli/ui/types.js +2 -0
- package/dist/cli/ui/utils/sanitizer.js +122 -0
- package/dist/cli/ui/utils/transcript.js +28 -0
- package/dist/cli/utils/asyncQueue.js +125 -0
- package/dist/cli/utils/audit-scope.js +10 -0
- package/dist/cli/utils/detectors/index.js +38 -0
- package/dist/cli/utils/llm-output.js +34 -0
- package/dist/cli/utils/outcome-reporter.js +17 -0
- package/dist/cli/utils/safe-fs.js +184 -0
- package/dist/cli/utils/verify-resolver.js +34 -0
- package/dist/cli/utils/worktree-prepare-resolver.js +18 -0
- package/dist/core/adapters/fs/atomic-file-writer.js +129 -0
- package/dist/core/adapters/fs/file-adapter.js +95 -0
- package/dist/core/adapters/fs/filesystem.js +31 -0
- package/dist/core/adapters/fs/index.js +5 -0
- package/dist/core/adapters/fs/node-fs.js +7 -0
- package/dist/core/adapters/fs/readonly-filesystem.js +23 -0
- package/dist/core/adapters/git/git-adapter.js +704 -0
- package/dist/core/adapters/git/git-runner.js +119 -0
- package/dist/core/adapters/git/lock-manager.js +314 -0
- package/dist/core/adapters/git/types.js +2 -0
- package/dist/core/adapters/path/index.js +2 -0
- package/dist/core/adapters/path/path-adapter.js +23 -0
- package/dist/core/ast/guard.js +116 -0
- package/dist/core/ast/index.js +4 -0
- package/dist/core/ast/parser.js +284 -0
- package/dist/core/ast/validator.js +46 -0
- package/dist/core/backends/salmon-loop/task-executor.js +68 -0
- package/dist/core/checkpoint-domain/manifest-store.js +379 -0
- package/dist/core/checkpoint-domain/service.js +84 -0
- package/dist/core/checkpoint-domain/types.js +2 -0
- package/dist/core/config/defaults.js +50 -0
- package/dist/core/config/errors.js +11 -0
- package/dist/core/config/file-format.js +108 -0
- package/dist/core/config/index.js +7 -0
- package/dist/core/config/limits.js +77 -0
- package/dist/core/config/load.js +34 -0
- package/dist/core/config/normalize.js +35 -0
- package/dist/core/config/paths.js +20 -0
- package/dist/core/config/redact.js +16 -0
- package/dist/core/config/resolve-env.js +43 -0
- package/dist/core/config/resolve-llm.js +130 -0
- package/dist/core/config/resolve.js +68 -0
- package/dist/core/config/resolvers/ast-validation.js +8 -0
- package/dist/core/config/resolvers/context.js +21 -0
- package/dist/core/config/resolvers/observability.js +45 -0
- package/dist/core/config/resolvers/output.js +8 -0
- package/dist/core/config/resolvers/permission-mode.js +6 -0
- package/dist/core/config/resolvers/security.js +14 -0
- package/dist/core/config/resolvers/server.js +36 -0
- package/dist/core/config/resolvers/tool-authorization.js +39 -0
- package/dist/core/config/resolvers/ui.js +26 -0
- package/dist/core/config/types/config-file.js +2 -0
- package/dist/core/config/types/primitives.js +9 -0
- package/dist/core/config/types/resolved.js +2 -0
- package/dist/core/config/types.js +4 -0
- package/dist/core/config/validate.js +852 -0
- package/dist/core/context/assembly/default-prompt-assembler.js +7 -0
- package/dist/core/context/assembly/prompt-assembler.js +2 -0
- package/dist/core/context/ast/import-extractor.js +28 -0
- package/dist/core/context/ast/module-resolver.js +61 -0
- package/dist/core/context/ast/source-outline.js +25 -0
- package/dist/core/context/audit-constants.js +23 -0
- package/dist/core/context/audit.js +54 -0
- package/dist/core/context/budget/dynamic-adjuster.js +149 -0
- package/dist/core/context/budget/example-integration.js +49 -0
- package/dist/core/context/budget/integration.js +93 -0
- package/dist/core/context/builder.js +289 -0
- package/dist/core/context/cache/errors.js +16 -0
- package/dist/core/context/cache/incremental-updater.js +131 -0
- package/dist/core/context/cache/index.js +25 -0
- package/dist/core/context/cache/path-resolver.js +127 -0
- package/dist/core/context/cache/prompt-caching.js +207 -0
- package/dist/core/context/cache/store-factory.js +63 -0
- package/dist/core/context/cache/store.js +193 -0
- package/dist/core/context/cache/types.js +15 -0
- package/dist/core/context/compression/js-like-comments.js +139 -0
- package/dist/core/context/compression/smart-compress.js +61 -0
- package/dist/core/context/compression/whitespace.js +26 -0
- package/dist/core/context/dependencies.js +102 -0
- package/dist/core/context/effectiveness/index.js +25 -0
- package/dist/core/context/effectiveness/tracker.js +253 -0
- package/dist/core/context/effectiveness/types.js +15 -0
- package/dist/core/context/formatters/index.js +7 -0
- package/dist/core/context/formatters/json-converter.js +662 -0
- package/dist/core/context/formatters/types.js +6 -0
- package/dist/core/context/formatters/xml-context.js +296 -0
- package/dist/core/context/gatherers/architecture-gatherer.js +75 -0
- package/dist/core/context/gatherers/artifact-gatherer.js +53 -0
- package/dist/core/context/gatherers/ast-gatherer.js +370 -0
- package/dist/core/context/gatherers/ghost-dependency-gatherer.js +46 -0
- package/dist/core/context/gatherers/git-diff-gatherer.js +91 -0
- package/dist/core/context/gatherers/git-history-gatherer.js +57 -0
- package/dist/core/context/gatherers/knowledge-gatherer.js +101 -0
- package/dist/core/context/gatherers/metadata-gatherer.js +59 -0
- package/dist/core/context/gatherers/primary-text-gatherer.js +36 -0
- package/dist/core/context/gatherers/ripgrep-gatherer.js +104 -0
- package/dist/core/context/hash.js +52 -0
- package/dist/core/context/index.js +3 -0
- package/dist/core/context/keywords.js +179 -0
- package/dist/core/context/policies/budget-policy.js +36 -0
- package/dist/core/context/policies/pack-until-full.js +419 -0
- package/dist/core/context/scoring/relevance.js +191 -0
- package/dist/core/context/service-deps.js +32 -0
- package/dist/core/context/service-helpers.js +32 -0
- package/dist/core/context/service.js +265 -0
- package/dist/core/context/steps/context-budget.js +157 -0
- package/dist/core/context/steps/context-gather.js +71 -0
- package/dist/core/context/steps/context-primary.js +19 -0
- package/dist/core/context/steps/context-promotion.js +78 -0
- package/dist/core/context/steps/context-targets.js +85 -0
- package/dist/core/context/steps/types.js +2 -0
- package/dist/core/context/summarization/index.js +27 -0
- package/dist/core/context/summarization/prompts.js +80 -0
- package/dist/core/context/summarization/summarizer.js +377 -0
- package/dist/core/context/summarization/types.js +29 -0
- package/dist/core/context/targeting/churn-policy.js +27 -0
- package/dist/core/context/targeting/target-resolver.js +491 -0
- package/dist/core/context/token/adaptive-budget.js +364 -0
- package/dist/core/context/token/cache.js +163 -0
- package/dist/core/context/token/counter.js +190 -0
- package/dist/core/context/token/encoding-registry.js +173 -0
- package/dist/core/context/token/index.js +31 -0
- package/dist/core/context/token/token-budget.js +213 -0
- package/dist/core/context/token/types.js +10 -0
- package/dist/core/context/truncation/index.js +23 -0
- package/dist/core/context/truncation/semantic-truncator.js +103 -0
- package/dist/core/context/truncation/strategies/error-stack.js +94 -0
- package/dist/core/context/truncation/strategies/generic.js +48 -0
- package/dist/core/context/truncation/strategies/git-diff.js +99 -0
- package/dist/core/context/truncation/strategies/index.js +10 -0
- package/dist/core/context/truncation/strategies/json.js +142 -0
- package/dist/core/context/truncation/strategies/log.js +131 -0
- package/dist/core/context/truncation/strategies/test-result.js +140 -0
- package/dist/core/context/truncation/type-detector.js +133 -0
- package/dist/core/context/truncation/types.js +16 -0
- package/dist/core/context/types.js +2 -0
- package/dist/core/extensions/index.js +118 -0
- package/dist/core/extensions/load.js +36 -0
- package/dist/core/extensions/merge.js +29 -0
- package/dist/core/extensions/paths.js +40 -0
- package/dist/core/extensions/redact.js +37 -0
- package/dist/core/extensions/schemas.js +70 -0
- package/dist/core/extensions/types.js +2 -0
- package/dist/core/facades/cli-authorization-allowlist.js +3 -0
- package/dist/core/facades/cli-authorization-non-interactive.js +3 -0
- package/dist/core/facades/cli-authorization-provider.js +2 -0
- package/dist/core/facades/cli-chat.js +11 -0
- package/dist/core/facades/cli-command-allowlist.js +3 -0
- package/dist/core/facades/cli-command-chat.js +8 -0
- package/dist/core/facades/cli-command-checkpoint.js +3 -0
- package/dist/core/facades/cli-command-config.js +10 -0
- package/dist/core/facades/cli-command-dispatcher.js +2 -0
- package/dist/core/facades/cli-command-parallel.js +8 -0
- package/dist/core/facades/cli-command-session.js +2 -0
- package/dist/core/facades/cli-command-tool-names.js +6 -0
- package/dist/core/facades/cli-context.js +8 -0
- package/dist/core/facades/cli-headless.js +3 -0
- package/dist/core/facades/cli-observability.js +3 -0
- package/dist/core/facades/cli-program-bootstrap.js +2 -0
- package/dist/core/facades/cli-reporters.js +5 -0
- package/dist/core/facades/cli-run-execute.js +3 -0
- package/dist/core/facades/cli-run-handler.js +7 -0
- package/dist/core/facades/cli-run-headless-error-writer.js +2 -0
- package/dist/core/facades/cli-run-loop-params.js +2 -0
- package/dist/core/facades/cli-run-persist-session.js +2 -0
- package/dist/core/facades/cli-run-runtime-llm.js +5 -0
- package/dist/core/facades/cli-serve.js +21 -0
- package/dist/core/facades/cli-slash-runtime.js +9 -0
- package/dist/core/facades/cli-subagent.js +2 -0
- package/dist/core/facades/cli-ui.js +5 -0
- package/dist/core/facades/cli-utils-llm-output.js +3 -0
- package/dist/core/facades/cli-utils-path.js +2 -0
- package/dist/core/facades/cli-utils-worktree.js +2 -0
- package/dist/core/failure/diagnostics.js +221 -0
- package/dist/core/feedback/index.js +28 -0
- package/dist/core/feedback/parsers.js +59 -0
- package/dist/core/feedback/patterns.js +26 -0
- package/dist/core/feedback/types.js +2 -0
- package/dist/core/grizzco/domain/grizzco-types.js +41 -0
- package/dist/core/grizzco/dsl/DecisionEngine.js +149 -0
- package/dist/core/grizzco/dsl/MicroTaskRunner.js +39 -0
- package/dist/core/grizzco/dsl/llm-strategy.js +80 -0
- package/dist/core/grizzco/dsl/strategies.js +69 -0
- package/dist/core/grizzco/dsl/types.js +2 -0
- package/dist/core/grizzco/engine/observability/event-adapter.js +41 -0
- package/dist/core/grizzco/engine/observability/index.js +3 -0
- package/dist/core/grizzco/engine/observability/loop-telemetry.js +51 -0
- package/dist/core/grizzco/engine/outcome/index.js +2 -0
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +167 -0
- package/dist/core/grizzco/engine/pipeline/pipeline.js +335 -0
- package/dist/core/grizzco/engine/pipeline/types.js +2 -0
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +242 -0
- package/dist/core/grizzco/engine/transaction/authorization-summary.js +44 -0
- package/dist/core/grizzco/engine/transaction/index.js +3 -0
- package/dist/core/grizzco/engine/transaction/report-mapper.js +50 -0
- package/dist/core/grizzco/engine/transaction/retry-policy.js +19 -0
- package/dist/core/grizzco/engine/transaction/runner-builder.js +45 -0
- package/dist/core/grizzco/engine/transaction/session.js +58 -0
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +193 -0
- package/dist/core/grizzco/engine/transaction/types.js +2 -0
- package/dist/core/grizzco/execution/Executor.js +58 -0
- package/dist/core/grizzco/execution/RejectionManager.js +71 -0
- package/dist/core/grizzco/execution/WorkerFactory.js +31 -0
- package/dist/core/grizzco/flows/SalmonLoopFlow.js +102 -0
- package/dist/core/grizzco/runtime/apply-back-runtime.js +136 -0
- package/dist/core/grizzco/runtime/apply-back-utils.js +13 -0
- package/dist/core/grizzco/runtime/host/host-runner.js +99 -0
- package/dist/core/grizzco/runtime/host/index.js +2 -0
- package/dist/core/grizzco/runtime/host/types.js +2 -0
- package/dist/core/grizzco/services/CachedService.js +42 -0
- package/dist/core/grizzco/services/implementations/default/GitConfigService.js +38 -0
- package/dist/core/grizzco/services/implementations/mock/MockLockService.js +11 -0
- package/dist/core/grizzco/services/implementations/mock/MockUserQuotaService.js +11 -0
- package/dist/core/grizzco/services/registry.js +30 -0
- package/dist/core/grizzco/services/types.js +2 -0
- package/dist/core/grizzco/steps/answer.js +75 -0
- package/dist/core/grizzco/steps/apply-back.js +46 -0
- package/dist/core/grizzco/steps/apply.js +136 -0
- package/dist/core/grizzco/steps/ast-validate.js +37 -0
- package/dist/core/grizzco/steps/audit.js +311 -0
- package/dist/core/grizzco/steps/context.js +74 -0
- package/dist/core/grizzco/steps/display-answer.js +6 -0
- package/dist/core/grizzco/steps/display-report.js +158 -0
- package/dist/core/grizzco/steps/display-research.js +6 -0
- package/dist/core/grizzco/steps/displayReview.js +6 -0
- package/dist/core/grizzco/steps/explore.js +245 -0
- package/dist/core/grizzco/steps/extractIssues.js +27 -0
- package/dist/core/grizzco/steps/generateFixPlan.js +13 -0
- package/dist/core/grizzco/steps/generateReview.js +71 -0
- package/dist/core/grizzco/steps/patch.js +220 -0
- package/dist/core/grizzco/steps/plan.js +191 -0
- package/dist/core/grizzco/steps/preflight.js +93 -0
- package/dist/core/grizzco/steps/prepare-deps.js +49 -0
- package/dist/core/grizzco/steps/read-only-shrink.js +4 -0
- package/dist/core/grizzco/steps/research.js +188 -0
- package/dist/core/grizzco/steps/rollback.js +138 -0
- package/dist/core/grizzco/steps/shrink.js +64 -0
- package/dist/core/grizzco/steps/validate.js +40 -0
- package/dist/core/grizzco/steps/verify.js +136 -0
- package/dist/core/grizzco/validation/AstValidationService.js +133 -0
- package/dist/core/grizzco/validation/ContextValidator.js +17 -0
- package/dist/core/grizzco/validation/ast-validation-policy.js +11 -0
- package/dist/core/grizzco/workers/direct-write-worker.js +44 -0
- package/dist/core/grizzco/workers/git-apply-worker.js +75 -0
- package/dist/core/grizzco/workers/i-merge-worker.js +2 -0
- package/dist/core/grizzco/workers/mm-three-way-worker.js +117 -0
- package/dist/core/grizzco/workers/no-op-worker.js +18 -0
- package/dist/core/grizzco/workers/overwrite-binary-worker.js +29 -0
- package/dist/core/grizzco/workers/strata-sync-worker.js +69 -0
- package/dist/core/grizzco/workers/three-way-merge-worker.js +84 -0
- package/dist/core/grizzco/workers/three-way-staged-worker.js +93 -0
- package/dist/core/grizzco/workers/union-merge-worker.js +71 -0
- package/dist/core/history/input-history.js +55 -0
- package/dist/core/intent/chat-intent.js +250 -0
- package/dist/core/interaction/events/bus.js +52 -0
- package/dist/core/interaction/model/events.js +2 -0
- package/dist/core/interaction/model/index.js +3 -0
- package/dist/core/interaction/model/task-state.js +9 -0
- package/dist/core/interaction/model/transition-policy.js +50 -0
- package/dist/core/interaction/model/types.js +2 -0
- package/dist/core/interaction/orchestration/facade.js +190 -0
- package/dist/core/interaction/orchestration/index.js +2 -0
- package/dist/core/interaction/orchestration/store.js +32 -0
- package/dist/core/interaction/sync/task-sync-engine.js +57 -0
- package/dist/core/interaction/turn-stop-reason.js +27 -0
- package/dist/core/language-support/index.js +3 -0
- package/dist/core/language-support/orchestrator.js +37 -0
- package/dist/core/language-support/strategies/extension-candidate-strategy.js +27 -0
- package/dist/core/language-support/strategies/index.js +3 -0
- package/dist/core/language-support/strategies/language-query-strategy.js +26 -0
- package/dist/core/llm/ai-sdk/chat-executor.js +88 -0
- package/dist/core/llm/ai-sdk/langfuse-headers.js +28 -0
- package/dist/core/llm/ai-sdk/message-mapper.js +240 -0
- package/dist/core/llm/ai-sdk/observation-context.js +16 -0
- package/dist/core/llm/ai-sdk/provider-factory.js +29 -0
- package/dist/core/llm/ai-sdk/request-params.js +18 -0
- package/dist/core/llm/ai-sdk/request-runtime.js +168 -0
- package/dist/core/llm/ai-sdk/result-mapper.js +31 -0
- package/dist/core/llm/ai-sdk/retry-classifier.js +82 -0
- package/dist/core/llm/ai-sdk/retry-executor.js +38 -0
- package/dist/core/llm/ai-sdk.js +92 -0
- package/dist/core/llm/audit.js +2 -0
- package/dist/core/llm/base-url.js +18 -0
- package/dist/core/llm/contracts/repair.js +68 -0
- package/dist/core/llm/errors.js +172 -0
- package/dist/core/llm/factory.js +21 -0
- package/dist/core/llm/http/index.js +2 -0
- package/dist/core/llm/index.js +6 -0
- package/dist/core/llm/message-composition.js +25 -0
- package/dist/core/llm/openai.js +69 -0
- package/dist/core/llm/output-policy.js +192 -0
- package/dist/core/llm/phase-router.js +55 -0
- package/dist/core/llm/redact.js +37 -0
- package/dist/core/llm/registry.js +81 -0
- package/dist/core/llm/retry-utils.js +114 -0
- package/dist/core/llm/stream-utils.js +87 -0
- package/dist/core/llm/utils.js +82 -0
- package/dist/core/observability/audit-file.js +199 -0
- package/dist/core/observability/audit-trail.js +125 -0
- package/dist/core/observability/authorization-decisions.js +54 -0
- package/dist/core/observability/debug-artifacts.js +61 -0
- package/dist/core/observability/error-envelope.js +63 -0
- package/dist/core/observability/error-mapping.js +271 -0
- package/dist/core/observability/ignored-error.js +6 -0
- package/dist/core/observability/logger.js +457 -0
- package/dist/core/observability/loop-event-reporter.js +46 -0
- package/dist/core/observability/monitor.js +240 -0
- package/dist/core/observability/run-outcome-reporter.js +15 -0
- package/dist/core/observability/token-usage.js +36 -0
- package/dist/core/observability/ui-log-sanitize.js +35 -0
- package/dist/core/patch/aggregator.js +93 -0
- package/dist/core/patch/diff.js +298 -0
- package/dist/core/permission-gate/default-gate.js +115 -0
- package/dist/core/permission-gate/gate.js +2 -0
- package/dist/core/permission-gate/types.js +2 -0
- package/dist/core/plan/index.js +2 -0
- package/dist/core/plan/manager.js +123 -0
- package/dist/core/plan/markdown-editor.js +238 -0
- package/dist/core/plan/storage.js +75 -0
- package/dist/core/plan/types.js +2 -0
- package/dist/core/plugin/interface.js +2 -0
- package/dist/core/plugin/loader.js +130 -0
- package/dist/core/plugin/registry.js +90 -0
- package/dist/core/plugin/validator.js +98 -0
- package/dist/core/prompts/registry.js +189 -0
- package/dist/core/prompts/runtime.js +69 -0
- package/dist/core/prompts/schema.js +2 -0
- package/dist/core/prompts/templates/phases/explore_user.hbs +26 -0
- package/dist/core/prompts/templates/phases/patch_user.hbs +57 -0
- package/dist/core/prompts/templates/phases/plan_user.hbs +33 -0
- package/dist/core/prompts/templates/system/_context_json_legend.hbs +21 -0
- package/dist/core/prompts/templates/system/_tool_defs.hbs +60 -0
- package/dist/core/prompts/templates/system/explore_system.hbs +26 -0
- package/dist/core/prompts/templates/system/main_system.hbs +18 -0
- package/dist/core/prompts/templates/system/patch_system.hbs +10 -0
- package/dist/core/prompts/templates/system/plan_system.hbs +1 -0
- package/dist/core/prompts/templates/system/reflection.hbs +39 -0
- package/dist/core/protocols/a2a/agent-card.js +30 -0
- package/dist/core/protocols/a2a/mapper.js +14 -0
- package/dist/core/protocols/a2a/sdk/auth-middleware.js +31 -0
- package/dist/core/protocols/a2a/sdk/executor.js +301 -0
- package/dist/core/protocols/a2a/sdk/server.js +24 -0
- package/dist/core/protocols/a2a/task-projection.js +45 -0
- package/dist/core/protocols/acp/acp-command-runner.js +204 -0
- package/dist/core/protocols/acp/acp-filesystem.js +43 -0
- package/dist/core/protocols/acp/checkpoint-meta.js +2 -0
- package/dist/core/protocols/acp/formal-agent.js +1201 -0
- package/dist/core/protocols/acp/handlers.js +51 -0
- package/dist/core/protocols/acp/permission-provider.js +122 -0
- package/dist/core/protocols/acp/stdio-server.js +116 -0
- package/dist/core/reflection/engine.js +55 -0
- package/dist/core/reflection/types.js +2 -0
- package/dist/core/runtime/agent-server-runtime.js +88 -0
- package/dist/core/runtime/bun-runtime.js +26 -0
- package/dist/core/runtime/command-runner-context.js +16 -0
- package/dist/core/runtime/exit-codes.js +11 -0
- package/dist/core/runtime/fastify-fetch-bridge.js +51 -0
- package/dist/core/runtime/fastify-server-bundle.js +26 -0
- package/dist/core/runtime/initialize.js +132 -0
- package/dist/core/runtime/loop-finalize.js +71 -0
- package/dist/core/runtime/loop-run-lifecycle.js +73 -0
- package/dist/core/runtime/loop-run-reporter.js +19 -0
- package/dist/core/runtime/loop-runtime-config.js +26 -0
- package/dist/core/runtime/loop-session-runner.js +30 -0
- package/dist/core/runtime/loop.js +84 -0
- package/dist/core/runtime/paths.js +84 -0
- package/dist/core/runtime/process-runner.js +16 -0
- package/dist/core/runtime/process-types.js +2 -0
- package/dist/core/runtime/semaphore.js +41 -0
- package/dist/core/runtime/sidecar-fastify-plugin.js +35 -0
- package/dist/core/runtime/sidecar-paths.js +47 -0
- package/dist/core/runtime/sidecar-route-catalog.js +103 -0
- package/dist/core/runtime/spawn-command.js +392 -0
- package/dist/core/runtime/spawn-interactive.js +71 -0
- package/dist/core/security/redaction.js +160 -0
- package/dist/core/session/compression.js +323 -0
- package/dist/core/session/flow.js +85 -0
- package/dist/core/session/manager.js +313 -0
- package/dist/core/session/pruning-strategy.js +153 -0
- package/dist/core/session/session-context-builder.js +122 -0
- package/dist/core/session/summary-sync.js +82 -0
- package/dist/core/session/token-tracker.js +82 -0
- package/dist/core/session/types.js +2 -0
- package/dist/core/skills/bridge.js +33 -0
- package/dist/core/skills/index.js +8 -0
- package/dist/core/skills/loader.js +80 -0
- package/dist/core/skills/parser.js +66 -0
- package/dist/core/skills/runtime/MicroTaskRunner.js +102 -0
- package/dist/core/skills/runtime/SkillRunner.js +108 -0
- package/dist/core/skills/strategy.js +29 -0
- package/dist/core/skills/types.js +2 -0
- package/dist/core/slash/index.js +6 -0
- package/dist/core/slash/parser.js +33 -0
- package/dist/core/slash/registry.js +78 -0
- package/dist/core/slash/router.js +76 -0
- package/dist/core/slash/steps/slash-decide.js +19 -0
- package/dist/core/slash/steps/slash-execute.js +73 -0
- package/dist/core/slash/steps/types.js +2 -0
- package/dist/core/slash/strategy.js +33 -0
- package/dist/core/slash/types.js +2 -0
- package/dist/core/strata/checkpoint/manager.js +492 -0
- package/dist/core/strata/checkpoint/snapshot-audit.js +88 -0
- package/dist/core/strata/checkpoint/snapshot-create.js +79 -0
- package/dist/core/strata/checkpoint/snapshot-write-tree.js +72 -0
- package/dist/core/strata/engine/shadow-merge-engine.js +394 -0
- package/dist/core/strata/index.js +15 -0
- package/dist/core/strata/interaction/content-guardian.js +59 -0
- package/dist/core/strata/interaction/file-system-provider.js +89 -0
- package/dist/core/strata/layers/file-state-resolver.js +157 -0
- package/dist/core/strata/layers/immutable-git-layer.js +42 -0
- package/dist/core/strata/layers/shadow-driver/copy-backend.js +114 -0
- package/dist/core/strata/layers/shadow-driver/env.js +29 -0
- package/dist/core/strata/layers/shadow-driver/error-classifier.js +41 -0
- package/dist/core/strata/layers/shadow-driver/index.js +17 -0
- package/dist/core/strata/layers/shadow-driver/readonly-lock.js +221 -0
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +234 -0
- package/dist/core/strata/layers/shadow-driver/strategy.js +86 -0
- package/dist/core/strata/layers/sidecar-layer.js +96 -0
- package/dist/core/strata/layers/worktree.js +240 -0
- package/dist/core/strata/runtime/environment.js +377 -0
- package/dist/core/strata/runtime/synchronizer.js +819 -0
- package/dist/core/strata/types.js +46 -0
- package/dist/core/streaming/canonical/canonical-responses-event-emitter.js +326 -0
- package/dist/core/streaming/canonical/function-call-item-id.js +13 -0
- package/dist/core/streaming/canonical/parts-from-llm-stream-chunk.js +54 -0
- package/dist/core/streaming/canonical/responses-event-emitter.js +127 -0
- package/dist/core/streaming/canonical/responses-events.js +2 -0
- package/dist/core/streaming/normalized-events.js +9 -0
- package/dist/core/streaming/normalized-from-text.js +47 -0
- package/dist/core/streaming/stream-assembler.js +347 -0
- package/dist/core/structured-output/index.js +3 -0
- package/dist/core/structured-output/json-extract.js +70 -0
- package/dist/core/structured-output/json-schema-validator.js +90 -0
- package/dist/core/structured-output/types.js +2 -0
- package/dist/core/sub-agent/artifacts/store.js +141 -0
- package/dist/core/sub-agent/artifacts/types.js +2 -0
- package/dist/core/sub-agent/controller.js +69 -0
- package/dist/core/sub-agent/core/loop.js +79 -0
- package/dist/core/sub-agent/core/manager.js +246 -0
- package/dist/core/sub-agent/registry-defaults.js +52 -0
- package/dist/core/sub-agent/registry.js +35 -0
- package/dist/core/sub-agent/tools/task-spawn.js +29 -0
- package/dist/core/sub-agent/types.js +23 -0
- package/dist/core/target-runtime/command-resolver.js +42 -0
- package/dist/core/target-runtime/index.js +3 -0
- package/dist/core/target-runtime/profile.js +73 -0
- package/dist/core/testgen/detector.js +17 -0
- package/dist/core/testgen/index.js +38 -0
- package/dist/core/testgen/templates.js +46 -0
- package/dist/core/tools/audit.js +140 -0
- package/dist/core/tools/authorization/types.js +2 -0
- package/dist/core/tools/budget.js +118 -0
- package/dist/core/tools/builtin/artifact.js +29 -0
- package/dist/core/tools/builtin/ast-grep.js +107 -0
- package/dist/core/tools/builtin/ast.js +62 -0
- package/dist/core/tools/builtin/code-search/backends/powershell.js +84 -0
- package/dist/core/tools/builtin/code-search/backends/rg.js +85 -0
- package/dist/core/tools/builtin/code-search/executor.js +87 -0
- package/dist/core/tools/builtin/code-search/parse/plain-grep.js +59 -0
- package/dist/core/tools/builtin/code-search/parse/rg-json.js +31 -0
- package/dist/core/tools/builtin/code-search/spec.js +82 -0
- package/dist/core/tools/builtin/fs.js +243 -0
- package/dist/core/tools/builtin/git.js +118 -0
- package/dist/core/tools/builtin/index.js +80 -0
- package/dist/core/tools/builtin/interaction.js +120 -0
- package/dist/core/tools/builtin/knowledge.js +98 -0
- package/dist/core/tools/builtin/plan.js +148 -0
- package/dist/core/tools/builtin/proposal.js +207 -0
- package/dist/core/tools/builtin/shell.js +71 -0
- package/dist/core/tools/builtin/verify.js +41 -0
- package/dist/core/tools/capability/executor.js +84 -0
- package/dist/core/tools/capability/runner.js +50 -0
- package/dist/core/tools/capability/types.js +2 -0
- package/dist/core/tools/dispatcher.js +80 -0
- package/dist/core/tools/headless-payload.js +37 -0
- package/dist/core/tools/loader.js +100 -0
- package/dist/core/tools/mapper.js +142 -0
- package/dist/core/tools/mcp/client.js +308 -0
- package/dist/core/tools/mcp/loader.js +110 -0
- package/dist/core/tools/mcp/schema.js +54 -0
- package/dist/core/tools/mcp/streamable-http.js +101 -0
- package/dist/core/tools/mcp/types.js +26 -0
- package/dist/core/tools/parallel/isolation.js +25 -0
- package/dist/core/tools/parallel/lock-manager.js +124 -0
- package/dist/core/tools/parallel/persistence.js +126 -0
- package/dist/core/tools/parallel/plan-builder.js +66 -0
- package/dist/core/tools/parallel/plan.js +2 -0
- package/dist/core/tools/parallel/refs.js +7 -0
- package/dist/core/tools/parallel/resolve-args.js +50 -0
- package/dist/core/tools/parallel/resource-helpers.js +35 -0
- package/dist/core/tools/parallel/resources.js +2 -0
- package/dist/core/tools/parallel/scheduler.js +372 -0
- package/dist/core/tools/parser.js +89 -0
- package/dist/core/tools/permissions/permission-rules.js +503 -0
- package/dist/core/tools/plugins/loader.js +102 -0
- package/dist/core/tools/policy.js +87 -0
- package/dist/core/tools/registry.js +29 -0
- package/dist/core/tools/router.js +514 -0
- package/dist/core/tools/sanitize.js +78 -0
- package/dist/core/tools/schema-utils.js +71 -0
- package/dist/core/tools/session.js +1105 -0
- package/dist/core/tools/streaming/ToolCallAccumulator.js +64 -0
- package/dist/core/tools/types.js +2 -0
- package/dist/core/types/authorization.js +2 -0
- package/dist/core/types/context.js +2 -0
- package/dist/core/types/errors.js +29 -0
- package/dist/core/types/execution.js +65 -0
- package/dist/core/types/index.js +9 -0
- package/dist/core/types/llm.js +9 -0
- package/dist/core/types/loop.js +2 -0
- package/dist/core/types/planning.js +2 -0
- package/dist/core/types/runtime.js +2 -0
- package/dist/core/types/usage.js +2 -0
- package/dist/core/ui/kaomoji.js +5 -0
- package/dist/core/utils/path.js +116 -0
- package/dist/core/utils/platform-shell.js +10 -0
- package/dist/core/utils/sanitizer.js +107 -0
- package/dist/core/verification/runner.js +265 -0
- package/dist/integrations/langfuse/litellm-langfuse-outcome-reporter.js +272 -0
- package/dist/integrations/langfuse/outcome-proxy.js +68 -0
- package/dist/interfaces/cli/task-runner.js +11 -0
- package/dist/languages/typescript/index.js +178 -0
- package/dist/locales/en.js +679 -0
- package/dist/locales/index.js +11 -0
- package/dist/utils/eol.js +35 -0
- package/package.json +153 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import * as fsPromises from 'fs/promises';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { ensureInSandbox, safeJoin } from '../../core/facades/cli-utils-path.js';
|
|
5
|
+
function resolvePath(targetPath, rootContext) {
|
|
6
|
+
if (!rootContext)
|
|
7
|
+
return targetPath;
|
|
8
|
+
// Allow passing either absolute paths or paths relative to the root context.
|
|
9
|
+
const candidate = targetPath.startsWith(rootContext)
|
|
10
|
+
? targetPath
|
|
11
|
+
: safeJoin(rootContext, targetPath);
|
|
12
|
+
ensureInSandbox(rootContext, candidate);
|
|
13
|
+
return path.resolve(candidate);
|
|
14
|
+
}
|
|
15
|
+
async function resolveRealRoot(rootContext) {
|
|
16
|
+
try {
|
|
17
|
+
return await fsPromises.realpath(rootContext);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return path.resolve(rootContext);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function resolveRealRootSync(rootContext) {
|
|
24
|
+
try {
|
|
25
|
+
return fs.realpathSync(rootContext);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return path.resolve(rootContext);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function assertNoSymlinkEscape(resolvedPath, rootContext) {
|
|
32
|
+
if (!rootContext)
|
|
33
|
+
return;
|
|
34
|
+
const [realRoot, realTarget] = await Promise.all([
|
|
35
|
+
resolveRealRoot(rootContext),
|
|
36
|
+
fsPromises.realpath(resolvedPath),
|
|
37
|
+
]);
|
|
38
|
+
ensureInSandbox(realRoot, realTarget);
|
|
39
|
+
}
|
|
40
|
+
function assertNoSymlinkEscapeSync(resolvedPath, rootContext) {
|
|
41
|
+
if (!rootContext)
|
|
42
|
+
return;
|
|
43
|
+
const realRoot = resolveRealRootSync(rootContext);
|
|
44
|
+
const realTarget = fs.realpathSync(resolvedPath);
|
|
45
|
+
ensureInSandbox(realRoot, realTarget);
|
|
46
|
+
}
|
|
47
|
+
async function assertParentInSandbox(resolvedPath, rootContext) {
|
|
48
|
+
if (!rootContext)
|
|
49
|
+
return;
|
|
50
|
+
if (!fs.existsSync(rootContext))
|
|
51
|
+
return;
|
|
52
|
+
const realRoot = await resolveRealRoot(rootContext);
|
|
53
|
+
let current = path.dirname(resolvedPath);
|
|
54
|
+
let depth = 0;
|
|
55
|
+
while (depth < 40) {
|
|
56
|
+
try {
|
|
57
|
+
const realParent = await fsPromises.realpath(current);
|
|
58
|
+
ensureInSandbox(realRoot, realParent);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error && typeof error === 'object' && 'code' in error && error.code !== 'ENOENT')
|
|
63
|
+
throw error;
|
|
64
|
+
const next = path.dirname(current);
|
|
65
|
+
if (next === current) {
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
current = next;
|
|
69
|
+
depth += 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`Security Violation: Parent directory ascent exceeded limit for: ${resolvedPath}`);
|
|
73
|
+
}
|
|
74
|
+
async function assertNotSymlink(resolvedPath) {
|
|
75
|
+
try {
|
|
76
|
+
const stats = await fsPromises.lstat(resolvedPath);
|
|
77
|
+
if (stats.isSymbolicLink()) {
|
|
78
|
+
throw new Error(`Security Violation: Refusing to follow symlink: ${resolvedPath}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT')
|
|
83
|
+
return;
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function existsSync(targetPath, rootContext) {
|
|
88
|
+
try {
|
|
89
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
90
|
+
if (!fs.existsSync(resolved))
|
|
91
|
+
return false;
|
|
92
|
+
assertNoSymlinkEscapeSync(resolved, rootContext);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function stat(targetPath, rootContext) {
|
|
100
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
101
|
+
await assertNoSymlinkEscape(resolved, rootContext);
|
|
102
|
+
return fsPromises.stat(resolved);
|
|
103
|
+
}
|
|
104
|
+
export function statSync(targetPath, rootContext) {
|
|
105
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
106
|
+
assertNoSymlinkEscapeSync(resolved, rootContext);
|
|
107
|
+
return fs.statSync(resolved);
|
|
108
|
+
}
|
|
109
|
+
export async function readdirDirents(dirPath, rootContext) {
|
|
110
|
+
const resolved = resolvePath(dirPath, rootContext);
|
|
111
|
+
await assertNoSymlinkEscape(resolved, rootContext);
|
|
112
|
+
return fsPromises.readdir(resolved, { withFileTypes: true });
|
|
113
|
+
}
|
|
114
|
+
export function readdirDirentsSync(dirPath, rootContext) {
|
|
115
|
+
const resolved = resolvePath(dirPath, rootContext);
|
|
116
|
+
assertNoSymlinkEscapeSync(resolved, rootContext);
|
|
117
|
+
return fs.readdirSync(resolved, { withFileTypes: true });
|
|
118
|
+
}
|
|
119
|
+
export async function readdir(dirPath, rootContext) {
|
|
120
|
+
const resolved = resolvePath(dirPath, rootContext);
|
|
121
|
+
await assertNoSymlinkEscape(resolved, rootContext);
|
|
122
|
+
return fsPromises.readdir(resolved);
|
|
123
|
+
}
|
|
124
|
+
export async function readFileUtf8(targetPath, rootContext) {
|
|
125
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
126
|
+
await assertNoSymlinkEscape(resolved, rootContext);
|
|
127
|
+
return fsPromises.readFile(resolved, 'utf-8');
|
|
128
|
+
}
|
|
129
|
+
export function readFileUtf8Sync(targetPath, rootContext) {
|
|
130
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
131
|
+
assertNoSymlinkEscapeSync(resolved, rootContext);
|
|
132
|
+
return fs.readFileSync(resolved, 'utf-8');
|
|
133
|
+
}
|
|
134
|
+
export async function mkdirp(dirPath, rootContext) {
|
|
135
|
+
const resolved = resolvePath(dirPath, rootContext);
|
|
136
|
+
await assertParentInSandbox(resolved, rootContext);
|
|
137
|
+
await fsPromises.mkdir(resolved, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
export async function unlink(targetPath, rootContext) {
|
|
140
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
141
|
+
await assertParentInSandbox(resolved, rootContext);
|
|
142
|
+
await fsPromises.unlink(resolved);
|
|
143
|
+
}
|
|
144
|
+
export async function writeFileUtf8(targetPath, content, rootContext) {
|
|
145
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
146
|
+
await assertParentInSandbox(resolved, rootContext);
|
|
147
|
+
await assertNotSymlink(resolved);
|
|
148
|
+
await fsPromises.writeFile(resolved, content, 'utf-8');
|
|
149
|
+
}
|
|
150
|
+
export async function rename(fromPath, toPath, rootContext) {
|
|
151
|
+
const resolvedFrom = resolvePath(fromPath, rootContext);
|
|
152
|
+
const resolvedTo = resolvePath(toPath, rootContext);
|
|
153
|
+
await assertParentInSandbox(resolvedFrom, rootContext);
|
|
154
|
+
await assertParentInSandbox(resolvedTo, rootContext);
|
|
155
|
+
await fsPromises.rename(resolvedFrom, resolvedTo);
|
|
156
|
+
}
|
|
157
|
+
export async function copyFile(fromPath, toPath, rootContext) {
|
|
158
|
+
const resolvedFrom = resolvePath(fromPath, rootContext);
|
|
159
|
+
const resolvedTo = resolvePath(toPath, rootContext);
|
|
160
|
+
await assertNoSymlinkEscape(resolvedFrom, rootContext);
|
|
161
|
+
await assertParentInSandbox(resolvedTo, rootContext);
|
|
162
|
+
await assertNotSymlink(resolvedTo);
|
|
163
|
+
await fsPromises.copyFile(resolvedFrom, resolvedTo);
|
|
164
|
+
}
|
|
165
|
+
export async function openFile(targetPath, flags, rootContext) {
|
|
166
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
167
|
+
await assertParentInSandbox(resolved, rootContext);
|
|
168
|
+
return fsPromises.open(resolved, flags);
|
|
169
|
+
}
|
|
170
|
+
export async function realpath(targetPath, rootContext) {
|
|
171
|
+
const resolved = resolvePath(targetPath, rootContext);
|
|
172
|
+
const resolvedReal = await fsPromises.realpath(resolved);
|
|
173
|
+
if (rootContext) {
|
|
174
|
+
const realRoot = await resolveRealRoot(rootContext);
|
|
175
|
+
ensureInSandbox(realRoot, resolvedReal);
|
|
176
|
+
}
|
|
177
|
+
return resolvedReal;
|
|
178
|
+
}
|
|
179
|
+
export function safePathJoin(root, ...parts) {
|
|
180
|
+
const joined = safeJoin(root, ...parts);
|
|
181
|
+
ensureInSandbox(root, joined);
|
|
182
|
+
return path.resolve(joined);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=safe-fs.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getLogger } from '../../core/facades/cli-observability.js';
|
|
2
|
+
import { text } from '../../locales/index.js';
|
|
3
|
+
import { autoDetectVerifyCommand } from './detectors/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the verification command based on priority:
|
|
6
|
+
* 1. CLI explicit disable (--no-verify) -> undefined
|
|
7
|
+
* 2. CLI explicit command (--verify "cmd") -> "cmd"
|
|
8
|
+
* 3. Config file command -> "cmd"
|
|
9
|
+
* 4. Auto-detection -> "detected-cmd"
|
|
10
|
+
*/
|
|
11
|
+
export async function resolveVerifyOption(repoPath, cliVerify, configVerify) {
|
|
12
|
+
// 1. Explicitly disabled via --no-verify
|
|
13
|
+
// Commander sets options.verify to false when --no-verify is used
|
|
14
|
+
if (cliVerify === false) {
|
|
15
|
+
getLogger().debug(text.verify.explicitlyDisabled);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
// 2. Explicitly provided via CLI --verify "cmd"
|
|
19
|
+
if (typeof cliVerify === 'string') {
|
|
20
|
+
return cliVerify;
|
|
21
|
+
}
|
|
22
|
+
// 3. Provided via config file
|
|
23
|
+
if (configVerify) {
|
|
24
|
+
return configVerify;
|
|
25
|
+
}
|
|
26
|
+
// 4. Auto-detect
|
|
27
|
+
const detected = await autoDetectVerifyCommand(repoPath);
|
|
28
|
+
if (detected) {
|
|
29
|
+
getLogger().info(text.verify.autoDetected(detected));
|
|
30
|
+
return detected;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=verify-resolver.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getLogger } from '../../core/facades/cli-utils-worktree.js';
|
|
2
|
+
import { text } from '../../locales/index.js';
|
|
3
|
+
import { autoDetectWorktreePrepareCommand } from './detectors/index.js';
|
|
4
|
+
export async function resolveWorktreePrepareOption(repoPath, strategy, cliWorktreePrepare) {
|
|
5
|
+
if (typeof cliWorktreePrepare === 'string' && cliWorktreePrepare.trim()) {
|
|
6
|
+
return cliWorktreePrepare;
|
|
7
|
+
}
|
|
8
|
+
if (strategy !== 'worktree') {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const detected = await autoDetectWorktreePrepareCommand(repoPath);
|
|
12
|
+
if (detected) {
|
|
13
|
+
getLogger().info(text.verify.autoDetectedWorktreePrepare(detected));
|
|
14
|
+
return detected;
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=worktree-prepare-resolver.js.map
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { LIMITS } from '../../config/limits.js';
|
|
4
|
+
/**
|
|
5
|
+
* AtomicFileWriter
|
|
6
|
+
* Handles secure, atomic file writes with retries for platform compatibility.
|
|
7
|
+
*/
|
|
8
|
+
export class AtomicFileWriter {
|
|
9
|
+
retryConfig = {
|
|
10
|
+
maxAttempts: LIMITS.retry.io.maxAttempts,
|
|
11
|
+
baseDelay: LIMITS.retry.io.initialDelayMs,
|
|
12
|
+
maxDelay: LIMITS.retry.io.maxDelayMs,
|
|
13
|
+
backoffMultiplier: 2,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Write content atomically to a file.
|
|
17
|
+
* 1. Check for symlinks (Safety).
|
|
18
|
+
* 2. Write to temp file.
|
|
19
|
+
* 3. Rename temp file to target (Atomic).
|
|
20
|
+
*/
|
|
21
|
+
async writeAtomic(filePath, content) {
|
|
22
|
+
// filePath is expected to be absolute or relative to CWD.
|
|
23
|
+
// Given the new absolutePath in FileState, the caller (TransactionStrategy)
|
|
24
|
+
// passes context.file.path. We should probably verify what path is passed.
|
|
25
|
+
// TransactionStrategy passes `this.ctx.file.path`.
|
|
26
|
+
// We should probably update TransactionStrategy to pass `this.ctx.file.absolutePath`?
|
|
27
|
+
// Or AtomicFileWriter assumes it gets a path it can write to.
|
|
28
|
+
// If it receives relative path, it writes relative to CWD.
|
|
29
|
+
// It's safer to use absolute path everywhere.
|
|
30
|
+
// 1. Safety check
|
|
31
|
+
await this.ensureNoSymlink(filePath);
|
|
32
|
+
// 2. Ensure directory exists
|
|
33
|
+
const dir = path.dirname(filePath);
|
|
34
|
+
await fs.mkdir(dir, { recursive: true });
|
|
35
|
+
// 3. Write to temp file
|
|
36
|
+
const tempPath = await this.writeToTemp(filePath, content);
|
|
37
|
+
// 4. Atomic Rename with Retry
|
|
38
|
+
await this.atomicRename(tempPath, filePath);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Delete file atomically (with retries).
|
|
42
|
+
*/
|
|
43
|
+
async deleteAtomic(filePath) {
|
|
44
|
+
// 1. Safety check (ensure we are not deleting a symlink that points elsewhere?
|
|
45
|
+
// Actually we probably want to delete the symlink itself if it is one.)
|
|
46
|
+
// But ensureNoSymlink throws if it is a symlink.
|
|
47
|
+
// If the intent is to delete the file at path, and it is a symlink, we delete the link.
|
|
48
|
+
// If it's a directory, we fail (this is file writer).
|
|
49
|
+
await this.retryWithBackoff(async () => {
|
|
50
|
+
try {
|
|
51
|
+
await fs.unlink(filePath);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if ((error && typeof error === 'object' && 'code' in error
|
|
55
|
+
? error.code
|
|
56
|
+
: undefined) === 'ENOENT')
|
|
57
|
+
return; // Already gone
|
|
58
|
+
if ((error && typeof error === 'object' && 'code' in error
|
|
59
|
+
? error.code
|
|
60
|
+
: undefined) === 'EBUSY' ||
|
|
61
|
+
(error && typeof error === 'object' && 'code' in error
|
|
62
|
+
? error.code
|
|
63
|
+
: undefined) === 'EPERM') {
|
|
64
|
+
throw error; // Trigger retry
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Ensure target path is not a symlink to prevent TOCTOU attacks.
|
|
72
|
+
*/
|
|
73
|
+
async ensureNoSymlink(filePath) {
|
|
74
|
+
try {
|
|
75
|
+
const stats = await fs.lstat(filePath);
|
|
76
|
+
if (stats.isSymbolicLink()) {
|
|
77
|
+
throw new Error(`Refusing to write to symbolic link: ${filePath}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if ((error && typeof error === 'object' && 'code' in error
|
|
82
|
+
? error.code
|
|
83
|
+
: undefined) !== 'ENOENT') {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async writeToTemp(targetPath, content) {
|
|
89
|
+
const tempPath = `${targetPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
90
|
+
await fs.writeFile(tempPath, content, { mode: 0o644, flag: 'w' });
|
|
91
|
+
return tempPath;
|
|
92
|
+
}
|
|
93
|
+
async atomicRename(tempPath, targetPath) {
|
|
94
|
+
await this.retryWithBackoff(async () => {
|
|
95
|
+
try {
|
|
96
|
+
await fs.rename(tempPath, targetPath);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if ((error && typeof error === 'object' && 'code' in error
|
|
100
|
+
? error.code
|
|
101
|
+
: undefined) === 'EBUSY' ||
|
|
102
|
+
(error && typeof error === 'object' && 'code' in error
|
|
103
|
+
? error.code
|
|
104
|
+
: undefined) === 'EPERM') {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`Atomic rename failed: ${error instanceof Error ? error.message : String(error)} (${tempPath} -> ${targetPath})`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async retryWithBackoff(fn) {
|
|
112
|
+
let lastError = null;
|
|
113
|
+
for (let attempt = 0; attempt < this.retryConfig.maxAttempts; attempt++) {
|
|
114
|
+
try {
|
|
115
|
+
await fn();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
120
|
+
if (attempt === this.retryConfig.maxAttempts - 1)
|
|
121
|
+
break;
|
|
122
|
+
const delay = Math.min(this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt), this.retryConfig.maxDelay);
|
|
123
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
throw lastError;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=atomic-file-writer.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { promises as fs, constants } from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { AtomicFileWriter } from './atomic-file-writer.js';
|
|
4
|
+
/**
|
|
5
|
+
* Unified file system adapter for all file operations.
|
|
6
|
+
* Provides both atomic and non-atomic operations with consistent error handling.
|
|
7
|
+
*/
|
|
8
|
+
export class FileAdapter {
|
|
9
|
+
atomicWriter = new AtomicFileWriter();
|
|
10
|
+
/**
|
|
11
|
+
* Read file (non-atomic, for configuration/session files)
|
|
12
|
+
*/
|
|
13
|
+
async readFile(filePath, encoding = 'utf-8') {
|
|
14
|
+
return fs.readFile(filePath, encoding);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Write file (non-atomic, for application data)
|
|
18
|
+
* Use this for session files, configs, logs where atomicity is not required
|
|
19
|
+
*/
|
|
20
|
+
async writeFile(filePath, content) {
|
|
21
|
+
const dir = path.dirname(filePath);
|
|
22
|
+
await fs.mkdir(dir, { recursive: true });
|
|
23
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Write file atomically (for user code modifications)
|
|
27
|
+
* Use this when modifying user's source code
|
|
28
|
+
*/
|
|
29
|
+
async writeFileAtomic(filePath, content) {
|
|
30
|
+
return this.atomicWriter.writeAtomic(filePath, content);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Append to file (non-atomic, for logs)
|
|
34
|
+
*/
|
|
35
|
+
async appendFile(filePath, content) {
|
|
36
|
+
const dir = path.dirname(filePath);
|
|
37
|
+
await fs.mkdir(dir, { recursive: true });
|
|
38
|
+
await fs.appendFile(filePath, content, 'utf-8');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if file exists
|
|
42
|
+
*/
|
|
43
|
+
async exists(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(filePath);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve real path (follows symlinks).
|
|
54
|
+
*/
|
|
55
|
+
async realpath(filePath) {
|
|
56
|
+
return fs.realpath(filePath);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Read directory
|
|
60
|
+
*/
|
|
61
|
+
async readdir(dirPath) {
|
|
62
|
+
return fs.readdir(dirPath);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Read directory entries with file type metadata.
|
|
66
|
+
*/
|
|
67
|
+
async readdirWithTypes(dirPath) {
|
|
68
|
+
return fs.readdir(dirPath, { withFileTypes: true });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get file stats
|
|
72
|
+
*/
|
|
73
|
+
async stat(filePath) {
|
|
74
|
+
return fs.stat(filePath);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create directory recursively
|
|
78
|
+
*/
|
|
79
|
+
async mkdir(dirPath) {
|
|
80
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Delete file atomically (with retries)
|
|
84
|
+
*/
|
|
85
|
+
async deleteFile(filePath) {
|
|
86
|
+
return this.atomicWriter.deleteAtomic(filePath);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check permissions/access for a file or directory.
|
|
90
|
+
*/
|
|
91
|
+
async access(filePath, mode = constants.R_OK | constants.W_OK) {
|
|
92
|
+
await fs.access(filePath, mode);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=file-adapter.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FileAdapter } from './file-adapter.js';
|
|
2
|
+
import { ReadOnlyFileSystem } from './readonly-filesystem.js';
|
|
3
|
+
class FileAdapterFileSystem {
|
|
4
|
+
adapter;
|
|
5
|
+
constructor(adapter = new FileAdapter()) {
|
|
6
|
+
this.adapter = adapter;
|
|
7
|
+
}
|
|
8
|
+
async readFile(path, encoding = 'utf-8') {
|
|
9
|
+
return this.adapter.readFile(path, encoding);
|
|
10
|
+
}
|
|
11
|
+
async writeFile(path, content) {
|
|
12
|
+
await this.adapter.writeFile(path, content);
|
|
13
|
+
}
|
|
14
|
+
async exists(path) {
|
|
15
|
+
return this.adapter.exists(path);
|
|
16
|
+
}
|
|
17
|
+
async mkdir(path, _options) {
|
|
18
|
+
await this.adapter.mkdir(path);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a FileSystem adapter based on the specified FlowMode.
|
|
23
|
+
* Review mode returns a ReadOnlyFileSystem to block writes.
|
|
24
|
+
*/
|
|
25
|
+
export function createFileSystemAdapter(mode, realFs = new FileAdapterFileSystem()) {
|
|
26
|
+
if (mode === 'review' || mode === 'research' || mode === 'answer') {
|
|
27
|
+
return new ReadOnlyFileSystem(realFs);
|
|
28
|
+
}
|
|
29
|
+
return realFs;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AtomicFileWriter } from './atomic-file-writer.js';
|
|
2
|
+
export { FileAdapter } from './file-adapter.js';
|
|
3
|
+
export { createFileSystemAdapter } from './filesystem.js';
|
|
4
|
+
export { ReadOnlyFileSystem } from './readonly-filesystem.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as fsPromises from 'fs/promises';
|
|
3
|
+
export const promises = fsPromises;
|
|
4
|
+
export const syncFs = Object.assign({}, fs, fsPromises);
|
|
5
|
+
export const { access, appendFile, chmod, chown, copyFile, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, stat, symlink, unlink, utimes, writeFile, } = fsPromises;
|
|
6
|
+
export const { existsSync, readFileSync, realpathSync } = fs;
|
|
7
|
+
//# sourceMappingURL=node-fs.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { text } from '../../../locales/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* FileSystem adapter that blocks write operations.
|
|
4
|
+
*/
|
|
5
|
+
export class ReadOnlyFileSystem {
|
|
6
|
+
realFs;
|
|
7
|
+
constructor(realFs) {
|
|
8
|
+
this.realFs = realFs;
|
|
9
|
+
}
|
|
10
|
+
async readFile(path, encoding) {
|
|
11
|
+
return this.realFs.readFile(path, encoding);
|
|
12
|
+
}
|
|
13
|
+
async writeFile(_path, _content) {
|
|
14
|
+
throw new Error(text.grizzco.errors.readOnlyFileSystem('writeFile'));
|
|
15
|
+
}
|
|
16
|
+
async exists(path) {
|
|
17
|
+
return this.realFs.exists(path);
|
|
18
|
+
}
|
|
19
|
+
async mkdir(_path, _options) {
|
|
20
|
+
throw new Error(text.grizzco.errors.readOnlyFileSystem('mkdir'));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=readonly-filesystem.js.map
|