@automaton-labs/aib 0.0.6 → 0.0.8
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/README.md +36 -257
- package/config/agent-dx-policy.default.json +31 -0
- package/config/control-plane-client.default.json +3 -0
- package/dist/agent-dx/agent-dx.js +805 -0
- package/dist/agent-dx/presentation.js +32 -0
- package/dist/alias-advisor/analyze.js +982 -0
- package/dist/alias-advisor/exact-text-cost.js +74 -0
- package/dist/alias-advisor/lexical.js +240 -0
- package/dist/alias-advisor/model.js +2 -0
- package/dist/alias-advisor/path-identity.js +49 -0
- package/dist/alias-advisor/ranking.js +171 -0
- package/dist/alias-advisor/token-estimator.js +85 -0
- package/dist/bin/aib.js +5 -1
- package/dist/bin/cli.js +811 -2
- package/dist/commands/add-missing-imports-preview-cache.js +99 -2
- package/dist/commands/add-missing-imports.js +241 -2
- package/dist/commands/apply-module-plan.js +1319 -3
- package/dist/commands/background-command.js +378 -0
- package/dist/commands/captured-input.js +74 -2
- package/dist/commands/config-command.js +314 -2
- package/dist/commands/config-output.js +357 -10
- package/dist/commands/control-plane-command.js +183 -0
- package/dist/commands/declaration-command.js +1209 -0
- package/dist/commands/declaration-execution-cache.js +79 -0
- package/dist/commands/declaration-format.js +221 -0
- package/dist/commands/declaration-preview-cache.js +114 -0
- package/dist/commands/diagnostics-command.js +70 -3
- package/dist/commands/doctor.js +137 -2
- package/dist/commands/execution-command.js +117 -1
- package/dist/commands/exports-star-collapse-command.js +178 -0
- package/dist/commands/exports-star-command.js +252 -0
- package/dist/commands/exports-star-preview-cache.js +84 -0
- package/dist/commands/feedback-command.js +176 -3
- package/dist/commands/file-move-to-dir-execution-cache.js +92 -0
- package/dist/commands/file-move-to-dir-preview-cache.js +125 -0
- package/dist/commands/file-move-to-dir-worker.js +54 -0
- package/dist/commands/file-move-to-dir.js +1073 -0
- package/dist/commands/file-mutation-runtime.js +102 -0
- package/dist/commands/file-mutation-worker-apply.js +180 -0
- package/dist/commands/file-refactor-batch-execution-cache.js +90 -0
- package/dist/commands/file-refactor-batch-preview-cache.js +125 -0
- package/dist/commands/file-refactor-batch-worker.js +54 -0
- package/dist/commands/file-refactor-batch.js +1154 -0
- package/dist/commands/file-rename-execution-cache.js +92 -0
- package/dist/commands/file-rename-preview-cache.js +125 -0
- package/dist/commands/file-rename-worker.js +54 -0
- package/dist/commands/file-rename.js +1053 -0
- package/dist/commands/file-text-edit-executor.js +205 -0
- package/dist/commands/find-importers.js +52 -1
- package/dist/commands/find-unused-imports.js +55 -1
- package/dist/commands/generate-docs-command.js +244 -6
- package/dist/commands/help-command.js +460 -7
- package/dist/commands/import-specifier-policy.js +391 -0
- package/dist/commands/imports-command.js +68 -1
- package/dist/commands/imports-rebase.js +1138 -0
- package/dist/commands/init-skill-usage.js +92 -3
- package/dist/commands/init-workspace.js +30 -1
- package/dist/commands/inspect-alias-candidates.js +413 -0
- package/dist/commands/inspect-cycles.js +811 -5
- package/dist/commands/inspect-direct-usages.js +98 -0
- package/dist/commands/inspect-duplicates-format.js +229 -0
- package/dist/commands/inspect-format-primitives.js +127 -0
- package/dist/commands/inspect-format.js +1590 -18
- package/dist/commands/inspect-graph.js +1553 -9
- package/dist/commands/inspect-imports.js +339 -2
- package/dist/commands/inspect-mixed-format.js +524 -0
- package/dist/commands/inspect-module-plan-format.js +216 -0
- package/dist/commands/inspect-module-plan-serialization.js +402 -0
- package/dist/commands/inspect-reference-path-format.js +157 -0
- package/dist/commands/inspect-request-values.js +599 -0
- package/dist/commands/inspect-selector-kind.js +21 -0
- package/dist/commands/inspect-selector.js +50 -0
- package/dist/commands/inspect-symbol-format.js +90 -0
- package/dist/commands/inspect-topology.js +435 -0
- package/dist/commands/inspect-tree.js +827 -5
- package/dist/commands/inspect-usages-detail.js +793 -0
- package/dist/commands/inspect-usages-evidence.js +31 -0
- package/dist/commands/inspect-usages-format.js +367 -0
- package/dist/commands/inspect.js +1450 -16
- package/dist/commands/internal-command.js +64 -0
- package/dist/commands/json-file-input.js +60 -1
- package/dist/commands/module-plan-cache.js +156 -2
- package/dist/commands/module-plan-standalone.js +208 -0
- package/dist/commands/module-plan-timeout.js +77 -1
- package/dist/commands/move-preview-cache.js +101 -2
- package/dist/commands/mutate-aggregate-output.js +996 -0
- package/dist/commands/mutate-child-execution.js +374 -0
- package/dist/commands/mutate-command.js +1394 -0
- package/dist/commands/mutate-declaration-output.js +313 -0
- package/dist/commands/mutate-domain-adapters.js +638 -0
- package/dist/commands/mutate-execution-cache.js +114 -0
- package/dist/commands/mutate-execution-status.js +598 -0
- package/dist/commands/mutate-failure-output.js +531 -0
- package/dist/commands/mutate-file-view.js +151 -0
- package/dist/commands/mutate-object-output.js +91 -0
- package/dist/commands/mutate-output-values.js +97 -0
- package/dist/commands/mutate-preview-cache.js +86 -0
- package/dist/commands/mutate-response-replay.js +153 -0
- package/dist/commands/mutate-result-projection.js +818 -0
- package/dist/commands/mutation-eta.js +28 -0
- package/dist/commands/mutation-execution-cache.js +140 -3
- package/dist/commands/mutation-recovery-journal.js +195 -0
- package/dist/commands/normalize-imports.js +1120 -4
- package/dist/commands/object-pack-command.js +546 -0
- package/dist/commands/object-pack-preview-cache.js +88 -0
- package/dist/commands/observability-command.js +47 -3
- package/dist/commands/ota-command.js +403 -0
- package/dist/commands/print-config.js +10 -1
- package/dist/commands/quick-read.js +1113 -11
- package/dist/commands/refactor-batch-builder.js +265 -1
- package/dist/commands/refactor-batch-execution-cache.js +85 -1
- package/dist/commands/refactor-batch-preview-cache.js +96 -2
- package/dist/commands/refactor-batch.js +461 -4
- package/dist/commands/rename-entities.js +794 -4
- package/dist/commands/rename-execution-cache.js +49 -1
- package/dist/commands/rename-input.js +22 -1
- package/dist/commands/rename-polling-policy.js +68 -0
- package/dist/commands/rename-preview-cache.js +96 -2
- package/dist/commands/result-view.js +993 -6
- package/dist/commands/reveal-command.js +445 -5
- package/dist/commands/selector-suggestions.js +93 -0
- package/dist/commands/session-workspace.js +1836 -31
- package/dist/commands/shared.js +2 -1
- package/dist/commands/skills-command.js +315 -0
- package/dist/commands/sync-command.js +59 -2
- package/dist/commands/worker-command.js +173 -0
- package/dist/commands/workspace-cache.js +55 -1
- package/dist/config/defaults.js +26 -1
- package/dist/config/env-vars.js +77 -1
- package/dist/config/glob-match.js +44 -1
- package/dist/config/import-rules.js +165 -1
- package/dist/config/local-config.js +293 -3
- package/dist/config/mutation-comments.js +51 -1
- package/dist/config/path-aliases.js +165 -1
- package/dist/config/path-display.js +84 -1
- package/dist/config/product-storage.js +37 -1
- package/dist/config/request-env.js +21 -0
- package/dist/config/request-routing-context.js +23 -0
- package/dist/config/resolve-command-alias.js +74 -1
- package/dist/config/resolve.js +24 -1
- package/dist/config/tsconfig-discovery.js +113 -1
- package/dist/config/typescript-preferences.js +131 -0
- package/dist/config/workspace-root.js +310 -3
- package/dist/config/workspace-state.js +254 -1
- package/dist/content/content-bundle.js +88 -1
- package/dist/diagnostics/module-plan-timeline.js +75 -2
- package/dist/diagnostics/readiness-text.js +45 -8
- package/dist/dsl/aib-dsl.js +838 -1
- package/dist/dsl/declaration-dsl.js +264 -0
- package/dist/dsl/file-move-to-dir-dsl.js +123 -0
- package/dist/dsl/file-refactor-batch-dsl.js +203 -0
- package/dist/dsl/file-rename-dsl.js +135 -0
- package/dist/dsl/mutate-dsl.js +746 -0
- package/dist/help/bootstrap.bash.md +742 -0
- package/dist/help/bootstrap.md +236 -437
- package/dist/help/bootstrap.pwsh.md +742 -0
- package/dist/help/docs/basics.md +1 -1
- package/dist/help/docs/config-setup.import-normalize.md +65 -65
- package/dist/help/docs/config-setup.import-rules.md +6 -5
- package/dist/help/docs/dsl.md +4 -3
- package/dist/help/docs/first-setup.md +6 -5
- package/dist/help/docs/help-protocol.md +4 -3
- package/dist/help/docs/import.base.md +38 -0
- package/dist/help/docs/import.rebase.md +85 -0
- package/dist/help/docs/inspect.aliasCandidates.md +39 -0
- package/dist/help/docs/inspect.code.md +5 -11
- package/dist/help/docs/inspect.deps.md +7 -7
- package/dist/help/docs/inspect.file.md +10 -18
- package/dist/help/docs/inspect.graph.md +6 -20
- package/dist/help/docs/{inspect.md → inspect.shared.md} +18 -17
- package/dist/help/docs/modulePlan.md +24 -28
- package/dist/help/docs/move.md +19 -22
- package/dist/help/docs/moveToDir.md +46 -0
- package/dist/help/docs/mutate.mixed.md +34 -0
- package/dist/help/docs/mutation.shared.md +55 -0
- package/dist/help/docs/patterns.md +3 -16
- package/dist/help/docs/qr.md +13 -22
- package/dist/help/docs/quick-map.md +36 -23
- package/dist/help/docs/recipe.file-layout.md +15 -0
- package/dist/help/docs/recipe.import-boundary.md +92 -0
- package/dist/help/docs/recipe.safe-artifact-probing.md +68 -0
- package/dist/help/docs/recipe.unfamiliar-area.md +64 -0
- package/dist/help/docs/recipes.md +20 -0
- package/dist/help/docs/rename.md +19 -27
- package/dist/help/docs/renameFile.md +36 -0
- package/dist/help/docs/rg.md +22 -0
- package/dist/help/docs/rules.md +26 -0
- package/dist/help/docs/selectors.md +3 -2
- package/dist/help/docs/session.md +1 -1
- package/dist/help/dsl/bootstrap.bash.md +742 -0
- package/dist/help/dsl/bootstrap.md +236 -437
- package/dist/help/dsl/bootstrap.pwsh.md +742 -0
- package/dist/help/dsl/docs/basics.md +1 -1
- package/dist/help/dsl/docs/config-setup.import-normalize.md +65 -65
- package/dist/help/dsl/docs/config-setup.import-rules.md +6 -5
- package/dist/help/dsl/docs/dsl.md +4 -3
- package/dist/help/dsl/docs/first-setup.md +6 -5
- package/dist/help/dsl/docs/help-protocol.md +4 -3
- package/dist/help/dsl/docs/import.base.md +38 -0
- package/dist/help/dsl/docs/import.rebase.md +85 -0
- package/dist/help/dsl/docs/inspect.aliasCandidates.md +39 -0
- package/dist/help/dsl/docs/inspect.code.md +5 -11
- package/dist/help/dsl/docs/inspect.deps.md +7 -7
- package/dist/help/dsl/docs/inspect.file.md +10 -18
- package/dist/help/dsl/docs/inspect.graph.md +6 -20
- package/dist/help/dsl/docs/{inspect.md → inspect.shared.md} +18 -17
- package/dist/help/dsl/docs/modulePlan.md +24 -28
- package/dist/help/dsl/docs/move.md +19 -22
- package/dist/help/dsl/docs/moveToDir.md +46 -0
- package/dist/help/dsl/docs/mutate.mixed.md +34 -0
- package/dist/help/dsl/docs/mutation.shared.md +55 -0
- package/dist/help/dsl/docs/patterns.md +3 -16
- package/dist/help/dsl/docs/qr.md +13 -22
- package/dist/help/dsl/docs/quick-map.md +36 -23
- package/dist/help/dsl/docs/recipe.file-layout.md +15 -0
- package/dist/help/dsl/docs/recipe.import-boundary.md +92 -0
- package/dist/help/dsl/docs/recipe.safe-artifact-probing.md +68 -0
- package/dist/help/dsl/docs/recipe.unfamiliar-area.md +64 -0
- package/dist/help/dsl/docs/recipes.md +20 -0
- package/dist/help/dsl/docs/rename.md +19 -27
- package/dist/help/dsl/docs/renameFile.md +36 -0
- package/dist/help/dsl/docs/rg.md +22 -0
- package/dist/help/dsl/docs/rules.md +26 -0
- package/dist/help/dsl/docs/selectors.md +3 -2
- package/dist/help/dsl/docs/session.md +1 -1
- package/dist/help/dsl/full.md +236 -437
- package/dist/help/dsl/help-index.md +49 -0
- package/dist/help/dsl/snippets/agents.md +2 -2
- package/dist/help/dsl/tokens/qr.inline.examples.md +2 -0
- package/dist/help/dsl/tokens/stdin.examples.bash.md +8 -0
- package/dist/help/dsl/tokens/stdin.examples.pwsh.md +8 -0
- package/dist/help/dsl/tokens/stdin.examples.with-qr.bash.md +12 -0
- package/dist/help/dsl/tokens/stdin.examples.with-qr.pwsh.md +12 -0
- package/dist/help/dsl/topics/basics.md +1 -1
- package/dist/help/dsl/topics/config-setup.import-normalize.md +65 -65
- package/dist/help/dsl/topics/config-setup.import-rules.md +6 -5
- package/dist/help/dsl/topics/dsl.md +4 -3
- package/dist/help/dsl/topics/first-setup.md +6 -5
- package/dist/help/dsl/topics/help-protocol.md +4 -3
- package/dist/help/dsl/topics/import.base.md +36 -0
- package/dist/help/dsl/topics/import.rebase.md +83 -0
- package/dist/help/dsl/topics/inspect.aliasCandidates.md +37 -0
- package/dist/help/dsl/topics/inspect.code.md +5 -11
- package/dist/help/dsl/topics/inspect.deps.md +7 -7
- package/dist/help/dsl/topics/inspect.file.md +10 -18
- package/dist/help/dsl/topics/inspect.graph.md +6 -20
- package/dist/help/dsl/topics/{inspect.md → inspect.shared.md} +18 -17
- package/dist/help/dsl/topics/modulePlan.md +21 -26
- package/dist/help/dsl/topics/move.md +17 -18
- package/dist/help/dsl/topics/moveToDir.md +44 -0
- package/dist/help/dsl/topics/mutate.mixed.md +32 -0
- package/dist/help/dsl/topics/mutation.shared.md +53 -0
- package/dist/help/dsl/topics/patterns.md +3 -16
- package/dist/help/dsl/topics/qr.md +13 -22
- package/dist/help/dsl/topics/quick-map.md +36 -23
- package/dist/help/dsl/topics/recipe.file-layout.md +13 -0
- package/dist/help/dsl/topics/recipe.import-boundary.md +90 -0
- package/dist/help/dsl/topics/recipe.safe-artifact-probing.md +66 -0
- package/dist/help/dsl/topics/recipe.unfamiliar-area.md +62 -0
- package/dist/help/dsl/topics/recipes.md +18 -0
- package/dist/help/dsl/topics/rename.md +15 -15
- package/dist/help/dsl/topics/renameFile.md +34 -0
- package/dist/help/dsl/topics/rg.md +20 -0
- package/dist/help/dsl/topics/rules.md +24 -0
- package/dist/help/dsl/topics/selectors.md +3 -2
- package/dist/help/dsl/topics/session.md +1 -1
- package/dist/help/full.md +236 -437
- package/dist/help/help-index.md +49 -0
- package/dist/help/help-meta.json +114 -48
- package/dist/help/index.md +76 -87
- package/dist/help/snippets/agents.md +2 -2
- package/dist/help/tokens/qr.inline.examples.md +2 -0
- package/dist/help/tokens/stdin.examples.bash.md +8 -0
- package/dist/help/tokens/stdin.examples.pwsh.md +8 -0
- package/dist/help/tokens/stdin.examples.with-qr.bash.md +12 -0
- package/dist/help/tokens/stdin.examples.with-qr.pwsh.md +12 -0
- package/dist/help/topics/basics.md +1 -1
- package/dist/help/topics/config-setup.import-normalize.md +65 -65
- package/dist/help/topics/config-setup.import-rules.md +6 -5
- package/dist/help/topics/dsl.md +4 -3
- package/dist/help/topics/first-setup.md +6 -5
- package/dist/help/topics/help-protocol.md +4 -3
- package/dist/help/topics/import.base.md +36 -0
- package/dist/help/topics/import.rebase.md +83 -0
- package/dist/help/topics/inspect.aliasCandidates.md +37 -0
- package/dist/help/topics/inspect.code.md +5 -11
- package/dist/help/topics/inspect.deps.md +7 -7
- package/dist/help/topics/inspect.file.md +10 -18
- package/dist/help/topics/inspect.graph.md +6 -20
- package/dist/help/topics/{inspect.md → inspect.shared.md} +18 -17
- package/dist/help/topics/modulePlan.md +21 -26
- package/dist/help/topics/move.md +17 -18
- package/dist/help/topics/moveToDir.md +44 -0
- package/dist/help/topics/mutate.mixed.md +32 -0
- package/dist/help/topics/mutation.shared.md +53 -0
- package/dist/help/topics/patterns.md +3 -16
- package/dist/help/topics/qr.md +13 -22
- package/dist/help/topics/quick-map.md +36 -23
- package/dist/help/topics/recipe.file-layout.md +13 -0
- package/dist/help/topics/recipe.import-boundary.md +90 -0
- package/dist/help/topics/recipe.safe-artifact-probing.md +66 -0
- package/dist/help/topics/recipe.unfamiliar-area.md +62 -0
- package/dist/help/topics/recipes.md +18 -0
- package/dist/help/topics/rename.md +15 -15
- package/dist/help/topics/renameFile.md +34 -0
- package/dist/help/topics/rg.md +20 -0
- package/dist/help/topics/rules.md +24 -0
- package/dist/help/topics/selectors.md +3 -2
- package/dist/help/topics/session.md +1 -1
- package/dist/host/capabilities.js +56 -0
- package/dist/imports/standalone-import-analysis.js +602 -0
- package/dist/imports/standalone-import-model.js +2 -0
- package/dist/imports/standalone-import-process.js +66 -0
- package/dist/imports/standalone-import-worker.js +27 -0
- package/dist/imports/standalone-ts-project.js +147 -0
- package/dist/inspect/inspect-duplicates-service.js +526 -0
- package/dist/inspect/inspect-reverse-module-closure.js +338 -0
- package/dist/inspect/inspect-source-ranges.js +82 -0
- package/dist/inspect/inspect-source-shape.js +649 -0
- package/dist/inspect/standalone-inspect-analysis.js +319 -0
- package/dist/inspect/standalone-inspect-model.js +9 -0
- package/dist/inspect/standalone-inspect-process.js +55 -0
- package/dist/inspect/standalone-inspect-usages.js +274 -0
- package/dist/inspect/standalone-inspect-worker.js +13 -0
- package/dist/metrics/central-metrics.js +101 -2
- package/dist/mutation/concrete-edit-plan.js +157 -0
- package/dist/mutation/exports-star-collapse-preview.js +361 -0
- package/dist/mutation/exports-star-expand-apply.js +373 -0
- package/dist/mutation/exports-star-expand-preview.js +807 -0
- package/dist/mutation/file-impact-scan.js +182 -0
- package/dist/mutation/file-mutation-discovery.js +674 -0
- package/dist/mutation/file-mutation-eta.js +99 -0
- package/dist/mutation/file-mutation-standalone-apply.js +584 -0
- package/dist/mutation/file-mutation-standalone-planner.js +500 -0
- package/dist/mutation/file-mutation-tsserver-session.js +473 -0
- package/dist/mutation/mutation-estimate.js +45 -0
- package/dist/mutation/mutation-plan.js +467 -0
- package/dist/mutation/object-mutation-foundation.js +2 -0
- package/dist/mutation/object-mutation-partition.js +148 -0
- package/dist/mutation/object-pack-semantic-apply.js +507 -0
- package/dist/mutation/object-pack-semantic-preview.js +984 -0
- package/dist/mutation/object-unpack-semantic-preview.js +993 -0
- package/dist/mutation/package-manifest-impact.js +176 -0
- package/dist/mutation/rename-owner-worker-child.js +37 -0
- package/dist/mutation/rename-owner-worker.js +122 -0
- package/dist/mutation/runtime-cycle-query.js +66 -0
- package/dist/mutation/semantic-execution-progress.js +63 -0
- package/dist/mutation/semantic-export-index.js +474 -0
- package/dist/mutation/semantic-impact-scan.js +434 -0
- package/dist/mutation/semantic-model.js +2 -0
- package/dist/mutation/semantic-move-best-effort-planner.js +209 -0
- package/dist/mutation/semantic-move-config-worker-child.js +61 -0
- package/dist/mutation/semantic-move-config-worker.js +449 -0
- package/dist/mutation/semantic-move-declarations.js +94 -0
- package/dist/mutation/semantic-move-metrics.js +119 -0
- package/dist/mutation/semantic-move-model.js +2 -0
- package/dist/mutation/semantic-move-owner-authority.js +122 -0
- package/dist/mutation/semantic-move-owner-candidates.js +300 -0
- package/dist/mutation/semantic-move-owner-divergence-harness.js +474 -0
- package/dist/mutation/semantic-move-owner-divergence-runner.js +162 -0
- package/dist/mutation/semantic-move-plan-hash.js +56 -0
- package/dist/mutation/semantic-move-policy.js +360 -0
- package/dist/mutation/semantic-move-process.js +218 -0
- package/dist/mutation/semantic-move-provider-diagnostics.js +27 -0
- package/dist/mutation/semantic-move-standalone-engine.js +919 -0
- package/dist/mutation/semantic-move-standalone-planner.js +1553 -0
- package/dist/mutation/semantic-move-transaction.js +639 -0
- package/dist/mutation/semantic-mutation-engine.js +478 -0
- package/dist/mutation/semantic-mutation-runtime.js +521 -0
- package/dist/mutation/semantic-planner-retry.js +26 -0
- package/dist/mutation/semantic-program-roots.js +69 -0
- package/dist/mutation/semantic-rename-commonjs.js +229 -0
- package/dist/mutation/semantic-rename-config-worker-child.js +46 -0
- package/dist/mutation/semantic-rename-config-worker.js +498 -0
- package/dist/mutation/semantic-rename-locations.js +192 -0
- package/dist/mutation/semantic-rename-model.js +2 -0
- package/dist/mutation/semantic-rename-process.js +210 -0
- package/dist/mutation/semantic-rename-standalone-engine.js +302 -0
- package/dist/mutation/semantic-rename-standalone-planner.js +567 -0
- package/dist/mutation/semantic-rename-transaction.js +333 -0
- package/dist/mutation/semantic-unused-import-cleanup.js +248 -0
- package/dist/mutation/semantic-worker-retry.js +40 -0
- package/dist/mutation/semantic-workspace.js +804 -0
- package/dist/mutation/targeted-import-canonicalizer.js +359 -0
- package/dist/observability/config.js +206 -1
- package/dist/observability/context.js +59 -1
- package/dist/observability/failure-snapshot.js +124 -2
- package/dist/observability/recent.js +63 -2
- package/dist/payloads/read-stdin-json.js +212 -1
- package/dist/rg-wrapper/core.js +714 -0
- package/dist/rg-wrapper/options.js +125 -0
- package/dist/rtk-wrapper/core.js +144 -0
- package/dist/rtk-wrapper/git-safety.js +203 -0
- package/dist/rtk-wrapper/output-adapter.js +106 -0
- package/dist/runtime/buffered-process.js +114 -0
- package/dist/runtime/bundled-node.js +97 -1
- package/dist/runtime/command-lifecycle.js +2 -0
- package/dist/runtime/input-source.js +238 -1
- package/dist/runtime/node-cli-identity.js +37 -0
- package/dist/runtime/run-command.js +191 -1
- package/dist/selectors/parse-entities.js +84 -1
- package/dist/semantic/semantic-context-pool.js +830 -0
- package/dist/semantic/semantic-context-provider.js +416 -0
- package/dist/semantic/semantic-resident-admission.js +38 -0
- package/dist/semantic/semantic-worker-child.js +40 -0
- package/dist/semantic/semantic-worker-manager.js +460 -0
- package/dist/semantic/semantic-worker-protocol.js +2 -0
- package/dist/semantic/semantic-worker-runtime.js +38 -0
- package/dist/semantic/workspace-semantic-context-pools.js +136 -0
- package/dist/session/client.js +359 -1
- package/dist/session/daemon-state.js +185 -0
- package/dist/session/external-tool-coordinator.js +88 -0
- package/dist/session/external-tool-request.js +52 -0
- package/dist/session/lane-owner.js +116 -0
- package/dist/session/paths.js +71 -1
- package/dist/session/runtime-lifecycle.js +225 -0
- package/dist/session/runtime-shutdown.js +95 -0
- package/dist/session/server.js +1194 -8
- package/dist/session/session-health.js +27 -0
- package/dist/shared/agent-text.js +29 -1
- package/dist/shared/errors.js +496 -30
- package/dist/shared/event-loop.js +6 -1
- package/dist/shared/hints.js +37 -1
- package/dist/shared/metrics.js +43 -1
- package/dist/shared/presentation.js +69 -4
- package/dist/shared/stdin-examples.js +77 -3
- package/dist/shared/stdout.js +6 -2
- package/dist/shared/types.js +23 -1
- package/dist/tool-runtime/runtime-tools.js +120 -0
- package/dist/topology/availability.js +663 -0
- package/dist/topology/cache.js +130 -0
- package/dist/topology/candidates.js +372 -0
- package/dist/topology/core.js +903 -0
- package/dist/topology/dependency-snapshot.js +189 -0
- package/dist/topology/model.js +2 -0
- package/dist/topology/scope.js +100 -0
- package/dist/topology/ts-oracle-batch.js +529 -0
- package/dist/topology/ts-oracle-host.js +69 -0
- package/dist/topology/ts-oracle-model.js +2 -0
- package/dist/topology/ts-oracle.js +224 -0
- package/dist/topology/tsconfig-loader.js +105 -0
- package/dist/topology/workspace-project-index.js +542 -0
- package/dist/tracing/config.js +192 -2
- package/dist/tracing/failure-summary.js +100 -0
- package/dist/tracing/trace.js +318 -5
- package/dist/tsc-wrapper/core.js +697 -0
- package/dist/workers/control-plane/aib-control-plane-worker.cjs +80 -0
- package/dist/workers/control-plane/client-config.default.json +3 -0
- package/dist/workers/lexical-worker-child.js +27 -0
- package/dist/workers/lexical-worker-manager.js +394 -0
- package/dist/workers/lexical-worker-protocol.js +2 -0
- package/dist/workers/lexical-worker-runtime.js +25 -0
- package/dist/workers/owned-one-shot-process.js +115 -0
- package/dist/workers/product-storage.js +23 -0
- package/dist/workers/registry.js +241 -0
- package/package.json +8 -11
- package/runtimes/tools/rg/darwin-arm64/rg +0 -0
- package/runtimes/tools/rg/darwin-x64/rg +0 -0
- package/runtimes/tools/rg/linux-arm64/rg +0 -0
- package/runtimes/tools/rg/linux-x64/rg +0 -0
- package/runtimes/tools/rg/manifest.json +36 -0
- package/runtimes/tools/rg/win32-x64/rg.exe +0 -0
- package/runtimes/tools/rtk/darwin-arm64/rtk +0 -0
- package/runtimes/tools/rtk/darwin-x64/rtk +0 -0
- package/runtimes/tools/rtk/linux-arm64/rtk +0 -0
- package/runtimes/tools/rtk/linux-x64/rtk +0 -0
- package/runtimes/tools/rtk/manifest.json +36 -0
- package/runtimes/tools/rtk/win32-x64/rtk.exe +0 -0
- package/scripts/postinstall.cjs +29 -29
- package/scripts/provision-runtime.cjs +411 -459
- package/dist/client/http-client.js +0 -1
- package/dist/client/transport-options.js +0 -1
- package/dist/client/websocket-client.js +0 -1
- package/dist/commands/entity-resolution.js +0 -1
- package/dist/commands/inspect-symbol-query.js +0 -1
- package/dist/commands/list-instances.js +0 -1
- package/dist/commands/module-plan-command.js +0 -1
- package/dist/commands/move-command.js +0 -1
- package/dist/commands/move-to-file.js +0 -2
- package/dist/commands/ping.js +0 -1
- package/dist/commands/refactor-command.js +0 -1
- package/dist/commands/rename-command.js +0 -1
- package/dist/commands/runtime-command.js +0 -4
- package/dist/commands/runtime-info.js +0 -1
- package/dist/commands/validate-module-plan.js +0 -2
- package/dist/compatibility/policy.js +0 -1
- package/dist/config/auto-start-ide.js +0 -1
- package/dist/discovery/registry.js +0 -1
- package/dist/discovery/select-instance.js +0 -1
- package/dist/help/docs/mutation.md +0 -50
- package/dist/help/docs/refactor.batch.md +0 -44
- package/dist/help/dsl/docs/mutation.md +0 -50
- package/dist/help/dsl/docs/refactor.batch.md +0 -44
- package/dist/help/dsl/topics/mutation.md +0 -48
- package/dist/help/dsl/topics/refactor.batch.md +0 -33
- package/dist/help/json/bootstrap.md +0 -1085
- package/dist/help/json/docs/basics.md +0 -15
- package/dist/help/json/docs/config-setup.aliases.md +0 -56
- package/dist/help/json/docs/config-setup.excludes.md +0 -45
- package/dist/help/json/docs/config-setup.import-normalize.md +0 -86
- package/dist/help/json/docs/config-setup.import-rules.md +0 -96
- package/dist/help/json/docs/config-setup.tsconfigs.md +0 -33
- package/dist/help/json/docs/dsl.md +0 -25
- package/dist/help/json/docs/first-setup.md +0 -292
- package/dist/help/json/docs/help-format.md +0 -9
- package/dist/help/json/docs/help-protocol.md +0 -26
- package/dist/help/json/docs/imports.normalize.md +0 -47
- package/dist/help/json/docs/inspect.code.md +0 -41
- package/dist/help/json/docs/inspect.cycles.md +0 -38
- package/dist/help/json/docs/inspect.deps.md +0 -46
- package/dist/help/json/docs/inspect.duplicates.md +0 -65
- package/dist/help/json/docs/inspect.exports.md +0 -40
- package/dist/help/json/docs/inspect.file.md +0 -38
- package/dist/help/json/docs/inspect.graph.md +0 -139
- package/dist/help/json/docs/inspect.imports.md +0 -15
- package/dist/help/json/docs/inspect.md +0 -88
- package/dist/help/json/docs/inspect.members.md +0 -32
- package/dist/help/json/docs/inspect.tree.md +0 -32
- package/dist/help/json/docs/inspect.usages.md +0 -61
- package/dist/help/json/docs/modulePlan.md +0 -73
- package/dist/help/json/docs/move.md +0 -56
- package/dist/help/json/docs/mutation.md +0 -65
- package/dist/help/json/docs/patterns.md +0 -76
- package/dist/help/json/docs/prefs.md +0 -40
- package/dist/help/json/docs/qr.md +0 -37
- package/dist/help/json/docs/quick-map.md +0 -30
- package/dist/help/json/docs/refactor.batch.md +0 -72
- package/dist/help/json/docs/rename.md +0 -47
- package/dist/help/json/docs/reveal.md +0 -30
- package/dist/help/json/docs/selectors.md +0 -23
- package/dist/help/json/docs/session.md +0 -77
- package/dist/help/json/docs/view.md +0 -30
- package/dist/help/json/full.md +0 -1085
- package/dist/help/json/snippets/agents.md +0 -14
- package/dist/help/json/topics/basics.md +0 -13
- package/dist/help/json/topics/config-setup.aliases.md +0 -54
- package/dist/help/json/topics/config-setup.excludes.md +0 -43
- package/dist/help/json/topics/config-setup.import-normalize.md +0 -84
- package/dist/help/json/topics/config-setup.import-rules.md +0 -94
- package/dist/help/json/topics/config-setup.tsconfigs.md +0 -31
- package/dist/help/json/topics/dsl.md +0 -23
- package/dist/help/json/topics/first-setup.md +0 -290
- package/dist/help/json/topics/help-format.md +0 -7
- package/dist/help/json/topics/help-protocol.md +0 -24
- package/dist/help/json/topics/imports.normalize.md +0 -45
- package/dist/help/json/topics/inspect.code.md +0 -39
- package/dist/help/json/topics/inspect.cycles.md +0 -36
- package/dist/help/json/topics/inspect.deps.md +0 -44
- package/dist/help/json/topics/inspect.duplicates.md +0 -37
- package/dist/help/json/topics/inspect.exports.md +0 -38
- package/dist/help/json/topics/inspect.file.md +0 -36
- package/dist/help/json/topics/inspect.graph.md +0 -137
- package/dist/help/json/topics/inspect.imports.md +0 -13
- package/dist/help/json/topics/inspect.md +0 -86
- package/dist/help/json/topics/inspect.members.md +0 -30
- package/dist/help/json/topics/inspect.tree.md +0 -22
- package/dist/help/json/topics/inspect.usages.md +0 -59
- package/dist/help/json/topics/modulePlan.md +0 -60
- package/dist/help/json/topics/move.md +0 -46
- package/dist/help/json/topics/mutation.md +0 -63
- package/dist/help/json/topics/patterns.md +0 -74
- package/dist/help/json/topics/prefs.md +0 -38
- package/dist/help/json/topics/qr.md +0 -35
- package/dist/help/json/topics/quick-map.md +0 -28
- package/dist/help/json/topics/refactor.batch.md +0 -61
- package/dist/help/json/topics/rename.md +0 -42
- package/dist/help/json/topics/reveal.md +0 -28
- package/dist/help/json/topics/selectors.md +0 -21
- package/dist/help/json/topics/session.md +0 -59
- package/dist/help/json/topics/view.md +0 -28
- package/dist/help/topics/mutation.md +0 -48
- package/dist/help/topics/refactor.batch.md +0 -33
- package/dist/ide-launch/common.cjs +0 -162
- package/dist/managed-host/extension-vsix-resolver.js +0 -1
- package/dist/managed-host/manage-serve-web-host.cjs +0 -141
- package/dist/managed-host/serve-web-autostart.js +0 -1
- package/dist/managed-host/serve-web-host.cjs +0 -1904
- package/dist/runtime/managed-runtime-provisioning.js +0 -1
- package/dist/shared/diagnostic-catalog.js +0 -1
- package/dist/shared/diagnostics.js +0 -1
- package/dist/shared/operations.js +0 -1
- package/dist/shared/protocol.js +0 -1
- package/dist/shared/routes.js +0 -1
- package/extension/vscode-refactor-bridge-extension.vsix +0 -0
- package/runtimes/launcher/linux-x64/aib +0 -0
- package/runtimes/launcher/win-x64/aib.exe +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.estimateFileMutationDurationMs = estimateFileMutationDurationMs;
|
|
4
|
+
exports.estimateFileMutationEta = estimateFileMutationEta;
|
|
5
|
+
exports.estimateFileMutationDefaultDurationMs = estimateFileMutationDefaultDurationMs;
|
|
6
|
+
exports.estimateFileMutationScanDurationMs = estimateFileMutationScanDurationMs;
|
|
7
|
+
const FILE_MUTATION_SCAN_MIN_MS = 10_000;
|
|
8
|
+
const FILE_MUTATION_SCAN_MAX_MS = 180_000;
|
|
9
|
+
const FILE_MUTATION_SCAN_BASE_MS = 4_000;
|
|
10
|
+
const FILE_MUTATION_SCAN_ROW_MS = 500;
|
|
11
|
+
const FILE_MUTATION_SCAN_ADDITIONAL_SOURCE_MS = 5_000;
|
|
12
|
+
const FILE_MUTATION_SCAN_TARGET_DIR_MS = 500;
|
|
13
|
+
const FILE_MUTATION_SCAN_DIR_TO_CREATE_MS = 500;
|
|
14
|
+
const FILE_MUTATION_SCAN_IMPORTING_FILE_MS = 200;
|
|
15
|
+
const FILE_MUTATION_SCAN_IMPORTING_FILE_SQRT_MS = 1_750;
|
|
16
|
+
const FILE_MUTATION_SCAN_EXTRA_IMPORT_STATEMENT_MS = 15;
|
|
17
|
+
const FILE_MUTATION_SCAN_BARREL_EXPORT_MS = 200;
|
|
18
|
+
function estimateFileMutationDurationMs(input) {
|
|
19
|
+
return estimateFileMutationEta(toEtaInput(input)).selectedMs;
|
|
20
|
+
}
|
|
21
|
+
function estimateFileMutationEta(input) {
|
|
22
|
+
const normalized = normalizeInput(input);
|
|
23
|
+
const defaultMs = estimateFileMutationDefaultDurationMs(normalized);
|
|
24
|
+
const scanMs = estimateFileMutationScanDurationMs(normalized);
|
|
25
|
+
const scan = buildScanStatus(normalized);
|
|
26
|
+
return {
|
|
27
|
+
defaultMs,
|
|
28
|
+
scanMs,
|
|
29
|
+
selectedMs: scanMs ?? defaultMs,
|
|
30
|
+
source: scanMs === null ? "default" : "scan",
|
|
31
|
+
scan
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function estimateFileMutationDefaultDurationMs(input) {
|
|
35
|
+
const normalized = normalizeInput(input);
|
|
36
|
+
return 90_000 +
|
|
37
|
+
normalized.rowCount * 25_000 +
|
|
38
|
+
normalized.targetDirCount * 5_000 +
|
|
39
|
+
normalized.dirsToCreate * 5_000;
|
|
40
|
+
}
|
|
41
|
+
function estimateFileMutationScanDurationMs(input) {
|
|
42
|
+
const normalized = normalizeInput(input);
|
|
43
|
+
const scan = buildScanStatus(normalized);
|
|
44
|
+
if (!scan.available) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const additionalSourceCount = Math.max(0, normalized.sourceFileCount - 1);
|
|
48
|
+
const extraImportStatementCount = Math.max(0, normalized.importStatementCount - normalized.importingFileCount);
|
|
49
|
+
return clampMs(FILE_MUTATION_SCAN_BASE_MS +
|
|
50
|
+
normalized.rowCount * FILE_MUTATION_SCAN_ROW_MS +
|
|
51
|
+
additionalSourceCount * FILE_MUTATION_SCAN_ADDITIONAL_SOURCE_MS +
|
|
52
|
+
normalized.targetDirCount * FILE_MUTATION_SCAN_TARGET_DIR_MS +
|
|
53
|
+
normalized.dirsToCreate * FILE_MUTATION_SCAN_DIR_TO_CREATE_MS +
|
|
54
|
+
Math.sqrt(normalized.importingFileCount) * FILE_MUTATION_SCAN_IMPORTING_FILE_SQRT_MS +
|
|
55
|
+
normalized.importingFileCount * FILE_MUTATION_SCAN_IMPORTING_FILE_MS +
|
|
56
|
+
extraImportStatementCount * FILE_MUTATION_SCAN_EXTRA_IMPORT_STATEMENT_MS +
|
|
57
|
+
normalized.barrelExportCount * FILE_MUTATION_SCAN_BARREL_EXPORT_MS, FILE_MUTATION_SCAN_MIN_MS, FILE_MUTATION_SCAN_MAX_MS);
|
|
58
|
+
}
|
|
59
|
+
function buildScanStatus(input) {
|
|
60
|
+
const reason = input.scanTruncated
|
|
61
|
+
? "truncated"
|
|
62
|
+
: input.sourceFileCount <= 0
|
|
63
|
+
? "no-source-files"
|
|
64
|
+
: input.existingSourceFileCount <= 0
|
|
65
|
+
? "missing-source-files"
|
|
66
|
+
: "ok";
|
|
67
|
+
return {
|
|
68
|
+
available: reason === "ok",
|
|
69
|
+
reason,
|
|
70
|
+
importingFileCount: input.importingFileCount,
|
|
71
|
+
importStatementCount: input.importStatementCount,
|
|
72
|
+
barrelExportCount: input.barrelExportCount,
|
|
73
|
+
sourceFileCount: input.sourceFileCount,
|
|
74
|
+
existingSourceFileCount: input.existingSourceFileCount,
|
|
75
|
+
truncated: input.scanTruncated
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function toEtaInput(input) {
|
|
79
|
+
return typeof input === "number" ? { rowCount: input } : input;
|
|
80
|
+
}
|
|
81
|
+
function normalizeInput(input) {
|
|
82
|
+
return {
|
|
83
|
+
rowCount: readCount(input.rowCount),
|
|
84
|
+
targetDirCount: readCount(input.targetDirCount),
|
|
85
|
+
dirsToCreate: readCount(input.dirsToCreate),
|
|
86
|
+
importingFileCount: readCount(input.importingFileCount),
|
|
87
|
+
importStatementCount: readCount(input.importStatementCount),
|
|
88
|
+
barrelExportCount: readCount(input.barrelExportCount),
|
|
89
|
+
sourceFileCount: readCount(input.sourceFileCount),
|
|
90
|
+
existingSourceFileCount: readCount(input.existingSourceFileCount),
|
|
91
|
+
scanTruncated: input.scanTruncated === true
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function readCount(value) {
|
|
95
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
|
|
96
|
+
}
|
|
97
|
+
function clampMs(value, minMs, maxMs) {
|
|
98
|
+
return Math.min(maxMs, Math.max(minMs, Math.round(value)));
|
|
99
|
+
}
|
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.applyStandaloneFileMutationTransaction = applyStandaloneFileMutationTransaction;
|
|
40
|
+
exports.removeUnusedImportBindings = removeUnusedImportBindings;
|
|
41
|
+
const crypto = __importStar(require("node:crypto"));
|
|
42
|
+
const fs = __importStar(require("node:fs"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
45
|
+
const import_rules_1 = require("../config/import-rules");
|
|
46
|
+
const file_text_edit_executor_1 = require("../commands/file-text-edit-executor");
|
|
47
|
+
const file_mutation_discovery_1 = require("./file-mutation-discovery");
|
|
48
|
+
const targeted_import_canonicalizer_1 = require("./targeted-import-canonicalizer");
|
|
49
|
+
function applyStandaloneFileMutationTransaction(input, dependencies = {
|
|
50
|
+
fs,
|
|
51
|
+
computeWorkspaceFingerprint: file_mutation_discovery_1.computeFileMutationWorkspaceFingerprint
|
|
52
|
+
}) {
|
|
53
|
+
if (!input.plan.complete) {
|
|
54
|
+
return failure(input.plan.code, input.plan.error ?? "Standalone file mutation plan is incomplete.");
|
|
55
|
+
}
|
|
56
|
+
const root = path.resolve(input.workspaceRoot);
|
|
57
|
+
const sourceFile = path.resolve(root, input.sourceFile);
|
|
58
|
+
const targetFile = path.resolve(root, input.targetFile);
|
|
59
|
+
const snapshots = new Map(input.plan.fileSnapshots.map((item) => [pathKey(item.file), item]));
|
|
60
|
+
try {
|
|
61
|
+
if (dependencies.computeWorkspaceFingerprint(root) !== input.plan.workspaceFingerprint) {
|
|
62
|
+
return failure("FILE_MUTATION_COMMIT_PREFLIGHT_STALE", "Workspace files, configs, or package metadata changed before apply.");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return failure("FILE_MUTATION_COMMIT_PREFLIGHT_FAILED", error instanceof Error ? error.message : String(error));
|
|
67
|
+
}
|
|
68
|
+
if (!dependencies.fs.existsSync(sourceFile) || !dependencies.fs.statSync(sourceFile).isFile()) {
|
|
69
|
+
return failure("FILE_MUTATION_SOURCE_CHANGED", "Source file is missing or is no longer a file.");
|
|
70
|
+
}
|
|
71
|
+
if (dependencies.fs.existsSync(targetFile)) {
|
|
72
|
+
return failure("FILE_MUTATION_TARGET_CHANGED", "Target path exists immediately before apply.");
|
|
73
|
+
}
|
|
74
|
+
if (input.plan.targetSnapshot.exists || !samePath(input.plan.targetSnapshot.file, targetFile)) {
|
|
75
|
+
return failure("FILE_MUTATION_TARGET_SNAPSHOT_MISMATCH", "Planner target snapshot does not authorize this target path.");
|
|
76
|
+
}
|
|
77
|
+
const originals = new Map();
|
|
78
|
+
for (const snapshot of input.plan.fileSnapshots) {
|
|
79
|
+
let text;
|
|
80
|
+
try {
|
|
81
|
+
text = dependencies.fs.readFileSync(snapshot.file, "utf8");
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return failure("FILE_MUTATION_TOUCHED_FILE_CHANGED", `Planned file disappeared before apply: ${snapshot.file}`);
|
|
85
|
+
}
|
|
86
|
+
if (sha256(text) !== snapshot.hash) {
|
|
87
|
+
return failure("FILE_MUTATION_TOUCHED_FILE_CHANGED", `Planned file changed before apply: ${snapshot.file}`);
|
|
88
|
+
}
|
|
89
|
+
originals.set(pathKey(snapshot.file), text);
|
|
90
|
+
}
|
|
91
|
+
if (!snapshots.has(pathKey(sourceFile))) {
|
|
92
|
+
return failure("FILE_MUTATION_SOURCE_SNAPSHOT_MISSING", "Planner did not publish the source file snapshot.");
|
|
93
|
+
}
|
|
94
|
+
const changesByFile = new Map();
|
|
95
|
+
for (const edit of input.plan.edits) {
|
|
96
|
+
const key = pathKey(edit.fileName);
|
|
97
|
+
if (!snapshots.has(key)) {
|
|
98
|
+
return failure("FILE_MUTATION_EDIT_SNAPSHOT_MISSING", `Planner edit lacks an exact snapshot: ${edit.fileName}`);
|
|
99
|
+
}
|
|
100
|
+
changesByFile.set(key, [...(changesByFile.get(key) ?? []), ...edit.textChanges]);
|
|
101
|
+
}
|
|
102
|
+
const prepared = new Map();
|
|
103
|
+
const cleanup = [];
|
|
104
|
+
let assetImportEditCount = 0;
|
|
105
|
+
for (const snapshot of input.plan.fileSnapshots) {
|
|
106
|
+
const key = pathKey(snapshot.file);
|
|
107
|
+
const originalText = originals.get(key);
|
|
108
|
+
const changes = changesByFile.get(key) ?? [];
|
|
109
|
+
const validation = validateTextChanges(changes, originalText.length);
|
|
110
|
+
if (validation) {
|
|
111
|
+
return failure(validation.code, `${snapshot.file}: ${validation.error}`);
|
|
112
|
+
}
|
|
113
|
+
let nextText = (0, file_text_edit_executor_1.applyTextChanges)(originalText, changes);
|
|
114
|
+
const destination = samePath(snapshot.file, sourceFile) ? targetFile : snapshot.file;
|
|
115
|
+
if (samePath(destination, targetFile)) {
|
|
116
|
+
const assetChanges = buildMovedFileAssetImportTextChanges(sourceFile, targetFile, nextText);
|
|
117
|
+
const assetValidation = validateTextChanges(assetChanges, nextText.length);
|
|
118
|
+
if (assetValidation) {
|
|
119
|
+
return failure(assetValidation.code, `${targetFile}: ${assetValidation.error}`);
|
|
120
|
+
}
|
|
121
|
+
nextText = (0, file_text_edit_executor_1.applyTextChanges)(nextText, assetChanges);
|
|
122
|
+
assetImportEditCount += assetChanges.length;
|
|
123
|
+
}
|
|
124
|
+
nextText = (0, targeted_import_canonicalizer_1.formatChangedNamedImports)(originalText, nextText, destination).text;
|
|
125
|
+
const cleanupEligible = samePath(destination, targetFile) || changes.length > 0;
|
|
126
|
+
if (import_rules_1.MUTATION_UNUSED_IMPORT_CLEANUP_ENABLED &&
|
|
127
|
+
cleanupEligible &&
|
|
128
|
+
input.postProcessImports &&
|
|
129
|
+
(0, import_rules_1.resolveImportRuleForFile)(destination, input.importRules)?.unusedImports === "remove") {
|
|
130
|
+
const cleaned = removeUnusedImportBindings(destination, nextText);
|
|
131
|
+
if (cleaned !== nextText) {
|
|
132
|
+
cleanup.push({ ok: true, phase: "removeUnusedImports", file: destination, editCount: 1, applied: true, savedFiles: [destination] });
|
|
133
|
+
nextText = cleaned;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
prepared.set(pathKey(destination), { file: destination, originalText, nextText });
|
|
137
|
+
}
|
|
138
|
+
const sourceOriginal = originals.get(pathKey(sourceFile));
|
|
139
|
+
const targetPrepared = prepared.get(pathKey(targetFile)) ?? {
|
|
140
|
+
file: targetFile,
|
|
141
|
+
originalText: sourceOriginal,
|
|
142
|
+
nextText: sourceOriginal
|
|
143
|
+
};
|
|
144
|
+
prepared.set(pathKey(targetFile), targetPrepared);
|
|
145
|
+
const attemptedWrites = [];
|
|
146
|
+
const createdDirs = [];
|
|
147
|
+
let targetClaimed = false;
|
|
148
|
+
let sourceRemoved = false;
|
|
149
|
+
let stagedFile = null;
|
|
150
|
+
let sourceGuard = null;
|
|
151
|
+
let sourceIdentity = null;
|
|
152
|
+
let sourceMode = null;
|
|
153
|
+
let ownedIdentity = null;
|
|
154
|
+
try {
|
|
155
|
+
createdDirs.push(...ensureDirectoryTree(path.dirname(targetFile), dependencies.fs));
|
|
156
|
+
const finalPreflight = verifyFinalCommitPreflight(root, sourceFile, targetFile, input.plan, dependencies);
|
|
157
|
+
if (finalPreflight) {
|
|
158
|
+
for (const dir of [...createdDirs].reverse()) {
|
|
159
|
+
try {
|
|
160
|
+
dependencies.fs.rmdirSync(dir);
|
|
161
|
+
}
|
|
162
|
+
catch { /* retained if non-empty */ }
|
|
163
|
+
}
|
|
164
|
+
return finalPreflight;
|
|
165
|
+
}
|
|
166
|
+
sourceIdentity = readRegularFileIdentity(sourceFile, dependencies.fs);
|
|
167
|
+
sourceMode = dependencies.fs.statSync(sourceFile).mode & 0o7777;
|
|
168
|
+
const staged = createOwnedStagedFile(targetFile, targetPrepared.nextText, sourceMode, dependencies.fs);
|
|
169
|
+
stagedFile = staged.file;
|
|
170
|
+
ownedIdentity = staged.identity;
|
|
171
|
+
sourceGuard = createUniqueAdjacentPath(sourceFile, "source-guard");
|
|
172
|
+
dependencies.fs.linkSync(sourceFile, sourceGuard);
|
|
173
|
+
if (!sameFileIdentity(readRegularFileIdentity(sourceGuard, dependencies.fs), sourceIdentity)) {
|
|
174
|
+
throw new Error("Source guard identity does not match the exact preflight source.");
|
|
175
|
+
}
|
|
176
|
+
dependencies.fs.linkSync(stagedFile, targetFile);
|
|
177
|
+
targetClaimed = true;
|
|
178
|
+
if (!sameFileIdentity(readRegularFileIdentity(targetFile, dependencies.fs), ownedIdentity) ||
|
|
179
|
+
!sameFileIdentity(readRegularFileIdentity(stagedFile, dependencies.fs), ownedIdentity) ||
|
|
180
|
+
!sameFileIdentity(readRegularFileIdentity(sourceFile, dependencies.fs), sourceIdentity) ||
|
|
181
|
+
readPermissionBits(targetFile, dependencies.fs) !== sourceMode ||
|
|
182
|
+
readPermissionBits(stagedFile, dependencies.fs) !== sourceMode ||
|
|
183
|
+
readPermissionBits(sourceFile, dependencies.fs) !== sourceMode ||
|
|
184
|
+
sha256(dependencies.fs.readFileSync(targetFile, "utf8")) !== sha256(targetPrepared.nextText)) {
|
|
185
|
+
throw new Error("Source or staged target identity changed during no-replace ownership claim.");
|
|
186
|
+
}
|
|
187
|
+
if (input.forceFailureAfterMove) {
|
|
188
|
+
throw new Error("Forced file mutation failure after filesystem move for test.");
|
|
189
|
+
}
|
|
190
|
+
for (const item of prepared.values()) {
|
|
191
|
+
if (samePath(item.file, targetFile) || item.nextText === item.originalText) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
attemptedWrites.push(item.file);
|
|
195
|
+
dependencies.fs.writeFileSync(item.file, item.nextText, "utf8");
|
|
196
|
+
}
|
|
197
|
+
assertExactOwnedFile(sourceFile, sourceIdentity, sourceOriginal, sourceMode, dependencies.fs, "Source changed before commit.");
|
|
198
|
+
assertExactOwnedFile(sourceGuard, sourceIdentity, sourceOriginal, sourceMode, dependencies.fs, "Source guard changed before commit.");
|
|
199
|
+
assertExactOwnedFile(targetFile, ownedIdentity, targetPrepared.nextText, sourceMode, dependencies.fs, "Target changed before commit.");
|
|
200
|
+
assertExactOwnedFile(stagedFile, ownedIdentity, targetPrepared.nextText, sourceMode, dependencies.fs, "Staged target changed before commit.");
|
|
201
|
+
dependencies.fs.unlinkSync(sourceFile);
|
|
202
|
+
sourceRemoved = true;
|
|
203
|
+
if (dependencies.fs.existsSync(sourceFile)) {
|
|
204
|
+
throw new Error("Source path still exists after the final commit unlink.");
|
|
205
|
+
}
|
|
206
|
+
assertExactOwnedFile(targetFile, ownedIdentity, targetPrepared.nextText, sourceMode, dependencies.fs, "Target changed at commit.");
|
|
207
|
+
removeOwnedPath(stagedFile, ownedIdentity, dependencies.fs);
|
|
208
|
+
stagedFile = null;
|
|
209
|
+
removeOwnedPath(sourceGuard, sourceIdentity, dependencies.fs);
|
|
210
|
+
sourceGuard = null;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (!targetClaimed && attemptedWrites.length === 0) {
|
|
214
|
+
cleanupOwnedTemp(stagedFile, ownedIdentity, dependencies.fs);
|
|
215
|
+
cleanupOwnedTemp(sourceGuard, sourceIdentity, dependencies.fs);
|
|
216
|
+
for (const dir of [...createdDirs].reverse()) {
|
|
217
|
+
try {
|
|
218
|
+
dependencies.fs.rmdirSync(dir);
|
|
219
|
+
}
|
|
220
|
+
catch { /* retained if non-empty */ }
|
|
221
|
+
}
|
|
222
|
+
const errorCode = readErrorCode(error) === "EEXIST"
|
|
223
|
+
? "FILE_MUTATION_TARGET_CHANGED"
|
|
224
|
+
: readErrorCode(error) === "EXDEV"
|
|
225
|
+
? "FILE_MUTATION_NO_REPLACE_UNSUPPORTED"
|
|
226
|
+
: "FILE_MUTATION_TARGET_CLAIM_FAILED";
|
|
227
|
+
return failure(errorCode, message(error));
|
|
228
|
+
}
|
|
229
|
+
const rollbackErrors = [];
|
|
230
|
+
const potentiallyModified = new Map(attemptedWrites.map((file) => [pathKey(file), path.normalize(file)]));
|
|
231
|
+
for (const file of uniquePaths(attemptedWrites).reverse()) {
|
|
232
|
+
if (samePath(file, targetFile)) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const item = prepared.get(pathKey(file));
|
|
236
|
+
if (!item)
|
|
237
|
+
continue;
|
|
238
|
+
try {
|
|
239
|
+
dependencies.fs.writeFileSync(file, item.originalText, "utf8");
|
|
240
|
+
const restored = dependencies.fs.existsSync(file) &&
|
|
241
|
+
sha256(dependencies.fs.readFileSync(file, "utf8")) === sha256(item.originalText);
|
|
242
|
+
if (!restored)
|
|
243
|
+
throw new Error("restored bytes do not match the exact preflight snapshot");
|
|
244
|
+
potentiallyModified.delete(pathKey(file));
|
|
245
|
+
}
|
|
246
|
+
catch (restoreError) {
|
|
247
|
+
rollbackErrors.push(`${file}: ${message(restoreError)}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (targetClaimed) {
|
|
251
|
+
potentiallyModified.set(pathKey(sourceFile), path.normalize(sourceFile));
|
|
252
|
+
potentiallyModified.set(pathKey(targetFile), path.normalize(targetFile));
|
|
253
|
+
try {
|
|
254
|
+
if (!sourceIdentity || sourceMode === null)
|
|
255
|
+
throw new Error("Source identity or mode was not captured before apply.");
|
|
256
|
+
if (sourceRemoved && !dependencies.fs.existsSync(sourceFile)) {
|
|
257
|
+
if (!sourceGuard)
|
|
258
|
+
throw new Error("Source guard is unavailable after commit failure.");
|
|
259
|
+
assertExactOwnedFile(sourceGuard, sourceIdentity, sourceOriginal, sourceMode, dependencies.fs, "Source guard changed before rollback.");
|
|
260
|
+
dependencies.fs.linkSync(sourceGuard, sourceFile);
|
|
261
|
+
}
|
|
262
|
+
assertExactOwnedFile(sourceFile, sourceIdentity, sourceOriginal, sourceMode, dependencies.fs, "Source path is foreign or changed; refusing to overwrite it.");
|
|
263
|
+
potentiallyModified.delete(pathKey(sourceFile));
|
|
264
|
+
}
|
|
265
|
+
catch (restoreError) {
|
|
266
|
+
rollbackErrors.push(`${sourceFile}: ${message(restoreError)}`);
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
if (!ownedIdentity)
|
|
270
|
+
throw new Error("Target identity was not captured before apply.");
|
|
271
|
+
removeOwnedPath(targetFile, ownedIdentity, dependencies.fs);
|
|
272
|
+
potentiallyModified.delete(pathKey(targetFile));
|
|
273
|
+
}
|
|
274
|
+
catch (restoreError) {
|
|
275
|
+
rollbackErrors.push(`${targetFile}: ${message(restoreError)}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
cleanupOwnedTemp(stagedFile, ownedIdentity, dependencies.fs, true);
|
|
280
|
+
}
|
|
281
|
+
catch (cleanupError) {
|
|
282
|
+
rollbackErrors.push(`${stagedFile}: ${message(cleanupError)}`);
|
|
283
|
+
if (stagedFile)
|
|
284
|
+
potentiallyModified.set(pathKey(stagedFile), path.normalize(stagedFile));
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
cleanupOwnedTemp(sourceGuard, sourceIdentity, dependencies.fs, true);
|
|
288
|
+
}
|
|
289
|
+
catch (cleanupError) {
|
|
290
|
+
rollbackErrors.push(`${sourceGuard}: ${message(cleanupError)}`);
|
|
291
|
+
if (sourceGuard)
|
|
292
|
+
potentiallyModified.set(pathKey(sourceGuard), path.normalize(sourceGuard));
|
|
293
|
+
}
|
|
294
|
+
for (const dir of [...createdDirs].reverse()) {
|
|
295
|
+
try {
|
|
296
|
+
dependencies.fs.rmdirSync(dir);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// A non-empty or concurrently reused directory is intentionally retained.
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const potentiallyModifiedFiles = rollbackErrors.length === 0 ? [] : uniquePaths([...potentiallyModified.values()]);
|
|
303
|
+
return {
|
|
304
|
+
ok: false,
|
|
305
|
+
code: rollbackErrors.length === 0 ? "FILE_MUTATION_TRANSACTION_FAILED" : "FILE_MUTATION_ROLLBACK_FAILED",
|
|
306
|
+
error: rollbackErrors.length === 0
|
|
307
|
+
? message(error)
|
|
308
|
+
: `${message(error)} Rollback failed: ${rollbackErrors.join("; ")}`,
|
|
309
|
+
rollback: rollbackErrors.length === 0 ? "ok" : "failed",
|
|
310
|
+
potentiallyModifiedFiles,
|
|
311
|
+
...(rollbackErrors.length > 0 ? { rollbackErrors } : {})
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
const changedFiles = [...prepared.values()]
|
|
315
|
+
.filter((item) => item.nextText !== item.originalText)
|
|
316
|
+
.map((item) => item.file);
|
|
317
|
+
return {
|
|
318
|
+
ok: true,
|
|
319
|
+
savedFiles: uniquePaths([targetFile, ...changedFiles]),
|
|
320
|
+
touchedFiles: uniquePaths([targetFile, ...changedFiles]),
|
|
321
|
+
importEditCount: input.plan.edits.reduce((sum, edit) => sum + edit.textChanges.length, 0),
|
|
322
|
+
assetImportEditCount,
|
|
323
|
+
cleanup
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function verifyFinalCommitPreflight(root, sourceFile, targetFile, plan, dependencies) {
|
|
327
|
+
try {
|
|
328
|
+
if (dependencies.computeWorkspaceFingerprint(root) !== plan.workspaceFingerprint) {
|
|
329
|
+
return failure("FILE_MUTATION_COMMIT_PREFLIGHT_STALE", "Workspace files, configs, or package metadata changed at the final apply boundary.");
|
|
330
|
+
}
|
|
331
|
+
if (dependencies.fs.existsSync(targetFile)) {
|
|
332
|
+
return failure("FILE_MUTATION_TARGET_CHANGED", "Target path exists at the final no-replace apply boundary.");
|
|
333
|
+
}
|
|
334
|
+
for (const snapshot of plan.fileSnapshots) {
|
|
335
|
+
if (!dependencies.fs.existsSync(snapshot.file) ||
|
|
336
|
+
sha256(dependencies.fs.readFileSync(snapshot.file, "utf8")) !== snapshot.hash) {
|
|
337
|
+
return failure("FILE_MUTATION_TOUCHED_FILE_CHANGED", `Planned file changed at the final apply boundary: ${snapshot.file}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (!dependencies.fs.existsSync(sourceFile) || !dependencies.fs.statSync(sourceFile).isFile()) {
|
|
341
|
+
return failure("FILE_MUTATION_SOURCE_CHANGED", "Source file changed at the final apply boundary.");
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
return failure("FILE_MUTATION_COMMIT_PREFLIGHT_FAILED", message(error));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function readRegularFileIdentity(file, fsAdapter) {
|
|
350
|
+
return readRegularFileIdentityFromStat(file, fsAdapter.statSync(file));
|
|
351
|
+
}
|
|
352
|
+
function readRegularFileIdentityFromStat(file, stat) {
|
|
353
|
+
if (!stat.isFile() || !Number.isFinite(stat.dev) || !Number.isFinite(stat.ino) || stat.ino === 0) {
|
|
354
|
+
throw new Error(`Stable regular-file identity is unavailable for ${file}.`);
|
|
355
|
+
}
|
|
356
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
357
|
+
}
|
|
358
|
+
function createOwnedStagedFile(targetFile, text, mode, fsAdapter) {
|
|
359
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
360
|
+
const file = createUniqueAdjacentPath(targetFile, "target-stage");
|
|
361
|
+
let descriptor;
|
|
362
|
+
try {
|
|
363
|
+
descriptor = fsAdapter.openSync(file, "wx", mode);
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
if (readErrorCode(error) === "EEXIST")
|
|
367
|
+
continue;
|
|
368
|
+
throw error;
|
|
369
|
+
}
|
|
370
|
+
let identity = null;
|
|
371
|
+
let writeError = null;
|
|
372
|
+
try {
|
|
373
|
+
identity = readRegularFileIdentityFromStat(file, fsAdapter.fstatSync(descriptor));
|
|
374
|
+
fsAdapter.fchmodSync(descriptor, mode);
|
|
375
|
+
const stagedStat = fsAdapter.fstatSync(descriptor);
|
|
376
|
+
identity = readRegularFileIdentityFromStat(file, stagedStat);
|
|
377
|
+
if ((stagedStat.mode & 0o7777) !== mode) {
|
|
378
|
+
throw new Error(`Staged target mode does not match source mode for ${file}.`);
|
|
379
|
+
}
|
|
380
|
+
const bytes = Buffer.from(text, "utf8");
|
|
381
|
+
let offset = 0;
|
|
382
|
+
while (offset < bytes.length) {
|
|
383
|
+
const written = fsAdapter.writeSync(descriptor, bytes, offset, bytes.length - offset, offset);
|
|
384
|
+
if (written <= 0)
|
|
385
|
+
throw new Error(`Staged target write made no progress for ${file}.`);
|
|
386
|
+
offset += written;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
writeError = error;
|
|
391
|
+
}
|
|
392
|
+
finally {
|
|
393
|
+
try {
|
|
394
|
+
fsAdapter.closeSync(descriptor);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
writeError ??= error;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (writeError) {
|
|
401
|
+
cleanupOwnedTemp(file, identity, fsAdapter);
|
|
402
|
+
throw writeError;
|
|
403
|
+
}
|
|
404
|
+
if (!identity)
|
|
405
|
+
throw new Error(`Staged target identity was not captured for ${file}.`);
|
|
406
|
+
assertExactOwnedFile(file, identity, text, mode, fsAdapter, "Staged target bytes or mode changed during preparation.");
|
|
407
|
+
return { file, identity };
|
|
408
|
+
}
|
|
409
|
+
throw new Error(`Could not reserve a unique staged target adjacent to ${targetFile}.`);
|
|
410
|
+
}
|
|
411
|
+
function createUniqueAdjacentPath(file, label) {
|
|
412
|
+
return path.join(path.dirname(file), `.${path.basename(file)}.aib-${label}-${process.pid}-${crypto.randomUUID()}`);
|
|
413
|
+
}
|
|
414
|
+
function assertExactOwnedFile(file, identity, expectedText, expectedMode, fsAdapter, error) {
|
|
415
|
+
if (!fsAdapter.existsSync(file) ||
|
|
416
|
+
!sameFileIdentity(readRegularFileIdentity(file, fsAdapter), identity) ||
|
|
417
|
+
readPermissionBits(file, fsAdapter) !== expectedMode ||
|
|
418
|
+
sha256(fsAdapter.readFileSync(file, "utf8")) !== sha256(expectedText)) {
|
|
419
|
+
throw new Error(error);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function readPermissionBits(file, fsAdapter) {
|
|
423
|
+
return fsAdapter.statSync(file).mode & 0o7777;
|
|
424
|
+
}
|
|
425
|
+
function removeOwnedPath(file, identity, fsAdapter) {
|
|
426
|
+
if (!fsAdapter.existsSync(file))
|
|
427
|
+
return;
|
|
428
|
+
if (!sameFileIdentity(readRegularFileIdentity(file, fsAdapter), identity)) {
|
|
429
|
+
throw new Error(`Refusing to remove foreign path ${file}.`);
|
|
430
|
+
}
|
|
431
|
+
fsAdapter.unlinkSync(file);
|
|
432
|
+
if (fsAdapter.existsSync(file))
|
|
433
|
+
throw new Error(`Owned path still exists after cleanup: ${file}.`);
|
|
434
|
+
}
|
|
435
|
+
function cleanupOwnedTemp(file, identity, fsAdapter, strict = false) {
|
|
436
|
+
if (!file || !fsAdapter.existsSync(file))
|
|
437
|
+
return;
|
|
438
|
+
if (!identity) {
|
|
439
|
+
if (strict)
|
|
440
|
+
throw new Error(`Temporary path identity is unavailable for ${file}.`);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (!sameFileIdentity(readRegularFileIdentity(file, fsAdapter), identity)) {
|
|
444
|
+
if (strict)
|
|
445
|
+
throw new Error(`Refusing to remove foreign temporary path ${file}.`);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
removeOwnedPath(file, identity, fsAdapter);
|
|
449
|
+
}
|
|
450
|
+
function sameFileIdentity(left, right) {
|
|
451
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
452
|
+
}
|
|
453
|
+
function readErrorCode(error) {
|
|
454
|
+
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : null;
|
|
455
|
+
}
|
|
456
|
+
function failure(code, error) {
|
|
457
|
+
return { ok: false, code, error, rollback: "not-needed", potentiallyModifiedFiles: [] };
|
|
458
|
+
}
|
|
459
|
+
function validateTextChanges(changes, textLength) {
|
|
460
|
+
const sorted = [...changes].sort((left, right) => left.span.start - right.span.start || left.span.length - right.span.length);
|
|
461
|
+
let previousEnd = -1;
|
|
462
|
+
for (const change of sorted) {
|
|
463
|
+
const { start, length } = change.span;
|
|
464
|
+
if (!Number.isInteger(start) || !Number.isInteger(length) || start < 0 || length < 0 || start + length > textLength) {
|
|
465
|
+
return { code: "FILE_TEXT_EDIT_INVALID_SPAN", error: `Invalid text edit span ${start}:${length}.` };
|
|
466
|
+
}
|
|
467
|
+
if (start < previousEnd || start === previousEnd && length > 0 && previousEnd >= 0) {
|
|
468
|
+
return { code: "FILE_TEXT_EDIT_OVERLAP", error: `Overlapping text edit span ${start}:${length}.` };
|
|
469
|
+
}
|
|
470
|
+
previousEnd = Math.max(previousEnd, start + length);
|
|
471
|
+
}
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
function buildMovedFileAssetImportTextChanges(sourceFile, targetFile, sourceText) {
|
|
475
|
+
if (!/\.(?:tsx?|jsx?|mjs|cjs)$/i.test(targetFile))
|
|
476
|
+
return [];
|
|
477
|
+
const sourceAst = typescript_1.default.createSourceFile(targetFile, sourceText, typescript_1.default.ScriptTarget.Latest, true, scriptKindForFile(targetFile));
|
|
478
|
+
const changes = [];
|
|
479
|
+
for (const statement of sourceAst.statements) {
|
|
480
|
+
if (!typescript_1.default.isImportDeclaration(statement) || statement.importClause || !typescript_1.default.isStringLiteral(statement.moduleSpecifier))
|
|
481
|
+
continue;
|
|
482
|
+
const parsed = /^(\.\.?\/.*\.(?:css|scss))([?#].*)?$/i.exec(statement.moduleSpecifier.text);
|
|
483
|
+
if (!parsed)
|
|
484
|
+
continue;
|
|
485
|
+
const assetBefore = path.resolve(path.dirname(sourceFile), (parsed[1] ?? "").replace(/\//g, path.sep));
|
|
486
|
+
const relative = path.relative(path.dirname(targetFile), assetBefore).replace(/\\/g, "/");
|
|
487
|
+
const next = `${relative.startsWith(".") ? relative : `./${relative}`}${parsed[2] ?? ""}`;
|
|
488
|
+
if (next !== statement.moduleSpecifier.text) {
|
|
489
|
+
changes.push({
|
|
490
|
+
span: { start: statement.moduleSpecifier.getStart(sourceAst) + 1, length: statement.moduleSpecifier.text.length },
|
|
491
|
+
newText: next
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return changes;
|
|
496
|
+
}
|
|
497
|
+
function removeUnusedImportBindings(file, text) {
|
|
498
|
+
const source = typescript_1.default.createSourceFile(file, text, typescript_1.default.ScriptTarget.Latest, true, scriptKindForFile(file));
|
|
499
|
+
const referenced = new Set();
|
|
500
|
+
const visit = (node) => {
|
|
501
|
+
if (typescript_1.default.isImportDeclaration(node))
|
|
502
|
+
return;
|
|
503
|
+
if (typescript_1.default.isIdentifier(node))
|
|
504
|
+
referenced.add(node.text);
|
|
505
|
+
typescript_1.default.forEachChild(node, visit);
|
|
506
|
+
};
|
|
507
|
+
visit(source);
|
|
508
|
+
const changes = [];
|
|
509
|
+
for (const statement of source.statements) {
|
|
510
|
+
if (!typescript_1.default.isImportDeclaration(statement) || !statement.importClause || !typescript_1.default.isStringLiteral(statement.moduleSpecifier))
|
|
511
|
+
continue;
|
|
512
|
+
const clause = statement.importClause;
|
|
513
|
+
const clauseText = text.slice(clause.getStart(source), clause.getEnd());
|
|
514
|
+
if (/\/\*|\/\//.test(clauseText))
|
|
515
|
+
continue;
|
|
516
|
+
const defaultName = clause.name && referenced.has(clause.name.text) ? clause.name.text : null;
|
|
517
|
+
const named = clause.namedBindings && typescript_1.default.isNamedImports(clause.namedBindings)
|
|
518
|
+
? clause.namedBindings.elements.filter((item) => referenced.has(item.name.text))
|
|
519
|
+
: [];
|
|
520
|
+
const namespace = clause.namedBindings && typescript_1.default.isNamespaceImport(clause.namedBindings) && referenced.has(clause.namedBindings.name.text)
|
|
521
|
+
? clause.namedBindings.name.text
|
|
522
|
+
: null;
|
|
523
|
+
let replacement = "";
|
|
524
|
+
if (defaultName || namespace || named.length > 0) {
|
|
525
|
+
const bindings = [
|
|
526
|
+
defaultName,
|
|
527
|
+
namespace ? `* as ${namespace}` : null,
|
|
528
|
+
named.length > 0 ? `{ ${named.map((item) => item.getText(source)).join(", ")} }` : null
|
|
529
|
+
].filter((item) => Boolean(item)).join(", ");
|
|
530
|
+
const suffix = text.slice(statement.moduleSpecifier.getEnd(), statement.getEnd()).replace(/;?\s*$/, "");
|
|
531
|
+
replacement = `import ${clause.isTypeOnly ? "type " : ""}${bindings} from ${statement.moduleSpecifier.getText(source)}${suffix};`;
|
|
532
|
+
}
|
|
533
|
+
const start = source.getPositionOfLineAndCharacter(source.getLineAndCharacterOfPosition(statement.getStart(source)).line, 0);
|
|
534
|
+
let end = statement.getEnd();
|
|
535
|
+
if (text.startsWith("\r\n", end))
|
|
536
|
+
end += 2;
|
|
537
|
+
else if (text[end] === "\n" || text[end] === "\r")
|
|
538
|
+
end += 1;
|
|
539
|
+
const current = text.slice(start, end);
|
|
540
|
+
const next = replacement ? `${replacement}${current.endsWith("\r\n") ? "\r\n" : current.endsWith("\n") ? "\n" : ""}` : "";
|
|
541
|
+
if (current !== next)
|
|
542
|
+
changes.push({ span: { start, length: end - start }, newText: next });
|
|
543
|
+
}
|
|
544
|
+
return (0, file_text_edit_executor_1.applyTextChanges)(text, changes);
|
|
545
|
+
}
|
|
546
|
+
function ensureDirectoryTree(dir, fsAdapter) {
|
|
547
|
+
const missing = [];
|
|
548
|
+
let current = dir;
|
|
549
|
+
while (!fsAdapter.existsSync(current)) {
|
|
550
|
+
missing.push(current);
|
|
551
|
+
const parent = path.dirname(current);
|
|
552
|
+
if (parent === current)
|
|
553
|
+
break;
|
|
554
|
+
current = parent;
|
|
555
|
+
}
|
|
556
|
+
fsAdapter.mkdirSync(dir, { recursive: true });
|
|
557
|
+
return missing;
|
|
558
|
+
}
|
|
559
|
+
function scriptKindForFile(file) {
|
|
560
|
+
const extension = path.extname(file).toLowerCase();
|
|
561
|
+
if (extension === ".tsx")
|
|
562
|
+
return typescript_1.default.ScriptKind.TSX;
|
|
563
|
+
if (extension === ".jsx")
|
|
564
|
+
return typescript_1.default.ScriptKind.JSX;
|
|
565
|
+
if ([".js", ".mjs", ".cjs"].includes(extension))
|
|
566
|
+
return typescript_1.default.ScriptKind.JS;
|
|
567
|
+
return typescript_1.default.ScriptKind.TS;
|
|
568
|
+
}
|
|
569
|
+
function sha256(value) {
|
|
570
|
+
return crypto.createHash("sha256").update(value).digest("hex");
|
|
571
|
+
}
|
|
572
|
+
function message(error) {
|
|
573
|
+
return error instanceof Error ? error.message : String(error);
|
|
574
|
+
}
|
|
575
|
+
function uniquePaths(files) {
|
|
576
|
+
return [...new Map(files.map((file) => [pathKey(file), path.normalize(file)])).values()].sort();
|
|
577
|
+
}
|
|
578
|
+
function samePath(left, right) {
|
|
579
|
+
return pathKey(left) === pathKey(right);
|
|
580
|
+
}
|
|
581
|
+
function pathKey(file) {
|
|
582
|
+
const normalized = path.normalize(file);
|
|
583
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
584
|
+
}
|