@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,1154 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FILE_REFACTOR_BATCH_TESTING = void 0;
|
|
37
|
+
exports.runFileRefactorBatch = runFileRefactorBatch;
|
|
38
|
+
exports.runFileRefactorBatchExecutionWorker = runFileRefactorBatchExecutionWorker;
|
|
39
|
+
exports.readCachedFileRefactorBatchExecution = readCachedFileRefactorBatchExecution;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
const node_child_process_1 = require("node:child_process");
|
|
43
|
+
const zod_1 = require("zod");
|
|
44
|
+
const env_vars_1 = require("../config/env-vars");
|
|
45
|
+
const agent_text_1 = require("../shared/agent-text");
|
|
46
|
+
const errors_1 = require("../shared/errors");
|
|
47
|
+
const inspect_cycles_1 = require("./inspect-cycles");
|
|
48
|
+
const file_mutation_worker_apply_1 = require("./file-mutation-worker-apply");
|
|
49
|
+
const mutation_eta_1 = require("./mutation-eta");
|
|
50
|
+
const file_refactor_batch_preview_cache_1 = require("./file-refactor-batch-preview-cache");
|
|
51
|
+
const file_refactor_batch_execution_cache_1 = require("./file-refactor-batch-execution-cache");
|
|
52
|
+
const file_mutation_runtime_1 = require("./file-mutation-runtime");
|
|
53
|
+
const mutation_execution_cache_1 = require("./mutation-execution-cache");
|
|
54
|
+
const mutation_recovery_journal_1 = require("./mutation-recovery-journal");
|
|
55
|
+
const file_impact_scan_1 = require("../mutation/file-impact-scan");
|
|
56
|
+
const runtime_lifecycle_1 = require("../session/runtime-lifecycle");
|
|
57
|
+
const FileRefactorBatchPayloadSchema = zod_1.z.object({
|
|
58
|
+
operations: zod_1.z.array(zod_1.z.object({
|
|
59
|
+
kind: zod_1.z.union([zod_1.z.literal("fileMoveToDir"), zod_1.z.literal("fileRename")]),
|
|
60
|
+
sourceFile: zod_1.z.string().min(1),
|
|
61
|
+
targetDir: zod_1.z.string().min(1),
|
|
62
|
+
targetFile: zod_1.z.string().min(1),
|
|
63
|
+
testCrashAfterFsMove: zod_1.z.string().optional()
|
|
64
|
+
})).min(1),
|
|
65
|
+
execute: zod_1.z.boolean().optional(),
|
|
66
|
+
testCrashAfterFsMove: zod_1.z.string().optional()
|
|
67
|
+
});
|
|
68
|
+
async function runFileRefactorBatch(cwd, rawPayload, options = {}, restArgs = []) {
|
|
69
|
+
const runtimeOptions = readFileRefactorBatchRuntimeOptions();
|
|
70
|
+
const action = restArgs[0] ?? "preview";
|
|
71
|
+
if (action === "help" || action === "--help") {
|
|
72
|
+
return FileRefactorBatchHelp();
|
|
73
|
+
}
|
|
74
|
+
if (action === "apply") {
|
|
75
|
+
const previewId = restArgs[1];
|
|
76
|
+
if (!previewId || previewId.startsWith("--")) {
|
|
77
|
+
throw new errors_1.CliError("FILE_REFACTOR_BATCH_PREVIEW_ID_REQUIRED", "file refactor batch apply expects a preview id.", {
|
|
78
|
+
usage: "aib file refactor batch apply <previewId>"
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return applyFileRefactorBatchPreview(cwd, previewId, options, runtimeOptions);
|
|
82
|
+
}
|
|
83
|
+
if (action !== "preview" && action !== "execute" && action !== "validate") {
|
|
84
|
+
throw new errors_1.CliError("UNKNOWN_FILE_REFACTOR_BATCH_COMMAND", `Unknown file refactor batch command: ${action}`, {
|
|
85
|
+
availableCommands: ["preview", "apply", "execute", "validate", "help"]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const payload = FileRefactorBatchPayloadSchema.parse(rawPayload);
|
|
89
|
+
const payloadRuntimeOptions = runtimeOptionsWithPayloadOverrides(runtimeOptions, payload);
|
|
90
|
+
if (action === "execute" && readFileRefactorBatchSyncWaitMs() > 0) {
|
|
91
|
+
return runFileRefactorBatchPayloadWithExecution(cwd, {
|
|
92
|
+
...payload,
|
|
93
|
+
execute: true
|
|
94
|
+
}, options, "execute", readFileRefactorBatchSyncWaitMs(), payloadRuntimeOptions);
|
|
95
|
+
}
|
|
96
|
+
return runFileRefactorBatchPayload(cwd, {
|
|
97
|
+
...payload,
|
|
98
|
+
execute: action === "execute"
|
|
99
|
+
}, options, action, payloadRuntimeOptions);
|
|
100
|
+
}
|
|
101
|
+
async function applyFileRefactorBatchPreview(cwd, previewId, options, runtimeOptions) {
|
|
102
|
+
const record = (0, file_refactor_batch_preview_cache_1.readFileRefactorBatchPreviewRecord)(cwd, previewId);
|
|
103
|
+
(0, file_refactor_batch_preview_cache_1.validateFileMoveStates)(record);
|
|
104
|
+
const payload = FileRefactorBatchPayloadSchema.parse({
|
|
105
|
+
...record.normalizedPayload,
|
|
106
|
+
execute: true
|
|
107
|
+
});
|
|
108
|
+
const syncWaitMs = readFileRefactorBatchSyncWaitMs();
|
|
109
|
+
if (syncWaitMs > 0) {
|
|
110
|
+
return runFileRefactorBatchPayloadWithExecution(cwd, payload, options, "apply", syncWaitMs, runtimeOptions, previewId);
|
|
111
|
+
}
|
|
112
|
+
const result = await runFileRefactorBatchPayload(cwd, payload, options, "apply", runtimeOptions, previewId);
|
|
113
|
+
return result.ok === false
|
|
114
|
+
? (0, agent_text_1.attachAgentText)({ ...result, next: "Fix the file refactor batch request and rerun preview." }, formatFileRefactorBatchAgentText({ ...result, next: "Fix the file refactor batch request and rerun preview." }))
|
|
115
|
+
: result;
|
|
116
|
+
}
|
|
117
|
+
async function runFileRefactorBatchPayloadWithExecution(cwd, payload, options, action, syncWaitMs, runtimeOptions, previewIdFromApply) {
|
|
118
|
+
const normalized = normalizePayload(cwd, payload, true);
|
|
119
|
+
const executionId = (0, file_refactor_batch_execution_cache_1.buildFileRefactorBatchExecutionId)();
|
|
120
|
+
const operation = `file.refactor.batch.${action}`;
|
|
121
|
+
const etaEstimate = (0, file_mutation_runtime_1.estimateFileMutationEta)(buildFileMutationEtaInput(cwd, normalized.operations));
|
|
122
|
+
const estimatedDurationMs = etaEstimate.selectedMs;
|
|
123
|
+
const status = (0, file_refactor_batch_execution_cache_1.createFileRefactorBatchExecutionStatus)(cwd, executionId, operation, buildPlannedMoves(cwd, normalized.operations));
|
|
124
|
+
const recoveryJournal = (0, mutation_recovery_journal_1.createFileMutationRecoveryJournal)(cwd, executionId, operation, normalized.operations.map((row) => ({
|
|
125
|
+
id: row.id,
|
|
126
|
+
kind: row.kind,
|
|
127
|
+
source: formatRelativePath(cwd, row.sourceFile),
|
|
128
|
+
target: formatRelativePath(cwd, row.targetFile)
|
|
129
|
+
})));
|
|
130
|
+
(0, mutation_recovery_journal_1.writeMutationRecoveryJournal)(cwd, recoveryJournal);
|
|
131
|
+
(0, mutation_recovery_journal_1.writeMutationRecoveryPlan)(cwd, recoveryJournal, buildFileRefactorBatchRecoveryPlan(cwd, normalized));
|
|
132
|
+
(0, file_refactor_batch_execution_cache_1.writeFileRefactorBatchExecutionStatus)(cwd, status);
|
|
133
|
+
const startedAtMs = Date.now();
|
|
134
|
+
const backgroundEnv = captureFileRefactorBatchBackgroundEnv();
|
|
135
|
+
const workerInputPath = writeFileRefactorBatchWorkerInput(cwd, executionId, {
|
|
136
|
+
schemaVersion: 1,
|
|
137
|
+
cwd,
|
|
138
|
+
payload,
|
|
139
|
+
normalized,
|
|
140
|
+
options: serializeResolveTargetInstanceOptions(options),
|
|
141
|
+
action,
|
|
142
|
+
runtimeOptions,
|
|
143
|
+
executionId,
|
|
144
|
+
status,
|
|
145
|
+
previewIdFromApply: previewIdFromApply ?? null,
|
|
146
|
+
recoveryJournal
|
|
147
|
+
});
|
|
148
|
+
startFileRefactorBatchWorkerProcess(cwd, workerInputPath, backgroundEnv);
|
|
149
|
+
const result = await waitForFileRefactorBatchWorkerResult(cwd, executionId, syncWaitMs);
|
|
150
|
+
if (result) {
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
const finalStatus = (0, file_refactor_batch_execution_cache_1.tryReadFileRefactorBatchExecutionStatus)(cwd, executionId);
|
|
154
|
+
if (finalStatus && finalStatus.status !== "running") {
|
|
155
|
+
return isObject(finalStatus.result)
|
|
156
|
+
? finalStatus.result
|
|
157
|
+
: readCachedFileRefactorBatchExecution(cwd, executionId);
|
|
158
|
+
}
|
|
159
|
+
return buildFileRefactorBatchStillRunningResponse(cwd, executionId, operation, estimatedDurationMs, Date.now() - startedAtMs, etaEstimate);
|
|
160
|
+
}
|
|
161
|
+
async function runFileRefactorBatchExecutionWorker(input) {
|
|
162
|
+
const status = input.status;
|
|
163
|
+
try {
|
|
164
|
+
const result = await executeFileRefactorBatchOperations(input.cwd, input.normalized, input.action, input.options, input.runtimeOptions, input.executionId, status, input.previewIdFromApply ?? undefined, input.recoveryJournal);
|
|
165
|
+
const rows = readFileRefactorBatchRows(result);
|
|
166
|
+
status.status = result.ok === false ? "failed" : "completed";
|
|
167
|
+
status.phase = "completed";
|
|
168
|
+
status.completedRows = result.ok === false ? rows.filter((row) => row.ok !== false).length : status.rowCount;
|
|
169
|
+
status.failedRows = result.ok === false ? rows.filter((row) => row.ok === false).length : 0;
|
|
170
|
+
status.notRunRows = result.ok === false ? Math.max(0, status.rowCount - rows.length) : 0;
|
|
171
|
+
status.filesWritten = readStringArray(result.filesWritten);
|
|
172
|
+
status.touchedFiles = readStringArray(result.touchedFiles);
|
|
173
|
+
status.moves = Array.isArray(result.changes) ? result.changes.filter(isObject) : [];
|
|
174
|
+
status.rows = rows;
|
|
175
|
+
if (isObject(result.postMutation)) {
|
|
176
|
+
status.postMutation = result.postMutation;
|
|
177
|
+
}
|
|
178
|
+
const recovery = (0, mutation_recovery_journal_1.mutationRecoveryJournalSummary)(input.recoveryJournal);
|
|
179
|
+
if (recovery) {
|
|
180
|
+
status.recovery = recovery;
|
|
181
|
+
}
|
|
182
|
+
status.result = result;
|
|
183
|
+
if (result.ok === false) {
|
|
184
|
+
status.error = readString(result.code) ?? readFirstFailedCode(rows) ?? "FILE_REFACTOR_BATCH_FAILED";
|
|
185
|
+
}
|
|
186
|
+
(0, file_refactor_batch_execution_cache_1.writeFileRefactorBatchExecutionStatus)(input.cwd, status);
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
status.status = "failed";
|
|
191
|
+
status.phase = "completed";
|
|
192
|
+
status.failedRows = Math.max(1, status.failedRows);
|
|
193
|
+
status.notRunRows = Math.max(0, status.rowCount - status.completedRows - status.failedRows);
|
|
194
|
+
status.error = error instanceof Error ? error.message : String(error);
|
|
195
|
+
(0, file_refactor_batch_execution_cache_1.writeFileRefactorBatchExecutionStatus)(input.cwd, status);
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function writeFileRefactorBatchWorkerInput(cwd, executionId, input) {
|
|
200
|
+
const filePath = path.join((0, mutation_recovery_journal_1.mutationRecoveryJournalDir)(cwd, executionId), "worker-input.json");
|
|
201
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
202
|
+
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
203
|
+
fs.writeFileSync(tmpPath, `${JSON.stringify(input, null, 2)}\n`);
|
|
204
|
+
fs.renameSync(tmpPath, filePath);
|
|
205
|
+
return filePath;
|
|
206
|
+
}
|
|
207
|
+
function startFileRefactorBatchWorkerProcess(cwd, inputPath, envPatch) {
|
|
208
|
+
const env = { ...process.env };
|
|
209
|
+
for (const [key, value] of Object.entries(envPatch)) {
|
|
210
|
+
if (value === undefined) {
|
|
211
|
+
delete env[key];
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
env[key] = value;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [fileRefactorBatchWorkerScriptPath(), inputPath], {
|
|
218
|
+
cwd,
|
|
219
|
+
env,
|
|
220
|
+
detached: true,
|
|
221
|
+
stdio: "ignore",
|
|
222
|
+
windowsHide: true
|
|
223
|
+
});
|
|
224
|
+
child.on("error", () => undefined);
|
|
225
|
+
(0, runtime_lifecycle_1.trackSessionOwnedProcess)(child, "file-refactor-batch-worker");
|
|
226
|
+
child.unref();
|
|
227
|
+
}
|
|
228
|
+
function fileRefactorBatchWorkerScriptPath() {
|
|
229
|
+
return path.join(__dirname, "file-refactor-batch-worker.js");
|
|
230
|
+
}
|
|
231
|
+
async function waitForFileRefactorBatchWorkerResult(cwd, executionId, syncWaitMs) {
|
|
232
|
+
if (syncWaitMs <= 0) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
const deadline = Date.now() + syncWaitMs;
|
|
236
|
+
while (Date.now() < deadline) {
|
|
237
|
+
const status = (0, file_refactor_batch_execution_cache_1.tryReadFileRefactorBatchExecutionStatus)(cwd, executionId);
|
|
238
|
+
if (status && isFinalFileRefactorBatchWorkerStatus(status)) {
|
|
239
|
+
return isObject(status.result)
|
|
240
|
+
? status.result
|
|
241
|
+
: readCachedFileRefactorBatchExecution(cwd, executionId);
|
|
242
|
+
}
|
|
243
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
244
|
+
}
|
|
245
|
+
const finalStatus = (0, file_refactor_batch_execution_cache_1.tryReadFileRefactorBatchExecutionStatus)(cwd, executionId);
|
|
246
|
+
if (finalStatus && isFinalFileRefactorBatchWorkerStatus(finalStatus)) {
|
|
247
|
+
return isObject(finalStatus.result)
|
|
248
|
+
? finalStatus.result
|
|
249
|
+
: readCachedFileRefactorBatchExecution(cwd, executionId);
|
|
250
|
+
}
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
function isFinalFileRefactorBatchWorkerStatus(status) {
|
|
254
|
+
return isObject(status.result) || status.phase === "completed";
|
|
255
|
+
}
|
|
256
|
+
function serializeResolveTargetInstanceOptions(options) {
|
|
257
|
+
return {
|
|
258
|
+
...(options.metricsEnabled !== undefined ? { metricsEnabled: options.metricsEnabled } : {}),
|
|
259
|
+
...(options.importRules ? { importRules: options.importRules } : {}),
|
|
260
|
+
...(options.mutationComments ? { mutationComments: options.mutationComments } : {})
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
async function runFileRefactorBatchPayload(cwd, payload, options, action, runtimeOptions, previewIdFromApply, executionId, normalizedFromExecution) {
|
|
264
|
+
await (0, file_mutation_runtime_1.maybeDelayFileMutationForTest)(process.env[env_vars_1.CLI_ENV.testFileRefactorBatchDelayMs]);
|
|
265
|
+
const normalized = normalizedFromExecution ?? normalizePayload(cwd, payload, action === "execute" || action === "apply");
|
|
266
|
+
const result = normalized.execute
|
|
267
|
+
? await executeFileRefactorBatchOperations(cwd, normalized, action === "apply" ? "apply" : "execute", options, runtimeOptions, executionId, undefined, previewIdFromApply)
|
|
268
|
+
: buildLocalFileRefactorBatchPreviewResult(normalized.operations);
|
|
269
|
+
const response = compactFileRefactorBatchResponse(cwd, result, normalized, action, previewIdFromApply, executionId);
|
|
270
|
+
if ((action === "preview" || action === "validate") && response.ok !== false) {
|
|
271
|
+
const previewId = (0, file_refactor_batch_preview_cache_1.buildFileRefactorBatchPreviewId)(normalized.normalizedPayload);
|
|
272
|
+
const states = (0, file_refactor_batch_preview_cache_1.readFileMoveStates)(normalized.operations);
|
|
273
|
+
const previewHash = (0, file_refactor_batch_preview_cache_1.buildFileRefactorBatchPreviewHash)(normalized.normalizedPayload, states, response);
|
|
274
|
+
(0, file_refactor_batch_preview_cache_1.writeFileRefactorBatchPreviewRecord)(cwd, {
|
|
275
|
+
previewId,
|
|
276
|
+
previewHash,
|
|
277
|
+
createdAt: new Date().toISOString(),
|
|
278
|
+
cwd: path.resolve(cwd),
|
|
279
|
+
normalizedPayload: normalized.normalizedPayload,
|
|
280
|
+
states,
|
|
281
|
+
previewResult: response
|
|
282
|
+
});
|
|
283
|
+
response.previewId = previewId;
|
|
284
|
+
response.next = `aib file refactor batch apply ${previewId}`;
|
|
285
|
+
}
|
|
286
|
+
return (0, agent_text_1.attachAgentText)(response, formatFileRefactorBatchAgentText(response));
|
|
287
|
+
}
|
|
288
|
+
async function executeFileRefactorBatchOperations(cwd, normalized, action, options, runtimeOptions, executionId, status, previewIdFromApply, recoveryJournal) {
|
|
289
|
+
const rawRows = [];
|
|
290
|
+
const filesWritten = new Set();
|
|
291
|
+
const touchedFiles = new Set();
|
|
292
|
+
const preMutationCycles = runPostMutationCyclesSnapshot(cwd, normalized.operations.map((operation) => operation.sourceFile));
|
|
293
|
+
let cleanup = [];
|
|
294
|
+
let postMutation = null;
|
|
295
|
+
for (const operation of normalized.operations) {
|
|
296
|
+
(0, mutation_recovery_journal_1.updateMutationRecoveryJournalRow)(cwd, recoveryJournal ?? null, operation.id, { phase: "started" });
|
|
297
|
+
if (status) {
|
|
298
|
+
status.phase = "movingFile";
|
|
299
|
+
status.status = "running";
|
|
300
|
+
const recovery = (0, mutation_recovery_journal_1.mutationRecoveryJournalSummary)(recoveryJournal ?? null);
|
|
301
|
+
if (recovery) {
|
|
302
|
+
status.recovery = recovery;
|
|
303
|
+
}
|
|
304
|
+
persistFileRefactorBatchExecutionProgress(cwd, status, rawRows, filesWritten, touchedFiles);
|
|
305
|
+
await yieldToEventLoop();
|
|
306
|
+
}
|
|
307
|
+
const rowResult = await executeFileRefactorBatchMutationRowInWorker(cwd, operation, options, runtimeOptions, recoveryJournal ?? null);
|
|
308
|
+
const row = Array.isArray(rowResult.rows) && isObject(rowResult.rows[0])
|
|
309
|
+
? rowResult.rows[0]
|
|
310
|
+
: localFailureRow(operation, "FILE_REFACTOR_BATCH_FAILED", "Extension did not return a file refactor batch row.");
|
|
311
|
+
const finalRow = row;
|
|
312
|
+
rawRows.push(finalRow);
|
|
313
|
+
for (const savedFile of collectStringArray(finalRow.savedFiles)) {
|
|
314
|
+
filesWritten.add(path.normalize(savedFile));
|
|
315
|
+
}
|
|
316
|
+
for (const touchedFile of collectStringArray(finalRow.touchedFiles)) {
|
|
317
|
+
touchedFiles.add(path.normalize(touchedFile));
|
|
318
|
+
}
|
|
319
|
+
for (const cleanupRow of Array.isArray(finalRow.cleanup) ? finalRow.cleanup.filter(isObject) : []) {
|
|
320
|
+
cleanup.push(cleanupRow);
|
|
321
|
+
}
|
|
322
|
+
const rowRecoveryPatch = {
|
|
323
|
+
phase: finalRow.ok === false ? "failed" : "completed",
|
|
324
|
+
filesWritten: collectStringArray(finalRow.savedFiles).map((file) => formatRelativePath(cwd, file)),
|
|
325
|
+
touchedFiles: collectStringArray(finalRow.touchedFiles).map((file) => formatRelativePath(cwd, file))
|
|
326
|
+
};
|
|
327
|
+
const finalRowError = readString(finalRow.error);
|
|
328
|
+
if (finalRowError) {
|
|
329
|
+
rowRecoveryPatch.error = finalRowError;
|
|
330
|
+
}
|
|
331
|
+
(0, mutation_recovery_journal_1.updateMutationRecoveryJournalRow)(cwd, recoveryJournal ?? null, operation.id, rowRecoveryPatch);
|
|
332
|
+
if (status) {
|
|
333
|
+
const recovery = (0, mutation_recovery_journal_1.mutationRecoveryJournalSummary)(recoveryJournal ?? null);
|
|
334
|
+
if (recovery) {
|
|
335
|
+
status.recovery = recovery;
|
|
336
|
+
}
|
|
337
|
+
persistFileRefactorBatchExecutionProgress(cwd, status, rawRows, filesWritten, touchedFiles);
|
|
338
|
+
await yieldToEventLoop();
|
|
339
|
+
}
|
|
340
|
+
if (finalRow.ok === false) {
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
await (0, file_mutation_runtime_1.delayFileMutationForTest)(runtimeOptions.testRowDelayMs);
|
|
344
|
+
}
|
|
345
|
+
const rowsOk = rawRows.every((row) => row.ok !== false) && rawRows.length === normalized.operations.length;
|
|
346
|
+
const cleanupOk = cleanup.every((row) => row.ok !== false);
|
|
347
|
+
if (rowsOk && cleanupOk) {
|
|
348
|
+
if (status) {
|
|
349
|
+
status.phase = "postMutation.cycles";
|
|
350
|
+
persistFileRefactorBatchExecutionProgress(cwd, status, rawRows, filesWritten, touchedFiles);
|
|
351
|
+
await yieldToEventLoop();
|
|
352
|
+
}
|
|
353
|
+
await maybeDelayPostMutationCycles(runtimeOptions.testPostMutationCyclesDelayMs);
|
|
354
|
+
const postMutationFocusFiles = uniqueStrings([...Array.from(touchedFiles), ...Array.from(filesWritten)]);
|
|
355
|
+
const postMutationCycles = runPostMutationCyclesSnapshot(cwd, postMutationFocusFiles);
|
|
356
|
+
postMutation = {
|
|
357
|
+
cycles: diffPostMutationCycles(preMutationCycles, postMutationCycles, new Set(formatCycleFocusFiles(cwd, postMutationFocusFiles)))
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const rawResult = compactObject({
|
|
361
|
+
...(!rowsOk || !cleanupOk ? { ok: false } : {}),
|
|
362
|
+
operation: "fileMutation",
|
|
363
|
+
execute: true,
|
|
364
|
+
rowCount: normalized.operations.length,
|
|
365
|
+
appliedCount: rawRows.filter((row) => row.applied === true).length,
|
|
366
|
+
savedFiles: Array.from(filesWritten),
|
|
367
|
+
touchedFiles: Array.from(touchedFiles),
|
|
368
|
+
cleanup,
|
|
369
|
+
rows: rawRows,
|
|
370
|
+
recovery: (0, mutation_recovery_journal_1.mutationRecoveryJournalSummary)(recoveryJournal ?? null),
|
|
371
|
+
postMutation
|
|
372
|
+
});
|
|
373
|
+
const response = compactFileRefactorBatchResponse(cwd, rawResult, normalized, action, previewIdFromApply, executionId);
|
|
374
|
+
return (0, agent_text_1.attachAgentText)(response, formatFileRefactorBatchAgentText(response));
|
|
375
|
+
}
|
|
376
|
+
function unwrapFileRefactorBatchRow(result, operation) {
|
|
377
|
+
return Array.isArray(result.rows) && isObject(result.rows[0])
|
|
378
|
+
? result.rows[0]
|
|
379
|
+
: localFailureRow(operation, "FILE_REFACTOR_BATCH_FAILED", "Extension did not return a file refactor batch row.");
|
|
380
|
+
}
|
|
381
|
+
function persistFileRefactorBatchExecutionProgress(cwd, status, rawRows, filesWritten, touchedFiles) {
|
|
382
|
+
const compactRows = rawRows.map((row) => compactRow(cwd, row));
|
|
383
|
+
status.rows = compactRows;
|
|
384
|
+
status.completedRows = compactRows.filter((row) => row.ok !== false).length;
|
|
385
|
+
status.failedRows = compactRows.filter((row) => row.ok === false).length;
|
|
386
|
+
status.notRunRows = status.failedRows > 0 ? Math.max(0, status.rowCount - compactRows.length) : 0;
|
|
387
|
+
status.filesWritten = Array.from(filesWritten).sort((left, right) => left.localeCompare(right)).map((file) => formatRelativePath(cwd, file));
|
|
388
|
+
status.touchedFiles = Array.from(touchedFiles).sort((left, right) => left.localeCompare(right)).map((file) => formatRelativePath(cwd, file));
|
|
389
|
+
if (status.failedRows > 0) {
|
|
390
|
+
status.status = "failed";
|
|
391
|
+
status.error = readFirstFailedCode(compactRows) ?? "FILE_REFACTOR_BATCH_FAILED";
|
|
392
|
+
}
|
|
393
|
+
(0, file_refactor_batch_execution_cache_1.writeFileRefactorBatchExecutionStatus)(cwd, status);
|
|
394
|
+
}
|
|
395
|
+
async function executeFileRefactorBatchMutationRowInWorker(cwd, operation, options, runtimeOptions, recoveryJournal, executeRow = file_mutation_worker_apply_1.executeWorkerOwnedFileMutationRow) {
|
|
396
|
+
let response;
|
|
397
|
+
try {
|
|
398
|
+
response = await executeRow(cwd, operation, options, runtimeOptions);
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
response = {
|
|
402
|
+
rows: [localFailureRow(operation, error instanceof errors_1.CliError ? error.code : "FILE_REFACTOR_BATCH_WORKER_FAILED", error instanceof Error ? error.message : String(error))]
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
const row = Array.isArray(response.rows) && isObject(response.rows[0]) ? response.rows[0] : null;
|
|
406
|
+
(0, mutation_recovery_journal_1.writeMutationRecoveryDetail)(cwd, recoveryJournal, "apply", operation.id, {
|
|
407
|
+
response,
|
|
408
|
+
savedFiles: row ? collectStringArray(row.savedFiles).map((file) => formatRelativePath(cwd, file)) : [],
|
|
409
|
+
touchedFiles: row ? collectStringArray(row.touchedFiles).map((file) => formatRelativePath(cwd, file)) : [],
|
|
410
|
+
planner: row && isObject(row.planner) ? row.planner : null,
|
|
411
|
+
discovery: row && isObject(row.discovery) ? row.discovery : null
|
|
412
|
+
});
|
|
413
|
+
return response;
|
|
414
|
+
}
|
|
415
|
+
exports.FILE_REFACTOR_BATCH_TESTING = {
|
|
416
|
+
executeWorkerOwnedRow: executeFileRefactorBatchMutationRowInWorker,
|
|
417
|
+
compactRow
|
|
418
|
+
};
|
|
419
|
+
function readCachedFileRefactorBatchExecution(cwd, executionId) {
|
|
420
|
+
const status = (0, file_refactor_batch_execution_cache_1.readFileRefactorBatchExecutionStatus)(cwd, executionId);
|
|
421
|
+
const response = {
|
|
422
|
+
operation: "execution.status",
|
|
423
|
+
executionId: status.executionId,
|
|
424
|
+
status: status.status,
|
|
425
|
+
phase: status.phase,
|
|
426
|
+
summary: buildFileRefactorBatchExecutionSummary(status),
|
|
427
|
+
progress: `${status.completedRows}/${status.rowCount}`,
|
|
428
|
+
filesWritten: status.filesWritten,
|
|
429
|
+
touchedFiles: status.touchedFiles,
|
|
430
|
+
...(status.recovery ? { recovery: status.recovery } : {}),
|
|
431
|
+
...(status.postMutation ? { postMutation: status.postMutation } : {}),
|
|
432
|
+
updatedAt: status.updatedAt,
|
|
433
|
+
...(status.error ? { error: status.error } : {})
|
|
434
|
+
};
|
|
435
|
+
return (0, agent_text_1.attachAgentText)(response, formatFileRefactorBatchExecutionStatusText(status));
|
|
436
|
+
}
|
|
437
|
+
function buildFileRefactorBatchStillRunningResponse(cwd, executionId, operation, estimatedDurationMs, elapsedMs, estimate = null) {
|
|
438
|
+
const status = (0, file_refactor_batch_execution_cache_1.readFileRefactorBatchExecutionStatus)(cwd, executionId);
|
|
439
|
+
const estimatedRemainingMs = Math.max(0, estimatedDurationMs - elapsedMs);
|
|
440
|
+
const eta = (0, mutation_eta_1.buildMutationEtaHint)(status.executionId, estimatedRemainingMs);
|
|
441
|
+
const response = {
|
|
442
|
+
operation: "execution.status",
|
|
443
|
+
executionId: status.executionId,
|
|
444
|
+
status: status.status,
|
|
445
|
+
phase: status.phase,
|
|
446
|
+
summary: buildFileRefactorBatchExecutionSummary(status),
|
|
447
|
+
progress: `${status.completedRows}/${status.rowCount}`,
|
|
448
|
+
filesWritten: status.filesWritten,
|
|
449
|
+
touchedFiles: status.touchedFiles,
|
|
450
|
+
...(status.recovery ? { recovery: status.recovery } : {}),
|
|
451
|
+
...(status.postMutation ? { postMutation: status.postMutation } : {}),
|
|
452
|
+
updatedAt: status.updatedAt,
|
|
453
|
+
...(estimate ? { eta: estimate } : {}),
|
|
454
|
+
estimatedRemainingMs: eta.estimatedRemainingMs,
|
|
455
|
+
suggestedFirstCheckMs: eta.suggestedFirstCheckMs,
|
|
456
|
+
next: eta.next
|
|
457
|
+
};
|
|
458
|
+
return (0, agent_text_1.attachAgentText)(response, formatFileRefactorBatchStillRunningText(operation, status, eta));
|
|
459
|
+
}
|
|
460
|
+
function formatFileRefactorBatchStillRunningText(operation, status, eta) {
|
|
461
|
+
return [
|
|
462
|
+
`${operation} ${status.executionId}`,
|
|
463
|
+
buildFileRefactorBatchExecutionSummary(status),
|
|
464
|
+
formatFileRefactorBatchPhaseLine(status),
|
|
465
|
+
...(0, mutation_eta_1.formatMutationEtaLines)(eta)
|
|
466
|
+
].join("\n");
|
|
467
|
+
}
|
|
468
|
+
function formatFileRefactorBatchExecutionStatusText(status) {
|
|
469
|
+
const lines = [
|
|
470
|
+
buildFileRefactorBatchExecutionSummary(status)
|
|
471
|
+
];
|
|
472
|
+
if (status.status === "running") {
|
|
473
|
+
lines.push(formatFileRefactorBatchPhaseLine(status));
|
|
474
|
+
return lines.join("\n");
|
|
475
|
+
}
|
|
476
|
+
appendExecutionChangeLines(lines, status);
|
|
477
|
+
const failedRows = status.rows.filter((row) => row.ok === false);
|
|
478
|
+
const firstFailed = failedRows[0];
|
|
479
|
+
if (firstFailed) {
|
|
480
|
+
const code = readString(firstFailed.code) ?? status.error ?? "FILE_REFACTOR_BATCH_FAILED";
|
|
481
|
+
lines.push(`code: ${code}`);
|
|
482
|
+
if (typeof firstFailed.error === "string") {
|
|
483
|
+
lines.push(firstFailed.error);
|
|
484
|
+
}
|
|
485
|
+
if (typeof firstFailed.rollback === "string") {
|
|
486
|
+
lines.push(`rollback: ${firstFailed.rollback}`);
|
|
487
|
+
}
|
|
488
|
+
if (typeof firstFailed.hint === "string") {
|
|
489
|
+
lines.push(`hint: ${firstFailed.hint}`);
|
|
490
|
+
}
|
|
491
|
+
lines.push("failed:");
|
|
492
|
+
for (const row of failedRows) {
|
|
493
|
+
lines.push(`${readString(row.source) ?? "source"} -> ${readString(row.target) ?? "target"}`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else if (status.error) {
|
|
497
|
+
lines.push(status.error);
|
|
498
|
+
}
|
|
499
|
+
appendExecutionNotRunLines(lines, status);
|
|
500
|
+
appendRecoveryLines(lines, status);
|
|
501
|
+
if (status.filesWritten.length > 0) {
|
|
502
|
+
appendFilesWrittenLines(lines, status.filesWritten, status.plannedMoves.map((move) => move.target));
|
|
503
|
+
}
|
|
504
|
+
if (isObject(status.postMutation) && isObject(status.postMutation.cycles)) {
|
|
505
|
+
appendPostMutationCyclesText(lines, status.postMutation.cycles);
|
|
506
|
+
}
|
|
507
|
+
if (status.status === "failed") {
|
|
508
|
+
lines.push("next: Fix failed rename row and rerun file.refactor.batch preview.");
|
|
509
|
+
}
|
|
510
|
+
return lines.join("\n");
|
|
511
|
+
}
|
|
512
|
+
function formatFileRefactorBatchPhaseLine(status) {
|
|
513
|
+
if (status.phase === "postProcessImports") {
|
|
514
|
+
return "updating imports";
|
|
515
|
+
}
|
|
516
|
+
if (status.phase === "postMutation.cycles") {
|
|
517
|
+
return "checking cycles";
|
|
518
|
+
}
|
|
519
|
+
if (status.phase === "recoveringFileMutation") {
|
|
520
|
+
return "recovering file mutation";
|
|
521
|
+
}
|
|
522
|
+
return "moving/renaming files";
|
|
523
|
+
}
|
|
524
|
+
function buildFileRefactorBatchExecutionSummary(status) {
|
|
525
|
+
const percent = Math.floor((Math.max(0, status.completedRows) / Math.max(1, status.rowCount)) * 100);
|
|
526
|
+
if (status.status === "completed") {
|
|
527
|
+
return `completed, ${status.completedRows}/${status.rowCount} rows, ${percent}% files, ${status.filesWritten.length} files written`;
|
|
528
|
+
}
|
|
529
|
+
if (status.status === "failed") {
|
|
530
|
+
const parts = [
|
|
531
|
+
`failed, ${status.completedRows}/${status.rowCount} rows, ${percent}% files`,
|
|
532
|
+
`${status.failedRows} failed`
|
|
533
|
+
];
|
|
534
|
+
if (status.notRunRows > 0) {
|
|
535
|
+
parts.push(`${status.notRunRows} not run`);
|
|
536
|
+
}
|
|
537
|
+
parts.push(`${status.filesWritten.length} files written`);
|
|
538
|
+
return parts.join(", ");
|
|
539
|
+
}
|
|
540
|
+
return `in progress, ${status.completedRows}/${status.rowCount} rows, ${percent}% files`;
|
|
541
|
+
}
|
|
542
|
+
function normalizePayload(cwd, payload, execute) {
|
|
543
|
+
const baseDir = path.resolve(cwd);
|
|
544
|
+
const operations = [];
|
|
545
|
+
const seenTargets = new Set();
|
|
546
|
+
for (const inputOperation of payload.operations) {
|
|
547
|
+
const sourceFile = resolveCliFilePath(cwd, inputOperation.sourceFile);
|
|
548
|
+
assertInsideCwd(cwd, sourceFile, "FILE_REFACTOR_BATCH_SOURCE_OUTSIDE_CWD");
|
|
549
|
+
const targetFile = resolveCliFilePath(cwd, inputOperation.targetFile);
|
|
550
|
+
assertInsideCwd(cwd, targetFile, "FILE_REFACTOR_BATCH_TARGET_OUTSIDE_CWD");
|
|
551
|
+
const targetDir = resolveCliFilePath(cwd, inputOperation.targetDir);
|
|
552
|
+
assertInsideCwd(cwd, targetDir, "FILE_REFACTOR_BATCH_TARGET_OUTSIDE_CWD");
|
|
553
|
+
const targetKey = normalizeKey(targetFile);
|
|
554
|
+
if (seenTargets.has(targetKey)) {
|
|
555
|
+
throw new errors_1.CliError("FILE_REFACTOR_BATCH_DUPLICATE_TARGET", "Several file refactor batch rows resolve to the same target.", {
|
|
556
|
+
targetFile: formatRelativePath(cwd, targetFile)
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
seenTargets.add(targetKey);
|
|
560
|
+
operations.push({
|
|
561
|
+
id: `${inputOperation.kind === "fileRename" ? "rename" : "move"}-${operations.length + 1}`,
|
|
562
|
+
kind: inputOperation.kind,
|
|
563
|
+
sourceFile,
|
|
564
|
+
targetDir,
|
|
565
|
+
targetFile,
|
|
566
|
+
execute,
|
|
567
|
+
testCrashAfterFsMove: readString(inputOperation.testCrashAfterFsMove)
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
if (operations.length === 0) {
|
|
571
|
+
throw new errors_1.CliError("FILE_REFACTOR_BATCH_ROWS_REQUIRED", "file refactor batch expects at least one operation.");
|
|
572
|
+
}
|
|
573
|
+
return {
|
|
574
|
+
execute,
|
|
575
|
+
baseDir,
|
|
576
|
+
operations,
|
|
577
|
+
normalizedPayload: {
|
|
578
|
+
operations: normalizedPayloadOperations(operations),
|
|
579
|
+
execute
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
function buildLocalFileRefactorBatchPreviewResult(operations) {
|
|
584
|
+
const rows = [];
|
|
585
|
+
const virtualFiles = new Set();
|
|
586
|
+
const removedFiles = new Set();
|
|
587
|
+
const virtualDirs = new Set();
|
|
588
|
+
for (const operation of operations) {
|
|
589
|
+
if (rows.some((row) => row.ok === false)) {
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
const row = validateLocalMoveOperation(operation, { virtualFiles, removedFiles, virtualDirs });
|
|
593
|
+
rows.push(row);
|
|
594
|
+
if (row.ok !== false) {
|
|
595
|
+
removedFiles.add(normalizeKey(operation.sourceFile));
|
|
596
|
+
virtualFiles.delete(normalizeKey(operation.sourceFile));
|
|
597
|
+
virtualFiles.add(normalizeKey(operation.targetFile));
|
|
598
|
+
virtualDirs.add(normalizeKey(operation.targetDir));
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
const ok = rows.every((row) => row.ok !== false) && rows.length === operations.length;
|
|
602
|
+
return {
|
|
603
|
+
...(ok ? {} : { ok: false }),
|
|
604
|
+
operation: "fileMutation",
|
|
605
|
+
execute: false,
|
|
606
|
+
rowCount: operations.length,
|
|
607
|
+
appliedCount: 0,
|
|
608
|
+
savedFiles: [],
|
|
609
|
+
rows
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
function validateLocalMoveOperation(operation, virtualState) {
|
|
613
|
+
if (operation.kind !== "fileMoveToDir" && operation.kind !== "fileRename") {
|
|
614
|
+
return localFailureRow(operation, "FILE_MUTATION_KIND_UNSUPPORTED", `Unsupported file mutation kind: ${operation.kind}`);
|
|
615
|
+
}
|
|
616
|
+
const sourceKey = normalizeKey(operation.sourceFile);
|
|
617
|
+
const targetKey = normalizeKey(operation.targetFile);
|
|
618
|
+
const targetDirKey = normalizeKey(operation.targetDir);
|
|
619
|
+
const sourceExists = virtualState?.virtualFiles.has(sourceKey) === true || (!virtualState?.removedFiles.has(sourceKey) && fs.existsSync(operation.sourceFile));
|
|
620
|
+
if (!sourceExists) {
|
|
621
|
+
return localFailureRow(operation, "FILE_REFACTOR_BATCH_SOURCE_NOT_FOUND", "Source file does not exist.");
|
|
622
|
+
}
|
|
623
|
+
if (virtualState?.virtualFiles.has(sourceKey) !== true) {
|
|
624
|
+
try {
|
|
625
|
+
const stat = fs.statSync(operation.sourceFile);
|
|
626
|
+
if (!stat.isFile()) {
|
|
627
|
+
return localFailureRow(operation, "FILE_REFACTOR_BATCH_SOURCE_DIRECTORY_UNSUPPORTED", "file refactor batch v1 supports files only, not directories.");
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
return localFailureRow(operation, "FILE_REFACTOR_BATCH_SOURCE_STAT_FAILED", error instanceof Error ? error.message : String(error));
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
const targetExists = virtualState?.virtualFiles.has(targetKey) === true || (!virtualState?.removedFiles.has(targetKey) && fs.existsSync(operation.targetFile));
|
|
635
|
+
if (targetExists) {
|
|
636
|
+
return localFailureRow(operation, "FILE_REFACTOR_BATCH_TARGET_EXISTS", "Target file already exists.", "Pick another target directory/name or remove the target collision.");
|
|
637
|
+
}
|
|
638
|
+
const targetDirExists = virtualState?.virtualDirs.has(targetDirKey) === true || fs.existsSync(operation.targetDir);
|
|
639
|
+
if (operation.kind === "fileRename" && !targetDirExists) {
|
|
640
|
+
return localFailureRow(operation, "FILE_REFACTOR_BATCH_TARGET_DIR_NOT_FOUND", "Target parent directory does not exist.");
|
|
641
|
+
}
|
|
642
|
+
return {
|
|
643
|
+
id: operation.id,
|
|
644
|
+
ok: true,
|
|
645
|
+
sourceFile: operation.sourceFile,
|
|
646
|
+
targetFile: operation.targetFile,
|
|
647
|
+
applied: false
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function localFailureRow(operation, code, error, hint) {
|
|
651
|
+
return {
|
|
652
|
+
id: operation.id,
|
|
653
|
+
ok: false,
|
|
654
|
+
sourceFile: operation.sourceFile,
|
|
655
|
+
targetFile: operation.targetFile,
|
|
656
|
+
applied: false,
|
|
657
|
+
code,
|
|
658
|
+
error,
|
|
659
|
+
...(hint ? { hint } : {})
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
function normalizedPayloadOperations(operations) {
|
|
663
|
+
return operations.map((operation) => ({
|
|
664
|
+
kind: operation.kind,
|
|
665
|
+
sourceFile: operation.sourceFile,
|
|
666
|
+
targetDir: operation.targetDir,
|
|
667
|
+
targetFile: operation.targetFile,
|
|
668
|
+
...(operation.testCrashAfterFsMove ? { testCrashAfterFsMove: operation.testCrashAfterFsMove } : {})
|
|
669
|
+
}));
|
|
670
|
+
}
|
|
671
|
+
function resolveSourceFile(cwd, baseDir, rawPath) {
|
|
672
|
+
const trimmed = rawPath.trim();
|
|
673
|
+
if (path.isAbsolute(trimmed)) {
|
|
674
|
+
return path.normalize(trimmed);
|
|
675
|
+
}
|
|
676
|
+
const baseRelative = path.normalize(path.resolve(baseDir, trimmed));
|
|
677
|
+
if (fs.existsSync(baseRelative)) {
|
|
678
|
+
return baseRelative;
|
|
679
|
+
}
|
|
680
|
+
const cwdRelative = path.normalize(path.resolve(cwd, trimmed));
|
|
681
|
+
if (fs.existsSync(cwdRelative)) {
|
|
682
|
+
return cwdRelative;
|
|
683
|
+
}
|
|
684
|
+
return baseRelative;
|
|
685
|
+
}
|
|
686
|
+
function resolveRenameTargetFile(cwd, baseDir, sourceFile, rawTarget) {
|
|
687
|
+
const trimmed = rawTarget.trim();
|
|
688
|
+
if (path.isAbsolute(trimmed)) {
|
|
689
|
+
return path.normalize(trimmed);
|
|
690
|
+
}
|
|
691
|
+
if (trimmed.includes("/") || trimmed.includes("\\")) {
|
|
692
|
+
return path.normalize(path.resolve(baseDir, trimmed));
|
|
693
|
+
}
|
|
694
|
+
return path.normalize(path.resolve(path.dirname(sourceFile), trimmed));
|
|
695
|
+
}
|
|
696
|
+
function resolveInsideCwd(cwd, rawPath) {
|
|
697
|
+
const resolved = path.normalize(path.isAbsolute(rawPath) ? rawPath : path.resolve(cwd, rawPath));
|
|
698
|
+
assertInsideCwd(cwd, resolved, "FILE_REFACTOR_BATCH_PATH_OUTSIDE_CWD");
|
|
699
|
+
return resolved;
|
|
700
|
+
}
|
|
701
|
+
function assertInsideCwd(cwd, filePath, code) {
|
|
702
|
+
const root = path.resolve(cwd);
|
|
703
|
+
const relative = path.relative(root, filePath);
|
|
704
|
+
if (relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative))) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
throw new errors_1.CliError(code, "File move paths must stay inside the current workspace.", {
|
|
708
|
+
cwd: root,
|
|
709
|
+
filePath
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
function compactFileRefactorBatchResponse(cwd, raw, normalized, action, previewIdFromApply, executionId) {
|
|
713
|
+
const rows = Array.isArray(raw.rows)
|
|
714
|
+
? raw.rows.filter(isObject).map((row) => compactRow(cwd, row))
|
|
715
|
+
: [];
|
|
716
|
+
const ok = raw.ok !== false && rows.every((row) => row.ok !== false);
|
|
717
|
+
const changedFiles = collectRows(rows, "target");
|
|
718
|
+
const filesWritten = collectExistingFiles(cwd, collectStringArray(raw.savedFiles)).map((file) => formatRelativePath(cwd, file));
|
|
719
|
+
const operation = action === "apply"
|
|
720
|
+
? "file.refactor.batch.apply"
|
|
721
|
+
: normalized.execute
|
|
722
|
+
? "file.refactor.batch.execute"
|
|
723
|
+
: "file.refactor.batch.preview";
|
|
724
|
+
const response = compactObject({
|
|
725
|
+
...(ok ? {} : { ok: false }),
|
|
726
|
+
operation,
|
|
727
|
+
executionId: executionId ?? null,
|
|
728
|
+
base: formatRelativePath(cwd, normalized.baseDir),
|
|
729
|
+
operationCount: normalized.operations.length,
|
|
730
|
+
summary: ok
|
|
731
|
+
? normalized.execute
|
|
732
|
+
? `${normalized.operations.length} ${plural(normalized.operations.length, "file", "files")} changed, ${filesWritten.length} ${plural(filesWritten.length, "file", "files")} written`
|
|
733
|
+
: `${normalized.operations.length} ${plural(normalized.operations.length, "file", "files")} ready`
|
|
734
|
+
: buildFailureSummary(rows, normalized.operations.length, normalized.execute || action === "apply"),
|
|
735
|
+
changes: formatChangePairs(cwd, normalized.operations),
|
|
736
|
+
...(normalized.execute || action === "apply" ? { filesWritten, filesChanged: changedFiles } : {}),
|
|
737
|
+
...(isObject(raw.postMutation) ? { postMutation: raw.postMutation } : {}),
|
|
738
|
+
...(isObject(raw.recovery) ? { recovery: raw.recovery } : {}),
|
|
739
|
+
rows: ok ? null : rows,
|
|
740
|
+
previewId: previewIdFromApply ?? null
|
|
741
|
+
});
|
|
742
|
+
return response;
|
|
743
|
+
}
|
|
744
|
+
function compactRow(cwd, row) {
|
|
745
|
+
return compactObject({
|
|
746
|
+
id: readString(row.id),
|
|
747
|
+
ok: row.ok !== false,
|
|
748
|
+
source: formatRelativePath(cwd, readString(row.sourceFile) ?? ""),
|
|
749
|
+
target: formatRelativePath(cwd, readString(row.targetFile) ?? ""),
|
|
750
|
+
applied: typeof row.applied === "boolean" ? row.applied : null,
|
|
751
|
+
rollback: readString(row.rollback),
|
|
752
|
+
potentiallyModifiedFiles: compactList(collectStringArray(row.potentiallyModifiedFiles).map((file) => formatRelativePath(cwd, file)), 10),
|
|
753
|
+
rollbackErrors: compactList(collectStringArray(row.rollbackErrors), 10),
|
|
754
|
+
recovered: row.recovered === true ? true : null,
|
|
755
|
+
recoveryReason: readString(row.recoveryReason),
|
|
756
|
+
savedFiles: compactList(collectStringArray(row.savedFiles).map((file) => formatRelativePath(cwd, file)), 5),
|
|
757
|
+
code: readString(row.code),
|
|
758
|
+
error: readString(row.error),
|
|
759
|
+
hint: readString(row.hint)
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
function formatChangePairs(cwd, operations) {
|
|
763
|
+
return operations.map((operation) => ({
|
|
764
|
+
source: formatRelativePath(cwd, operation.sourceFile),
|
|
765
|
+
target: formatRelativePath(cwd, operation.targetFile)
|
|
766
|
+
}));
|
|
767
|
+
}
|
|
768
|
+
function buildFailureSummary(rows, total, executed) {
|
|
769
|
+
const failed = rows.filter((row) => row.ok === false).length;
|
|
770
|
+
const notRun = Math.max(0, total - rows.length);
|
|
771
|
+
if (!executed) {
|
|
772
|
+
const checked = Math.min(total, rows.length);
|
|
773
|
+
return `${total} ${plural(total, "file", "files")}, validation blocked at row ${checked}`;
|
|
774
|
+
}
|
|
775
|
+
return `${total} ${plural(total, "file", "files")}, ${failed} failed${notRun > 0 ? `, ${notRun} not run` : ""}`;
|
|
776
|
+
}
|
|
777
|
+
function buildFileRefactorBatchRecoveryPlan(cwd, normalized) {
|
|
778
|
+
return {
|
|
779
|
+
domain: "file",
|
|
780
|
+
operation: "fileMutation",
|
|
781
|
+
execute: normalized.execute,
|
|
782
|
+
base: formatRelativePath(cwd, normalized.baseDir),
|
|
783
|
+
rowCount: normalized.operations.length,
|
|
784
|
+
rows: normalized.operations.map((operation) => ({
|
|
785
|
+
id: operation.id,
|
|
786
|
+
kind: operation.kind,
|
|
787
|
+
source: formatRelativePath(cwd, operation.sourceFile),
|
|
788
|
+
target: formatRelativePath(cwd, operation.targetFile),
|
|
789
|
+
targetDir: formatRelativePath(cwd, operation.targetDir),
|
|
790
|
+
applySteps: [
|
|
791
|
+
"provider.fileRenameEdits",
|
|
792
|
+
operation.kind === "fileRename" ? "fs.rename" : "fs.moveToDir",
|
|
793
|
+
"textEdits.requiredImports",
|
|
794
|
+
"textEdits.assetImports",
|
|
795
|
+
"postProcess.importCleanup"
|
|
796
|
+
]
|
|
797
|
+
}))
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
function buildPlannedMoves(cwd, operations) {
|
|
801
|
+
return operations.map((operation) => ({
|
|
802
|
+
source: formatRelativePath(cwd, operation.sourceFile),
|
|
803
|
+
target: formatRelativePath(cwd, operation.targetFile),
|
|
804
|
+
targetDir: formatRelativePath(cwd, operation.targetDir)
|
|
805
|
+
}));
|
|
806
|
+
}
|
|
807
|
+
function readFileRefactorBatchRows(result) {
|
|
808
|
+
return Array.isArray(result.rows) ? result.rows.filter(isObject) : [];
|
|
809
|
+
}
|
|
810
|
+
function buildFileMutationEtaInput(cwd, operations) {
|
|
811
|
+
const targetDirs = new Set(operations.map((operation) => operation.targetDir));
|
|
812
|
+
let dirsToCreate = 0;
|
|
813
|
+
for (const targetDir of targetDirs) {
|
|
814
|
+
if (!fs.existsSync(targetDir)) {
|
|
815
|
+
dirsToCreate += 1;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const impact = (0, file_impact_scan_1.estimateFileMutationImpact)(cwd, operations.map((operation) => operation.sourceFile));
|
|
819
|
+
return {
|
|
820
|
+
rowCount: operations.length,
|
|
821
|
+
targetDirCount: targetDirs.size,
|
|
822
|
+
dirsToCreate,
|
|
823
|
+
importingFileCount: impact.importingFileCount,
|
|
824
|
+
importStatementCount: impact.importStatementCount,
|
|
825
|
+
barrelExportCount: impact.barrelExportCount,
|
|
826
|
+
sourceFileCount: impact.sourceFileCount,
|
|
827
|
+
existingSourceFileCount: impact.existingSourceFileCount,
|
|
828
|
+
scanTruncated: impact.truncated
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function readFirstFailedCode(rows) {
|
|
832
|
+
const failed = rows.find((row) => row.ok === false);
|
|
833
|
+
return failed ? readString(failed.code) : null;
|
|
834
|
+
}
|
|
835
|
+
function appendExecutionChangeLines(lines, status) {
|
|
836
|
+
const completedSources = new Set(status.rows.filter((row) => row.ok !== false).map((row) => readString(row.source)).filter((value) => Boolean(value)));
|
|
837
|
+
const pairs = [];
|
|
838
|
+
for (const move of status.plannedMoves) {
|
|
839
|
+
if (status.status !== "completed" && !completedSources.has(move.source)) {
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
pairs.push(`${move.source} -> ${move.target}`);
|
|
843
|
+
}
|
|
844
|
+
if (pairs.length === 0) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
lines.push("changes:");
|
|
848
|
+
for (const pair of pairs) {
|
|
849
|
+
lines.push(pair);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
function appendExecutionNotRunLines(lines, status) {
|
|
853
|
+
if (status.notRunRows <= 0) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
const seenSources = new Set(status.rows.map((row) => readString(row.source)).filter((value) => Boolean(value)));
|
|
857
|
+
const notRun = status.plannedMoves.filter((move) => !seenSources.has(move.source));
|
|
858
|
+
if (notRun.length === 0) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
lines.push("not run:");
|
|
862
|
+
for (const move of notRun) {
|
|
863
|
+
lines.push(move.source);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
function appendRecoveryLines(lines, status) {
|
|
867
|
+
if (!isObject(status.recovery) || !Array.isArray(status.recovery.rows)) {
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
const rows = status.recovery.rows.filter(isObject);
|
|
871
|
+
const visibleRows = rows.filter((row) => {
|
|
872
|
+
const phase = readString(row.phase);
|
|
873
|
+
return phase && phase !== "planned" && phase !== "started" && phase !== "completed";
|
|
874
|
+
});
|
|
875
|
+
if (visibleRows.length === 0) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
lines.push("recovery:");
|
|
879
|
+
for (const row of visibleRows) {
|
|
880
|
+
const source = readString(row.source) ?? "source";
|
|
881
|
+
const target = readString(row.target) ?? "target";
|
|
882
|
+
const phase = readString(row.phase) ?? "unknown";
|
|
883
|
+
lines.push(`${source} -> ${target}: ${phase}`);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function readFileRefactorBatchSyncWaitMs() {
|
|
887
|
+
return (0, mutation_execution_cache_1.readMutationSyncWaitMs)(process.env[env_vars_1.CLI_ENV.fileRefactorBatchSyncWaitMs], 120_000);
|
|
888
|
+
}
|
|
889
|
+
function readFileRefactorBatchRuntimeOptions() {
|
|
890
|
+
return {
|
|
891
|
+
postProcessImports: (0, file_mutation_runtime_1.isFileMutationImportPostProcessEnabled)(),
|
|
892
|
+
testFailRequiredImportUpdate: readString(process.env[env_vars_1.CLI_ENV.testFileRefactorBatchFailImports]),
|
|
893
|
+
testCrashAfterFsMove: readString(process.env[env_vars_1.CLI_ENV.testFileRefactorBatchCrashAfterFsMove]),
|
|
894
|
+
testRowDelayMs: (0, file_mutation_runtime_1.readFileMutationTestDelayMs)(process.env[env_vars_1.CLI_ENV.testFileRefactorBatchRowDelayMs], 60_000),
|
|
895
|
+
testImportPostProcessDelayMs: (0, file_mutation_runtime_1.readFileMutationTestDelayMs)(process.env[env_vars_1.CLI_ENV.testFileRefactorBatchImportsDelayMs], 60_000),
|
|
896
|
+
testPostMutationCyclesDelayMs: (0, file_mutation_runtime_1.readFileMutationTestDelayMs)(process.env[env_vars_1.CLI_ENV.testPostMutationCyclesDelayMs], 60_000)
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
function captureFileRefactorBatchBackgroundEnv() {
|
|
900
|
+
return (0, file_mutation_runtime_1.captureFileMutationBackgroundEnv)([
|
|
901
|
+
env_vars_1.CLI_ENV.testFileRefactorBatchDelayMs,
|
|
902
|
+
env_vars_1.CLI_ENV.testFileRefactorBatchRowDelayMs,
|
|
903
|
+
env_vars_1.CLI_ENV.testFileRefactorBatchImportsDelayMs,
|
|
904
|
+
env_vars_1.CLI_ENV.testFileRefactorBatchFailImports,
|
|
905
|
+
env_vars_1.CLI_ENV.testFileRefactorBatchCrashAfterFsMove
|
|
906
|
+
]);
|
|
907
|
+
}
|
|
908
|
+
function runtimeOptionsWithPayloadOverrides(runtimeOptions, payload) {
|
|
909
|
+
return {
|
|
910
|
+
...runtimeOptions,
|
|
911
|
+
testCrashAfterFsMove: readString(payload.testCrashAfterFsMove) ?? runtimeOptions.testCrashAfterFsMove
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
function formatFileRefactorBatchAgentText(response) {
|
|
915
|
+
const operation = readString(response.operation);
|
|
916
|
+
if (!operation?.startsWith("file.refactor.batch.")) {
|
|
917
|
+
return null;
|
|
918
|
+
}
|
|
919
|
+
const lines = [];
|
|
920
|
+
const previewId = readString(response.previewId);
|
|
921
|
+
const executionId = readString(response.executionId);
|
|
922
|
+
lines.push(response.ok === false
|
|
923
|
+
? `${operation} failed`
|
|
924
|
+
: previewId && operation === "file.refactor.batch.preview"
|
|
925
|
+
? `${operation} ${previewId}`
|
|
926
|
+
: executionId && (operation === "file.refactor.batch.apply" || operation === "file.refactor.batch.execute")
|
|
927
|
+
? `${operation} ${executionId}`
|
|
928
|
+
: operation);
|
|
929
|
+
if (typeof response.summary === "string") {
|
|
930
|
+
lines.push(response.summary);
|
|
931
|
+
}
|
|
932
|
+
const changes = Array.isArray(response.changes) ? response.changes.filter(isObject) : [];
|
|
933
|
+
if (changes.length > 0 && response.ok !== false) {
|
|
934
|
+
lines.push("changes:");
|
|
935
|
+
for (const change of changes) {
|
|
936
|
+
const source = readString(change.source);
|
|
937
|
+
const target = readString(change.target);
|
|
938
|
+
if (source && target) {
|
|
939
|
+
lines.push(`${source} -> ${target}`);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
appendFailureLines(lines, response);
|
|
944
|
+
const filesWritten = Array.isArray(response.filesWritten) ? response.filesWritten : [];
|
|
945
|
+
if (filesWritten.length > 0) {
|
|
946
|
+
appendFilesWrittenLines(lines, filesWritten, Array.isArray(response.filesChanged) ? response.filesChanged : []);
|
|
947
|
+
}
|
|
948
|
+
if (isObject(response.postMutation) && isObject(response.postMutation.cycles)) {
|
|
949
|
+
appendPostMutationCyclesText(lines, response.postMutation.cycles);
|
|
950
|
+
}
|
|
951
|
+
if (typeof response.next === "string") {
|
|
952
|
+
lines.push(`next: ${response.next}`);
|
|
953
|
+
}
|
|
954
|
+
return lines.join("\n");
|
|
955
|
+
}
|
|
956
|
+
function appendFailureLines(lines, response) {
|
|
957
|
+
if (response.ok !== false || !Array.isArray(response.rows)) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
const failed = response.rows.filter(isObject).find((row) => row.ok === false);
|
|
961
|
+
if (!failed) {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
lines.push("failed:");
|
|
965
|
+
lines.push(`${readString(failed.source) ?? "source"} -> ${readString(failed.target) ?? "target"}`);
|
|
966
|
+
lines.push(`code: ${readString(failed.code) ?? "FILE_REFACTOR_BATCH_FAILED"}`);
|
|
967
|
+
if (typeof failed.error === "string") {
|
|
968
|
+
lines.push(failed.error);
|
|
969
|
+
}
|
|
970
|
+
if (typeof failed.rollback === "string") {
|
|
971
|
+
lines.push(`rollback: ${failed.rollback}`);
|
|
972
|
+
}
|
|
973
|
+
if (typeof failed.hint === "string") {
|
|
974
|
+
lines.push(`hint: ${failed.hint}`);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
function FileRefactorBatchHelp() {
|
|
978
|
+
return {
|
|
979
|
+
ok: true,
|
|
980
|
+
command: "file refactor batch",
|
|
981
|
+
usage: "aib file refactor batch preview --stdin | aib file refactor batch execute --stdin | aib file refactor batch apply <previewId>",
|
|
982
|
+
dsl: [
|
|
983
|
+
"@base packages/agent-project-tooling/src",
|
|
984
|
+
"rename workspace-runner-cli.ts->cli.ts workspace-runner-command-hints.ts->command-hints.ts"
|
|
985
|
+
],
|
|
986
|
+
notes: [
|
|
987
|
+
"preview validates planned file refactor batchs without writing.",
|
|
988
|
+
"execute moves/renames files and updates TypeScript imports.",
|
|
989
|
+
"apply uses the cached preview id and refuses stale source/target state."
|
|
990
|
+
]
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
function collectRows(rows, field) {
|
|
994
|
+
return rows.map((row) => readString(row[field])).filter((value) => Boolean(value));
|
|
995
|
+
}
|
|
996
|
+
function collectStringArray(value) {
|
|
997
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
998
|
+
}
|
|
999
|
+
function runPostMutationCyclesSnapshot(cwd, files) {
|
|
1000
|
+
const existingFiles = formatCycleFocusFiles(cwd, files).filter((file) => fs.existsSync(resolveCliFilePath(cwd, file)));
|
|
1001
|
+
if (existingFiles.length === 0) {
|
|
1002
|
+
return {
|
|
1003
|
+
op: "cycles",
|
|
1004
|
+
componentCount: 0,
|
|
1005
|
+
components: []
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
const args = ["cycles"];
|
|
1009
|
+
for (const file of existingFiles) {
|
|
1010
|
+
args.push("--files", file);
|
|
1011
|
+
}
|
|
1012
|
+
args.push("--detail", "imports", "--limit", "50");
|
|
1013
|
+
return (0, inspect_cycles_1.runInspectCycles)(cwd, args, undefined);
|
|
1014
|
+
}
|
|
1015
|
+
function diffPostMutationCycles(prePayload, postPayload, touchedFiles) {
|
|
1016
|
+
const preKeys = new Set(readCycleComponents(prePayload).map(cycleComponentKey));
|
|
1017
|
+
const newOrChanged = readCycleComponents(postPayload).filter((component) => readStringArray(component.files).some((file) => touchedFiles.has(file)) &&
|
|
1018
|
+
!preKeys.has(cycleComponentKey(component)));
|
|
1019
|
+
return {
|
|
1020
|
+
status: newOrChanged.length > 0 ? "new-or-changed" : "none",
|
|
1021
|
+
detail: "imports",
|
|
1022
|
+
newOrChangedCount: newOrChanged.length,
|
|
1023
|
+
preComponentCount: readNumber(prePayload.componentCount),
|
|
1024
|
+
postComponentCount: readNumber(postPayload.componentCount),
|
|
1025
|
+
components: newOrChanged
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
function readCycleComponents(payload) {
|
|
1029
|
+
return (Array.isArray(payload.components) ? payload.components : [])
|
|
1030
|
+
.filter(isObject)
|
|
1031
|
+
.map((component) => ({
|
|
1032
|
+
kind: readString(component.kind) ?? "mixed",
|
|
1033
|
+
files: readStringArray(component.files).sort(),
|
|
1034
|
+
chain: readString(component.chain) ?? "",
|
|
1035
|
+
...(isObject(component.cycle) ? { cycle: component.cycle } : {}),
|
|
1036
|
+
imports: readCycleImports(component)
|
|
1037
|
+
}));
|
|
1038
|
+
}
|
|
1039
|
+
function readCycleImports(component) {
|
|
1040
|
+
const cycle = isObject(component.cycle) ? component.cycle : {};
|
|
1041
|
+
return readStringArray(cycle.imports);
|
|
1042
|
+
}
|
|
1043
|
+
function cycleComponentKey(component) {
|
|
1044
|
+
return `${readString(component.kind) ?? "mixed"}:${readStringArray(component.files).sort().join("|")}`;
|
|
1045
|
+
}
|
|
1046
|
+
function formatCycleFocusFiles(cwd, files) {
|
|
1047
|
+
return uniqueStrings(files.map((file) => formatRelativePath(cwd, resolveCliFilePath(cwd, file))));
|
|
1048
|
+
}
|
|
1049
|
+
function resolveCliFilePath(cwd, file) {
|
|
1050
|
+
return path.normalize(path.isAbsolute(file) ? file : path.resolve(cwd, file));
|
|
1051
|
+
}
|
|
1052
|
+
function readStringArray(value) {
|
|
1053
|
+
return collectStringArray(value);
|
|
1054
|
+
}
|
|
1055
|
+
function collectExistingFiles(cwd, files) {
|
|
1056
|
+
return files.filter((file) => {
|
|
1057
|
+
const resolved = path.isAbsolute(file) ? file : path.resolve(cwd, file);
|
|
1058
|
+
return fs.existsSync(resolved);
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
function compactList(items, limit) {
|
|
1062
|
+
const unique = Array.from(new Set(items)).sort((left, right) => left.localeCompare(right));
|
|
1063
|
+
const visible = unique.slice(0, limit);
|
|
1064
|
+
const hidden = unique.length - visible.length;
|
|
1065
|
+
return hidden > 0 ? [...visible, `+ ${hidden} more`] : visible;
|
|
1066
|
+
}
|
|
1067
|
+
function formatInlineList(values, limit) {
|
|
1068
|
+
const visible = values.slice(0, limit);
|
|
1069
|
+
const hidden = values.length - visible.length;
|
|
1070
|
+
return hidden > 0 ? `${visible.join(", ")}, + ${hidden} more` : visible.join(", ");
|
|
1071
|
+
}
|
|
1072
|
+
function appendFilesWrittenLines(lines, values, movedTargets) {
|
|
1073
|
+
const files = values.filter((value) => typeof value === "string");
|
|
1074
|
+
if (files.length === 0) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
const moved = new Set(movedTargets.filter((value) => typeof value === "string"));
|
|
1078
|
+
const movedFiles = files.filter((file) => moved.has(file));
|
|
1079
|
+
const referenceFiles = files.filter((file) => !moved.has(file));
|
|
1080
|
+
const visibleReferenceFiles = referenceFiles.slice(0, 8);
|
|
1081
|
+
const hiddenReferenceFiles = referenceFiles.length - visibleReferenceFiles.length;
|
|
1082
|
+
lines.push("filesWritten:");
|
|
1083
|
+
for (const file of [...movedFiles, ...visibleReferenceFiles]) {
|
|
1084
|
+
lines.push(file);
|
|
1085
|
+
}
|
|
1086
|
+
if (hiddenReferenceFiles > 0) {
|
|
1087
|
+
lines.push(`+ ${hiddenReferenceFiles} reference ${plural(hiddenReferenceFiles, "file", "files")}`);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function appendPostMutationCyclesText(lines, cycles) {
|
|
1091
|
+
lines.push("cycles:");
|
|
1092
|
+
const count = readNumber(cycles.newOrChangedCount);
|
|
1093
|
+
if (count === 0) {
|
|
1094
|
+
lines.push("no new/changed cycles involving touched files");
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
const components = Array.isArray(cycles.components) ? cycles.components.filter(isObject) : [];
|
|
1098
|
+
lines.push(formatPostMutationCycleSummary(count, components));
|
|
1099
|
+
components.forEach((component, index) => {
|
|
1100
|
+
(0, inspect_cycles_1.appendCycleComponentText)(lines, component, {
|
|
1101
|
+
detail: "imports",
|
|
1102
|
+
prefix: components.length === 1 ? "" : `${index + 1}. `,
|
|
1103
|
+
indent: components.length === 1 ? "" : " "
|
|
1104
|
+
});
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
function formatPostMutationCycleSummary(count, components) {
|
|
1108
|
+
const kinds = components.map((component) => readString(component.kind) ?? "mixed");
|
|
1109
|
+
const uniqueKinds = Array.from(new Set(kinds));
|
|
1110
|
+
const kindText = uniqueKinds.length === 1 ? `${uniqueKinds[0]} ` : "";
|
|
1111
|
+
return `${count} new/changed ${kindText}${count === 1 ? "cycle" : "cycles"} involving touched files`;
|
|
1112
|
+
}
|
|
1113
|
+
function plural(count, one, many) {
|
|
1114
|
+
return count === 1 ? one : many;
|
|
1115
|
+
}
|
|
1116
|
+
function readString(value) {
|
|
1117
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1118
|
+
}
|
|
1119
|
+
function readNumber(value) {
|
|
1120
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
1121
|
+
}
|
|
1122
|
+
function compactObject(input) {
|
|
1123
|
+
return Object.fromEntries(Object.entries(input).filter(([, value]) => {
|
|
1124
|
+
if (value === null || value === undefined) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
return !(Array.isArray(value) && value.length === 0);
|
|
1128
|
+
}));
|
|
1129
|
+
}
|
|
1130
|
+
function isObject(value) {
|
|
1131
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1132
|
+
}
|
|
1133
|
+
function normalizeKey(filePath) {
|
|
1134
|
+
const normalized = path.normalize(filePath);
|
|
1135
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
1136
|
+
}
|
|
1137
|
+
function uniqueStrings(values) {
|
|
1138
|
+
return Array.from(new Set(values));
|
|
1139
|
+
}
|
|
1140
|
+
function yieldToEventLoop() {
|
|
1141
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
1142
|
+
}
|
|
1143
|
+
async function maybeDelayPostMutationCycles(delayMs) {
|
|
1144
|
+
if (delayMs <= 0) {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
1148
|
+
}
|
|
1149
|
+
function formatRelativePath(cwd, filePath) {
|
|
1150
|
+
if (!filePath) {
|
|
1151
|
+
return "";
|
|
1152
|
+
}
|
|
1153
|
+
return path.relative(cwd, filePath).replace(/\\/g, "/");
|
|
1154
|
+
}
|