@iloom/cli 0.9.2 → 0.10.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 (220) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +159 -40
  3. package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-ECJHBB67.js} +2 -2
  4. package/dist/ClaudeContextManager-QXX6ZFST.js +14 -0
  5. package/dist/ClaudeService-NJNK2SUH.js +13 -0
  6. package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
  7. package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
  8. package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-L64HHS3T.js} +9 -9
  9. package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
  10. package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
  11. package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-DULSVRRE.js} +2 -2
  12. package/dist/README.md +159 -40
  13. package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-BQDQA3FK.js} +4 -2
  14. package/dist/agents/iloom-artifact-reviewer.md +11 -0
  15. package/dist/agents/iloom-code-reviewer.md +14 -0
  16. package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
  17. package/dist/agents/iloom-issue-analyzer.md +49 -6
  18. package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
  19. package/dist/agents/iloom-issue-enhancer.md +86 -7
  20. package/dist/agents/iloom-issue-implementer.md +48 -7
  21. package/dist/agents/iloom-issue-planner.md +115 -62
  22. package/dist/{build-THZI572G.js → build-5GO3XW26.js} +9 -9
  23. package/dist/{chunk-NUACL52E.js → chunk-3D7WQM7I.js} +2 -2
  24. package/dist/chunk-4232AHNQ.js +35 -0
  25. package/dist/chunk-4232AHNQ.js.map +1 -0
  26. package/dist/{chunk-QN47QVBX.js → chunk-4WJNIR5O.js} +1 -1
  27. package/dist/chunk-4WJNIR5O.js.map +1 -0
  28. package/dist/{chunk-A7NJF73J.js → chunk-5MWV33NN.js} +4 -4
  29. package/dist/{chunk-3I4ONZRT.js → chunk-6EU6TCF6.js} +10 -10
  30. package/dist/chunk-6EU6TCF6.js.map +1 -0
  31. package/dist/{chunk-CWRI4JC3.js → chunk-FB47TIJG.js} +29 -11
  32. package/dist/chunk-FB47TIJG.js.map +1 -0
  33. package/dist/chunk-HEXKPKCK.js +1396 -0
  34. package/dist/chunk-HEXKPKCK.js.map +1 -0
  35. package/dist/{chunk-KAYXR544.js → chunk-J5S7DFYC.js} +2 -2
  36. package/dist/{chunk-ULSWCPQG.js → chunk-JO2LZ6EQ.js} +476 -5
  37. package/dist/chunk-JO2LZ6EQ.js.map +1 -0
  38. package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
  39. package/dist/chunk-KB64WNBZ.js.map +1 -0
  40. package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
  41. package/dist/chunk-KXDRI47U.js.map +1 -0
  42. package/dist/{chunk-R4YWBGY6.js → chunk-LXLMMXXY.js} +54 -14
  43. package/dist/chunk-LXLMMXXY.js.map +1 -0
  44. package/dist/{chunk-AR5QKYNE.js → chunk-MNHZB4Z2.js} +4 -4
  45. package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
  46. package/dist/{chunk-KJTVU3HZ.js → chunk-NRSWLOAZ.js} +8 -8
  47. package/dist/chunk-NRSWLOAZ.js.map +1 -0
  48. package/dist/{chunk-FO5GGFOV.js → chunk-ONQYPICO.js} +13 -5
  49. package/dist/chunk-ONQYPICO.js.map +1 -0
  50. package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
  51. package/dist/chunk-QZWEJVWV.js +207 -0
  52. package/dist/chunk-QZWEJVWV.js.map +1 -0
  53. package/dist/chunk-RSYT7MVI.js +202 -0
  54. package/dist/chunk-RSYT7MVI.js.map +1 -0
  55. package/dist/{chunk-Z2TWEXR7.js → chunk-RYWFS37M.js} +6 -6
  56. package/dist/chunk-RYWFS37M.js.map +1 -0
  57. package/dist/{chunk-B7U6OKUR.js → chunk-SF2P22EE.js} +11 -3
  58. package/dist/chunk-SF2P22EE.js.map +1 -0
  59. package/dist/{chunk-6IIL5M2L.js → chunk-SN3SQCFK.js} +10 -8
  60. package/dist/{chunk-6IIL5M2L.js.map → chunk-SN3SQCFK.js.map} +1 -1
  61. package/dist/{chunk-SOSQILHO.js → chunk-UD3WJDIV.js} +92 -82
  62. package/dist/chunk-UD3WJDIV.js.map +1 -0
  63. package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
  64. package/dist/chunk-UKBAJ2QQ.js.map +1 -0
  65. package/dist/{chunk-W6DP5RVR.js → chunk-UVD4CZKS.js} +3 -3
  66. package/dist/chunk-UWGVCXRF.js +207 -0
  67. package/dist/chunk-UWGVCXRF.js.map +1 -0
  68. package/dist/{chunk-NWMORW3U.js → chunk-VECNX6VX.js} +2 -2
  69. package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
  70. package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
  71. package/dist/{chunk-TC7APDKU.js → chunk-VGGST52X.js} +2 -2
  72. package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
  73. package/dist/{chunk-YKFCCV6S.js → chunk-WY4QBK43.js} +7 -7
  74. package/dist/chunk-WY4QBK43.js.map +1 -0
  75. package/dist/chunk-Y4YZTHZE.js +73 -0
  76. package/dist/chunk-Y4YZTHZE.js.map +1 -0
  77. package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
  78. package/dist/chunk-YQ57ORTV.js.map +1 -0
  79. package/dist/{chunk-RI2YL6TK.js → chunk-YYAKPQBT.js} +65 -18
  80. package/dist/chunk-YYAKPQBT.js.map +1 -0
  81. package/dist/{chunk-IZIYLYPK.js → chunk-ZEWU5PZK.js} +2 -2
  82. package/dist/{chunk-VPTAX5TR.js → chunk-ZHPNZC75.js} +12 -12
  83. package/dist/chunk-ZHPNZC75.js.map +1 -0
  84. package/dist/{chunk-DGG2VY7B.js → chunk-ZW2LKWWE.js} +9 -9
  85. package/dist/chunk-ZW2LKWWE.js.map +1 -0
  86. package/dist/{claude-TP2QO3BU.js → claude-P3NQR6IJ.js} +2 -2
  87. package/dist/{cleanup-PJRIFFU4.js → cleanup-6UCPVMFG.js} +81 -32
  88. package/dist/cleanup-6UCPVMFG.js.map +1 -0
  89. package/dist/cli.js +638 -349
  90. package/dist/cli.js.map +1 -1
  91. package/dist/{commit-IVP3M4HG.js → commit-L3EPY5QG.js} +21 -20
  92. package/dist/commit-L3EPY5QG.js.map +1 -0
  93. package/dist/{compile-R2J65HBQ.js → compile-ZS4HYRX5.js} +9 -9
  94. package/dist/{contribute-VDZXHK5Y.js → contribute-ORDDQGSL.js} +14 -6
  95. package/dist/contribute-ORDDQGSL.js.map +1 -0
  96. package/dist/{dev-server-7F622OEO.js → dev-server-FYZ2AQIH.js} +29 -15
  97. package/dist/dev-server-FYZ2AQIH.js.map +1 -0
  98. package/dist/{feedback-E7VET7CL.js → feedback-TMBXSCM5.js} +15 -15
  99. package/dist/{git-2QDQ2X2S.js → git-ET64COO3.js} +4 -4
  100. package/dist/hooks/iloom-hook.js +15 -0
  101. package/dist/ignite-CGOV3TD4.js +1393 -0
  102. package/dist/ignite-CGOV3TD4.js.map +1 -0
  103. package/dist/index.d.ts +382 -53
  104. package/dist/index.js +1167 -36
  105. package/dist/index.js.map +1 -1
  106. package/dist/{init-676DHF6R.js → init-GFQ5W7GK.js} +57 -21
  107. package/dist/init-GFQ5W7GK.js.map +1 -0
  108. package/dist/{issues-PJSOLOBJ.js → issues-T4ZZSPEG.js} +61 -20
  109. package/dist/issues-T4ZZSPEG.js.map +1 -0
  110. package/dist/{lint-CJM7BAIM.js → lint-6TQXDZ3T.js} +9 -9
  111. package/dist/mcp/issue-management-server.js +2471 -256
  112. package/dist/mcp/issue-management-server.js.map +1 -1
  113. package/dist/mcp/recap-server.js +144 -21
  114. package/dist/mcp/recap-server.js.map +1 -1
  115. package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
  116. package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
  117. package/dist/{open-544H7JF5.js → open-5QZGXQRF.js} +15 -15
  118. package/dist/open-5QZGXQRF.js.map +1 -0
  119. package/dist/{plan-Q7ELXDLC.js → plan-U7ZQWLFY.js} +41 -25
  120. package/dist/plan-U7ZQWLFY.js.map +1 -0
  121. package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
  122. package/dist/prompts/CLAUDE.md +62 -0
  123. package/dist/prompts/init-prompt.txt +347 -26
  124. package/dist/prompts/issue-prompt.txt +427 -54
  125. package/dist/prompts/plan-prompt.txt +97 -16
  126. package/dist/prompts/pr-prompt.txt +44 -1
  127. package/dist/prompts/regular-prompt.txt +42 -1
  128. package/dist/prompts/session-summary-prompt.txt +14 -0
  129. package/dist/prompts/swarm-orchestrator-prompt.txt +437 -0
  130. package/dist/{rebase-YND35CIE.js → rebase-DWIB77KV.js} +10 -10
  131. package/dist/{recap-3W7COH7D.js → recap-MX63HAKV.js} +47 -19
  132. package/dist/recap-MX63HAKV.js.map +1 -0
  133. package/dist/{run-QUXJKDQQ.js → run-O3TFNQFC.js} +15 -15
  134. package/dist/run-O3TFNQFC.js.map +1 -0
  135. package/dist/schema/package-iloom.schema.json +58 -0
  136. package/dist/schema/settings.schema.json +115 -15
  137. package/dist/{shell-QGECBLST.js → shell-G6VC2CYR.js} +14 -7
  138. package/dist/shell-G6VC2CYR.js.map +1 -0
  139. package/dist/{summary-G2T4452H.js → summary-FWHAX55O.js} +27 -25
  140. package/dist/summary-FWHAX55O.js.map +1 -0
  141. package/dist/{test-EA5NQFDC.js → test-F7JNJZYP.js} +9 -9
  142. package/dist/{test-git-M7LSLEFL.js → test-git-BTAOIUE2.js} +4 -4
  143. package/dist/test-jira-CHYNV33F.js +96 -0
  144. package/dist/test-jira-CHYNV33F.js.map +1 -0
  145. package/dist/{test-prefix-64NAAUON.js → test-prefix-Q6TFSU6F.js} +4 -4
  146. package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-EONCG7E7.js} +6 -6
  147. package/dist/{vscode-AR5NNXXI.js → vscode-VA5X4P25.js} +7 -7
  148. package/package.json +5 -1
  149. package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
  150. package/dist/ClaudeService-TK7FMC2X.js +0 -13
  151. package/dist/chunk-3I4ONZRT.js.map +0 -1
  152. package/dist/chunk-B7U6OKUR.js.map +0 -1
  153. package/dist/chunk-CWRI4JC3.js.map +0 -1
  154. package/dist/chunk-DGG2VY7B.js.map +0 -1
  155. package/dist/chunk-FJDRTVJX.js +0 -520
  156. package/dist/chunk-FJDRTVJX.js.map +0 -1
  157. package/dist/chunk-FO5GGFOV.js.map +0 -1
  158. package/dist/chunk-KBEIQP4G.js.map +0 -1
  159. package/dist/chunk-KJTVU3HZ.js.map +0 -1
  160. package/dist/chunk-KXGQYLFZ.js.map +0 -1
  161. package/dist/chunk-OFDN5NKS.js.map +0 -1
  162. package/dist/chunk-QN47QVBX.js.map +0 -1
  163. package/dist/chunk-R4YWBGY6.js.map +0 -1
  164. package/dist/chunk-RI2YL6TK.js.map +0 -1
  165. package/dist/chunk-SOSQILHO.js.map +0 -1
  166. package/dist/chunk-ULSWCPQG.js.map +0 -1
  167. package/dist/chunk-VOGGLPG5.js.map +0 -1
  168. package/dist/chunk-VPTAX5TR.js.map +0 -1
  169. package/dist/chunk-WHI5KEOX.js +0 -121
  170. package/dist/chunk-WHI5KEOX.js.map +0 -1
  171. package/dist/chunk-YKFCCV6S.js.map +0 -1
  172. package/dist/chunk-Z2TWEXR7.js.map +0 -1
  173. package/dist/cleanup-PJRIFFU4.js.map +0 -1
  174. package/dist/commit-IVP3M4HG.js.map +0 -1
  175. package/dist/contribute-VDZXHK5Y.js.map +0 -1
  176. package/dist/dev-server-7F622OEO.js.map +0 -1
  177. package/dist/ignite-IW35CDBD.js +0 -784
  178. package/dist/ignite-IW35CDBD.js.map +0 -1
  179. package/dist/init-676DHF6R.js.map +0 -1
  180. package/dist/issues-PJSOLOBJ.js.map +0 -1
  181. package/dist/open-544H7JF5.js.map +0 -1
  182. package/dist/plan-Q7ELXDLC.js.map +0 -1
  183. package/dist/recap-3W7COH7D.js.map +0 -1
  184. package/dist/run-QUXJKDQQ.js.map +0 -1
  185. package/dist/shell-QGECBLST.js.map +0 -1
  186. package/dist/summary-G2T4452H.js.map +0 -1
  187. /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-ECJHBB67.js.map} +0 -0
  188. /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-QXX6ZFST.js.map} +0 -0
  189. /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-NJNK2SUH.js.map} +0 -0
  190. /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
  191. /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
  192. /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-L64HHS3T.js.map} +0 -0
  193. /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
  194. /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
  195. /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-DULSVRRE.js.map} +0 -0
  196. /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-BQDQA3FK.js.map} +0 -0
  197. /package/dist/{build-THZI572G.js.map → build-5GO3XW26.js.map} +0 -0
  198. /package/dist/{chunk-NUACL52E.js.map → chunk-3D7WQM7I.js.map} +0 -0
  199. /package/dist/{chunk-A7NJF73J.js.map → chunk-5MWV33NN.js.map} +0 -0
  200. /package/dist/{chunk-KAYXR544.js.map → chunk-J5S7DFYC.js.map} +0 -0
  201. /package/dist/{chunk-AR5QKYNE.js.map → chunk-MNHZB4Z2.js.map} +0 -0
  202. /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
  203. /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
  204. /package/dist/{chunk-W6DP5RVR.js.map → chunk-UVD4CZKS.js.map} +0 -0
  205. /package/dist/{chunk-NWMORW3U.js.map → chunk-VECNX6VX.js.map} +0 -0
  206. /package/dist/{chunk-TC7APDKU.js.map → chunk-VGGST52X.js.map} +0 -0
  207. /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
  208. /package/dist/{chunk-IZIYLYPK.js.map → chunk-ZEWU5PZK.js.map} +0 -0
  209. /package/dist/{git-2QDQ2X2S.js.map → claude-P3NQR6IJ.js.map} +0 -0
  210. /package/dist/{compile-R2J65HBQ.js.map → compile-ZS4HYRX5.js.map} +0 -0
  211. /package/dist/{feedback-E7VET7CL.js.map → feedback-TMBXSCM5.js.map} +0 -0
  212. /package/dist/{neon-helpers-VVFFTLXE.js.map → git-ET64COO3.js.map} +0 -0
  213. /package/dist/{lint-CJM7BAIM.js.map → lint-6TQXDZ3T.js.map} +0 -0
  214. /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
  215. /package/dist/{rebase-YND35CIE.js.map → rebase-DWIB77KV.js.map} +0 -0
  216. /package/dist/{test-EA5NQFDC.js.map → test-F7JNJZYP.js.map} +0 -0
  217. /package/dist/{test-git-M7LSLEFL.js.map → test-git-BTAOIUE2.js.map} +0 -0
  218. /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-Q6TFSU6F.js.map} +0 -0
  219. /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-EONCG7E7.js.map} +0 -0
  220. /package/dist/{vscode-AR5NNXXI.js.map → vscode-VA5X4P25.js.map} +0 -0
