@iloom/cli 0.4.1 → 0.5.0

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 (115) hide show
  1. package/README.md +24 -0
  2. package/dist/{ClaudeContextManager-DK77227F.js → ClaudeContextManager-DQFKIMEP.js} +5 -5
  3. package/dist/{ClaudeService-W3SA7HVG.js → ClaudeService-CJS32WG2.js} +4 -4
  4. package/dist/{LoomLauncher-S3YGJRJQ.js → LoomLauncher-4UG2E4CD.js} +19 -24
  5. package/dist/LoomLauncher-4UG2E4CD.js.map +1 -0
  6. package/dist/MetadataManager-WXUVXKUS.js +10 -0
  7. package/dist/PRManager-7DSIMCAD.js +16 -0
  8. package/dist/{PromptTemplateManager-2TDZAUC6.js → PromptTemplateManager-72FEOGT6.js} +2 -2
  9. package/dist/README.md +24 -0
  10. package/dist/{SettingsManager-FJFU6JJD.js → SettingsManager-XPR4TEQL.js} +2 -2
  11. package/dist/agents/iloom-issue-analyze-and-plan.md +41 -7
  12. package/dist/agents/iloom-issue-analyzer.md +38 -8
  13. package/dist/agents/iloom-issue-complexity-evaluator.md +45 -15
  14. package/dist/agents/iloom-issue-enhancer.md +60 -18
  15. package/dist/agents/iloom-issue-implementer.md +29 -7
  16. package/dist/agents/iloom-issue-planner.md +36 -7
  17. package/dist/agents/iloom-issue-reviewer.md +30 -7
  18. package/dist/{chunk-JC5HXN75.js → chunk-3CMGCRB5.js} +2 -2
  19. package/dist/{chunk-G6CIIJLT.js → chunk-4YTILIIH.js} +7 -8
  20. package/dist/chunk-4YTILIIH.js.map +1 -0
  21. package/dist/{chunk-55TB3FSG.js → chunk-AS2IRKLU.js} +2 -2
  22. package/dist/{chunk-POI7KLBH.js → chunk-CDQEK2WD.js} +5 -5
  23. package/dist/{chunk-74VMN2KC.js → chunk-DKQ4SUII.js} +16 -1
  24. package/dist/chunk-DKQ4SUII.js.map +1 -0
  25. package/dist/{chunk-BIIQHEXJ.js → chunk-GVRO4PWE.js} +12 -8
  26. package/dist/chunk-GVRO4PWE.js.map +1 -0
  27. package/dist/{chunk-TMZAVPGF.js → chunk-HABINPX2.js} +71 -15
  28. package/dist/{chunk-TMZAVPGF.js.map → chunk-HABINPX2.js.map} +1 -1
  29. package/dist/{chunk-2W2FBL5G.js → chunk-LN4H3A6A.js} +66 -7
  30. package/dist/chunk-LN4H3A6A.js.map +1 -0
  31. package/dist/{chunk-VWNS6DH5.js → chunk-OOU3DKNT.js} +13 -7
  32. package/dist/chunk-OOU3DKNT.js.map +1 -0
  33. package/dist/chunk-P2ZQ5LKB.js +347 -0
  34. package/dist/chunk-P2ZQ5LKB.js.map +1 -0
  35. package/dist/{chunk-HD5SUKI2.js → chunk-RFUOIUQF.js} +49 -6
  36. package/dist/{chunk-HD5SUKI2.js.map → chunk-RFUOIUQF.js.map} +1 -1
  37. package/dist/{chunk-OF7BNW4D.js → chunk-RJKMF6BC.js} +30 -4
  38. package/dist/chunk-RJKMF6BC.js.map +1 -0
  39. package/dist/{chunk-O7WHXLCB.js → chunk-RNZMHJK7.js} +18 -4
  40. package/dist/chunk-RNZMHJK7.js.map +1 -0
  41. package/dist/{chunk-UPUAQYAW.js → chunk-S65T4O6I.js} +2 -2
  42. package/dist/{chunk-IARWMDAX.js → chunk-T5IIUG4Z.js} +98 -16
  43. package/dist/chunk-T5IIUG4Z.js.map +1 -0
  44. package/dist/{chunk-IJ7IGJT3.js → chunk-YZTDGPFB.js} +18 -1
  45. package/dist/chunk-YZTDGPFB.js.map +1 -0
  46. package/dist/{cleanup-KDLVTT7M.js → cleanup-MIDJVSIU.js} +14 -14
  47. package/dist/cli.js +228 -354
  48. package/dist/cli.js.map +1 -1
  49. package/dist/{contribute-HY372S6F.js → contribute-RS3DO3WP.js} +4 -4
  50. package/dist/{dev-server-JCJGQ3PV.js → dev-server-ASH7HJVI.js} +30 -16
  51. package/dist/dev-server-ASH7HJVI.js.map +1 -0
  52. package/dist/{feedback-7PVBQNLJ.js → feedback-RVIGHBJG.js} +5 -4
  53. package/dist/{feedback-7PVBQNLJ.js.map → feedback-RVIGHBJG.js.map} +1 -1
  54. package/dist/{git-4BVOOOOV.js → git-OQAPUPLP.js} +16 -6
  55. package/dist/git-OQAPUPLP.js.map +1 -0
  56. package/dist/{ignite-3B264M7K.js → ignite-XJALWFAT.js} +57 -22
  57. package/dist/ignite-XJALWFAT.js.map +1 -0
  58. package/dist/index.d.ts +58 -7
  59. package/dist/index.js +104 -7
  60. package/dist/index.js.map +1 -1
  61. package/dist/{init-LBA6NUK2.js → init-F6PFMSU5.js} +7 -7
  62. package/dist/init-F6PFMSU5.js.map +1 -0
  63. package/dist/mcp/recap-server.js +264 -0
  64. package/dist/mcp/recap-server.js.map +1 -0
  65. package/dist/{open-OGCV32Z4.js → open-KW4NTLXH.js} +16 -17
  66. package/dist/{open-OGCV32Z4.js.map → open-KW4NTLXH.js.map} +1 -1
  67. package/dist/{projects-P55273AB.js → projects-QEAEBAT2.js} +2 -2
  68. package/dist/prompts/init-prompt.txt +31 -72
  69. package/dist/prompts/issue-prompt.txt +115 -15
  70. package/dist/prompts/pr-prompt.txt +49 -1
  71. package/dist/prompts/regular-prompt.txt +80 -20
  72. package/dist/{rebase-4T5FQHNH.js → rebase-WZHHE5LU.js} +6 -6
  73. package/dist/recap-33NPZ3ZO.js +117 -0
  74. package/dist/recap-33NPZ3ZO.js.map +1 -0
  75. package/dist/{run-HNOP6WE2.js → run-HRYQ7TR7.js} +16 -17
  76. package/dist/{run-HNOP6WE2.js.map → run-HRYQ7TR7.js.map} +1 -1
  77. package/dist/schema/settings.schema.json +13 -2
  78. package/dist/{shell-DE3HKJSM.js → shell-JMU5XTHW.js} +6 -6
  79. package/dist/{summary-GDT7DTRI.js → summary-4SSGGH7N.js} +17 -9
  80. package/dist/summary-4SSGGH7N.js.map +1 -0
  81. package/dist/{test-git-YMAE57UP.js → test-git-6SAIRBUD.js} +4 -4
  82. package/dist/{test-prefix-YCKL6CMT.js → test-prefix-RLVRK5ZD.js} +4 -4
  83. package/package.json +1 -1
  84. package/dist/LoomLauncher-S3YGJRJQ.js.map +0 -1
  85. package/dist/chunk-2W2FBL5G.js.map +0 -1
  86. package/dist/chunk-74VMN2KC.js.map +0 -1
  87. package/dist/chunk-BIIQHEXJ.js.map +0 -1
  88. package/dist/chunk-G6CIIJLT.js.map +0 -1
  89. package/dist/chunk-IARWMDAX.js.map +0 -1
  90. package/dist/chunk-IJ7IGJT3.js.map +0 -1
  91. package/dist/chunk-O7WHXLCB.js.map +0 -1
  92. package/dist/chunk-OF7BNW4D.js.map +0 -1
  93. package/dist/chunk-QRBOPFAA.js +0 -48
  94. package/dist/chunk-QRBOPFAA.js.map +0 -1
  95. package/dist/chunk-VWNS6DH5.js.map +0 -1
  96. package/dist/dev-server-JCJGQ3PV.js.map +0 -1
  97. package/dist/ignite-3B264M7K.js.map +0 -1
  98. package/dist/summary-GDT7DTRI.js.map +0 -1
  99. /package/dist/{ClaudeContextManager-DK77227F.js.map → ClaudeContextManager-DQFKIMEP.js.map} +0 -0
  100. /package/dist/{ClaudeService-W3SA7HVG.js.map → ClaudeService-CJS32WG2.js.map} +0 -0
  101. /package/dist/{PromptTemplateManager-2TDZAUC6.js.map → MetadataManager-WXUVXKUS.js.map} +0 -0
  102. /package/dist/{SettingsManager-FJFU6JJD.js.map → PRManager-7DSIMCAD.js.map} +0 -0
  103. /package/dist/{git-4BVOOOOV.js.map → PromptTemplateManager-72FEOGT6.js.map} +0 -0
  104. /package/dist/{init-LBA6NUK2.js.map → SettingsManager-XPR4TEQL.js.map} +0 -0
  105. /package/dist/{chunk-JC5HXN75.js.map → chunk-3CMGCRB5.js.map} +0 -0
  106. /package/dist/{chunk-55TB3FSG.js.map → chunk-AS2IRKLU.js.map} +0 -0
  107. /package/dist/{chunk-POI7KLBH.js.map → chunk-CDQEK2WD.js.map} +0 -0
  108. /package/dist/{chunk-UPUAQYAW.js.map → chunk-S65T4O6I.js.map} +0 -0
  109. /package/dist/{cleanup-KDLVTT7M.js.map → cleanup-MIDJVSIU.js.map} +0 -0
  110. /package/dist/{contribute-HY372S6F.js.map → contribute-RS3DO3WP.js.map} +0 -0
  111. /package/dist/{projects-P55273AB.js.map → projects-QEAEBAT2.js.map} +0 -0
  112. /package/dist/{rebase-4T5FQHNH.js.map → rebase-WZHHE5LU.js.map} +0 -0
  113. /package/dist/{shell-DE3HKJSM.js.map → shell-JMU5XTHW.js.map} +0 -0
  114. /package/dist/{test-git-YMAE57UP.js.map → test-git-6SAIRBUD.js.map} +0 -0
  115. /package/dist/{test-prefix-YCKL6CMT.js.map → test-prefix-RLVRK5ZD.js.map} +0 -0
