@iloom/cli 0.7.6 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +32 -3
  3. package/dist/{ClaudeContextManager-Y2YJC6BU.js → ClaudeContextManager-RDP6CLK6.js} +5 -5
  4. package/dist/{ClaudeService-NDVFQRKC.js → ClaudeService-FKPOQRA4.js} +4 -4
  5. package/dist/GitHubService-ACZVNTJE.js +12 -0
  6. package/dist/{LoomLauncher-U2B3VHPC.js → LoomLauncher-NHZMEVTQ.js} +5 -5
  7. package/dist/{MetadataManager-XJ2YB762.js → MetadataManager-W3C54UYT.js} +2 -2
  8. package/dist/{PRManager-7F3AAY66.js → PRManager-H4TUZTZL.js} +5 -5
  9. package/dist/{PromptTemplateManager-7L3HJQQU.js → PromptTemplateManager-OUYDHOPI.js} +2 -2
  10. package/dist/README.md +32 -3
  11. package/dist/{SettingsManager-YU4VYPTW.js → SettingsManager-VCVLL32H.js} +4 -2
  12. package/dist/{SettingsMigrationManager-KZKDG66H.js → SettingsMigrationManager-LEBMJP3B.js} +3 -3
  13. package/dist/agents/iloom-code-reviewer.md +735 -0
  14. package/dist/agents/iloom-framework-detector.md +1 -1
  15. package/dist/agents/iloom-issue-analyze-and-plan.md +2 -2
  16. package/dist/agents/iloom-issue-analyzer.md +2 -2
  17. package/dist/agents/iloom-issue-complexity-evaluator.md +1 -1
  18. package/dist/agents/iloom-issue-enhancer.md +2 -2
  19. package/dist/agents/iloom-issue-implementer.md +3 -3
  20. package/dist/agents/iloom-issue-planner.md +2 -2
  21. package/dist/{build-HQ5HGA3T.js → build-H4DK3DMQ.js} +7 -7
  22. package/dist/{chunk-N7FVXZNI.js → chunk-4BSXZ5YZ.js} +31 -9
  23. package/dist/chunk-4BSXZ5YZ.js.map +1 -0
  24. package/dist/{chunk-VYKKWU36.js → chunk-4KGRPHM6.js} +3 -3
  25. package/dist/{chunk-CFQVOTHO.js → chunk-52MVUK5V.js} +2 -2
  26. package/dist/{chunk-TIYJEEVO.js → chunk-66QOCD5N.js} +1 -1
  27. package/dist/chunk-66QOCD5N.js.map +1 -0
  28. package/dist/chunk-7JDMYTFZ.js +251 -0
  29. package/dist/chunk-7JDMYTFZ.js.map +1 -0
  30. package/dist/{chunk-7LSSNB7Y.js → chunk-7ZEHSSUP.js} +2 -2
  31. package/dist/chunk-A4UQY3M2.js +75 -0
  32. package/dist/chunk-A4UQY3M2.js.map +1 -0
  33. package/dist/{chunk-ELJKYFSH.js → chunk-BCQDYAOJ.js} +4 -4
  34. package/dist/{chunk-F2PWIRV4.js → chunk-BYUMEDDD.js} +2 -2
  35. package/dist/{chunk-CAXFWFV6.js → chunk-ECP77QGE.js} +4 -4
  36. package/dist/{chunk-6YAMWLCP.js → chunk-EQOFNPEY.js} +3 -3
  37. package/dist/{chunk-ZA575VLF.js → chunk-GDS2HXSW.js} +4 -4
  38. package/dist/{chunk-UDRZY65Y.js → chunk-HSGZW3ID.js} +2 -2
  39. package/dist/{chunk-WFQ5CLTR.js → chunk-IWIIOFEB.js} +56 -5
  40. package/dist/chunk-IWIIOFEB.js.map +1 -0
  41. package/dist/{chunk-VWGKGNJP.js → chunk-KBEIQP4G.js} +3 -1
  42. package/dist/chunk-KBEIQP4G.js.map +1 -0
  43. package/dist/{chunk-ETY2SBW5.js → chunk-NR64HNF7.js} +17 -15
  44. package/dist/chunk-NR64HNF7.js.map +1 -0
  45. package/dist/{chunk-WT4UGBE2.js → chunk-PBSHQVCT.js} +5 -5
  46. package/dist/{chunk-64HCHVJM.js → chunk-PLI3JQWT.js} +2 -2
  47. package/dist/{chunk-USJSNHGG.js → chunk-PVW6JE7E.js} +3 -3
  48. package/dist/{chunk-HBJITKSZ.js → chunk-RNBIISBZ.js} +161 -3
  49. package/dist/chunk-RNBIISBZ.js.map +1 -0
  50. package/dist/{chunk-C7YW5IMS.js → chunk-RODL2HVY.js} +17 -6
  51. package/dist/{chunk-C7YW5IMS.js.map → chunk-RODL2HVY.js.map} +1 -1
  52. package/dist/{chunk-3K3WY3BN.js → chunk-SC6X5EBG.js} +4 -4
  53. package/dist/{chunk-NEPH2O4C.js → chunk-SSASIBDJ.js} +3 -3
  54. package/dist/{chunk-GCPAZSGV.js → chunk-THS5L54H.js} +150 -3
  55. package/dist/chunk-THS5L54H.js.map +1 -0
  56. package/dist/{chunk-5V74K5ZA.js → chunk-TVH67KEO.js} +25 -2
  57. package/dist/chunk-TVH67KEO.js.map +1 -0
  58. package/dist/{chunk-NPEMVE27.js → chunk-UDZCTLD6.js} +115 -3
  59. package/dist/chunk-UDZCTLD6.js.map +1 -0
  60. package/dist/{chunk-ENMTWE74.js → chunk-VZYSM7N7.js} +2 -2
  61. package/dist/{chunk-WZYBHD7P.js → chunk-XHNACIHO.js} +2 -2
  62. package/dist/{chunk-XAMBIVXE.js → chunk-XJHQVOT6.js} +2 -2
  63. package/dist/{chunk-O36JLYNW.js → chunk-XU5A6BWA.js} +4 -7
  64. package/dist/chunk-XU5A6BWA.js.map +1 -0
  65. package/dist/{cleanup-IO4KV2DL.js → cleanup-OGE7V7AD.js} +16 -16
  66. package/dist/cli.js +317 -164
  67. package/dist/cli.js.map +1 -1
  68. package/dist/{commit-3ULFKXNB.js → commit-534QIRHY.js} +10 -10
  69. package/dist/{compile-CT7IR7O2.js → compile-ZOAODFN2.js} +7 -7
  70. package/dist/{contribute-GXKOIA42.js → contribute-7USRBWRM.js} +6 -6
  71. package/dist/{dev-server-OAP3RZC6.js → dev-server-TYYJM3XA.js} +9 -9
  72. package/dist/{feedback-ZLAX3BVL.js → feedback-HZVLOTQJ.js} +9 -9
  73. package/dist/{git-ENLT2VNI.js → git-GUNOPP4Q.js} +4 -4
  74. package/dist/hooks/iloom-hook.js +75 -3
  75. package/dist/{ignite-HA2OJF6Z.js → ignite-ZO7SGUKP.js} +85 -25
  76. package/dist/ignite-ZO7SGUKP.js.map +1 -0
  77. package/dist/index.d.ts +85 -2
  78. package/dist/index.js +133 -73
  79. package/dist/index.js.map +1 -1
  80. package/dist/init-MZBIXQ7V.js +21 -0
  81. package/dist/{lint-HAVU4U34.js → lint-MDVUV3W2.js} +7 -7
  82. package/dist/mcp/issue-management-server.js +569 -2
  83. package/dist/mcp/issue-management-server.js.map +1 -1
  84. package/dist/{neon-helpers-3KBC4A3Y.js → neon-helpers-VVFFTLXE.js} +3 -3
  85. package/dist/{open-IN3LUZXX.js → open-2LPZ7XXW.js} +9 -9
  86. package/dist/plan-PIME6UNY.js +371 -0
  87. package/dist/plan-PIME6UNY.js.map +1 -0
  88. package/dist/{projects-CTRTTMSK.js → projects-325GEEGJ.js} +2 -2
  89. package/dist/{prompt-3SAZYRUN.js → prompt-ONNPSNKM.js} +2 -2
  90. package/dist/prompts/init-prompt.txt +83 -3
  91. package/dist/prompts/issue-prompt.txt +51 -3
  92. package/dist/prompts/plan-prompt.txt +435 -0
  93. package/dist/prompts/pr-prompt.txt +38 -0
  94. package/dist/prompts/regular-prompt.txt +53 -3
  95. package/dist/{rebase-RLEVFHWN.js → rebase-7YS3N274.js} +6 -6
  96. package/dist/{recap-ZKGHZCX6.js → recap-GSXFEOD6.js} +6 -6
  97. package/dist/{run-QEIS2EH2.js → run-XPGCMFFO.js} +9 -9
  98. package/dist/schema/settings.schema.json +57 -1
  99. package/dist/{shell-2NNSIU34.js → shell-2SPM3Z5O.js} +6 -6
  100. package/dist/{summary-MPOOQIOX.js → summary-C5VVSJAJ.js} +11 -11
  101. package/dist/{test-75WAA6DU.js → test-N2725YRI.js} +7 -7
  102. package/dist/{test-git-E2BLXR6M.js → test-git-ZPSPA2TP.js} +4 -4
  103. package/dist/{test-prefix-A7JGGYAA.js → test-prefix-6DLB2BHE.js} +4 -4
  104. package/dist/{test-webserver-J6SMNLU2.js → test-webserver-XLJ2TZFP.js} +6 -6
  105. package/package.json +1 -1
  106. package/dist/GitHubService-O7U4UQ7N.js +0 -12
  107. package/dist/agents/iloom-issue-reviewer.md +0 -139
  108. package/dist/chunk-5V74K5ZA.js.map +0 -1
  109. package/dist/chunk-ETY2SBW5.js.map +0 -1
  110. package/dist/chunk-GCPAZSGV.js.map +0 -1
  111. package/dist/chunk-HBJITKSZ.js.map +0 -1
  112. package/dist/chunk-N7FVXZNI.js.map +0 -1
  113. package/dist/chunk-NPEMVE27.js.map +0 -1
  114. package/dist/chunk-O36JLYNW.js.map +0 -1
  115. package/dist/chunk-TIYJEEVO.js.map +0 -1
  116. package/dist/chunk-VWGKGNJP.js.map +0 -1
  117. package/dist/chunk-WFQ5CLTR.js.map +0 -1
  118. package/dist/chunk-ZX3GTM7O.js +0 -119
  119. package/dist/chunk-ZX3GTM7O.js.map +0 -1
  120. package/dist/ignite-HA2OJF6Z.js.map +0 -1
  121. package/dist/init-S6IEGRSX.js +0 -21
  122. /package/dist/{ClaudeContextManager-Y2YJC6BU.js.map → ClaudeContextManager-RDP6CLK6.js.map} +0 -0
  123. /package/dist/{ClaudeService-NDVFQRKC.js.map → ClaudeService-FKPOQRA4.js.map} +0 -0
  124. /package/dist/{GitHubService-O7U4UQ7N.js.map → GitHubService-ACZVNTJE.js.map} +0 -0
  125. /package/dist/{LoomLauncher-U2B3VHPC.js.map → LoomLauncher-NHZMEVTQ.js.map} +0 -0
  126. /package/dist/{MetadataManager-XJ2YB762.js.map → MetadataManager-W3C54UYT.js.map} +0 -0
  127. /package/dist/{PRManager-7F3AAY66.js.map → PRManager-H4TUZTZL.js.map} +0 -0
  128. /package/dist/{PromptTemplateManager-7L3HJQQU.js.map → PromptTemplateManager-OUYDHOPI.js.map} +0 -0
  129. /package/dist/{SettingsManager-YU4VYPTW.js.map → SettingsManager-VCVLL32H.js.map} +0 -0
  130. /package/dist/{SettingsMigrationManager-KZKDG66H.js.map → SettingsMigrationManager-LEBMJP3B.js.map} +0 -0
  131. /package/dist/{build-HQ5HGA3T.js.map → build-H4DK3DMQ.js.map} +0 -0
  132. /package/dist/{chunk-VYKKWU36.js.map → chunk-4KGRPHM6.js.map} +0 -0
  133. /package/dist/{chunk-CFQVOTHO.js.map → chunk-52MVUK5V.js.map} +0 -0
  134. /package/dist/{chunk-7LSSNB7Y.js.map → chunk-7ZEHSSUP.js.map} +0 -0
  135. /package/dist/{chunk-ELJKYFSH.js.map → chunk-BCQDYAOJ.js.map} +0 -0
  136. /package/dist/{chunk-F2PWIRV4.js.map → chunk-BYUMEDDD.js.map} +0 -0
  137. /package/dist/{chunk-CAXFWFV6.js.map → chunk-ECP77QGE.js.map} +0 -0
  138. /package/dist/{chunk-6YAMWLCP.js.map → chunk-EQOFNPEY.js.map} +0 -0
  139. /package/dist/{chunk-ZA575VLF.js.map → chunk-GDS2HXSW.js.map} +0 -0
  140. /package/dist/{chunk-UDRZY65Y.js.map → chunk-HSGZW3ID.js.map} +0 -0
  141. /package/dist/{chunk-WT4UGBE2.js.map → chunk-PBSHQVCT.js.map} +0 -0
  142. /package/dist/{chunk-64HCHVJM.js.map → chunk-PLI3JQWT.js.map} +0 -0
  143. /package/dist/{chunk-USJSNHGG.js.map → chunk-PVW6JE7E.js.map} +0 -0
  144. /package/dist/{chunk-3K3WY3BN.js.map → chunk-SC6X5EBG.js.map} +0 -0
  145. /package/dist/{chunk-NEPH2O4C.js.map → chunk-SSASIBDJ.js.map} +0 -0
  146. /package/dist/{chunk-ENMTWE74.js.map → chunk-VZYSM7N7.js.map} +0 -0
  147. /package/dist/{chunk-WZYBHD7P.js.map → chunk-XHNACIHO.js.map} +0 -0
  148. /package/dist/{chunk-XAMBIVXE.js.map → chunk-XJHQVOT6.js.map} +0 -0
  149. /package/dist/{cleanup-IO4KV2DL.js.map → cleanup-OGE7V7AD.js.map} +0 -0
  150. /package/dist/{commit-3ULFKXNB.js.map → commit-534QIRHY.js.map} +0 -0
  151. /package/dist/{compile-CT7IR7O2.js.map → compile-ZOAODFN2.js.map} +0 -0
  152. /package/dist/{contribute-GXKOIA42.js.map → contribute-7USRBWRM.js.map} +0 -0
  153. /package/dist/{dev-server-OAP3RZC6.js.map → dev-server-TYYJM3XA.js.map} +0 -0
  154. /package/dist/{feedback-ZLAX3BVL.js.map → feedback-HZVLOTQJ.js.map} +0 -0
  155. /package/dist/{git-ENLT2VNI.js.map → git-GUNOPP4Q.js.map} +0 -0
  156. /package/dist/{init-S6IEGRSX.js.map → init-MZBIXQ7V.js.map} +0 -0
  157. /package/dist/{lint-HAVU4U34.js.map → lint-MDVUV3W2.js.map} +0 -0
  158. /package/dist/{neon-helpers-3KBC4A3Y.js.map → neon-helpers-VVFFTLXE.js.map} +0 -0
  159. /package/dist/{open-IN3LUZXX.js.map → open-2LPZ7XXW.js.map} +0 -0
  160. /package/dist/{projects-CTRTTMSK.js.map → projects-325GEEGJ.js.map} +0 -0
  161. /package/dist/{prompt-3SAZYRUN.js.map → prompt-ONNPSNKM.js.map} +0 -0
  162. /package/dist/{rebase-RLEVFHWN.js.map → rebase-7YS3N274.js.map} +0 -0
  163. /package/dist/{recap-ZKGHZCX6.js.map → recap-GSXFEOD6.js.map} +0 -0
  164. /package/dist/{run-QEIS2EH2.js.map → run-XPGCMFFO.js.map} +0 -0
  165. /package/dist/{shell-2NNSIU34.js.map → shell-2SPM3Z5O.js.map} +0 -0
  166. /package/dist/{summary-MPOOQIOX.js.map → summary-C5VVSJAJ.js.map} +0 -0
  167. /package/dist/{test-75WAA6DU.js.map → test-N2725YRI.js.map} +0 -0
  168. /package/dist/{test-git-E2BLXR6M.js.map → test-git-ZPSPA2TP.js.map} +0 -0
  169. /package/dist/{test-prefix-A7JGGYAA.js.map → test-prefix-6DLB2BHE.js.map} +0 -0
  170. /package/dist/{test-webserver-J6SMNLU2.js.map → test-webserver-XLJ2TZFP.js.map} +0 -0