@@ -325,6 +325,47 @@ The following JSON Schema defines valid iloom settings:
325
325
  "review": {
326
326
  "type": "boolean",
327
327
  "description": "Whether artifacts from this agent should be reviewed before posting (defaults to false)"
328
+ },
329
+ "agents": {
330
+ "type": "object",
331
+ "additionalProperties": {
332
+ "type": "object",
333
+ "properties": {
334
+ "model": {
335
+ "type": "string",
336
+ "enum": [
337
+ "sonnet",
338
+ "opus",
339
+ "haiku"
340
+ ],
341
+ "description": "Claude model shorthand: sonnet, opus, or haiku"
342
+ },
343
+ "enabled": {
344
+ "type": "boolean",
345
+ "description": "Whether this agent is enabled. Defaults to true."
346
+ },
347
+ "providers": {
348
+ "type": "object",
349
+ "additionalProperties": {
350
+ "type": "string"
351
+ },
352
+ "propertyNames": {
353
+ "enum": [
354
+ "claude",
355
+ "gemini",
356
+ "codex"
357
+ ]
358
+ },
359
+ "description": "Map of review providers to model names. Keys: claude, gemini, codex. Values: model name strings (e.g., \"sonnet\", \"gemini-3-pro-preview\", \"gpt-5.2-codex\")"
360
+ },
361
+ "review": {
362
+ "type": "boolean",
363
+ "description": "Whether artifacts from this agent should be reviewed before posting (defaults to false)"
364
+ }
365
+ },
366
+ "additionalProperties": false
367
+ },
368
+ "description": "Nested per-agent model overrides for swarm mode. Configure under agents.iloom-swarm-worker.agents.<agent-name>.model to set a different model for phase agents when running inside swarm workers. Fallback chain: swarm-specific agent model > explicit swarm worker model > base agent model. Only meaningful under the iloom-swarm-worker agent entry."
328
369
  }
