@iloom/cli 0.5.5 → 0.6.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 (86) hide show
  1. package/README.md +75 -4
  2. package/dist/{ClaudeContextManager-7WX7DUNI.js → ClaudeContextManager-6J2EB4QU.js} +4 -4
  3. package/dist/{ClaudeService-LQLN2GP4.js → ClaudeService-O2PB22GX.js} +3 -3
  4. package/dist/{LoomLauncher-5QU42LOM.js → LoomLauncher-5LFM4LXB.js} +4 -4
  5. package/dist/ProjectCapabilityDetector-S5FLNCFI.js +11 -0
  6. package/dist/{PromptTemplateManager-5GNF7FCP.js → PromptTemplateManager-C3DK6XZL.js} +2 -2
  7. package/dist/README.md +75 -4
  8. package/dist/agents/iloom-framework-detector.md +366 -0
  9. package/dist/agents/iloom-issue-analyze-and-plan.md +0 -10
  10. package/dist/agents/iloom-issue-implementer.md +1 -1
  11. package/dist/agents/iloom-issue-planner.md +0 -10
  12. package/dist/build-FJVYP7EV.js +27 -0
  13. package/dist/build-FJVYP7EV.js.map +1 -0
  14. package/dist/{chunk-SHVB3EFE.js → chunk-64O2UIWO.js} +44 -19
  15. package/dist/chunk-64O2UIWO.js.map +1 -0
  16. package/dist/{chunk-FO2H3YXI.js → chunk-6U6VI4SZ.js} +2 -2
  17. package/dist/{chunk-VXMY22TP.js → chunk-7WANFUIK.js} +2 -2
  18. package/dist/{chunk-LVLRMP7V.js → chunk-AXX3QIKK.js} +58 -14
  19. package/dist/chunk-AXX3QIKK.js.map +1 -0
  20. package/dist/chunk-BXCPJJYM.js +133 -0
  21. package/dist/chunk-BXCPJJYM.js.map +1 -0
  22. package/dist/{chunk-SJIMVKK7.js → chunk-K7SEEHKO.js} +2 -2
  23. package/dist/{chunk-46JVEGUW.js → chunk-PMVWQBWS.js} +13 -13
  24. package/dist/chunk-PMVWQBWS.js.map +1 -0
  25. package/dist/{chunk-NKRQNER7.js → chunk-Q7POFB5Q.js} +1 -55
  26. package/dist/chunk-Q7POFB5Q.js.map +1 -0
  27. package/dist/{chunk-N4ZJVATC.js → chunk-SN3Z6EZO.js} +11 -7
  28. package/dist/chunk-SN3Z6EZO.js.map +1 -0
  29. package/dist/chunk-TRQ76ISK.js +159 -0
  30. package/dist/chunk-TRQ76ISK.js.map +1 -0
  31. package/dist/{chunk-WZHBRKLN.js → chunk-UB4TFAXJ.js} +36 -7
  32. package/dist/chunk-UB4TFAXJ.js.map +1 -0
  33. package/dist/{chunk-K5G5SFWY.js → chunk-W6WVRHJ6.js} +13 -1
  34. package/dist/chunk-W6WVRHJ6.js.map +1 -0
  35. package/dist/{chunk-EBISESAP.js → chunk-ZPSTA5PR.js} +16 -6
  36. package/dist/chunk-ZPSTA5PR.js.map +1 -0
  37. package/dist/{cleanup-WTZZ74VS.js → cleanup-OU2HFOOG.js} +6 -6
  38. package/dist/cli.js +94 -56
  39. package/dist/cli.js.map +1 -1
  40. package/dist/compile-ULNO5F7Q.js +57 -0
  41. package/dist/compile-ULNO5F7Q.js.map +1 -0
  42. package/dist/{dev-server-S5QG5SBZ.js → dev-server-4RCDJ5MU.js} +5 -5
  43. package/dist/{feedback-PDMCKYOT.js → feedback-O4Q55SVS.js} +7 -7
  44. package/dist/{ignite-YF4Q5RA7.js → ignite-VHV65WEZ.js} +9 -5
  45. package/dist/ignite-VHV65WEZ.js.map +1 -0
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.js +12 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/{init-XQQGC6DN.js → init-HB34Q5FH.js} +5 -4
  50. package/dist/lint-5JMCWE4Y.js +27 -0
  51. package/dist/lint-5JMCWE4Y.js.map +1 -0
  52. package/dist/{open-AIZG5756.js → open-WHVUYGPY.js} +5 -5
  53. package/dist/prompts/init-prompt.txt +100 -0
  54. package/dist/prompts/issue-prompt.txt +12 -12
  55. package/dist/{run-CMZUYZVG.js → run-NCRK5NPR.js} +5 -5
  56. package/dist/{summary-5YXUGPRN.js → summary-CVFAMDOJ.js} +3 -3
  57. package/dist/test-3KIVXI6J.js +27 -0
  58. package/dist/test-3KIVXI6J.js.map +1 -0
  59. package/package.json +1 -1
  60. package/dist/ProjectCapabilityDetector-34LU7JJ4.js +0 -9
  61. package/dist/chunk-2ZPFJQ3B.js +0 -63
  62. package/dist/chunk-2ZPFJQ3B.js.map +0 -1
  63. package/dist/chunk-46JVEGUW.js.map +0 -1
  64. package/dist/chunk-EBISESAP.js.map +0 -1
  65. package/dist/chunk-K5G5SFWY.js.map +0 -1
  66. package/dist/chunk-LVLRMP7V.js.map +0 -1
  67. package/dist/chunk-N4ZJVATC.js.map +0 -1
  68. package/dist/chunk-NKRQNER7.js.map +0 -1
  69. package/dist/chunk-SHVB3EFE.js.map +0 -1
  70. package/dist/chunk-WZHBRKLN.js.map +0 -1
  71. package/dist/ignite-YF4Q5RA7.js.map +0 -1
  72. /package/dist/{ClaudeContextManager-7WX7DUNI.js.map → ClaudeContextManager-6J2EB4QU.js.map} +0 -0
  73. /package/dist/{ClaudeService-LQLN2GP4.js.map → ClaudeService-O2PB22GX.js.map} +0 -0
  74. /package/dist/{LoomLauncher-5QU42LOM.js.map → LoomLauncher-5LFM4LXB.js.map} +0 -0
  75. /package/dist/{ProjectCapabilityDetector-34LU7JJ4.js.map → ProjectCapabilityDetector-S5FLNCFI.js.map} +0 -0
  76. /package/dist/{PromptTemplateManager-5GNF7FCP.js.map → PromptTemplateManager-C3DK6XZL.js.map} +0 -0
  77. /package/dist/{chunk-FO2H3YXI.js.map → chunk-6U6VI4SZ.js.map} +0 -0
  78. /package/dist/{chunk-VXMY22TP.js.map → chunk-7WANFUIK.js.map} +0 -0
  79. /package/dist/{chunk-SJIMVKK7.js.map → chunk-K7SEEHKO.js.map} +0 -0
  80. /package/dist/{cleanup-WTZZ74VS.js.map → cleanup-OU2HFOOG.js.map} +0 -0
  81. /package/dist/{dev-server-S5QG5SBZ.js.map → dev-server-4RCDJ5MU.js.map} +0 -0
  82. /package/dist/{feedback-PDMCKYOT.js.map → feedback-O4Q55SVS.js.map} +0 -0
  83. /package/dist/{init-XQQGC6DN.js.map → init-HB34Q5FH.js.map} +0 -0
  84. /package/dist/{open-AIZG5756.js.map → open-WHVUYGPY.js.map} +0 -0
  85. /package/dist/{run-CMZUYZVG.js.map → run-NCRK5NPR.js.map} +0 -0
  86. /package/dist/{summary-5YXUGPRN.js.map → summary-CVFAMDOJ.js.map} +0 -0
@@ -141,7 +141,7 @@ Before implementing, extract and validate the implementation plan:
141
141
  - Keep the user informed of your plan and updated with your progress via an issue comment (see "HOW TO UPDATE THE USER OF YOUR PROGRESS", below)