package/README.md CHANGED
@@ -232,6 +232,30 @@ This example shows how to configure a project-wide default (e.g., GitHub remote)
232
232
  }
233
233
  ```
234
234
 
235
+ ### Merge Behavior
236
+
237
+ Control how `il finish` handles your work. Configure in `.iloom/settings.json`:
238
+
239
+ ```json
240
+ {
241
+ "mergeBehavior": {
242
+ "mode": "local" // "local", "github-pr", or "github-draft-pr"
243
+ }
244
+ }
245
+ ```
246
+
247
+ | **Mode** | **Description** |
248
+ |----------|-----------------|
249
+ | `local` | (Default) Merge directly into main branch locally. Fast-forward merge, no PR created. |
250
+ | `github-pr` | Push branch and create a GitHub PR on `il finish`. Worktree cleanup is optional. |
251
+ | `github-draft-pr` | Create a draft PR immediately on `il start`. On `il finish`, the PR is marked ready for review. **Recommended for contributions to forked repos.** |
252
+
253
+ **When to use `github-draft-pr`:**
254
+ - **Contributing to forks:** When you don't are contributing to a forked repo use this mode to create the PR from your fork immediately, allowing iloom's agents to post workflow comments directly to the PR instead of writing to the upstream repo's issues (which may not be appreciated by the repo owners).
255
+ - CI runs on your branch during development (draft PRs trigger CI on most repos)
256
+ - Your team requires PRs for all changes (no direct merges to main)
257
+ - You want reviewers to see progress before the work is complete
258
+
235
259
  Integrations
236
260
  ------------
237
261
 
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ClaudeContextManager
4
- } from "./chunk-UPUAQYAW.js";
5
- import "./chunk-POI7KLBH.js";
6
- import "./chunk-VWNS6DH5.js";
4
+ } from "./chunk-S65T4O6I.js";
5
+ import "./chunk-CDQEK2WD.js";
6
+ import "./chunk-DKQ4SUII.js";
7
+ import "./chunk-OOU3DKNT.js";
7
8
  import "./chunk-RUC7OULH.js";
8
9
  import "./chunk-VAYGNQTE.js";
9
10
  import "./chunk-Z5NXYJIG.js";
10
11
  import "./chunk-6UIGZD2N.js";
11
- import "./chunk-74VMN2KC.js";
12
12
  import "./chunk-UYVWLISQ.js";
13
13
  export {
14
14
  ClaudeContextManager
15
15
  };
16
- //# sourceMappingURL=ClaudeContextManager-DK77227F.js.map
16
+ //# sourceMappingURL=ClaudeContextManager-DQFKIMEP.js.map
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ClaudeService
4
- } from "./chunk-POI7KLBH.js";
5
- import "./chunk-VWNS6DH5.js";
4
+ } from "./chunk-CDQEK2WD.js";
5
+ import "./chunk-DKQ4SUII.js";
6
+ import "./chunk-OOU3DKNT.js";
6
7
  import "./chunk-RUC7OULH.js";
7
8
  import "./chunk-VAYGNQTE.js";
8
9
  import "./chunk-Z5NXYJIG.js";
9
10
  import "./chunk-6UIGZD2N.js";
10
- import "./chunk-74VMN2KC.js";
11
11
  import "./chunk-UYVWLISQ.js";
12
12
  export {
13
13
  ClaudeService
14
14
  };
15
- //# sourceMappingURL=ClaudeService-W3SA7HVG.js.map
15
+ //# sourceMappingURL=ClaudeService-CJS32WG2.js.map
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- getDevServerLaunchCommand
4
- } from "./chunk-QRBOPFAA.js";
5
- import "./chunk-VBFDVGAE.js";
6
2
  import {
7
3
  ClaudeContextManager
8
- } from "./chunk-UPUAQYAW.js";
9
- import "./chunk-POI7KLBH.js";
4
+ } from "./chunk-S65T4O6I.js";
5
+ import "./chunk-CDQEK2WD.js";
6
+ import "./chunk-DKQ4SUII.js";
10
7
  import {
11
8
  getExecutablePath
12
9
  } from "./chunk-GYCR2LOU.js";
13
- import "./chunk-VWNS6DH5.js";
10
+ import "./chunk-OOU3DKNT.js";
14
11
  import {
15
12
  generateColorFromBranchName,
16
13
  hexToRgb
@@ -26,7 +23,6 @@ import {
26
23
  import {
27
24
  getLogger
28
25
  } from "./chunk-6UIGZD2N.js";
29
- import "./chunk-74VMN2KC.js";
30
26
  import {
31
27
  logger
32
28
  } from "./chunk-UYVWLISQ.js";
@@ -118,7 +114,7 @@ var LoomLauncher = class {
118
114
  if (enableDevServer) {
119
115
  terminalsToLaunch.push({
120
116
  type: "devServer",
121
- options: await this.buildDevServerTerminalOptions(options)
117
+ options: this.buildDevServerTerminalOptions(options)
122
118
  });
123
119
  }
124
120
  if (enableTerminal) {
@@ -182,19 +178,19 @@ var LoomLauncher = class {
182
178
  }
183
179
  /**
184
180
  * Launch dev server terminal
181
+ * Runs `il dev-server [identifier]` which handles env loading internally
185
182
  */
186
183
  async launchDevServerTerminal(options) {
187
- const devServerCommand = await getDevServerLaunchCommand(
188
- options.worktreePath,
189
- options.port,
190
- options.capabilities
191
- );
184
+ const executable = options.executablePath ?? getExecutablePath();
185
+ const devServerIdentifier = String(options.identifier);
186
+ const devServerCommand = `${executable} dev-server ${devServerIdentifier}`;
192
187
  const backgroundColor = options.colorTerminal ?? true ? options.colorHex ? hexToRgb(options.colorHex) : generateColorFromBranchName(options.branchName).rgb : void 0;
193
188
  await openTerminalWindow({
194
189
  workspacePath: options.worktreePath,
195
190
  command: devServerCommand,
196
191
  ...backgroundColor && { backgroundColor },
197
- includeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),
192
+ // il dev-server handles env loading internally, so no includeEnvSetup
193
+ includeEnvSetup: false,
198
194
  includePortExport: options.capabilities.includes("web"),
199
195
  ...options.port !== void 0 && { port: options.port }
200
196
  });
@@ -247,14 +243,12 @@ var LoomLauncher = class {
247
243
  }
248
244
  /**
249
245
  * Build terminal options for dev server
246
+ * Uses `il dev-server [identifier]` which handles env loading internally
250
247
  */
251
- async buildDevServerTerminalOptions(options) {
252
- const devServerCommand = await getDevServerLaunchCommand(
253
- options.worktreePath,
254
- options.port,
255
- options.capabilities
256
- );
257
- const hasEnvFile = this.hasAnyEnvFiles(options.worktreePath);
248
+ buildDevServerTerminalOptions(options) {
249
+ const executable = options.executablePath ?? getExecutablePath();
250
+ const devServerIdentifier = String(options.identifier);
251
+ const devServerCommand = `${executable} dev-server ${devServerIdentifier}`;
258
252
  const devServerTitle = `Dev Server - ${this.formatIdentifier(options.workflowType, options.identifier)}`;
259
253
  const backgroundColor = options.colorTerminal ?? true ? options.colorHex ? hexToRgb(options.colorHex) : generateColorFromBranchName(options.branchName).rgb : void 0;
260
254
  return {
@@ -262,7 +256,8 @@ var LoomLauncher = class {
262
256
  command: devServerCommand,
263
257
  ...backgroundColor && { backgroundColor },
264
258
  title: devServerTitle,
265
- includeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,
259
+ // il dev-server handles env loading internally
260
+ includeEnvSetup: false,
266
261
  includePortExport: options.capabilities.includes("web"),
267
262
  ...options.port !== void 0 && { port: options.port }
268
263
  };
@@ -321,4 +316,4 @@ var LoomLauncher = class {
321
316
  export {
322
317
  LoomLauncher
323
318
  };
324
- //# sourceMappingURL=LoomLauncher-S3YGJRJQ.js.map
319
+ //# sourceMappingURL=LoomLauncher-4UG2E4CD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/LoomLauncher.ts","../src/utils/ide.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { openTerminalWindow, openMultipleTerminalWindows } from '../utils/terminal.js'\nimport type { TerminalWindowOptions } from '../utils/terminal.js'\nimport { openIdeWindow } from '../utils/ide.js'\nimport { generateColorFromBranchName, hexToRgb } from '../utils/color.js'\nimport { getLogger } from '../utils/logger-context.js'\nimport { ClaudeContextManager } from './ClaudeContextManager.js'\nimport type { SettingsManager } from './SettingsManager.js'\nimport type { Capability } from '../types/loom.js'\nimport { getDotenvFlowFiles } from '../utils/env.js'\nimport { getExecutablePath } from '../utils/cli-overrides.js'\n\nexport interface LaunchLoomOptions {\n\tenableClaude: boolean\n\tenableCode: boolean\n\tenableDevServer: boolean\n\tenableTerminal: boolean\n\tworktreePath: string\n\tbranchName: string\n\tport?: number\n\tcapabilities: Capability[]\n\tworkflowType: 'issue' | 'pr' | 'regular'\n\tidentifier: string | number\n\ttitle?: string\n\toneShot?: import('../types/index.js').OneShotMode\n\tsetArguments?: string[] // Raw --set arguments to forward\n\texecutablePath?: string // Executable path to use for spin command\n\tsourceEnvOnStart?: boolean // defaults to false if undefined\n\tcolorTerminal?: boolean // defaults to true if undefined\n\tcolorHex?: string // Pre-calculated hex color from metadata, avoids recalculation\n}\n\n/**\n * LoomLauncher orchestrates opening loom components\n */\nexport class LoomLauncher {\n\tprivate claudeContext: ClaudeContextManager\n\tprivate settings?: SettingsManager\n\n\tconstructor(claudeContext?: ClaudeContextManager, settings?: SettingsManager) {\n\t\tthis.claudeContext = claudeContext ?? new ClaudeContextManager()\n\t\tif (settings !== undefined) {\n\t\t\tthis.settings = settings\n\t\t}\n\t}\n\n\t/**\n\t * Launch loom components based on individual flags\n\t */\n\tasync launchLoom(options: LaunchLoomOptions): Promise<void> {\n\t\tconst { enableClaude, enableCode, enableDevServer, enableTerminal } = options\n\n\t\tgetLogger().debug(`Launching loom components: Claude=${enableClaude}, Code=${enableCode}, DevServer=${enableDevServer}, Terminal=${enableTerminal}`)\n\n\t\tconst launchPromises: Promise<void>[] = []\n\n\t\t// Launch VSCode if enabled\n\t\tif (enableCode) {\n\t\t\tgetLogger().debug('Launching VSCode')\n\t\t\tlaunchPromises.push(this.launchVSCode(options))\n\t\t}\n\n\t\t// Build array of terminals to launch\n\t\tconst terminalsToLaunch: Array<{\n\t\t\ttype: 'claude' | 'devServer' | 'terminal'\n\t\t\toptions: TerminalWindowOptions\n\t\t}> = []\n\n\t\tif (enableDevServer) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'devServer',\n\t\t\t\toptions: this.buildDevServerTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableTerminal) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'terminal',\n\t\t\t\toptions: this.buildStandaloneTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableClaude) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'claude',\n\t\t\t\toptions: await this.buildClaudeTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\t// Launch terminals based on count\n\t\tif (terminalsToLaunch.length > 1) {\n\t\t\t// Multiple terminals - launch as tabs in single window\n\t\t\tgetLogger().debug(`Launching ${terminalsToLaunch.length} terminals in single window`)\n\t\t\tlaunchPromises.push(this.launchMultipleTerminals(terminalsToLaunch, options))\n\t\t} else if (terminalsToLaunch.length === 1) {\n\t\t\t// Single terminal - launch standalone\n\t\t\tconst terminal = terminalsToLaunch[0]\n\t\t\tif (!terminal) {\n\t\t\t\tthrow new Error('Terminal configuration is undefined')\n\t\t\t}\n\t\t\tconst terminalType = terminal.type\n\t\t\tgetLogger().debug(`Launching single ${terminalType} terminal`)\n\n\t\t\tif (terminalType === 'claude') {\n\t\t\t\tlaunchPromises.push(this.launchClaudeTerminal(options))\n\t\t\t} else if (terminalType === 'devServer') {\n\t\t\t\tlaunchPromises.push(this.launchDevServerTerminal(options))\n\t\t\t} else {\n\t\t\t\tlaunchPromises.push(this.launchStandaloneTerminal(options))\n\t\t\t}\n\t\t}\n\n\t\t// Wait for all components to launch\n\t\tawait Promise.all(launchPromises)\n\n\t\tgetLogger().success('loom launched successfully')\n\t}\n\n\t/**\n\t * Launch IDE (VSCode or configured alternative)\n\t */\n\tprivate async launchVSCode(options: LaunchLoomOptions): Promise<void> {\n\t\tconst ideConfig = await this.settings?.loadSettings().then((s) => s.ide)\n\t\tawait openIdeWindow(options.worktreePath, ideConfig)\n\t\tgetLogger().info('IDE opened')\n\t}\n\n\t/**\n\t * Launch Claude terminal\n\t */\n\tprivate async launchClaudeTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tawait this.claudeContext.launchWithContext({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\ttype: options.workflowType,\n\t\t\tidentifier: options.identifier,\n\t\t\tbranchName: options.branchName,\n\t\t\t...(options.title && { title: options.title }),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t\toneShot: options.oneShot ?? 'default',\n\t\t\t...(options.setArguments && { setArguments: options.setArguments }),\n\t\t\t...(options.executablePath && { executablePath: options.executablePath }),\n\t\t})\n\t\tgetLogger().info('Claude terminal opened')\n\t}\n\n\t/**\n\t * Launch dev server terminal\n\t * Runs `il dev-server [identifier]` which handles env loading internally\n\t */\n\tprivate async launchDevServerTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\t// Build dev-server command with identifier\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst devServerIdentifier = String(options.identifier)\n\t\tconst devServerCommand = `${executable} dev-server ${devServerIdentifier}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\t// il dev-server handles env loading internally, so no includeEnvSetup\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tgetLogger().info('Dev server terminal opened')\n\t}\n\n\t/**\n\t * Launch standalone terminal running `il shell <identifier>`\n\t */\n\tprivate async launchStandaloneTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\t// Build shell command with identifier\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst shellIdentifier = String(options.identifier)\n\t\tconst shellCommand = `${executable} shell ${shellIdentifier}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: shellCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\t// il shell handles env loading internally, so we don't need includeEnvSetup\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tgetLogger().info('Standalone terminal opened')\n\t}\n\n\t/**\n\t * Build terminal options for Claude\n\t */\n\tprivate async buildClaudeTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): Promise<TerminalWindowOptions> {\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst claudeTitle = `Claude - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\tconst executable = options.executablePath ?? 'iloom'\n\t\tlet claudeCommand = `${executable} spin`\n\t\tif (options.oneShot !== undefined && options.oneShot !== 'default') {\n\t\t\tclaudeCommand += ` --one-shot=${options.oneShot}`\n\t\t}\n\t\tif (options.setArguments && options.setArguments.length > 0) {\n\t\t\tfor (const setArg of options.setArguments) {\n\t\t\t\tclaudeCommand += ` --set ${setArg}`\n\t\t\t}\n\t\t}\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: claudeCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: claudeTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\t...(options.port !== undefined && { port: options.port, includePortExport: true }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for dev server\n\t * Uses `il dev-server [identifier]` which handles env loading internally\n\t */\n\tprivate buildDevServerTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): TerminalWindowOptions {\n\t\t// Build dev-server command with identifier\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst devServerIdentifier = String(options.identifier)\n\t\tconst devServerCommand = `${executable} dev-server ${devServerIdentifier}`\n\n\t\tconst devServerTitle = `Dev Server - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: devServerTitle,\n\t\t\t// il dev-server handles env loading internally\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for standalone terminal\n\t * Runs `il shell <identifier>` which handles env loading internally\n\t */\n\tprivate buildStandaloneTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): TerminalWindowOptions {\n\t\tconst terminalTitle = `Terminal - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\t// Build shell command with identifier\n\t\t// Use the same executable path pattern as buildClaudeTerminalOptions\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst shellIdentifier = String(options.identifier)\n\t\tconst shellCommand = `${executable} shell ${shellIdentifier}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: shellCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: terminalTitle,\n\t\t\t// il shell handles env loading internally, so we don't need includeEnvSetup\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Launch multiple terminals (2+) as tabs in single window\n\t */\n\tprivate async launchMultipleTerminals(\n\t\tterminals: Array<{ type: string; options: TerminalWindowOptions }>,\n\t\t_options: LaunchLoomOptions\n\t): Promise<void> {\n\t\tconst terminalOptions = terminals.map((t) => t.options)\n\n\t\tawait openMultipleTerminalWindows(terminalOptions)\n\n\t\tconst terminalTypes = terminals.map((t) => t.type).join(' + ')\n\t\tgetLogger().info(`Multiple terminals opened: ${terminalTypes}`)\n\t}\n\n\t/**\n\t * Check if any dotenv-flow files exist in the workspace\n\t * Checks all files: .env, .env.local, .env.{NODE_ENV}, .env.{NODE_ENV}.local\n\t */\n\tprivate hasAnyEnvFiles(workspacePath: string): boolean {\n\t\tconst envFiles = getDotenvFlowFiles()\n\t\treturn envFiles.some(file => existsSync(join(workspacePath, file)))\n\t}\n\n\t/**\n\t * Format identifier for terminal tab titles\n\t */\n\tprivate formatIdentifier(workflowType: 'issue' | 'pr' | 'regular', identifier: string | number): string {\n\t\tif (workflowType === 'issue') {\n\t\t\treturn `Issue #${identifier}`\n\t\t} else if (workflowType === 'pr') {\n\t\t\treturn `PR #${identifier}`\n\t\t} else {\n\t\t\treturn `Branch: ${identifier}`\n\t\t}\n\t}\n}\n","import { execa } from 'execa'\nimport { logger } from './logger.js'\nimport type { IdeSettings } from '../lib/SettingsManager.js'\n\n// IDE preset configuration\nconst IDE_PRESETS = {\n\tvscode: { command: 'code', name: 'Visual Studio Code', args: [] },\n\tcursor: { command: 'cursor', name: 'Cursor', args: [] },\n\twebstorm: { command: 'webstorm', name: 'WebStorm', args: ['--nosplash'] },\n\tsublime: { command: 'subl', name: 'Sublime Text', args: [] },\n\tintellij: { command: 'idea', name: 'IntelliJ IDEA', args: ['--nosplash'] },\n\twindsurf: { command: 'surf', name: 'Windsurf', args: [] },\n\tantigravity: { command: 'agy', name: 'Antigravity', args: [] },\n} as const\n\ntype IdePreset = keyof typeof IDE_PRESETS\n\n// Resolve IDE configuration to command and args\nexport function getIdeConfig(ideSettings?: IdeSettings): {\n\tcommand: string\n\targs: string[]\n\tname: string\n} {\n\t// Default to vscode if not configured\n\tconst type = ideSettings?.type ?? 'vscode'\n\n\tconst preset = IDE_PRESETS[type as IdePreset]\n\treturn {\n\t\tcommand: preset.command,\n\t\targs: [...preset.args],\n\t\tname: preset.name,\n\t}\n}\n\n// Check if IDE is available\nexport async function isIdeAvailable(command: string): Promise<boolean> {\n\ttry {\n\t\tawait execa('command', ['-v', command], { shell: true, timeout: 5000 })\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// Get installation hint for IDE\nfunction getInstallHint(type: string): string {\n\tconst hints: Record<string, string> = {\n\t\tvscode:\n\t\t\t'Install command-line tools: Open VSCode > Command Palette > \"Shell Command: Install \\'code\\' command in PATH\"',\n\t\tcursor:\n\t\t\t'Install command-line tools: Open Cursor > Command Palette > \"Install \\'cursor\\' command in PATH\"',\n\t\twebstorm: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\tsublime:\n\t\t\t'Create symlink: ln -s \"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl\" /usr/local/bin/subl',\n\t\tintellij: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\twindsurf:\n\t\t\t'Install command-line tools during Windsurf installation or create symlink manually',\n\t\tantigravity:\n\t\t\t'Install command-line tools during Antigravity installation or create symlink manually',\n\t}\n\treturn hints[type] ?? `Ensure the IDE command is available in your PATH`\n}\n\n// Open IDE window for workspace\nexport async function openIdeWindow(\n\tworkspacePath: string,\n\tideSettings?: IdeSettings\n): Promise<void> {\n\tconst config = getIdeConfig(ideSettings)\n\tconst available = await isIdeAvailable(config.command)\n\n\tif (!available) {\n\t\tconst type = ideSettings?.type ?? 'vscode'\n\t\tthrow new Error(\n\t\t\t`${config.name} is not available. The \"${config.command}\" command was not found in PATH.\\n` +\n\t\t\t\tgetInstallHint(type)\n\t\t)\n\t}\n\n\ttry {\n\t\tawait execa(config.command, [...config.args, workspacePath])\n\t\tlogger.debug(`Opened ${config.name} for workspace: ${workspacePath}`)\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to open ${config.name}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t)\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MetadataManager
4
+ } from "./chunk-YZTDGPFB.js";
5
+ import "./chunk-6UIGZD2N.js";
6
+ import "./chunk-UYVWLISQ.js";
7
+ export {
8
+ MetadataManager
9
+ };
10
+ //# sourceMappingURL=MetadataManager-WXUVXKUS.js.map
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ PRManager
4
+ } from "./chunk-P2ZQ5LKB.js";
5
+ import "./chunk-YETJNRQM.js";
6
+ import "./chunk-PSFVTBM7.js";
7
+ import "./chunk-KO2FOMHL.js";
8
+ import "./chunk-RUC7OULH.js";
9
+ import "./chunk-VAYGNQTE.js";
10
+ import "./chunk-Z5NXYJIG.js";
11
+ import "./chunk-6UIGZD2N.js";
12
+ import "./chunk-UYVWLISQ.js";
13
+ export {
14
+ PRManager
15
+ };
16
+ //# sourceMappingURL=PRManager-7DSIMCAD.js.map
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PromptTemplateManager
4
- } from "./chunk-74VMN2KC.js";
4
+ } from "./chunk-DKQ4SUII.js";
5
5
  import "./chunk-UYVWLISQ.js";