329
370
  },
330
371
  "additionalProperties": false
@@ -336,7 +377,7 @@ The following JSON Schema defines valid iloom settings:
336
377
  "type": "null"
337
378
  }
338
379
  ],
339
- "description": "Per-agent configuration overrides. Available agents: iloom-issue-analyzer (analyzes issues), iloom-issue-planner (creates implementation plans), iloom-issue-analyze-and-plan (combined analysis and planning), iloom-issue-complexity-evaluator (evaluates complexity), iloom-issue-enhancer (enhances issue descriptions), iloom-issue-implementer (implements code changes), iloom-code-reviewer (reviews code changes against requirements), iloom-artifact-reviewer (reviews artifacts before posting)"
380
+ "description": "Per-agent configuration overrides. Available agents: iloom-issue-analyzer (analyzes issues), iloom-issue-planner (creates implementation plans), iloom-issue-analyze-and-plan (combined analysis and planning), iloom-issue-complexity-evaluator (evaluates complexity), iloom-issue-enhancer (enhances issue descriptions), iloom-issue-implementer (implements code changes), iloom-code-reviewer (reviews code changes against requirements), iloom-artifact-reviewer (reviews artifacts before posting), iloom-swarm-worker (swarm worker agent, dynamically generated). The iloom-swarm-worker agent supports a nested \"agents\" sub-record for configuring phase agent models specifically in swarm mode."
340
381
  },