@@ -3,7 +3,7 @@ name: iloom-framework-detector
3
3
  description: Use this agent to detect a project's language and framework, then generate appropriate build/test/dev scripts for non-Node.js projects. The agent creates `.iloom/package.iloom.json` with shell commands tailored to the detected stack. Use this for Python, Rust, Ruby, Go, and other non-Node.js projects that don't have a package.json.
4
4
  tools: Bash, Glob, Grep, Read, Write
5
5
  color: cyan
6
- model: sonnet
6
+ model: opus
7
7
  ---
8
8
 
9
9
  You are Claude, a framework detection specialist. Your task is to analyze a project's structure and generate appropriate install/build/test/dev scripts for iloom.
@@ -1,9 +1,9 @@
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: teal
6
- model: sonnet
6
+ model: opus
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.
@@ -1,9 +1,9 @@
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: pink
6
- model: sonnet
6
+ model: opus
7
7
  ---
8
8
 
9
9
  You are Claude, an elite issue analyst specializing in deep technical investigation and root cause analysis. Your expertise lies in methodically researching codebases, identifying patterns, and documenting technical findings with surgical precision.
@@ -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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact, mcp__recap__set_complexity
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, 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
  ---
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: iloom-issue-enhancer
3
3
  description: Use this agent when you need to analyze bug or enhancement reports from a Product Manager perspective. The agent accepts either an issue identifier or direct text description and creates structured specifications that enhance the original user report for development teams without performing code analysis or suggesting implementations. Ideal for triaging bugs and feature requests to prepare them for technical analysis and planning.\n\nExamples:\n<example>\nContext: User wants to triage and enhance a bug report from issue tracker\nuser: "Please analyze issue #42 - the login button doesn't work on mobile"\nassistant: "I'll use the iloom-issue-enhancer agent to analyze this bug report and create a structured specification."\n<commentary>\nSince this is a request to triage and structure a bug report from a user experience perspective, use the iloom-issue-enhancer agent.\n</commentary>\n</example>\n<example>\nContext: User needs to enhance an enhancement request that lacks detail\nuser: "Can you improve the description on issue #78? The user's request is pretty vague"\nassistant: "Let me launch the iloom-issue-enhancer agent to analyze the enhancement request and create a clear specification."\n<commentary>\nThe user is asking for enhancement report structuring, so use the iloom-issue-enhancer agent.\n</commentary>\n</example>\n<example>\nContext: User provides direct description without issue identifier\nuser: "Analyze this bug: Users report that the search function returns no results when they include special characters like & or # in their query"\nassistant: "I'll use the iloom-issue-enhancer agent to create a structured specification for this bug report."\n<commentary>\nEven though no issue identifier was provided, the iloom-issue-enhancer agent can analyze the direct description and create a structured specification.\n</commentary>\n</example>\n<example>\nContext: An issue has been labeled as a valid baug and needs structured analysis\nuser: "Structure issue #123 that was just labeled as a triaged bug"\nassistant: "I'll use the iloom-issue-enhancer agent to create a comprehensive bug specification."\n<commentary>\nThe issue needs Product Manager-style analysis and structuring, so use the iloom-issue-enhancer agent.\n</commentary>\n</example>
