@iloom/cli 0.8.2 → 0.9.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.
- package/LICENSE +1 -1
- package/README.md +50 -4
- package/dist/{BranchNamingService-AO7BPIUJ.js → BranchNamingService-K6XNWQ6C.js} +2 -2
- package/dist/ClaudeContextManager-X2Y72GRL.js +14 -0
- package/dist/ClaudeService-7P32TTES.js +13 -0
- package/dist/{LoomLauncher-NHZMEVTQ.js → LoomLauncher-3I47SUPV.js} +6 -6
- package/dist/{ProjectCapabilityDetector-IA56AUE6.js → ProjectCapabilityDetector-N5L7T4IY.js} +3 -3
- package/dist/PromptTemplateManager-36YLQRHP.js +11 -0
- package/dist/README.md +50 -4
- package/dist/{SettingsManager-VCVLL32H.js → SettingsManager-QR7V2IW2.js} +2 -2
- package/dist/agents/iloom-artifact-reviewer.md +280 -0
- package/dist/agents/iloom-code-reviewer.md +9 -7
- package/dist/agents/iloom-issue-analyze-and-plan.md +21 -6
- package/dist/agents/iloom-issue-analyzer.md +21 -6
- package/dist/agents/iloom-issue-complexity-evaluator.md +21 -6
- package/dist/agents/iloom-issue-enhancer.md +21 -6
- package/dist/agents/iloom-issue-implementer.md +21 -6
- package/dist/agents/iloom-issue-planner.md +21 -6
- package/dist/{build-Z3WCIKPD.js → build-IC4CJRMP.js} +8 -8
- package/dist/{chunk-TVH67KEO.js → chunk-2HZX6AMR.js} +2 -2
- package/dist/{chunk-VZYSM7N7.js → chunk-2JPXGGP4.js} +20 -15
- package/dist/chunk-2JPXGGP4.js.map +1 -0
- package/dist/{chunk-HSGZW3ID.js → chunk-4GAJJUYS.js} +3 -3
- package/dist/chunk-4GAJJUYS.js.map +1 -0
- package/dist/{chunk-RD7I2Q2F.js → chunk-4LKGCFGG.js} +2 -2
- package/dist/{chunk-SSASIBDJ.js → chunk-5LVVQGB3.js} +5 -5
- package/dist/{chunk-GWONJE3X.js → chunk-6Y3FTRJL.js} +189 -48
- package/dist/chunk-6Y3FTRJL.js.map +1 -0
- package/dist/{chunk-4BSXZ5YZ.js → chunk-B7U6OKUR.js} +5 -24
- package/dist/chunk-B7U6OKUR.js.map +1 -0
- package/dist/{chunk-IGKPPACU.js → chunk-FO5GGFOV.js} +17 -8
- package/dist/chunk-FO5GGFOV.js.map +1 -0
- package/dist/{chunk-GDS2HXSW.js → chunk-H6ST2TGP.js} +20 -3
- package/dist/chunk-H6ST2TGP.js.map +1 -0
- package/dist/{chunk-A7XHHUEV.js → chunk-HZXBHMVM.js} +47 -22
- package/dist/chunk-HZXBHMVM.js.map +1 -0
- package/dist/{chunk-44Y5IF7P.js → chunk-I23OQB4Y.js} +5 -5
- package/dist/chunk-JT5LZRMI.js +302 -0
- package/dist/chunk-JT5LZRMI.js.map +1 -0
- package/dist/{chunk-Q457PKGH.js → chunk-KAYXR544.js} +2 -2
- package/dist/{chunk-XU5A6BWA.js → chunk-MZPRBNYC.js} +4 -4
- package/dist/{chunk-XHNACIHO.js → chunk-NTTSUAVM.js} +2 -2
- package/dist/{chunk-PLI3JQWT.js → chunk-OAVJR4PM.js} +2 -2
- package/dist/{chunk-4KGRPHM6.js → chunk-PL2FDYEK.js} +2 -2
- package/dist/chunk-QN47QVBX.js +131 -0
- package/dist/chunk-QN47QVBX.js.map +1 -0
- package/dist/{chunk-3FC3VNEX.js → chunk-RD7OPXZK.js} +34 -8
- package/dist/chunk-RD7OPXZK.js.map +1 -0
- package/dist/{chunk-O6LECMT6.js → chunk-TGRK3CHF.js} +8 -8
- package/dist/{chunk-7GLZVDPQ.js → chunk-TL72BGP6.js} +2 -2
- package/dist/{chunk-52MVUK5V.js → chunk-USSL2X4A.js} +2 -2
- package/dist/chunk-USSL2X4A.js.map +1 -0
- package/dist/{chunk-XPKN3QWY.js → chunk-VOGGLPG5.js} +1 -2
- package/dist/{chunk-IWIIOFEB.js → chunk-XFEK2X2D.js} +16 -6
- package/dist/chunk-XFEK2X2D.js.map +1 -0
- package/dist/{chunk-PBSHQVCT.js → chunk-Z6F5CUS6.js} +4 -4
- package/dist/{claude-V4HRPR4Z.js → claude-TP2QO3BU.js} +2 -2
- package/dist/{cleanup-NWNKWPUY.js → cleanup-M6N7KV7E.js} +20 -15
- package/dist/{cleanup-NWNKWPUY.js.map → cleanup-M6N7KV7E.js.map} +1 -1
- package/dist/cli.js +118 -84
- package/dist/cli.js.map +1 -1
- package/dist/{commit-534QIRHY.js → commit-ORHR53KW.js} +10 -10
- package/dist/{compile-UANHMNTS.js → compile-EOWJORKO.js} +8 -8
- package/dist/{contribute-7USRBWRM.js → contribute-4KCEOHSH.js} +3 -3
- package/dist/{dev-server-TO7RLYJI.js → dev-server-Q6M62ATG.js} +13 -13
- package/dist/{feedback-7ZZI6RC5.js → feedback-XRI7SGYX.js} +11 -11
- package/dist/{git-GUNOPP4Q.js → git-W3XUIFTR.js} +5 -3
- package/dist/hooks/iloom-hook.js +5 -3
- package/dist/{ignite-5SIGOW5V.js → ignite-3FHQY23X.js} +90 -26
- package/dist/ignite-3FHQY23X.js.map +1 -0
- package/dist/index.d.ts +37 -2
- package/dist/index.js +49 -13
- package/dist/index.js.map +1 -1
- package/dist/{chunk-FPNSFP6K.js → init-ALYWKNWG.js} +42 -329
- package/dist/init-ALYWKNWG.js.map +1 -0
- package/dist/{lint-XPODLDVA.js → lint-IHUH45OC.js} +8 -8
- package/dist/{open-M2SUR74Y.js → open-KWOV2OFO.js} +15 -15
- package/dist/{plan-FB4AOJ2Q.js → plan-P6MXL7AU.js} +54 -22
- package/dist/plan-P6MXL7AU.js.map +1 -0
- package/dist/{projects-325GEEGJ.js → projects-LH362JZQ.js} +3 -3
- package/dist/prompts/init-prompt.txt +9 -1
- package/dist/prompts/issue-prompt.txt +315 -5
- package/dist/prompts/plan-prompt.txt +4 -6
- package/dist/prompts/pr-prompt.txt +79 -0
- package/dist/prompts/regular-prompt.txt +210 -5
- package/dist/{rebase-4FNRBW3H.js → rebase-AJOJOZUG.js} +9 -9
- package/dist/{recap-GSXFEOD6.js → recap-GKJXMDXW.js} +5 -5
- package/dist/{run-GZNHRJB2.js → run-QEUVZF7J.js} +15 -15
- package/dist/schema/settings.schema.json +9 -1
- package/dist/{shell-2SPM3Z5O.js → shell-DAAVG4YN.js} +5 -5
- package/dist/{summary-Z4F7YFXE.js → summary-WNEYCO4S.js} +11 -11
- package/dist/{test-LBSPYIJW.js → test-5GPWWO3P.js} +8 -8
- package/dist/{test-git-ZPSPA2TP.js → test-git-EJUKDB7F.js} +3 -3
- package/dist/{test-prefix-6DLB2BHE.js → test-prefix-23TOBUXY.js} +3 -3
- package/dist/{test-webserver-XLJ2TZFP.js → test-webserver-CKROHFBQ.js} +5 -5
- package/dist/{vscode-LH3VSQ2W.js → vscode-6TOLFCI2.js} +5 -5
- package/package.json +2 -2
- package/dist/ClaudeContextManager-RDP6CLK6.js +0 -14
- package/dist/ClaudeService-FKPOQRA4.js +0 -13
- package/dist/PRManager-A63LT3NF.js +0 -16
- package/dist/PromptTemplateManager-OUYDHOPI.js +0 -9
- package/dist/chunk-3FC3VNEX.js.map +0 -1
- package/dist/chunk-4BSXZ5YZ.js.map +0 -1
- package/dist/chunk-52MVUK5V.js.map +0 -1
- package/dist/chunk-66QOCD5N.js +0 -79
- package/dist/chunk-66QOCD5N.js.map +0 -1
- package/dist/chunk-A7XHHUEV.js.map +0 -1
- package/dist/chunk-FPNSFP6K.js.map +0 -1
- package/dist/chunk-GDS2HXSW.js.map +0 -1
- package/dist/chunk-GWONJE3X.js.map +0 -1
- package/dist/chunk-HSGZW3ID.js.map +0 -1
- package/dist/chunk-IGKPPACU.js.map +0 -1
- package/dist/chunk-IWIIOFEB.js.map +0 -1
- package/dist/chunk-VZYSM7N7.js.map +0 -1
- package/dist/git-GUNOPP4Q.js.map +0 -1
- package/dist/ignite-5SIGOW5V.js.map +0 -1
- package/dist/init-XXDIB2UJ.js +0 -21
- package/dist/init-XXDIB2UJ.js.map +0 -1
- package/dist/plan-FB4AOJ2Q.js.map +0 -1
- /package/dist/{BranchNamingService-AO7BPIUJ.js.map → BranchNamingService-K6XNWQ6C.js.map} +0 -0
- /package/dist/{ClaudeContextManager-RDP6CLK6.js.map → ClaudeContextManager-X2Y72GRL.js.map} +0 -0
- /package/dist/{ClaudeService-FKPOQRA4.js.map → ClaudeService-7P32TTES.js.map} +0 -0
- /package/dist/{LoomLauncher-NHZMEVTQ.js.map → LoomLauncher-3I47SUPV.js.map} +0 -0
- /package/dist/{PRManager-A63LT3NF.js.map → ProjectCapabilityDetector-N5L7T4IY.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-IA56AUE6.js.map → PromptTemplateManager-36YLQRHP.js.map} +0 -0
- /package/dist/{PromptTemplateManager-OUYDHOPI.js.map → SettingsManager-QR7V2IW2.js.map} +0 -0
- /package/dist/{build-Z3WCIKPD.js.map → build-IC4CJRMP.js.map} +0 -0
- /package/dist/{chunk-TVH67KEO.js.map → chunk-2HZX6AMR.js.map} +0 -0
- /package/dist/{chunk-RD7I2Q2F.js.map → chunk-4LKGCFGG.js.map} +0 -0
- /package/dist/{chunk-SSASIBDJ.js.map → chunk-5LVVQGB3.js.map} +0 -0
- /package/dist/{chunk-44Y5IF7P.js.map → chunk-I23OQB4Y.js.map} +0 -0
- /package/dist/{chunk-Q457PKGH.js.map → chunk-KAYXR544.js.map} +0 -0
- /package/dist/{chunk-XU5A6BWA.js.map → chunk-MZPRBNYC.js.map} +0 -0
- /package/dist/{chunk-XHNACIHO.js.map → chunk-NTTSUAVM.js.map} +0 -0
- /package/dist/{chunk-PLI3JQWT.js.map → chunk-OAVJR4PM.js.map} +0 -0
- /package/dist/{chunk-4KGRPHM6.js.map → chunk-PL2FDYEK.js.map} +0 -0
- /package/dist/{chunk-O6LECMT6.js.map → chunk-TGRK3CHF.js.map} +0 -0
- /package/dist/{chunk-7GLZVDPQ.js.map → chunk-TL72BGP6.js.map} +0 -0
- /package/dist/{chunk-XPKN3QWY.js.map → chunk-VOGGLPG5.js.map} +0 -0
- /package/dist/{chunk-PBSHQVCT.js.map → chunk-Z6F5CUS6.js.map} +0 -0
- /package/dist/{SettingsManager-VCVLL32H.js.map → claude-TP2QO3BU.js.map} +0 -0
- /package/dist/{commit-534QIRHY.js.map → commit-ORHR53KW.js.map} +0 -0
- /package/dist/{compile-UANHMNTS.js.map → compile-EOWJORKO.js.map} +0 -0
- /package/dist/{contribute-7USRBWRM.js.map → contribute-4KCEOHSH.js.map} +0 -0
- /package/dist/{dev-server-TO7RLYJI.js.map → dev-server-Q6M62ATG.js.map} +0 -0
- /package/dist/{feedback-7ZZI6RC5.js.map → feedback-XRI7SGYX.js.map} +0 -0
- /package/dist/{claude-V4HRPR4Z.js.map → git-W3XUIFTR.js.map} +0 -0
- /package/dist/{lint-XPODLDVA.js.map → lint-IHUH45OC.js.map} +0 -0
- /package/dist/{open-M2SUR74Y.js.map → open-KWOV2OFO.js.map} +0 -0
- /package/dist/{projects-325GEEGJ.js.map → projects-LH362JZQ.js.map} +0 -0
- /package/dist/{rebase-4FNRBW3H.js.map → rebase-AJOJOZUG.js.map} +0 -0
- /package/dist/{recap-GSXFEOD6.js.map → recap-GKJXMDXW.js.map} +0 -0
- /package/dist/{run-GZNHRJB2.js.map → run-QEUVZF7J.js.map} +0 -0
- /package/dist/{shell-2SPM3Z5O.js.map → shell-DAAVG4YN.js.map} +0 -0
- /package/dist/{summary-Z4F7YFXE.js.map → summary-WNEYCO4S.js.map} +0 -0
- /package/dist/{test-LBSPYIJW.js.map → test-5GPWWO3P.js.map} +0 -0
- /package/dist/{test-git-ZPSPA2TP.js.map → test-git-EJUKDB7F.js.map} +0 -0
- /package/dist/{test-prefix-6DLB2BHE.js.map → test-prefix-23TOBUXY.js.map} +0 -0
- /package/dist/{test-webserver-XLJ2TZFP.js.map → test-webserver-CKROHFBQ.js.map} +0 -0
- /package/dist/{vscode-LH3VSQ2W.js.map → vscode-6TOLFCI2.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/first-run-setup.ts"],"sourcesContent":["import { existsSync } from 'fs'\nimport { readFile } from 'fs/promises'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { logger } from './logger.js'\nimport { FirstRunManager } from './FirstRunManager.js'\nimport { getRepoRoot } from './git.js'\nimport { promptConfirmation, waitForKeypress } from './prompt.js'\n\n/**\n * Get the project root path for first-run tracking\n * Uses git repo root if available, otherwise falls back to cwd\n * This ensures consistent path resolution regardless of where the CLI is run from\n */\nasync function getProjectRoot(): Promise<string> {\n\tconst repoRoot = await getRepoRoot()\n\tif (repoRoot) {\n\t\tlogger.debug(`getProjectRoot: Using git repo root: ${repoRoot}`)\n\t\treturn repoRoot\n\t}\n\tconst cwd = process.cwd()\n\tlogger.debug(`getProjectRoot: Not in git repo, using cwd: ${cwd}`)\n\treturn cwd\n}\n\n/**\n * Check if project needs first-run setup\n * Returns true if:\n * 1. Project is not tracked as configured globally AND\n * 2. .iloom directory is missing or settings files are empty\n *\n * Uses git repo root for path resolution to ensure consistent behavior\n * regardless of whether the CLI is run from a subdirectory or worktree\n */\nexport async function needsFirstRunSetup(): Promise<boolean> {\n\tconst projectRoot = await getProjectRoot()\n\tconst firstRunManager = new FirstRunManager()\n\n\t// Check if project is tracked as configured globally\n\tconst isConfigured = await firstRunManager.isProjectConfigured(projectRoot)\n\tif (isConfigured) {\n\t\tlogger.debug('needsFirstRunSetup: Project is tracked as configured globally')\n\t\treturn false\n\t}\n\n\tconst iloomDir = path.join(projectRoot, '.iloom')\n\n\t// Check if .iloom directory exists\n\tif (!existsSync(iloomDir)) {\n\t\treturn true\n\t}\n\n\t// Check if either settings file has meaningful content\n\tconst settingsPath = path.join(iloomDir, 'settings.json')\n\tconst settingsLocalPath = path.join(iloomDir, 'settings.local.json')\n\n\tconst hasSettings = await hasNonEmptySettings(settingsPath)\n\tconst hasLocalSettings = await hasNonEmptySettings(settingsLocalPath)\n\n\treturn !hasSettings && !hasLocalSettings\n}\n\nasync function hasNonEmptySettings(filePath: string): Promise<boolean> {\n\tif (!existsSync(filePath)) return false\n\ttry {\n\t\tconst content = await readFile(filePath, 'utf-8')\n\t\tconst parsed = JSON.parse(content)\n\t\treturn Object.keys(parsed).length > 0\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Display default configuration values in a formatted box\n */\nfunction displayDefaultsBox(): void {\n\tlogger.info(chalk.bold('Default Configuration:'))\n\tlogger.info('')\n\tlogger.info(` ${chalk.cyan('Main Branch:')} main`)\n\tlogger.info(` ${chalk.cyan('IDE:')} vscode`)\n\tlogger.info(` ${chalk.cyan('Issue Tracker:')} GitHub Issues`)\n\tlogger.info(` ${chalk.cyan('Merge Mode:')} local ${chalk.dim('(merge locally)')}`)\n\tlogger.info(` ${chalk.cyan('Base Port:')} 3000`)\n}\n\n/**\n * Launch interactive first-run setup via InitCommand\n * Shows defaults first, allows quick acceptance or full wizard\n */\nexport async function launchFirstRunSetup(): Promise<void> {\n\tlogger.info('First-time project setup detected.')\n\tlogger.info('')\n\n\t// Display the defaults\n\tdisplayDefaultsBox()\n\n\tlogger.info('')\n\n\t// Import prompt utility\n\n\t// Ask if defaults are OK (default to Yes)\n\tconst acceptDefaults = await promptConfirmation(\n\t\t'Are these defaults OK?',\n\t\ttrue // default to true, so Enter accepts\n\t)\n\n\tif (acceptDefaults) {\n\t\t// User accepted defaults - just mark as configured\n\t\tconst projectRoot = await getProjectRoot()\n\t\tconst firstRunManager = new FirstRunManager()\n\t\tawait firstRunManager.markProjectAsConfigured(projectRoot)\n\t\tlogger.info(chalk.green('Configuration complete! Using defaults.'))\n\t\tlogger.info('You can run `il init` anytime to customize settings.')\n\t\treturn\n\t}\n\n\t// User declined - launch full wizard\n\tlogger.info('')\n\tlogger.info('iloom will now launch an interactive configuration session with Claude.')\n\n\tawait waitForKeypress('Press any key to start configuration...')\n\n\tconst { InitCommand } = await import('../commands/init.js')\n\tconst initCommand = new InitCommand()\n\tawait initCommand.execute(\n\t\t'Help me configure iloom settings for this project. This is my first time using iloom here. Note: Your iloom command will execute once we are done with configuration changes.'\n\t)\n\t// Note: InitCommand.execute() now handles markProjectAsConfigured() internally\n\t// when the guided init completes successfully\n\n\tlogger.info('Configuration complete! Continuing with your original command...')\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,WAAW;AAWlB,eAAe,iBAAkC;AAChD,QAAM,WAAW,MAAM,YAAY;AACnC,MAAI,UAAU;AACb,WAAO,MAAM,wCAAwC,QAAQ,EAAE;AAC/D,WAAO;AAAA,EACR;AACA,QAAM,MAAM,QAAQ,IAAI;AACxB,SAAO,MAAM,+CAA+C,GAAG,EAAE;AACjE,SAAO;AACR;AAWA,eAAsB,qBAAuC;AAC5D,QAAM,cAAc,MAAM,eAAe;AACzC,QAAM,kBAAkB,IAAI,gBAAgB;AAG5C,QAAM,eAAe,MAAM,gBAAgB,oBAAoB,WAAW;AAC1E,MAAI,cAAc;AACjB,WAAO,MAAM,+DAA+D;AAC5E,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,KAAK,KAAK,aAAa,QAAQ;AAGhD,MAAI,CAAC,WAAW,QAAQ,GAAG;AAC1B,WAAO;AAAA,EACR;AAGA,QAAM,eAAe,KAAK,KAAK,UAAU,eAAe;AACxD,QAAM,oBAAoB,KAAK,KAAK,UAAU,qBAAqB;AAEnE,QAAM,cAAc,MAAM,oBAAoB,YAAY;AAC1D,QAAM,mBAAmB,MAAM,oBAAoB,iBAAiB;AAEpE,SAAO,CAAC,eAAe,CAAC;AACzB;AAEA,eAAe,oBAAoB,UAAoC;AACtE,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAClC,MAAI;AACH,UAAM,UAAU,MAAM,SAAS,UAAU,OAAO;AAChD,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,WAAO,OAAO,KAAK,MAAM,EAAE,SAAS;AAAA,EACrC,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKA,SAAS,qBAA2B;AACnC,SAAO,KAAK,MAAM,KAAK,wBAAwB,CAAC;AAChD,SAAO,KAAK,EAAE;AACd,SAAO,KAAK,KAAK,MAAM,KAAK,cAAc,CAAC,WAAW;AACtD,SAAO,KAAK,KAAK,MAAM,KAAK,MAAM,CAAC,qBAAqB;AACxD,SAAO,KAAK,KAAK,MAAM,KAAK,gBAAgB,CAAC,kBAAkB;AAC/D,SAAO,KAAK,KAAK,MAAM,KAAK,aAAa,CAAC,eAAe,MAAM,IAAI,iBAAiB,CAAC,EAAE;AACvF,SAAO,KAAK,KAAK,MAAM,KAAK,YAAY,CAAC,aAAa;AACvD;AAMA,eAAsB,sBAAqC;AAC1D,SAAO,KAAK,oCAAoC;AAChD,SAAO,KAAK,EAAE;AAGd,qBAAmB;AAEnB,SAAO,KAAK,EAAE;AAKd,QAAM,iBAAiB,MAAM;AAAA,IAC5B;AAAA,IACA;AAAA;AAAA,EACD;AAEA,MAAI,gBAAgB;AAEnB,UAAM,cAAc,MAAM,eAAe;AACzC,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,UAAM,gBAAgB,wBAAwB,WAAW;AACzD,WAAO,KAAK,MAAM,MAAM,yCAAyC,CAAC;AAClE,WAAO,KAAK,sDAAsD;AAClE;AAAA,EACD;AAGA,SAAO,KAAK,EAAE;AACd,SAAO,KAAK,yEAAyE;AAErF,QAAM,gBAAgB,yCAAyC;AAE/D,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,oBAAqB;AAC1D,QAAM,cAAc,IAAI,YAAY;AACpC,QAAM,YAAY;AAAA,IACjB;AAAA,EACD;AAIA,SAAO,KAAK,kEAAkE;AAC/E;","names":[]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
runScript
|
|
4
|
-
} from "./chunk-RD7I2Q2F.js";
|
|
5
2
|
import {
|
|
6
3
|
IdentifierParser
|
|
7
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2HZX6AMR.js";
|
|
5
|
+
import {
|
|
6
|
+
runScript
|
|
7
|
+
} from "./chunk-4LKGCFGG.js";
|
|
8
8
|
import {
|
|
9
9
|
GitWorktreeManager
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4GAJJUYS.js";
|
|
11
11
|
import {
|
|
12
12
|
getPackageScripts
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-VOGGLPG5.js";
|
|
14
14
|
import {
|
|
15
15
|
extractIssueNumber
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-H6ST2TGP.js";
|
|
17
17
|
import {
|
|
18
18
|
logger
|
|
19
19
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -156,4 +156,4 @@ var ScriptCommandBase = class {
|
|
|
156
156
|
export {
|
|
157
157
|
ScriptCommandBase
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-TGRK3CHF.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getPackageConfig,
|
|
5
5
|
hasWebDependencies,
|
|
6
6
|
parseBinField
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VOGGLPG5.js";
|
|
8
8
|
|
|
9
9
|
// src/lib/ProjectCapabilityDetector.ts
|
|
10
10
|
var ProjectCapabilityDetector = class {
|
|
@@ -46,4 +46,4 @@ var ProjectCapabilityDetector = class {
|
|
|
46
46
|
export {
|
|
47
47
|
ProjectCapabilityDetector
|
|
48
48
|
};
|
|
49
|
-
//# sourceMappingURL=chunk-
|
|
49
|
+
//# sourceMappingURL=chunk-TL72BGP6.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
extractIssueNumber
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-H6ST2TGP.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-
|
|
111
|
+
//# sourceMappingURL=chunk-USSL2X4A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/port.ts"],"sourcesContent":["import { createHash } from 'crypto'\nimport path from 'path'\nimport fs from 'fs-extra'\nimport { parseEnvFile, extractPort, findEnvFileContainingVariable } from './env.js'\nimport { extractIssueNumber } from './git.js'\nimport { logger } from './logger.js'\n\n/**\n * Wrap a raw port that exceeds 65535 into the valid port range.\n * Uses modulo arithmetic to wrap back into [basePort+1, 65535].\n *\n * @param rawPort - The calculated port (basePort + issueNumber)\n * @param basePort - The base port (default: 3000)\n * @returns Port in valid range [basePort+1, 65535]\n */\nexport function wrapPort(rawPort: number, basePort: number): number {\n\tif (rawPort <= 65535) return rawPort\n\tconst range = 65535 - basePort\n\treturn ((rawPort - basePort - 1) % range) + basePort + 1\n}\n\n/**\n * Extract numeric suffix from alphanumeric issue ID (e.g., MARK-324 -> 324)\n * @returns The numeric part or null if no trailing number found\n */\nexport function extractNumericSuffix(issueId: string): number | null {\n\t// Match trailing digits after optional separator (-, _)\n\tconst match = issueId.match(/[-_]?(\\d+)$/)\n\tconst digits = match?.[1]\n\tif (digits === undefined) return null\n\treturn parseInt(digits, 10)\n}\n\n/**\n * Generate deterministic port offset from branch name using SHA256 hash\n * Range: 1-999 (matches existing random range for branches)\n *\n * @param branchName - Branch name to generate port offset from\n * @returns Port offset in range [1, 999]\n * @throws Error if branchName is empty\n */\nexport function generatePortOffsetFromBranchName(branchName: string): number {\n\t// Validate input\n\tif (!branchName || branchName.trim().length === 0) {\n\t\tthrow new Error('Branch name cannot be empty')\n\t}\n\n\t// Generate SHA256 hash of branch name (same pattern as color.ts)\n\tconst hash = createHash('sha256').update(branchName).digest('hex')\n\n\t// Take first 8 hex characters and convert to port offset (1-999)\n\tconst hashPrefix = hash.slice(0, 8)\n\tconst hashAsInt = parseInt(hashPrefix, 16)\n\tconst portOffset = (hashAsInt % 999) + 1 // +1 ensures range is 1-999, not 0-998\n\n\treturn portOffset\n}\n\n/**\n * Calculate deterministic port for branch-based workspace\n *\n * @param branchName - Branch name\n * @param basePort - Base port (default: 3000)\n * @returns Port number\n * @throws Error if branchName is empty\n */\n// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\nexport function calculatePortForBranch(branchName: string, basePort: number = 3000): number {\n\tconst offset = generatePortOffsetFromBranchName(branchName)\n\tconst port = basePort + offset\n\n\t// Use wrap-around for port overflow\n\treturn wrapPort(port, basePort)\n}\n\n/**\n * Calculate port from an identifier (issue number, PR number, or string).\n * This is the single source of truth for port calculation logic.\n *\n * Algorithm:\n * 1. Numeric identifiers: basePort + number (with wrapPort for overflow)\n * 2. String numeric (e.g., \"42\"): parse and same as above\n * 3. Alphanumeric with suffix (e.g., \"MARK-324\"): extract suffix and same as above\n * 4. Pure strings without numeric suffix: hash-based calculation via calculatePortForBranch\n *\n * @param identifier - The identifier (issue number, PR number, or string)\n * @param basePort - Base port (default: 3000)\n * @returns Port number in valid range\n */\n// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\nexport function calculatePortFromIdentifier(\n\tidentifier: string | number,\n\tbasePort: number = 3000\n): number {\n\t// Handle numeric identifiers directly\n\tif (typeof identifier === 'number') {\n\t\treturn wrapPort(basePort + identifier, basePort)\n\t}\n\n\t// Handle string identifiers\n\t// First, try to parse as pure numeric string\n\tconst numericValue = parseInt(identifier, 10)\n\tif (!isNaN(numericValue) && String(numericValue) === identifier) {\n\t\treturn wrapPort(basePort + numericValue, basePort)\n\t}\n\n\t// Try extracting numeric suffix from alphanumeric identifiers (e.g., MARK-324 -> 324)\n\tconst numericSuffix = extractNumericSuffix(identifier)\n\tif (numericSuffix !== null) {\n\t\treturn wrapPort(basePort + numericSuffix, basePort)\n\t}\n\n\t// For non-numeric strings without numeric suffix, use hash-based calculation\n\treturn calculatePortForBranch(`issue-${identifier}`, basePort)\n}\n\nexport interface GetWorkspacePortOptions {\n\tbasePort?: number | undefined\n\tworktreePath: string\n\tworktreeBranch: string\n\t/** If true, check .env files for PORT override before calculating. Defaults to false. */\n\tcheckEnvFile?: boolean\n}\n\nexport interface GetWorkspacePortDependencies {\n\tfileExists?: (path: string) => Promise<boolean>\n\treadFile?: (path: string) => Promise<string>\n\tlistWorktrees?: () => Promise<Array<{ path: string; branch: string }>>\n}\n\n/**\n * Get port for workspace - calculates based on workspace type, optionally checking .env files first.\n * Consolidates logic previously duplicated across dev-server, run, open commands.\n *\n * Priority (when checkEnvFile is true):\n * 1. Read PORT from dotenv-flow files (if present)\n * 2. Calculate from PR pattern (_pr_N suffix in directory name)\n * 3. Calculate from issue pattern (issue-N or alphanumeric like MARK-324)\n * 4. Calculate from branch name using deterministic hash\n *\n * When checkEnvFile is false (default), skips step 1 and only calculates.\n */\nexport async function getWorkspacePort(\n\toptions: GetWorkspacePortOptions,\n\tdependencies?: GetWorkspacePortDependencies\n): Promise<number> {\n\tconst basePort = options.basePort ?? 3000\n\tconst checkEnvFile = options.checkEnvFile ?? false\n\n\t// Only check .env files if explicitly requested\n\tif (checkEnvFile) {\n\t\tconst deps = {\n\t\t\tfileExists:\n\t\t\t\tdependencies?.fileExists ?? ((p: string): Promise<boolean> => fs.pathExists(p)),\n\t\t\treadFile:\n\t\t\t\tdependencies?.readFile ?? ((p: string): Promise<string> => fs.readFile(p, 'utf8')),\n\t\t}\n\n\t\t// Try to read PORT from any dotenv-flow file (as override)\n\t\tconst envFile = await findEnvFileContainingVariable(\n\t\t\toptions.worktreePath,\n\t\t\t'PORT',\n\t\t\tasync (p) => deps.fileExists(p),\n\t\t\tasync (p, varName) => {\n\t\t\t\tconst content = await deps.readFile(p)\n\t\t\t\tconst envMap = parseEnvFile(content)\n\t\t\t\treturn envMap.get(varName) ?? null\n\t\t\t}\n\t\t)\n\n\t\tif (envFile) {\n\t\t\tconst envPath = path.join(options.worktreePath, envFile)\n\t\t\tconst envContent = await deps.readFile(envPath)\n\t\t\tconst envMap = parseEnvFile(envContent)\n\t\t\tconst port = extractPort(envMap)\n\n\t\t\tif (port) {\n\t\t\t\tlogger.debug(`Using PORT from ${envFile}: ${port}`)\n\t\t\t\treturn port\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('PORT not found in any dotenv-flow file, calculating from workspace identifier')\n\t}\n\n\t// Calculate based on workspace identifier\n\n\t// Extract identifier from worktree path/branch\n\tconst dirName = path.basename(options.worktreePath)\n\n\t// Check for PR pattern: _pr_N\n\tconst prPattern = /_pr_(\\d+)$/\n\tconst prMatch = dirName.match(prPattern)\n\tif (prMatch?.[1]) {\n\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\tconst port = calculatePortFromIdentifier(prNumber, basePort)\n\t\tlogger.debug(`Calculated PORT for PR #${prNumber}: ${port}`)\n\t\treturn port\n\t}\n\n\t// Check for issue pattern: issue-N or alphanumeric like MARK-324\n\tconst issueId = extractIssueNumber(dirName) ?? extractIssueNumber(options.worktreeBranch)\n\tif (issueId !== null) {\n\t\tconst port = calculatePortFromIdentifier(issueId, basePort)\n\t\tlogger.debug(`Calculated PORT for issue ${issueId}: ${port}`)\n\t\treturn port\n\t}\n\n\t// Branch-based workspace - use deterministic hash\n\tconst port = calculatePortForBranch(options.worktreeBranch, basePort)\n\tlogger.debug(`Calculated PORT for branch \"${options.worktreeBranch}\": ${port}`)\n\treturn port\n}\n"],"mappings":"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","names":["port"]}
|
|
@@ -140,7 +140,6 @@ function getExplicitCapabilities(pkgJson) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export {
|
|
143
|
-
readPackageJson,
|
|
144
143
|
getPackageConfig,
|
|
145
144
|
parseBinField,
|
|
146
145
|
hasWebDependencies,
|
|
@@ -148,4 +147,4 @@ export {
|
|
|
148
147
|
getPackageScripts,
|
|
149
148
|
getExplicitCapabilities
|
|
150
149
|
};
|
|
151
|
-
//# sourceMappingURL=chunk-
|
|
150
|
+
//# sourceMappingURL=chunk-VOGGLPG5.js.map
|
|
@@ -16,7 +16,8 @@ var AgentSettingsSchema = z.object({
|
|
|
16
16
|
providers: z.record(
|
|
17
17
|
z.enum(["claude", "gemini", "codex"]),
|
|
18
18
|
z.string()
|
|
19
|
-
).optional().describe('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")')
|
|
19
|
+
).optional().describe('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")'),
|
|
20
|
+
review: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed before posting (defaults to false)")
|
|
20
21
|
});
|
|
21
22
|
var SpinAgentSettingsSchema = z.object({
|
|
22
23
|
model: z.enum(["sonnet", "opus", "haiku"]).default("opus").describe("Claude model shorthand for spin orchestrator")
|
|
@@ -114,7 +115,7 @@ var IloomSettingsSchema = z.object({
|
|
|
114
115
|
copyGitIgnoredPatterns: z.array(z.string().min(1, "Pattern cannot be empty")).optional().describe(`Glob patterns for gitignored files to copy to looms (e.g., ["*.db", "data/*.sqlite"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom's and claude's local settings are automatically copied and do not need to be specified here.`),
|
|
115
116
|
workflows: WorkflowsSettingsSchema.describe("Per-workflow-type permission configurations"),
|
|
116
117
|
agents: z.record(z.string(), AgentSettingsSchema).optional().nullable().describe(
|
|
117
|
-
"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)"
|
|
118
|
+
"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)"
|
|
118
119
|
),
|
|
119
120
|
spin: SpinAgentSettingsSchema.optional().describe(
|
|
120
121
|
"Spin orchestrator configuration. Model defaults to opus when not configured."
|
|
@@ -128,6 +129,7 @@ var IloomSettingsSchema = z.object({
|
|
|
128
129
|
capabilities: CapabilitiesSettingsSchema.describe("Project capability configurations"),
|
|
129
130
|
databaseProviders: DatabaseProvidersSettingsSchema.describe("Database provider configurations"),
|
|
130
131
|
issueManagement: z.object({
|
|
132
|
+
// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
|
|
131
133
|
provider: z.enum(["github", "linear"]).optional().default("github").describe("Issue tracker provider (github, linear)"),
|
|
132
134
|
github: z.object({
|
|
133
135
|
remote: z.string().min(1, "Remote name cannot be empty").describe("Git remote name to use for GitHub operations")
|
|
@@ -139,10 +141,15 @@ var IloomSettingsSchema = z.object({
|
|
|
139
141
|
}).optional()
|
|
140
142
|
}).optional().describe("Issue management configuration"),
|
|
141
143
|
mergeBehavior: z.object({
|
|
144
|
+
// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
|
|
142
145
|
mode: z.enum(["local", "github-pr", "github-draft-pr"]).default("local"),
|
|
143
|
-
remote: z.string().optional()
|
|
146
|
+
remote: z.string().optional(),
|
|
147
|
+
autoCommitPush: z.boolean().optional().describe(
|
|
148
|
+
"Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
|
|
149
|
+
)
|
|
144
150
|
}).optional().describe("Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)"),
|
|
145
151
|
ide: z.object({
|
|
152
|
+
// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
|
|
146
153
|
type: z.enum(["vscode", "cursor", "webstorm", "sublime", "intellij", "windsurf", "antigravity"]).default("vscode").describe(
|
|
147
154
|
"IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), windsurf (Windsurf editor), antigravity (Antigravity IDE)."
|
|
148
155
|
)
|
|
@@ -189,7 +196,7 @@ var IloomSettingsSchemaNoDefaults = z.object({
|
|
|
189
196
|
copyGitIgnoredPatterns: z.array(z.string().min(1, "Pattern cannot be empty")).optional().describe(`Glob patterns for gitignored files to copy to looms (e.g., ["*.db", "data/*.sqlite"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom's and claude's local settings are automatically copied and do not need to be specified here.`),
|
|
190
197
|
workflows: WorkflowsSettingsSchemaNoDefaults.describe("Per-workflow-type permission configurations"),
|
|
191
198
|
agents: z.record(z.string(), AgentSettingsSchema).optional().nullable().describe(
|
|
192
|
-
"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)"
|
|
199
|
+
"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)"
|
|
193
200
|
),
|
|
194
201
|
spin: z.object({
|
|
195
202
|
model: z.enum(["sonnet", "opus", "haiku"]).optional()
|
|
@@ -217,7 +224,10 @@ var IloomSettingsSchemaNoDefaults = z.object({
|
|
|
217
224
|
}).optional().describe("Issue management configuration"),
|
|
218
225
|
mergeBehavior: z.object({
|
|
219
226
|
mode: z.enum(["local", "github-pr", "github-draft-pr"]).optional(),
|
|
220
|
-
remote: z.string().optional()
|
|
227
|
+
remote: z.string().optional(),
|
|
228
|
+
autoCommitPush: z.boolean().optional().describe(
|
|
229
|
+
"Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
|
|
230
|
+
)
|
|
221
231
|
}).optional().describe("Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)"),
|
|
222
232
|
ide: z.object({
|
|
223
233
|
type: z.enum(["vscode", "cursor", "webstorm", "sublime", "intellij", "windsurf", "antigravity"]).optional().describe(
|
|
@@ -511,4 +521,4 @@ export {
|
|
|
511
521
|
IloomSettingsSchemaNoDefaults,
|
|
512
522
|
SettingsManager
|
|
513
523
|
};
|
|
514
|
-
//# sourceMappingURL=chunk-
|
|
524
|
+
//# sourceMappingURL=chunk-XFEK2X2D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/SettingsManager.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport path from 'path'\nimport os from 'os'\nimport { z } from 'zod'\nimport deepmerge from 'deepmerge'\nimport { logger } from '../utils/logger.js'\n\n/**\n * Valid project capability values for Zod enum validation.\n * When updating this constant, also update ProjectCapability type in src/types/loom.ts\n */\nconst PROJECT_CAPABILITIES = ['cli', 'web'] as const\n\n/**\n * Zod schema for agent settings\n */\nexport const AgentSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.optional()\n\t\t.describe('Claude model shorthand: sonnet, opus, or haiku'),\n\tenabled: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Whether this agent is enabled. Defaults to true.'),\n\tproviders: z\n\t\t.record(\n\t\t\tz.enum(['claude', 'gemini', 'codex']),\n\t\t\tz.string()\n\t\t)\n\t\t.optional()\n\t\t.describe('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\")'),\n\treview: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Whether artifacts from this agent should be reviewed before posting (defaults to false)'),\n})\n\n/**\n * Zod schema for spin agent settings with default model\n * Used for the spin orchestrator configuration\n */\nexport const SpinAgentSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('opus')\n\t\t.describe('Claude model shorthand for spin orchestrator'),\n})\n\n/**\n * Zod schema for plan command settings with default model\n * Used for the plan command configuration\n */\nexport const PlanCommandSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('opus')\n\t\t.describe('Claude model shorthand for plan command'),\n\tplanner: z\n\t\t.enum(['claude', 'gemini', 'codex'])\n\t\t.default('claude')\n\t\t.describe('AI provider for creating the plan'),\n\treviewer: z\n\t\t.enum(['claude', 'gemini', 'codex', 'none'])\n\t\t.default('none')\n\t\t.describe('AI provider for reviewing the plan (none to skip review)'),\n})\n\n/**\n * Zod schema for summary settings with default model\n * Used for session summary generation configuration\n */\nexport const SummarySettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('sonnet')\n\t\t.describe('Claude model shorthand for session summary generation'),\n})\n\n/**\n * Zod schema for workflow permission configuration\n */\nexport const WorkflowPermissionSchema = z.object({\n\tpermissionMode: z\n\t\t.enum(['plan', 'acceptEdits', 'bypassPermissions', 'default'])\n\t\t.optional()\n\t\t.describe('Permission mode for Claude CLI in this workflow type'),\n\tnoVerify: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Skip pre-commit hooks (--no-verify) when committing during commit and finish workflows'),\n\tstartIde: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch IDE (code) when starting this workflow type'),\n\tstartDevServer: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch development server when starting this workflow type'),\n\tstartAiAgent: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch Claude Code agent when starting this workflow type'),\n\tstartTerminal: z\n\t\t.boolean()\n\t\t.default(false)\n\t\t.describe('Launch terminal window without dev server when starting this workflow type'),\n\tgenerateSummary: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Generate and post Claude session summary when finishing this workflow type'),\n})\n\n/**\n * Non-defaulting variant for pre-merge validation\n * This prevents Zod from polluting partial settings with default values before merge\n */\nexport const WorkflowPermissionSchemaNoDefaults = z.object({\n\tpermissionMode: z\n\t\t.enum(['plan', 'acceptEdits', 'bypassPermissions', 'default'])\n\t\t.optional()\n\t\t.describe('Permission mode for Claude CLI in this workflow type'),\n\tnoVerify: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Skip pre-commit hooks (--no-verify) when committing during commit and finish workflows'),\n\tstartIde: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch IDE (code) when starting this workflow type'),\n\tstartDevServer: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch development server when starting this workflow type'),\n\tstartAiAgent: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch Claude Code agent when starting this workflow type'),\n\tstartTerminal: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch terminal window without dev server when starting this workflow type'),\n\tgenerateSummary: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Generate and post Claude session summary when finishing this workflow type'),\n})\n\n/**\n * Zod schema for workflows settings\n */\nexport const WorkflowsSettingsSchema = z\n\t.object({\n\t\tissue: WorkflowPermissionSchema.optional(),\n\t\tpr: WorkflowPermissionSchema.optional(),\n\t\tregular: WorkflowPermissionSchema.optional(),\n\t})\n\t.optional()\n\n/**\n * Non-defaulting variant for pre-merge validation\n */\nexport const WorkflowsSettingsSchemaNoDefaults = z\n\t.object({\n\t\tissue: WorkflowPermissionSchemaNoDefaults.optional(),\n\t\tpr: WorkflowPermissionSchemaNoDefaults.optional(),\n\t\tregular: WorkflowPermissionSchemaNoDefaults.optional(),\n\t})\n\t.optional()\n\n/**\n * Zod schema for capabilities settings\n */\nexport const CapabilitiesSettingsSchema = z\n\t.object({\n\t\tcapabilities: z\n\t\t\t.array(z.enum(PROJECT_CAPABILITIES))\n\t\t\t.optional()\n\t\t\t.describe('Explicitly declared project capabilities (auto-detected if not specified)'),\n\t\tweb: z\n\t\t\t.object({\n\t\t\t\tbasePort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Base port must be >= 1')\n\t\t\t\t\t.max(65535, 'Base port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Base port for web workspace port calculations (default: 3000)'),\n\t\t\t})\n\t\t\t.optional(),\n\t\tdatabase: z\n\t\t\t.object({\n\t\t\t\tdatabaseUrlEnvVarName: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1, 'Database URL variable name cannot be empty')\n\t\t\t\t\t.regex(/^[A-Z_][A-Z0-9_]*$/, 'Must be valid env var name (uppercase, underscores)')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.default('DATABASE_URL')\n\t\t\t\t\t.describe('Name of environment variable for database connection URL'),\n\t\t\t})\n\t\t\t.optional(),\n\t})\n\t.optional()\n\n/**\n * Non-defaulting variant for pre-merge validation\n */\nexport const CapabilitiesSettingsSchemaNoDefaults = z\n\t.object({\n\t\tcapabilities: z\n\t\t\t.array(z.enum(PROJECT_CAPABILITIES))\n\t\t\t.optional()\n\t\t\t.describe('Explicitly declared project capabilities (auto-detected if not specified)'),\n\t\tweb: z\n\t\t\t.object({\n\t\t\t\tbasePort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Base port must be >= 1')\n\t\t\t\t\t.max(65535, 'Base port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Base port for web workspace port calculations (default: 3000)'),\n\t\t\t})\n\t\t\t.optional(),\n\t\tdatabase: z\n\t\t\t.object({\n\t\t\t\tdatabaseUrlEnvVarName: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1, 'Database URL variable name cannot be empty')\n\t\t\t\t\t.regex(/^[A-Z_][A-Z0-9_]*$/, 'Must be valid env var name (uppercase, underscores)')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Name of environment variable for database connection URL'),\n\t\t\t})\n\t\t\t.optional(),\n\t})\n\t.optional()\n\n/**\n * Zod schema for Neon database provider settings\n */\nexport const NeonSettingsSchema = z.object({\n\tprojectId: z\n\t\t.string()\n\t\t.min(1)\n\t\t.regex(/^[a-zA-Z0-9-]+$/, 'Neon project ID must contain only letters, numbers, and hyphens')\n\t\t.describe('Neon project ID found in your project URL (e.g., \"fantastic-fox-3566354\")'),\n\tparentBranch: z\n\t\t.string()\n\t\t.min(1)\n\t\t.describe('Branch from which new database branches are created'),\n})\n\n/**\n * Zod schema for database provider settings\n */\nexport const DatabaseProvidersSettingsSchema = z\n\t.object({\n\t\tneon: NeonSettingsSchema.optional().describe(\n\t\t\t'Neon database configuration. Requires Neon CLI installed and authenticated for database branching.',\n\t\t),\n\t})\n\t.optional()\n\n/**\n * Zod schema for iloom settings\n */\nexport const IloomSettingsSchema = z.object({\n\tmainBranch: z\n\t\t.string()\n\t\t.min(1, \"Settings 'mainBranch' cannot be empty\")\n\t\t.optional()\n\t\t.describe('Name of the main/primary branch for the repository'),\n\tsourceEnvOnStart: z\n\t\t.boolean()\n\t\t.default(false)\n\t\t.describe(\n\t\t\t'Source all dotenv-flow files (.env, .env.local, .env.development, .env.development.local) when launching terminal processes (Claude, dev server, terminal). ' +\n\t\t\t\t'Files are sourced in precedence order so later files override earlier ones. ' +\n\t\t\t\t'NOTE TO AI AGENTS: Before making changes to settings files, YOU MUST OFFER to check .env file compatibility. ' +\n\t\t\t\t'WARNING: Unquoted values in .env files may break sourcing in bash/zsh shells. ' +\n\t\t\t\t'Before enabling, verify ALL your .env.* files do not contain unquoted special characters ' +\n\t\t\t\t'(e.g., database URLs with ?, &, or other shell metacharacters). ' +\n\t\t\t\t'Shell compatibility issues may cause processes to fail or behave unexpectedly.',\n\t\t),\n\tworktreePrefix: z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(\n\t\t\t(val) => {\n\t\t\t\tif (val === undefined) return true // undefined = use default calculation\n\t\t\t\tif (val === '') return true // empty string = no prefix mode\n\n\t\t\t\t// Allowlist: only alphanumeric, hyphens, underscores, and forward slashes\n\t\t\t\tconst allowedChars = /^[a-zA-Z0-9\\-_/]+$/\n\t\t\t\tif (!allowedChars.test(val)) return false\n\n\t\t\t\t// Reject if only special characters (no alphanumeric content)\n\t\t\t\tif (/^[-_/]+$/.test(val)) return false\n\n\t\t\t\t// Check each segment (split by /) contains at least one alphanumeric character\n\t\t\t\tconst segments = val.split('/')\n\t\t\t\tfor (const segment of segments) {\n\t\t\t\t\tif (segment && /^[-_]+$/.test(segment)) {\n\t\t\t\t\t\t// Segment exists but contains only hyphens/underscores\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true\n\t\t\t},\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"worktreePrefix contains invalid characters. Only alphanumeric characters, hyphens (-), underscores (_), and forward slashes (/) are allowed. Use forward slashes for nested directories.\",\n\t\t\t},\n\t\t)\n\t\t.describe(\n\t\t\t'Prefix for worktree directories. Empty string disables prefix. Defaults to <repo-name>-looms if not set.',\n\t\t),\n\tprotectedBranches: z\n\t\t.array(z.string().min(1, 'Protected branch name cannot be empty'))\n\t\t.optional()\n\t\t.describe('List of branches that cannot be deleted (defaults to [mainBranch, \"main\", \"master\", \"develop\"])'),\n\tcopyGitIgnoredPatterns: z\n\t\t.array(z.string().min(1, 'Pattern cannot be empty'))\n\t\t.optional()\n\t\t.describe('Glob patterns for gitignored files to copy to looms (e.g., [\"*.db\", \"data/*.sqlite\"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom\\'s and claude\\'s local settings are automatically copied and do not need to be specified here.'),\n\tworkflows: WorkflowsSettingsSchema.describe('Per-workflow-type permission configurations'),\n\tagents: z\n\t\t.record(z.string(), AgentSettingsSchema)\n\t\t.optional()\n\t\t.nullable()\n\t\t.describe(\n\t\t\t'Per-agent configuration overrides. Available agents: ' +\n\t\t\t\t'iloom-issue-analyzer (analyzes issues), ' +\n\t\t\t\t'iloom-issue-planner (creates implementation plans), ' +\n\t\t\t\t'iloom-issue-analyze-and-plan (combined analysis and planning), ' +\n\t\t\t\t'iloom-issue-complexity-evaluator (evaluates complexity), ' +\n\t\t\t\t'iloom-issue-enhancer (enhances issue descriptions), ' +\n\t\t\t\t'iloom-issue-implementer (implements code changes), ' +\n\t\t\t\t'iloom-code-reviewer (reviews code changes against requirements), ' +\n\t\t\t\t'iloom-artifact-reviewer (reviews artifacts before posting)',\n\t\t),\n\tspin: SpinAgentSettingsSchema.optional().describe(\n\t\t'Spin orchestrator configuration. Model defaults to opus when not configured.',\n\t),\n\tplan: PlanCommandSettingsSchema.optional().describe(\n\t\t'Plan command configuration. Model defaults to opus, planner to claude, reviewer to none when not configured.',\n\t),\n\tsummary: SummarySettingsSchema.optional().describe(\n\t\t'Session summary generation configuration. Model defaults to sonnet when not configured.',\n\t),\n\tcapabilities: CapabilitiesSettingsSchema.describe('Project capability configurations'),\n\tdatabaseProviders: DatabaseProvidersSettingsSchema.describe('Database provider configurations'),\n\tissueManagement: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\tprovider: z.enum(['github', 'linear']).optional().default('github').describe('Issue tracker provider (github, linear)'),\n\t\t\tgithub: z\n\t\t\t\t.object({\n\t\t\t\t\tremote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Remote name cannot be empty')\n\t\t\t\t\t\t.describe('Git remote name to use for GitHub operations'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tlinear: z\n\t\t\t\t.object({\n\t\t\t\t\tteamId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Team ID cannot be empty')\n\t\t\t\t\t\t.describe('Linear team identifier (e.g., \"ENG\", \"PLAT\")'),\n\t\t\t\t\tbranchFormat: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Branch naming template for Linear issues'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Linear API token (lin_api_...). SECURITY: Store in settings.local.json only, never commit to source control.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Issue management configuration'),\n\tmergeBehavior: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\tmode: z.enum(['local', 'github-pr', 'github-draft-pr']).default('local'),\n\t\t\tremote: z.string().optional(),\n\t\t\tautoCommitPush: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)'),\n\tide: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\ttype: z\n\t\t\t\t.enum(['vscode', 'cursor', 'webstorm', 'sublime', 'intellij', 'windsurf', 'antigravity'])\n\t\t\t\t.default('vscode')\n\t\t\t\t.describe(\n\t\t\t\t\t'IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), ' +\n\t\t\t\t\t\t'webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), ' +\n\t\t\t\t\t\t'windsurf (Windsurf editor), antigravity (Antigravity IDE).'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe(\n\t\t\t'IDE configuration for workspace launches. Controls which editor opens when you start a loom. ' +\n\t\t\t\t'Supports VSCode, Cursor, WebStorm, Sublime Text, IntelliJ, Windsurf, and Antigravity. ' +\n\t\t\t\t'Note: Color synchronization (title bar colors) only works with VSCode-compatible editors (vscode, cursor, windsurf, antigravity).'\n\t\t),\n\tcolors: z\n\t\t.object({\n\t\t\tterminal: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(true)\n\t\t\t\t.describe('Apply terminal background colors based on branch name (macOS only)'),\n\t\t\tvscode: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(false)\n\t\t\t\t.describe(\n\t\t\t\t\t'Apply VSCode/Cursor title bar colors based on branch name. ' +\n\t\t\t\t\t\t'Note: This modifies .vscode/settings.json which may be in source control. ' +\n\t\t\t\t\t\t'Default is false for safety; enable via init or explicitly if .vscode is gitignored.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Color synchronization settings for workspace identification'),\n\tattribution: z\n\t\t.enum(['off', 'upstreamOnly', 'on'])\n\t\t.default('upstreamOnly')\n\t\t.describe(\n\t\t\t'Controls when iloom attribution appears in session summaries. ' +\n\t\t\t\t'\"off\" - never show attribution. ' +\n\t\t\t\t'\"upstreamOnly\" - only show for contributions to external repositories (e.g., open source). ' +\n\t\t\t\t'\"on\" - always show attribution.'\n\t\t),\n})\n\n/**\n * Non-defaulting variant for pre-merge validation\n * This prevents Zod from polluting partial settings with default values before merge\n */\nexport const IloomSettingsSchemaNoDefaults = z.object({\n\tmainBranch: z\n\t\t.string()\n\t\t.min(1, \"Settings 'mainBranch' cannot be empty\")\n\t\t.optional()\n\t\t.describe('Name of the main/primary branch for the repository'),\n\tsourceEnvOnStart: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe(\n\t\t\t'Source all dotenv-flow files (.env, .env.local, .env.development, .env.development.local) when launching terminal processes (Claude, dev server, terminal). ' +\n\t\t\t\t'Files are sourced in precedence order so later files override earlier ones. ' +\n\t\t\t\t'NOTE TO AI AGENTS: Before making changes to settings files, YOU MUST OFFER to check .env compatibility. ' +\n\t\t\t\t'WARNING: Unquoted values in .env files may break sourcing in bash/zsh shells. ' +\n\t\t\t\t'Before enabling, verify ALL your .env.* files do not contain unquoted special characters ' +\n\t\t\t\t'(e.g., database URLs with ?, &, or other shell metacharacters). ' +\n\t\t\t\t'Shell compatibility issues may cause processes to fail or behave unexpectedly.',\n\t\t),\n\tworktreePrefix: z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(\n\t\t\t(val) => {\n\t\t\t\tif (val === undefined) return true // undefined = use default calculation\n\t\t\t\tif (val === '') return true // empty string = no prefix mode\n\n\t\t\t\t// Allowlist: only alphanumeric, hyphens, underscores, and forward slashes\n\t\t\t\tconst allowedChars = /^[a-zA-Z0-9\\-_/]+$/\n\t\t\t\tif (!allowedChars.test(val)) return false\n\n\t\t\t\t// Reject if only special characters (no alphanumeric content)\n\t\t\t\tif (/^[-_/]+$/.test(val)) return false\n\n\t\t\t\t// Check each segment (split by /) contains at least one alphanumeric character\n\t\t\t\tconst segments = val.split('/')\n\t\t\t\tfor (const segment of segments) {\n\t\t\t\t\tif (segment && /^[-_]+$/.test(segment)) {\n\t\t\t\t\t\t// Segment exists but contains only hyphens/underscores\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true\n\t\t\t},\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"worktreePrefix contains invalid characters. Only alphanumeric characters, hyphens (-), underscores (_), and forward slashes (/) are allowed. Use forward slashes for nested directories.\",\n\t\t\t},\n\t\t)\n\t\t.describe(\n\t\t\t'Prefix for worktree directories. Empty string disables prefix. Defaults to <repo-name>-looms if not set.',\n\t\t),\n\tprotectedBranches: z\n\t\t.array(z.string().min(1, 'Protected branch name cannot be empty'))\n\t\t.optional()\n\t\t.describe('List of branches that cannot be deleted (defaults to [mainBranch, \"main\", \"master\", \"develop\"])'),\n\tcopyGitIgnoredPatterns: z\n\t\t.array(z.string().min(1, 'Pattern cannot be empty'))\n\t\t.optional()\n\t\t.describe('Glob patterns for gitignored files to copy to looms (e.g., [\"*.db\", \"data/*.sqlite\"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom\\'s and claude\\'s local settings are automatically copied and do not need to be specified here.'),\n\tworkflows: WorkflowsSettingsSchemaNoDefaults.describe('Per-workflow-type permission configurations'),\n\tagents: z\n\t\t.record(z.string(), AgentSettingsSchema)\n\t\t.optional()\n\t\t.nullable()\n\t\t.describe(\n\t\t\t'Per-agent configuration overrides. Available agents: ' +\n\t\t\t\t'iloom-issue-analyzer (analyzes issues), ' +\n\t\t\t\t'iloom-issue-planner (creates implementation plans), ' +\n\t\t\t\t'iloom-issue-analyze-and-plan (combined analysis and planning), ' +\n\t\t\t\t'iloom-issue-complexity-evaluator (evaluates complexity), ' +\n\t\t\t\t'iloom-issue-enhancer (enhances issue descriptions), ' +\n\t\t\t\t'iloom-issue-implementer (implements code changes), ' +\n\t\t\t\t'iloom-code-reviewer (reviews code changes against requirements), ' +\n\t\t\t\t'iloom-artifact-reviewer (reviews artifacts before posting)',\n\t\t),\n\tspin: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Spin orchestrator configuration'),\n\tplan: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t\tplanner: z.enum(['claude', 'gemini', 'codex']).optional(),\n\t\t\treviewer: z.enum(['claude', 'gemini', 'codex', 'none']).optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Plan command configuration'),\n\tsummary: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Session summary generation configuration'),\n\tcapabilities: CapabilitiesSettingsSchemaNoDefaults.describe('Project capability configurations'),\n\tdatabaseProviders: DatabaseProvidersSettingsSchema.describe('Database provider configurations'),\n\tissueManagement: z\n\t\t.object({\n\t\t\tprovider: z.enum(['github', 'linear']).optional().describe('Issue tracker provider (github, linear)'),\n\t\t\tgithub: z\n\t\t\t\t.object({\n\t\t\t\t\tremote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Remote name cannot be empty')\n\t\t\t\t\t\t.describe('Git remote name to use for GitHub operations'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tlinear: z\n\t\t\t\t.object({\n\t\t\t\t\tteamId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Team ID cannot be empty')\n\t\t\t\t\t\t.describe('Linear team identifier (e.g., \"ENG\", \"PLAT\")'),\n\t\t\t\t\tbranchFormat: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Branch naming template for Linear issues'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Linear API token (lin_api_...). SECURITY: Store in settings.local.json only, never commit to source control.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Issue management configuration'),\n\tmergeBehavior: z\n\t\t.object({\n\t\t\tmode: z.enum(['local', 'github-pr', 'github-draft-pr']).optional(),\n\t\t\tremote: z.string().optional(),\n\t\t\tautoCommitPush: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)'),\n\tide: z\n\t\t.object({\n\t\t\ttype: z\n\t\t\t\t.enum(['vscode', 'cursor', 'webstorm', 'sublime', 'intellij', 'windsurf', 'antigravity'])\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), ' +\n\t\t\t\t\t\t'webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), ' +\n\t\t\t\t\t\t'windsurf (Windsurf editor), antigravity (Antigravity IDE).'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe(\n\t\t\t'IDE configuration for workspace launches. Controls which editor opens when you start a loom. ' +\n\t\t\t\t'Supports VSCode, Cursor, WebStorm, Sublime Text, IntelliJ, Windsurf, and Antigravity. ' +\n\t\t\t\t'Note: Color synchronization (title bar colors) only works with VSCode-compatible editors (vscode, cursor, windsurf, antigravity).'\n\t\t),\n\tcolors: z\n\t\t.object({\n\t\t\tterminal: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe('Apply terminal background colors based on branch name (macOS only)'),\n\t\t\tvscode: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Apply VSCode/Cursor title bar colors based on branch name. ' +\n\t\t\t\t\t\t'Note: This modifies .vscode/settings.json which may be in source control.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Color synchronization settings for workspace identification'),\n\tattribution: z\n\t\t.enum(['off', 'upstreamOnly', 'on'])\n\t\t.optional()\n\t\t.describe(\n\t\t\t'Controls when iloom attribution appears in session summaries. ' +\n\t\t\t\t'\"off\" - never show attribution. ' +\n\t\t\t\t'\"upstreamOnly\" - only show for contributions to external repositories (e.g., open source). ' +\n\t\t\t\t'\"on\" - always show attribution.'\n\t\t),\n})\n\n/**\n * TypeScript type for Neon settings derived from Zod schema\n */\nexport type NeonSettings = z.infer<typeof NeonSettingsSchema>\n\n/**\n * TypeScript type for database providers settings derived from Zod schema\n */\nexport type DatabaseProvidersSettings = z.infer<typeof DatabaseProvidersSettingsSchema>\n\n/**\n * TypeScript type for agent settings derived from Zod schema\n */\nexport type AgentSettings = z.infer<typeof AgentSettingsSchema>\n\n/**\n * TypeScript type for spin agent settings derived from Zod schema\n */\nexport type SpinAgentSettings = z.infer<typeof SpinAgentSettingsSchema>\n\n/**\n * TypeScript type for plan command settings derived from Zod schema\n */\nexport type PlanCommandSettings = z.infer<typeof PlanCommandSettingsSchema>\n\n/**\n * TypeScript type for summary settings derived from Zod schema\n */\nexport type SummarySettings = z.infer<typeof SummarySettingsSchema>\n\n/**\n * TypeScript type for workflow permission configuration derived from Zod schema\n */\nexport type WorkflowPermission = z.infer<typeof WorkflowPermissionSchema>\n\n/**\n * TypeScript type for workflows settings derived from Zod schema\n */\nexport type WorkflowsSettings = z.infer<typeof WorkflowsSettingsSchema>\n\n/**\n * TypeScript type for capabilities settings derived from Zod schema\n */\nexport type CapabilitiesSettings = z.infer<typeof CapabilitiesSettingsSchema>\n\n/**\n * TypeScript type for IDE settings derived from Zod schema\n */\nexport type IdeSettings = z.infer<typeof IloomSettingsSchema>['ide']\n\n/**\n * TypeScript type for iloom settings derived from Zod schema\n */\nexport type IloomSettings = z.infer<typeof IloomSettingsSchema>\n\n/**\n * TypeScript input type for iloom settings (before Zod defaults are applied)\n * Used for validation where partial/input objects need to be accepted\n */\nexport type IloomSettingsInput = z.input<typeof IloomSettingsSchema>\n\n/**\n * Manages project-level settings from .iloom/settings.json\n */\nexport class SettingsManager {\n\t/**\n\t * Load settings from global, project, and local sources with proper precedence\n\t * Merge hierarchy (lowest to highest priority):\n\t * 1. Global settings (~/.config/iloom-ai/settings.json)\n\t * 2. Project settings (<PROJECT_ROOT>/.iloom/settings.json)\n\t * 3. Local settings (<PROJECT_ROOT>/.iloom/settings.local.json)\n\t * 4. CLI overrides (--set flags)\n\t * Returns empty object if all files don't exist (not an error)\n\t */\n\tasync loadSettings(\n\t\tprojectRoot?: string,\n\t\tcliOverrides?: Partial<IloomSettings>,\n\t): Promise<IloomSettings> {\n\t\tconst root = this.getProjectRoot(projectRoot)\n\n\t\t// Load global settings (lowest priority)\n\t\tconst globalSettings = await this.loadGlobalSettingsFile()\n\t\tconst globalSettingsPath = this.getGlobalSettingsPath()\n\t\tlogger.debug(`🌍 Global settings from ${globalSettingsPath}:`, JSON.stringify(globalSettings, null, 2))\n\n\t\t// Load base settings from settings.json\n\t\tconst baseSettings = await this.loadSettingsFile(root, 'settings.json')\n\t\tconst baseSettingsPath = path.join(root, '.iloom', 'settings.json')\n\t\tlogger.debug(`📄 Base settings from ${baseSettingsPath}:`, JSON.stringify(baseSettings, null, 2))\n\n\t\t// Load local overrides from settings.local.json\n\t\tconst localSettings = await this.loadSettingsFile(root, 'settings.local.json')\n\t\tconst localSettingsPath = path.join(root, '.iloom', 'settings.local.json')\n\t\tlogger.debug(`📄 Local settings from ${localSettingsPath}:`, JSON.stringify(localSettings, null, 2))\n\n\t\t// Deep merge with priority: cliOverrides > localSettings > baseSettings > globalSettings\n\t\tlet merged = this.mergeSettings(this.mergeSettings(globalSettings, baseSettings), localSettings)\n\t\tlogger.debug('🔄 After merging global + base + local settings:', JSON.stringify(merged, null, 2))\n\n\t\tif (cliOverrides && Object.keys(cliOverrides).length > 0) {\n\t\t\tlogger.debug('⚙️ CLI overrides to apply:', JSON.stringify(cliOverrides, null, 2))\n\t\t\tmerged = this.mergeSettings(merged, cliOverrides)\n\t\t\tlogger.debug('🔄 After applying CLI overrides:', JSON.stringify(merged, null, 2))\n\t\t}\n\n\t\t// Validate merged result\n\t\ttry {\n\t\t\tconst finalSettings = IloomSettingsSchema.parse(merged)\n\n\t\t\t// Debug: Log final merged configuration\n\t\t\tthis.logFinalConfiguration(finalSettings)\n\n\t\t\treturn finalSettings\n\t\t} catch (error) {\n\t\t\t// Show all Zod validation errors\n\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\tconst errorMsg = this.formatAllZodErrors(error, '<merged settings>')\n\t\t\t\t// Enhance error message if CLI overrides were applied\n\t\t\t\tif (cliOverrides && Object.keys(cliOverrides).length > 0) {\n\t\t\t\t\tthrow new Error(`${errorMsg.message}\\n\\nNote: CLI overrides were applied. Check your --set arguments.`)\n\t\t\t\t}\n\t\t\t\tthrow errorMsg\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Log the final merged configuration for debugging\n\t */\n\tprivate logFinalConfiguration(settings: IloomSettings): void {\n\t\tlogger.debug('📋 Final merged configuration:', JSON.stringify(settings, null, 2))\n\t}\n\n\t/**\n\t * Load and parse a single settings file\n\t * Returns empty object if file doesn't exist (not an error)\n\t * Uses non-defaulting schema to prevent polluting partial settings with defaults before merge\n\t */\n\tprivate async loadSettingsFile(\n\t\tprojectRoot: string,\n\t\tfilename: string,\n\t): Promise<z.infer<typeof IloomSettingsSchemaNoDefaults>> {\n\t\tconst settingsPath = path.join(projectRoot, '.iloom', filename)\n\n\t\ttry {\n\t\t\tconst content = await readFile(settingsPath, 'utf-8')\n\t\t\tlet parsed: unknown\n\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(content)\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to parse settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Invalid JSON'}`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Basic type checking - ensure it's an object, but don't validate schema completeness\n\t\t\t// Individual files may be incomplete (e.g., Linear config split between files)\n\t\t\t// Final validation will happen on the merged result in loadSettings()\n\t\t\tif (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Settings validation failed at ${filename}:\\n - root: Expected object, received ${typeof parsed}`\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn parsed as z.infer<typeof IloomSettingsSchemaNoDefaults>\n\t\t} catch (error) {\n\t\t\t// File not found is not an error - return empty settings\n\t\t\tif ((error as { code?: string }).code === 'ENOENT') {\n\t\t\t\tlogger.debug(`No settings file found at ${settingsPath}, using defaults`)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Re-throw parsing errors\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Deep merge two settings objects with priority to override\n\t * Uses deepmerge library with array replacement strategy\n\t */\n\tprivate mergeSettings(\n\t\tbase: Partial<IloomSettings> | z.infer<typeof IloomSettingsSchemaNoDefaults>,\n\t\toverride: Partial<IloomSettings> | z.infer<typeof IloomSettingsSchemaNoDefaults>,\n\t): IloomSettings {\n\t\t// Use deepmerge with array replacement (not concatenation)\n\t\t// Type assertion is safe because the merged result will be validated with IloomSettingsSchema\n\t\t// which applies all the defaults after merging\n\t\treturn deepmerge(base as Record<string, unknown>, override as Record<string, unknown>, {\n\t\t\t// Replace arrays instead of concatenating them\n\t\t\tarrayMerge: (_destinationArray, sourceArray) => sourceArray,\n\t\t}) as IloomSettings\n\t}\n\n\t/**\n\t * Format all Zod validation errors into a single error message\n\t */\n\tprivate formatAllZodErrors(error: z.ZodError, settingsPath: string): Error {\n\t\tconst errorMessages = error.issues.map(issue => {\n\t\t\tconst path = issue.path.length > 0 ? issue.path.join('.') : 'root'\n\t\t\treturn ` - ${path}: ${issue.message}`\n\t\t})\n\n\t\treturn new Error(\n\t\t\t`Settings validation failed at ${settingsPath}:\\n${errorMessages.join('\\n')}`,\n\t\t)\n\t}\n\n\t/**\n\t * Validate settings structure and model names using Zod schema\n\t * This method is kept for testing purposes but uses Zod internally\n\t * @internal - Only used in tests via bracket notation\n\t */\n\t// @ts-expect-error - Used in tests via bracket notation, TypeScript can't detect this usage\n\tprivate validateSettings(settings: IloomSettingsInput): void {\n\t\ttry {\n\t\t\tIloomSettingsSchema.parse(settings)\n\t\t} catch (error) {\n\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\tthrow this.formatAllZodErrors(error, '<validation>')\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get project root (defaults to process.cwd())\n\t */\n\tprivate getProjectRoot(projectRoot?: string): string {\n\t\treturn projectRoot ?? process.cwd()\n\t}\n\n\t/**\n\t * Get global config directory path (~/.config/iloom-ai)\n\t */\n\tprivate getGlobalConfigDir(): string {\n\t\treturn path.join(os.homedir(), '.config', 'iloom-ai')\n\t}\n\n\t/**\n\t * Get global settings file path (~/.config/iloom-ai/settings.json)\n\t */\n\tprivate getGlobalSettingsPath(): string {\n\t\treturn path.join(this.getGlobalConfigDir(), 'settings.json')\n\t}\n\n\t/**\n\t * Load and parse global settings file\n\t * Returns empty object if file doesn't exist (not an error)\n\t * Warns but returns empty object on validation/parse errors (graceful degradation)\n\t */\n\tprivate async loadGlobalSettingsFile(): Promise<z.infer<typeof IloomSettingsSchemaNoDefaults>> {\n\t\tconst settingsPath = this.getGlobalSettingsPath()\n\n\t\ttry {\n\t\t\tconst content = await readFile(settingsPath, 'utf-8')\n\t\t\tlet parsed: unknown\n\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(content)\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Failed to parse global settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Invalid JSON'}. Ignoring global settings.`,\n\t\t\t\t)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Validate with non-defaulting schema\n\t\t\ttry {\n\t\t\t\tconst validated = IloomSettingsSchemaNoDefaults.strict().parse(parsed)\n\t\t\t\treturn validated\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\t\tconst errorMsg = this.formatAllZodErrors(error, 'global settings')\n\t\t\t\t\tlogger.warn(`${errorMsg.message}. Ignoring global settings.`)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.warn(`Validation error in global settings: ${error instanceof Error ? error.message : 'Unknown error'}. Ignoring global settings.`)\n\t\t\t\t}\n\t\t\t\treturn {}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// File not found is not an error - return empty settings\n\t\t\tif ((error as { code?: string }).code === 'ENOENT') {\n\t\t\t\tlogger.debug(`No global settings file found at ${settingsPath}`)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Other file system errors - warn and continue\n\t\t\tlogger.warn(`Error reading global settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Unknown error'}. Ignoring global settings.`)\n\t\t\treturn {}\n\t\t}\n\t}\n\n\t/**\n\t * Get effective protected branches list with mainBranch always included\n\t *\n\t * This method provides a single source of truth for protected branches logic:\n\t * 1. Use configured protectedBranches if provided\n\t * 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']\n\t * 3. ALWAYS ensure mainBranch is included even if user configured custom list\n\t *\n\t * @param projectRoot - Optional project root directory (defaults to process.cwd())\n\t * @returns Array of protected branch names with mainBranch guaranteed to be included\n\t */\n\tasync getProtectedBranches(projectRoot?: string): Promise<string[]> {\n\t\tconst settings = await this.loadSettings(projectRoot)\n\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\tconst mainBranch = settings.mainBranch ?? 'main'\n\n\t\t// Build protected branches list:\n\t\t// 1. Use configured protectedBranches if provided\n\t\t// 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']\n\t\t// 3. ALWAYS ensure mainBranch is included even if user configured custom list\n\t\tlet protectedBranches: string[]\n\t\tif (settings.protectedBranches) {\n\t\t\t// Use configured list but ensure mainBranch is always included\n\t\t\tprotectedBranches = settings.protectedBranches.includes(mainBranch)\n\t\t\t\t? settings.protectedBranches\n\t\t\t\t: [mainBranch, ...settings.protectedBranches]\n\t\t} else {\n\t\t\t// Use defaults with current mainBranch\n\t\t\tprotectedBranches = [mainBranch, 'main', 'master', 'develop']\n\t\t}\n\n\t\treturn protectedBranches\n\t}\n\n\t/**\n\t * Get the spin orchestrator model with default applied\n\t * Default is defined in SpinAgentSettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetSpinModel(settings?: IloomSettings): 'sonnet' | 'opus' | 'haiku' {\n\t\treturn settings?.spin?.model ?? SpinAgentSettingsSchema.parse({}).model\n\t}\n\n\t/**\n\t * Get the plan command model with default applied\n\t * Default is defined in PlanCommandSettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetPlanModel(settings?: IloomSettings): 'sonnet' | 'opus' | 'haiku' {\n\t\treturn settings?.plan?.model ?? PlanCommandSettingsSchema.parse({}).model\n\t}\n\n\t/**\n\t * Get the plan command planner with default applied\n\t * Default is 'claude'\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Planner provider ('claude', 'gemini', or 'codex')\n\t */\n\tgetPlanPlanner(settings?: IloomSettings): 'claude' | 'gemini' | 'codex' {\n\t\treturn settings?.plan?.planner ?? 'claude'\n\t}\n\n\t/**\n\t * Get the plan command reviewer with default applied\n\t * Default is 'none' (no review step)\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Reviewer provider ('claude', 'gemini', 'codex', or 'none')\n\t */\n\tgetPlanReviewer(settings?: IloomSettings): 'claude' | 'gemini' | 'codex' | 'none' {\n\t\treturn settings?.plan?.reviewer ?? 'none'\n\t}\n\n\t/**\n\t * Get the session summary model with default applied\n\t * Default is defined in SummarySettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetSummaryModel(settings?: IloomSettings): 'sonnet' | 'opus' | 'haiku' {\n\t\treturn settings?.summary?.model ?? SummarySettingsSchema.parse({}).model\n\t}\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -10,17 +10,17 @@ import {
|
|
|
10
10
|
} from "./chunk-FXDYIV3K.js";
|
|
11
11
|
import {
|
|
12
12
|
PromptTemplateManager
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QN47QVBX.js";
|
|
14
14
|
import {
|
|
15
15
|
SettingsManager
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-XFEK2X2D.js";
|
|
17
17
|
import {
|
|
18
18
|
MetadataManager
|
|
19
19
|
} from "./chunk-KBEIQP4G.js";
|
|
20
20
|
import {
|
|
21
21
|
generateDeterministicSessionId,
|
|
22
22
|
launchClaude
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-FO5GGFOV.js";
|
|
24
24
|
import {
|
|
25
25
|
logger
|
|
26
26
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -369,4 +369,4 @@ var SessionSummaryService = class {
|
|
|
369
369
|
export {
|
|
370
370
|
SessionSummaryService
|
|
371
371
|
};
|
|
372
|
-
//# sourceMappingURL=chunk-
|
|
372
|
+
//# sourceMappingURL=chunk-Z6F5CUS6.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getClaudeVersion,
|
|
8
8
|
launchClaude,
|
|
9
9
|
launchClaudeInNewTerminalWindow
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FO5GGFOV.js";
|
|
11
11
|
import "./chunk-6MLEBAYZ.js";
|
|
12
12
|
import "./chunk-VT4PDUYT.js";
|
|
13
13
|
export {
|
|
@@ -19,4 +19,4 @@ export {
|
|
|
19
19
|
launchClaude,
|
|
20
20
|
launchClaudeInNewTerminalWindow
|
|
21
21
|
};
|
|
22
|
-
//# sourceMappingURL=claude-
|
|
22
|
+
//# sourceMappingURL=claude-TP2QO3BU.js.map
|
|
@@ -5,26 +5,31 @@ import {
|
|
|
5
5
|
EnvironmentManager,
|
|
6
6
|
LoomManager,
|
|
7
7
|
ResourceCleanup
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6Y3FTRJL.js";
|
|
9
|
+
import "./chunk-I23OQB4Y.js";
|
|
9
10
|
import {
|
|
10
11
|
ProcessManager
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-52MVUK5V.js";
|
|
12
|
+
} from "./chunk-NTTSUAVM.js";
|
|
13
|
+
import "./chunk-USSL2X4A.js";
|
|
14
14
|
import {
|
|
15
15
|
IdentifierParser
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2HZX6AMR.js";
|
|
17
17
|
import {
|
|
18
18
|
createNeonProviderFromSettings
|
|
19
19
|
} from "./chunk-7ZEHSSUP.js";
|
|
20
|
+
import "./chunk-YETJNRQM.js";
|
|
21
|
+
import "./chunk-UDZCTLD6.js";
|
|
22
|
+
import "./chunk-RNBIISBZ.js";
|
|
23
|
+
import "./chunk-4LKGCFGG.js";
|
|
20
24
|
import {
|
|
21
25
|
GitWorktreeManager
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
26
|
+
} from "./chunk-4GAJJUYS.js";
|
|
27
|
+
import "./chunk-FXDYIV3K.js";
|
|
28
|
+
import "./chunk-VOGGLPG5.js";
|
|
29
|
+
import "./chunk-H6ST2TGP.js";
|
|
25
30
|
import {
|
|
26
31
|
SettingsManager
|
|
27
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-XFEK2X2D.js";
|
|
28
33
|
import "./chunk-KBEIQP4G.js";
|
|
29
34
|
import "./chunk-PVW6JE7E.js";
|
|
30
35
|
import "./chunk-THS5L54H.js";
|
|
@@ -32,7 +37,7 @@ import {
|
|
|
32
37
|
promptConfirmation
|
|
33
38
|
} from "./chunk-7JDMYTFZ.js";
|
|
34
39
|
import "./chunk-433MOLAU.js";
|
|
35
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-FO5GGFOV.js";
|
|
36
41
|
import {
|
|
37
42
|
getLogger
|
|
38
43
|
} from "./chunk-6MLEBAYZ.js";
|
|
@@ -79,9 +84,9 @@ var CleanupCommand = class {
|
|
|
79
84
|
);
|
|
80
85
|
if (!this.loomManager) {
|
|
81
86
|
const { GitHubService } = await import("./GitHubService-ACZVNTJE.js");
|
|
82
|
-
const { ClaudeContextManager } = await import("./ClaudeContextManager-
|
|
83
|
-
const { ProjectCapabilityDetector } = await import("./ProjectCapabilityDetector-
|
|
84
|
-
const { DefaultBranchNamingService } = await import("./BranchNamingService-
|
|
87
|
+
const { ClaudeContextManager } = await import("./ClaudeContextManager-X2Y72GRL.js");
|
|
88
|
+
const { ProjectCapabilityDetector } = await import("./ProjectCapabilityDetector-N5L7T4IY.js");
|
|
89
|
+
const { DefaultBranchNamingService } = await import("./BranchNamingService-K6XNWQ6C.js");
|
|
85
90
|
this.loomManager = new LoomManager(
|
|
86
91
|
this.gitWorktreeManager,
|
|
87
92
|
new GitHubService(),
|
|
@@ -285,7 +290,7 @@ var CleanupCommand = class {
|
|
|
285
290
|
const { force, dryRun } = parsed.options;
|
|
286
291
|
let parsedInput = await this.identifierParser.parseForPatternDetection(identifier);
|
|
287
292
|
if (parsedInput.type === "branch" && parsedInput.branchName) {
|
|
288
|
-
const { extractIssueNumber } = await import("./git-
|
|
293
|
+
const { extractIssueNumber } = await import("./git-W3XUIFTR.js");
|
|
289
294
|
const extractedNumber = extractIssueNumber(parsedInput.branchName);
|
|
290
295
|
if (extractedNumber !== null) {
|
|
291
296
|
parsedInput = {
|
|
@@ -484,4 +489,4 @@ var CleanupCommand = class {
|
|
|
484
489
|
export {
|
|
485
490
|
CleanupCommand
|
|
486
491
|
};
|
|
487
|
-
//# sourceMappingURL=cleanup-
|
|
492
|
+
//# sourceMappingURL=cleanup-M6N7KV7E.js.map
|