341
382
  "spin": {
342
383
  "type": "object",
@@ -413,17 +454,6 @@ The following JSON Schema defines valid iloom settings:
413
454
  "capabilities": {
414
455
  "type": "object",
415
456
  "properties": {
416
- "capabilities": {
417
- "type": "array",
418
- "items": {
419
- "type": "string",
420
- "enum": [
421
- "cli",
422
- "web"
423
- ]
424
- },
425
- "description": "Explicitly declared project capabilities (auto-detected if not specified)"
426
- },
427
457
  "web": {
428
458
  "type": "object",
429
459
  "properties": {
@@ -434,7 +464,8 @@ The following JSON Schema defines valid iloom settings:
434
464
  "description": "Base port for web workspace port calculations (default: 3000)"
435
465
  }
436
466
  },
437
- "additionalProperties": false
467
+ "additionalProperties": false,
468
+ "description": "Web dev server settings. To declare a project as a web project, add \"web\" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json."
438
469
  },
439
470
  "database": {
440
471
  "type": "object",
@@ -489,10 +520,11 @@ The following JSON Schema defines valid iloom settings:
489
520
  "type": "string",
490
521
  "enum": [
491
522
  "github",
492
- "linear"
523
+ "linear",
524
+ "jira"
493
525
  ],
494
526
  "default": "github",
495
- "description": "Issue tracker provider (github, linear)"
527
+ "description": "Issue tracker provider (github, linear, jira)"
496
528
  },
497
529
  "github": {
498
530
  "type": "object",
@@ -529,6 +561,69 @@ The following JSON Schema defines valid iloom settings:
529
561
  "teamId"
530
562
  ],
531
563
  "additionalProperties": false
564
+ },
565
+ "jira": {
566
+ "type": "object",
567
+ "properties": {
568
+ "host": {
569
+ "type": "string",
570
+ "minLength": 1,
571
+ "description": "Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")"
572
+ },
573
+ "username": {
574
+ "type": "string",
575
+ "minLength": 1,
576
+ "description": "Jira username or email address"
577
+ },
578
+ "apiToken": {
579
+ "type": "string",
580
+ "description": "Jira API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://id.atlassian.com/manage-profile/security/api-tokens"
581
+ },
582
+ "projectKey": {
583
+ "type": "string",
584
+ "minLength": 1,
585
+ "description": "Jira project key (e.g., \"PROJ\", \"ENG\")"
586
+ },
587
+ "boardId": {
588
+ "type": "string",
589
+ "description": "Jira board ID for sprint/workflow operations (optional)"
590
+ },
591
+ "transitionMappings": {
592
+ "type": "object",
593
+ "additionalProperties": {
594
+ "type": "string"
595
+ },
596
+ "description": "Map iloom states to Jira transition names (e.g., {\"In Review\": \"Start Review\"})"
597
+ },
598
+ "defaultIssueType": {
599
+ "type": "string",
600
+ "minLength": 1,
601
+ "default": "Task",
602
+ "description": "Default Jira issue type name for creating issues (e.g., \"Task\", \"Story\", \"Bug\")"
603
+ },
604
+ "defaultSubtaskType": {
605
+ "type": "string",
606
+ "minLength": 1,
607
+ "default": "Subtask",
608
+ "description": "Default Jira issue type name for creating subtasks/child issues (e.g., \"Subtask\", \"Sub-task\")"
609
+ },
610
+ "doneStatuses": {
611
+ "type": "array",
612
+ "items": {
613
+ "type": "string"
614
+ },
615
+ "default": [
616
+ "Done"
617
+ ],
618
+ "description": "Status names to exclude from issue lists (e.g., [\"Done\", \"Closed\", \"Verify\"])"
619
+ }
620
+ },
621
+ "required": [
622
+ "host",
623
+ "username",
624
+ "projectKey"
625
+ ],
626
+ "additionalProperties": false
532
627
  }
533
628
  },
534
629
  "additionalProperties": false,
