@iloom/cli 0.9.2 → 0.10.1
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/LICENSE +1 -1
- package/README.md +160 -41
- package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-25KSZAEM.js} +2 -2
- package/dist/ClaudeContextManager-66GR4BGM.js +14 -0
- package/dist/ClaudeService-7KM5NA5Z.js +13 -0
- package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
- package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
- package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-TDLZSYG2.js} +9 -9
- package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
- package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
- package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-YOE2SIPG.js} +2 -2
- package/dist/README.md +160 -41
- package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-FNKCOZMQ.js} +4 -2
- package/dist/agents/iloom-artifact-reviewer.md +11 -0
- package/dist/agents/iloom-code-reviewer.md +14 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
- package/dist/agents/iloom-issue-analyzer.md +49 -6
- package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
- package/dist/agents/iloom-issue-enhancer.md +86 -7
- package/dist/agents/iloom-issue-implementer.md +48 -7
- package/dist/agents/iloom-issue-planner.md +115 -62
- package/dist/{build-THZI572G.js → build-VHGEMXBA.js} +9 -9
- package/dist/chunk-4232AHNQ.js +35 -0
- package/dist/chunk-4232AHNQ.js.map +1 -0
- package/dist/chunk-4E7LCFUG.js +24 -0
- package/dist/chunk-4E7LCFUG.js.map +1 -0
- package/dist/{chunk-AR5QKYNE.js → chunk-4FGEGQW4.js} +4 -4
- package/dist/{chunk-R4YWBGY6.js → chunk-5FJWO4IT.js} +67 -22
- package/dist/chunk-5FJWO4IT.js.map +1 -0
- package/dist/{chunk-VPTAX5TR.js → chunk-5RPBYK5Q.js} +35 -30
- package/dist/chunk-5RPBYK5Q.js.map +1 -0
- package/dist/{chunk-YKFCCV6S.js → chunk-63QWFWH3.js} +7 -7
- package/dist/chunk-63QWFWH3.js.map +1 -0
- package/dist/{chunk-RI2YL6TK.js → chunk-7VHJNVLF.js} +80 -23
- package/dist/chunk-7VHJNVLF.js.map +1 -0
- package/dist/{chunk-B7U6OKUR.js → chunk-C6HNNJIV.js} +11 -3
- package/dist/chunk-C6HNNJIV.js.map +1 -0
- package/dist/{chunk-A7NJF73J.js → chunk-CVCTIDDK.js} +4 -4
- package/dist/{chunk-Z2TWEXR7.js → chunk-E6KOWMKA.js} +6 -6
- package/dist/chunk-E6KOWMKA.js.map +1 -0
- package/dist/{chunk-3I4ONZRT.js → chunk-EVPZFV3K.js} +10 -10
- package/dist/chunk-EVPZFV3K.js.map +1 -0
- package/dist/{chunk-IZIYLYPK.js → chunk-G5V75JD5.js} +2 -2
- package/dist/chunk-GRISNU6G.js +651 -0
- package/dist/chunk-GRISNU6G.js.map +1 -0
- package/dist/chunk-HEXKPKCK.js +1396 -0
- package/dist/chunk-HEXKPKCK.js.map +1 -0
- package/dist/{chunk-TC7APDKU.js → chunk-I5T677EA.js} +2 -2
- package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
- package/dist/chunk-KB64WNBZ.js.map +1 -0
- package/dist/{chunk-NWMORW3U.js → chunk-KIK2ZFAL.js} +2 -2
- package/dist/{chunk-CWRI4JC3.js → chunk-KKV5WH5M.js} +30 -31
- package/dist/chunk-KKV5WH5M.js.map +1 -0
- package/dist/{chunk-DGG2VY7B.js → chunk-KVHIAWVT.js} +9 -9
- package/dist/chunk-KVHIAWVT.js.map +1 -0
- package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
- package/dist/chunk-KXDRI47U.js.map +1 -0
- package/dist/{chunk-NUACL52E.js → chunk-LLHXQS3C.js} +2 -2
- package/dist/chunk-LUKXJSRI.js +73 -0
- package/dist/chunk-LUKXJSRI.js.map +1 -0
- package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
- package/dist/chunk-OTGH2HRS.js +1427 -0
- package/dist/chunk-OTGH2HRS.js.map +1 -0
- package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
- package/dist/{chunk-KAYXR544.js → chunk-QVLPWNE3.js} +2 -2
- package/dist/chunk-QZWEJVWV.js +207 -0
- package/dist/chunk-QZWEJVWV.js.map +1 -0
- package/dist/chunk-RJ3VBUFK.js +781 -0
- package/dist/chunk-RJ3VBUFK.js.map +1 -0
- package/dist/chunk-RSYT7MVI.js +202 -0
- package/dist/chunk-RSYT7MVI.js.map +1 -0
- package/dist/{chunk-6IIL5M2L.js → chunk-S7PZA6IV.js} +10 -8
- package/dist/{chunk-6IIL5M2L.js.map → chunk-S7PZA6IV.js.map} +1 -1
- package/dist/chunk-SKSYYBCU.js +229 -0
- package/dist/chunk-SKSYYBCU.js.map +1 -0
- package/dist/{chunk-ULSWCPQG.js → chunk-SWSJWA2S.js} +476 -5
- package/dist/chunk-SWSJWA2S.js.map +1 -0
- package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
- package/dist/chunk-UKBAJ2QQ.js.map +1 -0
- package/dist/{chunk-FO5GGFOV.js → chunk-UR5DGNUO.js} +71 -9
- package/dist/chunk-UR5DGNUO.js.map +1 -0
- package/dist/{chunk-QN47QVBX.js → chunk-UUEW5KWB.js} +1 -1
- package/dist/chunk-UUEW5KWB.js.map +1 -0
- package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
- package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
- package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
- package/dist/{chunk-KJTVU3HZ.js → chunk-WXIM2WS7.js} +8 -8
- package/dist/chunk-WXIM2WS7.js.map +1 -0
- package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
- package/dist/chunk-YQ57ORTV.js.map +1 -0
- package/dist/{chunk-SOSQILHO.js → chunk-ZNMPGMHY.js} +44 -797
- package/dist/chunk-ZNMPGMHY.js.map +1 -0
- package/dist/{claude-TP2QO3BU.js → claude-7GGEWVEM.js} +2 -2
- package/dist/{cleanup-PJRIFFU4.js → cleanup-6PVAC4NI.js} +85 -34
- package/dist/cleanup-6PVAC4NI.js.map +1 -0
- package/dist/cli.js +630 -801
- package/dist/cli.js.map +1 -1
- package/dist/{commit-IVP3M4HG.js → commit-FZR5XDQG.js} +26 -23
- package/dist/commit-FZR5XDQG.js.map +1 -0
- package/dist/{compile-R2J65HBQ.js → compile-7ALJHZ4N.js} +9 -9
- package/dist/{contribute-VDZXHK5Y.js → contribute-5GKLK3BQ.js} +14 -6
- package/dist/contribute-5GKLK3BQ.js.map +1 -0
- package/dist/{dev-server-7F622OEO.js → dev-server-7SMIB7OF.js} +29 -15
- package/dist/dev-server-7SMIB7OF.js.map +1 -0
- package/dist/{feedback-E7VET7CL.js → feedback-G2GJFN2F.js} +18 -16
- package/dist/{feedback-E7VET7CL.js.map → feedback-G2GJFN2F.js.map} +1 -1
- package/dist/{git-2QDQ2X2S.js → git-GTLKAZRJ.js} +4 -4
- package/dist/hooks/iloom-hook.js +15 -0
- package/dist/ignite-H2O5Y5A2.js +34 -0
- package/dist/ignite-H2O5Y5A2.js.map +1 -0
- package/dist/index.d.ts +482 -58
- package/dist/index.js +1340 -44
- package/dist/index.js.map +1 -1
- package/dist/{init-676DHF6R.js → init-32YOKXRL.js} +57 -21
- package/dist/init-32YOKXRL.js.map +1 -0
- package/dist/{issues-PJSOLOBJ.js → issues-4UUAQ5K6.js} +61 -20
- package/dist/issues-4UUAQ5K6.js.map +1 -0
- package/dist/{lint-CJM7BAIM.js → lint-AAN2NZWG.js} +9 -9
- package/dist/mcp/harness-server.js +140 -0
- package/dist/mcp/harness-server.js.map +1 -0
- package/dist/mcp/issue-management-server.js +2599 -262
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/recap-server.js +144 -21
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
- package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
- package/dist/{open-544H7JF5.js → open-FXWW3VI4.js} +15 -15
- package/dist/open-FXWW3VI4.js.map +1 -0
- package/dist/{plan-Q7ELXDLC.js → plan-RQ5FPIGF.js} +358 -40
- package/dist/plan-RQ5FPIGF.js.map +1 -0
- package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
- package/dist/prompts/CLAUDE.md +62 -0
- package/dist/prompts/init-prompt.txt +430 -34
- package/dist/prompts/issue-prompt.txt +473 -54
- package/dist/prompts/plan-prompt.txt +140 -19
- package/dist/prompts/pr-prompt.txt +44 -1
- package/dist/prompts/regular-prompt.txt +42 -1
- package/dist/prompts/session-summary-prompt.txt +14 -0
- package/dist/prompts/swarm-orchestrator-prompt.txt +464 -0
- package/dist/{rebase-YND35CIE.js → rebase-6NVLX5V7.js} +21 -12
- package/dist/rebase-6NVLX5V7.js.map +1 -0
- package/dist/{recap-3W7COH7D.js → recap-OMBOKJST.js} +47 -19
- package/dist/recap-OMBOKJST.js.map +1 -0
- package/dist/{run-QUXJKDQQ.js → run-BBXLRIZB.js} +15 -15
- package/dist/run-BBXLRIZB.js.map +1 -0
- package/dist/schema/package-iloom.schema.json +58 -0
- package/dist/schema/settings.schema.json +149 -15
- package/dist/{shell-QGECBLST.js → shell-RF7LTND5.js} +14 -7
- package/dist/shell-RF7LTND5.js.map +1 -0
- package/dist/{summary-G2T4452H.js → summary-WTQZ7XG2.js} +27 -25
- package/dist/summary-WTQZ7XG2.js.map +1 -0
- package/dist/{test-EA5NQFDC.js → test-SGO6I5Z7.js} +9 -9
- package/dist/{test-git-M7LSLEFL.js → test-git-XM4TM65W.js} +4 -4
- package/dist/test-jira-LDTOYFSD.js +96 -0
- package/dist/test-jira-LDTOYFSD.js.map +1 -0
- package/dist/{test-prefix-64NAAUON.js → test-prefix-GBO37XCN.js} +4 -4
- package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-NZ3JTVLL.js} +6 -6
- package/dist/{vscode-AR5NNXXI.js → vscode-6XUGHJKL.js} +7 -7
- package/package.json +5 -1
- package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
- package/dist/ClaudeService-TK7FMC2X.js +0 -13
- package/dist/chunk-3I4ONZRT.js.map +0 -1
- package/dist/chunk-B7U6OKUR.js.map +0 -1
- package/dist/chunk-CWRI4JC3.js.map +0 -1
- package/dist/chunk-DGG2VY7B.js.map +0 -1
- package/dist/chunk-FJDRTVJX.js +0 -520
- package/dist/chunk-FJDRTVJX.js.map +0 -1
- package/dist/chunk-FO5GGFOV.js.map +0 -1
- package/dist/chunk-KBEIQP4G.js.map +0 -1
- package/dist/chunk-KJTVU3HZ.js.map +0 -1
- package/dist/chunk-KXGQYLFZ.js.map +0 -1
- package/dist/chunk-OFDN5NKS.js.map +0 -1
- package/dist/chunk-QN47QVBX.js.map +0 -1
- package/dist/chunk-R4YWBGY6.js.map +0 -1
- package/dist/chunk-RI2YL6TK.js.map +0 -1
- package/dist/chunk-SOSQILHO.js.map +0 -1
- package/dist/chunk-ULSWCPQG.js.map +0 -1
- package/dist/chunk-VOGGLPG5.js.map +0 -1
- package/dist/chunk-VPTAX5TR.js.map +0 -1
- package/dist/chunk-W6DP5RVR.js +0 -101
- package/dist/chunk-W6DP5RVR.js.map +0 -1
- package/dist/chunk-WHI5KEOX.js +0 -121
- package/dist/chunk-WHI5KEOX.js.map +0 -1
- package/dist/chunk-YKFCCV6S.js.map +0 -1
- package/dist/chunk-Z2TWEXR7.js.map +0 -1
- package/dist/cleanup-PJRIFFU4.js.map +0 -1
- package/dist/commit-IVP3M4HG.js.map +0 -1
- package/dist/contribute-VDZXHK5Y.js.map +0 -1
- package/dist/dev-server-7F622OEO.js.map +0 -1
- package/dist/ignite-IW35CDBD.js +0 -784
- package/dist/ignite-IW35CDBD.js.map +0 -1
- package/dist/init-676DHF6R.js.map +0 -1
- package/dist/issues-PJSOLOBJ.js.map +0 -1
- package/dist/open-544H7JF5.js.map +0 -1
- package/dist/plan-Q7ELXDLC.js.map +0 -1
- package/dist/rebase-YND35CIE.js.map +0 -1
- package/dist/recap-3W7COH7D.js.map +0 -1
- package/dist/run-QUXJKDQQ.js.map +0 -1
- package/dist/shell-QGECBLST.js.map +0 -1
- package/dist/summary-G2T4452H.js.map +0 -1
- /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-25KSZAEM.js.map} +0 -0
- /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-66GR4BGM.js.map} +0 -0
- /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-7KM5NA5Z.js.map} +0 -0
- /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
- /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
- /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-TDLZSYG2.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
- /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
- /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-YOE2SIPG.js.map} +0 -0
- /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-FNKCOZMQ.js.map} +0 -0
- /package/dist/{build-THZI572G.js.map → build-VHGEMXBA.js.map} +0 -0
- /package/dist/{chunk-AR5QKYNE.js.map → chunk-4FGEGQW4.js.map} +0 -0
- /package/dist/{chunk-A7NJF73J.js.map → chunk-CVCTIDDK.js.map} +0 -0
- /package/dist/{chunk-IZIYLYPK.js.map → chunk-G5V75JD5.js.map} +0 -0
- /package/dist/{chunk-TC7APDKU.js.map → chunk-I5T677EA.js.map} +0 -0
- /package/dist/{chunk-NWMORW3U.js.map → chunk-KIK2ZFAL.js.map} +0 -0
- /package/dist/{chunk-NUACL52E.js.map → chunk-LLHXQS3C.js.map} +0 -0
- /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
- /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
- /package/dist/{chunk-KAYXR544.js.map → chunk-QVLPWNE3.js.map} +0 -0
- /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
- /package/dist/{git-2QDQ2X2S.js.map → claude-7GGEWVEM.js.map} +0 -0
- /package/dist/{compile-R2J65HBQ.js.map → compile-7ALJHZ4N.js.map} +0 -0
- /package/dist/{neon-helpers-VVFFTLXE.js.map → git-GTLKAZRJ.js.map} +0 -0
- /package/dist/{lint-CJM7BAIM.js.map → lint-AAN2NZWG.js.map} +0 -0
- /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
- /package/dist/{test-EA5NQFDC.js.map → test-SGO6I5Z7.js.map} +0 -0
- /package/dist/{test-git-M7LSLEFL.js.map → test-git-XM4TM65W.js.map} +0 -0
- /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-GBO37XCN.js.map} +0 -0
- /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-NZ3JTVLL.js.map} +0 -0
- /package/dist/{vscode-AR5NNXXI.js.map → vscode-6XUGHJKL.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/recap.ts"],"sourcesContent":["/**\n * RecapCommand - Fast read-only command for VS Code extension\n *\n * Reads ~/.config/iloom-ai/recaps/{current-loom}.json and outputs it.\n * Skips config validation for fast startup.\n * Includes filePath in output so extension can set up file watcher.\n */\nimport path from 'path'\nimport os from 'os'\nimport fs from 'fs-extra'\nimport type { RecapFile, RecapOutput } from '../mcp/recap-types.js'\nimport { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { IdentifierParser } from '../utils/IdentifierParser.js'\nimport { formatRecapMarkdown } from '../utils/recap-formatter.js'\nimport { findArchivedRecap } from '../utils/recap-archiver.js'\n\nconst RECAPS_DIR = path.join(os.homedir(), '.config', 'iloom-ai', 'recaps')\n\n/**\n * Reuse MetadataManager.slugifyPath() algorithm\n *\n * Algorithm:\n * 1. Trim trailing slashes\n * 2. Replace all path separators (/ or \\) with ___ (triple underscore)\n * 3. Replace any other non-alphanumeric characters (except _ and -) with -\n * 4. Append .json\n */\nfunction slugifyPath(loomPath: string): string {\n\tlet slug = loomPath.replace(/[/\\\\]+$/, '')\n\tslug = slug.replace(/[/\\\\]/g, '___')\n\tslug = slug.replace(/[^a-zA-Z0-9_-]/g, '-')\n\treturn `${slug}.json`\n}\n\nexport interface RecapCommandInput {\n\tidentifier?: string | undefined // Optional identifier (issue number, PR number, branch name)\n\tjson?: boolean | undefined\n}\n\nexport class RecapCommand {\n\t/**\n\t * Execute the recap command\n\t * Returns RecapOutput in JSON mode, void otherwise\n\t */\n\tasync execute(input: RecapCommandInput): Promise<RecapOutput | void> {\n\t\t// Resolve recap file path from identifier or fall back to cwd\n\t\tconst filePath = await this.resolveRecapFilePath(input.identifier)\n\n\t\t// Read recap file (return empty object if not found)\n\t\tlet recap: RecapFile = {}\n\t\ttry {\n\t\t\tif (await fs.pathExists(filePath)) {\n\t\t\t\tconst content = await fs.readFile(filePath, 'utf8')\n\t\t\t\trecap = JSON.parse(content) as RecapFile\n\t\t\t}\n\t\t} catch {\n\t\t\t// Graceful degradation - return empty recap on read error\n\t\t\t// This is intentional for fast startup\n\t\t}\n\n\t\t// Build output with filePath for file watching (provide defaults for optional fields)\n\t\tconst goal = recap.goal ?? null\n\t\tconst complexity = recap.complexity ?? null\n\t\tconst entries = recap.entries ?? []\n\t\tconst artifacts = recap.artifacts ?? []\n\t\tconst result: RecapOutput = { filePath, goal, complexity, entries, artifacts }\n\n\t\tif (input.json) {\n\t\t\treturn result\n\t\t}\n\n\t\t// Non-JSON mode: print markdown format (intentionally using console.log for piping/redirection)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(formatRecapMarkdown(result))\n\t}\n\n\t/**\n\t * Resolve identifier to a full recap file path.\n\t * Returns the path to the active recap file, or falls back to an archived\n\t * recap when the worktree no longer exists (e.g., after cleanup --archive).\n\t * Falls back to cwd when no identifier is provided (backward compatible).\n\t */\n\tprivate async resolveRecapFilePath(identifier: string | undefined): Promise<string> {\n\t\t// Default: use current working directory\n\t\tif (!identifier?.trim()) {\n\t\t\treturn path.join(RECAPS_DIR, slugifyPath(process.cwd()))\n\t\t}\n\n\t\tconst trimmedId = identifier.trim()\n\t\tconst gitWorktreeManager = new GitWorktreeManager()\n\t\tconst identifierParser = new IdentifierParser(gitWorktreeManager)\n\n\t\t// Check for PR-specific formats: pr/123, PR-123, PR/123\n\t\tconst prPattern = /^(?:pr|PR)[/-](\\d+)$/\n\t\tconst prMatch = trimmedId.match(prPattern)\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tconst worktree = await gitWorktreeManager.findWorktreeForPR(prNumber, '')\n\t\t\tif (worktree) {\n\t\t\t\treturn path.join(RECAPS_DIR, slugifyPath(worktree.path))\n\t\t\t}\n\t\t\t// Try archived recap before throwing\n\t\t\tconst archivedPath = await findArchivedRecap('pr', prNumber)\n\t\t\tif (archivedPath) return archivedPath\n\t\t\tthrow new Error(`No worktree or archived recap found for PR #${prNumber}`)\n\t\t}\n\n\t\t// Use IdentifierParser for pattern-based detection\n\t\ttry {\n\t\t\tconst parsed = await identifierParser.parseForPatternDetection(trimmedId)\n\n\t\t\t// Find worktree based on parsed type\n\t\t\tif (parsed.type === 'pr' && typeof parsed.number === 'number') {\n\t\t\t\tconst worktree = await gitWorktreeManager.findWorktreeForPR(parsed.number, '')\n\t\t\t\tif (worktree) {\n\t\t\t\t\treturn path.join(RECAPS_DIR, slugifyPath(worktree.path))\n\t\t\t\t}\n\t\t\t\t// Try archived recap before throwing\n\t\t\t\tconst archivedPath = await findArchivedRecap('pr', parsed.number)\n\t\t\t\tif (archivedPath) return archivedPath\n\t\t\t\tthrow new Error(`No worktree or archived recap found for PR #${parsed.number}`)\n\t\t\t}\n\n\t\t\tif (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\t\tconst worktree = await gitWorktreeManager.findWorktreeForIssue(parsed.number)\n\t\t\t\tif (worktree) {\n\t\t\t\t\treturn path.join(RECAPS_DIR, slugifyPath(worktree.path))\n\t\t\t\t}\n\t\t\t\t// Try archived recap before throwing\n\t\t\t\tconst issueNum = typeof parsed.number === 'string' ? parseInt(parsed.number, 10) : parsed.number\n\t\t\t\tif (isNaN(issueNum)) {\n\t\t\t\t\tthrow new Error(`No worktree found for identifier: ${identifier}`)\n\t\t\t\t}\n\t\t\t\tconst archivedPath = await findArchivedRecap('issue', issueNum)\n\t\t\t\tif (archivedPath) return archivedPath\n\t\t\t\tthrow new Error(`No worktree or archived recap found for issue #${parsed.number}`)\n\t\t\t}\n\n\t\t\tif (parsed.type === 'branch' && parsed.branchName) {\n\t\t\t\tconst worktree = await gitWorktreeManager.findWorktreeForBranch(parsed.branchName)\n\t\t\t\tif (worktree) {\n\t\t\t\t\treturn path.join(RECAPS_DIR, slugifyPath(worktree.path))\n\t\t\t\t}\n\t\t\t\t// Branch lookups cannot match archived metadata -- no fallback\n\t\t\t\tthrow new Error(`No worktree found for branch: ${parsed.branchName}`)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Let \"not found\" errors from our own lookups pass through without wrapping --\n\t\t\t// these are valid parse results where no worktree/archive was found\n\t\t\tif (error instanceof Error && (\n\t\t\t\terror.message.startsWith('No worktree or archived recap found') ||\n\t\t\t\terror.message.startsWith('No worktree found for branch:')\n\t\t\t)) {\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\t// IdentifierParser throws \"No worktree found for identifier: N\" when no active\n\t\t\t// worktree exists for a numeric input. For plain numbers, still try archived recaps\n\t\t\t// before giving up -- this is the primary archived-lookup path.\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message === `No worktree found for identifier: ${trimmedId}`\n\t\t\t) {\n\t\t\t\tconst numericMatch = trimmedId.match(/^(\\d+)$/)\n\t\t\t\tif (numericMatch?.[1]) {\n\t\t\t\t\tconst num = parseInt(numericMatch[1], 10)\n\t\t\t\t\t// Try issue first, then PR\n\t\t\t\t\tconst archivedIssue = await findArchivedRecap('issue', num)\n\t\t\t\t\tif (archivedIssue) return archivedIssue\n\t\t\t\t\tconst archivedPr = await findArchivedRecap('pr', num)\n\t\t\t\t\tif (archivedPr) return archivedPr\n\t\t\t\t\tthrow new Error(`No worktree or archived recap found for #${num}`)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Re-throw IdentifierParser errors with context\n\t\t\tif (error instanceof Error) {\n\t\t\t\tthrow new Error(`Could not resolve identifier '${identifier}': ${error.message}`)\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\n\t\t// Should not reach here, but provide a fallback error\n\t\tthrow new Error(`Could not resolve identifier: ${identifier}`)\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DevServerManager
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-CVCTIDDK.js";
|
|
5
|
+
import "./chunk-G5V75JD5.js";
|
|
6
6
|
import {
|
|
7
7
|
getWorkspacePort
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LLHXQS3C.js";
|
|
9
|
+
import "./chunk-WWKOVDWC.js";
|
|
9
10
|
import {
|
|
10
11
|
IdentifierParser
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-63QWFWH3.js";
|
|
13
|
+
import {
|
|
14
|
+
GitWorktreeManager
|
|
15
|
+
} from "./chunk-I5T677EA.js";
|
|
12
16
|
import {
|
|
13
17
|
openBrowser
|
|
14
18
|
} from "./chunk-YETJNRQM.js";
|
|
15
|
-
import "./chunk-4LKGCFGG.js";
|
|
16
19
|
import {
|
|
17
|
-
|
|
18
|
-
} from "./chunk-
|
|
20
|
+
ProjectCapabilityDetector
|
|
21
|
+
} from "./chunk-MORRVYPT.js";
|
|
22
|
+
import "./chunk-YQ57ORTV.js";
|
|
19
23
|
import {
|
|
20
24
|
extractSettingsOverrides
|
|
21
25
|
} from "./chunk-GYCR2LOU.js";
|
|
22
|
-
import {
|
|
23
|
-
ProjectCapabilityDetector
|
|
24
|
-
} from "./chunk-TL72BGP6.js";
|
|
25
|
-
import "./chunk-VOGGLPG5.js";
|
|
26
26
|
import {
|
|
27
27
|
extractIssueNumber
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-4FGEGQW4.js";
|
|
29
29
|
import {
|
|
30
30
|
SettingsManager
|
|
31
|
-
} from "./chunk-
|
|
32
|
-
import "./chunk-
|
|
31
|
+
} from "./chunk-7VHJNVLF.js";
|
|
32
|
+
import "./chunk-KB64WNBZ.js";
|
|
33
33
|
import "./chunk-6MLEBAYZ.js";
|
|
34
34
|
import {
|
|
35
35
|
logger
|
|
@@ -238,4 +238,4 @@ Make sure the project is built (run 'il start' first)`
|
|
|
238
238
|
export {
|
|
239
239
|
RunCommand
|
|
240
240
|
};
|
|
241
|
-
//# sourceMappingURL=run-
|
|
241
|
+
//# sourceMappingURL=run-BBXLRIZB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/run.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { ProjectCapabilityDetector } from '../lib/ProjectCapabilityDetector.js'\nimport { DevServerManager } from '../lib/DevServerManager.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { IdentifierParser } from '../utils/IdentifierParser.js'\nimport { openBrowser } from '../utils/browser.js'\nimport { getWorkspacePort } from '../utils/port.js'\nimport { extractIssueNumber } from '../utils/git.js'\nimport { logger } from '../utils/logger.js'\nimport { extractSettingsOverrides } from '../utils/cli-overrides.js'\nimport type { GitWorktree } from '../types/worktree.js'\n\nexport interface RunCommandInput {\n\tidentifier?: string\n\targs?: string[]\n}\n\ninterface ParsedRunInput {\n\ttype: 'issue' | 'pr' | 'branch' | 'epic'\n\tnumber?: string | number // For issues and PRs\n\tbranchName?: string // For branches\n\toriginalInput: string\n\tautoDetected: boolean\n}\n\n/**\n * RunCommand - Runs CLI tool or opens workspace in browser\n * Priority: CLI first, Web fallback\n */\nexport class RunCommand {\n\tconstructor(\n\t\tprivate gitWorktreeManager = new GitWorktreeManager(),\n\t\tprivate capabilityDetector = new ProjectCapabilityDetector(),\n\t\tprivate identifierParser = new IdentifierParser(new GitWorktreeManager()),\n\t\tprivate devServerManager = new DevServerManager(),\n\t\tprivate settingsManager = new SettingsManager()\n\t) {}\n\n\tasync execute(input: RunCommandInput): Promise<void> {\n\t\t// 1. Parse or auto-detect identifier\n\t\tconst parsed = input.identifier\n\t\t\t? await this.parseExplicitInput(input.identifier)\n\t\t\t: await this.autoDetectFromCurrentDirectory()\n\n\t\tlogger.debug(`Parsed input: ${JSON.stringify(parsed)}`)\n\n\t\t// 2. Find worktree path based on identifier\n\t\tconst worktree = await this.findWorktreeForIdentifier(parsed)\n\n\t\tlogger.info(`Found worktree at: ${worktree.path}`)\n\n\t\t// 3. Detect project capabilities\n\t\tconst { capabilities, binEntries } =\n\t\t\tawait this.capabilityDetector.detectCapabilities(worktree.path)\n\n\t\tlogger.debug(`Detected capabilities: ${capabilities.join(', ')}`)\n\n\t\t// 4. Execute based on capabilities (CLI first, web fallback)\n\t\tif (capabilities.includes('cli')) {\n\t\t\tawait this.runCLITool(worktree.path, binEntries, input.args ?? [])\n\t\t} else if (capabilities.includes('web')) {\n\t\t\tawait this.openWebBrowser(worktree)\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`No CLI or web capabilities detected for workspace at ${worktree.path}`\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Parse explicit identifier input\n\t */\n\tprivate async parseExplicitInput(identifier: string): Promise<ParsedRunInput> {\n\t\tconst parsed = await this.identifierParser.parseForPatternDetection(identifier)\n\n\t\t// Description type should never reach run command (converted in start)\n\t\tif (parsed.type === 'description') {\n\t\t\tthrow new Error('Description input type is not supported in run command')\n\t\t}\n\n\t\tconst result: ParsedRunInput = {\n\t\t\ttype: parsed.type,\n\t\t\toriginalInput: parsed.originalInput,\n\t\t\tautoDetected: false,\n\t\t}\n\n\t\tif (parsed.number !== undefined) {\n\t\t\tresult.number = parsed.number\n\t\t}\n\t\tif (parsed.branchName !== undefined) {\n\t\t\tresult.branchName = parsed.branchName\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Auto-detect identifier from current directory\n\t * Same logic as FinishCommand.autoDetectFromCurrentDirectory()\n\t */\n\tprivate async autoDetectFromCurrentDirectory(): Promise<ParsedRunInput> {\n\t\tconst currentDir = path.basename(process.cwd())\n\n\t\t// Check for PR worktree pattern: _pr_N suffix\n\t\tconst prPattern = /_pr_(\\d+)$/\n\t\tconst prMatch = currentDir.match(prPattern)\n\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tlogger.debug(`Auto-detected PR #${prNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'pr',\n\t\t\t\tnumber: prNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Check for issue pattern in directory\n\t\tconst issueNumber = extractIssueNumber(currentDir)\n\n\t\tif (issueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${issueNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: issueNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Fallback: get current branch name\n\t\tconst repoInfo = await this.gitWorktreeManager.getRepoInfo()\n\t\tconst currentBranch = repoInfo.currentBranch\n\n\t\tif (!currentBranch) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not auto-detect identifier. Please provide an issue number, PR number, or branch name.\\n' +\n\t\t\t\t\t'Expected directory pattern: feat/issue-XX-description OR worktree with _pr_N suffix'\n\t\t\t)\n\t\t}\n\n\t\t// Try to extract issue from branch name\n\t\tconst branchIssueNumber = extractIssueNumber(currentBranch)\n\t\tif (branchIssueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${branchIssueNumber} from branch: ${currentBranch}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: branchIssueNumber,\n\t\t\t\toriginalInput: currentBranch,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Last resort: use branch name\n\t\treturn {\n\t\t\ttype: 'branch',\n\t\t\tbranchName: currentBranch,\n\t\t\toriginalInput: currentBranch,\n\t\t\tautoDetected: true,\n\t\t}\n\t}\n\n\t/**\n\t * Find worktree for the given identifier\n\t */\n\tprivate async findWorktreeForIdentifier(parsed: ParsedRunInput): Promise<GitWorktree> {\n\t\tlet worktree: GitWorktree | null = null\n\n\t\tif (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForIssue(parsed.number)\n\t\t} else if (parsed.type === 'pr' && parsed.number !== undefined) {\n\t\t\t// For PRs, ensure the number is numeric (PRs are always numeric per GitHub)\n\t\t\tconst prNumber = typeof parsed.number === 'number' ? parsed.number : Number(parsed.number)\n\t\t\tif (isNaN(prNumber) || !isFinite(prNumber)) {\n\t\t\t\tthrow new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`)\n\t\t\t}\n\t\t\t// Pass empty string for branch name since we don't know it yet\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForPR(prNumber, '')\n\t\t} else if (parsed.type === 'branch' && parsed.branchName) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForBranch(\n\t\t\t\tparsed.branchName\n\t\t\t)\n\t\t}\n\n\t\tif (!worktree) {\n\t\t\tthrow new Error(\n\t\t\t\t`No worktree found for ${this.formatParsedInput(parsed)}. ` +\n\t\t\t\t\t`Run 'il start ${parsed.originalInput}' to create one.`\n\t\t\t)\n\t\t}\n\n\t\treturn worktree\n\t}\n\n\t/**\n\t * Format parsed input for display\n\t */\n\tprivate formatParsedInput(parsed: ParsedRunInput): string {\n\t\tconst autoLabel = parsed.autoDetected ? ' (auto-detected)' : ''\n\n\t\tif (parsed.type === 'issue') {\n\t\t\treturn `issue #${parsed.number}${autoLabel}`\n\t\t}\n\t\tif (parsed.type === 'pr') {\n\t\t\treturn `PR #${parsed.number}${autoLabel}`\n\t\t}\n\t\treturn `branch \"${parsed.branchName}\"${autoLabel}`\n\t}\n\n\t/**\n\t * Run CLI tool directly from worktree bin path (NO SYMLINKS!)\n\t */\n\tprivate async runCLITool(\n\t\tworktreePath: string,\n\t\tbinEntries: Record<string, string>,\n\t\targs: string[]\n\t): Promise<void> {\n\t\t// Validate binEntries exist\n\t\tif (Object.keys(binEntries).length === 0) {\n\t\t\tthrow new Error('No bin entries found in package.json')\n\t\t}\n\n\t\t// Get first bin entry (deterministic)\n\t\tconst firstEntry = Object.entries(binEntries)[0]\n\t\tif (!firstEntry) {\n\t\t\tthrow new Error('No bin entries found in package.json')\n\t\t}\n\t\tconst [binName, binPath] = firstEntry\n\t\tlogger.debug(`Using bin entry: ${binName} -> ${binPath}`)\n\n\t\t// CRITICAL: Construct absolute path (NO SYMLINKS!)\n\t\tconst binFilePath = path.resolve(worktreePath, binPath)\n\t\tlogger.debug(`Resolved bin file path: ${binFilePath}`)\n\n\t\t// Verify file exists\n\t\tif (!(await fs.pathExists(binFilePath))) {\n\t\t\tthrow new Error(\n\t\t\t\t`CLI executable not found: ${binFilePath}\\n` +\n\t\t\t\t\t`Make sure the project is built (run 'il start' first)`\n\t\t\t)\n\t\t}\n\n\t\t// Execute with Node.js\n\t\tlogger.info(`Running CLI: node ${binFilePath} ${args.join(' ')}`)\n\t\tawait execa('node', [binFilePath, ...args], {\n\t\t\tstdio: 'inherit', // Allow interactive CLIs (prompts, colors, etc.)\n\t\t\tcwd: worktreePath, // Execute in worktree context\n\t\t\tenv: process.env, // Inherit environment\n\t\t})\n\t}\n\n\t/**\n\t * Open web browser with workspace URL\n\t * Auto-starts dev server if not already running\n\t */\n\tprivate async openWebBrowser(worktree: GitWorktree): Promise<void> {\n\t\tconst cliOverrides = extractSettingsOverrides()\n\t\tconst settings = await this.settingsManager.loadSettings(undefined, cliOverrides)\n\t\tconst port = await getWorkspacePort({\n\t\t\tworktreePath: worktree.path,\n\t\t\tworktreeBranch: worktree.branch,\n\t\t\tbasePort: settings.capabilities?.web?.basePort,\n\t\t\tcheckEnvFile: true,\n\t\t})\n\n\t\t// Ensure dev server is running on the port\n\t\tconst serverReady = await this.devServerManager.ensureServerRunning(\n\t\t\tworktree.path,\n\t\t\tport\n\t\t)\n\n\t\tif (!serverReady) {\n\t\t\tlogger.warn(\n\t\t\t\t`Dev server failed to start on port ${port}. Opening browser anyway...`\n\t\t\t)\n\t\t}\n\n\t\t// Construct URL and open browser\n\t\tconst url = `http://localhost:${port}`\n\t\tlogger.info(`Opening browser: ${url}`)\n\t\tawait openBrowser(url)\n\t\tlogger.success('Browser opened')\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$ref": "#/definitions/PackageIloom",
|
|
3
|
+
"definitions": {
|
|
4
|
+
"PackageIloom": {
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"capabilities": {
|
|
8
|
+
"type": "array",
|
|
9
|
+
"items": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"enum": [
|
|
12
|
+
"cli",
|
|
13
|
+
"web"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"description": "Project capabilities - \"cli\" for command-line tools (enables CLI isolation), \"web\" for web applications (enables port assignment and dev server)"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"install": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Install command (e.g., \"bundle install\", \"poetry install\")"
|
|
24
|
+
},
|
|
25
|
+
"build": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Build/compile command"
|
|
28
|
+
},
|
|
29
|
+
"test": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Test suite command"
|
|
32
|
+
},
|
|
33
|
+
"dev": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Dev server command"
|
|
36
|
+
},
|
|
37
|
+
"lint": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"description": "Linting command"
|
|
40
|
+
},
|
|
41
|
+
"typecheck": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Type checking command"
|
|
44
|
+
},
|
|
45
|
+
"compile": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"description": "Compilation command (preferred over typecheck if both exist)"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"description": "Custom shell commands for project operations. These are raw shell commands, not npm script names."
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
58
|
+
}
|
|
@@ -197,6 +197,15 @@
|
|
|
197
197
|
],
|
|
198
198
|
"description": "Claude model shorthand: sonnet, opus, or haiku"
|
|
199
199
|
},
|
|
200
|
+
"swarmModel": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"enum": [
|
|
203
|
+
"sonnet",
|
|
204
|
+
"opus",
|
|
205
|
+
"haiku"
|
|
206
|
+
],
|
|
207
|
+
"description": "Model to use for this agent in swarm mode. Overrides the base model when running inside swarm workers."
|
|
208
|
+
},
|
|
200
209
|
"enabled": {
|
|
201
210
|
"type": "boolean",
|
|
202
211
|
"description": "Whether this agent is enabled. Defaults to true."
|
|
@@ -218,6 +227,63 @@
|
|
|
218
227
|
"review": {
|
|
219
228
|
"type": "boolean",
|
|
220
229
|
"description": "Whether artifacts from this agent should be reviewed before posting (defaults to false)"
|
|
230
|
+
},
|
|
231
|
+
"agents": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"additionalProperties": {
|
|
234
|
+
"type": "object",
|
|
235
|
+
"properties": {
|
|
236
|
+
"model": {
|
|
237
|
+
"type": "string",
|
|
238
|
+
"enum": [
|
|
239
|
+
"sonnet",
|
|
240
|
+
"opus",
|
|
241
|
+
"haiku"
|
|
242
|
+
],
|
|
243
|
+
"description": "Claude model shorthand: sonnet, opus, or haiku"
|
|
244
|
+
},
|
|
245
|
+
"swarmModel": {
|
|
246
|
+
"type": "string",
|
|
247
|
+
"enum": [
|
|
248
|
+
"sonnet",
|
|
249
|
+
"opus",
|
|
250
|
+
"haiku"
|
|
251
|
+
],
|
|
252
|
+
"description": "Model to use for this agent in swarm mode. Overrides the base model when running inside swarm workers."
|
|
253
|
+
},
|
|
254
|
+
"enabled": {
|
|
255
|
+
"type": "boolean",
|
|
256
|
+
"description": "Whether this agent is enabled. Defaults to true."
|
|
257
|
+
},
|
|
258
|
+
"providers": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"additionalProperties": {
|
|
261
|
+
"type": "string"
|
|
262
|
+
},
|
|
263
|
+
"propertyNames": {
|
|
264
|
+
"enum": [
|
|
265
|
+
"claude",
|
|
266
|
+
"gemini",
|
|
267
|
+
"codex"
|
|
268
|
+
]
|
|
269
|
+
},
|
|
270
|
+
"description": "Map of review providers to model names. Keys: claude, gemini, codex. Values: model name strings (e.g., \"sonnet\", \"gemini-3-pro-preview\", \"gpt-5.2-codex\")"
|
|
271
|
+
},
|
|
272
|
+
"review": {
|
|
273
|
+
"type": "boolean",
|
|
274
|
+
"description": "Whether artifacts from this agent should be reviewed before posting (defaults to false)"
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"additionalProperties": false
|
|
278
|
+
},
|
|
279
|
+
"description": "Nested per-agent settings. Only meaningful under the iloom-swarm-worker agent entry for sub-agent timeout configuration."
|
|
280
|
+
},
|
|
281
|
+
"subAgentTimeout": {
|
|
282
|
+
"type": "number",
|
|
283
|
+
"minimum": 1,
|
|
284
|
+
"maximum": 120,
|
|
285
|
+
"default": 10,
|
|
286
|
+
"description": "Timeout in minutes for sub-agent claude -p invocations in swarm mode. Applies to each phase agent (evaluator, analyzer, planner, implementer) when invoked via the Bash tool. Default: 10 minutes. Only meaningful under the iloom-swarm-worker agent entry."
|
|
221
287
|
}
|
|
222
288
|
},
|
|
223
289
|
"additionalProperties": false
|
|
@@ -229,7 +295,7 @@
|
|
|
229
295
|
"type": "null"
|
|
230
296
|
}
|
|
231
297
|
],
|
|
232
|
-
"description": "Per-agent configuration overrides. Available agents: iloom-issue-analyzer (analyzes issues), iloom-issue-planner (creates implementation plans), iloom-issue-analyze-and-plan (combined analysis and planning), iloom-issue-complexity-evaluator (evaluates complexity), iloom-issue-enhancer (enhances issue descriptions), iloom-issue-implementer (implements code changes), iloom-code-reviewer (reviews code changes against requirements), iloom-artifact-reviewer (reviews artifacts before posting)"
|
|
298
|
+
"description": "Per-agent configuration overrides. Available agents: iloom-issue-analyzer (analyzes issues), iloom-issue-planner (creates implementation plans), iloom-issue-analyze-and-plan (combined analysis and planning), iloom-issue-complexity-evaluator (evaluates complexity), iloom-issue-enhancer (enhances issue descriptions), iloom-issue-implementer (implements code changes), iloom-code-reviewer (reviews code changes against requirements), iloom-artifact-reviewer (reviews artifacts before posting), iloom-swarm-worker (swarm worker agent, dynamically generated). Use swarmModel on any agent to override its model in swarm mode."
|
|
233
299
|
},
|
|
234
300
|
"spin": {
|
|
235
301
|
"type": "object",
|
|
@@ -243,6 +309,15 @@
|
|
|
243
309
|
],
|
|
244
310
|
"default": "opus",
|
|
245
311
|
"description": "Claude model shorthand for spin orchestrator"
|
|
312
|
+
},
|
|
313
|
+
"swarmModel": {
|
|
314
|
+
"type": "string",
|
|
315
|
+
"enum": [
|
|
316
|
+
"sonnet",
|
|
317
|
+
"opus",
|
|
318
|
+
"haiku"
|
|
319
|
+
],
|
|
320
|
+
"description": "Model for the spin orchestrator when running in swarm mode. Overrides spin.model for swarm workflows."
|
|
246
321
|
}
|
|
247
322
|
},
|
|
248
323
|
"additionalProperties": false,
|
|
@@ -306,17 +381,6 @@
|
|
|
306
381
|
"capabilities": {
|
|
307
382
|
"type": "object",
|
|
308
383
|
"properties": {
|
|
309
|
-
"capabilities": {
|
|
310
|
-
"type": "array",
|
|
311
|
-
"items": {
|
|
312
|
-
"type": "string",
|
|
313
|
-
"enum": [
|
|
314
|
-
"cli",
|
|
315
|
-
"web"
|
|
316
|
-
]
|
|
317
|
-
},
|
|
318
|
-
"description": "Explicitly declared project capabilities (auto-detected if not specified)"
|
|
319
|
-
},
|
|
320
384
|
"web": {
|
|
321
385
|
"type": "object",
|
|
322
386
|
"properties": {
|
|
@@ -327,7 +391,8 @@
|
|
|
327
391
|
"description": "Base port for web workspace port calculations (default: 3000)"
|
|
328
392
|
}
|
|
329
393
|
},
|
|
330
|
-
"additionalProperties": false
|
|
394
|
+
"additionalProperties": false,
|
|
395
|
+
"description": "Web dev server settings. To declare a project as a web project, add \"web\" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json."
|
|
331
396
|
},
|
|
332
397
|
"database": {
|
|
333
398
|
"type": "object",
|
|
@@ -382,10 +447,11 @@
|
|
|
382
447
|
"type": "string",
|
|
383
448
|
"enum": [
|
|
384
449
|
"github",
|
|
385
|
-
"linear"
|
|
450
|
+
"linear",
|
|
451
|
+
"jira"
|
|
386
452
|
],
|
|
387
453
|
"default": "github",
|
|
388
|
-
"description": "Issue tracker provider (github, linear)"
|
|
454
|
+
"description": "Issue tracker provider (github, linear, jira)"
|
|
389
455
|
},
|
|
390
456
|
"github": {
|
|
391
457
|
"type": "object",
|
|
@@ -422,6 +488,69 @@
|
|
|
422
488
|
"teamId"
|
|
423
489
|
],
|
|
424
490
|
"additionalProperties": false
|
|
491
|
+
},
|
|
492
|
+
"jira": {
|
|
493
|
+
"type": "object",
|
|
494
|
+
"properties": {
|
|
495
|
+
"host": {
|
|
496
|
+
"type": "string",
|
|
497
|
+
"minLength": 1,
|
|
498
|
+
"description": "Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")"
|
|
499
|
+
},
|
|
500
|
+
"username": {
|
|
501
|
+
"type": "string",
|
|
502
|
+
"minLength": 1,
|
|
503
|
+
"description": "Jira username or email address"
|
|
504
|
+
},
|
|
505
|
+
"apiToken": {
|
|
506
|
+
"type": "string",
|
|
507
|
+
"description": "Jira API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://id.atlassian.com/manage-profile/security/api-tokens"
|
|
508
|
+
},
|
|
509
|
+
"projectKey": {
|
|
510
|
+
"type": "string",
|
|
511
|
+
"minLength": 1,
|
|
512
|
+
"description": "Jira project key (e.g., \"PROJ\", \"ENG\")"
|
|
513
|
+
},
|
|
514
|
+
"boardId": {
|
|
515
|
+
"type": "string",
|
|
516
|
+
"description": "Jira board ID for sprint/workflow operations (optional)"
|
|
517
|
+
},
|
|
518
|
+
"transitionMappings": {
|
|
519
|
+
"type": "object",
|
|
520
|
+
"additionalProperties": {
|
|
521
|
+
"type": "string"
|
|
522
|
+
},
|
|
523
|
+
"description": "Map iloom states to Jira transition names (e.g., {\"In Review\": \"Start Review\"})"
|
|
524
|
+
},
|
|
525
|
+
"defaultIssueType": {
|
|
526
|
+
"type": "string",
|
|
527
|
+
"minLength": 1,
|
|
528
|
+
"default": "Task",
|
|
529
|
+
"description": "Default Jira issue type name for creating issues (e.g., \"Task\", \"Story\", \"Bug\")"
|
|
530
|
+
},
|
|
531
|
+
"defaultSubtaskType": {
|
|
532
|
+
"type": "string",
|
|
533
|
+
"minLength": 1,
|
|
534
|
+
"default": "Subtask",
|
|
535
|
+
"description": "Default Jira issue type name for creating subtasks/child issues (e.g., \"Subtask\", \"Sub-task\")"
|
|
536
|
+
},
|
|
537
|
+
"doneStatuses": {
|
|
538
|
+
"type": "array",
|
|
539
|
+
"items": {
|
|
540
|
+
"type": "string"
|
|
541
|
+
},
|
|
542
|
+
"default": [
|
|
543
|
+
"Done"
|
|
544
|
+
],
|
|
545
|
+
"description": "Status names to exclude from issue lists (e.g., [\"Done\", \"Closed\", \"Verify\"])"
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
"required": [
|
|
549
|
+
"host",
|
|
550
|
+
"username",
|
|
551
|
+
"projectKey"
|
|
552
|
+
],
|
|
553
|
+
"additionalProperties": false
|
|
425
554
|
}
|
|
426
555
|
},
|
|
427
556
|
"additionalProperties": false,
|
|
@@ -445,6 +574,11 @@
|
|
|
445
574
|
"autoCommitPush": {
|
|
446
575
|
"type": "boolean",
|
|
447
576
|
"description": "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
|
|
577
|
+
},
|
|
578
|
+
"openBrowserOnFinish": {
|
|
579
|
+
"type": "boolean",
|
|
580
|
+
"default": true,
|
|
581
|
+
"description": "Open the PR in the default browser after finishing in github-pr or github-draft-pr mode. Use --no-browser flag to override."
|
|
448
582
|
}
|
|
449
583
|
},
|
|
450
584
|
"additionalProperties": false,
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
IdentifierParser
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-63QWFWH3.js";
|
|
5
5
|
import {
|
|
6
6
|
GitWorktreeManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-I5T677EA.js";
|
|
8
8
|
import {
|
|
9
9
|
extractIssueNumber
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4FGEGQW4.js";
|
|
11
11
|
import {
|
|
12
12
|
SettingsManager
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import
|
|
13
|
+
} from "./chunk-7VHJNVLF.js";
|
|
14
|
+
import {
|
|
15
|
+
MetadataManager
|
|
16
|
+
} from "./chunk-KB64WNBZ.js";
|
|
15
17
|
import "./chunk-6MLEBAYZ.js";
|
|
16
18
|
import {
|
|
17
19
|
getDotenvFlowFiles,
|
|
@@ -24,10 +26,11 @@ import path from "path";
|
|
|
24
26
|
import { execa } from "execa";
|
|
25
27
|
import fs from "fs-extra";
|
|
26
28
|
var ShellCommand = class {
|
|
27
|
-
constructor(gitWorktreeManager = new GitWorktreeManager(), identifierParser = new IdentifierParser(new GitWorktreeManager()), settingsManager = new SettingsManager()) {
|
|
29
|
+
constructor(gitWorktreeManager = new GitWorktreeManager(), identifierParser = new IdentifierParser(new GitWorktreeManager()), settingsManager = new SettingsManager(), metadataManager = new MetadataManager()) {
|
|
28
30
|
this.gitWorktreeManager = gitWorktreeManager;
|
|
29
31
|
this.identifierParser = identifierParser;
|
|
30
32
|
this.settingsManager = settingsManager;
|
|
33
|
+
this.metadataManager = metadataManager;
|
|
31
34
|
}
|
|
32
35
|
async execute(input) {
|
|
33
36
|
const parsed = input.identifier ? await this.parseExplicitInput(input.identifier) : await this.autoDetectFromCurrentDirectory();
|
|
@@ -47,6 +50,10 @@ var ShellCommand = class {
|
|
|
47
50
|
}
|
|
48
51
|
const loomIdentifier = this.formatLoomIdentifier(parsed);
|
|
49
52
|
envVars.ILOOM_LOOM = loomIdentifier;
|
|
53
|
+
const metadata = await this.metadataManager.readMetadata(worktree.path);
|
|
54
|
+
if (metadata == null ? void 0 : metadata.colorHex) {
|
|
55
|
+
envVars.ILOOM_COLOR_HEX = metadata.colorHex;
|
|
56
|
+
}
|
|
50
57
|
const shell = this.detectShell();
|
|
51
58
|
this.printSummary(worktree.path, shell, loadedEnvFiles, envVars, shouldLoadEnv);
|
|
52
59
|
await execa(shell, [], {
|
|
@@ -235,4 +242,4 @@ var ShellCommand = class {
|
|
|
235
242
|
export {
|
|
236
243
|
ShellCommand
|
|
237
244
|
};
|
|
238
|
-
//# sourceMappingURL=shell-
|
|
245
|
+
//# sourceMappingURL=shell-RF7LTND5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/shell.ts"],"sourcesContent":["import path from 'path'\nimport { execa } from 'execa'\nimport fs from 'fs-extra'\nimport { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { MetadataManager } from '../lib/MetadataManager.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { IdentifierParser } from '../utils/IdentifierParser.js'\nimport { loadWorkspaceEnv, getDotenvFlowFiles } from '../utils/env.js'\nimport { extractIssueNumber } from '../utils/git.js'\nimport { logger } from '../utils/logger.js'\nimport type { GitWorktree } from '../types/worktree.js'\n\nexport interface ShellCommandInput {\n\tidentifier?: string | undefined\n}\n\ninterface ParsedShellInput {\n\ttype: 'issue' | 'pr' | 'branch' | 'epic'\n\tnumber?: string | number\n\tbranchName?: string\n\toriginalInput: string\n\tautoDetected: boolean\n}\n\n/**\n * ShellCommand - Open interactive shell with workspace environment\n * Loads dotenv-flow files when sourceEnvOnStart is configured\n */\nexport class ShellCommand {\n\tconstructor(\n\t\tprivate gitWorktreeManager = new GitWorktreeManager(),\n\t\tprivate identifierParser = new IdentifierParser(new GitWorktreeManager()),\n\t\tprivate settingsManager = new SettingsManager(),\n\t\tprivate metadataManager = new MetadataManager()\n\t) {}\n\n\tasync execute(input: ShellCommandInput): Promise<void> {\n\t\t// 1. Parse or auto-detect identifier\n\t\tconst parsed = input.identifier\n\t\t\t? await this.parseExplicitInput(input.identifier)\n\t\t\t: await this.autoDetectFromCurrentDirectory()\n\n\t\tlogger.debug(`Parsed input: ${JSON.stringify(parsed)}`)\n\n\t\t// 2. Find worktree path based on identifier\n\t\tconst worktree = await this.findWorktreeForIdentifier(parsed)\n\n\t\tlogger.debug(`Found worktree at: ${worktree.path}`)\n\n\t\t// 3. Load settings to check sourceEnvOnStart\n\t\tconst settings = await this.settingsManager.loadSettings()\n\t\tconst shouldLoadEnv = settings.sourceEnvOnStart ?? false\n\n\t\t// 4. Build environment variables\n\t\tlet envVars: Record<string, string> = { ...process.env as Record<string, string> }\n\t\tlet loadedEnvFiles: string[] = []\n\n\t\tif (shouldLoadEnv) {\n\t\t\tconst envResult = loadWorkspaceEnv(worktree.path)\n\t\t\tif (envResult.parsed) {\n\t\t\t\tenvVars = { ...envVars, ...envResult.parsed }\n\t\t\t}\n\t\t\t// Determine which files were actually loaded\n\t\t\tloadedEnvFiles = await this.getExistingEnvFiles(worktree.path)\n\t\t}\n\n\t\t// 5. Set ILOOM_LOOM for PS1 customization\n\t\tconst loomIdentifier = this.formatLoomIdentifier(parsed)\n\t\tenvVars.ILOOM_LOOM = loomIdentifier\n\n\t\t// 5b. Set ILOOM_COLOR_HEX from loom metadata if available\n\t\tconst metadata = await this.metadataManager.readMetadata(worktree.path)\n\t\tif (metadata?.colorHex) {\n\t\t\tenvVars.ILOOM_COLOR_HEX = metadata.colorHex\n\t\t}\n\n\t\t// 6. Detect shell\n\t\tconst shell = this.detectShell()\n\n\t\t// 7. Print summary\n\t\tthis.printSummary(worktree.path, shell, loadedEnvFiles, envVars, shouldLoadEnv)\n\n\t\t// 8. Launch interactive shell\n\t\tawait execa(shell, [], {\n\t\t\tcwd: worktree.path,\n\t\t\tenv: envVars,\n\t\t\tstdio: 'inherit',\n\t\t})\n\t}\n\n\t/**\n\t * Parse explicit identifier input\n\t */\n\tprivate async parseExplicitInput(identifier: string): Promise<ParsedShellInput> {\n\t\tconst parsed = await this.identifierParser.parseForPatternDetection(identifier)\n\n\t\t// Description type should never reach terminal command\n\t\tif (parsed.type === 'description') {\n\t\t\tthrow new Error('Description input type is not supported in terminal command')\n\t\t}\n\n\t\tconst result: ParsedShellInput = {\n\t\t\ttype: parsed.type,\n\t\t\toriginalInput: parsed.originalInput,\n\t\t\tautoDetected: false,\n\t\t}\n\n\t\tif (parsed.number !== undefined) {\n\t\t\tresult.number = parsed.number\n\t\t}\n\t\tif (parsed.branchName !== undefined) {\n\t\t\tresult.branchName = parsed.branchName\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Auto-detect identifier from current directory\n\t */\n\tprivate async autoDetectFromCurrentDirectory(): Promise<ParsedShellInput> {\n\t\tconst currentDir = path.basename(process.cwd())\n\n\t\t// Check for PR worktree pattern: _pr_N suffix\n\t\tconst prPattern = /_pr_(\\d+)$/\n\t\tconst prMatch = currentDir.match(prPattern)\n\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tlogger.debug(`Auto-detected PR #${prNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'pr',\n\t\t\t\tnumber: prNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Check for issue pattern in directory\n\t\tconst issueNumber = extractIssueNumber(currentDir)\n\n\t\tif (issueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${issueNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: issueNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Fallback: get current branch name\n\t\tconst repoInfo = await this.gitWorktreeManager.getRepoInfo()\n\t\tconst currentBranch = repoInfo.currentBranch\n\n\t\tif (!currentBranch) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not auto-detect identifier. Please provide an issue number, PR number, or branch name.\\n' +\n\t\t\t\t\t'Expected directory pattern: feat/issue-XX-description OR worktree with _pr_N suffix'\n\t\t\t)\n\t\t}\n\n\t\t// Try to extract issue from branch name\n\t\tconst branchIssueNumber = extractIssueNumber(currentBranch)\n\t\tif (branchIssueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${branchIssueNumber} from branch: ${currentBranch}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: branchIssueNumber,\n\t\t\t\toriginalInput: currentBranch,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Last resort: use branch name\n\t\treturn {\n\t\t\ttype: 'branch',\n\t\t\tbranchName: currentBranch,\n\t\t\toriginalInput: currentBranch,\n\t\t\tautoDetected: true,\n\t\t}\n\t}\n\n\t/**\n\t * Find worktree for the given identifier\n\t */\n\tprivate async findWorktreeForIdentifier(parsed: ParsedShellInput): Promise<GitWorktree> {\n\t\tlet worktree: GitWorktree | null = null\n\n\t\tif (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForIssue(parsed.number)\n\t\t} else if (parsed.type === 'pr' && parsed.number !== undefined) {\n\t\t\tconst prNumber = typeof parsed.number === 'number' ? parsed.number : Number(parsed.number)\n\t\t\tif (isNaN(prNumber) || !isFinite(prNumber)) {\n\t\t\t\tthrow new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`)\n\t\t\t}\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForPR(prNumber, '')\n\t\t} else if (parsed.type === 'branch' && parsed.branchName) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForBranch(\n\t\t\t\tparsed.branchName\n\t\t\t)\n\t\t}\n\n\t\tif (!worktree) {\n\t\t\tthrow new Error(\n\t\t\t\t`No worktree found for ${this.formatParsedInput(parsed)}. ` +\n\t\t\t\t\t`Run 'il start ${parsed.originalInput}' to create one.`\n\t\t\t)\n\t\t}\n\n\t\treturn worktree\n\t}\n\n\t/**\n\t * Format parsed input for display\n\t */\n\tprivate formatParsedInput(parsed: ParsedShellInput): string {\n\t\tconst autoLabel = parsed.autoDetected ? ' (auto-detected)' : ''\n\n\t\tif (parsed.type === 'issue') {\n\t\t\treturn `issue #${parsed.number}${autoLabel}`\n\t\t}\n\t\tif (parsed.type === 'pr') {\n\t\t\treturn `PR #${parsed.number}${autoLabel}`\n\t\t}\n\t\treturn `branch \"${parsed.branchName}\"${autoLabel}`\n\t}\n\n\t/**\n\t * Format loom identifier for ILOOM_LOOM env var\n\t */\n\tprivate formatLoomIdentifier(parsed: ParsedShellInput): string {\n\t\tif (parsed.type === 'issue') {\n\t\t\treturn `issue-${parsed.number}`\n\t\t}\n\t\tif (parsed.type === 'pr') {\n\t\t\treturn `pr-${parsed.number}`\n\t\t}\n\t\treturn parsed.branchName ?? parsed.originalInput\n\t}\n\n\t/**\n\t * Detect shell based on platform and environment variables\n\t */\n\tprivate detectShell(): string {\n\t\t// ILOOM_SHELL takes highest priority\n\t\tif (process.env.ILOOM_SHELL) {\n\t\t\treturn process.env.ILOOM_SHELL\n\t\t}\n\n\t\t// Platform-specific detection\n\t\tif (process.platform === 'win32') {\n\t\t\t// Windows: prefer PowerShell, fall back to COMSPEC (cmd.exe)\n\t\t\treturn process.env.COMSPEC ?? 'cmd.exe'\n\t\t}\n\n\t\t// Unix/macOS: use SHELL or fall back to /bin/bash\n\t\treturn process.env.SHELL ?? '/bin/bash'\n\t}\n\n\t/**\n\t * Get list of existing dotenv-flow files in workspace\n\t */\n\tprivate async getExistingEnvFiles(workspacePath: string): Promise<string[]> {\n\t\tconst files = getDotenvFlowFiles()\n\t\tconst existing: string[] = []\n\n\t\tfor (const file of files) {\n\t\t\tconst fullPath = path.join(workspacePath, file)\n\t\t\tif (await fs.pathExists(fullPath)) {\n\t\t\t\texisting.push(file)\n\t\t\t}\n\t\t}\n\n\t\treturn existing\n\t}\n\n\t/**\n\t * Print summary of shell session\n\t */\n\tprivate printSummary(\n\t\tworkspacePath: string,\n\t\tshell: string,\n\t\tloadedEnvFiles: string[],\n\t\tenvVars: Record<string, string>,\n\t\tenvEnabled: boolean\n\t): void {\n\t\tlogger.info('Opening interactive shell')\n\t\tlogger.info(` Workspace: ${workspacePath}`)\n\t\tlogger.info(` Shell: ${shell}`)\n\n\t\tif (envEnabled) {\n\t\t\tif (loadedEnvFiles.length > 0) {\n\t\t\t\tlogger.info(` Env files: ${loadedEnvFiles.join(', ')}`)\n\t\t\t} else {\n\t\t\t\tlogger.info(' Env files: (none found)')\n\t\t\t}\n\n\t\t\t// Print key environment variables if present\n\t\t\tconst keyVars = ['PORT', 'DATABASE_URL', 'NODE_ENV']\n\t\t\tconst presentVars = keyVars.filter(v => envVars[v])\n\t\t\tif (presentVars.length > 0) {\n\t\t\t\tconst varSummary = presentVars.map(v => {\n\t\t\t\t\tconst value = envVars[v]\n\t\t\t\t\t// Truncate long values like DATABASE_URL\n\t\t\t\t\tconst displayValue = value && value.length > 40\n\t\t\t\t\t\t? value.substring(0, 37) + '...'\n\t\t\t\t\t\t: value\n\t\t\t\t\treturn `${v}=${displayValue}`\n\t\t\t\t}).join(', ')\n\t\t\t\tlogger.info(` Key vars: ${varSummary}`)\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.info(' Env loading: disabled (set sourceEnvOnStart in settings to enable)')\n\t\t}\n\n\t\tlogger.info('')\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionSummaryService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EVPZFV3K.js";
|
|
5
5
|
import "./chunk-NXMDEL3F.js";
|
|
6
6
|
import {
|
|
7
7
|
PRManager
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-FJDRTVJX.js";
|
|
8
|
+
} from "./chunk-KVHIAWVT.js";
|
|
9
|
+
import "./chunk-SWSJWA2S.js";
|
|
10
|
+
import "./chunk-4232AHNQ.js";
|
|
12
11
|
import {
|
|
13
12
|
GitWorktreeManager
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-I5T677EA.js";
|
|
14
|
+
import "./chunk-YETJNRQM.js";
|
|
15
15
|
import "./chunk-FXDYIV3K.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-UR5DGNUO.js";
|
|
17
|
+
import "./chunk-UUEW5KWB.js";
|
|
17
18
|
import {
|
|
18
19
|
extractIssueNumber
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-4FGEGQW4.js";
|
|
20
21
|
import {
|
|
21
22
|
SettingsManager
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-7VHJNVLF.js";
|
|
23
24
|
import {
|
|
24
25
|
MetadataManager
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
26
|
+
} from "./chunk-KB64WNBZ.js";
|
|
27
|
+
import "./chunk-HEXKPKCK.js";
|
|
28
|
+
import "./chunk-VG45TUYK.js";
|
|
28
29
|
import {
|
|
29
30
|
getLogger
|
|
30
31
|
} from "./chunk-6MLEBAYZ.js";
|
|
32
|
+
import "./chunk-7JDMYTFZ.js";
|
|
31
33
|
import "./chunk-VT4PDUYT.js";
|
|
32
34
|
|
|
33
35
|
// src/commands/summary.ts
|
|
@@ -120,7 +122,7 @@ var SummaryCommand = class {
|
|
|
120
122
|
* - Branch names: "my-feature-branch"
|
|
121
123
|
*/
|
|
122
124
|
async findLoom(identifier) {
|
|
123
|
-
var _a, _b, _c, _d, _e, _f;
|
|
125
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
124
126
|
const cleanId = identifier.replace(/^#/, "").trim();
|
|
125
127
|
const prMatch = cleanId.match(/^pr\/(\d+)$/i);
|
|
126
128
|
if (prMatch == null ? void 0 : prMatch[1]) {
|
|
@@ -145,7 +147,7 @@ var SummaryCommand = class {
|
|
|
145
147
|
return {
|
|
146
148
|
worktree: issueWorktree,
|
|
147
149
|
loomType: (metadata == null ? void 0 : metadata.issueType) ?? "issue",
|
|
148
|
-
issueNumber: ((_b = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _b[0]) ?? String(issueNumber)
|
|
150
|
+
issueNumber: (metadata == null ? void 0 : metadata.issueKey) ?? ((_b = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _b[0]) ?? String(issueNumber)
|
|
149
151
|
};
|
|
150
152
|
}
|
|
151
153
|
const prWorktree = await this.gitWorktreeManager.findWorktreeForPR(issueNumber, "");
|
|
@@ -168,7 +170,7 @@ var SummaryCommand = class {
|
|
|
168
170
|
return {
|
|
169
171
|
worktree: issueWorktree,
|
|
170
172
|
loomType: (metadata == null ? void 0 : metadata.issueType) ?? "issue",
|
|
171
|
-
issueNumber: ((_d = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _d[0]) ?? alphanumericId
|
|
173
|
+
issueNumber: (metadata == null ? void 0 : metadata.issueKey) ?? ((_d = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _d[0]) ?? alphanumericId
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
176
|
throw new Error(`No loom found for identifier: ${identifier}`);
|
|
@@ -178,9 +180,9 @@ var SummaryCommand = class {
|
|
|
178
180
|
const metadata = await this.metadataManager.readMetadata(branchWorktree.path);
|
|
179
181
|
const loomType = (metadata == null ? void 0 : metadata.issueType) ?? "branch";
|
|
180
182
|
let issueNumber;
|
|
181
|
-
if (loomType === "issue" && ((_e = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _e[0])) {
|
|
182
|
-
issueNumber = metadata.issue_numbers[0];
|
|
183
|
-
} else if (loomType === "pr" && ((
|
|
183
|
+
if (loomType === "issue" && ((metadata == null ? void 0 : metadata.issueKey) || ((_e = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _e[0]))) {
|
|
184
|
+
issueNumber = (metadata == null ? void 0 : metadata.issueKey) ?? ((_f = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _f[0]);
|
|
185
|
+
} else if (loomType === "pr" && ((_g = metadata == null ? void 0 : metadata.pr_numbers) == null ? void 0 : _g[0])) {
|
|
184
186
|
issueNumber = metadata.pr_numbers[0];
|
|
185
187
|
}
|
|
186
188
|
return {
|
|
@@ -202,7 +204,7 @@ var SummaryCommand = class {
|
|
|
202
204
|
* 4. Fall back to using current branch as branch loom
|
|
203
205
|
*/
|
|
204
206
|
async autoDetectFromCurrentDirectory() {
|
|
205
|
-
var _a, _b, _c, _d, _e;
|
|
207
|
+
var _a, _b, _c, _d, _e, _f;
|
|
206
208
|
const logger = getLogger();
|
|
207
209
|
const currentDir = path.basename(process.cwd());
|
|
208
210
|
const prPattern = /_pr_(\d+)$/;
|
|
@@ -230,7 +232,7 @@ var SummaryCommand = class {
|
|
|
230
232
|
return {
|
|
231
233
|
worktree,
|
|
232
234
|
loomType: (metadata == null ? void 0 : metadata.issueType) ?? "issue",
|
|
233
|
-
issueNumber: ((_b = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _b[0]) ?? String(issueNumber)
|
|
235
|
+
issueNumber: (metadata == null ? void 0 : metadata.issueKey) ?? ((_b = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _b[0]) ?? String(issueNumber)
|
|
234
236
|
};
|
|
235
237
|
}
|
|
236
238
|
throw new Error(`No loom found for auto-detected issue #${issueNumber}`);
|
|
@@ -251,7 +253,7 @@ var SummaryCommand = class {
|
|
|
251
253
|
return {
|
|
252
254
|
worktree,
|
|
253
255
|
loomType: (metadata == null ? void 0 : metadata.issueType) ?? "issue",
|
|
254
|
-
issueNumber: ((_c = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _c[0]) ?? String(branchIssueNumber)
|
|
256
|
+
issueNumber: (metadata == null ? void 0 : metadata.issueKey) ?? ((_c = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _c[0]) ?? String(branchIssueNumber)
|
|
255
257
|
};
|
|
256
258
|
}
|
|
257
259
|
}
|
|
@@ -260,9 +262,9 @@ var SummaryCommand = class {
|
|
|
260
262
|
const metadata = await this.metadataManager.readMetadata(branchWorktree.path);
|
|
261
263
|
const loomType = (metadata == null ? void 0 : metadata.issueType) ?? "branch";
|
|
262
264
|
let resolvedIssueNumber;
|
|
263
|
-
if (loomType === "issue" && ((_d = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _d[0])) {
|
|
264
|
-
resolvedIssueNumber = metadata.issue_numbers[0];
|
|
265
|
-
} else if (loomType === "pr" && ((
|
|
265
|
+
if (loomType === "issue" && ((metadata == null ? void 0 : metadata.issueKey) || ((_d = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _d[0]))) {
|
|
266
|
+
resolvedIssueNumber = (metadata == null ? void 0 : metadata.issueKey) ?? ((_e = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _e[0]);
|
|
267
|
+
} else if (loomType === "pr" && ((_f = metadata == null ? void 0 : metadata.pr_numbers) == null ? void 0 : _f[0])) {
|
|
266
268
|
resolvedIssueNumber = metadata.pr_numbers[0];
|
|
267
269
|
}
|
|
268
270
|
return {
|
|
@@ -280,4 +282,4 @@ Please provide an issue number, PR number, or branch name.`
|
|
|
280
282
|
export {
|
|
281
283
|
SummaryCommand
|
|
282
284
|
};
|
|
283
|
-
//# sourceMappingURL=summary-
|
|
285
|
+
//# sourceMappingURL=summary-WTQZ7XG2.js.map
|