142
142
  - Identify any ambiguities or decision points before starting
143
143
  - Implement the solution exactly as specified
144
- - When done, run "validate:commit" command if available in package.json. If not: typecheck, run tests and lint in that order.
144
+ - When done, run "validate:commit" command if available in package.json. If not: run `il compile`, `il test`, and `il lint` in that order.
145
145
  - When all is validated, update your issue comment with a concise final summary (see "Final Summary Format" below)
146
146
  - Avoid escaping issues by writing comments to temporary files before posting
147
147
 
@@ -186,16 +186,6 @@ When planning frontend changes:
186
186
  - Look for alternative existing classes first
187
187
  - Create new classes or element-specific overrides when needed
188
188
 
189
- ### Payload 3.0 CMS Data Migrations - see context7 for more information:
190
- * If you need to do custom migrations (such as a data migration), you must first create a migration using `pnpm payload migrate:create --force-accept-warning` - you must then edit that empty migration to implement the data migration. Focus on making the up() implementation correct, and provide a reasonable proxy to a down() solution. It doesn’t have to be a perfect reversal in terms of data correctness, only schema correctness.
191
- * IMPORTANT - DO NOT SKIP THIS (OR ANY OTHER) STEP: When doing custom migrations (which should only be necessary in case of data migrations, you must make sure all tables and columns exist by cross-referencing them with the most recently committed *.json file in the migrations folder. These JSON files contain the most recent schema as understood by the migration tool. It should be used in lieu of access to the the DB, which you don’t have.
192
- * If you are creating a regular migration after adjusting the schema you must use `pnpm payload migrate:create --skip-empty`
193
- * If performing multiple phases (i.e creating some fields and deleting some fields) create migrations after each phase (i.e after adding to a collection or global config, then again after removing fields from a collection or global config). Doing them together will cause issues with the migration tool and you won’t be able to complete your task.
194
- * Similarly, separate data migration files from schema change files - using a separate migration for each
195
- * IMPORTANT: DO NOT manually create/edit migrations for adding or removing fields from a collection or global config. This is handled by running the migrate:create command. You only need to create manual migrations when doing data migrations, not schema migrations.
196
- * You should provide a slug string argument to migrate:create that is a description of the change - this will create more descriptive filenames and makes part of the filename deterministic, but be mindful of multiple files with the same slug (but will have a different timestamp)
197
- * Do not plan to run the migrations - the implementor will not have permissions to do that. The deploy process will automatically do that when the implementor makes a commit.
198
-
199
189
  ## Plan Documentation Format
200
190
 
201
191
  **CRITICAL**: Your implementation plan must be structured in TWO sections for different audiences:
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ScriptCommandBase
4
+ } from "./chunk-TRQ76ISK.js";
5
+ import "./chunk-AXX3QIKK.js";
6
+ import "./chunk-UQIXZ3BA.js";
7
+ import "./chunk-BXCPJJYM.js";
8
+ import "./chunk-EK3XCAAS.js";
9
+ import "./chunk-GEXP5IOF.js";
10
+ import "./chunk-F6WVM437.js";
11
+ import "./chunk-CFUWQHCJ.js";
12
+ import "./chunk-6MLEBAYZ.js";
13
+ import "./chunk-VT4PDUYT.js";
14
+
15
+ // src/commands/build.ts
16
+ var BuildCommand = class extends ScriptCommandBase {
17
+ getScriptName() {
18
+ return "build";
19
+ }
20
+ getScriptDisplayName() {
21
+ return "Build";
22
+ }
23
+ };
24
+ export {
25
+ BuildCommand
26
+ };
27
+ //# sourceMappingURL=build-FJVYP7EV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/build.ts"],"sourcesContent":["import { ScriptCommandBase, ScriptCommandInput } from './script-command-base.js'\n\nexport type { ScriptCommandInput as BuildCommandInput }\n\n/**\n * BuildCommand - Run the build script for a workspace\n * Uses package.iloom.json if available, otherwise falls back to package.json\n */\nexport class BuildCommand extends ScriptCommandBase {\n\tgetScriptName(): string {\n\t\treturn 'build'\n\t}\n\n\tgetScriptDisplayName(): string {\n\t\treturn 'Build'\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;AAQO,IAAM,eAAN,cAA2B,kBAAkB;AAAA,EACnD,gBAAwB;AACvB,WAAO;AAAA,EACR;AAAA,EAEA,uBAA+B;AAC9B,WAAO;AAAA,EACR;AACD;","names":[]}
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- detectPackageManager
4
- } from "./chunk-LVLRMP7V.js";
5
2
  import {
6
3
  ProcessManager
7
4
  } from "./chunk-VU3QMIP2.js";
5
+ import {
6
+ detectPackageManager,
7
+ runScript
8
+ } from "./chunk-AXX3QIKK.js";
9
+ import {
10
+ readPackageJson
11
+ } from "./chunk-BXCPJJYM.js";
8
12
  import {
9
13
  logger
10
14
  } from "./chunk-VT4PDUYT.js";