4
- tools: Bash, Glob, Grep, Read, WebFetch, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__issue_management__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
4
+ tools: Bash, Glob, Grep, Read, WebFetch, WebSearch, BashOutput, KillShell, SlashCommand, ListMcpResourcesTool, ReadMcpResourceTool, mcp__context7__resolve-library-id, mcp__context7__get-library-docs, mcp__issue_management__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: purple
6
- model: sonnet
6
+ model: opus
7
7
  ---
8
8
 
9
9
  You are Claude, an elite Product Manager specializing in bug and enhancement report analysis. Your expertise lies in understanding user experiences, structuring problem statements, and creating clear specifications that enable development teams to work autonomously.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: iloom-issue-implementer
3
3
  description: Use this agent when you need to implement an issue exactly as specified in its comments and description. This agent reads issue details, follows implementation plans precisely, and ensures all code passes tests, typechecking, and linting before completion. Examples:\n\n<example>\nContext: User wants to implement a specific issue.\nuser: "Please implement issue #42"\nassistant: "I'll use the issue-implementer agent to read and implement issue #42 exactly as specified."\n<commentary>\nSince the user is asking to implement an issue, use the Task tool to launch the issue-implementer agent.\n</commentary>\n</example>\n\n<example>\nContext: User references an issue that needs implementation.\nuser: "Can you work on the authentication issue we discussed in #15?"\nassistant: "Let me launch the issue-implementer agent to read issue #15 and implement it according to the plan in the comments."\n<commentary>\nThe user is referencing a specific issue number, so use the issue-implementer agent to handle the implementation.\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 ,mcp__issue_management__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
- model: sonnet
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 ,mcp__issue_management__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
+ model: opus
6
6
  color: green
7
7
  ---
8
8
 
9
- You are Claude, an AI assistant specialized in implementing issues with absolute precision and adherence to specifications. You are currently using the 'sonnet' model - if you are not, you must immediately notify the user and stop. Ultrathink to perform as described below.
9
+ You are Claude, an AI assistant specialized in implementing issues with absolute precision and adherence to specifications. You are currently using the 'opus' model - if you are not, you must immediately notify the user and stop. Ultrathink to perform as described below.
10
10
 
11
11
  ## Loom Recap
12
12
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: iloom-issue-planner
3
3
  description: Use this agent when you need to analyze issues and create detailed implementation plans. This agent specializes in reading issue context, understanding requirements, and creating focused implementation plans with specific file changes and line numbers. The agent will document the plan as a comment on the issue without executing any changes. Examples: <example>Context: The user wants detailed implementation planning for an issue.\nuser: "Analyze issue #42 and create an implementation plan"\nassistant: "I'll use the issue-planner agent to analyze the issue and create a detailed implementation plan"\n<commentary>Since the user wants issue analysis and implementation planning, use the issue-planner agent.</commentary></example> <example>Context: The user needs a plan for implementing a feature described in an issue.\nuser: "Read issue #15 and plan out what needs to be changed"\nassistant: "Let me use the issue-planner agent to analyze the issue and document a comprehensive implementation plan"\n<commentary>The user needs issue analysis and planning, so the issue-planner agent is the right choice.</commentary></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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
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__get_issue, mcp__issue_management__get_pr, mcp__issue_management__get_comment, mcp__issue_management__create_comment, mcp__issue_management__update_comment, mcp__issue_management__create_dependency, mcp__issue_management__get_dependencies, mcp__issue_management__remove_dependency, mcp__recap__get_recap, mcp__recap__add_entry, mcp__recap__add_artifact
5
5
  color: blue
6
- model: sonnet
6
+ model: opus
7
7
  ---
8
8
 
9
9
  You are Claude, an AI assistant designed to excel at analyzing issues and creating detailed implementation plans. Analyze the context and respond with precision and thoroughness. Think harder as you execute your tasks.
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScriptCommandBase
4
- } from "./chunk-ELJKYFSH.js";
5
- import "./chunk-5V74K5ZA.js";
4
+ } from "./chunk-BCQDYAOJ.js";
5
+ import "./chunk-TVH67KEO.js";
6
6
  import "./chunk-RD7I2Q2F.js";
7
- import "./chunk-UDRZY65Y.js";
7
+ import "./chunk-HSGZW3ID.js";
8
8
  import "./chunk-XPKN3QWY.js";
9
- import "./chunk-ZA575VLF.js";
10
- import "./chunk-WFQ5CLTR.js";
11
- import "./chunk-VWGKGNJP.js";
9
+ import "./chunk-GDS2HXSW.js";
10
+ import "./chunk-IWIIOFEB.js";
11
+ import "./chunk-KBEIQP4G.js";
12
12
  import "./chunk-6MLEBAYZ.js";
13
13
  import "./chunk-VT4PDUYT.js";
14
14
 