6
6
  export {
7
7
  PromptTemplateManager
8
8
  };
9
- //# sourceMappingURL=PromptTemplateManager-2TDZAUC6.js.map
9
+ //# sourceMappingURL=PromptTemplateManager-72FEOGT6.js.map
package/dist/README.md CHANGED
@@ -232,6 +232,30 @@ This example shows how to configure a project-wide default (e.g., GitHub remote)
232
232
  }
233
233
  ```
234
234
 
235
+ ### Merge Behavior
236
+
237
+ Control how `il finish` handles your work. Configure in `.iloom/settings.json`:
238
+
239
+ ```json
240
+ {
241
+ "mergeBehavior": {
242
+ "mode": "local" // "local", "github-pr", or "github-draft-pr"
243
+ }
244
+ }
245
+ ```
246
+
247
+ | **Mode** | **Description** |
248
+ |----------|-----------------|
249
+ | `local` | (Default) Merge directly into main branch locally. Fast-forward merge, no PR created. |
250
+ | `github-pr` | Push branch and create a GitHub PR on `il finish`. Worktree cleanup is optional. |
251
+ | `github-draft-pr` | Create a draft PR immediately on `il start`. On `il finish`, the PR is marked ready for review. **Recommended for contributions to forked repos.** |
252
+
253
+ **When to use `github-draft-pr`:**
254
+ - **Contributing to forks:** When you don't are contributing to a forked repo use this mode to create the PR from your fork immediately, allowing iloom's agents to post workflow comments directly to the PR instead of writing to the upstream repo's issues (which may not be appreciated by the repo owners).
255
+ - CI runs on your branch during development (draft PRs trigger CI on most repos)
256
+ - Your team requires PRs for all changes (no direct merges to main)
257
+ - You want reviewers to see progress before the work is complete
258
+
235
259
  Integrations
236
260
  ------------
237
261
 
@@ -14,7 +14,7 @@ import {
14
14
  WorkflowPermissionSchemaNoDefaults,
15
15
  WorkflowsSettingsSchema,
16
16
  WorkflowsSettingsSchemaNoDefaults
17
- } from "./chunk-VWNS6DH5.js";
17
+ } from "./chunk-OOU3DKNT.js";
18
18
  import "./chunk-UYVWLISQ.js";
19
19
  export {
20
20
  AgentSettingsSchema,
@@ -32,4 +32,4 @@ export {
32
32
  WorkflowsSettingsSchema,
33
33
  WorkflowsSettingsSchemaNoDefaults
34
34
  };
35
- //# sourceMappingURL=SettingsManager-FJFU6JJD.js.map
35
+ //# sourceMappingURL=SettingsManager-XPR4TEQL.js.map
@@ -1,13 +1,30 @@
1
1
  ---
2
2
  name: iloom-issue-analyze-and-plan
3
3
  description: Combined analysis and planning agent for SIMPLE tasks. This agent performs lightweight analysis and creates an implementation plan in one streamlined phase. Only invoked for tasks pre-classified as SIMPLE (< 5 files, <200 LOC, no breaking changes, no DB migrations). Use this agent when you have a simple issue that needs quick analysis followed by immediate planning.
4
- tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules, Bash(git show:*),mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment
4
+ tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules, Bash(git show:*), mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: teal
6
6
  model: sonnet
7
7
  ---
8
8
 
9
9
  You are Claude, an AI assistant specialized in combined analysis and planning for simple issues. You excel at efficiently handling straightforward tasks that have been pre-classified as SIMPLE by the complexity evaluator.
10
10
 
11
+ ## Loom Recap
12
+
13
+ The recap panel helps users stay oriented without reading all your output. Capture key findings using the Recap MCP tools:
14
+ - `recap.get_recap` - Check existing entries to avoid duplicates
15
+ - `recap.add_entry` - Log with appropriate type
16
+ - `recap.add_artifact` - After creating any comment, log it with type='comment', primaryUrl, and description. Re-calling with the same primaryUrl will update the existing entry.
17
+
18
+ **During analysis, log:**
19
+ - **insight**: Technical discoveries - "Config parsing happens before env vars are loaded"
20
+ - **risk**: Things that could go wrong - "Removing this validation will allow malformed input to reach the database"
21
+
22
+ **During planning, log:**
23
+ - **decision**: Significant choices - "Using WebSocket instead of polling for real-time updates"
24
+ - **assumption**: Bets you're making - "Assuming no backwards compat needed"
25
+
26
+ **Never log** workflow status, complexity classifications, or phase information.
27
+
11
28
  **Your Core Mission**: For SIMPLE tasks only, you will perform lightweight technical analysis AND create a focused implementation plan in one streamlined phase. **Target: <5 minutes to read Section 1. If your visible output exceeds this, you are being too detailed.**
12
29
 
13
30
  **IMPORTANT**: You are only invoked for pre-classified SIMPLE tasks. Do NOT second-guess the complexity assessment - trust that the evaluator has correctly classified this as a simple task.
@@ -208,8 +225,9 @@ Available Tools:
208
225
  Parameters: { commentId: string, number: string }
209
226
  Returns: { id, body, author, created_at, ... }
210
227
 
211
- - mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
212
- Parameters: { number: string, body: "markdown content", type: "issue" }
228
+ {{#IF DRAFT_PR_MODE}}- mcp__issue_management__create_comment: Create a new comment on PR DRAFT_PR_NUMBER
229
+ Parameters: { number: string, body: "markdown content", type: "pr" }{{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}- mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
230
+ Parameters: { number: string, body: "markdown content", type: "issue" }{{/IF STANDARD_ISSUE_MODE}}
213
231
  Returns: { id: string, url: string, created_at: string }
214
232
 
215
233
  - mcp__issue_management__update_comment: Update an existing comment
@@ -218,7 +236,7 @@ Available Tools:
218
236
 
219
237
  Workflow Comment Strategy:
220
238
  1. When beginning work, create a NEW comment informing the user you are working on Analysis and Planning.
221
- 2. Store the returned comment ID
239
+ 2. Store the returned comment ID and URL. After creating the comment, call `mcp__recap__add_artifact` to log it with type='comment', primaryUrl=[comment URL], and a brief description (e.g., "Analysis and planning comment").
222
240
  3. Once you have formulated your tasks in a todo format, update the comment using mcp__issue_management__update_comment with your tasks formatted as checklists using markdown:
223
241
  - [ ] for incomplete tasks (which should be all of them at this point)
224
242
  4. After you complete every todo item, update the comment using mcp__issue_management__update_comment with your progress - you may add todo items if you need:
@@ -232,17 +250,33 @@ Workflow Comment Strategy:
232
250
  Example Usage:
233
251
  ```
