@iloom/cli 0.13.2 → 0.13.4

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.
Files changed (169) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/{BranchNamingService-MEK2WZUD.js → BranchNamingService-PBP6DY3H.js} +2 -2
  4. package/dist/{ClaudeContextManager-KJ4VEA2F.js → ClaudeContextManager-3HT4LEIU.js} +5 -5
  5. package/dist/{ClaudeService-WTJO4UW6.js → ClaudeService-7BHL2GWC.js} +4 -4
  6. package/dist/{IssueTrackerFactory-UEJALI4X.js → IssueTrackerFactory-JH34S4GX.js} +3 -3
  7. package/dist/{LoomLauncher-KG2VBNQA.js → LoomLauncher-RGXJOCMC.js} +8 -5
  8. package/dist/LoomLauncher-RGXJOCMC.js.map +1 -0
  9. package/dist/{MetadataManager-HHE6LQF2.js → MetadataManager-WKM7JJIO.js} +2 -2
  10. package/dist/README.md +1 -1
  11. package/dist/{SettingsManager-PVHBSCMI.js → SettingsManager-Y5OU5HCX.js} +4 -2
  12. package/dist/agents/CLAUDE.md +12 -7
  13. package/dist/agents/iloom-code-reviewer.md +2 -1
  14. package/dist/agents/iloom-framework-detector.md +56 -9
  15. package/dist/agents/iloom-issue-analyze-and-plan.md +1 -0
  16. package/dist/agents/iloom-issue-analyzer.md +1 -0
  17. package/dist/agents/iloom-issue-complexity-evaluator.md +1 -0
  18. package/dist/agents/iloom-issue-enhancer.md +2 -1
  19. package/dist/agents/iloom-issue-implementer.md +4 -1
  20. package/dist/agents/iloom-issue-planner.md +2 -1
  21. package/dist/agents/iloom-wave-verifier.md +1 -0
  22. package/dist/{build-2FXDYEZQ.js → build-NJJT6UHO.js} +7 -7
  23. package/dist/{chunk-VUIPDX3T.js → chunk-27CQSBUG.js} +2 -2
  24. package/dist/{chunk-YVNG35OW.js → chunk-2Z4VKQND.js} +2 -2
  25. package/dist/{chunk-UQWMPQ2Q.js → chunk-4QROZMPZ.js} +3 -3
  26. package/dist/{chunk-U2OPXZ6E.js → chunk-5NVJ6N3C.js} +7 -7
  27. package/dist/{chunk-2WRD6Y5E.js → chunk-5VP2HAWF.js} +2 -2
  28. package/dist/{chunk-CQHHEW2M.js → chunk-5WJN63T4.js} +1 -1
  29. package/dist/chunk-5WJN63T4.js.map +1 -0
  30. package/dist/{chunk-H4TSDALC.js → chunk-64K5SZXC.js} +6 -6
  31. package/dist/{chunk-5W44AI63.js → chunk-6FHFHMNF.js} +4 -4
  32. package/dist/{chunk-XC5JKRSH.js → chunk-6RKZDUTQ.js} +2 -2
  33. package/dist/{chunk-RP6MHV24.js → chunk-7VSOM25S.js} +20 -15
  34. package/dist/chunk-7VSOM25S.js.map +1 -0
  35. package/dist/{chunk-UMAOVKQX.js → chunk-CSJ7JNJV.js} +3 -3
  36. package/dist/{chunk-AQUSMNBF.js → chunk-CWRQ4NU4.js} +2 -2
  37. package/dist/{chunk-R2EFSRKR.js → chunk-EBPFEM5X.js} +16 -15
  38. package/dist/chunk-EBPFEM5X.js.map +1 -0
  39. package/dist/{chunk-OMV47LLA.js → chunk-FPM6XDEO.js} +2 -2
  40. package/dist/{chunk-DYLOITSO.js → chunk-HMMDNIKG.js} +38 -31
  41. package/dist/chunk-HMMDNIKG.js.map +1 -0
  42. package/dist/{chunk-XIVLGWUX.js → chunk-JDXJIPXR.js} +3 -1
  43. package/dist/chunk-JDXJIPXR.js.map +1 -0
  44. package/dist/{chunk-ZWXJ7G2C.js → chunk-JIMFSNZI.js} +2 -2
  45. package/dist/{chunk-D6FU4DLN.js → chunk-LULQYBRA.js} +2 -2
  46. package/dist/{chunk-DDHWZNGL.js → chunk-MB4CB7Q4.js} +6 -5
  47. package/dist/chunk-MB4CB7Q4.js.map +1 -0
  48. package/dist/{chunk-OHX3PSAY.js → chunk-MZPVETJH.js} +7 -15
  49. package/dist/chunk-MZPVETJH.js.map +1 -0
  50. package/dist/{chunk-OIJNBFMP.js → chunk-OSWL7YDO.js} +2 -2
  51. package/dist/{chunk-32D4CWWH.js → chunk-R2RGFNR4.js} +2 -2
  52. package/dist/{chunk-MPHSR6GA.js → chunk-R4Y2ZBOL.js} +5 -5
  53. package/dist/{chunk-L3P3YJCE.js → chunk-RLFS5KHU.js} +3 -3
  54. package/dist/{chunk-DMNI225H.js → chunk-SM2YM3YR.js} +4 -4
  55. package/dist/{chunk-MNPKEWBQ.js → chunk-UVZBZ5IF.js} +52 -1
  56. package/dist/chunk-UVZBZ5IF.js.map +1 -0
  57. package/dist/{chunk-Y2JHYPMX.js → chunk-VG7UFVF2.js} +47 -35
  58. package/dist/chunk-VG7UFVF2.js.map +1 -0
  59. package/dist/{chunk-OVW26FHW.js → chunk-VQ3Y3PVT.js} +2 -2
  60. package/dist/{chunk-PH65MFQM.js → chunk-Y2TPRF5H.js} +3 -3
  61. package/dist/{claude-ACL7G4CF.js → claude-IYLIOOP7.js} +2 -2
  62. package/dist/{cleanup-I62RA5TZ.js → cleanup-Q6PEKMVF.js} +18 -18
  63. package/dist/cli.js +93 -77
  64. package/dist/cli.js.map +1 -1
  65. package/dist/{commit-7RI2JFFW.js → commit-JKZQYNEB.js} +8 -8
  66. package/dist/{compile-NWTMKAGL.js → compile-QEMZDLKO.js} +7 -7
  67. package/dist/{contribute-QWPOT4QR.js → contribute-TCEOVFDN.js} +4 -4
  68. package/dist/{dev-server-OZ6KKKTR.js → dev-server-25BIZKTB.js} +12 -12
  69. package/dist/{feedback-G63MODT2.js → feedback-CQ42GFZE.js} +7 -7
  70. package/dist/{git-ZTMT6OAI.js → git-HWDX2KWU.js} +4 -4
  71. package/dist/{ignite-GUYKYC5G.js → ignite-25QLX2FS.js} +13 -13
  72. package/dist/index.d.ts +1764 -1709
  73. package/dist/index.js +105 -8
  74. package/dist/index.js.map +1 -1
  75. package/dist/{init-AMLCFVXG.js → init-LRNRRFFU.js} +8 -8
  76. package/dist/{install-deps-XS2UUCUS.js → install-deps-DHFHT3KI.js} +7 -7
  77. package/dist/{issues-2IT7PSNZ.js → issues-W722ILMI.js} +5 -5
  78. package/dist/{lint-DKWJHET3.js → lint-TZDEPVKN.js} +7 -7
  79. package/dist/mcp/issue-management-server.js +39 -0
  80. package/dist/mcp/issue-management-server.js.map +1 -1
  81. package/dist/mcp/recap-server.js +2 -2
  82. package/dist/mcp/recap-server.js.map +1 -1
  83. package/dist/{open-6PXNIPXS.js → open-BCQSZYAD.js} +12 -12
  84. package/dist/{plan-NJVQBBT3.js → plan-2LUGSOYG.js} +30 -28
  85. package/dist/plan-2LUGSOYG.js.map +1 -0
  86. package/dist/{projects-3F6T3KZL.js → projects-INTNTWRM.js} +2 -2
  87. package/dist/prompts/init-prompt.txt +72 -4
  88. package/dist/prompts/issue-prompt.txt +6 -3
  89. package/dist/prompts/pr-prompt.txt +3 -2
  90. package/dist/prompts/regular-prompt.txt +3 -2
  91. package/dist/prompts/session-summary-prompt.txt +2 -1
  92. package/dist/prompts/swarm-orchestrator-prompt.txt +2 -2
  93. package/dist/{rebase-6AXN45AE.js → rebase-ZKZKKQKB.js} +7 -7
  94. package/dist/{recap-XDKI3MTA.js → recap-XXLLMETY.js} +7 -7
  95. package/dist/{run-RHE5NPDT.js → run-5P5ULYZY.js} +12 -12
  96. package/dist/schema/settings.schema.json +50 -0
  97. package/dist/{shell-XOILFEZW.js → shell-GNDHII2J.js} +6 -6
  98. package/dist/{summary-BVYOM63C.js → summary-TVLBZNKY.js} +10 -10
  99. package/dist/{test-6T2UMQ7T.js → test-T5K7FOKQ.js} +7 -7
  100. package/dist/{test-git-CQ65OL45.js → test-git-AQ3ZQ4RA.js} +4 -4
  101. package/dist/{test-jira-CQQHGZ3S.js → test-jira-7XQ63U2C.js} +3 -3
  102. package/dist/{test-prefix-HMTZSS67.js → test-prefix-OTY2HBSB.js} +4 -4
  103. package/dist/{test-webserver-ZN73CM2T.js → test-webserver-CPQMUCDD.js} +6 -6
  104. package/dist/{vscode-ABQ5ZSH7.js → vscode-M4KRTKZK.js} +6 -6
  105. package/package.json +1 -1
  106. package/dist/LoomLauncher-KG2VBNQA.js.map +0 -1
  107. package/dist/chunk-CQHHEW2M.js.map +0 -1
  108. package/dist/chunk-DDHWZNGL.js.map +0 -1
  109. package/dist/chunk-DYLOITSO.js.map +0 -1
  110. package/dist/chunk-MNPKEWBQ.js.map +0 -1
  111. package/dist/chunk-OHX3PSAY.js.map +0 -1
  112. package/dist/chunk-R2EFSRKR.js.map +0 -1
  113. package/dist/chunk-RP6MHV24.js.map +0 -1
  114. package/dist/chunk-XIVLGWUX.js.map +0 -1
  115. package/dist/chunk-Y2JHYPMX.js.map +0 -1
  116. package/dist/plan-NJVQBBT3.js.map +0 -1
  117. /package/dist/{BranchNamingService-MEK2WZUD.js.map → BranchNamingService-PBP6DY3H.js.map} +0 -0
  118. /package/dist/{ClaudeContextManager-KJ4VEA2F.js.map → ClaudeContextManager-3HT4LEIU.js.map} +0 -0
  119. /package/dist/{ClaudeService-WTJO4UW6.js.map → ClaudeService-7BHL2GWC.js.map} +0 -0
  120. /package/dist/{IssueTrackerFactory-UEJALI4X.js.map → IssueTrackerFactory-JH34S4GX.js.map} +0 -0
  121. /package/dist/{MetadataManager-HHE6LQF2.js.map → MetadataManager-WKM7JJIO.js.map} +0 -0
  122. /package/dist/{SettingsManager-PVHBSCMI.js.map → SettingsManager-Y5OU5HCX.js.map} +0 -0
  123. /package/dist/{build-2FXDYEZQ.js.map → build-NJJT6UHO.js.map} +0 -0
  124. /package/dist/{chunk-VUIPDX3T.js.map → chunk-27CQSBUG.js.map} +0 -0
  125. /package/dist/{chunk-YVNG35OW.js.map → chunk-2Z4VKQND.js.map} +0 -0
  126. /package/dist/{chunk-UQWMPQ2Q.js.map → chunk-4QROZMPZ.js.map} +0 -0
  127. /package/dist/{chunk-U2OPXZ6E.js.map → chunk-5NVJ6N3C.js.map} +0 -0
  128. /package/dist/{chunk-2WRD6Y5E.js.map → chunk-5VP2HAWF.js.map} +0 -0
  129. /package/dist/{chunk-H4TSDALC.js.map → chunk-64K5SZXC.js.map} +0 -0
  130. /package/dist/{chunk-5W44AI63.js.map → chunk-6FHFHMNF.js.map} +0 -0
  131. /package/dist/{chunk-XC5JKRSH.js.map → chunk-6RKZDUTQ.js.map} +0 -0
  132. /package/dist/{chunk-UMAOVKQX.js.map → chunk-CSJ7JNJV.js.map} +0 -0
  133. /package/dist/{chunk-AQUSMNBF.js.map → chunk-CWRQ4NU4.js.map} +0 -0
  134. /package/dist/{chunk-OMV47LLA.js.map → chunk-FPM6XDEO.js.map} +0 -0
  135. /package/dist/{chunk-ZWXJ7G2C.js.map → chunk-JIMFSNZI.js.map} +0 -0
  136. /package/dist/{chunk-D6FU4DLN.js.map → chunk-LULQYBRA.js.map} +0 -0
  137. /package/dist/{chunk-OIJNBFMP.js.map → chunk-OSWL7YDO.js.map} +0 -0
  138. /package/dist/{chunk-32D4CWWH.js.map → chunk-R2RGFNR4.js.map} +0 -0
  139. /package/dist/{chunk-MPHSR6GA.js.map → chunk-R4Y2ZBOL.js.map} +0 -0
  140. /package/dist/{chunk-L3P3YJCE.js.map → chunk-RLFS5KHU.js.map} +0 -0
  141. /package/dist/{chunk-DMNI225H.js.map → chunk-SM2YM3YR.js.map} +0 -0
  142. /package/dist/{chunk-OVW26FHW.js.map → chunk-VQ3Y3PVT.js.map} +0 -0
  143. /package/dist/{chunk-PH65MFQM.js.map → chunk-Y2TPRF5H.js.map} +0 -0
  144. /package/dist/{claude-ACL7G4CF.js.map → claude-IYLIOOP7.js.map} +0 -0
  145. /package/dist/{cleanup-I62RA5TZ.js.map → cleanup-Q6PEKMVF.js.map} +0 -0
  146. /package/dist/{commit-7RI2JFFW.js.map → commit-JKZQYNEB.js.map} +0 -0
  147. /package/dist/{compile-NWTMKAGL.js.map → compile-QEMZDLKO.js.map} +0 -0
  148. /package/dist/{contribute-QWPOT4QR.js.map → contribute-TCEOVFDN.js.map} +0 -0
  149. /package/dist/{dev-server-OZ6KKKTR.js.map → dev-server-25BIZKTB.js.map} +0 -0
  150. /package/dist/{feedback-G63MODT2.js.map → feedback-CQ42GFZE.js.map} +0 -0
  151. /package/dist/{git-ZTMT6OAI.js.map → git-HWDX2KWU.js.map} +0 -0
  152. /package/dist/{ignite-GUYKYC5G.js.map → ignite-25QLX2FS.js.map} +0 -0
  153. /package/dist/{init-AMLCFVXG.js.map → init-LRNRRFFU.js.map} +0 -0
  154. /package/dist/{install-deps-XS2UUCUS.js.map → install-deps-DHFHT3KI.js.map} +0 -0
  155. /package/dist/{issues-2IT7PSNZ.js.map → issues-W722ILMI.js.map} +0 -0
  156. /package/dist/{lint-DKWJHET3.js.map → lint-TZDEPVKN.js.map} +0 -0
  157. /package/dist/{open-6PXNIPXS.js.map → open-BCQSZYAD.js.map} +0 -0
  158. /package/dist/{projects-3F6T3KZL.js.map → projects-INTNTWRM.js.map} +0 -0
  159. /package/dist/{rebase-6AXN45AE.js.map → rebase-ZKZKKQKB.js.map} +0 -0
  160. /package/dist/{recap-XDKI3MTA.js.map → recap-XXLLMETY.js.map} +0 -0
  161. /package/dist/{run-RHE5NPDT.js.map → run-5P5ULYZY.js.map} +0 -0
  162. /package/dist/{shell-XOILFEZW.js.map → shell-GNDHII2J.js.map} +0 -0
  163. /package/dist/{summary-BVYOM63C.js.map → summary-TVLBZNKY.js.map} +0 -0
  164. /package/dist/{test-6T2UMQ7T.js.map → test-T5K7FOKQ.js.map} +0 -0
  165. /package/dist/{test-git-CQ65OL45.js.map → test-git-AQ3ZQ4RA.js.map} +0 -0
  166. /package/dist/{test-jira-CQQHGZ3S.js.map → test-jira-7XQ63U2C.js.map} +0 -0
  167. /package/dist/{test-prefix-HMTZSS67.js.map → test-prefix-OTY2HBSB.js.map} +0 -0
  168. /package/dist/{test-webserver-ZN73CM2T.js.map → test-webserver-CPQMUCDD.js.map} +0 -0
  169. /package/dist/{vscode-ABQ5ZSH7.js.map → vscode-M4KRTKZK.js.map} +0 -0