@@ -24,4 +24,4 @@ var BuildCommand = class extends ScriptCommandBase {
24
24
  export {
25
25
  BuildCommand
26
26
  };
27
- //# sourceMappingURL=build-HQ5HGA3T.js.map
27
+ //# sourceMappingURL=build-H4DK3DMQ.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PromptTemplateManager
4
- } from "./chunk-TIYJEEVO.js";
4
+ } from "./chunk-66QOCD5N.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-VT4PDUYT.js";
@@ -149,6 +149,7 @@ var AgentManager = class {
149
149
  * Supports negation patterns like ['*.md', '!iloom-framework-detector.md']
150
150
  */
151
151
  async loadAgents(settings, templateVariables, patterns = ["*.md"]) {
152
+ var _a;
152
153
  const agentFiles = await fg(patterns, {
153
154
  cwd: this.agentDir,
154
155
  onlyFiles: true
@@ -172,6 +173,26 @@ var AgentManager = class {
172
173
  }
173
174
  }
174
175
  if (templateVariables) {
176
+ const reviewerSettings = (_a = settings == null ? void 0 : settings.agents) == null ? void 0 : _a["iloom-code-reviewer"];
177
+ const reviewEnabled = (reviewerSettings == null ? void 0 : reviewerSettings.enabled) !== false;
178
+ templateVariables.REVIEW_ENABLED = reviewEnabled;
179
+ if (reviewEnabled) {
180
+ const providers = (reviewerSettings == null ? void 0 : reviewerSettings.providers) ?? {};
181
+ const hasAnyProvider = Object.keys(providers).length > 0;
182
+ const claudeModel = providers.claude ?? (hasAnyProvider ? void 0 : "sonnet");
183
+ if (claudeModel) {
184
+ templateVariables.REVIEW_CLAUDE_MODEL = claudeModel;
185
+ }
186
+ if (providers.gemini) {
187
+ templateVariables.REVIEW_GEMINI_MODEL = providers.gemini;
188
+ }
189
+ if (providers.codex) {
190
+ templateVariables.REVIEW_CODEX_MODEL = providers.codex;
191
+ }
192
+ templateVariables.HAS_REVIEW_CLAUDE = !!claudeModel;
193
+ templateVariables.HAS_REVIEW_GEMINI = !!providers.gemini;
194
+ templateVariables.HAS_REVIEW_CODEX = !!providers.codex;
195
+ }
175
196
  for (const [agentName, agentConfig] of Object.entries(agents)) {
176
197
  agents[agentName] = {
177
198
  ...agentConfig,
@@ -197,15 +218,16 @@ var AgentManager = class {
197
218
  }
198
219
  /**
199
220
  * Validate agent configuration has required fields
221
+ * Note: tools is optional - when omitted, agent inherits all tools from parent
200
222
  */
201
223
  validateAgentConfig(config, agentName) {
202
- const requiredFields = ["description", "prompt", "tools", "model"];
224
+ const requiredFields = ["description", "prompt", "model"];
203
225
  for (const field of requiredFields) {
204
226
  if (!config[field]) {
205
227
  throw new Error(`Agent ${agentName} missing required field: ${field}`);
206
228
  }
207
229
  }
208
- if (!Array.isArray(config.tools)) {
230
+ if (config.tools !== void 0 && !Array.isArray(config.tools)) {
209
231
  throw new Error(`Agent ${agentName} tools must be an array`);
210
232
  }
211
233
  }
@@ -224,13 +246,13 @@ var AgentManager = class {
224
246
  if (!data.description) {
225
247
  throw new Error("Missing required field: description");
226
248
  }
227
- if (!data.tools) {
228
- throw new Error("Missing required field: tools");
229
- }
230
249
  if (!data.model) {
231
250
  throw new Error("Missing required field: model");
232
251
  }
233
- const tools = data.tools.split(",").map((tool) => tool.trim()).filter((tool) => tool.length > 0);
252
+ let tools;
253
+ if (data.tools) {
254
+ tools = data.tools.split(",").map((tool) => tool.trim()).filter((tool) => tool.length > 0);
255
+ }
234
256
  const validModels = ["sonnet", "opus", "haiku"];
235
257
  if (!validModels.includes(data.model)) {
236
258
  logger.warn(
@@ -240,8 +262,8 @@ var AgentManager = class {
240
262
  const config = {
241
263
  description: data.description,
242
264
  prompt: markdownBody.trim(),
243
- tools,
244
265
  model: data.model,
266
+ ...tools && { tools },
245
267
  ...data.color && { color: data.color }
246
268
  };
247
269
  return { config, name: data.name };
@@ -263,4 +285,4 @@ var AgentManager = class {
263
285
  export {
264
286
  AgentManager
265
287
  };
266
- //# sourceMappingURL=chunk-N7FVXZNI.js.map
288
+ //# sourceMappingURL=chunk-4BSXZ5YZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/AgentManager.ts","../src/utils/MarkdownAgentParser.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport { accessSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport fg from 'fast-glob'\nimport { MarkdownAgentParser } from '../utils/MarkdownAgentParser.js'\nimport { logger } from '../utils/logger.js'\nimport type { IloomSettings } from './SettingsManager.js'\nimport { PromptTemplateManager, TemplateVariables } from './PromptTemplateManager.js'\n\n// Agent schema interface\nexport interface AgentConfig {\n\tdescription: string\n\tprompt: string\n\ttools?: string[] // Optional - when omitted, agent inherits all tools from parent\n\tmodel: string\n\tcolor?: string\n}\n\n// Container for all loaded agents (keyed by agent name without extension)\nexport interface AgentConfigs {\n\t[agentName: string]: AgentConfig\n}\n\nexport class AgentManager {\n\tprivate agentDir: string\n\tprivate templateManager: PromptTemplateManager\n\n\tconstructor(agentDir?: string, templateManager?: PromptTemplateManager) {\n\t\tthis.templateManager = templateManager ?? new PromptTemplateManager()\n\t\tif (agentDir) {\n\t\t\tthis.agentDir = agentDir\n\t\t} else {\n\t\t\t// Find agents relative to package installation\n\t\t\t// Same pattern as PromptTemplateManager\n\t\t\t// When running from dist/, agents are copied to dist/agents/\n\t\t\tconst currentFileUrl = import.meta.url\n\t\t\tconst currentFilePath = fileURLToPath(currentFileUrl)\n\t\t\tconst distDir = path.dirname(currentFilePath)\n\n\t\t\t// Walk up to find the agents directory\n\t\t\tlet agentDirPath = path.join(distDir, 'agents')\n\t\t\tlet currentDir = distDir\n\n\t\t\twhile (currentDir !== path.dirname(currentDir)) {\n\t\t\t\tconst candidatePath = path.join(currentDir, 'agents')\n\t\t\t\ttry {\n\t\t\t\t\taccessSync(candidatePath)\n\t\t\t\t\tagentDirPath = candidatePath\n\t\t\t\t\tbreak\n\t\t\t\t} catch {\n\t\t\t\t\tcurrentDir = path.dirname(currentDir)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.agentDir = agentDirPath\n\t\t\tlogger.debug('AgentManager initialized', { agentDir: this.agentDir })\n\t\t}\n\t}\n\n\t/**\n\t * Load agent configuration files from markdown (.md) format\n\t * Optionally apply model overrides from settings and template variable substitution\n\t * Throws error if agents directory doesn't exist or files are malformed\n\t * @param settings - Optional project settings with per-agent model overrides\n\t * @param templateVariables - Optional variables for template substitution in agent prompts\n\t * @param patterns - Optional glob patterns to filter which agents to load (default: ['*.md'])\n\t * Supports negation patterns like ['*.md', '!iloom-framework-detector.md']\n\t */\n\tasync loadAgents(\n\t\tsettings?: IloomSettings,\n\t\ttemplateVariables?: TemplateVariables,\n\t\tpatterns: string[] = ['*.md']\n\t): Promise<AgentConfigs> {\n\t\t// Use fast-glob to filter agent files based on patterns\n\t\tconst agentFiles = await fg(patterns, {\n\t\t\tcwd: this.agentDir,\n\t\t\tonlyFiles: true,\n\t\t})\n\n\t\tconst agents: AgentConfigs = {}\n\n\t\tfor (const filename of agentFiles) {\n\t\t\tconst agentPath = path.join(this.agentDir, filename)\n\n\t\t\ttry {\n\t\t\t\tconst content = await readFile(agentPath, 'utf-8')\n\n\t\t\t\t// Parse markdown with frontmatter\n\t\t\t\tconst parsed = this.parseMarkdownAgent(content, filename)\n\t\t\t\tconst agentConfig = parsed.config\n\t\t\t\tconst agentName = parsed.name\n\n\t\t\t\t// Validate required fields\n\t\t\t\tthis.validateAgentConfig(agentConfig, agentName)\n\n\t\t\t\tagents[agentName] = agentConfig\n\t\t\t\tlogger.debug(`Loaded agent: ${agentName}`)\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(`Failed to load agent from ${filename}`, { error })\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to load agent from ${filename}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Apply template variable substitution to agent prompts if variables provided\n\t\tif (templateVariables) {\n\t\t\t// Extract review config from settings with defaults and add to template variables\n\t\t\tconst reviewerSettings = settings?.agents?.['iloom-code-reviewer']\n\t\t\tconst reviewEnabled = reviewerSettings?.enabled !== false // Default to true\n\n\t\t\ttemplateVariables.REVIEW_ENABLED = reviewEnabled\n\n\t\t\tif (reviewEnabled) {\n\t\t\t\tconst providers = reviewerSettings?.providers ?? {}\n\t\t\t\t// Default to Claude if no providers specified\n\t\t\t\tconst hasAnyProvider = Object.keys(providers).length > 0\n\n\t\t\t\t// Determine Claude model: use configured, or default to 'sonnet' if no providers specified\n\t\t\t\tconst claudeModel = providers.claude ?? (hasAnyProvider ? undefined : 'sonnet')\n\t\t\t\tif (claudeModel) {\n\t\t\t\t\ttemplateVariables.REVIEW_CLAUDE_MODEL = claudeModel\n\t\t\t\t}\n\t\t\t\tif (providers.gemini) {\n\t\t\t\t\ttemplateVariables.REVIEW_GEMINI_MODEL = providers.gemini\n\t\t\t\t}\n\t\t\t\tif (providers.codex) {\n\t\t\t\t\ttemplateVariables.REVIEW_CODEX_MODEL = providers.codex\n\t\t\t\t}\n\t\t\t\ttemplateVariables.HAS_REVIEW_CLAUDE = !!claudeModel\n\t\t\t\ttemplateVariables.HAS_REVIEW_GEMINI = !!providers.gemini\n\t\t\t\ttemplateVariables.HAS_REVIEW_CODEX = !!providers.codex\n\t\t\t}\n\n\t\t\tfor (const [agentName, agentConfig] of Object.entries(agents)) {\n\t\t\t\tagents[agentName] = {\n\t\t\t\t\t...agentConfig,\n\t\t\t\t\tprompt: this.templateManager.substituteVariables(agentConfig.prompt, templateVariables),\n\t\t\t\t}\n\t\t\t\tlogger.debug(`Applied template substitution to agent: ${agentName}`)\n\t\t\t}\n\t\t}\n\n\t\t// Apply settings overrides if provided\n\t\tif (settings?.agents) {\n\t\t\tfor (const [agentName, agentSettings] of Object.entries(settings.agents)) {\n\t\t\t\tif (agents[agentName] && agentSettings.model) {\n\t\t\t\t\tlogger.debug(`Overriding model for ${agentName}: ${agents[agentName].model} -> ${agentSettings.model}`)\n\t\t\t\t\tagents[agentName] = {\n\t\t\t\t\t\t...agents[agentName],\n\t\t\t\t\t\tmodel: agentSettings.model,\n\t\t\t\t\t}\n\t\t\t\t} else if (!agents[agentName]) {\n\t\t\t\t\tlogger.warn(`Settings reference unknown agent: ${agentName}`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn agents\n\t}\n\n\t/**\n\t * Validate agent configuration has required fields\n\t * Note: tools is optional - when omitted, agent inherits all tools from parent\n\t */\n\tprivate validateAgentConfig(config: AgentConfig, agentName: string): void {\n\t\tconst requiredFields: (keyof AgentConfig)[] = ['description', 'prompt', 'model']\n\n\t\tfor (const field of requiredFields) {\n\t\t\tif (!config[field]) {\n\t\t\t\tthrow new Error(`Agent ${agentName} missing required field: ${field}`)\n\t\t\t}\n\t\t}\n\n\t\t// Tools is optional, but if present must be an array\n\t\tif (config.tools !== undefined && !Array.isArray(config.tools)) {\n\t\t\tthrow new Error(`Agent ${agentName} tools must be an array`)\n\t\t}\n\t}\n\n\t/**\n\t * Parse markdown agent file with YAML frontmatter\n\t * @param content - Raw markdown file content\n\t * @param filename - Original filename for error messages\n\t * @returns Parsed agent config and name\n\t */\n\tprivate parseMarkdownAgent(content: string, filename: string): { config: AgentConfig; name: string } {\n\t\ttry {\n\t\t\t// Parse frontmatter using custom parser\n\t\t\tconst { data, content: markdownBody } = MarkdownAgentParser.parse(content)\n\n\t\t\t// Validate frontmatter has required fields\n\t\t\tif (!data.name) {\n\t\t\t\tthrow new Error('Missing required field: name')\n\t\t\t}\n\t\t\tif (!data.description) {\n\t\t\t\tthrow new Error('Missing required field: description')\n\t\t\t}\n\t\t\t// Note: tools is now optional - when omitted, agent inherits all tools from parent\n\t\t\tif (!data.model) {\n\t\t\t\tthrow new Error('Missing required field: model')\n\t\t\t}\n\n\t\t\t// Parse tools from comma-separated string to array (only if tools field is present)\n\t\t\tlet tools: string[] | undefined\n\t\t\tif (data.tools) {\n\t\t\t\ttools = data.tools\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map((tool: string) => tool.trim())\n\t\t\t\t\t.filter((tool: string) => tool.length > 0)\n\t\t\t}\n\n\t\t\t// Validate model and warn if non-standard\n\t\t\tconst validModels = ['sonnet', 'opus', 'haiku']\n\t\t\tif (!validModels.includes(data.model)) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Agent ${data.name} uses model \"${data.model}\" which may not be recognized by Claude CLI, and your workflow may fail or produce unexpected results. ` +\n\t\t\t\t\t\t`Valid values are: ${validModels.join(', ')}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Construct AgentConfig\n\t\t\tconst config: AgentConfig = {\n\t\t\t\tdescription: data.description,\n\t\t\t\tprompt: markdownBody.trim(),\n\t\t\t\tmodel: data.model,\n\t\t\t\t...(tools && { tools }),\n\t\t\t\t...(data.color && { color: data.color }),\n\t\t\t}\n\n\t\t\treturn { config, name: data.name }\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to parse markdown agent ${filename}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Format loaded agents for Claude CLI --agents flag\n\t * Returns object suitable for JSON.stringify\n\t */\n\tformatForCli(agents: AgentConfigs): Record<string, unknown> {\n\t\t// The agents object is already in the correct format\n\t\t// Just return it - launchClaude will JSON.stringify it\n\t\treturn agents as Record<string, unknown>\n\t}\n}\n","/**\n * Custom YAML frontmatter parser for agent markdown files\n * Replaces gray-matter dependency with lightweight custom implementation\n */\n\ninterface ParseResult {\n\tdata: Record<string, string>\n\tcontent: string\n}\n\nexport class MarkdownAgentParser {\n\t/**\n\t * Parse markdown content with YAML frontmatter\n\t * @param content - Raw markdown file content\n\t * @returns Object with parsed frontmatter data and markdown body content\n\t * @throws Error if frontmatter is malformed or missing\n\t */\n\tstatic parse(content: string): ParseResult {\n\t\tconst lines = content.split('\\n')\n\n\t\t// Check for opening frontmatter delimiter\n\t\tif (lines[0]?.trim() !== '---') {\n\t\t\tthrow new Error('Missing opening frontmatter delimiter (---)')\n\t\t}\n\n\t\t// Find closing frontmatter delimiter\n\t\tlet closingDelimiterIndex = -1\n\t\tfor (let i = 1; i < lines.length; i++) {\n\t\t\tif (lines[i]?.trim() === '---') {\n\t\t\t\tclosingDelimiterIndex = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif (closingDelimiterIndex === -1) {\n\t\t\tthrow new Error('Missing closing frontmatter delimiter (---)')\n\t\t}\n\n\t\t// Extract frontmatter lines (between the delimiters)\n\t\tconst frontmatterLines = lines.slice(1, closingDelimiterIndex)\n\n\t\t// Extract markdown body (after closing delimiter)\n\t\tconst bodyLines = lines.slice(closingDelimiterIndex + 1)\n\t\tconst markdownBody = bodyLines.join('\\n')\n\n\t\t// Parse YAML frontmatter into key-value pairs\n\t\tconst data = this.parseYaml(frontmatterLines.join('\\n'))\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tcontent: markdownBody,\n\t\t}\n\t}\n\n\t/**\n\t * Parse simplified YAML into key-value object\n\t * Supports:\n\t * - Simple key: value pairs\n\t * - Multiline values with | indicator\n\t * - Values with special characters and newlines\n\t *\n\t * @param yaml - YAML string to parse\n\t * @returns Object with parsed key-value pairs\n\t */\n\tprivate static parseYaml(yaml: string): Record<string, string> {\n\t\tconst result: Record<string, string> = {}\n\t\tconst lines = yaml.split('\\n')\n\t\tlet currentKey: string | null = null\n\t\tlet currentValue: string[] = []\n\t\tlet isMultiline = false\n\n\t\tconst finalizeCurrent = (): void => {\n\t\t\tif (currentKey && currentValue.length > 0) {\n\t\t\t\tresult[currentKey] = currentValue.join('\\n').trim()\n\t\t\t\tcurrentKey = null\n\t\t\t\tcurrentValue = []\n\t\t\t}\n\t\t}\n\n\t\tfor (const line of lines) {\n\t\t\t// Skip empty lines when not in multiline mode\n\t\t\tif (!isMultiline && line.trim() === '') {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Check if this is a new key-value pair\n\t\t\tconst keyValueMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)\\s*:\\s*(.*)$/)\n\n\t\t\tif (keyValueMatch && !isMultiline) {\n\t\t\t\t// Finalize previous key if exists\n\t\t\t\tfinalizeCurrent()\n\n\t\t\t\tconst [, key, value] = keyValueMatch\n\t\t\t\tif (!key || value === undefined) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tcurrentKey = key\n\n\t\t\t\t// Check for multiline indicator\n\t\t\t\tif (value.trim() === '|') {\n\t\t\t\t\tisMultiline = true\n\t\t\t\t\tcurrentValue = []\n\t\t\t\t} else {\n\t\t\t\t\t// Single line value\n\t\t\t\t\tcurrentValue = [value]\n\t\t\t\t\tfinalizeCurrent()\n\t\t\t\t\tisMultiline = false\n\t\t\t\t}\n\t\t\t} else if (isMultiline && currentKey) {\n\t\t\t\t// Continuation of multiline value\n\t\t\t\t// Check if we've returned to normal indentation (new key)\n\t\t\t\tif (line.match(/^[a-zA-Z_][a-zA-Z0-9_-]*\\s*:/) && !line.startsWith(' ')) {\n\t\t\t\t\t// End of multiline, this is a new key\n\t\t\t\t\tfinalizeCurrent()\n\t\t\t\t\tisMultiline = false\n\n\t\t\t\t\t// Process this line as a new key\n\t\t\t\t\tconst match = line.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)\\s*:\\s*(.*)$/)\n\t\t\t\t\tif (match) {\n\t\t\t\t\t\tconst [, key, value] = match\n\t\t\t\t\t\tif (key && value !== undefined) {\n\t\t\t\t\t\t\tcurrentKey = key\n\t\t\t\t\t\t\tcurrentValue = [value]\n\t\t\t\t\t\t\tfinalizeCurrent()\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// Remove leading spaces (common indentation) from multiline values\n\t\t\t\t\tconst trimmedLine = line.replace(/^ {2}/, '')\n\t\t\t\t\tcurrentValue.push(trimmedLine)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Finalize last key\n\t\tfinalizeCurrent()\n\n\t\treturn result\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generateIssueManagementMcpConfig
4
- } from "./chunk-XAMBIVXE.js";
4
+ } from "./chunk-XJHQVOT6.js";
5
5
  import {
6
6
  openBrowser
7
7
  } from "./chunk-YETJNRQM.js";
8
8
  import {
9
9
  waitForKeypress
10
- } from "./chunk-ZX3GTM7O.js";
10
+ } from "./chunk-7JDMYTFZ.js";
11
11
  import {
12
12
  launchClaude
13
13
  } from "./chunk-IGKPPACU.js";
@@ -244,4 +244,4 @@ export {
244
244
  IssueEnhancementService,
245
245
  capitalizeFirstLetter
246
246
  };
247
- //# sourceMappingURL=chunk-VYKKWU36.js.map
247
+ //# sourceMappingURL=chunk-4KGRPHM6.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  extractIssueNumber
4
- } from "./chunk-ZA575VLF.js";
4
+ } from "./chunk-GDS2HXSW.js";
5
5
  import {
6
6
  extractPort,
7
7
  findEnvFileContainingVariable,
@@ -108,4 +108,4 @@ export {
108
108
  calculatePortFromIdentifier,
109
109
  getWorkspacePort
110
110
  };
111
- //# sourceMappingURL=chunk-CFQVOTHO.js.map
111
+ //# sourceMappingURL=chunk-52MVUK5V.js.map
@@ -76,4 +76,4 @@ var PromptTemplateManager = class {
76
76
  export {
77
77
  PromptTemplateManager
78
78
  };
79
- //# sourceMappingURL=chunk-TIYJEEVO.js.map
79
+ //# sourceMappingURL=chunk-66QOCD5N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/PromptTemplateManager.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport { accessSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport Handlebars from 'handlebars'\nimport { logger } from '../utils/logger.js'\n\n// Register raw helper to handle content with curly braces (e.g., JSON)\n// Usage: {{{{raw}}}}{{VARIABLE}}{{{{/raw}}}}\n// This outputs the variable content as-is without Handlebars parsing its curly braces\nHandlebars.registerHelper('raw', function (this: unknown, options: Handlebars.HelperOptions) {\n\treturn options.fn(this)\n})\n\nexport interface TemplateVariables {\n\tISSUE_NUMBER?: string | number\n\tPR_NUMBER?: number\n\tISSUE_TITLE?: string\n\tPR_TITLE?: string\n\tWORKSPACE_PATH?: string\n\tPORT?: number\n\tONE_SHOT_MODE?: boolean\n\tINTERACTIVE_MODE?: boolean\n\tSETTINGS_SCHEMA?: string\n\tSETTINGS_GLOBAL_JSON?: string\n\tSETTINGS_JSON?: string\n\tSETTINGS_LOCAL_JSON?: string\n\tSHELL_TYPE?: string\n\tSHELL_CONFIG_PATH?: string\n\tSHELL_CONFIG_CONTENT?: string\n\tREMOTES_INFO?: string\n\tMULTIPLE_REMOTES?: string\n\tSINGLE_REMOTE?: string\n\tSINGLE_REMOTE_NAME?: string\n\tSINGLE_REMOTE_URL?: string\n\tNO_REMOTES?: string\n\tREADME_CONTENT?: string\n\tSETTINGS_SCHEMA_CONTENT?: string\n\tFIRST_TIME_USER?: boolean\n\tVSCODE_SETTINGS_GITIGNORED?: string\n\t// Session summary template variables\n\tSESSION_CONTEXT?: string // Session ID for Claude to reference its conversation\n\tBRANCH_NAME?: string // Branch being finished\n\tLOOM_TYPE?: string // 'issue' or 'pr'\n\tCOMPACT_SUMMARIES?: string // Extracted compact summaries from session transcript\n\tRECAP_DATA?: string // Formatted recap data (goal, complexity, entries, artifacts)\n\t// Draft PR mode variables - mutually exclusive with standard issue mode\n\tDRAFT_PR_NUMBER?: number // PR number for draft PR workflow\n\tDRAFT_PR_MODE?: boolean // True when using github-draft-pr merge mode\n\tSTANDARD_ISSUE_MODE?: boolean // True when using standard issue commenting (not draft PR)\n\t// VS Code environment detection\n\tIS_VSCODE_MODE?: boolean // True when ILOOM_VSCODE=1 environment variable is set\n\t// Multi-language support variables - mutually exclusive\n\tHAS_PACKAGE_JSON?: boolean // True when project has package.json\n\tNO_PACKAGE_JSON?: boolean // True when project does not have package.json (non-Node.js projects)\n\t// Review agent configuration variables\n\tREVIEW_ENABLED?: boolean // True if review is enabled (defaults to true)\n\tREVIEW_CLAUDE_MODEL?: string // Claude model if configured (defaults to 'sonnet')\n\tREVIEW_GEMINI_MODEL?: string // Gemini model if configured\n\tREVIEW_CODEX_MODEL?: string // Codex model if configured\n\tHAS_REVIEW_CLAUDE?: boolean // True if claude provider configured (defaults to true)\n\tHAS_REVIEW_GEMINI?: boolean // True if gemini provider configured\n\tHAS_REVIEW_CODEX?: boolean // True if codex provider configured\n\t// Planning mode variables - mutually exclusive\n\tEXISTING_ISSUE_MODE?: boolean // True when decomposing an existing issue (il plan 42)\n\tFRESH_PLANNING_MODE?: boolean // True when starting fresh planning session (il plan \"feature idea\")\n\t// Issue context for decomposition mode\n\tPARENT_ISSUE_NUMBER?: string | undefined // Issue number being decomposed\n\tPARENT_ISSUE_TITLE?: string | undefined // Title of issue being decomposed\n\tPARENT_ISSUE_BODY?: string | undefined // Body of issue being decomposed\n\t// Existing children and dependencies context for decomposition mode\n\tPARENT_ISSUE_CHILDREN?: string | undefined // Formatted list of existing child issues (if any)\n\tPARENT_ISSUE_DEPENDENCIES?: string | undefined // Formatted list of existing dependencies (if any)\n\t// Multi-AI provider support for plan command\n\tPLANNER?: 'claude' | 'gemini' | 'codex'\n\tREVIEWER?: 'claude' | 'gemini' | 'codex' | 'none'\n\tUSE_CLAUDE_PLANNER?: boolean\n\tUSE_GEMINI_PLANNER?: boolean\n\tUSE_CODEX_PLANNER?: boolean\n\tUSE_CLAUDE_REVIEWER?: boolean\n\tUSE_GEMINI_REVIEWER?: boolean\n\tUSE_CODEX_REVIEWER?: boolean\n\tHAS_REVIEWER?: boolean\n}\n\nexport class PromptTemplateManager {\n\tprivate templateDir: string\n\n\tconstructor(templateDir?: string) {\n\t\tif (templateDir) {\n\t\t\tthis.templateDir = templateDir\n\t\t} else {\n\t\t\t// Find templates relative to the package installation\n\t\t\t// When running from dist/, templates are copied to dist/prompts/\n\t\t\tconst currentFileUrl = import.meta.url\n\t\t\tconst currentFilePath = fileURLToPath(currentFileUrl)\n\t\t\tconst distDir = path.dirname(currentFilePath) // dist directory (may be chunked file location)\n\n\t\t\t// Walk up to find the dist directory (in case of chunked files)\n\t\t\tlet templateDir = path.join(distDir, 'prompts')\n\t\t\tlet currentDir = distDir\n\n\t\t\t// Try to find the prompts directory by walking up\n\t\t\twhile (currentDir !== path.dirname(currentDir)) {\n\t\t\t\tconst candidatePath = path.join(currentDir, 'prompts')\n\t\t\t\ttry {\n\t\t\t\t\t// Check if this directory exists (sync check for constructor)\n\t\t\t\t\taccessSync(candidatePath)\n\t\t\t\t\ttemplateDir = candidatePath\n\t\t\t\t\tbreak\n\t\t\t\t} catch {\n\t\t\t\t\tcurrentDir = path.dirname(currentDir)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.templateDir = templateDir\n\t\t\tlogger.debug('PromptTemplateManager initialized', {\n\t\t\t\tcurrentFilePath,\n\t\t\t\tdistDir,\n\t\t\t\ttemplateDir: this.templateDir\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Load a template file by name\n\t */\n\tasync loadTemplate(templateName: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan'): Promise<string> {\n\t\tconst templatePath = path.join(this.templateDir, `${templateName}-prompt.txt`)\n\n\t\tlogger.debug('Loading template', {\n\t\t\ttemplateName,\n\t\t\ttemplateDir: this.templateDir,\n\t\t\ttemplatePath\n\t\t})\n\n\t\ttry {\n\t\t\treturn await readFile(templatePath, 'utf-8')\n\t\t} catch (error) {\n\t\t\tlogger.error('Failed to load template', { templateName, templatePath, error })\n\t\t\tthrow new Error(`Template not found: ${templatePath}`)\n\t\t}\n\t}\n\n\t/**\n\t * Substitute variables in a template string using Handlebars\n\t */\n\tsubstituteVariables(template: string, variables: TemplateVariables): string {\n\t\tconst compiled = Handlebars.compile(template, { noEscape: true })\n\t\treturn compiled(variables)\n\t}\n\n\t/**\n\t * Get a fully processed prompt for a workflow type\n\t */\n\tasync getPrompt(\n\t\ttype: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan',\n\t\tvariables: TemplateVariables\n\t): Promise<string> {\n\t\tconst template = await this.loadTemplate(type)\n\t\treturn this.substituteVariables(template, variables)\n\t}\n}\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,gBAAgB;AAMvB,WAAW,eAAe,OAAO,SAAyB,SAAmC;AAC5F,SAAO,QAAQ,GAAG,IAAI;AACvB,CAAC;AAyEM,IAAM,wBAAN,MAA4B;AAAA,EAGlC,YAAY,aAAsB;AACjC,QAAI,aAAa;AAChB,WAAK,cAAc;AAAA,IACpB,OAAO;AAGN,YAAM,iBAAiB,YAAY;AACnC,YAAM,kBAAkB,cAAc,cAAc;AACpD,YAAM,UAAU,KAAK,QAAQ,eAAe;AAG5C,UAAIA,eAAc,KAAK,KAAK,SAAS,SAAS;AAC9C,UAAI,aAAa;AAGjB,aAAO,eAAe,KAAK,QAAQ,UAAU,GAAG;AAC/C,cAAM,gBAAgB,KAAK,KAAK,YAAY,SAAS;AACrD,YAAI;AAEH,qBAAW,aAAa;AACxB,UAAAA,eAAc;AACd;AAAA,QACD,QAAQ;AACP,uBAAa,KAAK,QAAQ,UAAU;AAAA,QACrC;AAAA,MACD;AAEA,WAAK,cAAcA;AACnB,aAAO,MAAM,qCAAqC;AAAA,QACjD;AAAA,QACA;AAAA,QACA,aAAa,KAAK;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,cAAiG;AACnH,UAAM,eAAe,KAAK,KAAK,KAAK,aAAa,GAAG,YAAY,aAAa;AAE7E,WAAO,MAAM,oBAAoB;AAAA,MAChC;AAAA,MACA,aAAa,KAAK;AAAA,MAClB;AAAA,IACD,CAAC;AAED,QAAI;AACH,aAAO,MAAM,SAAS,cAAc,OAAO;AAAA,IAC5C,SAAS,OAAO;AACf,aAAO,MAAM,2BAA2B,EAAE,cAAc,cAAc,MAAM,CAAC;AAC7E,YAAM,IAAI,MAAM,uBAAuB,YAAY,EAAE;AAAA,IACtD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,UAAkB,WAAsC;AAC3E,UAAM,WAAW,WAAW,QAAQ,UAAU,EAAE,UAAU,KAAK,CAAC;AAChE,WAAO,SAAS,SAAS;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UACL,MACA,WACkB;AAClB,UAAM,WAAW,MAAM,KAAK,aAAa,IAAI;AAC7C,WAAO,KAAK,oBAAoB,UAAU,SAAS;AAAA,EACpD;AACD;","names":["templateDir"]}
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ logger
4
+ } from "./chunk-VT4PDUYT.js";
5
+
6
+ // src/utils/prompt.ts
7
+ import * as readline from "readline";
8
+
9
+ // src/utils/notification.ts
10
+ import net from "net";
11
+ import fs from "fs";
12
+ import path from "path";
13
+ import os from "os";
14
+ import { execSync } from "child_process";
15
+ var DEBUG = process.env.ILOOM_NOTIF_DEBUG === "1";
16
+ var LOG_FILE = "/tmp/iloom-notif.log";
17
+ function debug(message, data = {}) {
18
+ if (!DEBUG) return;
19
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
20
+ const dataStr = Object.keys(data).length > 0 ? ` ${JSON.stringify(data)}` : "";
21
+ const logLine = `[${timestamp}] ${message}${dataStr}
22
+ `;
23
+ try {
24
+ fs.appendFileSync(LOG_FILE, logLine);
25
+ } catch {
26
+ }
27
+ }
28
+ function slugifyPath(worktreePath) {
29
+ let slug = worktreePath.replace(/[/\\]+$/, "");
30
+ slug = slug.replace(/[/\\]/g, "___");
31
+ slug = slug.replace(/[^a-zA-Z0-9_-]/g, "-");
32
+ return `${slug}.json`;
33
+ }
34
+ function getMetadataFilePath(cwd) {
35
+ const loomsDir = path.join(os.homedir(), ".config", "iloom-ai", "looms");
36
+ return path.join(loomsDir, slugifyPath(cwd));
37
+ }
38
+ function readSessionId(cwd) {
39
+ try {
40
+ const filePath = getMetadataFilePath(cwd);
41
+ debug("Reading metadata file", { cwd, filePath });
42
+ if (!fs.existsSync(filePath)) {
43
+ debug("Metadata file not found", { filePath });
44
+ return null;
45
+ }
46
+ const content = fs.readFileSync(filePath, "utf8");
47
+ const metadata = JSON.parse(content);
48
+ debug("Read session ID from metadata", { sessionId: metadata.sessionId });
49
+ return metadata.sessionId ?? null;
50
+ } catch (error) {
51
+ debug("Failed to read session ID", { cwd, error: String(error) });
52
+ return null;
53
+ }
54
+ }
55
+ function findWindowsNamedPipes() {
56
+ try {
57
+ const output = execSync(
58
+ `powershell -Command "Get-ChildItem \\\\.\\pipe\\ | Where-Object { $_.Name -like 'iloom-*' } | Select-Object -ExpandProperty FullName"`,
59
+ { encoding: "utf-8", timeout: 5e3 }
60
+ );
61
+ return output.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
62
+ } catch {
63
+ return [];
64
+ }
65
+ }
66
+ function findAllIloomSockets() {
67
+ if (process.platform === "win32") {
68
+ return findWindowsNamedPipes();
69
+ }
70
+ try {
71
+ const tempDir = "/tmp";
72
+ const files = fs.readdirSync(tempDir);
73
+ const sockets = files.filter((file) => file.startsWith("iloom-") && file.endsWith(".sock")).map((file) => path.join(tempDir, file)).filter((socketPath) => {
74
+ try {
75
+ const stat = fs.statSync(socketPath);
76
+ return stat.isSocket();
77
+ } catch {
78
+ return false;
79
+ }
80
+ });
81
+ return sockets;
82
+ } catch {
83
+ return [];
84
+ }
85
+ }
86
+ async function sendStatus(socketPath, status, cwd, hookEventName, sessionId, toolName) {
87
+ return new Promise((resolve) => {
88
+ const client = net.createConnection(socketPath, () => {
89
+ const message = JSON.stringify({
90
+ type: "session_status",
91
+ status,
92
+ session_id: sessionId,
93
+ hook_event_name: hookEventName,
94
+ tool_name: toolName,
95
+ cwd,
96
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
97
+ });
98
+ debug("Sending status to socket", { socketPath, status, sessionId, hookEventName, cwd });
99
+ client.write(message + "\n");
100
+ client.end();
101
+ resolve();
102
+ });
103
+ client.on("error", (err) => {
104
+ debug("Socket connection error", { socketPath, error: String(err) });
105
+ resolve();
106
+ });
107
+ });
108
+ }
109
+ async function broadcastStatus(status, cwd, hookEventName, toolName) {
110
+ debug("broadcastStatus called", { status, cwd, hookEventName, toolName });
111
+ const sockets = findAllIloomSockets();
112
+ debug("Found sockets", { count: sockets.length, sockets });
113
+ if (sockets.length === 0) {
114
+ debug("No sockets found, skipping broadcast");
115
+ return;
116
+ }
117
+ const sessionId = readSessionId(cwd);
118
+ debug("Session ID for broadcast", { sessionId });
119
+ const promises = sockets.map(
120
+ (socketPath) => sendStatus(socketPath, status, cwd, hookEventName, sessionId, toolName).catch(() => {
121
+ })
122
+ );
123
+ await Promise.allSettled(promises);
124
+ debug("Broadcast completed");
125
+ }
126
+ async function broadcastApprovalNotification(cwd) {
127
+ await broadcastStatus("waiting_for_approval", cwd, "CommitApproval", "iloom_commit");
128
+ }
129
+ async function clearApprovalNotification(cwd) {
130
+ await broadcastStatus("working", cwd, "CommitApprovalResponse", "iloom_commit");
131
+ }
132
+
133
+ // src/utils/prompt.ts
134
+ async function promptConfirmation(message, defaultValue = false) {
135
+ const suffix = defaultValue ? "[Y/n]" : "[y/N]";
136
+ const fullMessage = `${message} ${suffix}: `;
137
+ while (true) {
138
+ const rl = readline.createInterface({
139
+ input: process.stdin,
140
+ output: process.stdout
141
+ });
142
+ const answer = await new Promise((resolve) => {
143
+ rl.question(fullMessage, (ans) => {
144
+ rl.close();
145
+ resolve(ans);
146
+ });
147
+ });
148
+ const normalized = answer.trim().toLowerCase();
149
+ if (normalized === "") {
150
+ return defaultValue;
151
+ }
152
+ if (normalized === "y" || normalized === "yes") {
153
+ return true;
154
+ }
155
+ if (normalized === "n" || normalized === "no") {
156
+ return false;
157
+ }
158
+ logger.warn("Invalid input. Please enter y/yes or n/no.");
159
+ }
160
+ }
161
+ async function promptInput(message, defaultValue) {
162
+ const rl = readline.createInterface({
163
+ input: process.stdin,
164
+ output: process.stdout
165
+ });
166
+ const suffix = defaultValue ? ` [${defaultValue}]` : "";
167
+ const fullMessage = `${message}${suffix}: `;
168
+ return new Promise((resolve) => {
169
+ rl.question(fullMessage, (answer) => {
170
+ rl.close();
171
+ const trimmed = answer.trim();
172
+ if (trimmed === "" && defaultValue !== void 0) {
173
+ resolve(defaultValue);
174
+ return;
175
+ }
176
+ resolve(trimmed);
177
+ });
178
+ });
179
+ }
180
+ async function waitForKeypress(message = "Press any key to continue...") {
181
+ if (!process.stdin.isTTY || typeof process.stdin.setRawMode !== "function") {
182
+ return "";
183
+ }
184
+ process.stdout.write(message);
185
+ return new Promise((resolve) => {
186
+ process.stdin.setRawMode(true);
187
+ process.stdin.resume();
188
+ process.stdin.once("data", (chunk) => {
189
+ const key = chunk.toString("utf8");
190
+ process.stdin.setRawMode(false);
191
+ process.stdin.pause();
192
+ if (key === "") {
193
+ process.stdout.write("\n");
194
+ process.exit(130);
195
+ }
196
+ process.stdout.write("\n");
197
+ resolve(key);
198
+ });
199
+ });
200
+ }
201
+ function isInteractiveEnvironment() {
202
+ return process.stdin.isTTY === true && process.env.CI !== "true";
203
+ }
204
+ async function promptCommitAction(message) {
205
+ if (!isInteractiveEnvironment()) {
206
+ return "accept";
207
+ }
208
+ const cwd = process.cwd();
209
+ process.stdout.write("\n" + "=".repeat(60) + "\n");
210
+ process.stdout.write("COMMIT MESSAGE:\n");
211
+ process.stdout.write("=".repeat(60) + "\n");
212
+ process.stdout.write(message + "\n");
213
+ process.stdout.write("=".repeat(60) + "\n\n");
214
+ await broadcastApprovalNotification(cwd);
215
+ try {
216
+ while (true) {
217
+ const rl = readline.createInterface({
218
+ input: process.stdin,
219
+ output: process.stdout
220
+ });
221
+ const answer = await new Promise((resolve) => {
222
+ rl.question("[A]ccept as-is, [E]dit in editor, A[b]ort? [A/e/b]: ", (ans) => {
223
+ rl.close();
224
+ resolve(ans);
225
+ });
226
+ });
227
+ const normalized = answer.trim().toLowerCase();
228
+ if (normalized === "" || normalized === "a" || normalized === "accept") {
229
+ return "accept";
230
+ }
231
+ if (normalized === "e" || normalized === "edit") {
232
+ return "edit";
233
+ }
234
+ if (normalized === "b" || normalized === "abort") {
235
+ return "abort";
236
+ }
237
+ logger.warn("Invalid input. Please enter A (accept), E (edit), or B (abort).");
238
+ }
239
+ } finally {
240
+ await clearApprovalNotification(cwd);
241
+ }
242
+ }
243
+
244
+ export {
245
+ promptConfirmation,
246
+ promptInput,
247
+ waitForKeypress,
248
+ isInteractiveEnvironment,
249
+ promptCommitAction
250
+ };
251
+ //# sourceMappingURL=chunk-7JDMYTFZ.js.map