infra-kit 0.1.114 → 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-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-fe1057b4-9a25-4e8e-8c3f-3e11652ee697.jsonl +5 -0
- package/.omc/state/idle-notif-cooldown.json +1 -1
- 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/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/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/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 +104 -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/open-cursor-workspace.ts +6 -11
- 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 +49 -10
- 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/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/vitest.config.ts
CHANGED
|
@@ -13,6 +13,14 @@ export default defineConfig(() => {
|
|
|
13
13
|
test: {
|
|
14
14
|
environment: 'node',
|
|
15
15
|
setupFiles: ['./vitest.setup.ts'],
|
|
16
|
+
server: {
|
|
17
|
+
deps: {
|
|
18
|
+
// ink-testing-library imports `ink` without declaring it as a dep, so
|
|
19
|
+
// pnpm's strict isolation hides it. Inlining lets vite resolve `ink`
|
|
20
|
+
// from this package's node_modules.
|
|
21
|
+
inline: ['ink-testing-library'],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
16
24
|
},
|
|
17
25
|
}
|
|
18
26
|
})
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { listCmuxWorkspaceTitles, openCmuxWorkspaceWithLayout } from 'src/integrations/cmux'
|
|
4
|
-
import { getRepoName } from 'src/lib/git-utils'
|
|
5
|
-
|
|
6
|
-
import { openCmux } from '../worktrees-open'
|
|
7
|
-
|
|
8
|
-
vi.mock('src/integrations/cmux', async (importActual) => {
|
|
9
|
-
const actual = await importActual<typeof import('src/integrations/cmux')>()
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
...actual,
|
|
13
|
-
listCmuxWorkspaceTitles: vi.fn(),
|
|
14
|
-
openCmuxWorkspaceWithLayout: vi.fn(),
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
vi.mock('src/lib/git-utils', () => {
|
|
19
|
-
return {
|
|
20
|
-
getRepoName: vi.fn(),
|
|
21
|
-
getProjectRoot: vi.fn(),
|
|
22
|
-
getCurrentWorktrees: vi.fn(),
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
const REPO = 'hulyo-monorepo'
|
|
27
|
-
const WORKTREE_DIR = '/repos/project-worktrees'
|
|
28
|
-
const BRANCHES = ['release/v1.48.0', 'release/checkout-redesign']
|
|
29
|
-
|
|
30
|
-
const titleFor = {
|
|
31
|
-
versioned: `${REPO} 1.48.0`,
|
|
32
|
-
named: `${REPO} checkout-redesign`,
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
describe('openCmux dedup', () => {
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
vi.clearAllMocks()
|
|
38
|
-
vi.mocked(getRepoName).mockResolvedValue(REPO)
|
|
39
|
-
vi.mocked(openCmuxWorkspaceWithLayout).mockResolvedValue(undefined)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('opens a workspace for every branch when none are open', async () => {
|
|
43
|
-
vi.mocked(listCmuxWorkspaceTitles).mockResolvedValue(new Set())
|
|
44
|
-
|
|
45
|
-
const result = await openCmux({ worktreeDir: WORKTREE_DIR, currentBranches: BRANCHES })
|
|
46
|
-
|
|
47
|
-
expect(result.opened).toEqual([titleFor.versioned, titleFor.named])
|
|
48
|
-
expect(result.skipped).toEqual([])
|
|
49
|
-
expect(openCmuxWorkspaceWithLayout).toHaveBeenCalledTimes(2)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('skips every branch when all are already open (no duplicates)', async () => {
|
|
53
|
-
vi.mocked(listCmuxWorkspaceTitles).mockResolvedValue(new Set([titleFor.versioned, titleFor.named]))
|
|
54
|
-
|
|
55
|
-
const result = await openCmux({ worktreeDir: WORKTREE_DIR, currentBranches: BRANCHES })
|
|
56
|
-
|
|
57
|
-
expect(result.opened).toEqual([])
|
|
58
|
-
expect(result.skipped).toEqual([titleFor.versioned, titleFor.named])
|
|
59
|
-
expect(openCmuxWorkspaceWithLayout).not.toHaveBeenCalled()
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
it('opens only the missing branch in a mixed state', async () => {
|
|
63
|
-
vi.mocked(listCmuxWorkspaceTitles).mockResolvedValue(new Set([titleFor.versioned]))
|
|
64
|
-
|
|
65
|
-
const result = await openCmux({ worktreeDir: WORKTREE_DIR, currentBranches: BRANCHES })
|
|
66
|
-
|
|
67
|
-
expect(result.skipped).toEqual([titleFor.versioned])
|
|
68
|
-
expect(result.opened).toEqual([titleFor.named])
|
|
69
|
-
expect(openCmuxWorkspaceWithLayout).toHaveBeenCalledTimes(1)
|
|
70
|
-
expect(openCmuxWorkspaceWithLayout).toHaveBeenCalledWith({
|
|
71
|
-
cwd: `${WORKTREE_DIR}/release/checkout-redesign`,
|
|
72
|
-
title: titleFor.named,
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('skips a versioned branch whose workspace was stored under an old v-prefixed title', async () => {
|
|
77
|
-
// listCmuxWorkspaceTitles already returns canonical keys, so an old
|
|
78
|
-
// "hulyo-monorepo v1.48.0" workspace is surfaced as the canonical key below.
|
|
79
|
-
vi.mocked(listCmuxWorkspaceTitles).mockResolvedValue(new Set([titleFor.versioned]))
|
|
80
|
-
|
|
81
|
-
const result = await openCmux({ worktreeDir: WORKTREE_DIR, currentBranches: ['release/v1.48.0'] })
|
|
82
|
-
|
|
83
|
-
expect(result.opened).toEqual([])
|
|
84
|
-
expect(result.skipped).toEqual([titleFor.versioned])
|
|
85
|
-
expect(openCmuxWorkspaceWithLayout).not.toHaveBeenCalled()
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('returns empty outcome when there are no worktrees', async () => {
|
|
89
|
-
vi.mocked(listCmuxWorkspaceTitles).mockResolvedValue(new Set())
|
|
90
|
-
|
|
91
|
-
const result = await openCmux({ worktreeDir: WORKTREE_DIR, currentBranches: [] })
|
|
92
|
-
|
|
93
|
-
expect(result).toEqual({ ran: true, opened: [], skipped: [] })
|
|
94
|
-
expect(listCmuxWorkspaceTitles).not.toHaveBeenCalled()
|
|
95
|
-
})
|
|
96
|
-
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { worktreesOpen, worktreesOpenMcpTool } from './worktrees-open'
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
buildCmuxWorkspaceTitle,
|
|
5
|
-
canonicalizeCmuxTitle,
|
|
6
|
-
listCmuxWorkspaceTitles,
|
|
7
|
-
openCmuxWorkspaceWithLayout,
|
|
8
|
-
} from 'src/integrations/cmux'
|
|
9
|
-
import { ideProviderLabel, openIdeWorkspace } from 'src/integrations/ide'
|
|
10
|
-
import type { IdeProvider } from 'src/integrations/ide'
|
|
11
|
-
import { commandEcho } from 'src/lib/command-echo'
|
|
12
|
-
import { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'
|
|
13
|
-
import { OperationError } from 'src/lib/errors/operation-error'
|
|
14
|
-
import { getCurrentWorktrees, getProjectRoot, getRepoName } from 'src/lib/git-utils'
|
|
15
|
-
import { logger } from 'src/lib/logger'
|
|
16
|
-
import { defineMcpTool, textContent } from 'src/types'
|
|
17
|
-
|
|
18
|
-
interface WorktreesOpenResult {
|
|
19
|
-
openedCmux: string[]
|
|
20
|
-
skippedCmux: string[]
|
|
21
|
-
ideProviders: IdeProvider[]
|
|
22
|
-
ideFoldersAdded: number
|
|
23
|
-
ideFoldersRemoved: number
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Cold-start restore command: reconciles the configured editor workspace against
|
|
28
|
-
* the set of release worktrees on disk, opens the editor against it, and ensures
|
|
29
|
-
* one cmux workspace exists per worktree. Idempotent and additive — never removes
|
|
30
|
-
* worktrees, never recreates running cmux workspaces.
|
|
31
|
-
*/
|
|
32
|
-
export const worktreesOpen = async () => {
|
|
33
|
-
commandEcho.start('worktrees-open')
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const projectRoot = await getProjectRoot()
|
|
37
|
-
const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`
|
|
38
|
-
const currentBranches = await getCurrentWorktrees('release')
|
|
39
|
-
|
|
40
|
-
const ideOutcomes = await openIdeWorkspace({
|
|
41
|
-
projectRoot,
|
|
42
|
-
worktreeDir,
|
|
43
|
-
currentBranches,
|
|
44
|
-
skipRelaunchWhenEmpty: false,
|
|
45
|
-
})
|
|
46
|
-
const cmuxOutcome = await openCmux({ worktreeDir, currentBranches })
|
|
47
|
-
|
|
48
|
-
const result: WorktreesOpenResult = {
|
|
49
|
-
openedCmux: cmuxOutcome.opened,
|
|
50
|
-
skippedCmux: cmuxOutcome.skipped,
|
|
51
|
-
ideProviders: ideOutcomes
|
|
52
|
-
.filter((outcome) => {
|
|
53
|
-
return outcome.ran
|
|
54
|
-
})
|
|
55
|
-
.map((outcome) => {
|
|
56
|
-
return outcome.provider
|
|
57
|
-
}),
|
|
58
|
-
ideFoldersAdded: ideOutcomes.reduce((sum, outcome) => {
|
|
59
|
-
return sum + outcome.added
|
|
60
|
-
}, 0),
|
|
61
|
-
ideFoldersRemoved: ideOutcomes.reduce((sum, outcome) => {
|
|
62
|
-
return sum + outcome.removed
|
|
63
|
-
}, 0),
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
logResults(result, {
|
|
67
|
-
ideRan: ideOutcomes.some((outcome) => {
|
|
68
|
-
return outcome.ran
|
|
69
|
-
}),
|
|
70
|
-
cmuxRan: cmuxOutcome.ran,
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
commandEcho.print()
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
content: textContent(JSON.stringify(result, null, 2)),
|
|
77
|
-
structuredContent: { ...result },
|
|
78
|
-
}
|
|
79
|
-
} catch (error) {
|
|
80
|
-
logger.error({ error }, '❌ Error opening worktrees')
|
|
81
|
-
throw new OperationError(error, {
|
|
82
|
-
operation: 'open worktrees',
|
|
83
|
-
remediation: "run 'worktrees-list' to confirm the branches exist",
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
interface OpenCmuxArgs {
|
|
89
|
-
worktreeDir: string
|
|
90
|
-
currentBranches: string[]
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
interface OpenCmuxOutcome {
|
|
94
|
-
ran: boolean
|
|
95
|
-
opened: string[]
|
|
96
|
-
skipped: string[]
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const openCmux = async (args: OpenCmuxArgs): Promise<OpenCmuxOutcome> => {
|
|
100
|
-
const { worktreeDir, currentBranches } = args
|
|
101
|
-
|
|
102
|
-
if (currentBranches.length === 0) {
|
|
103
|
-
return { ran: true, opened: [], skipped: [] }
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const repoName = await getRepoName()
|
|
107
|
-
const existingTitles = await listCmuxWorkspaceTitles()
|
|
108
|
-
|
|
109
|
-
const opened: string[] = []
|
|
110
|
-
const skipped: string[] = []
|
|
111
|
-
|
|
112
|
-
for (const branch of currentBranches) {
|
|
113
|
-
const title = buildCmuxWorkspaceTitle({ repoName, branch })
|
|
114
|
-
|
|
115
|
-
// existingTitles holds canonical keys; match the built title the same way so
|
|
116
|
-
// dedup survives whitespace / cross-CLI-version title drift (no duplicates).
|
|
117
|
-
if (existingTitles.has(canonicalizeCmuxTitle(title))) {
|
|
118
|
-
skipped.push(title)
|
|
119
|
-
continue
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
await openCmuxWorkspaceWithLayout({ cwd: `${worktreeDir}/${branch}`, title })
|
|
124
|
-
opened.push(title)
|
|
125
|
-
} catch (error) {
|
|
126
|
-
logger.warn({ error, title }, `⚠️ Failed to open cmux workspace for ${branch}`)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return { ran: true, opened, skipped }
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
interface LogResultsContext {
|
|
134
|
-
ideRan: boolean
|
|
135
|
-
cmuxRan: boolean
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const logResults = (result: WorktreesOpenResult, context: LogResultsContext): void => {
|
|
139
|
-
if (context.ideRan) {
|
|
140
|
-
const ideLabels = result.ideProviders
|
|
141
|
-
.map((provider) => {
|
|
142
|
-
return ideProviderLabel(provider)
|
|
143
|
-
})
|
|
144
|
-
.join(', ')
|
|
145
|
-
|
|
146
|
-
if (result.ideFoldersAdded > 0) {
|
|
147
|
-
logger.info(`✅ Added ${result.ideFoldersAdded} folder(s) to ${ideLabels} workspace(s)`)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (result.ideFoldersRemoved > 0) {
|
|
151
|
-
logger.info(`🧹 Removed ${result.ideFoldersRemoved} dangling folder(s) from ${ideLabels} workspace(s)`)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (result.openedCmux.length > 0) {
|
|
156
|
-
logger.info('✅ Opened cmux workspaces:')
|
|
157
|
-
for (const title of result.openedCmux) {
|
|
158
|
-
logger.info(title)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (result.skippedCmux.length > 0) {
|
|
163
|
-
logger.info(`ℹ️ Skipped ${result.skippedCmux.length} cmux workspace(s) already open`)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
!context.ideRan &&
|
|
168
|
-
result.openedCmux.length === 0 &&
|
|
169
|
-
result.skippedCmux.length === 0 &&
|
|
170
|
-
result.ideFoldersAdded === 0 &&
|
|
171
|
-
result.ideFoldersRemoved === 0
|
|
172
|
-
) {
|
|
173
|
-
logger.info('ℹ️ Nothing to open')
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// MCP Tool Registration
|
|
178
|
-
export const worktreesOpenMcpTool = defineMcpTool({
|
|
179
|
-
name: 'worktrees-open',
|
|
180
|
-
description:
|
|
181
|
-
'Open every configured editor (Cursor and/or Zed) against its workspace and ensure a cmux workspace exists for each existing release worktree. Idempotent and additive — never removes worktrees, never recreates running cmux workspaces. Use after a cold start (editor + cmux closed). For stale-worktree cleanup, use worktrees-sync.',
|
|
182
|
-
inputSchema: {},
|
|
183
|
-
outputSchema: {
|
|
184
|
-
openedCmux: z.array(z.string()).describe('Titles of cmux workspaces opened during this run'),
|
|
185
|
-
skippedCmux: z.array(z.string()).describe('Titles of cmux workspaces that were already open'),
|
|
186
|
-
ideProviders: z
|
|
187
|
-
.array(z.string())
|
|
188
|
-
.describe('Configured IDE providers that were opened (cursor | zed); empty if none configured'),
|
|
189
|
-
ideFoldersAdded: z.number().describe('Total worktree folders added across all configured editor workspaces'),
|
|
190
|
-
ideFoldersRemoved: z
|
|
191
|
-
.number()
|
|
192
|
-
.describe('Total dangling worktree folders removed across all configured editor workspaces'),
|
|
193
|
-
},
|
|
194
|
-
handler: worktreesOpen,
|
|
195
|
-
})
|