@@ -552,6 +647,11 @@ The following JSON Schema defines valid iloom settings:
552
647
  "autoCommitPush": {
553
648
  "type": "boolean",
554
649
  "description": "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
650
+ },
651
+ "openBrowserOnFinish": {
652
+ "type": "boolean",
653
+ "default": true,
654
+ "description": "Open the PR in the default browser after finishing in github-pr or github-draft-pr mode. Use --no-browser flag to override."
555
655
  }
556
656
  },
557
657
  "additionalProperties": false,
@@ -720,6 +820,10 @@ Extract these current values if they exist:
720
820
  - `currentIssueProvider` from `issueManagement.provider` field (default: "github")
721
821
  - `currentLinearTeamId` from `issueManagement.linear.teamId` field (if Linear is provider)
722
822
  - `currentGitHubRemote` from `issueManagement.github.remote` field (if GitHub is provider and multiple remotes)
823
+ - `currentJiraHost` from `issueManagement.jira.host` field (if Jira is provider)
824
+ - `currentJiraUsername` from `issueManagement.jira.username` field (if Jira is provider)
825
+ - `currentJiraProjectKey` from `issueManagement.jira.projectKey` field (if Jira is provider)
826
+ - `currentJiraBoardId` from `issueManagement.jira.boardId` field (if Jira is provider, optional)
723
827
 
724
828
  **If configuration already exists, display current configuration summary:**
725
829
 
@@ -733,6 +837,9 @@ IDE: [currentIdeType or "vscode (default)"]
733
837
  Issue Tracker: [currentIssueProvider or "github (default)"]
734
838
  Linear Team ID: [currentLinearTeamId] (only if currentIssueProvider == linear)
