infra-kit 0.1.126 → 0.1.128
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/.eslintcache +1 -1
- package/.omc/state/agent-replay-036daa78-5fee-4c7d-9b44-53584acb0d87.jsonl +26 -0
- package/.omc/state/agent-replay-0a65ec83-9de7-458d-9d0f-e56e1a26c68e.jsonl +2 -0
- package/.omc/state/agent-replay-1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a.jsonl +17 -0
- package/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +5 -0
- package/.omc/state/agent-replay-d02e6565-5168-40c8-8629-de219a29fa43.jsonl +2 -0
- package/.omc/state/idle-notif-cooldown.json +1 -1
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/mission-state.json +129 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/pre-tool-advisory-throttle.json +34 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralph-state.json +13 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralplan-state.json +11 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/subagent-tracking-state.json +80 -0
- package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ultrawork-state.json +11 -0
- package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/skill-active-state.json +15 -0
- package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/mission-state.json +139 -0
- package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/pre-tool-advisory-throttle.json +50 -0
- package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/ralplan-state.json +11 -0
- package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/subagent-tracking-state.json +90 -0
- package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +79 -0
- package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +10 -0
- package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/skill-active-state.json +15 -0
- package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +26 -0
- package/.omc/state/sessions/7772f972-4ec1-4287-bf42-a92c14cf3ffc/pre-tool-advisory-throttle.json +10 -0
- package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/mission-state.json +53 -0
- package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/subagent-tracking-state.json +17 -0
- package/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +10 -0
- package/.turbo/turbo-build.log +7 -6
- package/.turbo/turbo-check.log +1 -1
- package/.turbo/turbo-eslint-check.log +2 -1
- package/.turbo/turbo-infra-kit-check.log +14 -0
- package/.turbo/turbo-prettier-check.log +1 -1
- package/.turbo/turbo-test.log +406 -128
- package/.turbo/turbo-ts-check.log +1 -1
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/cli/index.html +116 -0
- package/coverage/cli/package.json.html +283 -0
- package/coverage/cli/src/commands/audit/audit.ts.html +616 -0
- package/coverage/cli/src/commands/audit/index.html +131 -0
- package/coverage/cli/src/commands/audit/index.ts.html +88 -0
- package/coverage/cli/src/commands/doctor/doctor.ts.html +1654 -0
- package/coverage/cli/src/commands/doctor/index.html +131 -0
- package/coverage/cli/src/commands/doctor/index.ts.html +88 -0
- package/coverage/cli/src/commands/env-clear/env-clear.ts.html +370 -0
- package/coverage/cli/src/commands/env-clear/index.html +131 -0
- package/coverage/cli/src/commands/env-clear/index.ts.html +88 -0
- package/coverage/cli/src/commands/env-list/env-list.ts.html +229 -0
- package/coverage/cli/src/commands/env-list/index.html +131 -0
- package/coverage/cli/src/commands/env-list/index.ts.html +88 -0
- package/coverage/cli/src/commands/env-load/env-load.ts.html +1201 -0
- package/coverage/cli/src/commands/env-load/index.html +131 -0
- package/coverage/cli/src/commands/env-load/index.ts.html +91 -0
- package/coverage/cli/src/commands/env-status/env-status.ts.html +409 -0
- package/coverage/cli/src/commands/env-status/index.html +131 -0
- package/coverage/cli/src/commands/env-status/index.ts.html +88 -0
- package/coverage/cli/src/commands/gh-merge-dev/gh-merge-dev.ts.html +694 -0
- package/coverage/cli/src/commands/gh-merge-dev/index.html +131 -0
- package/coverage/cli/src/commands/gh-merge-dev/index.ts.html +88 -0
- package/coverage/cli/src/commands/gh-release-deliver/gh-release-deliver.ts.html +1495 -0
- package/coverage/cli/src/commands/gh-release-deliver/index.html +131 -0
- package/coverage/cli/src/commands/gh-release-deliver/index.ts.html +88 -0
- package/coverage/cli/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts.html +706 -0
- package/coverage/cli/src/commands/gh-release-deploy-all/index.html +131 -0
- package/coverage/cli/src/commands/gh-release-deploy-all/index.ts.html +88 -0
- package/coverage/cli/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts.html +994 -0
- package/coverage/cli/src/commands/gh-release-deploy-selected/index.html +131 -0
- package/coverage/cli/src/commands/gh-release-deploy-selected/index.ts.html +88 -0
- package/coverage/cli/src/commands/gh-release-list/gh-release-list.ts.html +355 -0
- package/coverage/cli/src/commands/gh-release-list/index.html +131 -0
- package/coverage/cli/src/commands/gh-release-list/index.ts.html +88 -0
- package/coverage/cli/src/commands/init/agent-files.ts.html +742 -0
- package/coverage/cli/src/commands/init/index.html +146 -0
- package/coverage/cli/src/commands/init/init.ts.html +1159 -0
- package/coverage/cli/src/commands/init/migrate-config.ts.html +1219 -0
- package/coverage/cli/src/commands/release-create/index.html +131 -0
- package/coverage/cli/src/commands/release-create/index.ts.html +88 -0
- package/coverage/cli/src/commands/release-create/release-create.ts.html +1426 -0
- package/coverage/cli/src/commands/release-desc-edit/index.html +131 -0
- package/coverage/cli/src/commands/release-desc-edit/index.ts.html +88 -0
- package/coverage/cli/src/commands/release-desc-edit/release-desc-edit.ts.html +766 -0
- package/coverage/cli/src/commands/vendor-check/index.html +131 -0
- package/coverage/cli/src/commands/vendor-check/index.ts.html +88 -0
- package/coverage/cli/src/commands/vendor-check/vendor-check.ts.html +466 -0
- package/coverage/cli/src/commands/vendor-config/index.html +116 -0
- package/coverage/cli/src/commands/vendor-config/vendor-config.ts.html +571 -0
- package/coverage/cli/src/commands/vendor-diff/index.html +131 -0
- package/coverage/cli/src/commands/vendor-diff/index.ts.html +88 -0
- package/coverage/cli/src/commands/vendor-diff/vendor-diff.ts.html +316 -0
- package/coverage/cli/src/commands/vendor-manifest/index.html +131 -0
- package/coverage/cli/src/commands/vendor-manifest/index.ts.html +88 -0
- package/coverage/cli/src/commands/vendor-manifest/vendor-manifest.ts.html +265 -0
- package/coverage/cli/src/commands/vendor-sync/index.html +131 -0
- package/coverage/cli/src/commands/vendor-sync/index.ts.html +88 -0
- package/coverage/cli/src/commands/vendor-sync/vendor-sync.ts.html +355 -0
- package/coverage/cli/src/commands/version/index.html +131 -0
- package/coverage/cli/src/commands/version/index.ts.html +88 -0
- package/coverage/cli/src/commands/version/version.ts.html +184 -0
- package/coverage/cli/src/commands/worktrees-add/index.html +131 -0
- package/coverage/cli/src/commands/worktrees-add/index.ts.html +88 -0
- package/coverage/cli/src/commands/worktrees-add/worktrees-add.ts.html +1183 -0
- package/coverage/cli/src/commands/worktrees-list/index.html +131 -0
- package/coverage/cli/src/commands/worktrees-list/index.ts.html +88 -0
- package/coverage/cli/src/commands/worktrees-list/worktrees-list.ts.html +400 -0
- package/coverage/cli/src/commands/worktrees-reload/index.html +131 -0
- package/coverage/cli/src/commands/worktrees-reload/index.ts.html +88 -0
- package/coverage/cli/src/commands/worktrees-reload/worktrees-reload.ts.html +775 -0
- package/coverage/cli/src/commands/worktrees-remove/index.html +131 -0
- package/coverage/cli/src/commands/worktrees-remove/index.ts.html +88 -0
- package/coverage/cli/src/commands/worktrees-remove/worktrees-remove.ts.html +682 -0
- package/coverage/cli/src/commands/worktrees-sync/index.html +131 -0
- package/coverage/cli/src/commands/worktrees-sync/index.ts.html +88 -0
- package/coverage/cli/src/commands/worktrees-sync/worktrees-sync.ts.html +679 -0
- package/coverage/cli/src/dev/__tests__/fixtures.ts.html +787 -0
- package/coverage/cli/src/dev/__tests__/index.html +116 -0
- package/coverage/cli/src/dev/dev-server.ts.html +1855 -0
- package/coverage/cli/src/dev/discovery.ts.html +598 -0
- package/coverage/cli/src/dev/index.html +191 -0
- package/coverage/cli/src/dev/interfaces.ts.html +223 -0
- package/coverage/cli/src/dev/logger.ts.html +1102 -0
- package/coverage/cli/src/dev/ports.ts.html +430 -0
- package/coverage/cli/src/dev/serverless-local-run.ts.html +916 -0
- package/coverage/cli/src/entry/dev-server.ts.html +409 -0
- package/coverage/cli/src/entry/index.html +116 -0
- package/coverage/cli/src/index.html +116 -0
- package/coverage/cli/src/integrations/cmux/canonicalize-cmux-title.ts.html +178 -0
- package/coverage/cli/src/integrations/cmux/close-workspace-by-title.ts.html +262 -0
- package/coverage/cli/src/integrations/cmux/index.html +191 -0
- package/coverage/cli/src/integrations/cmux/index.ts.html +100 -0
- package/coverage/cli/src/integrations/cmux/list-workspace-titles.ts.html +226 -0
- package/coverage/cli/src/integrations/cmux/open-workspace-with-layout.ts.html +325 -0
- package/coverage/cli/src/integrations/cmux/workspace-title.ts.html +154 -0
- package/coverage/cli/src/integrations/cursor/add-folders-to-workspace.ts.html +337 -0
- package/coverage/cli/src/integrations/cursor/index.html +206 -0
- package/coverage/cli/src/integrations/cursor/index.ts.html +103 -0
- package/coverage/cli/src/integrations/cursor/launch-cursor.ts.html +121 -0
- package/coverage/cli/src/integrations/cursor/open-cursor-workspace.ts.html +277 -0
- package/coverage/cli/src/integrations/cursor/reconcile-workspace-folders.ts.html +355 -0
- package/coverage/cli/src/integrations/cursor/remove-folders-from-workspace.ts.html +364 -0
- package/coverage/cli/src/integrations/cursor/resolve-workspace-path.ts.html +124 -0
- package/coverage/cli/src/integrations/doppler/doppler-cli-auth.ts.html +178 -0
- package/coverage/cli/src/integrations/doppler/doppler-errors.ts.html +349 -0
- package/coverage/cli/src/integrations/doppler/doppler-project.ts.html +355 -0
- package/coverage/cli/src/integrations/doppler/index.html +161 -0
- package/coverage/cli/src/integrations/doppler/index.ts.html +97 -0
- package/coverage/cli/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts.html +172 -0
- package/coverage/cli/src/integrations/gh/gh-cli-auth/index.html +131 -0
- package/coverage/cli/src/integrations/gh/gh-cli-auth/index.ts.html +88 -0
- package/coverage/cli/src/integrations/gh/gh-release-prs/gh-release-prs.ts.html +703 -0
- package/coverage/cli/src/integrations/gh/gh-release-prs/index.html +131 -0
- package/coverage/cli/src/integrations/gh/gh-release-prs/index.ts.html +91 -0
- package/coverage/cli/src/integrations/gh/index.html +116 -0
- package/coverage/cli/src/integrations/gh/index.ts.html +94 -0
- package/coverage/cli/src/integrations/ide/add-ide-worktree-folders.ts.html +316 -0
- package/coverage/cli/src/integrations/ide/index.html +191 -0
- package/coverage/cli/src/integrations/ide/index.ts.html +103 -0
- package/coverage/cli/src/integrations/ide/open-ide-workspace.ts.html +238 -0
- package/coverage/cli/src/integrations/ide/provider-label.ts.html +157 -0
- package/coverage/cli/src/integrations/ide/remove-ide-worktree-folders.ts.html +520 -0
- package/coverage/cli/src/integrations/ide/types.ts.html +208 -0
- package/coverage/cli/src/integrations/jira/api.ts.html +1060 -0
- package/coverage/cli/src/integrations/jira/index.html +131 -0
- package/coverage/cli/src/integrations/jira/index.ts.html +142 -0
- package/coverage/cli/src/integrations/zed/add-folders-to-zed-workspace.ts.html +175 -0
- package/coverage/cli/src/integrations/zed/index.html +161 -0
- package/coverage/cli/src/integrations/zed/index.ts.html +94 -0
- package/coverage/cli/src/integrations/zed/open-zed-workspace.ts.html +238 -0
- package/coverage/cli/src/integrations/zed/reuse-zed-workspace.ts.html +256 -0
- package/coverage/cli/src/lib/assert-never/assert-never.ts.html +130 -0
- package/coverage/cli/src/lib/assert-never/index.html +131 -0
- package/coverage/cli/src/lib/assert-never/index.ts.html +88 -0
- package/coverage/cli/src/lib/command-catalog/command-catalog.ts.html +523 -0
- package/coverage/cli/src/lib/command-catalog/index.html +116 -0
- package/coverage/cli/src/lib/command-echo/command-echo.ts.html +319 -0
- package/coverage/cli/src/lib/command-echo/index.html +131 -0
- package/coverage/cli/src/lib/command-echo/index.ts.html +88 -0
- package/coverage/cli/src/lib/constants/constants.ts.html +472 -0
- package/coverage/cli/src/lib/constants/index.html +131 -0
- package/coverage/cli/src/lib/constants/index.ts.html +139 -0
- package/coverage/cli/src/lib/env-autoload/env-autoload.ts.html +1111 -0
- package/coverage/cli/src/lib/env-autoload/index.html +116 -0
- package/coverage/cli/src/lib/errors/format-zx-error.ts.html +247 -0
- package/coverage/cli/src/lib/errors/index.html +146 -0
- package/coverage/cli/src/lib/errors/is-prompt-cancellation.ts.html +199 -0
- package/coverage/cli/src/lib/errors/operation-error.ts.html +325 -0
- package/coverage/cli/src/lib/git-guard/git-guard.ts.html +250 -0
- package/coverage/cli/src/lib/git-guard/index.html +131 -0
- package/coverage/cli/src/lib/git-guard/index.ts.html +91 -0
- package/coverage/cli/src/lib/git-utils/git-utils.ts.html +622 -0
- package/coverage/cli/src/lib/git-utils/index.html +131 -0
- package/coverage/cli/src/lib/git-utils/index.ts.html +115 -0
- package/coverage/cli/src/lib/infra-kit-config/index.html +131 -0
- package/coverage/cli/src/lib/infra-kit-config/index.ts.html +142 -0
- package/coverage/cli/src/lib/infra-kit-config/infra-kit-config.ts.html +1447 -0
- package/coverage/cli/src/lib/json-output/index.html +116 -0
- package/coverage/cli/src/lib/json-output/json-output.ts.html +226 -0
- package/coverage/cli/src/lib/logger/index.html +116 -0
- package/coverage/cli/src/lib/logger/index.ts.html +205 -0
- package/coverage/cli/src/lib/managed-block/index.html +131 -0
- package/coverage/cli/src/lib/managed-block/index.ts.html +109 -0
- package/coverage/cli/src/lib/managed-block/managed-block.ts.html +520 -0
- package/coverage/cli/src/lib/package-config/index.html +146 -0
- package/coverage/cli/src/lib/package-config/index.ts.html +94 -0
- package/coverage/cli/src/lib/package-config/package-config-schema.ts.html +142 -0
- package/coverage/cli/src/lib/package-config/package-config.ts.html +376 -0
- package/coverage/cli/src/lib/package-validator/checks/config-check.ts.html +175 -0
- package/coverage/cli/src/lib/package-validator/checks/files-check.ts.html +172 -0
- package/coverage/cli/src/lib/package-validator/checks/index.html +176 -0
- package/coverage/cli/src/lib/package-validator/checks/index.ts.html +97 -0
- package/coverage/cli/src/lib/package-validator/checks/scripts-check.ts.html +154 -0
- package/coverage/cli/src/lib/package-validator/checks/turbo-check.ts.html +226 -0
- package/coverage/cli/src/lib/package-validator/fs-utils.ts.html +139 -0
- package/coverage/cli/src/lib/package-validator/index.html +146 -0
- package/coverage/cli/src/lib/package-validator/index.ts.html +94 -0
- package/coverage/cli/src/lib/package-validator/loader/config-loader.ts.html +316 -0
- package/coverage/cli/src/lib/package-validator/loader/index.html +146 -0
- package/coverage/cli/src/lib/package-validator/loader/index.ts.html +91 -0
- package/coverage/cli/src/lib/package-validator/loader/package-discovery.ts.html +379 -0
- package/coverage/cli/src/lib/package-validator/package-validator.ts.html +229 -0
- package/coverage/cli/src/lib/path-display/index.html +131 -0
- package/coverage/cli/src/lib/path-display/index.ts.html +88 -0
- package/coverage/cli/src/lib/path-display/path-display.ts.html +211 -0
- package/coverage/cli/src/lib/release-id/index.html +131 -0
- package/coverage/cli/src/lib/release-id/index.ts.html +130 -0
- package/coverage/cli/src/lib/release-id/release-id.ts.html +859 -0
- package/coverage/cli/src/lib/release-utils/index.html +131 -0
- package/coverage/cli/src/lib/release-utils/index.ts.html +130 -0
- package/coverage/cli/src/lib/release-utils/release-utils.ts.html +778 -0
- package/coverage/cli/src/lib/render/index.html +116 -0
- package/coverage/cli/src/lib/render/render.ts.html +157 -0
- package/coverage/cli/src/lib/vendor/__tests__/index.html +116 -0
- package/coverage/cli/src/lib/vendor/__tests__/zx-mock.ts.html +181 -0
- package/coverage/cli/src/lib/vendor/config-schema.ts.html +319 -0
- package/coverage/cli/src/lib/vendor/config.ts.html +259 -0
- package/coverage/cli/src/lib/vendor/factory-config-schema.ts.html +190 -0
- package/coverage/cli/src/lib/vendor/factory-config.ts.html +358 -0
- package/coverage/cli/src/lib/vendor/hash.ts.html +133 -0
- package/coverage/cli/src/lib/vendor/index.html +251 -0
- package/coverage/cli/src/lib/vendor/index.ts.html +154 -0
- package/coverage/cli/src/lib/vendor/manifest.ts.html +538 -0
- package/coverage/cli/src/lib/vendor/skip-sets.ts.html +229 -0
- package/coverage/cli/src/lib/vendor/sync-ops.ts.html +955 -0
- package/coverage/cli/src/lib/vendor/walk.ts.html +253 -0
- package/coverage/cli/src/lib/version-utils/index.html +161 -0
- package/coverage/cli/src/lib/version-utils/index.ts.html +139 -0
- package/coverage/cli/src/lib/version-utils/load-existing-versions.ts.html +343 -0
- package/coverage/cli/src/lib/version-utils/next-version.ts.html +934 -0
- package/coverage/cli/src/lib/version-utils/version-utils.ts.html +178 -0
- package/coverage/cli/src/lib/worktrees/index.html +131 -0
- package/coverage/cli/src/lib/worktrees/index.ts.html +88 -0
- package/coverage/cli/src/lib/worktrees/remove-worktrees.ts.html +283 -0
- package/coverage/cli/src/tui/boot.tsx.html +265 -0
- package/coverage/cli/src/tui/index.html +116 -0
- package/coverage/cli/src/tui/screens/command-palette.tsx.html +562 -0
- package/coverage/cli/src/tui/screens/index.html +116 -0
- package/coverage/cli/src/types.ts.html +283 -0
- package/coverage/clover.xml +4488 -0
- package/coverage/coverage-final.json +156 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +1076 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/chunk-DB6CTNBS.js +3 -0
- package/dist/chunk-DB6CTNBS.js.map +7 -0
- package/dist/chunk-QBHCWAAG.js +164 -0
- package/dist/chunk-QBHCWAAG.js.map +7 -0
- package/dist/chunk-YSBF5C7C.js +2 -0
- package/dist/chunk-YSBF5C7C.js.map +7 -0
- package/dist/cli.js +5 -5
- package/dist/cli.js.map +3 -3
- package/dist/dev-server.js +13 -0
- package/dist/dev-server.js.map +7 -0
- package/dist/index.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/mcp.js.map +1 -1
- package/package.json +7 -2
- package/scripts/build.js +4 -4
- package/src/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +5 -0
- package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +79 -0
- package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +26 -0
- package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +26 -0
- package/src/commands/audit/.omc/state/agent-replay-f9c17a0e-2dd8-4f7d-badf-631f266c5d4c.jsonl +4 -0
- package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/mission-state.json +79 -0
- package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +22 -0
- package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/subagent-tracking-state.json +26 -0
- package/src/commands/audit/audit.ts +1 -1
- package/src/commands/doctor/doctor.ts +53 -0
- package/src/commands/env-autoload/env-autoload.ts +14 -2
- package/src/commands/env-clear/env-clear.ts +48 -7
- package/src/commands/env-load/env-load.ts +23 -1
- package/src/commands/init/__tests__/shell-body.test.ts +104 -3
- package/src/commands/init/init.ts +91 -9
- package/src/dev/__tests__/dev-server-options.test.ts +57 -0
- package/src/dev/__tests__/dev-server.test.ts +420 -0
- package/src/dev/__tests__/discovery.test.ts +181 -0
- package/src/dev/__tests__/fixtures.ts +257 -0
- package/src/dev/__tests__/ports.test.ts +98 -0
- package/src/dev/__tests__/serverless-local-run.test.ts +533 -0
- package/src/dev/dev-server.ts +796 -0
- package/src/dev/discovery.ts +229 -0
- package/src/dev/interfaces.ts +11 -0
- package/src/dev/managed-child.ts +73 -0
- package/src/dev/ports.ts +100 -0
- package/src/dev/serverless-local-run.ts +329 -0
- package/src/dev/turbo-watch.ts +62 -0
- package/src/dev/ui-dev.ts +62 -0
- package/src/entry/cli.ts +25 -6
- package/src/entry/dev-server.ts +103 -0
- package/src/lib/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +18 -0
- package/src/lib/command-catalog/__tests__/__snapshots__/command-catalog.test.ts.snap +1 -0
- package/src/lib/command-catalog/command-catalog.ts +4 -0
- package/src/lib/constants/constants.ts +38 -0
- package/src/lib/constants/index.ts +4 -0
- package/src/lib/env-autoload/__tests__/env-autoload.test.ts +25 -0
- package/src/lib/env-autoload/env-autoload.ts +35 -4
- package/src/lib/infra-kit-config/index.ts +2 -0
- package/src/lib/infra-kit-config/infra-kit-config.ts +22 -0
- package/src/lib/package-config/package-config.ts +2 -2
- package/src/lib/package-validator/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +10 -0
- package/src/lib/package-validator/__tests__/package-validator.test.ts +9 -2
- package/src/lib/warm-cache/__tests__/warm-cache.test.ts +164 -0
- package/src/lib/warm-cache/index.ts +7 -0
- package/src/lib/warm-cache/warm-cache.ts +136 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-EY5LDHXC.js +0 -164
- package/dist/chunk-EY5LDHXC.js.map +0 -7
- package/dist/chunk-WA4BQRDC.js +0 -2
- package/dist/chunk-WA4BQRDC.js.map +0 -7
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem discovery helpers for the dev-server.
|
|
3
|
+
*
|
|
4
|
+
* These functions read the filesystem (walking for the monorepo root, scanning
|
|
5
|
+
* `apps/` and `packages/`) but never `chdir` and never resolve ports / prefixes —
|
|
6
|
+
* that stays with the pure {@link file://./ports.ts} layer. The starting directory
|
|
7
|
+
* is passed in so discovery is testable against a fixture root.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs'
|
|
10
|
+
import * as path from 'node:path'
|
|
11
|
+
|
|
12
|
+
/** Bare metadata for a discovered API app (no resolved port / prefix). */
|
|
13
|
+
export interface DiscoveredApiApp {
|
|
14
|
+
/** App folder name (e.g. backoffice, client). */
|
|
15
|
+
name: string
|
|
16
|
+
/** Package name from package.json (e.g. sls-trvl-client), or the folder name as fallback. */
|
|
17
|
+
packageName: string
|
|
18
|
+
path: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Walk up from `startDir` (max 10 levels) to the dir containing `pnpm-workspace.yaml`. */
|
|
22
|
+
export function findMonorepoRoot(startDir: string): string {
|
|
23
|
+
let currentDir = startDir
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < 10; i++) {
|
|
26
|
+
const workspaceFile = path.join(currentDir, 'pnpm-workspace.yaml')
|
|
27
|
+
|
|
28
|
+
if (fs.existsSync(workspaceFile)) {
|
|
29
|
+
return currentDir
|
|
30
|
+
}
|
|
31
|
+
currentDir = path.dirname(currentDir)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
throw new Error('Could not find monorepo root (pnpm-workspace.yaml)')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Read the `name` field from `<apiPath>/package.json`, falling back to `appName`. */
|
|
38
|
+
export function getPackageName(apiPath: string, appName: string): string {
|
|
39
|
+
const pkgPath = path.join(apiPath, 'package.json')
|
|
40
|
+
|
|
41
|
+
if (!fs.existsSync(pkgPath)) return appName
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { name?: string }
|
|
45
|
+
|
|
46
|
+
return typeof pkg.name === 'string' ? pkg.name : appName
|
|
47
|
+
} catch {
|
|
48
|
+
return appName
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Discover every `apps/<app>` that has an `api/serverless.yml` (bare metadata only). */
|
|
53
|
+
export function discoverApiApps(root: string): DiscoveredApiApp[] {
|
|
54
|
+
const appsDir = path.join(root, 'apps')
|
|
55
|
+
const apps: DiscoveredApiApp[] = []
|
|
56
|
+
|
|
57
|
+
if (!fs.existsSync(appsDir)) {
|
|
58
|
+
throw new Error(`Apps directory not found: ${appsDir}`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const appDirs = fs
|
|
62
|
+
.readdirSync(appsDir, { withFileTypes: true })
|
|
63
|
+
.filter((dirent) => {
|
|
64
|
+
return dirent.isDirectory()
|
|
65
|
+
})
|
|
66
|
+
.map((dirent) => {
|
|
67
|
+
return dirent.name
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
for (const appName of appDirs) {
|
|
71
|
+
const apiPath = path.join(appsDir, appName, 'api')
|
|
72
|
+
const serverlessPath = path.join(apiPath, 'serverless.yml')
|
|
73
|
+
|
|
74
|
+
if (fs.existsSync(serverlessPath)) {
|
|
75
|
+
apps.push({
|
|
76
|
+
name: appName,
|
|
77
|
+
packageName: getPackageName(apiPath, appName),
|
|
78
|
+
path: apiPath,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return apps
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Bare metadata for a discovered UI app (a frontend with its own framework `dev` script). */
|
|
87
|
+
export interface DiscoveredUiApp {
|
|
88
|
+
/** App folder name (e.g. backoffice, client). */
|
|
89
|
+
name: string
|
|
90
|
+
/** package.json `name` — used as the exact `turbo run dev --filter` target. */
|
|
91
|
+
packageName: string
|
|
92
|
+
/** Absolute path to `apps/<app>/ui`. */
|
|
93
|
+
path: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** True when `<dir>/package.json` declares a non-empty `scripts.dev`. */
|
|
97
|
+
function hasDevScript(dir: string): boolean {
|
|
98
|
+
const pkgPath = path.join(dir, 'package.json')
|
|
99
|
+
|
|
100
|
+
if (!fs.existsSync(pkgPath)) return false
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { scripts?: Record<string, string> }
|
|
104
|
+
|
|
105
|
+
return typeof pkg.scripts?.dev === 'string' && pkg.scripts.dev.length > 0
|
|
106
|
+
} catch {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Discover every `apps/<app>/ui` whose package.json declares a `dev` script — the frontends
|
|
113
|
+
* `infra-kit dev --ui` runs (via one delegated `turbo run dev`). Lenient: no `apps/` dir → `[]`
|
|
114
|
+
* (UIs are optional), unlike {@link discoverApiApps} which requires it.
|
|
115
|
+
*/
|
|
116
|
+
export function discoverUiApps(root: string): DiscoveredUiApp[] {
|
|
117
|
+
const appsDir = path.join(root, 'apps')
|
|
118
|
+
const apps: DiscoveredUiApp[] = []
|
|
119
|
+
|
|
120
|
+
if (!fs.existsSync(appsDir)) return apps
|
|
121
|
+
|
|
122
|
+
const appDirs = fs
|
|
123
|
+
.readdirSync(appsDir, { withFileTypes: true })
|
|
124
|
+
.filter((dirent) => {
|
|
125
|
+
return dirent.isDirectory()
|
|
126
|
+
})
|
|
127
|
+
.map((dirent) => {
|
|
128
|
+
return dirent.name
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
for (const appName of appDirs) {
|
|
132
|
+
const uiPath = path.join(appsDir, appName, 'ui')
|
|
133
|
+
|
|
134
|
+
if (fs.existsSync(uiPath) && hasDevScript(uiPath)) {
|
|
135
|
+
apps.push({
|
|
136
|
+
name: appName,
|
|
137
|
+
packageName: getPackageName(uiPath, appName),
|
|
138
|
+
path: uiPath,
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return apps
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Normalize the `--app` include list: drop empties, and collapse an empty list to `null`. */
|
|
147
|
+
export function normalizeAppInclude(include?: string[] | null): string[] | null {
|
|
148
|
+
const filtered = include?.filter(Boolean) ?? []
|
|
149
|
+
|
|
150
|
+
return filtered.length > 0 ? filtered : null
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Existing `packages/<pkg>/dist` directories under the monorepo root — the compiled
|
|
155
|
+
* outputs `turbo watch` rewrites. Watched (alongside app dist) because editing a shared
|
|
156
|
+
* lib rewrites only the lib's `dist`, never the dependent app's, so a package-dist change
|
|
157
|
+
* is the only signal that a lib was rebuilt.
|
|
158
|
+
*/
|
|
159
|
+
export function getPackageDistDirs(root: string): string[] {
|
|
160
|
+
const packagesDir = path.join(root, 'packages')
|
|
161
|
+
|
|
162
|
+
if (!fs.existsSync(packagesDir)) return []
|
|
163
|
+
|
|
164
|
+
const names = fs
|
|
165
|
+
.readdirSync(packagesDir, { withFileTypes: true })
|
|
166
|
+
.filter((d) => {
|
|
167
|
+
return d.isDirectory()
|
|
168
|
+
})
|
|
169
|
+
.map((d) => {
|
|
170
|
+
return d.name
|
|
171
|
+
})
|
|
172
|
+
const dirs: string[] = []
|
|
173
|
+
|
|
174
|
+
for (const name of names) {
|
|
175
|
+
const distDir = path.join(packagesDir, name, 'dist')
|
|
176
|
+
|
|
177
|
+
if (fs.existsSync(distDir) && fs.statSync(distDir).isDirectory()) {
|
|
178
|
+
dirs.push(distDir)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return dirs
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Existing `<app.path>/dist` directories for the given apps (order preserved). */
|
|
186
|
+
export function getAppDistDirs(apps: Array<{ path: string }>): string[] {
|
|
187
|
+
return apps
|
|
188
|
+
.map((app) => {
|
|
189
|
+
return path.join(app.path, 'dist')
|
|
190
|
+
})
|
|
191
|
+
.filter((dir) => {
|
|
192
|
+
return fs.existsSync(dir)
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** How a watched dist change should be routed. */
|
|
197
|
+
export interface ChangeClassification {
|
|
198
|
+
kind: 'app' | 'package'
|
|
199
|
+
/** For app changes: the matched app dist dir (undefined when nothing matched). */
|
|
200
|
+
app?: string
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Route a changed compiled-output path: a `packages/<pkg>/dist` change is a shared-package
|
|
205
|
+
* rebuild (restart every app), an `<app>/dist` change restarts only that app (the matched
|
|
206
|
+
* app dist dir is returned; `undefined` when the path matches neither). Package matches take
|
|
207
|
+
* precedence.
|
|
208
|
+
*/
|
|
209
|
+
export function classifyDistChange(
|
|
210
|
+
changedPath: string,
|
|
211
|
+
appDistDirs: string[],
|
|
212
|
+
packageDistDirs: string[],
|
|
213
|
+
): ChangeClassification {
|
|
214
|
+
const normalized = path.normalize(changedPath)
|
|
215
|
+
|
|
216
|
+
const inPackage = packageDistDirs.some((dir) => {
|
|
217
|
+
return normalized.startsWith(path.normalize(dir))
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
if (inPackage) {
|
|
221
|
+
return { kind: 'package' }
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const matchedDir = appDistDirs.find((dir) => {
|
|
225
|
+
return normalized.startsWith(path.normalize(dir))
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
return { kind: 'app', app: matchedDir }
|
|
229
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LogLevel, LoggerInterface } from '@aws-lambda-powertools/logger/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Logger handed to local dev handlers as their third `(event, ctx, log)` argument.
|
|
5
|
+
* Extends AWS Powertools `LoggerInterface` so the real Powertools `Logger` (or any
|
|
6
|
+
* compatible implementation) is assignable wherever a handler expects it.
|
|
7
|
+
*/
|
|
8
|
+
export interface ILogger extends LoggerInterface {}
|
|
9
|
+
|
|
10
|
+
// Re-export for consumers that need the Powertools LogLevel type.
|
|
11
|
+
export type { LogLevel }
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared supervision for the dev-server's long-lived, detached child processes
|
|
3
|
+
* (`turbo watch build`, `turbo run dev`). Both are deep trees
|
|
4
|
+
* (`sh → pnpm → node → turbo → …`) spawned `detached` so they form their own process
|
|
5
|
+
* group; teardown signals the whole GROUP (`process.kill(-pid, …)`), not just the wrapper.
|
|
6
|
+
*
|
|
7
|
+
* Escalation: SIGTERM first, then — if the group is still alive after a grace window —
|
|
8
|
+
* SIGKILL. FE dev servers (vite/vike/astro) run async teardown and can straggle on a
|
|
9
|
+
* lone SIGTERM (orphaned port → next run's `EADDRINUSE`), so the SIGKILL fallback matters.
|
|
10
|
+
*/
|
|
11
|
+
import type { ChildProcess } from 'node:child_process'
|
|
12
|
+
import process from 'node:process'
|
|
13
|
+
|
|
14
|
+
/** Handle to a supervised child; `kill()` reaps its whole process group and resolves when gone. */
|
|
15
|
+
export interface ManagedChild {
|
|
16
|
+
kill: () => Promise<void>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Default grace before escalating SIGTERM → SIGKILL on a stubborn process group. */
|
|
20
|
+
const DEFAULT_GRACE_MS = 2000
|
|
21
|
+
|
|
22
|
+
/** Is the process group led by `pid` still alive? (`kill(-pid, 0)` throws ESRCH when gone.) */
|
|
23
|
+
function groupAlive(pid: number): boolean {
|
|
24
|
+
try {
|
|
25
|
+
process.kill(-pid, 0)
|
|
26
|
+
|
|
27
|
+
return true
|
|
28
|
+
} catch {
|
|
29
|
+
return false
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Wrap a detached child: `unref()` it (so it never keeps the loop alive) and return a
|
|
35
|
+
* handle whose `kill()` sends a group SIGTERM, polls up to `graceMs` for the group to
|
|
36
|
+
* exit, and SIGKILLs any survivor. Resolves once the group is gone (or was never spawned).
|
|
37
|
+
*/
|
|
38
|
+
export function superviseChild(child: ChildProcess, graceMs: number = DEFAULT_GRACE_MS): ManagedChild {
|
|
39
|
+
// Don't keep the parent event loop alive on the child; the runner owns lifecycle via kill().
|
|
40
|
+
child.unref()
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
kill: async (): Promise<void> => {
|
|
44
|
+
const pid = child.pid
|
|
45
|
+
|
|
46
|
+
if (pid == null) return
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
// Negative pid → the whole group (detached made the child a group leader).
|
|
50
|
+
process.kill(-pid, 'SIGTERM')
|
|
51
|
+
} catch {
|
|
52
|
+
// Already exited (ESRCH) — nothing to reap.
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const deadline = Date.now() + graceMs
|
|
57
|
+
|
|
58
|
+
while (Date.now() < deadline) {
|
|
59
|
+
await new Promise((r) => {
|
|
60
|
+
return setTimeout(r, 100)
|
|
61
|
+
})
|
|
62
|
+
if (!groupAlive(pid)) return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Still alive after the grace window — force it.
|
|
66
|
+
try {
|
|
67
|
+
process.kill(-pid, 'SIGKILL')
|
|
68
|
+
} catch {
|
|
69
|
+
// Raced to exit between the last poll and now — fine.
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/dev/ports.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure port / URL-prefix resolution for the dev-server.
|
|
3
|
+
*
|
|
4
|
+
* These functions are intentionally side-effect free: the environment is passed
|
|
5
|
+
* in (never read from `process.env` here) and no cwd / fs access happens. That
|
|
6
|
+
* keeps port precedence and conflict detection unit-testable in isolation.
|
|
7
|
+
*/
|
|
8
|
+
import type { DevConfig } from '../lib/infra-kit-config/index.js'
|
|
9
|
+
|
|
10
|
+
/** Fallback port when no PORT / {APP}_PORT env var and no config port is set. */
|
|
11
|
+
export const DEFAULT_PORT = 3010
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* URL prefix applied to each app's routes when nothing is configured. Overridable
|
|
15
|
+
* per app via `dev.<app>.prefixUrl` in infra-kit.json — this is only the fallback.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_PREFIX_URL = '/api/v1'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parse a raw port string (env var or config), stripping a single pair of
|
|
21
|
+
* surrounding quotes and treating blank / non-numeric input as "unset".
|
|
22
|
+
*/
|
|
23
|
+
export function parsePortString(raw: string | undefined): number | undefined {
|
|
24
|
+
if (raw == null || raw === '') {
|
|
25
|
+
return undefined
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const n = parseInt(raw.trim().replace(/^["']|["']$/g, ''), 10)
|
|
29
|
+
|
|
30
|
+
return Number.isNaN(n) ? undefined : n
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the PORT for an API app (highest priority first):
|
|
35
|
+
*
|
|
36
|
+
* 1. **`{APP}_PORT`** — e.g. `CLIENT_PORT`, `SEARCH_ENGINE_PORT` (secrets manager or shell)
|
|
37
|
+
* 2. **`PORT`** — shared fallback (multi-app: use distinct `{APP}_PORT` in env)
|
|
38
|
+
* 3. **`dev.<app>.port`** from infra-kit.json
|
|
39
|
+
* 4. Default {@link DEFAULT_PORT}
|
|
40
|
+
*
|
|
41
|
+
* Per-app env keys use the app folder name in **UPPER_SNAKE_CASE** (hyphens → underscores).
|
|
42
|
+
*/
|
|
43
|
+
export function resolvePort(appName: string, env: NodeJS.ProcessEnv, devConfig: DevConfig): number {
|
|
44
|
+
const prefix = appName.replace(/-/g, '_').toUpperCase()
|
|
45
|
+
const prefixedKey = `${prefix}_PORT`
|
|
46
|
+
|
|
47
|
+
const fromPrefixed = parsePortString(env[prefixedKey])
|
|
48
|
+
|
|
49
|
+
if (fromPrefixed != null) {
|
|
50
|
+
return fromPrefixed
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const fromPort = parsePortString(env.PORT)
|
|
54
|
+
|
|
55
|
+
if (fromPort != null) {
|
|
56
|
+
return fromPort
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const fromConfig = devConfig[appName]?.port
|
|
60
|
+
|
|
61
|
+
if (fromConfig != null) {
|
|
62
|
+
return fromConfig
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return DEFAULT_PORT
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the URL prefix for an API app: `dev.<app>.prefixUrl` from
|
|
70
|
+
* infra-kit.json, falling back to {@link DEFAULT_PREFIX_URL} (`/api/v1`).
|
|
71
|
+
*/
|
|
72
|
+
export function resolvePrefixUrl(appName: string, devConfig: DevConfig): string {
|
|
73
|
+
return devConfig[appName]?.prefixUrl ?? DEFAULT_PREFIX_URL
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The apps that collide on a port, plus the raw duplicate-port list for messaging. */
|
|
77
|
+
export interface PortConflicts {
|
|
78
|
+
/** Ports that appear more than once (one entry per extra occurrence, in scan order). */
|
|
79
|
+
duplicatePorts: number[]
|
|
80
|
+
/** Every app whose resolved port is one of the duplicates. */
|
|
81
|
+
conflictingApps: Array<{ name: string; port: number }>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Find apps that resolve to the same port. Returns empty `duplicatePorts` when
|
|
86
|
+
* there is no conflict; the caller decides how to surface / throw.
|
|
87
|
+
*/
|
|
88
|
+
export function findPortConflicts(apps: Array<{ name: string; port: number }>): PortConflicts {
|
|
89
|
+
const ports = apps.map((a) => {
|
|
90
|
+
return a.port
|
|
91
|
+
})
|
|
92
|
+
const duplicatePorts = ports.filter((port, index) => {
|
|
93
|
+
return ports.indexOf(port) !== index
|
|
94
|
+
})
|
|
95
|
+
const conflictingApps = apps.filter((a) => {
|
|
96
|
+
return duplicatePorts.includes(a.port)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
return { duplicatePorts, conflictingApps }
|
|
100
|
+
}
|