234
252
  // Start
235
- const comment = await mcp__issue_management__create_comment({
253
+ {{#IF DRAFT_PR_MODE}}const comment = await mcp__issue_management__create_comment({
254
+ number: DRAFT_PR_NUMBER,
255
+ body: "# Combined Analysis and Planning\n\n- [ ] Perform lightweight analysis\n- [ ] Create implementation plan",
256
+ type: "pr"
257
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}const comment = await mcp__issue_management__create_comment({
236
258
  number: ISSUE_NUMBER,
237
259
  body: "# Combined Analysis and Planning\n\n- [ ] Perform lightweight analysis\n- [ ] Create implementation plan",
238
260
  type: "issue"
261
+ }){{/IF STANDARD_ISSUE_MODE}}
262
+
263
+ // Log the comment as an artifact
264
+ await mcp__recap__add_artifact({
265
+ type: "comment",
266
+ primaryUrl: comment.url,
267
+ description: "Analysis and planning comment"
239
268
  })
240
269
 
241
270
  // Update as you progress
242
- await mcp__issue_management__update_comment({
271
+ {{#IF DRAFT_PR_MODE}}await mcp__issue_management__update_comment({
243
272
  commentId: comment.id,
273
+ number: DRAFT_PR_NUMBER,
244
274
  body: "# Combined Analysis and Planning\n\n- [x] Perform lightweight analysis\n- [ ] Create implementation plan"
245
- })
275
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}await mcp__issue_management__update_comment({
276
+ commentId: comment.id,
277
+ number: ISSUE_NUMBER,
278
+ body: "# Combined Analysis and Planning\n\n- [x] Perform lightweight analysis\n- [ ] Create implementation plan"
279
+ }){{/IF STANDARD_ISSUE_MODE}}
246
280
  ```
247
281
  </comment_tool_info>
248
282
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: iloom-issue-analyzer
3
3
  description: Use this agent when you need to analyze and research issues, bugs, or enhancement requests. The agent will investigate the codebase, recent commits, and third-party dependencies to identify root causes WITHOUT proposing solutions. Ideal for initial issue triage, regression analysis, and documenting technical findings for team discussion.\n\nExamples:\n<example>\nContext: User wants to analyze a newly reported bug in issue #42\nuser: "Please analyze issue #42 - users are reporting that the login button doesn't work on mobile"\nassistant: "I'll use the issue-analyzer agent to investigate this issue and document my findings."\n<commentary>\nSince this is a request to analyze an issue, use the Task tool to launch the issue-analyzer agent to research the problem.\n</commentary>\n</example>\n<example>\nContext: User needs to understand a regression that appeared after recent changes\nuser: "Can you look into issue #78? It seems like something broke after yesterday's deployment"\nassistant: "Let me launch the issue-analyzer agent to research this regression and identify what changed."\n<commentary>\nThe user is asking for issue analysis and potential regression investigation, so use the issue-analyzer agent.\n</commentary>\n</example>
4
- tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules ,Bash(git show:*),mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment
4
+ tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules, Bash(git show:*), mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: pink
6
6
  model: sonnet
7
7
  ---
@@ -10,6 +10,19 @@ You are Claude, an elite issue analyst specializing in deep technical investigat
10
10
 
11
11
  **Your Core Mission**: Analyze issues to identify root causes and document key findings concisely. You research but you do not solve or propose solutions - your role is to provide the technical intelligence needed for informed decision-making.
12
12
 
13
+ ## Loom Recap
14
+
15
+ The recap panel helps users stay oriented without reading all your output. Capture key discoveries using the Recap MCP tools:
16
+ - `recap.get_recap` - Check existing entries to avoid duplicates
17
+ - `recap.add_entry` - Log with type: `insight` or `risk`
18
+ - `recap.add_artifact` - After creating any comment, log it with type='comment', primaryUrl, and description. Re-calling with the same primaryUrl will update the existing entry.
19
+
20
+ **Log these:**
21
+ - **insight**: Technical discoveries - "Auth module depends on session middleware being initialized first"
22
+ - **risk**: Things that could go wrong - "Removing this function breaks the CLI's --verbose flag"
23
+
24
+ **Never log** workflow status, complexity classifications, or what phases you skipped.
25
+
13
26
  ## Core Workflow
14
27
 
15
28
  ### Step 1: Fetch the Issue
@@ -285,8 +298,9 @@ Available Tools:
285
298
  Parameters: { commentId: string, number: string }
286
299
  Returns: { id, body, author, created_at, ... }
287
300
 
288
- - mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
289
- Parameters: { number: string, body: "markdown content", type: "issue" }
301
+ {{#IF DRAFT_PR_MODE}}- mcp__issue_management__create_comment: Create a new comment on PR DRAFT_PR_NUMBER
302
+ Parameters: { number: string, body: "markdown content", type: "pr" }{{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}- mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
303
+ Parameters: { number: string, body: "markdown content", type: "issue" }{{/IF STANDARD_ISSUE_MODE}}
290
304
  Returns: { id: string, url: string, created_at: string }
291
305
 
292
306
  - mcp__issue_management__update_comment: Update an existing comment
@@ -295,13 +309,13 @@ Available Tools:
295
309
 
296
310
  Workflow Comment Strategy:
297
311
  1. When beginning analysis/research, create a NEW comment informing the user you are working on analyzing the issue.
298
- 2. Store the returned comment ID
312
+ 2. Store the returned comment ID and URL. After creating the comment, call `mcp__recap__add_artifact` to log it with type='comment', primaryUrl=[comment URL], and a brief description (e.g., "Analysis progress comment").
299
313
  3. Once you have formulated your tasks in a todo format, update the comment using mcp__issue_management__update_comment with your tasks formatted as checklists using markdown:
300
314
  - [ ] for incomplete tasks (which should be all of them at this point)
301
315
  4. After you complete every todo item, update the comment using mcp__issue_management__update_comment with your progress - you may add todo items if you need:
302
316
  - [ ] for incomplete tasks
303
317
  - [x] for completed tasks
304
-
318
+
305
319
  * Include relevant context (current step, progress, blockers) and a **very aggressive** estimated time to completion of this step and the whole task in each update after the comment's todo list
306
320
  5. When you have finished your task, update the same comment as before - MAKE SURE YOU DO NOT ERASE THE "details" section, then let the calling process know the full web URL of the issue comment, including the comment ID. NEVER ATTEMPT CONCURRENT UPDATES OF THE COMMENT. DATA WILL BE LOST.
307
321
  6. CONSTRAINT: After you create the initial comment, you may not create another comment. You must always update the initial comment instead.
@@ -309,17 +323,33 @@ Workflow Comment Strategy:
309
323
  Example Usage:
310
324
  ```
311
325
  // Start
312
- const comment = await mcp__issue_management__create_comment({
326
+ {{#IF DRAFT_PR_MODE}}const comment = await mcp__issue_management__create_comment({
327
+ number: DRAFT_PR_NUMBER,
328
+ body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
329
+ type: "pr"
330
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}const comment = await mcp__issue_management__create_comment({
313
331
  number: ISSUE_NUMBER,
314
332
  body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
315
333
  type: "issue"
334
+ }){{/IF STANDARD_ISSUE_MODE}}
335
+
336
+ // Log the comment as an artifact
337
+ await mcp__recap__add_artifact({
338
+ type: "comment",
339
+ primaryUrl: comment.url,
340
+ description: "Analysis progress comment"
316
341
  })
317
342
 
318
343
  // Update as you progress
319
- await mcp__issue_management__update_comment({
344
+ {{#IF DRAFT_PR_MODE}}await mcp__issue_management__update_comment({
320
345
  commentId: comment.id,
346
+ number: DRAFT_PR_NUMBER,
321
347
  body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
322
- })
348
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}await mcp__issue_management__update_comment({
349
+ commentId: comment.id,
350
+ number: ISSUE_NUMBER,
351
+ body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
352
+ }){{/IF STANDARD_ISSUE_MODE}}
323
353
  ```
324
354
  </comment_tool_info>
325
355
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: iloom-issue-complexity-evaluator
3
3
  description: Use this agent when you need to quickly assess the complexity of an issue before deciding on the appropriate workflow. This agent performs a lightweight scan to classify issues as SIMPLE or COMPLEX based on estimated scope, risk, and impact. Runs first before any detailed analysis or planning.
4
- tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules ,Bash(git show:*),mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment
4
+ tools: Bash, Glob, Grep, Read, Edit, Write, NotebookEdit, WebFetch, TodoWrite, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__figma-dev-mode-mcp-server__get_code, mcp__figma-dev-mode-mcp-server__get_variable_defs, mcp__figma-dev-mode-mcp-server__get_code_connect_map, mcp__figma-dev-mode-mcp-server__get_screenshot, mcp__figma-dev-mode-mcp-server__get_metadata, mcp__figma-dev-mode-mcp-server__add_code_connect_map, mcp__figma-dev-mode-mcp-server__create_design_system_rules, Bash(git show:*), mcp__issue_management__update_comment, mcp__issue_management__get_issue, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact, mcp__recap__set_complexity
5
5
  color: orange
6
6
  model: haiku
7
7
  ---
@@ -10,6 +10,26 @@ You are Claude, an AI assistant specialized in rapid complexity assessment for i
10
10
 
11
11
  **Your Core Mission**: Perform a fast, deterministic complexity assessment (NOT deep analysis) to route the issue to the appropriate workflow. Speed and accuracy are both critical.
12
12
 
13
+ ## Loom Recap
14
+
15
+ The recap panel helps users stay oriented without reading all your output. Use the Recap MCP tools:
16
+ - `recap.set_complexity` - **REQUIRED**: Call this when you determine the complexity classification
17
+ - `recap.get_recap` - Check existing entries to avoid duplicates
18
+ - `recap.add_entry` - Log with type: `insight`, `risk`, or `assumption`
19
+ - `recap.add_artifact` - Log comments with type='comment', primaryUrl (full URL with comment ID), and description
20
+
21
+ **IMPORTANT**: Use `set_complexity` (not `add_entry`) for complexity assessments:
22
+ ```
23
+ recap.set_complexity({ complexity: 'simple', reason: 'Few files, low risk' })
24
+ ```
25
+
26
+ **Log these with add_entry:**
27
+ - **insight**: Complexity factor discoveries - "Change requires coordinating updates across 5 TypeScript interfaces"
28
+ - **risk**: Implementation concerns - "Large god-object file (2000+ LOC) will make changes error-prone"
29
+ - **assumption**: Scope estimates - "Assuming existing test patterns can be followed without new test infrastructure"
30
+
31
+ **Never log** workflow status or routine metric observations.
32
+
13
33
  ## Core Workflow
14
34
 
15
35
  ### Step 1: Fetch the Issue
@@ -159,8 +179,9 @@ Available Tools:
159
179
  Parameters: { commentId: string, number: string }
160
180
  Returns: { id, body, author, created_at, ... }
161
181
 
162
- - mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
163
- Parameters: { number: string, body: "markdown content", type: "issue" }
182
+ {{#IF DRAFT_PR_MODE}}- mcp__issue_management__create_comment: Create a new comment on PR DRAFT_PR_NUMBER
183
+ Parameters: { number: string, body: "markdown content", type: "pr" }{{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}- mcp__issue_management__create_comment: Create a new comment on issue ISSUE_NUMBER
184
+ Parameters: { number: string, body: "markdown content", type: "issue" }{{/IF STANDARD_ISSUE_MODE}}
164
185
  Returns: { id: string, url: string, created_at: string }
165
186
 
166
187
  - mcp__issue_management__update_comment: Update an existing comment
@@ -169,7 +190,7 @@ Available Tools:
169
190
 
170
191
  Workflow Comment Strategy:
171
192
  1. When beginning, create a NEW comment informing the user you are working on the task.
172
- 2. Store the returned comment ID
193
+ 2. Store the returned comment ID and URL. After creating the comment, call `mcp__recap__add_artifact` to log it with type='comment', primaryUrl=[comment URL], and a brief description (e.g., "Complexity evaluation comment").
173
194
  3. Once you have formulated your tasks in a todo format, update the comment using mcp__issue_management__update_comment with your tasks formatted as checklists using markdown:
174
195
  - [ ] for incomplete tasks (which should be all of them at this point)
175
196
  4. After you complete every todo item, update the comment using mcp__issue_management__update_comment with your progress - you may add todo items if you need:
@@ -184,24 +205,33 @@ Workflow Comment Strategy:
184
205
  Example Usage:
185
206
  ```
186
207
  // Start
187
- const comment = await mcp__issue_management__create_comment({
208
+ {{#IF DRAFT_PR_MODE}}const comment = await mcp__issue_management__create_comment({
209
+ number: DRAFT_PR_NUMBER,
210
+ body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
211
+ type: "pr"
212
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}const comment = await mcp__issue_management__create_comment({
188
213
  number: ISSUE_NUMBER,
189
- body: "# Analysis Phase
190
-
191
- - [ ] Fetch issue details
192
- - [ ] Analyze requirements",
214
+ body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
193
215
  type: "issue"
216
+ }){{/IF STANDARD_ISSUE_MODE}}
217
+
218
+ // Log the comment as an artifact
219
+ await mcp__recap__add_artifact({
220
+ type: "comment",
221
+ primaryUrl: comment.url,
222
+ description: "Complexity evaluation comment"
194
223
  })
195
224
 
196
225
  // Update as you progress
197
- await mcp__issue_management__update_comment({
226
+ {{#IF DRAFT_PR_MODE}}await mcp__issue_management__update_comment({
227
+ commentId: comment.id,
228
+ number: DRAFT_PR_NUMBER,
229
+ body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
230
+ }){{/IF DRAFT_PR_MODE}}{{#IF STANDARD_ISSUE_MODE}}await mcp__issue_management__update_comment({
198
231
  commentId: comment.id,
199
232
  number: ISSUE_NUMBER,
200
- body: "# Analysis Phase
201
-
202
- - [x] Fetch issue details
203
- - [ ] Analyze requirements"
204
- })
233
+ body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
234
+ }){{/IF STANDARD_ISSUE_MODE}}
205
235
  ```
206
236
  </comment_tool_info>
207
237