@@ -152,7 +152,7 @@ server.registerTool(
152
152
  title: "Add Entry",
153
153
  description: "Append an entry to the recap. If an entry with the same type and content already exists, it will be skipped.",
154
154
  inputSchema: {
155
- type: z.enum(["decision", "insight", "risk", "assumption", "other"]).describe("Entry type"),
155
+ type: z.enum(["decision", "insight", "risk", "assumption", "fix", "other"]).describe("Entry type"),
156
156
  content: z.string().describe("Entry content"),
157
157
  worktreePath: z.string().optional().describe("Optional worktree path to scope recap to a specific loom")
158
158
  },
@@ -259,7 +259,7 @@ server.registerTool(
259
259
  z.object({
260
260
  id: z.string(),
261
261
  timestamp: z.string(),
262
- type: z.enum(["decision", "insight", "risk", "assumption", "other"]),
262
+ type: z.enum(["decision", "insight", "risk", "assumption", "fix", "other"]),
263
263
  content: z.string()
264
264
  })
265
265
  ),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/recap-server.ts"],"sourcesContent":["/**\n * Loom Recap MCP Server\n *\n * Captures session context (goal, decisions, insights, risks, assumptions)\n * for the VS Code Loom Context Panel.\n *\n * Environment variables:\n * - RECAP_FILE_PATH: Complete path to the recap.json file (read/write)\n * - LOOM_METADATA_JSON: Stringified JSON of the loom metadata (parsed using LoomMetadata type)\n * - METADATA_FILE_PATH: Complete path to the loom metadata JSON file (for state transition tools)\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport path from 'path'\nimport os from 'os'\nimport fs from 'fs-extra'\nimport { randomUUID } from 'crypto'\nimport type { RecapFile, RecapEntry, RecapOutput, RecapArtifact } from './recap-types.js'\nimport type { LoomMetadata, MetadataFile, SwarmState } from '../lib/MetadataManager.js'\n\ninterface EnvConfig {\n\trecapFilePath: string\n\tloomMetadata: LoomMetadata\n\tmetadataFilePath: string | null\n}\n\n// Store validated config for use in tool handlers\nlet validatedRecapFilePath: string | null = null\nlet validatedLoomMetadata: LoomMetadata | null = null\nlet validatedMetadataFilePath: string | null = null\n\n/**\n * Validate required environment variables\n * Exits with error if missing (matches issue-management-server.ts pattern)\n */\nfunction validateEnvironment(): EnvConfig {\n\tconst recapFilePath = process.env.RECAP_FILE_PATH\n\tconst loomMetadataJson = process.env.LOOM_METADATA_JSON\n\n\tif (!recapFilePath) {\n\t\tconsole.error('Missing required environment variable: RECAP_FILE_PATH')\n\t\tprocess.exit(1)\n\t}\n\tif (!loomMetadataJson) {\n\t\tconsole.error('Missing required environment variable: LOOM_METADATA_JSON')\n\t\tprocess.exit(1)\n\t}\n\n\tlet loomMetadata: LoomMetadata\n\ttry {\n\t\tloomMetadata = JSON.parse(loomMetadataJson) as LoomMetadata\n\t} catch (error) {\n\t\tconsole.error('Failed to parse LOOM_METADATA_JSON:', error)\n\t\tprocess.exit(1)\n\t}\n\n\t// METADATA_FILE_PATH is optional (only needed for state transition tools)\n\tconst metadataFilePath = process.env.METADATA_FILE_PATH ?? null\n\n\t// Store for tool handlers\n\tvalidatedRecapFilePath = recapFilePath\n\tvalidatedLoomMetadata = loomMetadata\n\tvalidatedMetadataFilePath = metadataFilePath\n\n\treturn { recapFilePath, loomMetadata, metadataFilePath }\n}\n\n/**\n * Get the validated recap file path\n * Throws if called before validateEnvironment()\n */\nfunction getRecapFilePath(): string {\n\tif (!validatedRecapFilePath) {\n\t\tthrow new Error('RECAP_FILE_PATH not validated - validateEnvironment() must be called first')\n\t}\n\treturn validatedRecapFilePath\n}\n\n/**\n * Get the validated loom metadata\n * Throws if called before validateEnvironment()\n */\nexport function getLoomMetadata(): LoomMetadata {\n\tif (!validatedLoomMetadata) {\n\t\tthrow new Error('LOOM_METADATA_JSON not validated - validateEnvironment() must be called first')\n\t}\n\treturn validatedLoomMetadata\n}\n\n/**\n * Get the validated metadata file path\n * Throws if METADATA_FILE_PATH was not provided\n */\nfunction getMetadataFilePath(): string {\n\tif (!validatedMetadataFilePath) {\n\t\tthrow new Error('METADATA_FILE_PATH not configured - state transition tools require this environment variable')\n\t}\n\treturn validatedMetadataFilePath\n}\n\n/**\n * Convert worktree path to filename slug\n * Same algorithm as MetadataManager.slugifyPath() and src/utils/mcp.ts slugifyPath()\n */\nfunction slugifyPath(worktreePath: string): string {\n\tlet slug = worktreePath.replace(/[/\\\\]+$/, '')\n\tslug = slug.replace(/[/\\\\]/g, '___')\n\tslug = slug.replace(/[^a-zA-Z0-9_-]/g, '-')\n\treturn `${slug}.json`\n}\n\n/**\n * Resolve the recap file path.\n * When worktreePath is provided, derives the path dynamically.\n * Otherwise falls back to the env var default.\n */\nexport function resolveRecapFilePath(worktreePath?: string): string {\n\tif (worktreePath) {\n\t\tconst recapsDir = path.join(os.homedir(), '.config', 'iloom-ai', 'recaps')\n\t\treturn path.join(recapsDir, slugifyPath(worktreePath))\n\t}\n\treturn getRecapFilePath()\n}\n\n/**\n * Resolve the metadata file path.\n * When worktreePath is provided, derives the path dynamically.\n * Otherwise falls back to the env var default.\n */\nexport function resolveMetadataFilePath(worktreePath?: string): string {\n\tif (worktreePath) {\n\t\tconst loomsDir = path.join(os.homedir(), '.config', 'iloom-ai', 'looms')\n\t\treturn path.join(loomsDir, slugifyPath(worktreePath))\n\t}\n\treturn getMetadataFilePath()\n}\n\n/**\n * Read recap file (returns empty object if not found or invalid)\n */\nasync function readRecapFile(filePath: string): Promise<RecapFile> {\n\ttry {\n\t\tif (await fs.pathExists(filePath)) {\n\t\t\tconst content = await fs.readFile(filePath, 'utf8')\n\t\t\treturn JSON.parse(content) as RecapFile\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Warning: Could not read recap file: ${error}`)\n\t}\n\treturn {}\n}\n\n/**\n * Write recap file (ensures parent directory exists)\n */\nasync function writeRecapFile(filePath: string, recap: RecapFile): Promise<void> {\n\tawait fs.ensureDir(path.dirname(filePath), { mode: 0o755 })\n\tawait fs.writeFile(filePath, JSON.stringify(recap, null, 2), { mode: 0o644 })\n}\n\n// Initialize MCP server\nconst server = new McpServer({\n\tname: 'loom-recap',\n\tversion: '0.1.0',\n})\n\n// Register set_goal tool conditionally\n// In issue/epic workflows, set_goal is disabled via RECAP_DISABLE_SET_GOAL env var\n// to prevent agents from overwriting the goal set by the PR-level prompt\nif (!process.env.RECAP_DISABLE_SET_GOAL) {\n\tserver.registerTool(\n\t\t'set_goal',\n\t\t{\n\t\t\ttitle: 'Set Goal',\n\t\t\tdescription: 'Set the initial goal (called once at session start)',\n\t\t\tinputSchema: {\n\t\t\t\tgoal: z.string().describe('The original problem statement'),\n\t\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t\t},\n\t\t\toutputSchema: {\n\t\t\t\tsuccess: z.literal(true),\n\t\t\t},\n\t\t},\n\t\tasync ({ goal, worktreePath }) => {\n\t\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\t\tconst recap = await readRecapFile(filePath)\n\t\t\trecap.goal = goal\n\t\t\tawait writeRecapFile(filePath, recap)\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify({ success: true }) }],\n\t\t\t\tstructuredContent: { success: true },\n\t\t\t}\n\t\t}\n\t)\n}\n\n// Register set_complexity tool\nserver.registerTool(\n\t'set_complexity',\n\t{\n\t\ttitle: 'Set Complexity',\n\t\tdescription: 'Set the assessed complexity of the current task',\n\t\tinputSchema: {\n\t\t\tcomplexity: z.enum(['trivial', 'simple', 'complex']).describe('Task complexity level'),\n\t\t\treason: z.string().optional().describe('Brief explanation for the assessment'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tsuccess: z.literal(true),\n\t\t\ttimestamp: z.string(),\n\t\t},\n\t},\n\tasync ({ complexity, reason, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\tconst timestamp = new Date().toISOString()\n\t\trecap.complexity = reason !== undefined ? { level: complexity, reason, timestamp } : { level: complexity, timestamp }\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { success: true as const, timestamp }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register add_entry tool\nserver.registerTool(\n\t'add_entry',\n\t{\n\t\ttitle: 'Add Entry',\n\t\tdescription:\n\t\t\t'Append an entry to the recap. If an entry with the same type and content already exists, it will be skipped.',\n\t\tinputSchema: {\n\t\t\ttype: z\n\t\t\t\t.enum(['decision', 'insight', 'risk', 'assumption', 'other'])\n\t\t\t\t.describe('Entry type'),\n\t\t\tcontent: z.string().describe('Entry content'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tid: z.string(),\n\t\t\ttimestamp: z.string(),\n\t\t\tskipped: z.boolean(),\n\t\t},\n\t},\n\tasync ({ type, content, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\trecap.entries ??= []\n\n\t\t// Deduplication: skip if entry with same type and content exists\n\t\tconst existingEntry = recap.entries.find((e) => e.type === type && e.content === content)\n\n\t\tif (existingEntry) {\n\t\t\tconst result = { id: existingEntry.id, timestamp: existingEntry.timestamp, skipped: true }\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\t\tstructuredContent: result,\n\t\t\t}\n\t\t}\n\n\t\tconst entry: RecapEntry = {\n\t\t\tid: randomUUID(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttype,\n\t\t\tcontent,\n\t\t}\n\t\trecap.entries.push(entry)\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { id: entry.id, timestamp: entry.timestamp, skipped: false }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register add_artifact tool\nserver.registerTool(\n\t'add_artifact',\n\t{\n\t\ttitle: 'Add Artifact',\n\t\tdescription:\n\t\t\t'Track an artifact (comment, issue, PR) created during the session. If an artifact with the same primaryUrl already exists, it will be replaced.',\n\t\tinputSchema: {\n\t\t\ttype: z.enum(['comment', 'issue', 'pr']).describe('Artifact type'),\n\t\t\tprimaryUrl: z.string().url().describe('Main URL for the artifact'),\n\t\t\tdescription: z.string().describe('Brief description of the artifact'),\n\t\t\tid: z.string().optional().describe('Optional artifact ID (e.g., comment ID, issue number)'),\n\t\t\turls: z.record(z.string()).optional().describe('Optional additional URLs (e.g., { api: \"...\" })'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tid: z.string(),\n\t\t\ttimestamp: z.string(),\n\t\t\treplaced: z.boolean(),\n\t\t},\n\t},\n\tasync ({ type, primaryUrl, description, id, urls, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\n\t\tconst artifact: RecapArtifact = {\n\t\t\tid: id ?? randomUUID(),\n\t\t\ttype,\n\t\t\tprimaryUrl,\n\t\t\turls: urls ?? {},\n\t\t\tdescription,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t}\n\n\t\trecap.artifacts ??= []\n\n\t\t// Deduplication: replace existing artifact with same primaryUrl\n\t\tconst existingIndex = recap.artifacts.findIndex((a) => a.primaryUrl === primaryUrl)\n\t\tconst replaced = existingIndex !== -1\n\n\t\tif (replaced) {\n\t\t\t// Preserve the original id if not explicitly provided\n\t\t\tconst existingArtifact = recap.artifacts[existingIndex]\n\t\t\tif (existingArtifact) {\n\t\t\t\tartifact.id = id ?? existingArtifact.id\n\t\t\t\trecap.artifacts[existingIndex] = artifact\n\t\t\t}\n\t\t} else {\n\t\t\trecap.artifacts.push(artifact)\n\t\t}\n\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { id: artifact.id, timestamp: artifact.timestamp, replaced }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register get_recap tool\nserver.registerTool(\n\t'get_recap',\n\t{\n\t\ttitle: 'Get Recap',\n\t\tdescription: 'Read current recap (for catching up or review)',\n\t\tinputSchema: {\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tfilePath: z.string(),\n\t\t\tgoal: z.string().nullable(),\n\t\t\tcomplexity: z\n\t\t\t\t.object({\n\t\t\t\t\tlevel: z.enum(['trivial', 'simple', 'complex']),\n\t\t\t\t\treason: z.string().optional(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t})\n\t\t\t\t.nullable(),\n\t\t\tentries: z.array(\n\t\t\t\tz.object({\n\t\t\t\t\tid: z.string(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t\ttype: z.enum(['decision', 'insight', 'risk', 'assumption', 'other']),\n\t\t\t\t\tcontent: z.string(),\n\t\t\t\t})\n\t\t\t),\n\t\t\tartifacts: z.array(\n\t\t\t\tz.object({\n\t\t\t\t\tid: z.string(),\n\t\t\t\t\ttype: z.enum(['comment', 'issue', 'pr']),\n\t\t\t\t\tprimaryUrl: z.string(),\n\t\t\t\t\turls: z.record(z.string()),\n\t\t\t\t\tdescription: z.string(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t})\n\t\t\t),\n\t\t},\n\t},\n\tasync ({ worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\t// Use loom description as default goal for new/missing recap files\n\t\t// When worktreePath is provided, read metadata from the target worktree's metadata file\n\t\tlet defaultGoal: string | null = null\n\t\tif (worktreePath) {\n\t\t\ttry {\n\t\t\t\tconst metaPath = resolveMetadataFilePath(worktreePath)\n\t\t\t\tif (await fs.pathExists(metaPath)) {\n\t\t\t\t\tconst metaContent = await fs.readFile(metaPath, 'utf8')\n\t\t\t\t\tconst meta = JSON.parse(metaContent) as MetadataFile\n\t\t\t\t\tdefaultGoal = meta.description || null\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to null default goal\n\t\t\t}\n\t\t} else {\n\t\t\tdefaultGoal = getLoomMetadata().description || null\n\t\t}\n\t\tconst result: RecapOutput = {\n\t\t\tfilePath,\n\t\t\tgoal: recap.goal ?? defaultGoal,\n\t\t\tcomplexity: recap.complexity ?? null,\n\t\t\tentries: recap.entries ?? [],\n\t\t\tartifacts: recap.artifacts ?? [],\n\t\t}\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result as unknown as Record<string, unknown>,\n\t\t}\n\t}\n)\n\n// Zod schema for swarm state values\nconst swarmStateSchema = z.enum(['pending', 'in_progress', 'code_review', 'done', 'failed'])\n\n// Register set_loom_state tool\nserver.registerTool(\n\t'set_loom_state',\n\t{\n\t\ttitle: 'Set Loom State',\n\t\tdescription: 'Set the swarm lifecycle state of the current loom',\n\t\tinputSchema: {\n\t\t\tstate: swarmStateSchema.describe('The new state for the loom'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope state operations to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tsuccess: z.literal(true),\n\t\t\tstate: swarmStateSchema,\n\t\t},\n\t},\n\tasync ({ state, worktreePath }) => {\n\t\tconst metadataFilePath = resolveMetadataFilePath(worktreePath)\n\n\t\t// Read existing metadata\n\t\tlet metadata: MetadataFile\n\t\ttry {\n\t\t\tconst content = await fs.readFile(metadataFilePath, 'utf8')\n\t\t\tmetadata = JSON.parse(content) as MetadataFile\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to read metadata file at ${metadataFilePath}: ${error instanceof Error ? error.message : String(error)}`)\n\t\t}\n\n\t\t// Update state\n\t\tmetadata.state = state as SwarmState\n\n\t\t// Write back\n\t\tawait fs.writeFile(metadataFilePath, JSON.stringify(metadata, null, 2), { mode: 0o644 })\n\n\t\tconst result = { success: true as const, state: state as SwarmState }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register get_loom_state tool\nserver.registerTool(\n\t'get_loom_state',\n\t{\n\t\ttitle: 'Get Loom State',\n\t\tdescription: 'Get the current swarm lifecycle state of the loom',\n\t\tinputSchema: {\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope state operations to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tstate: swarmStateSchema.nullable(),\n\t\t},\n\t},\n\tasync ({ worktreePath }) => {\n\t\tconst metadataFilePath = resolveMetadataFilePath(worktreePath)\n\n\t\t// Read metadata\n\t\tlet metadata: MetadataFile\n\t\ttry {\n\t\t\tconst content = await fs.readFile(metadataFilePath, 'utf8')\n\t\t\tmetadata = JSON.parse(content) as MetadataFile\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to read metadata file at ${metadataFilePath}: ${error instanceof Error ? error.message : String(error)}`)\n\t\t}\n\n\t\tconst result = { state: metadata.state ?? null }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Main server startup\nasync function main(): Promise<void> {\n\tconsole.error('=== Loom Recap MCP Server Starting ===')\n\tconsole.error(`PID: ${process.pid}`)\n\tconsole.error(`Node version: ${process.version}`)\n\tconsole.error(`CWD: ${process.cwd()}`)\n\tconsole.error(`Script: ${new URL(import.meta.url).pathname}`)\n\n\t// Log relevant env vars (LOOM_METADATA_JSON is large, just log presence and length)\n\tconsole.error('Environment variables:')\n\tconsole.error(` RECAP_FILE_PATH=${process.env.RECAP_FILE_PATH ?? '<not set>'}`)\n\tconsole.error(` METADATA_FILE_PATH=${process.env.METADATA_FILE_PATH ?? '<not set>'}`)\n\tconsole.error(` LOOM_METADATA_JSON=${process.env.LOOM_METADATA_JSON ? `<set, ${process.env.LOOM_METADATA_JSON.length} chars>` : '<not set>'}`)\n\n\tconst { recapFilePath, loomMetadata, metadataFilePath } = validateEnvironment()\n\tconsole.error(`Recap file path: ${recapFilePath}`)\n\tconsole.error(`Metadata file path: ${metadataFilePath ?? '<not configured>'}`)\n\tconsole.error(`Loom: ${loomMetadata.description} (branch: ${loomMetadata.branchName})`)\n\n\t// Check if recap file already exists\n\tconst recapExists = await fs.pathExists(recapFilePath)\n\tconsole.error(`Recap file exists: ${recapExists}`)\n\n\tconst transport = new StdioServerTransport()\n\tawait server.connect(transport)\n\tconsole.error('=== Loom Recap MCP Server READY (stdio transport) ===')\n}\n\nmain().catch((error) => {\n\tconsole.error('Fatal error starting MCP server:', error)\n\tprocess.exit(1)\n})\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../../src/mcp/recap-server.ts"],"sourcesContent":["/**\n * Loom Recap MCP Server\n *\n * Captures session context (goal, decisions, insights, risks, fixes, assumptions)\n * for the VS Code Loom Context Panel.\n *\n * Environment variables:\n * - RECAP_FILE_PATH: Complete path to the recap.json file (read/write)\n * - LOOM_METADATA_JSON: Stringified JSON of the loom metadata (parsed using LoomMetadata type)\n * - METADATA_FILE_PATH: Complete path to the loom metadata JSON file (for state transition tools)\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport path from 'path'\nimport os from 'os'\nimport fs from 'fs-extra'\nimport { randomUUID } from 'crypto'\nimport type { RecapFile, RecapEntry, RecapOutput, RecapArtifact } from './recap-types.js'\nimport type { LoomMetadata, MetadataFile, SwarmState } from '../lib/MetadataManager.js'\n\ninterface EnvConfig {\n\trecapFilePath: string\n\tloomMetadata: LoomMetadata\n\tmetadataFilePath: string | null\n}\n\n// Store validated config for use in tool handlers\nlet validatedRecapFilePath: string | null = null\nlet validatedLoomMetadata: LoomMetadata | null = null\nlet validatedMetadataFilePath: string | null = null\n\n/**\n * Validate required environment variables\n * Exits with error if missing (matches issue-management-server.ts pattern)\n */\nfunction validateEnvironment(): EnvConfig {\n\tconst recapFilePath = process.env.RECAP_FILE_PATH\n\tconst loomMetadataJson = process.env.LOOM_METADATA_JSON\n\n\tif (!recapFilePath) {\n\t\tconsole.error('Missing required environment variable: RECAP_FILE_PATH')\n\t\tprocess.exit(1)\n\t}\n\tif (!loomMetadataJson) {\n\t\tconsole.error('Missing required environment variable: LOOM_METADATA_JSON')\n\t\tprocess.exit(1)\n\t}\n\n\tlet loomMetadata: LoomMetadata\n\ttry {\n\t\tloomMetadata = JSON.parse(loomMetadataJson) as LoomMetadata\n\t} catch (error) {\n\t\tconsole.error('Failed to parse LOOM_METADATA_JSON:', error)\n\t\tprocess.exit(1)\n\t}\n\n\t// METADATA_FILE_PATH is optional (only needed for state transition tools)\n\tconst metadataFilePath = process.env.METADATA_FILE_PATH ?? null\n\n\t// Store for tool handlers\n\tvalidatedRecapFilePath = recapFilePath\n\tvalidatedLoomMetadata = loomMetadata\n\tvalidatedMetadataFilePath = metadataFilePath\n\n\treturn { recapFilePath, loomMetadata, metadataFilePath }\n}\n\n/**\n * Get the validated recap file path\n * Throws if called before validateEnvironment()\n */\nfunction getRecapFilePath(): string {\n\tif (!validatedRecapFilePath) {\n\t\tthrow new Error('RECAP_FILE_PATH not validated - validateEnvironment() must be called first')\n\t}\n\treturn validatedRecapFilePath\n}\n\n/**\n * Get the validated loom metadata\n * Throws if called before validateEnvironment()\n */\nexport function getLoomMetadata(): LoomMetadata {\n\tif (!validatedLoomMetadata) {\n\t\tthrow new Error('LOOM_METADATA_JSON not validated - validateEnvironment() must be called first')\n\t}\n\treturn validatedLoomMetadata\n}\n\n/**\n * Get the validated metadata file path\n * Throws if METADATA_FILE_PATH was not provided\n */\nfunction getMetadataFilePath(): string {\n\tif (!validatedMetadataFilePath) {\n\t\tthrow new Error('METADATA_FILE_PATH not configured - state transition tools require this environment variable')\n\t}\n\treturn validatedMetadataFilePath\n}\n\n/**\n * Convert worktree path to filename slug\n * Same algorithm as MetadataManager.slugifyPath() and src/utils/mcp.ts slugifyPath()\n */\nfunction slugifyPath(worktreePath: string): string {\n\tlet slug = worktreePath.replace(/[/\\\\]+$/, '')\n\tslug = slug.replace(/[/\\\\]/g, '___')\n\tslug = slug.replace(/[^a-zA-Z0-9_-]/g, '-')\n\treturn `${slug}.json`\n}\n\n/**\n * Resolve the recap file path.\n * When worktreePath is provided, derives the path dynamically.\n * Otherwise falls back to the env var default.\n */\nexport function resolveRecapFilePath(worktreePath?: string): string {\n\tif (worktreePath) {\n\t\tconst recapsDir = path.join(os.homedir(), '.config', 'iloom-ai', 'recaps')\n\t\treturn path.join(recapsDir, slugifyPath(worktreePath))\n\t}\n\treturn getRecapFilePath()\n}\n\n/**\n * Resolve the metadata file path.\n * When worktreePath is provided, derives the path dynamically.\n * Otherwise falls back to the env var default.\n */\nexport function resolveMetadataFilePath(worktreePath?: string): string {\n\tif (worktreePath) {\n\t\tconst loomsDir = path.join(os.homedir(), '.config', 'iloom-ai', 'looms')\n\t\treturn path.join(loomsDir, slugifyPath(worktreePath))\n\t}\n\treturn getMetadataFilePath()\n}\n\n/**\n * Read recap file (returns empty object if not found or invalid)\n */\nasync function readRecapFile(filePath: string): Promise<RecapFile> {\n\ttry {\n\t\tif (await fs.pathExists(filePath)) {\n\t\t\tconst content = await fs.readFile(filePath, 'utf8')\n\t\t\treturn JSON.parse(content) as RecapFile\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Warning: Could not read recap file: ${error}`)\n\t}\n\treturn {}\n}\n\n/**\n * Write recap file (ensures parent directory exists)\n */\nasync function writeRecapFile(filePath: string, recap: RecapFile): Promise<void> {\n\tawait fs.ensureDir(path.dirname(filePath), { mode: 0o755 })\n\tawait fs.writeFile(filePath, JSON.stringify(recap, null, 2), { mode: 0o644 })\n}\n\n// Initialize MCP server\nconst server = new McpServer({\n\tname: 'loom-recap',\n\tversion: '0.1.0',\n})\n\n// Register set_goal tool conditionally\n// In issue/epic workflows, set_goal is disabled via RECAP_DISABLE_SET_GOAL env var\n// to prevent agents from overwriting the goal set by the PR-level prompt\nif (!process.env.RECAP_DISABLE_SET_GOAL) {\n\tserver.registerTool(\n\t\t'set_goal',\n\t\t{\n\t\t\ttitle: 'Set Goal',\n\t\t\tdescription: 'Set the initial goal (called once at session start)',\n\t\t\tinputSchema: {\n\t\t\t\tgoal: z.string().describe('The original problem statement'),\n\t\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t\t},\n\t\t\toutputSchema: {\n\t\t\t\tsuccess: z.literal(true),\n\t\t\t},\n\t\t},\n\t\tasync ({ goal, worktreePath }) => {\n\t\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\t\tconst recap = await readRecapFile(filePath)\n\t\t\trecap.goal = goal\n\t\t\tawait writeRecapFile(filePath, recap)\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify({ success: true }) }],\n\t\t\t\tstructuredContent: { success: true },\n\t\t\t}\n\t\t}\n\t)\n}\n\n// Register set_complexity tool\nserver.registerTool(\n\t'set_complexity',\n\t{\n\t\ttitle: 'Set Complexity',\n\t\tdescription: 'Set the assessed complexity of the current task',\n\t\tinputSchema: {\n\t\t\tcomplexity: z.enum(['trivial', 'simple', 'complex']).describe('Task complexity level'),\n\t\t\treason: z.string().optional().describe('Brief explanation for the assessment'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tsuccess: z.literal(true),\n\t\t\ttimestamp: z.string(),\n\t\t},\n\t},\n\tasync ({ complexity, reason, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\tconst timestamp = new Date().toISOString()\n\t\trecap.complexity = reason !== undefined ? { level: complexity, reason, timestamp } : { level: complexity, timestamp }\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { success: true as const, timestamp }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register add_entry tool\nserver.registerTool(\n\t'add_entry',\n\t{\n\t\ttitle: 'Add Entry',\n\t\tdescription:\n\t\t\t'Append an entry to the recap. If an entry with the same type and content already exists, it will be skipped.',\n\t\tinputSchema: {\n\t\t\ttype: z\n\t\t\t\t.enum(['decision', 'insight', 'risk', 'assumption', 'fix', 'other'])\n\t\t\t\t.describe('Entry type'),\n\t\t\tcontent: z.string().describe('Entry content'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tid: z.string(),\n\t\t\ttimestamp: z.string(),\n\t\t\tskipped: z.boolean(),\n\t\t},\n\t},\n\tasync ({ type, content, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\trecap.entries ??= []\n\n\t\t// Deduplication: skip if entry with same type and content exists\n\t\tconst existingEntry = recap.entries.find((e) => e.type === type && e.content === content)\n\n\t\tif (existingEntry) {\n\t\t\tconst result = { id: existingEntry.id, timestamp: existingEntry.timestamp, skipped: true }\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\t\tstructuredContent: result,\n\t\t\t}\n\t\t}\n\n\t\tconst entry: RecapEntry = {\n\t\t\tid: randomUUID(),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\ttype,\n\t\t\tcontent,\n\t\t}\n\t\trecap.entries.push(entry)\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { id: entry.id, timestamp: entry.timestamp, skipped: false }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register add_artifact tool\nserver.registerTool(\n\t'add_artifact',\n\t{\n\t\ttitle: 'Add Artifact',\n\t\tdescription:\n\t\t\t'Track an artifact (comment, issue, PR) created during the session. If an artifact with the same primaryUrl already exists, it will be replaced.',\n\t\tinputSchema: {\n\t\t\ttype: z.enum(['comment', 'issue', 'pr']).describe('Artifact type'),\n\t\t\tprimaryUrl: z.string().url().describe('Main URL for the artifact'),\n\t\t\tdescription: z.string().describe('Brief description of the artifact'),\n\t\t\tid: z.string().optional().describe('Optional artifact ID (e.g., comment ID, issue number)'),\n\t\t\turls: z.record(z.string()).optional().describe('Optional additional URLs (e.g., { api: \"...\" })'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tid: z.string(),\n\t\t\ttimestamp: z.string(),\n\t\t\treplaced: z.boolean(),\n\t\t},\n\t},\n\tasync ({ type, primaryUrl, description, id, urls, worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\n\t\tconst artifact: RecapArtifact = {\n\t\t\tid: id ?? randomUUID(),\n\t\t\ttype,\n\t\t\tprimaryUrl,\n\t\t\turls: urls ?? {},\n\t\t\tdescription,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t}\n\n\t\trecap.artifacts ??= []\n\n\t\t// Deduplication: replace existing artifact with same primaryUrl\n\t\tconst existingIndex = recap.artifacts.findIndex((a) => a.primaryUrl === primaryUrl)\n\t\tconst replaced = existingIndex !== -1\n\n\t\tif (replaced) {\n\t\t\t// Preserve the original id if not explicitly provided\n\t\t\tconst existingArtifact = recap.artifacts[existingIndex]\n\t\t\tif (existingArtifact) {\n\t\t\t\tartifact.id = id ?? existingArtifact.id\n\t\t\t\trecap.artifacts[existingIndex] = artifact\n\t\t\t}\n\t\t} else {\n\t\t\trecap.artifacts.push(artifact)\n\t\t}\n\n\t\tawait writeRecapFile(filePath, recap)\n\t\tconst result = { id: artifact.id, timestamp: artifact.timestamp, replaced }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register get_recap tool\nserver.registerTool(\n\t'get_recap',\n\t{\n\t\ttitle: 'Get Recap',\n\t\tdescription: 'Read current recap (for catching up or review)',\n\t\tinputSchema: {\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope recap to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tfilePath: z.string(),\n\t\t\tgoal: z.string().nullable(),\n\t\t\tcomplexity: z\n\t\t\t\t.object({\n\t\t\t\t\tlevel: z.enum(['trivial', 'simple', 'complex']),\n\t\t\t\t\treason: z.string().optional(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t})\n\t\t\t\t.nullable(),\n\t\t\tentries: z.array(\n\t\t\t\tz.object({\n\t\t\t\t\tid: z.string(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t\ttype: z.enum(['decision', 'insight', 'risk', 'assumption', 'fix', 'other']),\n\t\t\t\t\tcontent: z.string(),\n\t\t\t\t})\n\t\t\t),\n\t\t\tartifacts: z.array(\n\t\t\t\tz.object({\n\t\t\t\t\tid: z.string(),\n\t\t\t\t\ttype: z.enum(['comment', 'issue', 'pr']),\n\t\t\t\t\tprimaryUrl: z.string(),\n\t\t\t\t\turls: z.record(z.string()),\n\t\t\t\t\tdescription: z.string(),\n\t\t\t\t\ttimestamp: z.string(),\n\t\t\t\t})\n\t\t\t),\n\t\t},\n\t},\n\tasync ({ worktreePath }) => {\n\t\tconst filePath = resolveRecapFilePath(worktreePath)\n\t\tconst recap = await readRecapFile(filePath)\n\t\t// Use loom description as default goal for new/missing recap files\n\t\t// When worktreePath is provided, read metadata from the target worktree's metadata file\n\t\tlet defaultGoal: string | null = null\n\t\tif (worktreePath) {\n\t\t\ttry {\n\t\t\t\tconst metaPath = resolveMetadataFilePath(worktreePath)\n\t\t\t\tif (await fs.pathExists(metaPath)) {\n\t\t\t\t\tconst metaContent = await fs.readFile(metaPath, 'utf8')\n\t\t\t\t\tconst meta = JSON.parse(metaContent) as MetadataFile\n\t\t\t\t\tdefaultGoal = meta.description || null\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to null default goal\n\t\t\t}\n\t\t} else {\n\t\t\tdefaultGoal = getLoomMetadata().description || null\n\t\t}\n\t\tconst result: RecapOutput = {\n\t\t\tfilePath,\n\t\t\tgoal: recap.goal ?? defaultGoal,\n\t\t\tcomplexity: recap.complexity ?? null,\n\t\t\tentries: recap.entries ?? [],\n\t\t\tartifacts: recap.artifacts ?? [],\n\t\t}\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result as unknown as Record<string, unknown>,\n\t\t}\n\t}\n)\n\n// Zod schema for swarm state values\nconst swarmStateSchema = z.enum(['pending', 'in_progress', 'code_review', 'done', 'failed'])\n\n// Register set_loom_state tool\nserver.registerTool(\n\t'set_loom_state',\n\t{\n\t\ttitle: 'Set Loom State',\n\t\tdescription: 'Set the swarm lifecycle state of the current loom',\n\t\tinputSchema: {\n\t\t\tstate: swarmStateSchema.describe('The new state for the loom'),\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope state operations to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tsuccess: z.literal(true),\n\t\t\tstate: swarmStateSchema,\n\t\t},\n\t},\n\tasync ({ state, worktreePath }) => {\n\t\tconst metadataFilePath = resolveMetadataFilePath(worktreePath)\n\n\t\t// Read existing metadata\n\t\tlet metadata: MetadataFile\n\t\ttry {\n\t\t\tconst content = await fs.readFile(metadataFilePath, 'utf8')\n\t\t\tmetadata = JSON.parse(content) as MetadataFile\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to read metadata file at ${metadataFilePath}: ${error instanceof Error ? error.message : String(error)}`)\n\t\t}\n\n\t\t// Update state\n\t\tmetadata.state = state as SwarmState\n\n\t\t// Write back\n\t\tawait fs.writeFile(metadataFilePath, JSON.stringify(metadata, null, 2), { mode: 0o644 })\n\n\t\tconst result = { success: true as const, state: state as SwarmState }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Register get_loom_state tool\nserver.registerTool(\n\t'get_loom_state',\n\t{\n\t\ttitle: 'Get Loom State',\n\t\tdescription: 'Get the current swarm lifecycle state of the loom',\n\t\tinputSchema: {\n\t\t\tworktreePath: z.string().optional().describe('Optional worktree path to scope state operations to a specific loom'),\n\t\t},\n\t\toutputSchema: {\n\t\t\tstate: swarmStateSchema.nullable(),\n\t\t},\n\t},\n\tasync ({ worktreePath }) => {\n\t\tconst metadataFilePath = resolveMetadataFilePath(worktreePath)\n\n\t\t// Read metadata\n\t\tlet metadata: MetadataFile\n\t\ttry {\n\t\t\tconst content = await fs.readFile(metadataFilePath, 'utf8')\n\t\t\tmetadata = JSON.parse(content) as MetadataFile\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to read metadata file at ${metadataFilePath}: ${error instanceof Error ? error.message : String(error)}`)\n\t\t}\n\n\t\tconst result = { state: metadata.state ?? null }\n\t\treturn {\n\t\t\tcontent: [{ type: 'text' as const, text: JSON.stringify(result) }],\n\t\t\tstructuredContent: result,\n\t\t}\n\t}\n)\n\n// Main server startup\nasync function main(): Promise<void> {\n\tconsole.error('=== Loom Recap MCP Server Starting ===')\n\tconsole.error(`PID: ${process.pid}`)\n\tconsole.error(`Node version: ${process.version}`)\n\tconsole.error(`CWD: ${process.cwd()}`)\n\tconsole.error(`Script: ${new URL(import.meta.url).pathname}`)\n\n\t// Log relevant env vars (LOOM_METADATA_JSON is large, just log presence and length)\n\tconsole.error('Environment variables:')\n\tconsole.error(` RECAP_FILE_PATH=${process.env.RECAP_FILE_PATH ?? '<not set>'}`)\n\tconsole.error(` METADATA_FILE_PATH=${process.env.METADATA_FILE_PATH ?? '<not set>'}`)\n\tconsole.error(` LOOM_METADATA_JSON=${process.env.LOOM_METADATA_JSON ? `<set, ${process.env.LOOM_METADATA_JSON.length} chars>` : '<not set>'}`)\n\n\tconst { recapFilePath, loomMetadata, metadataFilePath } = validateEnvironment()\n\tconsole.error(`Recap file path: ${recapFilePath}`)\n\tconsole.error(`Metadata file path: ${metadataFilePath ?? '<not configured>'}`)\n\tconsole.error(`Loom: ${loomMetadata.description} (branch: ${loomMetadata.branchName})`)\n\n\t// Check if recap file already exists\n\tconst recapExists = await fs.pathExists(recapFilePath)\n\tconsole.error(`Recap file exists: ${recapExists}`)\n\n\tconst transport = new StdioServerTransport()\n\tawait server.connect(transport)\n\tconsole.error('=== Loom Recap MCP Server READY (stdio transport) ===')\n}\n\nmain().catch((error) => {\n\tconsole.error('Fatal error starting MCP server:', error)\n\tprocess.exit(1)\n})\n"],"mappings":"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","names":["result"]}
@@ -2,38 +2,38 @@
2
2
  import {
3
3
  DevServerManager,
4
4
  buildDevServerUrl
5
- } from "./chunk-OVW26FHW.js";
5
+ } from "./chunk-VQ3Y3PVT.js";
6
6
  import {
7
7
  DockerManager
8
8
  } from "./chunk-Z32HPRZF.js";
9
- import "./chunk-2WRD6Y5E.js";
9
+ import "./chunk-5VP2HAWF.js";
10
10
  import {
11
11
  getWorkspacePort
12
- } from "./chunk-YVNG35OW.js";
12
+ } from "./chunk-2Z4VKQND.js";
13
13
  import {
14
14
  IdentifierParser
15
- } from "./chunk-XC5JKRSH.js";
15
+ } from "./chunk-6RKZDUTQ.js";
16
16
  import "./chunk-OLJ54WGW.js";