735
839
  {{#if MULTIPLE_REMOTES}}GitHub Remote: [currentGitHubRemote] (only if currentIssueProvider == github){{/if}}
840
+ Jira Host: [currentJiraHost] (only if currentIssueProvider == jira)
841
+ Jira Project Key: [currentJiraProjectKey] (only if currentIssueProvider == jira)
842
+ Jira Board ID: [currentJiraBoardId] (only if currentIssueProvider == jira and boardId is set)
736
843
  ```
737
844
 
738
845
  **Then ask the user what they want to do:**
@@ -814,7 +921,69 @@ The agent will:
814
921
  4. Create `.iloom/package.iloom.json` with the detected configuration
815
922
  5. Detect and set project capabilities (cli, web) based on the framework
816
923
 
817
- **File Format:**
924
+ **package.iloom.json Schema:**
925
+ ```json
926
+ {
927
+ "$ref": "#/definitions/PackageIloom",
928
+ "definitions": {
929
+ "PackageIloom": {
930
+ "type": "object",
931
+ "properties": {
932
+ "capabilities": {
933
+ "type": "array",
934
+ "items": {
935
+ "type": "string",
936
+ "enum": [
937
+ "cli",
938
+ "web"
939
+ ]
940
+ },
941
+ "description": "Project capabilities - \"cli\" for command-line tools (enables CLI isolation), \"web\" for web applications (enables port assignment and dev server)"
942
+ },
943
+ "scripts": {
944
+ "type": "object",
945
+ "properties": {
946
+ "install": {
947
+ "type": "string",
948
+ "description": "Install command (e.g., \"bundle install\", \"poetry install\")"
949
+ },
950
+ "build": {
951
+ "type": "string",
952
+ "description": "Build/compile command"
953
+ },
954
+ "test": {
955
+ "type": "string",
956
+ "description": "Test suite command"
957
+ },
958
+ "dev": {
959
+ "type": "string",
960
+ "description": "Dev server command"
961
+ },
962
+ "lint": {
963
+ "type": "string",
964
+ "description": "Linting command"
965
+ },
966
+ "typecheck": {
967
+ "type": "string",
968
+ "description": "Type checking command"
969
+ },
970
+ "compile": {
971
+ "type": "string",
972
+ "description": "Compilation command (preferred over typecheck if both exist)"
973
+ }
974
+ },
975
+ "additionalProperties": false,
976
+ "description": "Custom shell commands for project operations. These are raw shell commands, not npm script names."
977
+ }
978
+ },
979
+ "additionalProperties": false
980
+ }
981
+ },
982
+ "$schema": "http://json-schema.org/draft-07/schema#"
983
+ }
984
+ ```
985
+
986
+ **File Format Example:**
818
987
  ```json
819
988
  {
820
989
  "capabilities": ["cli"],
@@ -855,7 +1024,16 @@ If the framework detector did not set capabilities, or if you need to ask the us
855
1024
  - "web" - Web application with dev server
856
1025
  - "both" - Both CLI and web capabilities
857
1026
  - "neither" - Library or other project type
858
- - Update `.iloom/package.iloom.json` with the appropriate `capabilities` array.
1027
+
1028
+ **Choose where to save package.iloom configuration:**
1029
+
1030
+ After determining the configuration, ask the user where to save it:
1031
+ - **Project** (`package.iloom.json`) - Shared with team, committed to git
1032
+ - **Local** (`package.iloom.local.json`) - Local only, gitignored, never committed
1033
+
1034
+ Default to **Local** if fork was detected (origin + upstream remotes). Otherwise default to **Project**.
1035
+
1036
+ Write the capabilities and scripts to the chosen file.
859
1037
 
860
1038
  **When to infer capabilities:**
861
1039
  - Flask/Django/FastAPI/Rails/Actix/Rocket detected -> include "web"
@@ -873,7 +1051,7 @@ This phase configures external tooling integrations. Use AskUserQuestion to gath
873
1051
  **Step 1: Issue Tracker Provider**
874
1052
 
875
1053
  {{#if MULTIPLE_REMOTES}}
876
- Since this repository has multiple git remotes, GitHub Issues is suggested as the default since it integrates with your existing GitHub workflow. However, you can choose Linear if that's your team's issue tracker.
1054
+ Since this repository has multiple git remotes, GitHub Issues is suggested as the default since it integrates with your existing GitHub workflow. However, you can choose Linear or Jira if that's your team's issue tracker.
877
1055
  {{/if}}
878
1056
 
879
1057
  1. **Issue Tracker Provider**
@@ -881,8 +1059,9 @@ Since this repository has multiple git remotes, GitHub Issues is suggested as th
881
1059
  - Options:
882
1060
  - "github" - GitHub Issues (default)
883
1061
  - "linear" - Linear Issues
1062
+ - "jira" - Jira Cloud
884
1063
  - Default: currentIssueProvider or "github"
885
- - Validation: Must be one of: github, linear
1064
+ - Validation: Must be one of: github, linear, jira
886
1065
  - Store answer as: `issueManagement.provider`
887
1066
 
888
1067
  **Note on Provider + Merge Mode Combinations:**
@@ -890,6 +1069,8 @@ Since this repository has multiple git remotes, GitHub Issues is suggested as th
890
1069
  - GitHub Issues + github-pr or github-draft-pr: Requires authorized GitHub CLI (`gh`)
891
1070
  - Linear Issues + local merge: Requires Linear API token only
892
1071
  - Linear Issues + github-pr or github-draft-pr: Requires BOTH Linear API token AND authorized GitHub CLI (`gh`)
1072
+ - Jira Cloud + local merge: Requires Jira credentials (host, username, API token) only
1073
+ - Jira Cloud + github-pr or github-draft-pr: Requires BOTH Jira credentials AND authorized GitHub CLI (`gh`)
893
1074
 
894
1075
  **Step 2: Provider-Specific Configuration**
895
1076
 
@@ -945,6 +1126,59 @@ This repository has multiple git remotes detected. iloom needs to know which rem
945
1126
  - **CRITICAL SECURITY REQUIREMENT:** This value MUST ALWAYS be saved to `settings.local.json`, NEVER to `settings.json`, regardless of which file the user selected for other settings. This token must never be committed to source control.
946
1127
  - Context: Get your API token from Linear Settings → API → Personal API Keys (https://linear.app/settings/api)
947
1128
 
1129
+ **If Jira was selected:**
1130
+
1131
+ 2. **Jira Host URL** (only ask if issue provider is "jira")
1132
+ - Question format: "What is your Jira instance URL?{{#if currentJiraHost}} (Currently: [currentJiraHost]){{/if}}"
1133
+ - Options (as examples):
1134
+ - "https://yourcompany.atlassian.net" - Jira Cloud instance
1135
+ - Default: currentJiraHost or NO DEFAULT (required if Jira is selected)
1136
+ - Validation: Non-empty string, must be a valid URL. If the user provides a value without `https://`, automatically prepend `https://` (e.g., `yourcompany.atlassian.net` becomes `https://yourcompany.atlassian.net`). Strip any trailing slashes.
1137
+ - Store answer as: `issueManagement.jira.host`
1138
+ - Context: This is your Jira Cloud instance URL (e.g., "https://yourcompany.atlassian.net")
1139
+
1140
+ 3. **Jira Username/Email** (only ask if issue provider is "jira")
1141
+ - Question format: "What is your Atlassian account email?{{#if currentJiraUsername}} (Currently: [currentJiraUsername]){{/if}}"
1142
+ - Default: currentJiraUsername or NO DEFAULT (required if Jira is selected)
1143
+ - Validation: Non-empty string
1144
+ - Store answer as: `issueManagement.jira.username`
1145
+ - **CRITICAL SECURITY REQUIREMENT:** This value MUST ALWAYS be saved to `settings.local.json`, NEVER to `settings.json`, regardless of which file the user selected for other settings. This is personal account information that should not be committed to source control.
1146
+ - Context: This is the email address associated with your Atlassian account
1147
+
1148
+ 4. **Jira API Token** (only ask if issue provider is "jira")
1149
+ - Question format: "What is your Jira API token? (Currently: 'set' or 'unset' - do not print)"
1150
+ - Options:
1151
+ - I have it now - use the "Type something" option to enter it
1152
+ - I'll come back to it
1153
+ - Default: currentJiraApiToken or NO DEFAULT
1154
+ - Validation: Non-empty string
1155
+ - Guidance: Choose "Type something" to enter it
1156
+ - Store answer as: `issueManagement.jira.apiToken`
1157
+ - **CRITICAL SECURITY REQUIREMENT:** This value MUST ALWAYS be saved to `settings.local.json`, NEVER to `settings.json`, regardless of which file the user selected for other settings. This token must never be committed to source control.
1158
+ - Context: Generate an API token at https://id.atlassian.com/manage-profile/security/api-tokens
1159
+
1160
+ 5. **Jira Project Key** (only ask if issue provider is "jira")
1161
+ - Question format: "What is your Jira project key?{{#if currentJiraProjectKey}} (Currently: [currentJiraProjectKey]){{/if}}"
1162
+ - Options (as examples):
1163
+ - "PROJ" - Project team
1164
+ - "ENG" - Engineering team
1165
+ - Default: currentJiraProjectKey or NO DEFAULT (required if Jira is selected)
1166
+ - Validation: Non-empty string, typically uppercase letters
1167
+ - Store answer as: `issueManagement.jira.projectKey`
1168
+ - Context: This is the project key prefix shown in your Jira issue IDs (e.g., "PROJ" in "PROJ-123")
1169
+
1170
+ 6. **Jira Board ID** (only ask if issue provider is "jira")
1171
+ - Question format: "What is your Jira board ID? (optional, used for sprint filtering){{#if currentJiraBoardId}} (Currently: [currentJiraBoardId]){{/if}}"
1172
+ - Options:
1173
+ - Skip - Don't configure board ID now
1174
+ - Enter board ID - use the "Type something" option to enter it
1175
+ - Default: currentJiraBoardId or SKIP (optional)
1176
+ - Validation: If provided, must be a numeric string
1177
+ - Store answer as: `issueManagement.jira.boardId`
1178
+ - Context: The board ID can be found in the URL when viewing a Jira board (e.g., `/board/42`). This is optional and used for sprint-based filtering with `il issues --sprint`.
1179
+
1180
+ **Note:** Advanced Jira settings like `transitionMappings`, `doneStatuses`, `defaultIssueType`, and `defaultSubtaskType` can be configured later by editing the settings files directly. Mention this to the user.
1181
+
948
1182
  **Step 3: IDE Selection**
949
1183
 
950
1184
  4. **IDE Selection**
@@ -982,7 +1216,7 @@ This repository has multiple git remotes detected. iloom needs to know which rem
982
1216
 
983
1217
  **Implementation Details:**
984
1218
  - Ask Step 1 first to determine provider
985
- - Then ask Step 2 based on the provider selected (includes Linear API Token if Linear was selected)
1219
+ - Then ask Step 2 based on the provider selected (includes Linear API Token if Linear was selected, or Jira credentials if Jira was selected)
986
1220
  - Ask Step 3 (IDE) for all users
987
1221
  - Ask Step 4 (Merge Mode) only if multiple remotes detected OR user requests advanced config
988
1222
  - Set multiSelect: false for all questions
@@ -1040,6 +1274,10 @@ Tooling Configuration (Phase 2):
1040
1274
  Linear Team ID: [value] (only if issue tracker is Linear)
1041
1275
  Linear API Token: [configured/not configured] (only if issue tracker is Linear - never show actual token)
1042
1276
  {{#if MULTIPLE_REMOTES}}GitHub Remote: [value] (only if issue tracker is GitHub){{/if}}
1277
+ Jira Host: [value] (only if issue tracker is Jira)
1278
+ Jira Project Key: [value] (only if issue tracker is Jira)
1279
+ Jira Board ID: [value or "not configured"] (only if issue tracker is Jira)
1280
+ Jira API Token: [configured/not configured] (only if issue tracker is Jira - never show actual token)
1043
1281
  IDE: [value or "vscode (default)"]
1044
1282
  Merge Mode: [value] (only if configured)
1045
1283
  ```
@@ -1047,6 +1285,7 @@ Tooling Configuration (Phase 2):
1047
1285
  **Note**:
1048
1286
  - Include the GitHub Remote line in the summary ONLY if it was configured in Phase 2 (multiple remotes and GitHub selected)
1049
1287
  - Include Linear Team ID ONLY if Linear was selected as the issue tracker provider
1288
+ - Include Jira Host, Project Key, Board ID, and API Token ONLY if Jira was selected as the issue tracker provider
1050
1289
  - Include Merge Mode ONLY if it was asked and configured (multiple remotes or advanced config)
1051
1290
 
1052
1291
  Then ask: "Does this configuration look correct?"
@@ -1185,6 +1424,46 @@ When both settings.json and settings.local.json exist, you MUST prevent duplicat
1185
1424
  }
1186
1425
  ```
1187
1426
 
1427
+ **For Jira:**
1428
+
1429
+ In settings.json (committed):
1430
+ ```json
1431
+ {
1432
+ "issueManagement": {
1433
+ "provider": "jira",
1434
+ "jira": {
1435
+ "host": "<user's Jira host URL>",
1436
+ "projectKey": "<user's project key>"
1437
+ }
1438
+ }
1439
+ }
1440
+ ```
1441
+
1442
+ In settings.local.json (gitignored - MUST be separate from settings.json):
1443
+ ```json
1444
+ {
1445
+ "issueManagement": {
1446
+ "jira": {
1447
+ "username": "<user's Atlassian email>",
1448
+ "apiToken": "<user's API token>"
1449
+ }
1450
+ }
1451
+ }
1452
+ ```
1453
+
1454
+ If a boardId was provided, add it to settings.json alongside host and projectKey:
1455
+ ```json
1456
+ {
1457
+ "issueManagement": {
1458
+ "jira": {
1459
+ "boardId": "<user's board ID>"
1460
+ }
1461
+ }
1462
+ }
1463
+ ```
1464
+
1465
+ **CRITICAL:** The `username` and `apiToken` fields MUST be saved to `settings.local.json`, never to `settings.json`. The `host`, `projectKey`, and `boardId` fields are safe to commit in `settings.json`.
1466
+
1188
1467
  6. **Add mergeBehavior ONLY if mode is not "local":**
1189
1468
  ```json
1190
1469
  {
@@ -1315,16 +1594,16 @@ Would you like to commit these changes?
1315
1594
  - Yes - Commit iloom configuration changes (strongly recommended)
1316
1595
  - No - Skip committing (not recommended)
1317
1596
 
1318
- ⚠️ WARNING: If you don't commit settings.json, iloom will not work correctly in new looms.
1597
+ ⚠️ WARNING: If you don't commit settings.json and package.iloom.json, iloom will not work correctly in new looms.
1319
1598
  Looms are created from committed code, so your configuration won't be available.
1320
- (Local files like settings.local.json and .env are copied automatically - but settings.json must be committed.)
1599
+ (Local files like settings.local.json, package.iloom.local.json, and .env are copied automatically - but shared files must be committed.)
1321
1600
  ```
1322
1601
 
1323
1602
  **CRITICAL RULES:**
1324
- - **ONLY commit iloom-related files**: .iloom/settings.json, .gitignore
1603
+ - **ONLY commit iloom-related files**: .iloom/settings.json, .iloom/package.iloom.json, .gitignore
1325
1604
  - **NEVER stage or commit unrelated files** - even if they appear in `git status`
1326
1605
  - **If the commit fails, you must then subsequently request to use --no-verify flag** to bypass pre-commit hooks that might fail due to unrelated codebase state
1327
- - **Do NOT commit settings.local.json** - it should be gitignored, not committed
1606
+ - **Do NOT commit local-only files** - settings.local.json and package.iloom.local.json should be gitignored, not committed
1328
1607
  - **YOU MAY NEED TO EDIT/UPDATE MORE THAN ONE FILE if the user is changing something like API Keys (local only), permissionsMode (local only), IDE (recommened global) as well as shared settings.
1329
1608
 
1330
1609
  **Step 3: If user says yes, commit the changes**
@@ -1333,10 +1612,10 @@ VERIFY YOU'RE NOT BUNDLING ALL CHANGES IN ONE FILE DESPITE GUIDANCE TO SPLIT ACC
1333
1612
 
1334
1613
  Stage ONLY the iloom-related files that should be committed:
1335
1614
  ```bash
1336
- git add .iloom/settings.json .gitignore 2>/dev/null || true
1615
+ git add .iloom/settings.json .iloom/package.iloom.json .gitignore 2>/dev/null || true
1337
1616
  ```
1338
1617
 
1339
- Note: Do NOT add .iloom/settings.local.json - it's meant to be local-only.
1618
+ Note: Do NOT add local-only files (.iloom/settings.local.json, .iloom/package.iloom.local.json) - they should be gitignored, not committed.
1340
1619
 
1341
1620
  Then commit:
1342
1621
 
@@ -1404,6 +1683,7 @@ Need more advanced configuration? I can help you set up:
1404
1683
  • Multi-Provider Code Review - Get code reviews from Gemini or Codex alongside Claude
1405
1684
  • Plan Configuration - Use different AI providers for planning and plan review
1406
1685
  • Agent Models - Use different Claude models for different tasks
1686
+ • Swarm Agent Models - Configure different models for agents when running in swarm mode
1407
1687
  • Database Settings - Configure database branching for isolated development
1408
1688
  • Skip Pre-Commit Hooks - Bypass slow or failing hooks during commit and finish workflows
1409
1689
  • Workflow Behavior - Control permissions, IDE launching, dev servers, and terminal behavior
@@ -1421,6 +1701,7 @@ You can ask me questions like:
1421
1701
  "Can I disable the IDE from launching automatically?"
1422
1702
  "How do I protect my main branch from worktree creation?"
1423
1703
  "What models are available for the different agents?"
1704
+ "How do I use different models for swarm workers vs normal mode?"
1424
1705
  "How do I use custom build/test commands instead of package.json scripts?"
1425
1706
 
1426
1707
  Just ask any of these questions and I'll help you modify your settings.
@@ -1452,6 +1733,35 @@ When configuring agents, use these model identifiers:
1452
1733
  }
1453
1734
  ```
1454
1735
 
1736
+ **Swarm-Specific Phase Agent Models:**
1737
+
1738
+ In swarm mode, you can configure different models for phase agents (analyzer, planner, implementer, etc.) than in normal mode:
1739
+
1740
+ ```json
1741
+ "agents": {
1742
+ "iloom-issue-implementer": {
1743
+ "model": "opus"
1744
+ },
1745
+ "iloom-swarm-worker": {
1746
+ "model": "opus",
1747
+ "agents": {
1748
+ "iloom-issue-implementer": {
1749
+ "model": "sonnet"
1750
+ },
1751
+ "iloom-issue-planner": {
1752
+ "model": "haiku"
1753
+ }
1754
+ }
1755
+ }
1756
+ }
1757
+ ```
1758
+
1759
+ Fallback chain in swarm mode:
1760
+ 1. `agents.iloom-swarm-worker.agents.<agent>.model` (swarm-specific per-agent)
1761
+ 2. `agents.iloom-swarm-worker.model` (blanket swarm worker model)
1762
+ 3. `agents.<agent>.model` (base per-agent model)
1763
+ 4. Agent default from its definition file
1764
+
1455
1765
  2. **Database Environment Variable:**
1456
1766
  ```json
1457
1767
  "capabilities": {
@@ -1564,6 +1874,15 @@ When configuring agents, use these model identifiers:
1564
1874
  - Your local environment needs different commands than the team standard
1565
1875
  - You want to add debug flags or local-only tooling without affecting others
1566
1876
 
1877
+ ## Telemetry
1878
+
1879
+ iloom collects anonymous usage data to improve the product. If the user asks about telemetry or data collection during setup:
1880
+
1881
+ - **CLI telemetry**: Managed via `il telemetry off` (disable) and `il telemetry on` (re-enable). Run `il telemetry status` to check current state.
1882
+ - **VS Code extension telemetry**: If the user also uses the iloom VS Code extension, its telemetry is managed separately via VS Code settings (`iloom.telemetry.enabled`). Disabling CLI telemetry does NOT affect the extension, and vice versa.
1883
+ - **What's collected**: Only anonymous usage events (commands run, errors). No personal information, repo names, or code.
1884
+ - **Distinct ID**: A random UUID stored in `~/.config/iloom-ai/telemetry.json`, shared between CLI and VS Code extension.
1885
+
1567
1886
  ## Important Notes
1568
1887
 
1569
1888
  - **Validate ALL inputs** against the schema before writing files
@@ -1581,3 +1900,5 @@ When configuring agents, use these model identifiers:
1581
1900
  - **CRITICAL: PREVENT DUPLICATION** - When writing settings.local.json, ONLY include settings that differ from settings.json. If a setting has the same value in both files, it MUST be removed from the local file. Local should only contain overrides, never duplicates.
1582
1901
  - **Deep comparison required** - When comparing settings for duplication, compare nested objects deeply (e.g., capabilities.web.basePort), not just top-level keys
1583
1902
  - **Empty local is OK** - If all local settings match shared settings after deduplication, an empty settings.local.json file is perfectly valid (or the user may choose not to create it at all)
1903
+ - **ALWAYS ask where to save package.iloom configuration** - When creating or modifying package.iloom.json outside of the guided wizard flow, always ask the user whether to save to `package.iloom.json` (shared, committed) or `package.iloom.local.json` (local, gitignored) before writing. Apply the same fork detection logic — if origin + upstream remotes are detected, default to the local variant.
1904
+ - **ALWAYS offer to commit after writing shared files** - Whenever you create or modify a committable file (settings.json, package.iloom.json, .gitignore), offer to commit it — even outside the guided wizard flow. Looms are created from committed code, so uncommitted shared configuration won't be available in new looms. Follow the same commit rules from Phase 7: only stage iloom-related files, never stage local-only files.