@@ -77,6 +81,17 @@ var DevServerManager = class {
77
81
  * Start dev server in background and wait for it to be ready
78
82
  */
79
83
  async startDevServer(worktreePath, port) {
84
+ var _a;
85
+ try {
86
+ const packageJson = await readPackageJson(worktreePath);
87
+ if (!((_a = packageJson.scripts) == null ? void 0 : _a["dev"])) {
88
+ logger.warn('Skipping auto-start: no "dev" script found in package.json');
89
+ return;
90
+ }
91
+ } catch {
92
+ logger.debug("Skipping auto-start: no package.json found");
93
+ return;
94
+ }
80
95
  const devCommand = await buildDevServerCommand(worktreePath);
81
96
  logger.debug(`Starting dev server with command: ${devCommand}`);
82
97
  const serverProcess = execa("sh", ["-c", devCommand], {
@@ -144,26 +159,36 @@ var DevServerManager = class {
144
159
  * @returns Process information including PID
145
160
  */
146
161
  async runServerForeground(worktreePath, port, redirectToStderr = false, onProcessStarted, envOverrides) {
147
- const devCommand = await buildDevServerCommand(worktreePath);
148
- logger.debug(`Starting dev server in foreground with command: ${devCommand}`);
149
- const stdio = redirectToStderr ? [process.stdin, process.stderr, process.stderr] : "inherit";
150
- const serverProcess = execa("sh", ["-c", devCommand], {
151
- cwd: worktreePath,
162
+ logger.debug(`Starting dev server in foreground on port ${port}`);
163
+ if (redirectToStderr) {
164
+ const devCommand = await buildDevServerCommand(worktreePath);
165
+ logger.debug(`Starting dev server with command: ${devCommand}`);
166
+ const serverProcess = execa("sh", ["-c", devCommand], {
167
+ cwd: worktreePath,
168
+ env: {
169
+ ...process.env,
170
+ ...envOverrides,
171
+ PORT: port.toString()
172
+ },
173
+ stdio: [process.stdin, process.stderr, process.stderr]
174
+ });
175
+ const processInfo = serverProcess.pid !== void 0 ? { pid: serverProcess.pid } : {};
176
+ if (onProcessStarted) {
177
+ onProcessStarted(processInfo.pid);
178
+ }
179
+ await serverProcess;
180
+ return processInfo;
181
+ }
182
+ return await runScript("dev", worktreePath, [], {
152
183
  env: {
153
- ...process.env,
154
184
  ...envOverrides,
155
185
  PORT: port.toString()
156
- // PORT always wins (explicit parameter)
157
186
  },
158
- // Configure stdio based on whether we want to redirect output
159
- stdio
187
+ foreground: true,
188
+ ...onProcessStarted && { onStart: onProcessStarted },
189
+ noCi: true
190
+ // Dev servers should not have CI=true
160
191
  });
161
- const processInfo = serverProcess.pid !== void 0 ? { pid: serverProcess.pid } : {};
162
- if (onProcessStarted) {
163
- onProcessStarted(processInfo.pid);
164
- }
165
- await serverProcess;
166
- return processInfo;
167
192
  }
168
193
  /**
169
194
  * Clean up all running server processes
@@ -187,4 +212,4 @@ var DevServerManager = class {
187
212
  export {
188
213
  DevServerManager
189
214
  };
190
- //# sourceMappingURL=chunk-SHVB3EFE.js.map
215
+ //# sourceMappingURL=chunk-64O2UIWO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/DevServerManager.ts","../src/utils/dev-server.ts"],"sourcesContent":["import { execa, type ExecaChildProcess } from 'execa'\nimport { setTimeout } from 'timers/promises'\nimport { ProcessManager } from './process/ProcessManager.js'\nimport { buildDevServerCommand } from '../utils/dev-server.js'\nimport { runScript } from '../utils/package-manager.js'\nimport { readPackageJson } from '../utils/package-json.js'\nimport { logger } from '../utils/logger.js'\n\nexport interface DevServerManagerOptions {\n\t/**\n\t * Maximum time to wait for server to start (in milliseconds)\n\t * Default: 30000 (30 seconds)\n\t */\n\tstartupTimeout?: number\n\n\t/**\n\t * Interval between port checks (in milliseconds)\n\t * Default: 1000 (1 second)\n\t */\n\tcheckInterval?: number\n}\n\n/**\n * DevServerManager handles auto-starting and monitoring dev servers\n * Used by open/run commands to ensure dev server is running before opening browser\n */\nexport class DevServerManager {\n\tprivate readonly processManager: ProcessManager\n\tprivate readonly options: Required<DevServerManagerOptions>\n\tprivate runningServers: Map<number, ExecaChildProcess> = new Map()\n\n\tconstructor(\n\t\tprocessManager?: ProcessManager,\n\t\toptions: DevServerManagerOptions = {}\n\t) {\n\t\tthis.processManager = processManager ?? new ProcessManager()\n\t\tthis.options = {\n\t\t\tstartupTimeout: options.startupTimeout ?? 30000,\n\t\t\tcheckInterval: options.checkInterval ?? 1000,\n\t\t}\n\t}\n\n\t/**\n\t * Ensure dev server is running on the specified port\n\t * If not running, start it and wait for it to be ready\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param port - Port the server should run on\n\t * @returns true if server is ready, false if startup failed/timed out\n\t */\n\tasync ensureServerRunning(worktreePath: string, port: number): Promise<boolean> {\n\t\tlogger.debug(`Checking if dev server is running on port ${port}...`)\n\n\t\t// Check if already running\n\t\tconst existingProcess = await this.processManager.detectDevServer(port)\n\t\tif (existingProcess) {\n\t\t\tlogger.debug(\n\t\t\t\t`Dev server already running on port ${port} (PID: ${existingProcess.pid})`\n\t\t\t)\n\t\t\treturn true\n\t\t}\n\n\t\t// Not running - start it\n\t\tlogger.info(`Dev server not running on port ${port}, starting...`)\n\n\t\ttry {\n\t\t\tawait this.startDevServer(worktreePath, port)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tlogger.error(\n\t\t\t\t`Failed to start dev server: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Start dev server in background and wait for it to be ready\n\t */\n\tprivate async startDevServer(worktreePath: string, port: number): Promise<void> {\n\t\t// Guard: Check if package.json exists and has a dev script\n\t\t// Note: buildDevServerCommand only supports package.json via package managers,\n\t\t// not package.iloom.json. See #406 for multi-language support.\n\t\ttry {\n\t\t\tconst packageJson = await readPackageJson(worktreePath)\n\t\t\tif (!packageJson.scripts?.['dev']) {\n\t\t\t\tlogger.warn('Skipping auto-start: no \"dev\" script found in package.json')\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch {\n\t\t\t// package.json doesn't exist - skip auto-start silently\n\t\t\tlogger.debug('Skipping auto-start: no package.json found')\n\t\t\treturn\n\t\t}\n\n\t\t// Build dev server command\n\t\tconst devCommand = await buildDevServerCommand(worktreePath)\n\t\tlogger.debug(`Starting dev server with command: ${devCommand}`)\n\n\t\t// Start server in background\n\t\tconst serverProcess = execa('sh', ['-c', devCommand], {\n\t\t\tcwd: worktreePath,\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tPORT: port.toString(),\n\t\t\t},\n\t\t\t// Important: Don't inherit stdio - server runs in background\n\t\t\tstdio: 'ignore',\n\t\t\t// Detach from parent process so it continues running\n\t\t\tdetached: true,\n\t\t})\n\n\t\t// Store reference to prevent cleanup\n\t\tthis.runningServers.set(port, serverProcess)\n\n\t\t// Unref so parent can exit\n\t\tserverProcess.unref()\n\n\t\t// Wait for server to be ready\n\t\tlogger.info(`Waiting for dev server to start on port ${port}...`)\n\t\tconst ready = await this.waitForServerReady(port)\n\n\t\tif (!ready) {\n\t\t\tthrow new Error(\n\t\t\t\t`Dev server failed to start within ${this.options.startupTimeout}ms timeout`\n\t\t\t)\n\t\t}\n\n\t\tlogger.success(`Dev server started successfully on port ${port}`)\n\t}\n\n\t/**\n\t * Wait for server to be ready by polling the port\n\t */\n\tprivate async waitForServerReady(port: number): Promise<boolean> {\n\t\tconst startTime = Date.now()\n\t\tlet attempts = 0\n\n\t\twhile (Date.now() - startTime < this.options.startupTimeout) {\n\t\t\tattempts++\n\n\t\t\t// Check if server is listening\n\t\t\tconst processInfo = await this.processManager.detectDevServer(port)\n\n\t\t\tif (processInfo) {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t`Server detected on port ${port} after ${attempts} attempts (${Date.now() - startTime}ms)`\n\t\t\t\t)\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\t// Wait before next check\n\t\t\tawait setTimeout(this.options.checkInterval)\n\t\t}\n\n\t\t// Timeout\n\t\tlogger.warn(\n\t\t\t`Server did not start on port ${port} after ${this.options.startupTimeout}ms (${attempts} attempts)`\n\t\t)\n\t\treturn false\n\t}\n\n\t/**\n\t * Check if a dev server is running on the specified port\n\t *\n\t * @param port - Port to check\n\t * @returns true if server is running, false otherwise\n\t */\n\tasync isServerRunning(port: number): Promise<boolean> {\n\t\tconst existingProcess = await this.processManager.detectDevServer(port)\n\t\treturn existingProcess !== null\n\t}\n\n\t/**\n\t * Run dev server in foreground mode (blocking)\n\t * This method blocks until the server is stopped (e.g., via Ctrl+C)\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param port - Port the server should run on\n\t * @param redirectToStderr - If true, redirect stdout/stderr to stderr (useful for JSON output)\n\t * @param onProcessStarted - Callback called immediately after process starts with PID\n\t * @returns Process information including PID\n\t */\n\tasync runServerForeground(\n\t\tworktreePath: string,\n\t\tport: number,\n\t\tredirectToStderr = false,\n\t\tonProcessStarted?: (pid?: number) => void,\n\t\tenvOverrides?: Record<string, string>\n\t): Promise<{ pid?: number }> {\n\t\tlogger.debug(`Starting dev server in foreground on port ${port}`)\n\n\t\t// Use runScript for foreground mode to support multi-language projects\n\t\t// Note: redirectToStderr is handled via custom execa call when needed\n\t\tif (redirectToStderr) {\n\t\t\t// For redirectToStderr, we still need direct execa control for custom stdio\n\t\t\tconst devCommand = await buildDevServerCommand(worktreePath)\n\t\t\tlogger.debug(`Starting dev server with command: ${devCommand}`)\n\n\t\t\tconst serverProcess = execa('sh', ['-c', devCommand], {\n\t\t\t\tcwd: worktreePath,\n\t\t\t\tenv: {\n\t\t\t\t\t...process.env,\n\t\t\t\t\t...envOverrides,\n\t\t\t\t\tPORT: port.toString(),\n\t\t\t\t},\n\t\t\t\tstdio: [process.stdin, process.stderr, process.stderr],\n\t\t\t})\n\n\t\t\tconst processInfo: { pid?: number } = serverProcess.pid !== undefined ? { pid: serverProcess.pid } : {}\n\n\t\t\tif (onProcessStarted) {\n\t\t\t\tonProcessStarted(processInfo.pid)\n\t\t\t}\n\n\t\t\tawait serverProcess\n\t\t\treturn processInfo\n\t\t}\n\n\t\t// Use runScript for standard foreground mode\n\t\treturn await runScript('dev', worktreePath, [], {\n\t\t\tenv: {\n\t\t\t\t...envOverrides,\n\t\t\t\tPORT: port.toString(),\n\t\t\t},\n\t\t\tforeground: true,\n\t\t\t...(onProcessStarted && { onStart: onProcessStarted }),\n\t\t\tnoCi: true, // Dev servers should not have CI=true\n\t\t})\n\t}\n\n\t/**\n\t * Clean up all running server processes\n\t * This should be called when the manager is being disposed\n\t */\n\tasync cleanup(): Promise<void> {\n\t\tfor (const [port, serverProcess] of this.runningServers.entries()) {\n\t\t\ttry {\n\t\t\t\tlogger.debug(`Cleaning up server process on port ${port}`)\n\t\t\t\tserverProcess.kill()\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Failed to kill server process on port ${port}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tthis.runningServers.clear()\n\t}\n}\n","import { detectPackageManager } from './package-manager.js'\nimport { logger } from './logger.js'\nimport type { Capability } from '../types/loom.js'\n\n/**\n * Build dev server command for workspace\n * Detects package manager and constructs appropriate command\n */\nexport async function buildDevServerCommand(\n\tworkspacePath: string\n): Promise<string> {\n\tconst packageManager = await detectPackageManager(workspacePath)\n\n\tlet devCommand: string\n\n\tswitch (packageManager) {\n\t\tcase 'pnpm':\n\t\t\tdevCommand = 'pnpm dev'\n\t\t\tbreak\n\t\tcase 'npm':\n\t\t\tdevCommand = 'npm run dev'\n\t\t\tbreak\n\t\tcase 'yarn':\n\t\t\tdevCommand = 'yarn dev'\n\t\t\tbreak\n\t\tdefault:\n\t\t\t// Fallback to npm (handles bun and other package managers)\n\t\t\tlogger.warn(`Unknown or unsupported package manager: ${packageManager}, defaulting to npm`)\n\t\t\tdevCommand = 'npm run dev'\n\t}\n\n\tlogger.debug(`Dev server command: ${devCommand}`)\n\treturn devCommand\n}\n\n/**\n * Build complete dev server launch command for terminal\n * Includes VSCode launch, echo message (only for web projects), and dev server start\n */\nexport async function getDevServerLaunchCommand(\n\tworkspacePath: string,\n\tport?: number,\n\tcapabilities: Capability[] = []\n): Promise<string> {\n\tconst devCommand = await buildDevServerCommand(workspacePath)\n\n\tconst commands: string[] = []\n\n\t// // Open VSCode\n\t// commands.push('code .')\n\n\t// Echo message (only for web projects)\n\tif (capabilities.includes('web')) {\n\t\tif (port !== undefined) {\n\t\t\tcommands.push(`echo 'Starting dev server on PORT=${port}...'`)\n\t\t} else {\n\t\t\tcommands.push(`echo 'Starting dev server...'`)\n\t\t}\n\t}\n\n\t// Start dev server\n\tcommands.push(devCommand)\n\n\treturn commands.join(' && ')\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,aAAqC;AAC9C,SAAS,kBAAkB;;;ACO3B,eAAsB,sBACrB,eACkB;AAClB,QAAM,iBAAiB,MAAM,qBAAqB,aAAa;AAE/D,MAAI;AAEJ,UAAQ,gBAAgB;AAAA,IACvB,KAAK;AACJ,mBAAa;AACb;AAAA,IACD,KAAK;AACJ,mBAAa;AACb;AAAA,IACD,KAAK;AACJ,mBAAa;AACb;AAAA,IACD;AAEC,aAAO,KAAK,2CAA2C,cAAc,qBAAqB;AAC1F,mBAAa;AAAA,EACf;AAEA,SAAO,MAAM,uBAAuB,UAAU,EAAE;AAChD,SAAO;AACR;;;ADPO,IAAM,mBAAN,MAAuB;AAAA,EAK7B,YACC,gBACA,UAAmC,CAAC,GACnC;AALF,SAAQ,iBAAiD,oBAAI,IAAI;AAMhE,SAAK,iBAAiB,kBAAkB,IAAI,eAAe;AAC3D,SAAK,UAAU;AAAA,MACd,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,eAAe,QAAQ,iBAAiB;AAAA,IACzC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAoB,cAAsB,MAAgC;AAC/E,WAAO,MAAM,6CAA6C,IAAI,KAAK;AAGnE,UAAM,kBAAkB,MAAM,KAAK,eAAe,gBAAgB,IAAI;AACtE,QAAI,iBAAiB;AACpB,aAAO;AAAA,QACN,sCAAsC,IAAI,UAAU,gBAAgB,GAAG;AAAA,MACxE;AACA,aAAO;AAAA,IACR;AAGA,WAAO,KAAK,kCAAkC,IAAI,eAAe;AAEjE,QAAI;AACH,YAAM,KAAK,eAAe,cAAc,IAAI;AAC5C,aAAO;AAAA,IACR,SAAS,OAAO;AACf,aAAO;AAAA,QACN,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,cAAsB,MAA6B;AA/EjF;AAmFE,QAAI;AACH,YAAM,cAAc,MAAM,gBAAgB,YAAY;AACtD,UAAI,GAAC,iBAAY,YAAZ,mBAAsB,SAAQ;AAClC,eAAO,KAAK,4DAA4D;AACxE;AAAA,MACD;AAAA,IACD,QAAQ;AAEP,aAAO,MAAM,4CAA4C;AACzD;AAAA,IACD;AAGA,UAAM,aAAa,MAAM,sBAAsB,YAAY;AAC3D,WAAO,MAAM,qCAAqC,UAAU,EAAE;AAG9D,UAAM,gBAAgB,MAAM,MAAM,CAAC,MAAM,UAAU,GAAG;AAAA,MACrD,KAAK;AAAA,MACL,KAAK;AAAA,QACJ,GAAG,QAAQ;AAAA,QACX,MAAM,KAAK,SAAS;AAAA,MACrB;AAAA;AAAA,MAEA,OAAO;AAAA;AAAA,MAEP,UAAU;AAAA,IACX,CAAC;AAGD,SAAK,eAAe,IAAI,MAAM,aAAa;AAG3C,kBAAc,MAAM;AAGpB,WAAO,KAAK,2CAA2C,IAAI,KAAK;AAChE,UAAM,QAAQ,MAAM,KAAK,mBAAmB,IAAI;AAEhD,QAAI,CAAC,OAAO;AACX,YAAM,IAAI;AAAA,QACT,qCAAqC,KAAK,QAAQ,cAAc;AAAA,MACjE;AAAA,IACD;AAEA,WAAO,QAAQ,2CAA2C,IAAI,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAmB,MAAgC;AAChE,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI,WAAW;AAEf,WAAO,KAAK,IAAI,IAAI,YAAY,KAAK,QAAQ,gBAAgB;AAC5D;AAGA,YAAM,cAAc,MAAM,KAAK,eAAe,gBAAgB,IAAI;AAElE,UAAI,aAAa;AAChB,eAAO;AAAA,UACN,2BAA2B,IAAI,UAAU,QAAQ,cAAc,KAAK,IAAI,IAAI,SAAS;AAAA,QACtF;AACA,eAAO;AAAA,MACR;AAGA,YAAM,WAAW,KAAK,QAAQ,aAAa;AAAA,IAC5C;AAGA,WAAO;AAAA,MACN,gCAAgC,IAAI,UAAU,KAAK,QAAQ,cAAc,OAAO,QAAQ;AAAA,IACzF;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,MAAgC;AACrD,UAAM,kBAAkB,MAAM,KAAK,eAAe,gBAAgB,IAAI;AACtE,WAAO,oBAAoB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,oBACL,cACA,MACA,mBAAmB,OACnB,kBACA,cAC4B;AAC5B,WAAO,MAAM,6CAA6C,IAAI,EAAE;AAIhE,QAAI,kBAAkB;AAErB,YAAM,aAAa,MAAM,sBAAsB,YAAY;AAC3D,aAAO,MAAM,qCAAqC,UAAU,EAAE;AAE9D,YAAM,gBAAgB,MAAM,MAAM,CAAC,MAAM,UAAU,GAAG;AAAA,QACrD,KAAK;AAAA,QACL,KAAK;AAAA,UACJ,GAAG,QAAQ;AAAA,UACX,GAAG;AAAA,UACH,MAAM,KAAK,SAAS;AAAA,QACrB;AAAA,QACA,OAAO,CAAC,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,MAAM;AAAA,MACtD,CAAC;AAED,YAAM,cAAgC,cAAc,QAAQ,SAAY,EAAE,KAAK,cAAc,IAAI,IAAI,CAAC;AAEtG,UAAI,kBAAkB;AACrB,yBAAiB,YAAY,GAAG;AAAA,MACjC;AAEA,YAAM;AACN,aAAO;AAAA,IACR;AAGA,WAAO,MAAM,UAAU,OAAO,cAAc,CAAC,GAAG;AAAA,MAC/C,KAAK;AAAA,QACJ,GAAG;AAAA,QACH,MAAM,KAAK,SAAS;AAAA,MACrB;AAAA,MACA,YAAY;AAAA,MACZ,GAAI,oBAAoB,EAAE,SAAS,iBAAiB;AAAA,MACpD,MAAM;AAAA;AAAA,IACP,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAyB;AAC9B,eAAW,CAAC,MAAM,aAAa,KAAK,KAAK,eAAe,QAAQ,GAAG;AAClE,UAAI;AACH,eAAO,MAAM,sCAAsC,IAAI,EAAE;AACzD,sBAAc,KAAK;AAAA,MACpB,SAAS,OAAO;AACf,eAAO;AAAA,UACN,yCAAyC,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC3G;AAAA,MACD;AAAA,IACD;AACA,SAAK,eAAe,MAAM;AAAA,EAC3B;AACD;","names":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PromptTemplateManager
4
- } from "./chunk-K5G5SFWY.js";
4
+ } from "./chunk-W6WVRHJ6.js";
5
5
  import {
6
6
  SettingsManager
7
7
  } from "./chunk-F6WVM437.js";
@@ -122,4 +122,4 @@ var ClaudeService = class {
122
122
  export {
123
123
  ClaudeService
124
124
  };
125
- //# sourceMappingURL=chunk-FO2H3YXI.js.map
125
+ //# sourceMappingURL=chunk-6U6VI4SZ.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ClaudeService
4
- } from "./chunk-FO2H3YXI.js";
4
+ } from "./chunk-6U6VI4SZ.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-VT4PDUYT.js";
@@ -63,4 +63,4 @@ var ClaudeContextManager = class {
63
63
  export {
64
64
  ClaudeContextManager
65
65
  };
66
- //# sourceMappingURL=chunk-VXMY22TP.js.map
66
+ //# sourceMappingURL=chunk-7WANFUIK.js.map
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ getPackageScripts
4
+ } from "./chunk-BXCPJJYM.js";
2
5
  import {
3
6
  getLogger
4
7
  } from "./chunk-6MLEBAYZ.js";
@@ -55,9 +58,16 @@ async function installDependencies(cwd, frozen = true, quiet = false) {
55
58
  getLogger().debug("Skipping dependency installation - no working directory provided");
56
59
  return;
57
60
  }
61
+ const scripts = await getPackageScripts(cwd);
62
+ if (scripts.install) {
63
+ getLogger().info("Installing dependencies with install script...");
64
+ await runScript("install", cwd, [], { quiet });
65
+ getLogger().success("Dependencies installed successfully");
66
+ return;
67
+ }
58
68
  const pkgPath = path.join(cwd, "package.json");
59
69
  if (!await fs.pathExists(pkgPath)) {
60
- getLogger().debug("Skipping dependency installation - no package.json found");
70
+ getLogger().debug("Skipping dependency installation - no package.json found and no install script");
61
71
  return;
62
72
  }
63
73
  const packageManager = await detectPackageManager(cwd);
@@ -92,19 +102,53 @@ async function installDependencies(cwd, frozen = true, quiet = false) {
92
102
  }
93
103
  }
94
104
  async function runScript(scriptName, cwd, args = [], options = {}) {
95
- const packageManager = await detectPackageManager(cwd);
96
- const command = packageManager === "npm" ? ["run", scriptName] : [scriptName];
105
+ const scripts = await getPackageScripts(cwd);
106
+ const scriptConfig = scripts[scriptName];
107
+ const isDebugMode = getLogger().isDebugEnabled();
108
+ if (!scriptConfig) {
109
+ throw new Error(`Script '${scriptName}' not found`);
110
+ }
111
+ const env = {
112
+ ...process.env,
113
+ ...options.env
114
+ };
115
+ if (!options.noCi) {
116
+ env.CI = "true";
117
+ }
118
+ const stdio = options.foreground ? "inherit" : options.quiet ? "pipe" : "inherit";
97
119
  try {
98
- await execa(packageManager, [...command, ...args], {
99
- cwd,
100
- stdio: options.quiet ? "pipe" : "inherit",
101
- timeout: 6e5,
102
- // 10 minute timeout for scripts
103
- env: {
104
- ...process.env,
105
- CI: "true"
106
- }
107
- });
120
+ let execaProcess;
121
+ if (scriptConfig.source === "iloom-config") {
122
+ getLogger().debug(`Executing shell command: ${scriptConfig.command} with args: ${args.join(" ")}`);
123
+ execaProcess = execa("sh", ["-c", `${scriptConfig.command} "$@"`, "--", ...args], {
124
+ cwd,
125
+ stdio,
126
+ ...!options.foreground && { timeout: 6e5 },
127
+ // No timeout for foreground mode
128
+ env,
129
+ verbose: isDebugMode
130
+ });
131
+ } else {
132
+ const packageManager = await detectPackageManager(cwd);
133
+ const command = packageManager === "npm" ? ["run", scriptName] : [scriptName];
134
+ execaProcess = execa(packageManager, [...command, ...args], {
135
+ cwd,
136
+ stdio,
137
+ ...!options.foreground && { timeout: 6e5 },
138
+ // No timeout for foreground mode
139
+ env,
140
+ verbose: isDebugMode
141
+ });
142
+ }
143
+ const result = {};
144
+ if (options.foreground && execaProcess.pid !== void 0) {
145
+ result.pid = execaProcess.pid;
146
+ }
147
+ if (options.onStart) {
148
+ options.onStart(result.pid);
149
+ }
150
+ await execaProcess;
151
+ return result;
108
152
  } catch (error) {
109
153
  const execaError = error;
110
154
  const stderr = execaError.stderr ?? execaError.message ?? "Unknown error";
@@ -117,4 +161,4 @@ export {
117
161
  installDependencies,
118
162
  runScript
119
163
  };
120
- //# sourceMappingURL=chunk-LVLRMP7V.js.map
164
+ //# sourceMappingURL=chunk-AXX3QIKK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/package-manager.ts"],"sourcesContent":["import { execa, type ExecaError } from 'execa'\nimport { getLogger } from './logger-context.js'\nimport { getPackageScripts } from './package-json.js'\nimport fs from 'fs-extra'\nimport path from 'path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn'\n\n/**\n * Validate if a string is a supported package manager\n */\nfunction isValidPackageManager(manager: string): manager is PackageManager {\n return manager === 'pnpm' || manager === 'npm' || manager === 'yarn'\n}\n\n/**\n * Detect which package manager to use for a project\n * Checks in order:\n * 1. packageManager field in package.json (Node.js standard)\n * 2. Lock files (pnpm-lock.yaml, package-lock.json, yarn.lock)\n * 3. Installed package managers (system-wide check)\n * 4. Defaults to npm if all detection fails\n *\n * @param cwd Working directory to detect package manager in (defaults to process.cwd())\n * @returns The detected package manager, or 'npm' as default\n */\nexport async function detectPackageManager(cwd: string = process.cwd()): Promise<PackageManager> {\n // 1. Check packageManager field in package.json\n try {\n const packageJsonPath = path.join(cwd, 'package.json')\n if (await fs.pathExists(packageJsonPath)) {\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')\n const packageJson = JSON.parse(packageJsonContent)\n\n if (packageJson.packageManager) {\n // Parse \"pnpm@8.15.0\" or \"pnpm@10.16.1+sha512...\" -> \"pnpm\"\n const manager = packageJson.packageManager.split('@')[0]\n if (isValidPackageManager(manager)) {\n getLogger().debug(`Detected package manager from package.json: ${manager}`)\n return manager\n }\n }\n }\n } catch (error) {\n // If package.json doesn't exist, is malformed, or unreadable, continue to next detection method\n getLogger().debug(`Could not read packageManager from package.json: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n\n // 2. Check lock files (priority: pnpm > npm > yarn)\n const lockFiles: Array<{ file: string; manager: PackageManager }> = [\n { file: 'pnpm-lock.yaml', manager: 'pnpm' },\n { file: 'package-lock.json', manager: 'npm' },\n { file: 'yarn.lock', manager: 'yarn' },\n ]\n\n for (const { file, manager } of lockFiles) {\n if (await fs.pathExists(path.join(cwd, file))) {\n getLogger().debug(`Detected package manager from lock file ${file}: ${manager}`)\n return manager\n }\n }\n\n // 3. Check installed package managers (original behavior)\n const managers: PackageManager[] = ['pnpm', 'npm', 'yarn']\n for (const manager of managers) {\n try {\n await execa(manager, ['--version'])\n getLogger().debug(`Detected installed package manager: ${manager}`)\n return manager\n } catch {\n // Continue to next manager\n }\n }\n\n // 4. Default to npm (always available in Node.js environments)\n getLogger().debug('No package manager detected, defaulting to npm')\n return 'npm'\n}\n\n/**\n * Install dependencies using the detected package manager\n * @param cwd Working directory to run install in\n * @param frozen Whether to use frozen lockfile (for production installs)\n * @param quiet Whether to suppress command output (default: false)\n * @returns true if installation succeeded, throws Error on failure\n */\nexport async function installDependencies(\n cwd: string,\n frozen: boolean = true,\n quiet: boolean = false\n): Promise<void> {\n // Check if working directory is provided\n if (!cwd) {\n getLogger().debug('Skipping dependency installation - no working directory provided')\n return\n }\n\n // Check for install script in package.iloom.json or package.json\n const scripts = await getPackageScripts(cwd)\n if (scripts.install) {\n getLogger().info('Installing dependencies with install script...')\n // runScript handles both iloom-config (shell execution) and package-manager (npm/pnpm/yarn) sources\n await runScript('install', cwd, [], { quiet })\n getLogger().success('Dependencies installed successfully')\n return\n }\n\n // Fall back to Node.js package manager detection for projects without install script\n const pkgPath = path.join(cwd, 'package.json')\n if (!(await fs.pathExists(pkgPath))) {\n getLogger().debug('Skipping dependency installation - no package.json found and no install script')\n return\n }\n\n const packageManager = await detectPackageManager(cwd)\n\n getLogger().info(`Installing dependencies with ${packageManager}...`)\n\n const args: string[] = ['install']\n\n // Add frozen lockfile flag based on package manager\n if (frozen) {\n switch (packageManager) {\n case 'pnpm':\n args.push('--frozen-lockfile')\n break\n case 'yarn':\n args.push('--frozen-lockfile')\n break\n case 'npm':\n args.shift() // Remove 'install'\n args.push('ci') // npm ci is equivalent to frozen lockfile\n break\n }\n }\n\n try {\n await execa(packageManager, args, {\n cwd,\n stdio: quiet ? 'pipe' : 'inherit',\n timeout: 300000, // 5 minute timeout for install\n })\n\n getLogger().success('Dependencies installed successfully')\n } catch (error) {\n const execaError = error as ExecaError\n const stderr = execaError.stderr ?? execaError.message ?? 'Unknown error'\n throw new Error(`Failed to install dependencies: ${stderr}`)\n }\n}\n\n/**\n * Options for running a script\n */\nexport interface RunScriptOptions {\n /** Suppress command output (default: false) */\n quiet?: boolean\n /** Custom environment variables merged with process.env */\n env?: Record<string, string>\n /** Use inherited stdio, return process info (default: false) */\n foreground?: boolean\n /** Callback when process starts, receives PID */\n onStart?: (pid?: number) => void\n /** Don't set CI=true (for dev servers, default: false) */\n noCi?: boolean\n}\n\n/**\n * Run a package.json or iloom config script\n * Automatically detects whether to use package manager or direct shell execution\n * based on the script source.\n *\n * @param scriptName The script name from package.json or package.iloom.json\n * @param cwd Working directory\n * @param args Additional arguments to pass to the script\n * @param options Execution options\n * @returns Object with pid when foreground mode is enabled\n */\nexport async function runScript(\n scriptName: string,\n cwd: string,\n args: string[] = [],\n options: RunScriptOptions = {}\n): Promise<{ pid?: number }> {\n // Get scripts with source metadata\n const scripts = await getPackageScripts(cwd)\n const scriptConfig = scripts[scriptName]\n\n const isDebugMode = getLogger().isDebugEnabled()\n\n if (!scriptConfig) {\n throw new Error(`Script '${scriptName}' not found`)\n }\n\n // Build environment variables\n const env: Record<string, string> = {\n ...process.env as Record<string, string>,\n ...options.env,\n }\n\n // Add CI=true unless noCi is set\n if (!options.noCi) {\n env.CI = 'true'\n }\n\n // Determine stdio mode\n const stdio = options.foreground ? 'inherit' : (options.quiet ? 'pipe' : 'inherit')\n\n try {\n let execaProcess\n\n if (scriptConfig.source === 'iloom-config') {\n // Execute directly as shell command (for non-Node.js projects)\n // Use \"$@\" pattern to properly handle argument escaping via the shell\n getLogger().debug(`Executing shell command: ${scriptConfig.command} with args: ${args.join(' ')}`)\n\n execaProcess = execa('sh', ['-c', `${scriptConfig.command} \"$@\"`, '--', ...args], {\n cwd,\n stdio,\n ...(!options.foreground && { timeout: 600000 }), // No timeout for foreground mode\n env,\n verbose: isDebugMode,\n })\n } else {\n // Execute via package manager (for Node.js projects)\n const packageManager = await detectPackageManager(cwd)\n const command = packageManager === 'npm' ? ['run', scriptName] : [scriptName]\n\n execaProcess = execa(packageManager, [...command, ...args], {\n cwd,\n stdio,\n ...(!options.foreground && { timeout: 600000 }), // No timeout for foreground mode\n env,\n verbose: isDebugMode,\n })\n }\n\n // For foreground mode, get PID and call onStart callback immediately\n const result: { pid?: number } = {}\n if (options.foreground && execaProcess.pid !== undefined) {\n result.pid = execaProcess.pid\n }\n\n // Call onStart callback if provided\n if (options.onStart) {\n options.onStart(result.pid)\n }\n\n // Wait for process to complete\n await execaProcess\n\n return result\n } catch (error) {\n const execaError = error as ExecaError\n const stderr = execaError.stderr ?? execaError.message ?? 'Unknown error'\n throw new Error(`Failed to run script '${scriptName}': ${stderr}`)\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getLogger
4
+ } from "./chunk-6MLEBAYZ.js";
5
+
6
+ // src/utils/package-json.ts
7
+ import fs from "fs-extra";
8
+ import path from "path";
9
+ var ILOOM_PACKAGE_PATH = ".iloom/package.iloom.json";
10
+ async function readPackageJson(dir) {
11
+ const pkgPath = path.join(dir, "package.json");
12
+ try {
13
+ const pkgJson = await fs.readJson(pkgPath);
14
+ return pkgJson;
15
+ } catch (error) {
16
+ if (error.code === "ENOENT") {
17
+ throw new Error(`package.json not found in ${dir}`);
18
+ }
19
+ const message = error instanceof Error ? error.message : "Unknown error";
20
+ throw new Error(`Invalid package.json in ${dir}: ${message}`);
21
+ }
22
+ }
23
+ async function readIloomPackageScripts(dir) {
24
+ const iloomPkgPath = path.join(dir, ILOOM_PACKAGE_PATH);
25
+ try {
26
+ const exists = await fs.pathExists(iloomPkgPath);
27
+ if (!exists) {
28
+ return null;
29
+ }
30
+ const content = await fs.readJson(iloomPkgPath);
31
+ return content;
32
+ } catch (error) {
33
+ const message = error instanceof Error ? error.message : "Unknown error";
34
+ getLogger().warn(`Failed to read ${ILOOM_PACKAGE_PATH}: ${message}`);
35
+ return null;
36
+ }
37
+ }
38
+ async function getPackageConfig(dir) {
39
+ const iloomPackage = await readIloomPackageScripts(dir);
40
+ if (iloomPackage) {
41
+ try {
42
+ const basePackage = await readPackageJson(dir);
43
+ getLogger().debug("Merging scripts from .iloom/package.iloom.json over package.json");
44
+ return {
45
+ ...basePackage,
46
+ scripts: {
47
+ ...basePackage.scripts,
48
+ ...iloomPackage.scripts
49
+ }
50
+ };
51
+ } catch {
52
+ getLogger().debug("Using scripts from .iloom/package.iloom.json (no package.json)");
53
+ return iloomPackage;
54
+ }
55
+ }
56
+ return readPackageJson(dir);
57
+ }
58
+ function parseBinField(bin, packageName) {
59
+ if (!bin) {
60
+ return {};
61
+ }
62
+ if (typeof bin === "string") {
63
+ return { [packageName]: bin };
64
+ }
65
+ return bin;
66
+ }
67
+ function hasWebDependencies(pkgJson) {
68
+ const webIndicators = [
69
+ "next",
70
+ "vite",
71
+ "express",
72
+ "react-scripts",
73
+ "nuxt",
74
+ "svelte-kit",
75
+ "astro",
76
+ "remix",
77
+ "fastify",
78
+ "koa",
79
+ "hapi",
80
+ "@angular/core",
81
+ "gatsby",
82
+ "@11ty/eleventy",
83
+ "ember-cli"
84
+ ];
85
+ const allDeps = {
86
+ ...pkgJson.dependencies,
87
+ ...pkgJson.devDependencies
88
+ };
89
+ return webIndicators.some((indicator) => indicator in allDeps);
90
+ }
91
+ function hasScript(pkgJson, scriptName) {
92
+ var _a;
93
+ return !!((_a = pkgJson.scripts) == null ? void 0 : _a[scriptName]);
94
+ }
95
+ async function getPackageScripts(dir) {
96
+ const scripts = {};
97
+ const packageJsonPath = path.join(dir, "package.json");
98
+ if (await fs.pathExists(packageJsonPath)) {
99
+ const pkgJson = await readPackageJson(dir);
100
+ if (pkgJson.scripts) {
101
+ for (const [name, command] of Object.entries(pkgJson.scripts)) {
102
+ scripts[name] = { command, source: "package-manager" };
103
+ }
104
+ }
105
+ }
106
+ const iloomPackage = await readIloomPackageScripts(dir);
107
+ if (iloomPackage == null ? void 0 : iloomPackage.scripts) {
108
+ for (const [name, command] of Object.entries(iloomPackage.scripts)) {
109
+ scripts[name] = { command, source: "iloom-config" };
110
+ }
111
+ }
112
+ return scripts;
113
+ }
114
+ var VALID_CAPABILITIES = ["cli", "web"];
115
+ function getExplicitCapabilities(pkgJson) {
116
+ if (!pkgJson.capabilities || !Array.isArray(pkgJson.capabilities)) {
117
+ return [];
118
+ }
119
+ return pkgJson.capabilities.filter(
120
+ (cap) => VALID_CAPABILITIES.includes(cap)
121
+ );
122
+ }
123
+
124
+ export {
125
+ readPackageJson,
126
+ getPackageConfig,
127
+ parseBinField,
128
+ hasWebDependencies,
129
+ hasScript,
130
+ getPackageScripts,
131
+ getExplicitCapabilities
132
+ };
133
+ //# sourceMappingURL=chunk-BXCPJJYM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/package-json.ts"],"sourcesContent":["import fs from 'fs-extra'\nimport path from 'path'\nimport { getLogger } from './logger-context.js'\nimport type { ProjectCapability } from '../types/loom.js'\n\n/**\n * Path to the iloom package configuration file (relative to project root)\n * This file allows non-Node.js projects to define scripts for iloom workflows\n */\nexport const ILOOM_PACKAGE_PATH = '.iloom/package.iloom.json'\n\nexport interface PackageJson {\n name: string\n version?: string\n bin?: string | Record<string, string>\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n scripts?: Record<string, string>\n capabilities?: Array<'cli' | 'web'>\n [key: string]: unknown\n}\n\n/**\n * Source of a script - determines how it should be executed\n * - 'package-manager': Execute via package manager (pnpm/npm/yarn)\n * - 'iloom-config': Execute directly as shell command\n */\nexport type ScriptSource = 'package-manager' | 'iloom-config'\n\n/**\n * Configuration for a single script including its source\n * The source determines whether to use package manager or direct shell execution\n */\nexport interface PackageScriptConfig {\n /** The script command to execute */\n command: string\n /** Source of the script - determines execution method */\n source: ScriptSource\n}\n\n/**\n * Read and parse package.json from a directory\n * @param dir Directory containing package.json\n * @returns Parsed package.json object\n * @throws Error if package.json doesn't exist or contains invalid JSON\n */\nexport async function readPackageJson(dir: string): Promise<PackageJson> {\n const pkgPath = path.join(dir, 'package.json')\n\n try {\n const pkgJson = await fs.readJson(pkgPath)\n return pkgJson as PackageJson\n } catch (error) {\n if ((error as { code?: string }).code === 'ENOENT') {\n throw new Error(`package.json not found in ${dir}`)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new Error(`Invalid package.json in ${dir}: ${message}`)\n }\n}\n\n/**\n * Read scripts from .iloom/package.iloom.json if it exists\n * This file takes precedence over package.json and contains raw shell commands\n * @param dir Directory containing .iloom/package.iloom.json\n * @returns PackageJson-like object with scripts, or null if file doesn't exist\n */\nexport async function readIloomPackageScripts(dir: string): Promise<PackageJson | null> {\n const iloomPkgPath = path.join(dir, ILOOM_PACKAGE_PATH)\n\n try {\n const exists = await fs.pathExists(iloomPkgPath)\n if (!exists) {\n return null\n }\n\n const content = await fs.readJson(iloomPkgPath)\n return content as PackageJson\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n getLogger().warn(`Failed to read ${ILOOM_PACKAGE_PATH}: ${message}`)\n return null\n }\n}\n\n/**\n * Read package configuration for a project, merging .iloom/package.iloom.json scripts over package.json\n * This allows non-Node.js projects to define scripts for iloom workflows while preserving\n * all other package.json fields (name, version, bin, dependencies, etc.)\n *\n * @param dir Directory to read package configuration from\n * @returns PackageJson object with merged scripts (iloom scripts take precedence)\n * @throws Error if neither file exists or contains valid JSON\n */\nexport async function getPackageConfig(dir: string): Promise<PackageJson> {\n // Check for .iloom/package.iloom.json first\n const iloomPackage = await readIloomPackageScripts(dir)\n\n if (iloomPackage) {\n // Try to read package.json as base\n try {\n const basePackage = await readPackageJson(dir)\n getLogger().debug('Merging scripts from .iloom/package.iloom.json over package.json')\n // Merge: base package.json with iloom scripts taking precedence\n return {\n ...basePackage,\n scripts: {\n ...basePackage.scripts,\n ...iloomPackage.scripts,\n },\n }\n } catch {\n // No package.json - use iloom package as-is (non-Node project)\n getLogger().debug('Using scripts from .iloom/package.iloom.json (no package.json)')\n return iloomPackage\n }\n }\n\n // Fall back to package.json only\n return readPackageJson(dir)\n}\n\n/**\n * Parse bin field into normalized Record format\n * @param bin The bin field from package.json (string or object)\n * @param packageName Package name to use for string bin variant\n * @returns Normalized bin entries as Record<string, string>\n */\nexport function parseBinField(\n bin: string | Record<string, string> | undefined,\n packageName: string\n): Record<string, string> {\n if (!bin) {\n return {}\n }\n\n if (typeof bin === 'string') {\n return { [packageName]: bin }\n }\n\n return bin\n}\n\n/**\n * Check if package.json indicates a web application\n * @param pkgJson Parsed package.json object\n * @returns true if package has web framework dependencies\n */\nexport function hasWebDependencies(pkgJson: PackageJson): boolean {\n const webIndicators = [\n 'next',\n 'vite',\n 'express',\n 'react-scripts',\n 'nuxt',\n 'svelte-kit',\n 'astro',\n 'remix',\n 'fastify',\n 'koa',\n 'hapi',\n '@angular/core',\n 'gatsby',\n '@11ty/eleventy',\n 'ember-cli'\n ]\n\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies\n }\n\n return webIndicators.some(indicator => indicator in allDeps)\n}\n\n/**\n * Check if package.json has a specific script\n * @param pkgJson Parsed package.json object\n * @param scriptName Script name to check for\n * @returns true if script exists\n */\nexport function hasScript(pkgJson: PackageJson, scriptName: string): boolean {\n return !!pkgJson.scripts?.[scriptName]\n}\n\n/**\n * Get all scripts with their source metadata\n * Scripts from .iloom/package.iloom.json are marked as 'iloom-config' and should be executed directly\n * Scripts from package.json are marked as 'package-manager' and should use pnpm/npm/yarn\n *\n * @param dir Directory to read package configuration from\n * @returns Map of script names to their configurations including source\n */\nexport async function getPackageScripts(dir: string): Promise<Record<string, PackageScriptConfig>> {\n const scripts: Record<string, PackageScriptConfig> = {}\n\n // First, check if package.json exists and read scripts (these are package-manager sourced)\n const packageJsonPath = path.join(dir, 'package.json')\n if (await fs.pathExists(packageJsonPath)) {\n const pkgJson = await readPackageJson(dir)\n if (pkgJson.scripts) {\n for (const [name, command] of Object.entries(pkgJson.scripts)) {\n scripts[name] = { command, source: 'package-manager' }\n }\n }\n }\n\n // Then, read iloom package scripts (these override and are iloom-config sourced)\n const iloomPackage = await readIloomPackageScripts(dir)\n if (iloomPackage?.scripts) {\n for (const [name, command] of Object.entries(iloomPackage.scripts)) {\n scripts[name] = { command, source: 'iloom-config' }\n }\n }\n\n return scripts\n}\n\n/**\n * Valid capability values that can be explicitly declared\n */\nconst VALID_CAPABILITIES: readonly ProjectCapability[] = ['cli', 'web'] as const\n\n/**\n * Extract explicit capabilities from package configuration\n * Used for non-Node.js projects that declare capabilities in package.iloom.json\n * @param pkgJson Parsed package configuration object\n * @returns Array of valid ProjectCapability values, or empty array if none declared\n */\nexport function getExplicitCapabilities(pkgJson: PackageJson): ProjectCapability[] {\n // Return empty if no capabilities field or not an array\n if (!pkgJson.capabilities || !Array.isArray(pkgJson.capabilities)) {\n return []\n }\n\n // Filter to only valid ProjectCapability values\n return pkgJson.capabilities.filter(\n (cap): cap is ProjectCapability => VALID_CAPABILITIES.includes(cap as ProjectCapability)\n )\n}\n"],"mappings":"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","names":[]}
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-FXDYIV3K.js";
15
15
  import {
16
16
  PromptTemplateManager
17
- } from "./chunk-K5G5SFWY.js";
17
+ } from "./chunk-W6WVRHJ6.js";
18
18
  import {
19
19
  SettingsManager
20
20
  } from "./chunk-F6WVM437.js";
@@ -776,4 +776,4 @@ var SessionSummaryService = class {
776
776
  export {
777
777
  SessionSummaryService
778
778
  };
779
- //# sourceMappingURL=chunk-SJIMVKK7.js.map
779
+ //# sourceMappingURL=chunk-K7SEEHKO.js.map
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- installDependencies,
4
- runScript
5
- } from "./chunk-LVLRMP7V.js";
6
2
  import {
7
3
  calculatePortForBranch
8
4
  } from "./chunk-VU3QMIP2.js";
9
5
  import {
10
- hasScript,
11
- readPackageJson
12
- } from "./chunk-2ZPFJQ3B.js";
6
+ installDependencies,
7
+ runScript
8
+ } from "./chunk-AXX3QIKK.js";
9
+ import {
10
+ getPackageConfig,
11
+ hasScript
12
+ } from "./chunk-BXCPJJYM.js";
13
13
  import {
14
14
  branchExists,
15
15
  checkRemoteBranchStatus,
@@ -393,8 +393,8 @@ This PR was created automatically by iloom.`;
393
393
  const setArguments = (_j = input.options) == null ? void 0 : _j.setArguments;
394
394
  const executablePath = (_k = input.options) == null ? void 0 : _k.executablePath;
395
395
  if (enableClaude || enableCode || enableDevServer || enableTerminal) {
396
- const { LoomLauncher } = await import("./LoomLauncher-5QU42LOM.js");
397
- const { ClaudeContextManager } = await import("./ClaudeContextManager-7WX7DUNI.js");
396
+ const { LoomLauncher } = await import("./LoomLauncher-5LFM4LXB.js");
397
+ const { ClaudeContextManager } = await import("./ClaudeContextManager-6J2EB4QU.js");
398
398
  const claudeContext = new ClaudeContextManager(void 0, void 0, this.settings);
399
399
  const launcher = new LoomLauncher(claudeContext, this.settings);
400
400
  await launcher.launchLoom({
@@ -1020,8 +1020,8 @@ This PR was created automatically by iloom.`;
1020
1020
  const executablePath = (_i = input.options) == null ? void 0 : _i.executablePath;
1021
1021
  if (enableClaude || enableCode || enableDevServer || enableTerminal) {
1022
1022
  getLogger().info("Launching workspace components...");
1023
- const { LoomLauncher } = await import("./LoomLauncher-5QU42LOM.js");
1024
- const { ClaudeContextManager } = await import("./ClaudeContextManager-7WX7DUNI.js");
1023
+ const { LoomLauncher } = await import("./LoomLauncher-5LFM4LXB.js");
1024
+ const { ClaudeContextManager } = await import("./ClaudeContextManager-6J2EB4QU.js");
1025
1025
  const claudeContext = new ClaudeContextManager(void 0, void 0, this.settings);
1026
1026
  const launcher = new LoomLauncher(claudeContext, this.settings);
1027
1027
  await launcher.launchLoom({
@@ -1338,7 +1338,7 @@ var CLIIsolationManager = class {
1338
1338
  * @param worktreePath Path to the worktree
1339
1339
  */
1340
1340
  async buildProject(worktreePath) {
1341
- const pkgJson = await readPackageJson(worktreePath);
1341
+ const pkgJson = await getPackageConfig(worktreePath);
1342
1342
  if (!hasScript(pkgJson, "build")) {
1343
1343
  getLogger().warn("No build script found in package.json - skipping build");
1344
1344
  return;
@@ -2427,4 +2427,4 @@ export {
2427
2427
  DatabaseManager,
2428
2428
  ResourceCleanup
2429
2429
  };
2430
- //# sourceMappingURL=chunk-46JVEGUW.js.map
2430
+ //# sourceMappingURL=chunk-PMVWQBWS.js.map