17
17
  import {
18
18
  GitWorktreeManager
19
- } from "./chunk-D6FU4DLN.js";
19
+ } from "./chunk-LULQYBRA.js";
20
20
  import {
21
21
  openBrowser
22
22
  } from "./chunk-WEBMMJKL.js";
23
- import {
24
- extractSettingsOverrides
25
- } from "./chunk-GYCR2LOU.js";
26
23
  import {
27
24
  ProjectCapabilityDetector
28
25
  } from "./chunk-772N5WCA.js";
29
26
  import "./chunk-K3QGG4O2.js";
27
+ import {
28
+ extractSettingsOverrides
29
+ } from "./chunk-GYCR2LOU.js";
30
30
  import {
31
31
  extractIssueNumber
32
- } from "./chunk-5W44AI63.js";
32
+ } from "./chunk-6FHFHMNF.js";
33
33
  import {
34
34
  SettingsManager
35
- } from "./chunk-MNPKEWBQ.js";
36
- import "./chunk-XIVLGWUX.js";
35
+ } from "./chunk-UVZBZ5IF.js";
36
+ import "./chunk-JDXJIPXR.js";
37
37
  import "./chunk-FTYWGQFM.js";
38
38
  import {
39
39
  logger
@@ -258,4 +258,4 @@ Make sure the project is built (run 'il start' first)`
258
258
  export {
259
259
  OpenCommand
260
260
  };
261
- //# sourceMappingURL=open-6PXNIPXS.js.map
261
+ //# sourceMappingURL=open-BCQSZYAD.js.map
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  IgniteCommand
4
- } from "./chunk-Y2JHYPMX.js";
4
+ } from "./chunk-VG7UFVF2.js";
5
5
  import {
6
6
  StartCommand,
7
7
  launchFirstRunSetup,
8
8
  needsFirstRunSetup
9
- } from "./chunk-R2EFSRKR.js";
10
- import "./chunk-DYLOITSO.js";
11
- import "./chunk-L3P3YJCE.js";
12
- import "./chunk-OIJNBFMP.js";
9
+ } from "./chunk-EBPFEM5X.js";
10
+ import "./chunk-HMMDNIKG.js";
11
+ import "./chunk-RLFS5KHU.js";
12
+ import "./chunk-OSWL7YDO.js";
13
13
  import {
14
14
  preAcceptClaudeTrust
15
15
  } from "./chunk-7UBEHQTP.js";
16
- import "./chunk-YVNG35OW.js";
16
+ import "./chunk-2Z4VKQND.js";
17
17
  import {
18
18
  matchIssueIdentifier
19
- } from "./chunk-XC5JKRSH.js";
19
+ } from "./chunk-6RKZDUTQ.js";
20
20
  import "./chunk-HKEXRZMU.js";
21
21
  import {
22
22
  TelemetryService
@@ -26,29 +26,29 @@ import "./chunk-4E7LCFUG.js";
26
26
  import {
27
27
  generateHarnessMcpConfig,
28
28
  generateIssueManagementMcpConfig
29
- } from "./chunk-CQHHEW2M.js";
29
+ } from "./chunk-5WJN63T4.js";
30
30
  import {
31
31
  AgentManager
32
- } from "./chunk-RP6MHV24.js";
32
+ } from "./chunk-7VSOM25S.js";
33
33
  import {
34
34
  IssueManagementProviderFactory
35
- } from "./chunk-VUIPDX3T.js";
35
+ } from "./chunk-27CQSBUG.js";
36
36
  import "./chunk-4232AHNQ.js";
37
37
  import "./chunk-OLJ54WGW.js";
38
- import "./chunk-D6FU4DLN.js";
38
+ import "./chunk-LULQYBRA.js";
39
39
  import "./chunk-WEBMMJKL.js";
40
- import "./chunk-32D4CWWH.js";
41
- import "./chunk-UMAOVKQX.js";
40
+ import "./chunk-772N5WCA.js";
41
+ import "./chunk-K3QGG4O2.js";
42
+ import "./chunk-R2RGFNR4.js";
43
+ import "./chunk-CSJ7JNJV.js";
42
44
  import {
43
45
  PromptTemplateManager
44
46
  } from "./chunk-LDE6VNG5.js";
45
47
  import "./chunk-GYCR2LOU.js";
46
- import "./chunk-AQUSMNBF.js";
47
- import "./chunk-772N5WCA.js";
48
- import "./chunk-K3QGG4O2.js";
48
+ import "./chunk-CWRQ4NU4.js";
49
49
  import {
50
50
  IssueTrackerFactory
51
- } from "./chunk-ZWXJ7G2C.js";
51
+ } from "./chunk-JIMFSNZI.js";
52
52
  import "./chunk-DMSL5BAP.js";
53
53
  import "./chunk-D4Q7T5KD.js";
54
54
  import "./chunk-KV4NU3RP.js";
@@ -63,13 +63,13 @@ import "./chunk-OIVFHJOA.js";
63
63
  import {
64
64
  detectClaudeCli,
65
65
  launchClaude
66
- } from "./chunk-DDHWZNGL.js";
67
- import "./chunk-5W44AI63.js";
66
+ } from "./chunk-MB4CB7Q4.js";
67
+ import "./chunk-6FHFHMNF.js";
68
68
  import {
69
69
  PlanCommandSettingsSchema,
70
70
  SettingsManager
71
- } from "./chunk-MNPKEWBQ.js";
72
- import "./chunk-XIVLGWUX.js";
71
+ } from "./chunk-UVZBZ5IF.js";
72
+ import "./chunk-JDXJIPXR.js";
73
73
  import {
74
74
  withLogger
75
75
  } from "./chunk-FTYWGQFM.js";
@@ -268,18 +268,18 @@ var PlanCommand = class {
268
268
  * @param reviewer - Optional reviewer provider (defaults to 'none')
269
269
  * @param printOptions - Print mode options for headless/CI execution
270
270
  */
271
- async execute(prompt, model, flags, planner, reviewer, printOptions) {
271
+ async execute(prompt, model, flags, planner, reviewer, printOptions, effort) {
272
272
  const isJsonMode = ((printOptions == null ? void 0 : printOptions.json) ?? false) || ((printOptions == null ? void 0 : printOptions.jsonStream) ?? false);
273
273
  if (isJsonMode) {
274
274
  const jsonLogger = createStderrLogger();
275
- return withLogger(jsonLogger, () => this.executeInternal(prompt, model, flags, planner, reviewer, printOptions));
275
+ return withLogger(jsonLogger, () => this.executeInternal(prompt, model, flags, planner, reviewer, printOptions, effort));
276
276
  }
277
- return this.executeInternal(prompt, model, flags, planner, reviewer, printOptions);
277
+ return this.executeInternal(prompt, model, flags, planner, reviewer, printOptions, effort);
278
278
  }
279
279
  /**
280
280
  * Internal execution method (separated for withLogger wrapping)
281
281
  */
282
- async executeInternal(prompt, model, flags, planner, reviewer, printOptions) {
282
+ async executeInternal(prompt, model, flags, planner, reviewer, printOptions, effort) {
283
283
  var _a, _b;
284
284
  let normalizedPlanner;
285
285
  if (planner) {
@@ -373,6 +373,7 @@ var PlanCommand = class {
373
373
  }
374
374
  }
375
375
  const effectiveModel = model ?? settingsManager.getPlanModel(settings ?? void 0);
376
+ const effectiveEffort = effort ?? settingsManager.getPlanEffort(settings ?? void 0);
376
377
  const effectivePlanner = normalizedPlanner ?? settingsManager.getPlanPlanner(settings ?? void 0);
377
378
  const effectiveReviewer = normalizedReviewer ?? settingsManager.getPlanReviewer(settings ?? void 0);
378
379
  logger.debug("Detected issue provider, model, planner, and reviewer", {
@@ -394,7 +395,7 @@ var PlanCommand = class {
394
395
  );
395
396
  if (shouldRunInit) {
396
397
  logger.info(chalk.bold("Launching iloom init..."));
397
- const { InitCommand } = await import("./init-AMLCFVXG.js");
398
+ const { InitCommand } = await import("./init-LRNRRFFU.js");
398
399
  const initCommand = new InitCommand();
399
400
  await initCommand.execute(
400
401
  "Help the user set up a GitHub repository or Linear project for this project so they can use issue management features. When complete tell the user they can exit to continue the planning session."
@@ -573,7 +574,8 @@ var PlanCommand = class {
573
574
  mcpConfig,
574
575
  addDir: process.cwd(),
575
576
  allowedTools,
576
- ...agents && { agents }
577
+ ...agents && { agents },
578
+ ...effectiveEffort && { effort: effectiveEffort }
577
579
  };
578
580
  if ((printOptions == null ? void 0 : printOptions.outputFormat) !== void 0) {
579
581
  claudeOptions.outputFormat = printOptions.outputFormat;
@@ -743,4 +745,4 @@ ${initialMessage}`;
743
745
  export {
744
746
  PlanCommand
745
747
  };
746
- //# sourceMappingURL=plan-NJVQBBT3.js.map
748
+ //# sourceMappingURL=plan-2LUGSOYG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/plan.ts","../src/lib/HarnessServer.ts"],"sourcesContent":["/* global AbortController, setImmediate */\nimport { logger, createStderrLogger } from '../utils/logger.js'\nimport { withLogger } from '../utils/logger-context.js'\nimport chalk from 'chalk'\nimport { detectClaudeCli, launchClaude } from '../utils/claude.js'\nimport { preAcceptClaudeTrust } from '../utils/claude-trust.js'\nimport { PromptTemplateManager, type TemplateVariables } from '../lib/PromptTemplateManager.js'\nimport { AgentManager } from '../lib/AgentManager.js'\nimport { generateIssueManagementMcpConfig, generateHarnessMcpConfig } from '../utils/mcp.js'\nimport { HarnessServer } from '../lib/HarnessServer.js'\nimport { SettingsManager, PlanCommandSettingsSchema } from '../lib/SettingsManager.js'\nimport type { EffortLevel } from '../types/index.js'\nimport { IssueTrackerFactory } from '../lib/IssueTrackerFactory.js'\nimport { matchIssueIdentifier } from '../utils/IdentifierParser.js'\nimport { IssueManagementProviderFactory } from '../mcp/IssueManagementProviderFactory.js'\nimport { needsFirstRunSetup, launchFirstRunSetup } from '../utils/first-run-setup.js'\nimport type { IssueProvider, ChildIssueResult, DependenciesResult } from '../mcp/types.js'\nimport { promptConfirmation, isInteractiveEnvironment } from '../utils/prompt.js'\nimport { TelemetryService } from '../lib/TelemetryService.js'\nimport { StartCommand } from './start.js'\nimport { IgniteCommand } from './ignite.js'\n\n// Define provider arrays for validation and dynamic flag generation\nconst PLANNER_PROVIDERS = ['claude', 'gemini', 'codex'] as const\nconst REVIEWER_PROVIDERS = ['claude', 'gemini', 'codex', 'none'] as const\n\ntype PlannerProvider = (typeof PLANNER_PROVIDERS)[number]\ntype ReviewerProvider = (typeof REVIEWER_PROVIDERS)[number]\n\n/**\n * Format child issues as a markdown list for inclusion in the prompt\n */\nfunction formatChildIssues(children: ChildIssueResult[], issuePrefix: string): string {\n\tif (children.length === 0) return 'None'\n\treturn children\n\t\t.map(child => `- ${issuePrefix}${child.id}: ${child.title} (${child.state})`)\n\t\t.join('\\n')\n}\n\n/**\n * Format dependencies as a markdown list for inclusion in the prompt\n */\nfunction formatDependencies(dependencies: DependenciesResult, issuePrefix: string): string {\n\tconst lines: string[] = []\n\n\tif (dependencies.blockedBy.length > 0) {\n\t\tlines.push('**Blocked by:**')\n\t\tfor (const dep of dependencies.blockedBy) {\n\t\t\tlines.push(`- ${issuePrefix}${dep.id}: ${dep.title} (${dep.state})`)\n\t\t}\n\t}\n\n\tif (dependencies.blocking.length > 0) {\n\t\tif (lines.length > 0) lines.push('')\n\t\tlines.push('**Blocking:**')\n\t\tfor (const dep of dependencies.blocking) {\n\t\t\tlines.push(`- ${issuePrefix}${dep.id}: ${dep.title} (${dep.state})`)\n\t\t}\n\t}\n\n\treturn lines.length > 0 ? lines.join('\\n') : 'None'\n}\n\n/**\n * Launch interactive planning session with Architect persona\n * Implements the `il plan` command requested in issue #471\n *\n * The Architect persona helps users:\n * - Break epics down into child issues following \"1 issue = 1 loom = 1 PR\" pattern\n * - Think through implementation approaches\n * - Create issues at the end of the planning session using MCP tools\n */\nexport class PlanCommand {\n\tprivate readonly templateManager: PromptTemplateManager\n\tprivate readonly agentManager: AgentManager\n\n\tconstructor(templateManager?: PromptTemplateManager, agentManager?: AgentManager) {\n\t\tthis.templateManager = templateManager ?? new PromptTemplateManager()\n\t\tthis.agentManager = agentManager ?? new AgentManager()\n\t}\n\n\t/**\n\t * Main entry point for the plan command\n\t * @param prompt - Optional initial planning prompt or topic\n\t * @param model - Optional model to use (defaults to 'opus')\n\t * @param flags - Optional flags object controlling permissions and auto-swarm\n\t * @param planner - Optional planner provider (defaults to 'claude')\n\t * @param reviewer - Optional reviewer provider (defaults to 'none')\n\t * @param printOptions - Print mode options for headless/CI execution\n\t */\n\tpublic async execute(\n\t\tprompt?: string,\n\t\tmodel?: string,\n\t\tflags?: {\n\t\t\toneShot?: 'default' | 'noReview' | 'bypassPermissions'\n\t\t\tdangerouslySkipPermissions?: boolean\n\t\t\tautoSwarm?: boolean\n\t\t},\n\t\tplanner?: string,\n\t\treviewer?: string,\n\t\tprintOptions?: {\n\t\t\tprint?: boolean\n\t\t\toutputFormat?: 'json' | 'stream-json' | 'text'\n\t\t\tverbose?: boolean\n\t\t\tjson?: boolean\n\t\t\tjsonStream?: boolean\n\t\t},\n\t\teffort?: EffortLevel\n\t): Promise<void> {\n\t\t// Wrap execution in stderr logger for JSON modes to keep stdout clean\n\t\tconst isJsonMode = (printOptions?.json ?? false) || (printOptions?.jsonStream ?? false)\n\t\tif (isJsonMode) {\n\t\t\tconst jsonLogger = createStderrLogger()\n\t\t\treturn withLogger(jsonLogger, () => this.executeInternal(prompt, model, flags, planner, reviewer, printOptions, effort))\n\t\t}\n\n\t\treturn this.executeInternal(prompt, model, flags, planner, reviewer, printOptions, effort)\n\t}\n\n\t/**\n\t * Internal execution method (separated for withLogger wrapping)\n\t */\n\tprivate async executeInternal(\n\t\tprompt?: string,\n\t\tmodel?: string,\n\t\tflags?: {\n\t\t\toneShot?: 'default' | 'noReview' | 'bypassPermissions'\n\t\t\tdangerouslySkipPermissions?: boolean\n\t\t\tautoSwarm?: boolean\n\t\t},\n\t\tplanner?: string,\n\t\treviewer?: string,\n\t\tprintOptions?: {\n\t\t\tprint?: boolean\n\t\t\toutputFormat?: 'json' | 'stream-json' | 'text'\n\t\t\tverbose?: boolean\n\t\t\tjson?: boolean\n\t\t\tjsonStream?: boolean\n\t\t},\n\t\teffort?: EffortLevel\n\t): Promise<void> {\n\t\t// Validate and normalize planner CLI argument\n\t\tlet normalizedPlanner: PlannerProvider | undefined\n\t\tif (planner) {\n\t\t\tconst normalized = planner.toLowerCase()\n\t\t\tconst result = PlanCommandSettingsSchema.shape.planner.safeParse(normalized)\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(`Invalid planner: \"${planner}\". Allowed values: ${PLANNER_PROVIDERS.join(', ')}`)\n\t\t\t}\n\t\t\tnormalizedPlanner = normalized as PlannerProvider\n\t\t}\n\n\t\t// Validate and normalize reviewer CLI argument\n\t\tlet normalizedReviewer: ReviewerProvider | undefined\n\t\tif (reviewer) {\n\t\t\tconst normalized = reviewer.toLowerCase()\n\t\t\tconst result = PlanCommandSettingsSchema.shape.reviewer.safeParse(normalized)\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(`Invalid reviewer: \"${reviewer}\". Allowed values: ${REVIEWER_PROVIDERS.join(', ')}`)\n\t\t\t}\n\t\t\tnormalizedReviewer = normalized as ReviewerProvider\n\t\t}\n\n\t\tconst resolvedFlags = flags ?? {}\n\t\tconst autoSwarm = resolvedFlags.autoSwarm ?? false\n\n\t\tlogger.debug('PlanCommand.execute() starting', {\n\t\t\tcwd: process.cwd(),\n\t\t\thasPrompt: !!prompt,\n\t\t\tflags: resolvedFlags,\n\t\t\tplanner: normalizedPlanner ?? planner,\n\t\t\treviewer: normalizedReviewer ?? reviewer,\n\t\t})\n\n\t\t// Check for first-run setup (same check as StartCommand)\n\t\tif (process.env.FORCE_FIRST_TIME_SETUP === \"true\" || await needsFirstRunSetup()) {\n\t\t\tawait launchFirstRunSetup()\n\t\t}\n\n\t\tlogger.info(chalk.bold('Starting interactive planning session...'))\n\n\t\t// Check if Claude CLI is available\n\t\tlogger.debug('Checking Claude CLI availability')\n\t\tconst claudeAvailable = await detectClaudeCli()\n\t\tlogger.debug('Claude CLI availability check result', { claudeAvailable })\n\n\t\tif (!claudeAvailable) {\n\t\t\tlogger.error(\n\t\t\t\t\"Claude Code not detected. Please install it: npm install -g @anthropic-ai/claude-code\"\n\t\t\t)\n\t\t\tthrow new Error('Claude Code CLI is required for planning sessions')\n\t\t}\n\n\t\t// Load settings to detect configured issue provider and model\n\t\tconst settingsManager = new SettingsManager()\n\t\tconst settings = await settingsManager.loadSettings()\n\n\t\t// Detect if prompt is an issue number for decomposition mode\n\t\t// Uses shared matchIssueIdentifier() utility to identify issue identifiers:\n\t\t// - Numeric pattern: #123 or 123 (GitHub format)\n\t\t// - Project key pattern: ENG-123, PROJ-456 (requires at least 2 letters before dash)\n\t\tconst identifierMatch = prompt ? matchIssueIdentifier(prompt) : { isIssueIdentifier: false }\n\t\tconst looksLikeIssueIdentifier = identifierMatch.isIssueIdentifier\n\t\tlet decompositionContext: {\n\t\t\tidentifier: string\n\t\t\ttitle: string\n\t\t\tbody: string\n\t\t\tchildren?: ChildIssueResult[]\n\t\t\tdependencies?: DependenciesResult\n\t\t} | null = null\n\n\t\tconst provider = settings ? IssueTrackerFactory.getProviderName(settings) : 'github'\n\t\tconst issuePrefix = provider === 'github' ? '#' : ''\n\n\t\tif (prompt && looksLikeIssueIdentifier) {\n\t\t\t// Validate and fetch issue using issueTracker.detectInputType() pattern from StartCommand\n\t\t\tconst issueTracker = IssueTrackerFactory.create(settings)\n\n\t\t\tlogger.debug('Detected potential issue identifier, validating via issueTracker', { identifier: prompt })\n\n\t\t\t// Use detectInputType to validate the identifier exists (same pattern as StartCommand)\n\t\t\tconst detection = await issueTracker.detectInputType(prompt)\n\n\t\t\tif (detection.type === 'issue' && detection.identifier) {\n\t\t\t\t// Valid issue found - fetch full details for decomposition context\n\t\t\t\tconst issue = await issueTracker.fetchIssue(detection.identifier)\n\t\t\t\tdecompositionContext = {\n\t\t\t\t\tidentifier: String(issue.number),\n\t\t\t\t\ttitle: issue.title,\n\t\t\t\t\tbody: issue.body\n\t\t\t\t}\n\t\t\t\tlogger.info(chalk.dim(`Preparing to create a detailed plan for issue #${decompositionContext.identifier}: ${decompositionContext.title}`))\n\n\t\t\t\t// Fetch existing children and dependencies using MCP provider\n\t\t\t\t// This allows users to resume planning where they left off\n\t\t\t\ttry {\n\t\t\t\t\tconst mcpProvider = IssueManagementProviderFactory.create(provider as IssueProvider, settings ?? undefined)\n\n\t\t\t\t\t// Fetch child issues\n\t\t\t\t\tlogger.debug('Fetching child issues for decomposition context', { identifier: decompositionContext.identifier })\n\t\t\t\t\tconst children = await mcpProvider.getChildIssues({ number: decompositionContext.identifier })\n\t\t\t\t\tif (children.length > 0) {\n\t\t\t\t\t\tdecompositionContext.children = children\n\t\t\t\t\t\tlogger.debug('Found existing child issues', { count: children.length })\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fetch dependencies (both directions)\n\t\t\t\t\tlogger.debug('Fetching dependencies for decomposition context', { identifier: decompositionContext.identifier })\n\t\t\t\t\tconst dependencies = await mcpProvider.getDependencies({\n\t\t\t\t\t\tnumber: decompositionContext.identifier,\n\t\t\t\t\t\tdirection: 'both'\n\t\t\t\t\t})\n\t\t\t\t\tif (dependencies.blocking.length > 0 || dependencies.blockedBy.length > 0) {\n\t\t\t\t\t\tdecompositionContext.dependencies = dependencies\n\t\t\t\t\t\tlogger.debug('Found existing dependencies', {\n\t\t\t\t\t\t\tblocking: dependencies.blocking.length,\n\t\t\t\t\t\t\tblockedBy: dependencies.blockedBy.length\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Log but don't fail - children/dependencies are optional context\n\t\t\t\t\tlogger.debug('Failed to fetch children/dependencies, continuing without them', {\n\t\t\t\t\t\terror: error instanceof Error ? error.message : 'Unknown error'\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Input matched issue pattern but issue not found - treat as regular prompt\n\t\t\t\tlogger.debug('Input matched issue pattern but issue not found, treating as planning topic', {\n\t\t\t\t\tidentifier: prompt,\n\t\t\t\t\tdetectionType: detection.type\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Use CLI model if provided, otherwise use settings (plan.model), defaults to opus\n\t\tconst effectiveModel = model ?? settingsManager.getPlanModel(settings ?? undefined)\n\n\t\t// Get effective effort level (CLI > settings > undefined/defer to Claude Code)\n\t\tconst effectiveEffort = effort ?? settingsManager.getPlanEffort(settings ?? undefined)\n\n\t\t// Get effective planner/reviewer (CLI > settings > default)\n\t\tconst effectivePlanner = normalizedPlanner ?? settingsManager.getPlanPlanner(settings ?? undefined)\n\t\tconst effectiveReviewer = normalizedReviewer ?? settingsManager.getPlanReviewer(settings ?? undefined)\n\n\t\tlogger.debug('Detected issue provider, model, planner, and reviewer', {\n\t\t\tprovider,\n\t\t\teffectiveModel,\n\t\t\teffectivePlanner,\n\t\t\teffectiveReviewer,\n\t\t})\n\n\t\t// Generate MCP config for issue management tools\n\t\t// This will throw if no git remote is configured - offer to run 'il init' as fallback\n\t\tlogger.debug('Generating MCP config for issue management')\n\t\tlet mcpConfig: Record<string, unknown>[]\n\t\ttry {\n\t\t\tmcpConfig = await generateIssueManagementMcpConfig(undefined, undefined, provider, settings ?? undefined)\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\n\n\t\t\t// Check if running in interactive mode - offer to run init\n\t\t\tif (isInteractiveEnvironment()) {\n\t\t\t\tconst shouldRunInit = await promptConfirmation(\n\t\t\t\t\t\"No git repository or remote found. Would you like to run 'il init' to set up?\",\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t\tif (shouldRunInit) {\n\t\t\t\t\t// Dynamically import and run InitCommand\n\t\t\t\t\tlogger.info(chalk.bold('Launching iloom init...'))\n\t\t\t\t\tconst { InitCommand } = await import('./init.js')\n\t\t\t\t\tconst initCommand = new InitCommand()\n\t\t\t\t\tawait initCommand.execute(\n\t\t\t\t\t\t'Help the user set up a GitHub repository or Linear project for this project so they can use issue management features. When complete tell the user they can exit to continue the planning session.'\n\t\t\t\t\t)\n\n\t\t\t\t\t// Retry MCP config generation after init\n\t\t\t\t\tlogger.info(chalk.bold('Retrying planning session setup...'))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmcpConfig = await generateIssueManagementMcpConfig(undefined, undefined, provider, settings ?? undefined)\n\t\t\t\t\t} catch (retryError) {\n\t\t\t\t\t\tconst retryMessage = retryError instanceof Error ? retryError.message : 'Unknown error'\n\t\t\t\t\t\tlogger.error(`Failed to generate MCP config: ${retryMessage}`)\n\t\t\t\t\t\tif (provider === 'github') {\n\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t'GitHub issue management requires a git repository with a GitHub remote configured.'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Cannot start planning session after init: ${retryMessage}. Ensure you are in a git repository with a GitHub remote configured.`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t'Linear issue management requires LINEAR_API_TOKEN to be configured.'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Cannot start planning session after init: ${retryMessage}. Ensure LINEAR_API_TOKEN is configured in settings or environment.`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// User declined init prompt - show provider-specific error messages\n\t\t\t\t\tlogger.error(`Failed to generate MCP config: ${message}`)\n\t\t\t\t\tif (provider === 'github') {\n\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t'GitHub issue management requires a git repository with a GitHub remote configured.'\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot start planning session: ${message}. Ensure you are in a git repository with a GitHub remote configured.`\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t'Linear issue management requires LINEAR_API_TOKEN to be configured.'\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot start planning session: ${message}. Ensure LINEAR_API_TOKEN is configured in settings or environment.`\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Non-interactive mode - show provider-specific error messages\n\t\t\t\tlogger.error(`Failed to generate MCP config: ${message}`)\n\t\t\t\tif (provider === 'github') {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t'GitHub issue management requires a git repository with a GitHub remote configured.'\n\t\t\t\t\t)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot start planning session: ${message}. Ensure you are in a git repository with a GitHub remote configured.`\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t'Linear issue management requires LINEAR_API_TOKEN to be configured.'\n\t\t\t\t\t)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot start planning session: ${message}. Ensure LINEAR_API_TOKEN is configured in settings or environment.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('MCP config generated', {\n\t\t\tserverCount: mcpConfig.length,\n\t\t})\n\n\t\t// --- Auto-swarm harness lifecycle ---\n\t\tlet harness: HarnessServer | null = null\n\t\tlet externalHarness = false\n\t\tlet epicData: { epicIssueNumber: string; childIssues: number[] } | null = null\n\t\tconst controller = autoSwarm ? new AbortController() : null\n\t\tconst autoSwarmStartTime = autoSwarm ? Date.now() : null\n\t\tlet autoSwarmSuccess = false\n\t\tlet autoSwarmPhaseReached: 'plan' | 'start' | 'spin' = 'plan'\n\t\tlet autoSwarmFallbackToNormal = false\n\n\t\tif (autoSwarm) {\n\t\t\tconst autoSwarmSource = decompositionContext ? 'decomposition' : 'fresh'\n\t\t\ttry {\n\t\t\t\tTelemetryService.getInstance().track('auto_swarm.started', {\n\t\t\t\t\tsource: autoSwarmSource,\n\t\t\t\t\tplanner: effectivePlanner,\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tlogger.debug(`Telemetry auto_swarm.started tracking failed: ${error instanceof Error ? error.message : error}`)\n\t\t\t}\n\n\t\t\t// 1. Check for external harness (e.g., VS Code extension provides its own socket)\n\t\t\tconst externalSocket = process.env.ILOOM_HARNESS_SOCKET\n\t\t\texternalHarness = !!externalSocket\n\n\t\t\tif (!externalSocket) {\n\t\t\t\t// 2. Create and start harness server\n\t\t\t\tharness = new HarnessServer()\n\t\t\t\tawait harness.start()\n\t\t\t}\n\n\t\t\tconst socketPath = externalSocket ?? harness?.path\n\t\t\tif (!socketPath) {\n\t\t\t\tthrow new Error('Unexpected: no harness socket path available')\n\t\t\t}\n\n\t\t\t// 3. Register \"done\" handler (only when we own the harness server)\n\t\t\tif (harness) {\n\t\t\t\tharness.registerHandler('done', (data) => {\n\t\t\t\t\tepicData = data as typeof epicData\n\t\t\t\t\tsetImmediate(() => { controller?.abort() })\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'instruction' as const,\n\t\t\t\t\t\tcontent: 'Planning complete. The auto-swarm pipeline will now create the epic workspace and launch swarm mode automatically.',\n\t\t\t\t\t}\n\t\t\t\t}, { idempotent: true })\n\t\t\t}\n\n\t\t\t// 4. Merge harness MCP config\n\t\t\tconst harnessMcpConfig = generateHarnessMcpConfig(socketPath)\n\t\t\tmcpConfig = [...mcpConfig, ...harnessMcpConfig]\n\t\t}\n\n\t\t// Detect VS Code mode\n\t\tconst isVscodeMode = process.env.ILOOM_VSCODE === '1'\n\t\tlogger.debug('VS Code mode detection', { isVscodeMode })\n\n\t\t// Compute template variables for multi-AI provider support\n\t\t// Generate USE_*_PLANNER and USE_*_REVIEWER flags dynamically\n\t\tconst providerFlags = PLANNER_PROVIDERS.reduce((acc, p) => ({\n\t\t\t...acc,\n\t\t\t[`USE_${p.toUpperCase()}_PLANNER`]: effectivePlanner === p,\n\t\t}), {} as Record<string, boolean>)\n\n\t\t// Add reviewer flags (excluding 'none')\n\t\t;(['claude', 'gemini', 'codex'] as const).forEach(p => {\n\t\t\tproviderFlags[`USE_${p.toUpperCase()}_REVIEWER`] = effectiveReviewer === p\n\t\t})\n\n\t\t// Get wave verification setting (default true)\n\t\tconst waveVerification = settingsManager.getPlanWaveVerification(settings ?? undefined)\n\n\t\t// Determine if we're in print/headless mode (needed early for template variables)\n\t\tconst isHeadless = printOptions?.print ?? false\n\n\t\t// Resolve effective flag values once, early, so they can be reused for both\n\t\t// template variables and runtime logic (autonomous-mode gating, permission bypass, etc.).\n\t\t// - oneShot='noReview' or 'bypassPermissions' enables AUTONOMOUS_MODE (skips confirmation gates)\n\t\t// - oneShot='bypassPermissions' also sets permissionMode=bypassPermissions\n\t\t// - dangerouslySkipPermissions sets permissionMode=bypassPermissions without AUTONOMOUS_MODE\n\t\t// - Print/headless mode implies both autonomous and skip-permissions\n\t\tconst effectiveOneShot = isHeadless ? 'bypassPermissions' as const : (resolvedFlags.oneShot ?? 'default')\n\t\tconst effectiveAutonomous = effectiveOneShot === 'noReview' || effectiveOneShot === 'bypassPermissions'\n\t\tconst skipPermissions = effectiveOneShot === 'bypassPermissions' || (resolvedFlags.dangerouslySkipPermissions ?? false)\n\n\t\t// Load plan prompt template with mode-specific variables\n\t\tlogger.debug('Loading plan prompt template')\n\t\tconst templateVariables: TemplateVariables = {\n\t\t\tIS_VSCODE_MODE: isVscodeMode,\n\t\t\tWAVE_VERIFICATION: waveVerification,\n\t\t\tISSUE_TRACKER: provider,\n\t\t\tIS_GITHUB_TRACKER: provider === 'github',\n\t\t\tVCS_PROVIDER: settings?.versionControl?.provider ?? 'github',\n\t\t\tIS_GITHUB_VCS: (settings?.versionControl?.provider ?? 'github') === 'github',\n\t\t\tEXISTING_ISSUE_MODE: !!decompositionContext,\n\t\t\tFRESH_PLANNING_MODE: !decompositionContext,\n\t\t\tPARENT_ISSUE_NUMBER: decompositionContext?.identifier,\n\t\t\tPARENT_ISSUE_TITLE: decompositionContext?.title,\n\t\t\tPARENT_ISSUE_BODY: decompositionContext?.body,\n\t\t\tPARENT_ISSUE_CHILDREN: decompositionContext?.children\n\t\t\t\t? formatChildIssues(decompositionContext.children, issuePrefix)\n\t\t\t\t: undefined,\n\t\t\tPARENT_ISSUE_DEPENDENCIES: decompositionContext?.dependencies\n\t\t\t\t? formatDependencies(decompositionContext.dependencies, issuePrefix)\n\t\t\t\t: undefined,\n\t\t\tPLANNER: effectivePlanner,\n\t\t\tREVIEWER: effectiveReviewer,\n\t\t\tHAS_REVIEWER: effectiveReviewer !== 'none',\n\t\t\tAUTO_SWARM_MODE: autoSwarm,\n\t\t\tAUTONOMOUS_MODE: effectiveAutonomous,\n\t\t\t...providerFlags,\n\t\t}\n\t\tconst architectPrompt = await this.templateManager.getPrompt('plan', templateVariables)\n\t\tlogger.debug('Plan prompt loaded', {\n\t\t\tpromptLength: architectPrompt.length,\n\t\t\tmode: decompositionContext ? 'decomposition' : 'fresh',\n\t\t})\n\n\t\t// Load analyzer agent for research delegation\n\t\tlet agents: Record<string, unknown> | undefined\n\t\ttry {\n\t\t\tagents = await this.agentManager.loadAndPrepare(\n\t\t\t\tsettings ?? undefined,\n\t\t\t\ttemplateVariables,\n\t\t\t\t['iloom-issue-analyzer.md']\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tlogger.warn(`Failed to load agents: ${error instanceof Error ? error.message : 'Unknown error'}`)\n\t\t}\n\n\t\t// Pre-approve issue management tools so the plan agent can use them without prompting\n\t\tconst allowedTools = [\n\t\t\t'mcp__issue_management__get_issue',\n\t\t\t'mcp__issue_management__get_child_issues',\n\t\t\t'mcp__issue_management__create_issue',\n\t\t\t'mcp__issue_management__create_child_issue',\n\t\t\t'mcp__issue_management__create_comment',\n\t\t\t'mcp__issue_management__create_dependency',\n\t\t\t'mcp__issue_management__get_dependencies',\n\t\t\t'mcp__issue_management__remove_dependency',\n\t\t\t...(autoSwarm ? ['mcp__harness__signal'] : []),\n\t\t]\n\n\t\t// Build Claude options\n\t\tconst claudeOptions: Parameters<typeof launchClaude>[1] = {\n\t\t\tmodel: effectiveModel,\n\t\t\theadless: isHeadless,\n\t\t\tappendSystemPrompt: architectPrompt,\n\t\t\tmcpConfig,\n\t\t\taddDir: process.cwd(),\n\t\t\tallowedTools,\n\t\t\t...(agents && { agents }),\n\t\t\t...(effectiveEffort && { effort: effectiveEffort }),\n\t\t}\n\n\t\t// Add output format and verbose options if provided (print mode only)\n\t\tif (printOptions?.outputFormat !== undefined) {\n\t\t\tclaudeOptions.outputFormat = printOptions.outputFormat\n\t\t}\n\t\tif (printOptions?.verbose !== undefined) {\n\t\t\tclaudeOptions.verbose = printOptions.verbose\n\t\t}\n\n\t\t// Add JSON mode if specified (requires print mode)\n\t\tif (printOptions?.json) {\n\t\t\tclaudeOptions.jsonMode = 'json'\n\t\t\tclaudeOptions.outputFormat = 'stream-json' // Force stream-json for parsing\n\t\t} else if (printOptions?.jsonStream) {\n\t\t\tclaudeOptions.jsonMode = 'stream'\n\t\t\tclaudeOptions.outputFormat = 'stream-json' // Force stream-json for streaming\n\t\t}\n\n\t\t// Handle one-shot mode validation: require prompt when running autonomously\n\t\tif (effectiveAutonomous && !isHeadless) {\n\t\t\tif (!prompt) {\n\t\t\t\tthrow new Error('Autonomous mode (--one-shot=noReview, --one-shot=bypassPermissions, --autonomous, or --yolo) requires a prompt or issue identifier (e.g., il plan --autonomous \"add gitlab support\" or il plan --yolo 42)')\n\t\t\t}\n\t\t}\n\n\t\t// Warn when skip-permissions is active\n\t\tif (skipPermissions) {\n\t\t\tif (effectiveAutonomous) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t'Autonomous mode enabled - Claude will skip permission prompts and proceed without user interaction. This could destroy important data or make irreversible changes. Proceeding means you accept this risk.'\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t'Permission bypass enabled - Claude will skip permission prompts. This could destroy important data or make irreversible changes. Proceeding means you accept this risk.'\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('Launching Claude with options', {\n\t\t\toptionKeys: Object.keys(claudeOptions),\n\t\t\theadless: claudeOptions.headless,\n\t\t\thasSystemPrompt: !!claudeOptions.appendSystemPrompt,\n\t\t\taddDir: claudeOptions.addDir,\n\t\t\teffectiveAutonomous,\n\t\t\teffectiveOneShot,\n\t\t\tautoSwarm,\n\t\t\tprint: isHeadless,\n\t\t})\n\n\t\t// Pre-accept Claude Code trust for the working directory\n\t\ttry {\n\t\t\tawait preAcceptClaudeTrust(process.cwd())\n\t\t} catch (error) {\n\t\t\tlogger.warn(`Failed to pre-accept Claude trust: ${error instanceof Error ? error.message : String(error)}`)\n\t\t}\n\n\t\t// Launch Claude in interactive mode\n\t\t// Construct initial message based on mode\n\t\tlet initialMessage: string\n\t\tif (decompositionContext) {\n\t\t\t// Issue decomposition mode - provide context about what to decompose\n\t\t\tinitialMessage = `Break down issue #${decompositionContext.identifier} into child issues.`\n\t\t} else if (prompt) {\n\t\t\t// Fresh planning with user-provided topic\n\t\t\tinitialMessage = prompt\n\t\t} else {\n\t\t\t// Interactive mode - no topic provided\n\t\t\tinitialMessage = 'Help me plan a feature or decompose work into issues.'\n\t\t}\n\n\t\t// Apply autonomous mode wrapper if enabled (includes print mode)\n\t\tif (effectiveAutonomous) {\n\t\t\tinitialMessage = `[AUTONOMOUS MODE]\nProceed through the flow without requiring user interaction. Make and document your assumptions and proceed to create the epic and child issues and dependencies if necessary. This guidance supersedes all previous guidance.\n\n[TOPIC]\n${initialMessage}`\n\t\t}\n\n\t\ttry {\n\t\t\tconst claudeResult = await launchClaude(initialMessage, {\n\t\t\t\t...claudeOptions,\n\t\t\t\t...(skipPermissions && { permissionMode: 'bypassPermissions' as const }),\n\t\t\t\t...(controller && { signal: controller.signal }),\n\t\t\t})\n\n\t\t\t// Check auto-swarm outcome\n\t\t\tif (autoSwarm) {\n\t\t\t\t// When an external harness (e.g., VS Code) owns the socket, it handles\n\t\t\t\t// the \"done\" signal and manages the start/spin pipeline itself.\n\t\t\t\t// The CLI just exits cleanly after the plan phase.\n\t\t\t\tif (externalHarness) {\n\t\t\t\t\tlogger.info(chalk.green('Planning session ended. External harness will manage the pipeline.'))\n\t\t\t\t\tautoSwarmSuccess = true\n\t\t\t\t\tautoSwarmPhaseReached = 'plan'\n\t\t\t\t} else if (!epicData) {\n\t\t\t\t\tthrow new Error('Plan phase exited without completing. The Architect did not signal done.')\n\t\t\t\t} else {\n\t\t\t\t\t// Cast required because TypeScript cannot narrow let variables mutated in closures.\n\t\t\t\t\t// Defensively default childIssues — the data comes from AI-generated signal payloads.\n\t\t\t\t\tconst resolvedEpicData = epicData as { epicIssueNumber: string; childIssues?: number[] }\n\t\t\t\t\tconst epicIssueNumber = resolvedEpicData.epicIssueNumber\n\t\t\t\t\tconst childIssues = resolvedEpicData.childIssues ?? []\n\t\t\t\t\tlogger.info(chalk.green(`Planning complete. Epic issue: #${epicIssueNumber}`))\n\t\t\t\t\tautoSwarmFallbackToNormal = childIssues.length === 0\n\n\t\t\t\t\tconst startCommand = new StartCommand(IssueTrackerFactory.create(settings ?? {}))\n\n\t\t\t\t\tif (childIssues.length === 0) {\n\t\t\t\t\t\t// Zero-children fallback: normal (non-epic) autonomous loom\n\t\t\t\t\t\tlogger.info('No child issues created. Starting as a normal autonomous loom.')\n\t\t\t\t\t\tlet startResult\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tstartResult = await startCommand.execute({\n\t\t\t\t\t\t\t\tidentifier: String(epicIssueNumber),\n\t\t\t\t\t\t\t\toptions: { oneShot: 'bypassPermissions', json: true, claude: false, code: false, devServer: false, terminal: false },\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} catch (startError) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Auto-swarm: failed to create epic workspace. ${startError instanceof Error ? startError.message : String(startError)}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst epicWorktreePath = startResult?.path\n\t\t\t\t\t\tif (!epicWorktreePath) {\n\t\t\t\t\t\t\tthrow new Error('Auto-swarm: StartCommand did not return a workspace path.')\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst igniteCommand = new IgniteCommand()\n\t\t\t\t\t\tawait igniteCommand.execute('bypassPermissions', undefined, undefined, epicWorktreePath)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Epic mode: start + spin with swarm\n\t\t\t\t\t\tlet startResult\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tstartResult = await startCommand.execute({\n\t\t\t\t\t\t\t\tidentifier: String(epicIssueNumber),\n\t\t\t\t\t\t\t\toptions: { epic: true, json: true, oneShot: 'bypassPermissions', claude: false, code: false, devServer: false, terminal: false },\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} catch (startError) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Auto-swarm: failed to create epic workspace. ${startError instanceof Error ? startError.message : String(startError)}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst epicWorktreePath = startResult?.path\n\t\t\t\t\t\tif (!epicWorktreePath) {\n\t\t\t\t\t\t\tthrow new Error('Auto-swarm: StartCommand did not return a workspace path.')\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst igniteCommand = new IgniteCommand()\n\t\t\t\t\t\tawait igniteCommand.execute('bypassPermissions', undefined, undefined, epicWorktreePath)\n\t\t\t\t\t}\n\n\t\t\t\t\tautoSwarmSuccess = true\n\t\t\t\t\tautoSwarmPhaseReached = 'spin'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Track epic.planned telemetry for decomposition sessions\n\t\t\tif (decompositionContext) {\n\t\t\t\ttry {\n\t\t\t\t\tconst mcpProv = IssueManagementProviderFactory.create(provider as IssueProvider, settings ?? undefined)\n\t\t\t\t\tconst children = await mcpProv.getChildIssues({ number: decompositionContext.identifier })\n\t\t\t\t\tTelemetryService.getInstance().track('epic.planned', {\n\t\t\t\t\t\tchild_count: children.length,\n\t\t\t\t\t\ttracker: provider,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.debug(`Telemetry epic.planned tracking failed: ${error instanceof Error ? error.message : error}`)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Output final JSON for --json mode (--json-stream already streamed to stdout)\n\t\t\tif (printOptions?.json) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(JSON.stringify({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: claudeResult ?? ''\n\t\t\t\t}))\n\t\t\t}\n\n\t\t\tlogger.debug('Claude session completed')\n\t\t\tlogger.info(chalk.green('Planning session ended.'))\n\t\t} finally {\n\t\t\tif (harness) {\n\t\t\t\tawait harness.stop()\n\t\t\t}\n\n\t\t\tif (autoSwarm && autoSwarmStartTime !== null) {\n\t\t\t\tconst durationMinutes = (Date.now() - autoSwarmStartTime) / 60000\n\t\t\t\tconst autoSwarmSource = decompositionContext ? 'decomposition' : 'fresh'\n\t\t\t\tconst resolvedEpicData = epicData as { epicIssueNumber: string; childIssues: number[] } | null\n\t\t\t\ttry {\n\t\t\t\t\tTelemetryService.getInstance().track('auto_swarm.completed', {\n\t\t\t\t\t\tsource: autoSwarmSource,\n\t\t\t\t\t\tsuccess: autoSwarmSuccess,\n\t\t\t\t\t\tchild_count: resolvedEpicData?.childIssues.length ?? 0,\n\t\t\t\t\t\tduration_minutes: Math.round(durationMinutes * 10) / 10,\n\t\t\t\t\t\tphase_reached: autoSwarmPhaseReached,\n\t\t\t\t\t\tfallback_to_normal: autoSwarmFallbackToNormal,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.debug(`Telemetry auto_swarm.completed tracking failed: ${error instanceof Error ? error.message : error}`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import net from 'net'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { randomUUID } from 'crypto'\nimport { logger } from '../utils/logger.js'\n\nexport interface HarnessMessage {\n\ttype: string\n\tdata?: unknown\n}\n\nexport interface HarnessResponse {\n\ttype: 'instruction' | 'acknowledged' | 'error'\n\tcontent?: string\n}\n\nexport type HarnessHandler = (data: unknown) => HarnessResponse | Promise<HarnessResponse>\n\nexport interface HarnessServerOptions {\n\tsocketPath?: string\n}\n\nexport class HarnessServer {\n\tprivate server: net.Server | null = null\n\tprivate readonly socketPath: string\n\tprivate readonly handlers: Map<string, HarnessHandler> = new Map()\n\tprivate readonly idempotentTypes: Set<string> = new Set()\n\tprivate readonly handledTypes: Set<string> = new Set()\n\tprivate readonly connections: Set<net.Socket> = new Set()\n\tprivate readonly waiters: Map<string, Array<(data: unknown) => void>> = new Map()\n\tprivate readonly boundSignalHandler: (signal: NodeJS.Signals) => void\n\n\tconstructor(options: HarnessServerOptions = {}) {\n\t\tthis.socketPath =\n\t\t\toptions.socketPath ??\n\t\t\tpath.join(os.tmpdir(), `iloom-harness-${randomUUID()}.sock`)\n\t\tthis.boundSignalHandler = (signal: NodeJS.Signals): void => {\n\t\t\tvoid this.stop().finally(() => {\n\t\t\t\t// Re-raise so the default handler terminates the process\n\t\t\t\tprocess.kill(process.pid, signal)\n\t\t\t})\n\t\t}\n\t}\n\n\tget path(): string {\n\t\treturn this.socketPath\n\t}\n\n\tregisterHandler(type: string, handler: HarnessHandler, options?: { idempotent?: boolean }): void {\n\t\tthis.handlers.set(type, handler)\n\t\tif (options?.idempotent) {\n\t\t\tthis.idempotentTypes.add(type)\n\t\t}\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (this.server !== null) {\n\t\t\tthrow new Error('HarnessServer is already started')\n\t\t}\n\n\t\t// Remove stale socket file from crashed previous runs\n\t\tfs.rmSync(this.socketPath, { force: true })\n\n\t\tconst server = net.createServer((socket) => {\n\t\t\tthis.handleConnection(socket)\n\t\t})\n\t\tthis.server = server\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.listen(this.socketPath, () => resolve())\n\t\t\tserver.once('error', reject)\n\t\t})\n\n\t\t// Set socket to owner read/write only\n\t\tfs.chmodSync(this.socketPath, 0o600)\n\n\t\t// Register signal handlers for cleanup on process exit\n\t\tprocess.on('SIGINT', this.boundSignalHandler)\n\t\tprocess.on('SIGTERM', this.boundSignalHandler)\n\n\t\tlogger.debug(`HarnessServer listening on ${this.socketPath}`)\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tif (this.server === null) {\n\t\t\treturn\n\t\t}\n\n\t\t// Destroy all active connections so the server can close\n\t\tfor (const socket of this.connections) {\n\t\t\tsocket.destroy()\n\t\t}\n\t\tthis.connections.clear()\n\n\t\t// Close the server (set to null first for idempotency guard)\n\t\tconst serverToClose = this.server\n\t\tthis.server = null\n\n\t\ttry {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tserverToClose.close((err) => {\n\t\t\t\t\tif (err) reject(err)\n\t\t\t\t\telse resolve()\n\t\t\t\t})\n\t\t\t})\n\t\t} finally {\n\t\t\t// Cleanup must run even if server.close() rejects\n\t\t\tfs.rmSync(this.socketPath, { force: true })\n\t\t\tthis.waiters.clear()\n\t\t\tprocess.off('SIGINT', this.boundSignalHandler)\n\t\t\tprocess.off('SIGTERM', this.boundSignalHandler)\n\t\t\tlogger.debug('HarnessServer stopped')\n\t\t}\n\t}\n\n\twaitFor(type: string): Promise<unknown> {\n\t\treturn new Promise<unknown>((resolve) => {\n\t\t\tconst resolvers = this.waiters.get(type) ?? []\n\t\t\tresolvers.push(resolve)\n\t\t\tthis.waiters.set(type, resolvers)\n\t\t})\n\t}\n\n\tprivate handleConnection(socket: net.Socket): void {\n\t\tthis.connections.add(socket)\n\t\tlet buffer = ''\n\t\tconst MAX_BUFFER_SIZE = 1024 * 1024 // 1MB\n\n\t\tsocket.on('data', (chunk: Buffer) => {\n\t\t\tbuffer += chunk.toString()\n\t\t\tif (buffer.length > MAX_BUFFER_SIZE) {\n\t\t\t\tsocket.destroy(new Error('Payload too large'))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst lines = buffer.split('\\n')\n\t\t\t// Keep the last potentially incomplete segment in the buffer\n\t\t\tbuffer = lines.pop() ?? ''\n\t\t\tfor (const line of lines) {\n\t\t\t\tconst trimmed = line.trim()\n\t\t\t\tif (trimmed) {\n\t\t\t\t\tvoid this.processMessage(trimmed, socket)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tsocket.on('close', () => {\n\t\t\tthis.connections.delete(socket)\n\t\t})\n\n\t\tsocket.on('error', (err: Error) => {\n\t\t\tlogger.debug(`HarnessServer socket error: ${err.message}`)\n\t\t})\n\t}\n\n\tprivate async processMessage(raw: string, socket: net.Socket): Promise<void> {\n\t\tlet message: HarnessMessage\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(raw)\n\t\t\tif (!parsed || typeof parsed !== 'object' || typeof (parsed as Record<string, unknown>).type !== 'string') {\n\t\t\t\tthis.sendResponse(socket, { type: 'error', content: 'Invalid message format' })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmessage = parsed as HarnessMessage\n\t\t} catch {\n\t\t\tthis.sendResponse(socket, { type: 'error', content: 'Malformed JSON' })\n\t\t\treturn\n\t\t}\n\n\t\t// Resolve any waiters registered for this message type\n\t\tconst resolvers = this.waiters.get(message.type)\n\t\tif (resolvers && resolvers.length > 0) {\n\t\t\tthis.waiters.delete(message.type)\n\t\t\tfor (const resolve of resolvers) {\n\t\t\t\tresolve(message.data)\n\t\t\t}\n\t\t}\n\n\t\t// Idempotent handling: only applies to handlers registered with { idempotent: true }\n\t\tif (this.idempotentTypes.has(message.type) && this.handledTypes.has(message.type)) {\n\t\t\tthis.sendResponse(socket, { type: 'acknowledged' })\n\t\t\treturn\n\t\t}\n\n\t\t// No handler registered for this type\n\t\tconst handler = this.handlers.get(message.type)\n\t\tif (!handler) {\n\t\t\tthis.sendResponse(socket, {\n\t\t\t\ttype: 'error',\n\t\t\t\tcontent: `No handler registered for type: ${message.type}`,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\t// Mark as handled before calling handler (only for idempotent types)\n\t\tif (this.idempotentTypes.has(message.type)) {\n\t\t\tthis.handledTypes.add(message.type)\n\t\t}\n\t\tconst response = await handler(message.data)\n\t\tthis.sendResponse(socket, response)\n\t}\n\n\tprivate sendResponse(socket: net.Socket, response: HarnessResponse): void {\n\t\tsocket.write(JSON.stringify(response) + '\\n')\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  import "./chunk-K3QGG4O2.js";
6
6
  import {
7
7
  MetadataManager
8
- } from "./chunk-XIVLGWUX.js";
8
+ } from "./chunk-JDXJIPXR.js";
9
9
  import {
10
10
  getLogger
11
11
  } from "./chunk-FTYWGQFM.js";
@@ -100,4 +100,4 @@ var ProjectsCommand = class {
100
100
  export {
101
101
  ProjectsCommand
102
102
  };
103
- //# sourceMappingURL=projects-3F6T3KZL.js.map
103
+ //# sourceMappingURL=projects-INTNTWRM.js.map