infra-kit 0.1.113 → 0.1.115
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-0d1515ce-4ebe-4ce8-a865-2897f68de168.jsonl +1 -0
- package/.omc/state/agent-replay-1fcfe0ec-7567-41c3-9bfd-501e99e86819.jsonl +19 -0
- package/.omc/state/agent-replay-38382db5-3088-4b5a-aff7-2561a60827c7.jsonl +17 -0
- package/.omc/state/agent-replay-50c36be9-a3a2-42b9-9c85-5a06d3e22f6a.jsonl +5 -0
- package/.omc/state/agent-replay-8198b3e5-fad6-4ee0-9c59-ef773ad89af4.jsonl +1 -0
- package/.omc/state/agent-replay-8cd7652a-b8b5-49cf-9b1f-bee8e5972458.jsonl +3 -0
- package/.omc/state/agent-replay-9bea518f-a9ee-4d14-bb53-a936ebaf647c.jsonl +7 -0
- package/.omc/state/agent-replay-b52d89fb-0e24-4901-bc66-27e3c1697126.jsonl +2 -0
- package/.omc/state/agent-replay-f581a1ae-0ee4-48a3-96f3-ce31a0633bb0.jsonl +1 -0
- package/.omc/state/agent-replay-f99d8dad-81d1-4987-8183-62edf0843d0c.jsonl +2 -0
- package/.omc/state/agent-replay-fe1057b4-9a25-4e8e-8c3f-3e11652ee697.jsonl +5 -0
- package/.omc/state/idle-notif-cooldown.json +1 -1
- package/.omc/state/sessions/0d1515ce-4ebe-4ce8-a865-2897f68de168/pre-tool-advisory-throttle.json +10 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/mission-state.json +109 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/pre-tool-advisory-throttle.json +42 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/ralph-state.json +13 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/skill-active-state.json +15 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/subagent-tracking-state.json +62 -0
- package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/ultrawork-state.json +11 -0
- package/.omc/state/sessions/23d0ff82-17e5-428b-8743-38f7979bb6f3/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/23d0ff82-17e5-428b-8743-38f7979bb6f3/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/mission-state.json +145 -0
- package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/pre-tool-advisory-throttle.json +38 -0
- package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/ralplan-state.json +11 -0
- package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/subagent-tracking-state.json +98 -0
- package/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/mission-state.json +61 -0
- package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/pre-tool-advisory-throttle.json +22 -0
- package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/skill-active-state.json +15 -0
- package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/subagent-tracking-state.json +26 -0
- package/.omc/state/sessions/560ea519-574a-4713-b134-5bf6cfaf3c33/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/8198b3e5-fad6-4ee0-9c59-ef773ad89af4/pre-tool-advisory-throttle.json +14 -0
- package/.omc/state/sessions/8198b3e5-fad6-4ee0-9c59-ef773ad89af4/subagent-tracking-state.json +17 -0
- package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/ralplan-state.json +11 -0
- package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/subagent-tracking-state.json +35 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/mission-state.json +79 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/pre-tool-advisory-throttle.json +22 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/progress.txt +7 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/skill-active-state.json +15 -0
- package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/subagent-tracking-state.json +26 -0
- package/.omc/state/sessions/b52d89fb-0e24-4901-bc66-27e3c1697126/pre-tool-advisory-throttle.json +14 -0
- package/.omc/state/sessions/b52d89fb-0e24-4901-bc66-27e3c1697126/subagent-tracking-state.json +17 -0
- package/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/f581a1ae-0ee4-48a3-96f3-ce31a0633bb0/pre-tool-advisory-throttle.json +18 -0
- package/.omc/state/sessions/f581a1ae-0ee4-48a3-96f3-ce31a0633bb0/subagent-tracking-state.json +17 -0
- package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +14 -0
- package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/ralph-state.json +13 -0
- package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/ultrawork-state.json +11 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/last-tool-error-state.json +7 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/mission-state.json +61 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/prd.json +22 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/pre-tool-advisory-throttle.json +22 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/progress.txt +22 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/skill-active-state.json +15 -0
- package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/subagent-tracking-state.json +26 -0
- package/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-test.log +92 -44
- package/dist/boot-K4QUAFSP.js +2 -0
- package/dist/boot-K4QUAFSP.js.map +7 -0
- package/dist/chunk-RTSP2FCA.js +2 -0
- package/dist/chunk-RTSP2FCA.js.map +7 -0
- package/dist/chunk-VPBZR2PY.js +166 -0
- package/dist/chunk-VPBZR2PY.js.map +7 -0
- package/dist/cli.js +11 -107
- package/dist/cli.js.map +4 -4
- package/dist/entry/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/lib/vendor/config-schema.d.ts +58 -0
- package/dist/mcp.js +1 -54
- package/dist/mcp.js.map +4 -4
- package/eslint.config.js +33 -1
- package/package.json +5 -1
- package/scripts/build.js +11 -1
- package/src/.omc/state/agent-replay-c513ef38-cc3e-4a29-9c4c-1e0137245dd5.jsonl +4 -0
- package/src/.omc/state/agent-replay-ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a.jsonl +2 -0
- package/src/.omc/state/idle-notif-cooldown.json +1 -1
- package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/mission-state.json +79 -0
- package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/pre-tool-advisory-throttle.json +22 -0
- package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/subagent-tracking-state.json +26 -0
- package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/pre-tool-advisory-throttle.json +18 -0
- package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/ralph-state.json +13 -0
- package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/ultrawork-state.json +11 -0
- package/src/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +14 -0
- package/src/commands/config/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/last-tool-error-state.json +7 -0
- package/src/commands/config/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/pre-tool-advisory-throttle.json +18 -0
- package/src/commands/config/config.ts +7 -37
- package/src/commands/doctor/__tests__/agent-files.test.ts +8 -30
- package/src/commands/doctor/__tests__/check-legacy-user-global-config.test.ts +110 -0
- package/src/commands/doctor/doctor.ts +110 -44
- package/src/commands/env-autoload/env-autoload.ts +12 -0
- package/src/commands/env-autoload/index.ts +1 -0
- package/src/commands/env-clear/__tests__/env-clear.test.ts +27 -0
- package/src/commands/env-clear/env-clear.ts +22 -8
- package/src/commands/env-load/__tests__/env-load.test.ts +36 -1
- package/src/commands/env-load/env-load.ts +152 -35
- package/src/commands/env-load/index.ts +2 -1
- package/src/commands/env-status/__tests__/env-status.test.ts +78 -0
- package/src/commands/env-status/env-status.ts +19 -7
- package/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts +45 -1
- package/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts +46 -1
- package/src/commands/init/__tests__/agent-files.test.ts +145 -27
- package/src/commands/init/__tests__/migrate-config.test.ts +136 -5
- package/src/commands/init/__tests__/migrate-factory-config.test.ts +93 -0
- package/src/commands/init/__tests__/seed-user-global-config.test.ts +64 -0
- package/src/commands/init/__tests__/shell-body.test.ts +30 -0
- package/src/commands/init/agent-files.ts +65 -45
- package/src/commands/init/init.ts +140 -31
- package/src/commands/init/migrate-config.ts +160 -32
- package/src/commands/vendor-check/__tests__/runtime-isolation.test.ts +71 -0
- package/src/commands/vendor-check/__tests__/vendor-check.test.ts +87 -0
- package/src/commands/vendor-check/index.ts +1 -0
- package/src/commands/vendor-check/vendor-check.ts +127 -0
- package/src/commands/vendor-config/__tests__/vendor-config.test.ts +103 -0
- package/src/commands/vendor-config/index.ts +1 -0
- package/src/commands/vendor-config/vendor-config.ts +162 -0
- package/src/commands/vendor-diff/__tests__/vendor-diff.test.ts +74 -0
- package/src/commands/vendor-diff/index.ts +1 -0
- package/src/commands/vendor-diff/vendor-diff.ts +77 -0
- package/src/commands/vendor-manifest/index.ts +1 -0
- package/src/commands/vendor-manifest/vendor-manifest.ts +60 -0
- package/src/commands/vendor-sync/__tests__/vendor-write.test.ts +86 -0
- package/src/commands/vendor-sync/index.ts +1 -0
- package/src/commands/vendor-sync/vendor-sync.ts +90 -0
- package/src/commands/worktrees-add/worktrees-add.ts +1 -1
- package/src/commands/worktrees-reload/worktrees-reload.ts +6 -5
- package/src/commands/worktrees-remove/worktrees-remove.ts +10 -1
- package/src/commands/worktrees-sync/worktrees-sync.ts +9 -1
- package/src/entry/cli.ts +417 -210
- package/src/entry/index.ts +7 -1
- package/src/integrations/cmux/__tests__/open-workspace-with-layout.test.ts +127 -0
- package/src/integrations/cmux/close-workspace-by-title.ts +2 -2
- package/src/integrations/cmux/list-workspace-titles.ts +1 -1
- package/src/integrations/cmux/open-workspace-with-layout.ts +15 -4
- package/src/integrations/cursor/.omc/state/agent-replay-f99d8dad-81d1-4987-8183-62edf0843d0c.jsonl +2 -0
- package/src/integrations/cursor/.omc/state/idle-notif-cooldown.json +3 -0
- package/src/integrations/cursor/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +18 -0
- package/src/integrations/cursor/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/subagent-tracking-state.json +17 -0
- package/src/integrations/cursor/index.ts +1 -0
- package/src/integrations/cursor/launch-cursor.ts +12 -0
- package/src/integrations/cursor/open-cursor-workspace.ts +8 -14
- package/src/integrations/doppler/__tests__/doppler-errors.test.ts +76 -0
- package/src/integrations/doppler/doppler-cli-auth.ts +12 -4
- package/src/integrations/doppler/doppler-errors.ts +88 -0
- package/src/integrations/doppler/doppler-project.ts +80 -0
- package/src/integrations/doppler/index.ts +3 -1
- package/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts +9 -5
- package/src/integrations/gh/gh-release-prs/gh-release-prs.ts +16 -8
- package/src/integrations/ide/__tests__/ide-facade.test.ts +57 -10
- package/src/integrations/ide/add-ide-worktree-folders.ts +2 -4
- package/src/integrations/ide/open-ide-workspace.ts +6 -6
- package/src/integrations/ide/remove-ide-worktree-folders.ts +95 -30
- package/src/integrations/ide/types.ts +10 -1
- package/src/integrations/zed/__tests__/open-zed-workspace.test.ts +1 -17
- package/src/integrations/zed/__tests__/reuse-zed-workspace.test.ts +86 -0
- package/src/integrations/zed/index.ts +1 -0
- package/src/integrations/zed/open-zed-workspace.ts +4 -10
- package/src/integrations/zed/reuse-zed-workspace.ts +57 -0
- package/src/lib/command-catalog/__tests__/__snapshots__/command-catalog.test.ts.snap +212 -0
- package/src/lib/command-catalog/__tests__/command-catalog.test.ts +193 -0
- package/src/lib/command-catalog/command-catalog.ts +141 -0
- package/src/lib/command-catalog/index.ts +2 -0
- package/src/lib/command-echo/__tests__/command-echo.test.ts +127 -0
- package/src/lib/constants/constants.ts +13 -0
- package/src/lib/constants/index.ts +2 -0
- package/src/lib/env-autoload/__tests__/env-autoload.test.ts +288 -0
- package/src/lib/env-autoload/env-autoload.ts +294 -0
- package/src/lib/env-autoload/index.ts +9 -0
- package/src/lib/errors/operation-error.ts +1 -1
- package/src/lib/infra-kit-config/__tests__/env-autoload-schema.test.ts +71 -0
- package/src/lib/infra-kit-config/__tests__/infra-kit-config.test.ts +77 -6
- package/src/lib/infra-kit-config/index.ts +9 -1
- package/src/lib/infra-kit-config/infra-kit-config.ts +71 -11
- package/src/lib/json-output/__tests__/json-output.test.ts +139 -0
- package/src/lib/json-output/index.ts +1 -0
- package/src/lib/json-output/json-output.ts +47 -0
- package/src/lib/managed-block/managed-block.ts +4 -4
- package/src/lib/path-display/index.ts +1 -0
- package/src/lib/path-display/path-display.ts +42 -0
- package/src/lib/render/__tests__/render.test.ts +48 -0
- package/src/lib/render/index.ts +1 -0
- package/src/lib/render/render.ts +24 -0
- package/src/lib/vendor/__tests__/config-schema.test.ts +31 -0
- package/src/lib/vendor/__tests__/config.test.ts +63 -0
- package/src/lib/vendor/__tests__/factory-config.test.ts +92 -0
- package/src/lib/vendor/__tests__/vendor-lib.test.ts +158 -0
- package/src/lib/vendor/__tests__/zx-mock.ts +32 -0
- package/src/lib/vendor/config-schema.ts +78 -0
- package/src/lib/vendor/config.ts +58 -0
- package/src/lib/vendor/factory-config-schema.ts +35 -0
- package/src/lib/vendor/factory-config.ts +91 -0
- package/src/lib/vendor/hash.ts +16 -0
- package/src/lib/vendor/index.ts +23 -0
- package/src/lib/vendor/manifest.ts +151 -0
- package/src/lib/vendor/skip-sets.ts +48 -0
- package/src/lib/vendor/sync-ops.ts +290 -0
- package/src/lib/vendor/walk.ts +56 -0
- package/src/lib/worktrees/remove-worktrees.ts +15 -0
- package/src/mcp/tools/index.ts +5 -42
- package/src/sanity.test.tsx +1 -0
- package/src/tui/__tests__/no-react-boundary.test.ts +51 -0
- package/src/tui/boot.tsx +45 -0
- package/src/tui/screens/__tests__/command-palette.test.tsx +136 -0
- package/src/tui/screens/command-palette.tsx +159 -0
- package/src/tui/types.ts +8 -0
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +8 -0
- package/src/commands/worktrees-open/__tests__/open-cmux.test.ts +0 -96
- package/src/commands/worktrees-open/index.ts +0 -1
- package/src/commands/worktrees-open/worktrees-open.ts +0 -195
package/src/entry/cli.ts
CHANGED
|
@@ -5,6 +5,7 @@ import process from 'node:process'
|
|
|
5
5
|
import { audit } from 'src/commands/audit'
|
|
6
6
|
import { configEdit, configPath } from 'src/commands/config'
|
|
7
7
|
import { doctor } from 'src/commands/doctor'
|
|
8
|
+
import { envAutoload } from 'src/commands/env-autoload'
|
|
8
9
|
import { envClear } from 'src/commands/env-clear'
|
|
9
10
|
import { envList } from 'src/commands/env-list'
|
|
10
11
|
import { envLoad } from 'src/commands/env-load'
|
|
@@ -17,16 +18,24 @@ import { ghReleaseList } from 'src/commands/gh-release-list'
|
|
|
17
18
|
import { init } from 'src/commands/init'
|
|
18
19
|
import { releaseCreate } from 'src/commands/release-create'
|
|
19
20
|
import { releaseDescEdit } from 'src/commands/release-desc-edit'
|
|
21
|
+
import { vendorCheck } from 'src/commands/vendor-check'
|
|
22
|
+
import { vendorConfig } from 'src/commands/vendor-config'
|
|
23
|
+
import { vendorDiff } from 'src/commands/vendor-diff'
|
|
24
|
+
import { vendorManifest } from 'src/commands/vendor-manifest'
|
|
25
|
+
import { vendorSync } from 'src/commands/vendor-sync'
|
|
20
26
|
import { version } from 'src/commands/version'
|
|
21
27
|
import { worktreesAdd } from 'src/commands/worktrees-add'
|
|
22
28
|
import { worktreesList } from 'src/commands/worktrees-list'
|
|
23
|
-
import { worktreesOpen } from 'src/commands/worktrees-open'
|
|
24
29
|
import { worktreesReload } from 'src/commands/worktrees-reload'
|
|
25
30
|
import { worktreesRemove } from 'src/commands/worktrees-remove'
|
|
26
31
|
import { worktreesSync } from 'src/commands/worktrees-sync'
|
|
27
32
|
import { IDE_MODES } from 'src/integrations/ide'
|
|
28
33
|
import type { IdeMode } from 'src/integrations/ide'
|
|
34
|
+
import { getMenuGroupCommands } from 'src/lib/command-catalog'
|
|
35
|
+
import { runEnvAutoLoad } from 'src/lib/env-autoload'
|
|
36
|
+
import { addJsonOption, emit, jsonOutput } from 'src/lib/json-output'
|
|
29
37
|
import { logger } from 'src/lib/logger'
|
|
38
|
+
import { formatAlignedRows } from 'src/lib/render'
|
|
30
39
|
import { parseReleaseSpec } from 'src/lib/version-utils'
|
|
31
40
|
import type { ReleaseInput } from 'src/lib/version-utils'
|
|
32
41
|
|
|
@@ -36,6 +45,11 @@ const collectReleaseSpec = (value: string, prev: string[]): string[] => {
|
|
|
36
45
|
return [...prev, value]
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
/** Parse a `--repos a,b,c` option into a target-name list (undefined = all). */
|
|
49
|
+
const parseRepos = (value: unknown): string[] | undefined => {
|
|
50
|
+
return typeof value === 'string' ? value.split(',').filter(Boolean) : undefined
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
const normalizeIdeMode = (value: unknown, flagName: '--ide' | '--cursor'): IdeMode | undefined => {
|
|
40
54
|
if (typeof value === 'undefined') {
|
|
41
55
|
return undefined
|
|
@@ -71,164 +85,244 @@ const runProgram = async (argv?: string[]): Promise<void> => {
|
|
|
71
85
|
}
|
|
72
86
|
}
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
// --- Deprecation support for flat command aliases (Phase 3 grouping) ---
|
|
89
|
+
// Flat names (`release-create`, `worktrees-add`, `vendor-config`, ...) are kept
|
|
90
|
+
// as working aliases of the grouped forms (`release create`, ...) for one
|
|
91
|
+
// release cycle. They warn once when invoked directly, but stay silent when the
|
|
92
|
+
// interactive no-arg menu drives them (the menu is a guided surface).
|
|
93
|
+
const invokedViaMenu = { value: false }
|
|
94
|
+
|
|
95
|
+
const deprecatedAlias = (cmd: Command, preferred: string): Command => {
|
|
96
|
+
return cmd.hook('preAction', () => {
|
|
97
|
+
if (!invokedViaMenu.value) {
|
|
98
|
+
logger.warn(`"${cmd.name()}" is a deprecated alias; use "${preferred}" instead.`)
|
|
99
|
+
}
|
|
81
100
|
})
|
|
101
|
+
}
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
// --- Command configurators (one source of options + action, shared by the
|
|
104
|
+
// grouped form and its flat alias so the two can never diverge) ---
|
|
105
|
+
const configureMergeDev = (cmd: Command): Command => {
|
|
106
|
+
return cmd
|
|
107
|
+
.description('Merge dev branch into every release branch')
|
|
108
|
+
.option('-a, --all', 'Select all active release branches')
|
|
109
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
110
|
+
.action(async (options) => {
|
|
111
|
+
emit(await ghMergeDev({ all: options.all, confirmedCommand: options.yes }))
|
|
112
|
+
})
|
|
113
|
+
}
|
|
89
114
|
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
'Release spec "<version|next|name>[:type[:description]]" (repeatable). The token is a semver ("1.2.5"), the literal "next", or a kebab-case name ("checkout-redesign"). Type is regular|hotfix (default regular). Examples: "1.2.5", "1.2.5:hotfix", "next:regular:Holiday backend", "checkout-redesign:regular:Q3 redesign".',
|
|
96
|
-
collectReleaseSpec,
|
|
97
|
-
[],
|
|
98
|
-
)
|
|
99
|
-
.option('-y, --yes', 'Skip confirmation prompt')
|
|
100
|
-
.action(async (options) => {
|
|
101
|
-
const specs = options.release as string[]
|
|
102
|
-
const inputs: ReleaseInput[] = specs.map(parseReleaseSpec)
|
|
103
|
-
const releases = inputs.length > 0 ? inputs : undefined
|
|
115
|
+
const configureReleaseList = (cmd: Command): Command => {
|
|
116
|
+
return cmd.description('List all release branches').action(async () => {
|
|
117
|
+
emit(await ghReleaseList())
|
|
118
|
+
})
|
|
119
|
+
}
|
|
104
120
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
const configureReleaseCreate = (cmd: Command): Command => {
|
|
122
|
+
return cmd
|
|
123
|
+
.description('Create one or more release branches (each entry can mix regular/hotfix and its own description)')
|
|
124
|
+
.option(
|
|
125
|
+
'-r, --release <spec>',
|
|
126
|
+
'Release spec "<version|next|name>[:type[:description]]" (repeatable). The token is a semver ("1.2.5"), the literal "next", or a kebab-case name ("checkout-redesign"). Type is regular|hotfix (default regular). Examples: "1.2.5", "1.2.5:hotfix", "next:regular:Holiday backend", "checkout-redesign:regular:Q3 redesign".',
|
|
127
|
+
collectReleaseSpec,
|
|
128
|
+
[],
|
|
129
|
+
)
|
|
130
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
131
|
+
.action(async (options) => {
|
|
132
|
+
const specs = options.release as string[]
|
|
133
|
+
const inputs: ReleaseInput[] = specs.map(parseReleaseSpec)
|
|
134
|
+
const releases = inputs.length > 0 ? inputs : undefined
|
|
135
|
+
|
|
136
|
+
emit(
|
|
137
|
+
await releaseCreate({
|
|
138
|
+
releases,
|
|
139
|
+
confirmedCommand: options.yes,
|
|
140
|
+
}),
|
|
141
|
+
)
|
|
108
142
|
})
|
|
109
|
-
|
|
143
|
+
}
|
|
110
144
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const configureReleaseDescEdit = (cmd: Command): Command => {
|
|
146
|
+
return cmd
|
|
147
|
+
.description("Edit a release's description in Jira and in the matching GitHub PR body")
|
|
148
|
+
.option('-v, --version <version>', 'Release version (e.g. 1.2.5) or release name (e.g. checkout-redesign)')
|
|
149
|
+
.option('-d, --description <description>', 'New description (use "" to clear)')
|
|
150
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
151
|
+
.action(async (options) => {
|
|
152
|
+
emit(
|
|
153
|
+
await releaseDescEdit({
|
|
154
|
+
version: options.version,
|
|
155
|
+
description: options.description,
|
|
156
|
+
confirmedCommand: options.yes,
|
|
157
|
+
}),
|
|
158
|
+
)
|
|
122
159
|
})
|
|
123
|
-
|
|
160
|
+
}
|
|
124
161
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
162
|
+
const configureReleaseDeployAll = (cmd: Command): Command => {
|
|
163
|
+
return cmd
|
|
164
|
+
.description('Deploy any release branch to any environment')
|
|
165
|
+
.option(
|
|
166
|
+
'-v, --version <version>',
|
|
167
|
+
'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch',
|
|
168
|
+
)
|
|
169
|
+
.option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')
|
|
170
|
+
.option('--skip-terraform', 'Skip terraform deployment step')
|
|
171
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
172
|
+
.action(async (options) => {
|
|
173
|
+
emit(
|
|
174
|
+
await ghReleaseDeployAll({
|
|
175
|
+
version: options.version,
|
|
176
|
+
env: options.env,
|
|
177
|
+
skipTerraform: options.skipTerraform,
|
|
178
|
+
confirmedCommand: options.yes,
|
|
179
|
+
}),
|
|
180
|
+
)
|
|
181
|
+
})
|
|
182
|
+
}
|
|
137
183
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
184
|
+
const configureReleaseDeploySelected = (cmd: Command): Command => {
|
|
185
|
+
return cmd
|
|
186
|
+
.description('Deploy selected services from release branch to any environment')
|
|
187
|
+
.option(
|
|
188
|
+
'-v, --version <version>',
|
|
189
|
+
'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch',
|
|
190
|
+
)
|
|
191
|
+
.option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')
|
|
192
|
+
.option('-s, --services <services...>', 'Specify services to deploy, e.g. client-be client-fe')
|
|
193
|
+
.option('--skip-terraform', 'Skip terraform deployment step')
|
|
194
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
195
|
+
.action(async (options) => {
|
|
196
|
+
emit(
|
|
197
|
+
await ghReleaseDeploySelected({
|
|
198
|
+
version: options.version,
|
|
199
|
+
env: options.env,
|
|
200
|
+
services: options.services,
|
|
201
|
+
skipTerraform: options.skipTerraform,
|
|
202
|
+
confirmedCommand: options.yes,
|
|
203
|
+
}),
|
|
204
|
+
)
|
|
154
205
|
})
|
|
155
|
-
|
|
206
|
+
}
|
|
156
207
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
208
|
+
const configureReleaseDeliver = (cmd: Command): Command => {
|
|
209
|
+
return cmd
|
|
210
|
+
.description('Release a new version to production')
|
|
211
|
+
.option('-v, --version <version>', 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deliver')
|
|
212
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
213
|
+
.action(async (options) => {
|
|
214
|
+
emit(await ghReleaseDeliver({ version: options.version, confirmedCommand: options.yes }))
|
|
215
|
+
})
|
|
216
|
+
}
|
|
165
217
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
218
|
+
const configureWorktreesSync = (cmd: Command): Command => {
|
|
219
|
+
return cmd
|
|
220
|
+
.description('Remove release worktrees whose PRs are no longer open')
|
|
221
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
222
|
+
.action(async (options) => {
|
|
223
|
+
emit(await worktreesSync({ confirmedCommand: options.yes }))
|
|
224
|
+
})
|
|
225
|
+
}
|
|
173
226
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
227
|
+
const configureWorktreesAdd = (cmd: Command): Command => {
|
|
228
|
+
return cmd
|
|
229
|
+
.description('Add git worktrees for release branches')
|
|
230
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
231
|
+
.option('-a, --all', 'Select all active release branches')
|
|
232
|
+
.option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')
|
|
233
|
+
.option('-i, --ide [mode]', 'Editor mode for created worktrees: workspace (default) | none')
|
|
234
|
+
.option('--no-ide', 'Skip the editor (alias for --ide none)')
|
|
235
|
+
.option('-c, --cursor [mode]', 'Deprecated alias for --ide')
|
|
236
|
+
.option('--no-cursor', 'Deprecated alias for --no-ide')
|
|
237
|
+
.option('-g, --github-desktop', 'Open created worktrees in GitHub Desktop')
|
|
238
|
+
.option('--no-github-desktop', 'Skip GitHub Desktop prompt')
|
|
239
|
+
.option('-m, --cmux', 'Open created worktrees in cmux (3-pane layout)')
|
|
240
|
+
.option('--no-cmux', 'Skip cmux prompt')
|
|
241
|
+
.action(async (options) => {
|
|
242
|
+
// `--ide` wins over the deprecated `--cursor` alias when both are provided.
|
|
243
|
+
const ide = normalizeIdeMode(options.ide, '--ide') ?? normalizeIdeMode(options.cursor, '--cursor')
|
|
244
|
+
|
|
245
|
+
emit(
|
|
246
|
+
await worktreesAdd({
|
|
247
|
+
confirmedCommand: options.yes,
|
|
248
|
+
all: options.all,
|
|
249
|
+
versions: options.versions,
|
|
250
|
+
ide,
|
|
251
|
+
githubDesktop: options.githubDesktop,
|
|
252
|
+
cmux: options.cmux,
|
|
253
|
+
}),
|
|
254
|
+
)
|
|
199
255
|
})
|
|
200
|
-
|
|
256
|
+
}
|
|
201
257
|
|
|
202
|
-
|
|
203
|
-
.
|
|
204
|
-
|
|
205
|
-
.action(async () => {
|
|
206
|
-
await worktreesList()
|
|
258
|
+
const configureWorktreesList = (cmd: Command): Command => {
|
|
259
|
+
return cmd.description('List all git worktrees with detailed information').action(async () => {
|
|
260
|
+
emit(await worktreesList())
|
|
207
261
|
})
|
|
262
|
+
}
|
|
208
263
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
264
|
+
const configureWorktreesRemove = (cmd: Command): Command => {
|
|
265
|
+
return cmd
|
|
266
|
+
.description('Remove git worktrees for release branches')
|
|
267
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
268
|
+
.option('-a, --all', 'Select all active release branches')
|
|
269
|
+
.option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')
|
|
270
|
+
.action(async (options) => {
|
|
271
|
+
emit(await worktreesRemove({ confirmedCommand: options.yes, all: options.all, versions: options.versions }))
|
|
272
|
+
})
|
|
273
|
+
}
|
|
218
274
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
275
|
+
const configureWorktreesReload = (cmd: Command): Command => {
|
|
276
|
+
return cmd
|
|
277
|
+
.description(
|
|
278
|
+
'Close all cmux/editor worktree windows, then reopen the current release worktrees (also cold-start restore)',
|
|
279
|
+
)
|
|
280
|
+
.action(async () => {
|
|
281
|
+
emit(await worktreesReload())
|
|
282
|
+
})
|
|
283
|
+
}
|
|
225
284
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
285
|
+
const configureVendorConfig = (cmd: Command): Command => {
|
|
286
|
+
return cmd
|
|
287
|
+
.description('Show the machine-local factory config (~/.infra-kit/vendor.json) or scaffold it with --init')
|
|
288
|
+
.option('--init', 'Scaffold ~/.infra-kit/vendor.json (skips if it already exists)')
|
|
289
|
+
.action(async (options) => {
|
|
290
|
+
emit(await vendorConfig({ init: options.init }))
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// --- Grouped command surface (preferred form) ---
|
|
295
|
+
const releaseGroup = program.command('release').description('Release management commands')
|
|
296
|
+
|
|
297
|
+
configureMergeDev(releaseGroup.command('merge-dev'))
|
|
298
|
+
configureReleaseList(releaseGroup.command('list'))
|
|
299
|
+
configureReleaseCreate(releaseGroup.command('create'))
|
|
300
|
+
configureReleaseDescEdit(releaseGroup.command('desc-edit'))
|
|
301
|
+
configureReleaseDeployAll(releaseGroup.command('deploy-all'))
|
|
302
|
+
configureReleaseDeploySelected(releaseGroup.command('deploy-selected'))
|
|
303
|
+
configureReleaseDeliver(releaseGroup.command('deliver'))
|
|
304
|
+
|
|
305
|
+
const worktreesGroup = program.command('worktrees').description('Git worktree management commands')
|
|
306
|
+
|
|
307
|
+
configureWorktreesAdd(worktreesGroup.command('add'))
|
|
308
|
+
configureWorktreesList(worktreesGroup.command('list'))
|
|
309
|
+
configureWorktreesRemove(worktreesGroup.command('remove'))
|
|
310
|
+
configureWorktreesSync(worktreesGroup.command('sync'))
|
|
311
|
+
configureWorktreesReload(worktreesGroup.command('reload'))
|
|
312
|
+
|
|
313
|
+
// --- Deprecated flat aliases (kept one release cycle; warn when used directly) ---
|
|
314
|
+
deprecatedAlias(configureMergeDev(program.command('merge-dev')), 'release merge-dev')
|
|
315
|
+
deprecatedAlias(configureReleaseList(program.command('release-list')), 'release list')
|
|
316
|
+
deprecatedAlias(configureReleaseCreate(program.command('release-create')), 'release create')
|
|
317
|
+
deprecatedAlias(configureReleaseDescEdit(program.command('release-desc-edit')), 'release desc-edit')
|
|
318
|
+
deprecatedAlias(configureReleaseDeployAll(program.command('release-deploy-all')), 'release deploy-all')
|
|
319
|
+
deprecatedAlias(configureReleaseDeploySelected(program.command('release-deploy-selected')), 'release deploy-selected')
|
|
320
|
+
deprecatedAlias(configureReleaseDeliver(program.command('release-deliver')), 'release deliver')
|
|
321
|
+
deprecatedAlias(configureWorktreesAdd(program.command('worktrees-add')), 'worktrees add')
|
|
322
|
+
deprecatedAlias(configureWorktreesList(program.command('worktrees-list')), 'worktrees list')
|
|
323
|
+
deprecatedAlias(configureWorktreesRemove(program.command('worktrees-remove')), 'worktrees remove')
|
|
324
|
+
deprecatedAlias(configureWorktreesSync(program.command('worktrees-sync')), 'worktrees sync')
|
|
325
|
+
deprecatedAlias(configureWorktreesReload(program.command('worktrees-reload')), 'worktrees reload')
|
|
232
326
|
|
|
233
327
|
const configCmd = program.command('config').description('Manage infra-kit configuration files')
|
|
234
328
|
|
|
@@ -236,14 +330,14 @@ configCmd
|
|
|
236
330
|
.command('path')
|
|
237
331
|
.description('Show the resolved config merge chain and file paths')
|
|
238
332
|
.action(async () => {
|
|
239
|
-
await configPath()
|
|
333
|
+
emit(await configPath())
|
|
240
334
|
})
|
|
241
335
|
|
|
242
336
|
configCmd
|
|
243
337
|
.command('edit')
|
|
244
338
|
.description('Open the user-scope per-project override file in $EDITOR')
|
|
245
339
|
.action(async () => {
|
|
246
|
-
await configEdit()
|
|
340
|
+
emit(await configEdit())
|
|
247
341
|
})
|
|
248
342
|
|
|
249
343
|
program
|
|
@@ -254,44 +348,97 @@ program
|
|
|
254
348
|
.action(async (options) => {
|
|
255
349
|
const result = await audit({ all: options.all, root: options.root })
|
|
256
350
|
|
|
351
|
+
emit(result)
|
|
352
|
+
|
|
257
353
|
if (!result.structuredContent.allPassed) {
|
|
258
354
|
process.exitCode = 1
|
|
259
355
|
}
|
|
260
356
|
})
|
|
261
357
|
|
|
358
|
+
const vendorCmd = program.command('vendor').description('Verify and sync the mirrored vendor/ tree')
|
|
359
|
+
|
|
360
|
+
vendorCmd
|
|
361
|
+
.command('check')
|
|
362
|
+
.description('Verify vendor/ matches vendor/.sync-manifest.json (self-contained; for any consumer repo)')
|
|
363
|
+
.action(async () => {
|
|
364
|
+
const result = await vendorCheck()
|
|
365
|
+
|
|
366
|
+
emit(result)
|
|
367
|
+
|
|
368
|
+
if (!result.structuredContent.ok) {
|
|
369
|
+
process.exitCode = 1
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
vendorCmd
|
|
374
|
+
.command('sync')
|
|
375
|
+
.description('Copy vendored files from the source repo into each target and regenerate manifests')
|
|
376
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
377
|
+
.option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')
|
|
378
|
+
.action(async (options) => {
|
|
379
|
+
emit(await vendorSync({ confirmedCommand: options.yes, repos: parseRepos(options.repos) }))
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
vendorCmd
|
|
383
|
+
.command('manifest')
|
|
384
|
+
.description('Regenerate each target vendor/.sync-manifest.json + README from current content (no copy)')
|
|
385
|
+
.option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')
|
|
386
|
+
.action(async (options) => {
|
|
387
|
+
emit(await vendorManifest({ confirmedCommand: true, repos: parseRepos(options.repos) }))
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
vendorCmd
|
|
391
|
+
.command('diff')
|
|
392
|
+
.description('Source-aware drift check (rsync dry-run) of each target vendored subtree vs the source')
|
|
393
|
+
.option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')
|
|
394
|
+
.action(async (options) => {
|
|
395
|
+
const result = await vendorDiff({ repos: parseRepos(options.repos) })
|
|
396
|
+
|
|
397
|
+
emit(result)
|
|
398
|
+
|
|
399
|
+
if (!result.structuredContent.ok) {
|
|
400
|
+
process.exitCode = 1
|
|
401
|
+
}
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
// Grouped form (preferred); the flat `vendor-config` below is a deprecated alias.
|
|
405
|
+
configureVendorConfig(vendorCmd.command('config'))
|
|
406
|
+
|
|
407
|
+
deprecatedAlias(configureVendorConfig(program.command('vendor-config')), 'vendor config')
|
|
408
|
+
|
|
262
409
|
program
|
|
263
410
|
.command('doctor')
|
|
264
411
|
.description('Check installation and authentication status of gh and doppler CLIs')
|
|
265
412
|
.action(async () => {
|
|
266
|
-
await doctor()
|
|
413
|
+
emit(await doctor())
|
|
267
414
|
})
|
|
268
415
|
|
|
269
416
|
program
|
|
270
417
|
.command('version')
|
|
271
418
|
.description('Print the installed infra-kit CLI version')
|
|
272
419
|
.action(async () => {
|
|
273
|
-
await version()
|
|
420
|
+
emit(await version())
|
|
274
421
|
})
|
|
275
422
|
|
|
276
423
|
program
|
|
277
424
|
.command('env-status')
|
|
278
|
-
.description('Show
|
|
425
|
+
.description('Show which env is loaded in this session (local introspection; no Doppler call)')
|
|
279
426
|
.action(async () => {
|
|
280
|
-
await envStatus()
|
|
427
|
+
emit(await envStatus())
|
|
281
428
|
})
|
|
282
429
|
|
|
283
430
|
program
|
|
284
431
|
.command('env-list')
|
|
285
432
|
.description('List available Doppler configs for the detected project')
|
|
286
433
|
.action(async () => {
|
|
287
|
-
await envList()
|
|
434
|
+
emit(await envList())
|
|
288
435
|
})
|
|
289
436
|
|
|
290
437
|
program
|
|
291
438
|
.command('init')
|
|
292
439
|
.description('Inject shell integration into .zshrc and sync repo agent-instruction files')
|
|
293
440
|
.action(async () => {
|
|
294
|
-
await init()
|
|
441
|
+
emit(await init())
|
|
295
442
|
})
|
|
296
443
|
|
|
297
444
|
program
|
|
@@ -299,45 +446,67 @@ program
|
|
|
299
446
|
.description('Load Doppler env vars for a config. Source the returned file path to apply.')
|
|
300
447
|
.option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')
|
|
301
448
|
.action(async (options) => {
|
|
302
|
-
await envLoad({ config: options.config })
|
|
449
|
+
emit(await envLoad({ config: options.config }))
|
|
303
450
|
})
|
|
304
451
|
|
|
305
452
|
program
|
|
306
453
|
.command('env-clear')
|
|
307
454
|
.description('Clear loaded env vars. Source the returned file path to apply.')
|
|
308
455
|
.action(async () => {
|
|
309
|
-
await envClear()
|
|
456
|
+
emit(await envClear())
|
|
310
457
|
})
|
|
311
458
|
|
|
459
|
+
// Internal: driven by the init shell-startup integration (backgrounded). Writes
|
|
460
|
+
// env-load.sh when envAutoLoad is configured + eligible; the precmd hook sources
|
|
461
|
+
// it. Hidden + no stdout output so it never pollutes the shell or the menu.
|
|
462
|
+
program
|
|
463
|
+
.command('env-autoload', { hidden: true })
|
|
464
|
+
.description('Internal: prime env for the shell-startup auto-load trigger')
|
|
465
|
+
.action(async () => {
|
|
466
|
+
await envAutoload()
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
// Register `--json` on every command, then resolve the flag before each action
|
|
470
|
+
// runs. In JSON mode we lower the logger to `warn` so the human-oriented info
|
|
471
|
+
// lines stop cluttering stderr while errors still surface; the structured
|
|
472
|
+
// payload is written to stdout by `emit`. No handler logic is affected.
|
|
473
|
+
program.commands.forEach(addJsonOption)
|
|
474
|
+
|
|
475
|
+
// Commands excluded from the cli-invocation auto-load trigger: the env-* family
|
|
476
|
+
// (avoids recursion — `env-autoload`/`env-load` would re-enter), plus the
|
|
477
|
+
// host-inspecting / meta commands where priming Doppler env would be surprising
|
|
478
|
+
// (`init` bootstraps the shell block, `doctor` inspects auth, `version` prints a
|
|
479
|
+
// string). `--help`/`--version`/the bare-arg menu don't fire preAction at all.
|
|
480
|
+
const isAutoLoadExcludedCommand = (name: string): boolean => {
|
|
481
|
+
return name.startsWith('env-') || name === 'init' || name === 'doctor' || name === 'version'
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
485
|
+
// `optsWithGlobals` (not `opts`) so `--json` is seen on grouped subcommands:
|
|
486
|
+
// for `release list --json` Commander binds the post-subcommand flag to the
|
|
487
|
+
// parent `release` group, so the leaf's own `opts()` would not carry it.
|
|
488
|
+
jsonOutput.enabled = Boolean(actionCommand.optsWithGlobals().json)
|
|
489
|
+
|
|
490
|
+
if (jsonOutput.enabled) {
|
|
491
|
+
logger.level = 'warn'
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// cli-invocation auto-load: primes the shell env for SUBSEQUENT commands. The
|
|
495
|
+
// current command does NOT see these vars — a child process can't mutate its
|
|
496
|
+
// parent shell; the precmd hook sources the written file on the next prompt.
|
|
497
|
+
// runEnvAutoLoad self-gates on config trigger and swallows transient failures,
|
|
498
|
+
// so this is a no-op unless configured for cli-invocation and never blocks.
|
|
499
|
+
if (!isAutoLoadExcludedCommand(actionCommand.name())) {
|
|
500
|
+
await runEnvAutoLoad({ expectedTrigger: 'cli-invocation' })
|
|
501
|
+
}
|
|
502
|
+
})
|
|
503
|
+
|
|
312
504
|
if (process.argv.length <= 2) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
'release-deploy-all',
|
|
319
|
-
'release-deploy-selected',
|
|
320
|
-
'release-deliver',
|
|
321
|
-
]
|
|
322
|
-
const worktreeCommands = [
|
|
323
|
-
'worktrees-add',
|
|
324
|
-
'worktrees-list',
|
|
325
|
-
'worktrees-open',
|
|
326
|
-
'worktrees-reload',
|
|
327
|
-
'worktrees-remove',
|
|
328
|
-
'worktrees-sync',
|
|
329
|
-
]
|
|
330
|
-
const envCommands = [
|
|
331
|
-
'audit',
|
|
332
|
-
'doctor',
|
|
333
|
-
'init',
|
|
334
|
-
'version',
|
|
335
|
-
'config',
|
|
336
|
-
'env-status',
|
|
337
|
-
'env-list',
|
|
338
|
-
'env-load',
|
|
339
|
-
'env-clear',
|
|
340
|
-
]
|
|
505
|
+
// Menu groups derive from the single command catalog (no hand-maintained
|
|
506
|
+
// name arrays). Membership and order live in src/lib/command-catalog.
|
|
507
|
+
const releaseCommands = getMenuGroupCommands('release')
|
|
508
|
+
const worktreeCommands = getMenuGroupCommands('worktrees')
|
|
509
|
+
const envCommands = getMenuGroupCommands('environment')
|
|
341
510
|
|
|
342
511
|
const commandMap = new Map(
|
|
343
512
|
program.commands.map((cmd) => {
|
|
@@ -345,45 +514,83 @@ if (process.argv.length <= 2) {
|
|
|
345
514
|
}),
|
|
346
515
|
)
|
|
347
516
|
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
517
|
+
const groups = [
|
|
518
|
+
{ label: 'Release Management', names: releaseCommands },
|
|
519
|
+
{ label: 'Worktrees', names: worktreeCommands },
|
|
520
|
+
{ label: 'Environment', names: envCommands },
|
|
521
|
+
]
|
|
354
522
|
|
|
355
|
-
|
|
523
|
+
// Flat {name, description, group} list shared by both the Ink palette and the
|
|
524
|
+
// Inquirer fallback; descriptions come from Commander (single source).
|
|
525
|
+
const paletteItems = groups.flatMap(({ label, names }) => {
|
|
356
526
|
return names
|
|
357
|
-
.filter((
|
|
358
|
-
return commandMap.has(
|
|
527
|
+
.filter((name) => {
|
|
528
|
+
return commandMap.has(name)
|
|
359
529
|
})
|
|
360
|
-
.map((
|
|
361
|
-
return {
|
|
362
|
-
name: `${n.padEnd(maxLen)} ${commandMap.get(n)!.description()}`,
|
|
363
|
-
value: n,
|
|
364
|
-
}
|
|
530
|
+
.map((name) => {
|
|
531
|
+
return { name, description: commandMap.get(name)!.description(), group: label }
|
|
365
532
|
})
|
|
533
|
+
})
|
|
534
|
+
|
|
535
|
+
let selected: string | null
|
|
536
|
+
|
|
537
|
+
// Interactive TTY → Ink command palette, loaded lazily via dynamic import so
|
|
538
|
+
// React/Ink never touch the MCP / `--json` / non-TTY code paths. Otherwise fall
|
|
539
|
+
// back to the Inquirer menu (scripts, pipes, CI).
|
|
540
|
+
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
541
|
+
const { runCommandPalette } = await import('src/tui/boot')
|
|
542
|
+
|
|
543
|
+
selected = await runCommandPalette(paletteItems)
|
|
544
|
+
} else {
|
|
545
|
+
const alignedLabels = formatAlignedRows(
|
|
546
|
+
paletteItems.map((item) => {
|
|
547
|
+
return [item.name, item.description] as const
|
|
548
|
+
}),
|
|
549
|
+
)
|
|
550
|
+
const labelByName = new Map<string, string>()
|
|
551
|
+
|
|
552
|
+
paletteItems.forEach((item, index) => {
|
|
553
|
+
labelByName.set(item.name, alignedLabels[index] ?? item.name)
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
const toChoices = (names: string[]) => {
|
|
557
|
+
return names
|
|
558
|
+
.filter((name) => {
|
|
559
|
+
return commandMap.has(name)
|
|
560
|
+
})
|
|
561
|
+
.map((name) => {
|
|
562
|
+
return {
|
|
563
|
+
name: labelByName.get(name) ?? name,
|
|
564
|
+
value: name,
|
|
565
|
+
}
|
|
566
|
+
})
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
selected = await select(
|
|
570
|
+
{
|
|
571
|
+
message: 'Select a command to run',
|
|
572
|
+
choices: [
|
|
573
|
+
new Separator(' '),
|
|
574
|
+
new Separator('— Release Management —'),
|
|
575
|
+
...toChoices(releaseCommands),
|
|
576
|
+
new Separator(' '),
|
|
577
|
+
new Separator('— Worktrees —'),
|
|
578
|
+
...toChoices(worktreeCommands),
|
|
579
|
+
new Separator(' '),
|
|
580
|
+
new Separator('— Environment —'),
|
|
581
|
+
...toChoices(envCommands),
|
|
582
|
+
],
|
|
583
|
+
},
|
|
584
|
+
{ output: process.stderr },
|
|
585
|
+
)
|
|
366
586
|
}
|
|
367
587
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
choices: [
|
|
372
|
-
new Separator(' '),
|
|
373
|
-
new Separator('— Release Management —'),
|
|
374
|
-
...toChoices(releaseCommands),
|
|
375
|
-
new Separator(' '),
|
|
376
|
-
new Separator('— Worktrees —'),
|
|
377
|
-
...toChoices(worktreeCommands),
|
|
378
|
-
new Separator(' '),
|
|
379
|
-
new Separator('— Environment —'),
|
|
380
|
-
...toChoices(envCommands),
|
|
381
|
-
],
|
|
382
|
-
},
|
|
383
|
-
{ output: process.stderr },
|
|
384
|
-
)
|
|
588
|
+
// The menu is a guided surface; don't nag about deprecated flat names here.
|
|
589
|
+
if (selected) {
|
|
590
|
+
invokedViaMenu.value = true
|
|
385
591
|
|
|
386
|
-
|
|
592
|
+
await runProgram(['node', 'infra-kit', selected])
|
|
593
|
+
}
|
|
387
594
|
} else {
|
|
388
595
|
await runProgram()
|
|
389
596
|
}
|