@iloom/cli 0.7.0 → 0.7.2
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/dist/{ProjectCapabilityDetector-UZYW32SY.js → ProjectCapabilityDetector-IA56AUE6.js} +3 -3
- package/dist/agents/iloom-framework-detector.md +78 -9
- package/dist/{build-O2EJHDEW.js → build-HQ5HGA3T.js} +4 -4
- package/dist/{chunk-3CDWFEGL.js → chunk-7GLZVDPQ.js} +2 -2
- package/dist/{chunk-GV5X6XUE.js → chunk-AFRICMSW.js} +3 -3
- package/dist/{chunk-LQBLDI47.js → chunk-DAOS6EC3.js} +4 -4
- package/dist/{chunk-Z6BO53V7.js → chunk-ELJKYFSH.js} +3 -3
- package/dist/{chunk-5F6IWWRS.js → chunk-EWJFUFPT.js} +2 -2
- package/dist/chunk-EWJFUFPT.js.map +1 -0
- package/dist/{chunk-B2UO6EYE.js → chunk-NGJZ4TOU.js} +21 -3
- package/dist/{chunk-B2UO6EYE.js.map → chunk-NGJZ4TOU.js.map} +1 -1
- package/dist/{chunk-S7YMZQUD.js → chunk-QQFBMCAH.js} +26 -3
- package/dist/chunk-QQFBMCAH.js.map +1 -0
- package/dist/{chunk-LLWX3PCW.js → chunk-RD7I2Q2F.js} +2 -2
- package/dist/{chunk-ITN64ENQ.js → chunk-XPKN3QWY.js} +24 -6
- package/dist/chunk-XPKN3QWY.js.map +1 -0
- package/dist/{chunk-NTIZLX42.js → chunk-YQNSZKKT.js} +3 -3
- package/dist/{cleanup-ZPOMRSNN.js → cleanup-77U5ATYI.js} +5 -5
- package/dist/cli.js +43 -22
- package/dist/cli.js.map +1 -1
- package/dist/{commit-6S2RIA2K.js → commit-ONRXU67O.js} +4 -4
- package/dist/{compile-LRMAADUT.js → compile-CT7IR7O2.js} +4 -4
- package/dist/{dev-server-GREJUEKW.js → dev-server-UKAPBGUR.js} +5 -5
- package/dist/{feedback-G7G5QCY4.js → feedback-K3A4QUSG.js} +3 -3
- package/dist/{installation-detector-VXZOCL6P.js → installation-detector-MMFWLJYN.js} +2 -2
- package/dist/{lint-OFVN7FT6.js → lint-HAVU4U34.js} +4 -4
- package/dist/{open-MCWQAPSZ.js → open-QI63XQ4F.js} +5 -5
- package/dist/{projects-PQOTWUII.js → projects-TWY4RT2Z.js} +3 -3
- package/dist/prompts/init-prompt.txt +57 -0
- package/dist/{rebase-RKQED567.js → rebase-QYCRF7JG.js} +5 -5
- package/dist/{run-CCG24PBC.js → run-YDVYORT2.js} +5 -5
- package/dist/{test-QZDOEUIO.js → test-75WAA6DU.js} +4 -4
- package/dist/{update-5NOHT4SG.js → update-HJKDYA3F.js} +3 -3
- package/dist/{update-notifier-ARA5SPUW.js → update-notifier-LBAUOOLM.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-5F6IWWRS.js.map +0 -1
- package/dist/chunk-ITN64ENQ.js.map +0 -1
- package/dist/chunk-S7YMZQUD.js.map +0 -1
- /package/dist/{ProjectCapabilityDetector-UZYW32SY.js.map → ProjectCapabilityDetector-IA56AUE6.js.map} +0 -0
- /package/dist/{build-O2EJHDEW.js.map → build-HQ5HGA3T.js.map} +0 -0
- /package/dist/{chunk-3CDWFEGL.js.map → chunk-7GLZVDPQ.js.map} +0 -0
- /package/dist/{chunk-GV5X6XUE.js.map → chunk-AFRICMSW.js.map} +0 -0
- /package/dist/{chunk-LQBLDI47.js.map → chunk-DAOS6EC3.js.map} +0 -0
- /package/dist/{chunk-Z6BO53V7.js.map → chunk-ELJKYFSH.js.map} +0 -0
- /package/dist/{chunk-LLWX3PCW.js.map → chunk-RD7I2Q2F.js.map} +0 -0
- /package/dist/{chunk-NTIZLX42.js.map → chunk-YQNSZKKT.js.map} +0 -0
- /package/dist/{cleanup-ZPOMRSNN.js.map → cleanup-77U5ATYI.js.map} +0 -0
- /package/dist/{commit-6S2RIA2K.js.map → commit-ONRXU67O.js.map} +0 -0
- /package/dist/{compile-LRMAADUT.js.map → compile-CT7IR7O2.js.map} +0 -0
- /package/dist/{dev-server-GREJUEKW.js.map → dev-server-UKAPBGUR.js.map} +0 -0
- /package/dist/{feedback-G7G5QCY4.js.map → feedback-K3A4QUSG.js.map} +0 -0
- /package/dist/{installation-detector-VXZOCL6P.js.map → installation-detector-MMFWLJYN.js.map} +0 -0
- /package/dist/{lint-OFVN7FT6.js.map → lint-HAVU4U34.js.map} +0 -0
- /package/dist/{open-MCWQAPSZ.js.map → open-QI63XQ4F.js.map} +0 -0
- /package/dist/{projects-PQOTWUII.js.map → projects-TWY4RT2Z.js.map} +0 -0
- /package/dist/{rebase-RKQED567.js.map → rebase-QYCRF7JG.js.map} +0 -0
- /package/dist/{run-CCG24PBC.js.map → run-YDVYORT2.js.map} +0 -0
- /package/dist/{test-QZDOEUIO.js.map → test-75WAA6DU.js.map} +0 -0
- /package/dist/{update-5NOHT4SG.js.map → update-HJKDYA3F.js.map} +0 -0
- /package/dist/{update-notifier-ARA5SPUW.js.map → update-notifier-LBAUOOLM.js.map} +0 -0
package/dist/{ProjectCapabilityDetector-UZYW32SY.js → ProjectCapabilityDetector-IA56AUE6.js}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ProjectCapabilityDetector
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-7GLZVDPQ.js";
|
|
5
|
+
import "./chunk-XPKN3QWY.js";
|
|
6
6
|
import "./chunk-6MLEBAYZ.js";
|
|
7
7
|
import "./chunk-VT4PDUYT.js";
|
|
8
8
|
export {
|
|
9
9
|
ProjectCapabilityDetector
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=ProjectCapabilityDetector-
|
|
11
|
+
//# sourceMappingURL=ProjectCapabilityDetector-IA56AUE6.js.map
|
|
@@ -8,12 +8,57 @@ model: sonnet
|
|
|
8
8
|
|
|
9
9
|
You are Claude, a framework detection specialist. Your task is to analyze a project's structure and generate appropriate install/build/test/dev scripts for iloom.
|
|
10
10
|
|
|
11
|
-
**Your Core Mission**: Detect the project's programming language and framework, then create
|
|
11
|
+
**Your Core Mission**: Detect the project's programming language and framework, then create the appropriate iloom package configuration file with shell commands for install, build, test, and development workflows.
|
|
12
12
|
|
|
13
13
|
**Key Distinction:**
|
|
14
14
|
- `install` - Installs dependencies (runs during loom creation and post-merge)
|
|
15
15
|
- `build` - Compiles/builds the project (for compiled languages or asset compilation)
|
|
16
16
|
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🍴 FORK CHECK - DO THIS FIRST (Before Any File Decisions)
|
|
20
|
+
|
|
21
|
+
**CRITICAL: Before creating ANY configuration file, check if this is a fork.**
|
|
22
|
+
|
|
23
|
+
### Step 0: Detect Fork Pattern
|
|
24
|
+
|
|
25
|
+
Run this check FIRST, before any other detection work:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git remote -v 2>/dev/null | grep -E '^(origin|upstream)\s' | awk '{print $1}' | sort -u
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**If BOTH `origin` AND `upstream` are present → This is a FORK**
|
|
32
|
+
|
|
33
|
+
### Fork Mode Behavior
|
|
34
|
+
|
|
35
|
+
When fork is detected:
|
|
36
|
+
|
|
37
|
+
1. **Default to `.iloom/package.iloom.local.json`** (NOT `package.iloom.json`)
|
|
38
|
+
2. **Inform the user immediately:**
|
|
39
|
+
```
|
|
40
|
+
🍴 Fork Detected (origin + upstream remotes)
|
|
41
|
+
|
|
42
|
+
For fork contributors, iloom configuration should be saved to LOCAL files
|
|
43
|
+
to prevent your personal settings from appearing in PRs to upstream.
|
|
44
|
+
|
|
45
|
+
Recommendation: Save to `.iloom/package.iloom.local.json`
|
|
46
|
+
- This file is globally gitignored
|
|
47
|
+
- Won't appear in your PRs to upstream
|
|
48
|
+
- Local scripts merge with package.iloom.json (local takes precedence)
|
|
49
|
+
|
|
50
|
+
If the upstream project already has package.iloom.json, your local file
|
|
51
|
+
will override/extend those scripts for your environment only.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. **Proceed with detection** but write to the local file by default
|
|
55
|
+
|
|
56
|
+
### Non-Fork Behavior
|
|
57
|
+
|
|
58
|
+
If only `origin` exists (or no upstream), proceed normally with `package.iloom.json`.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
17
62
|
## Core Workflow
|
|
18
63
|
|
|
19
64
|
### Step 1: Scan for Language Markers
|
|
@@ -299,18 +344,37 @@ Create `.iloom/package.iloom.json` with appropriate scripts and capabilities bas
|
|
|
299
344
|
|
|
300
345
|
### Step 4: Write the File
|
|
301
346
|
|
|
302
|
-
|
|
303
|
-
|
|
347
|
+
**⚠️ CHECKPOINT: Verify fork status from Step 0 before proceeding.**
|
|
348
|
+
|
|
349
|
+
If fork was detected (both `origin` and `upstream` remotes exist):
|
|
350
|
+
- Default target file: `.iloom/package.iloom.local.json`
|
|
351
|
+
- This prevents personal config from appearing in PRs to upstream
|
|
352
|
+
|
|
353
|
+
If NOT a fork:
|
|
354
|
+
- Default target file: `.iloom/package.iloom.json`
|
|
355
|
+
|
|
356
|
+
**Writing Process:**
|
|
357
|
+
|
|
358
|
+
1. **Determine target file** based on fork status (see above)
|
|
359
|
+
2. Read the target file first to check if it already exists
|
|
360
|
+
3. **If the file exists:**
|
|
304
361
|
- Compare existing configuration with detected configuration
|
|
305
362
|
- Preserve existing scripts (user may have customized them)
|
|
306
363
|
- Only add missing scripts that were detected
|
|
307
364
|
- Preserve existing capabilities, add any missing ones
|
|
308
365
|
- Preserve any other existing fields (like `_metadata`)
|
|
309
|
-
|
|
366
|
+
4. **If the file does not exist:**
|
|
310
367
|
- Create the full detected configuration
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
368
|
+
5. Ensure `.iloom/` directory exists
|
|
369
|
+
6. Write the merged/new JSON to the target file
|
|
370
|
+
7. Report what was detected, which file was written, and what changes were made (if any)
|
|
371
|
+
|
|
372
|
+
**File Selection Summary:**
|
|
373
|
+
| Scenario | Target File | Reason |
|
|
374
|
+
|----------|-------------|--------|
|
|
375
|
+
| Fork detected (origin + upstream) | `package.iloom.local.json` | Keeps PRs clean, gitignored globally |
|
|
376
|
+
| Direct contributor (origin only) | `package.iloom.json` | Shared team configuration |
|
|
377
|
+
| User explicitly requests shared | `package.iloom.json` | User override (even for forks) |
|
|
314
378
|
|
|
315
379
|
## Output Format
|
|
316
380
|
|
|
@@ -324,8 +388,9 @@ Detected:
|
|
|
324
388
|
- Framework: [framework or "None detected"]
|
|
325
389
|
- Package Manager: [package manager]
|
|
326
390
|
- Capabilities: [cli, web, or none]
|
|
391
|
+
- Fork Status: [Yes (origin + upstream) | No]
|
|
327
392
|
|
|
328
|
-
Created: .iloom/package.iloom.json
|
|
393
|
+
Created: .iloom/[package.iloom.json OR package.iloom.local.json]
|
|
329
394
|
|
|
330
395
|
Configuration:
|
|
331
396
|
- capabilities: [list of detected capabilities]
|
|
@@ -334,7 +399,11 @@ Configuration:
|
|
|
334
399
|
- test: [command]
|
|
335
400
|
- dev: [command]
|
|
336
401
|
|
|
337
|
-
|
|
402
|
+
[If fork]: This configuration was saved to the LOCAL file (package.iloom.local.json)
|
|
403
|
+
because you're working on a fork. This prevents your iloom settings
|
|
404
|
+
from appearing in PRs to upstream.
|
|
405
|
+
|
|
406
|
+
You can customize these settings by editing .iloom/[filename].
|
|
338
407
|
```
|
|
339
408
|
|
|
340
409
|
## Error Handling
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ScriptCommandBase
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ELJKYFSH.js";
|
|
5
5
|
import "./chunk-5V74K5ZA.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-RD7I2Q2F.js";
|
|
7
7
|
import "./chunk-UDRZY65Y.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-XPKN3QWY.js";
|
|
9
9
|
import "./chunk-ZA575VLF.js";
|
|
10
10
|
import "./chunk-WFQ5CLTR.js";
|
|
11
11
|
import "./chunk-VWGKGNJP.js";
|
|
@@ -24,4 +24,4 @@ var BuildCommand = class extends ScriptCommandBase {
|
|
|
24
24
|
export {
|
|
25
25
|
BuildCommand
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=build-
|
|
27
|
+
//# sourceMappingURL=build-HQ5HGA3T.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getPackageConfig,
|
|
5
5
|
hasWebDependencies,
|
|
6
6
|
parseBinField
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-XPKN3QWY.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-7GLZVDPQ.js.map
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
detectPackageManager,
|
|
7
7
|
runScript
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RD7I2Q2F.js";
|
|
9
9
|
import {
|
|
10
10
|
readPackageJson
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-XPKN3QWY.js";
|
|
12
12
|
import {
|
|
13
13
|
logger
|
|
14
14
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -212,4 +212,4 @@ var DevServerManager = class {
|
|
|
212
212
|
export {
|
|
213
213
|
DevServerManager
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-AFRICMSW.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ProjectCapabilityDetector
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7GLZVDPQ.js";
|
|
5
5
|
import {
|
|
6
6
|
detectPackageManager,
|
|
7
7
|
runScript
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RD7I2Q2F.js";
|
|
9
9
|
import {
|
|
10
10
|
getPackageConfig,
|
|
11
11
|
hasScript
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XPKN3QWY.js";
|
|
13
13
|
import {
|
|
14
14
|
executeGitCommand,
|
|
15
15
|
findMainWorktreePathWithSettings,
|
|
@@ -467,4 +467,4 @@ export {
|
|
|
467
467
|
MergeManager,
|
|
468
468
|
BuildRunner
|
|
469
469
|
};
|
|
470
|
-
//# sourceMappingURL=chunk-
|
|
470
|
+
//# sourceMappingURL=chunk-DAOS6EC3.js.map
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-5V74K5ZA.js";
|
|
5
5
|
import {
|
|
6
6
|
runScript
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RD7I2Q2F.js";
|
|
8
8
|
import {
|
|
9
9
|
GitWorktreeManager
|
|
10
10
|
} from "./chunk-UDRZY65Y.js";
|
|
11
11
|
import {
|
|
12
12
|
getPackageScripts
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XPKN3QWY.js";
|
|
14
14
|
import {
|
|
15
15
|
extractIssueNumber
|
|
16
16
|
} from "./chunk-ZA575VLF.js";
|
|
@@ -156,4 +156,4 @@ var ScriptCommandBase = class {
|
|
|
156
156
|
export {
|
|
157
157
|
ScriptCommandBase
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-ELJKYFSH.js.map
|
|
@@ -10,7 +10,7 @@ function detectInstallationMethod(scriptPath) {
|
|
|
10
10
|
logger.debug(`[installation-detector] Detecting installation method for: ${scriptPath}`);
|
|
11
11
|
if (process.env.OVERRIDE_INSTALLATION_METHOD) {
|
|
12
12
|
const overrideMethod = process.env.OVERRIDE_INSTALLATION_METHOD;
|
|
13
|
-
logger.
|
|
13
|
+
logger.debug(`[installation-detector] Override detected, returning: ${overrideMethod}`);
|
|
14
14
|
return overrideMethod;
|
|
15
15
|
}
|
|
16
16
|
try {
|
|
@@ -72,4 +72,4 @@ export {
|
|
|
72
72
|
detectInstallationMethod,
|
|
73
73
|
shouldShowUpdateNotification
|
|
74
74
|
};
|
|
75
|
-
//# sourceMappingURL=chunk-
|
|
75
|
+
//# sourceMappingURL=chunk-EWJFUFPT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/installation-detector.ts"],"sourcesContent":["import { dirname, join } from 'path'\nimport { existsSync, lstatSync, realpathSync } from 'fs'\nimport { logger } from './logger.js'\n\nexport type InstallationMethod = 'global' | 'local' | 'linked' | 'unknown'\n\n/**\n * Detect how iloom-cli is installed\n * - global: npm install -g (in global node_modules)\n * - local: Running from source directory (has src/ sibling to dist/)\n * - linked: npm link (symlinked executable)\n * - unknown: Cannot determine\n */\nexport function detectInstallationMethod(scriptPath: string): InstallationMethod {\n logger.debug(`[installation-detector] Detecting installation method for: ${scriptPath}`)\n\n if (process.env.OVERRIDE_INSTALLATION_METHOD) {\n const overrideMethod = process.env.OVERRIDE_INSTALLATION_METHOD as InstallationMethod\n logger.debug(`[installation-detector] Override detected, returning: ${overrideMethod}`)\n return overrideMethod\n }\n\n try {\n // Check if the script is a symlink (npm link creates symlinks)\n try {\n const stats = lstatSync(scriptPath)\n if (stats.isSymbolicLink()) {\n logger.debug(`[installation-detector] Script is a symlink`)\n // Resolve symlink to check where it actually points\n const realPath = realpathSync(scriptPath)\n logger.debug(`[installation-detector] Symlink resolves to: ${realPath}`)\n // If the real path is in node_modules, it's a global install\n // Only return 'linked' if it points outside node_modules\n if (!realPath.includes('/node_modules/')) {\n logger.debug(`[installation-detector] Symlink points outside node_modules, classification: linked`)\n return 'linked'\n }\n logger.debug(`[installation-detector] Symlink points to node_modules, treating as potential global install`)\n // Otherwise, continue checking with the resolved path\n scriptPath = realPath\n }\n } catch {\n // If we can't stat it, continue to other checks\n logger.debug(`[installation-detector] Unable to stat script file, continuing to other checks`)\n }\n\n // Check if running from source directory\n // If the file is at dist/cli.js, check if src/ exists as a sibling\n if (scriptPath.includes('/dist/') || scriptPath.includes('\\\\dist\\\\')) {\n logger.debug(`[installation-detector] Script is in dist/ directory, checking for local development setup`)\n const distDir = dirname(scriptPath) // dist/\n const projectRoot = dirname(distDir) // project root\n const srcDir = join(projectRoot, 'src')\n const packageJsonPath = join(projectRoot, 'package.json')\n logger.debug(`[installation-detector] Looking for src/ at: ${srcDir}`)\n logger.debug(`[installation-detector] Looking for package.json at: ${packageJsonPath}`)\n\n // If src/ and package.json exist in parent, we're running from source\n if (existsSync(srcDir) && existsSync(packageJsonPath)) {\n logger.debug(`[installation-detector] Found src/ and package.json, classification: local`)\n return 'local'\n }\n }\n\n // Check if in global node_modules\n // Global installs are typically in:\n // - /usr/local/lib/node_modules/ (macOS/Linux)\n // - ~/.nvm/versions/node/*/lib/node_modules/ (NVM)\n // - C:\\Users\\*\\AppData\\Roaming\\npm\\node_modules\\ (Windows)\n // - /opt/homebrew/lib/node_modules (Homebrew on Apple Silicon)\n const globalPatterns = [\n '/lib/node_modules/',\n '/.nvm/versions/node/',\n '/AppData/Roaming/npm/node_modules/',\n '/.local/lib/node_modules/',\n ]\n\n const normalizedPath = scriptPath.replace(/\\\\/g, '/')\n logger.debug(`[installation-detector] Checking global patterns against: ${normalizedPath}`)\n for (const pattern of globalPatterns) {\n if (normalizedPath.includes(pattern)) {\n logger.debug(`[installation-detector] Matched global pattern '${pattern}', classification: global`)\n return 'global'\n }\n }\n\n logger.debug(`[installation-detector] No patterns matched, classification: unknown`)\n return 'unknown'\n } catch (error) {\n logger.debug(`[installation-detector] Error during detection: ${error}, classification: unknown`)\n return 'unknown'\n }\n}\n\n/**\n * Determine if update notifications should be shown\n * Returns true only for global installations\n */\nexport function shouldShowUpdateNotification(method: InstallationMethod): boolean {\n return method === 'global'\n}\n"],"mappings":";;;;;;AAAA,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY,WAAW,oBAAoB;AAY7C,SAAS,yBAAyB,YAAwC;AAC/E,SAAO,MAAM,8DAA8D,UAAU,EAAE;AAEvF,MAAI,QAAQ,IAAI,8BAA8B;AAC5C,UAAM,iBAAiB,QAAQ,IAAI;AACnC,WAAO,MAAM,yDAAyD,cAAc,EAAE;AACtF,WAAO;AAAA,EACT;AAEA,MAAI;AAEF,QAAI;AACF,YAAM,QAAQ,UAAU,UAAU;AAClC,UAAI,MAAM,eAAe,GAAG;AAC1B,eAAO,MAAM,6CAA6C;AAE1D,cAAM,WAAW,aAAa,UAAU;AACxC,eAAO,MAAM,gDAAgD,QAAQ,EAAE;AAGvE,YAAI,CAAC,SAAS,SAAS,gBAAgB,GAAG;AACxC,iBAAO,MAAM,qFAAqF;AAClG,iBAAO;AAAA,QACT;AACA,eAAO,MAAM,8FAA8F;AAE3G,qBAAa;AAAA,MACf;AAAA,IACF,QAAQ;AAEN,aAAO,MAAM,gFAAgF;AAAA,IAC/F;AAIA,QAAI,WAAW,SAAS,QAAQ,KAAK,WAAW,SAAS,UAAU,GAAG;AACpE,aAAO,MAAM,4FAA4F;AACzG,YAAM,UAAU,QAAQ,UAAU;AAClC,YAAM,cAAc,QAAQ,OAAO;AACnC,YAAM,SAAS,KAAK,aAAa,KAAK;AACtC,YAAM,kBAAkB,KAAK,aAAa,cAAc;AACxD,aAAO,MAAM,gDAAgD,MAAM,EAAE;AACrE,aAAO,MAAM,wDAAwD,eAAe,EAAE;AAGtF,UAAI,WAAW,MAAM,KAAK,WAAW,eAAe,GAAG;AACrD,eAAO,MAAM,4EAA4E;AACzF,eAAO;AAAA,MACT;AAAA,IACF;AAQA,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,iBAAiB,WAAW,QAAQ,OAAO,GAAG;AACpD,WAAO,MAAM,6DAA6D,cAAc,EAAE;AAC1F,eAAW,WAAW,gBAAgB;AACpC,UAAI,eAAe,SAAS,OAAO,GAAG;AACpC,eAAO,MAAM,mDAAmD,OAAO,2BAA2B;AAClG,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO,MAAM,sEAAsE;AACnF,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,MAAM,mDAAmD,KAAK,2BAA2B;AAChG,WAAO;AAAA,EACT;AACF;AAMO,SAAS,6BAA6B,QAAqC;AAChF,SAAO,WAAW;AACpB;","names":[]}
|
|
@@ -173,7 +173,7 @@ var UpdateNotifier = class {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
|
-
async function checkAndNotifyUpdate(currentVersion, packageName, installMethod) {
|
|
176
|
+
async function checkAndNotifyUpdate(currentVersion, packageName, installMethod, options) {
|
|
177
177
|
logger.debug(`checkAndNotifyUpdate: Called with version=${currentVersion}, package=${packageName}, installMethod=${installMethod}`);
|
|
178
178
|
try {
|
|
179
179
|
if (installMethod !== "global") {
|
|
@@ -182,11 +182,29 @@ async function checkAndNotifyUpdate(currentVersion, packageName, installMethod)
|
|
|
182
182
|
}
|
|
183
183
|
logger.debug("checkAndNotifyUpdate: Creating UpdateNotifier instance");
|
|
184
184
|
const notifier = new UpdateNotifier(currentVersion, packageName);
|
|
185
|
+
const fakeUpdateEnv = process.env.ILOOM_FAKE_UPDATE_AVAILABLE;
|
|
186
|
+
if (fakeUpdateEnv === "1" || fakeUpdateEnv === "true") {
|
|
187
|
+
logger.debug("checkAndNotifyUpdate: ILOOM_FAKE_UPDATE_AVAILABLE is set, using fake update result");
|
|
188
|
+
const fakeResult = {
|
|
189
|
+
currentVersion,
|
|
190
|
+
latestVersion: "99.99.99",
|
|
191
|
+
updateAvailable: true
|
|
192
|
+
};
|
|
193
|
+
if (!(options == null ? void 0 : options.suppressOutput)) {
|
|
194
|
+
logger.debug("checkAndNotifyUpdate: Displaying fake update notification");
|
|
195
|
+
notifier.displayUpdateNotification(fakeResult);
|
|
196
|
+
} else {
|
|
197
|
+
logger.debug("checkAndNotifyUpdate: Suppressing fake update notification (suppressOutput=true)");
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
185
201
|
logger.debug("checkAndNotifyUpdate: Calling checkForUpdates()");
|
|
186
202
|
const result = await notifier.checkForUpdates();
|
|
187
|
-
if (result !== null) {
|
|
203
|
+
if (result !== null && !(options == null ? void 0 : options.suppressOutput)) {
|
|
188
204
|
logger.debug(`checkAndNotifyUpdate: Got result, calling displayUpdateNotification`);
|
|
189
205
|
notifier.displayUpdateNotification(result);
|
|
206
|
+
} else if (result !== null && (options == null ? void 0 : options.suppressOutput)) {
|
|
207
|
+
logger.debug("checkAndNotifyUpdate: Suppressing update notification (suppressOutput=true)");
|
|
190
208
|
} else {
|
|
191
209
|
logger.debug("checkAndNotifyUpdate: Result was null, not displaying notification");
|
|
192
210
|
}
|
|
@@ -200,4 +218,4 @@ export {
|
|
|
200
218
|
UpdateNotifier,
|
|
201
219
|
checkAndNotifyUpdate
|
|
202
220
|
};
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-NGJZ4TOU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/update-notifier.ts"],"sourcesContent":["import os from 'os'\nimport path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport chalk from 'chalk'\nimport { logger } from './logger.js'\n\nexport interface UpdateCheckCache {\n lastCheck: number // timestamp\n latestVersion: string\n}\n\nexport interface UpdateCheckResult {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n}\n\nexport class UpdateNotifier {\n private cacheFilePath: string\n private currentVersion: string\n private packageName: string\n\n constructor(currentVersion: string, packageName: string) {\n this.currentVersion = currentVersion\n this.packageName = packageName\n // Cross-platform cache directory\n const configDir = path.join(os.homedir(), '.config', 'iloom-ai')\n this.cacheFilePath = path.join(configDir, 'update-check.json')\n logger.debug(`UpdateNotifier initialized: version=${currentVersion}, package=${packageName}, cachePath=${this.cacheFilePath}`)\n }\n\n /**\n * Check for updates, respecting 24hr cache\n * Returns UpdateCheckResult or null if check failed/not needed\n */\n async checkForUpdates(): Promise<UpdateCheckResult | null> {\n logger.debug('checkForUpdates: Starting update check')\n try {\n // Check cache first\n logger.debug('checkForUpdates: Checking cache')\n const cached = await this.getCachedCheck()\n if (cached !== null) {\n logger.debug(`checkForUpdates: Using cached result - latest=${cached.latestVersion}, lastCheck=${new Date(cached.lastCheck).toISOString()}`)\n const updateAvailable = this.isNewerVersion(this.currentVersion, cached.latestVersion)\n logger.debug(`checkForUpdates: Update available from cache: ${updateAvailable}`)\n return {\n currentVersion: this.currentVersion,\n latestVersion: cached.latestVersion,\n updateAvailable,\n }\n }\n\n logger.debug('checkForUpdates: No valid cache, querying npm registry')\n // Query npm registry\n const latestVersion = await this.fetchLatestVersion()\n if (latestVersion === null) {\n logger.debug('checkForUpdates: Failed to fetch latest version from npm')\n return null\n }\n\n logger.debug(`checkForUpdates: Fetched latest version: ${latestVersion}`)\n\n // Save to cache\n logger.debug('checkForUpdates: Saving to cache')\n await this.saveCacheFile(latestVersion)\n\n const updateAvailable = this.isNewerVersion(this.currentVersion, latestVersion)\n logger.debug(`checkForUpdates: Update available: ${updateAvailable} (current=${this.currentVersion}, latest=${latestVersion})`)\n\n return {\n currentVersion: this.currentVersion,\n latestVersion,\n updateAvailable,\n }\n } catch (error) {\n // Handle all errors gracefully - update check should never break user experience\n logger.debug(`checkForUpdates: Error during update check: ${error}`)\n return null\n }\n }\n\n /**\n * Read cache file, return null if stale or missing\n */\n private async getCachedCheck(): Promise<UpdateCheckCache | null> {\n logger.debug(`getCachedCheck: Checking cache file at ${this.cacheFilePath}`)\n try {\n if (!fs.existsSync(this.cacheFilePath)) {\n logger.debug('getCachedCheck: Cache file does not exist')\n return null\n }\n\n logger.debug('getCachedCheck: Cache file exists, reading contents')\n const content = await fs.readFile(this.cacheFilePath, 'utf8')\n logger.debug(`getCachedCheck: Cache file content: ${content}`)\n const cache = JSON.parse(content) as UpdateCheckCache\n\n // Check if cache is still fresh (< configurable hours)\n const cacheTimeoutMins = parseInt(process.env.ILOOM_UPDATE_CACHE_TIMEOUT_MINS ?? '60', 10) // Default 1 hour\n const cacheTimeoutMs = cacheTimeoutMins * 60 * 1000\n logger.debug(`getCachedCheck: Using cache timeout of ${cacheTimeoutMins} minutes`)\n const now = Date.now()\n const age = now - cache.lastCheck\n const ageHours = age / (60 * 60 * 1000)\n logger.debug(`getCachedCheck: Cache age: ${ageHours.toFixed(2)} hours (threshold: ${cacheTimeoutMins / 60} hours)`)\n\n if (now - cache.lastCheck < cacheTimeoutMs) {\n logger.debug('getCachedCheck: Cache is fresh, returning cached data')\n return cache\n }\n\n logger.debug('getCachedCheck: Cache is stale, will query npm registry')\n return null\n } catch (error) {\n // If cache is corrupted or unreadable, treat as missing\n logger.debug(`getCachedCheck: Error reading cache: ${error}`)\n return null\n }\n }\n\n /**\n * Save successful check to cache\n */\n private async saveCacheFile(latestVersion: string): Promise<void> {\n logger.debug(`saveCacheFile: Attempting to save cache for version ${latestVersion}`)\n try {\n // Ensure cache directory exists\n const configDir = path.dirname(this.cacheFilePath)\n logger.debug(`saveCacheFile: Ensuring cache directory exists: ${configDir}`)\n await fs.ensureDir(configDir)\n\n // Write cache file\n const cache: UpdateCheckCache = {\n lastCheck: Date.now(),\n latestVersion,\n }\n const cacheJson = JSON.stringify(cache, null, 2)\n logger.debug(`saveCacheFile: Writing cache file: ${cacheJson}`)\n await fs.writeFile(this.cacheFilePath, cacheJson, 'utf8')\n logger.debug(`saveCacheFile: Cache file saved successfully to ${this.cacheFilePath}`)\n } catch (error) {\n // Log debug message but don't throw - cache write failure shouldn't break anything\n logger.debug(`saveCacheFile: Failed to save update check cache to ${this.cacheFilePath}: ${error}`)\n }\n }\n\n /**\n * Display update notification to user\n */\n displayUpdateNotification(result: UpdateCheckResult): void {\n logger.debug(`displayUpdateNotification: updateAvailable=${result.updateAvailable}, current=${result.currentVersion}, latest=${result.latestVersion}`)\n if (result.updateAvailable) {\n logger.debug('displayUpdateNotification: Displaying update notification to user')\n // Simple, clear update notification\n /* eslint-disable no-console */\n console.log('')\n console.log(' ' + chalk.bold(`Update available: ${result.currentVersion} → ${result.latestVersion}`))\n console.log(' ' + chalk.bold('Run: il update'))\n console.log('')\n /* eslint-enable no-console */\n } else {\n logger.debug('displayUpdateNotification: No update available, skipping notification')\n }\n }\n\n /**\n * Query npm registry for latest version\n */\n private async fetchLatestVersion(): Promise<string | null> {\n logger.debug(`fetchLatestVersion: Querying npm for package ${this.packageName}`)\n try {\n const { stdout } = await execa('npm', ['view', this.packageName, 'version'], {\n timeout: 5000,\n })\n const version = stdout.trim()\n logger.debug(`fetchLatestVersion: npm returned version: ${version}`)\n return version\n } catch (error) {\n // Network errors, timeouts, npm not available, or package not found\n logger.debug(`fetchLatestVersion: Failed to query npm: ${error}`)\n return null\n }\n }\n\n /**\n * Compare semver versions\n * Returns true if latest > current\n */\n private isNewerVersion(current: string, latest: string): boolean {\n logger.debug(`isNewerVersion: Comparing versions - current=${current}, latest=${latest}`)\n // Simple version comparison: split by dots and compare numerically\n try {\n const currentParts = current.split('.').map(p => parseInt(p, 10))\n const latestParts = latest.split('.').map(p => parseInt(p, 10))\n logger.debug(`isNewerVersion: Parsed parts - current=[${currentParts.join(', ')}], latest=[${latestParts.join(', ')}]`)\n\n for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {\n const curr = currentParts[i] ?? 0\n const next = latestParts[i] ?? 0\n\n logger.debug(`isNewerVersion: Comparing part ${i}: current=${curr}, latest=${next}`)\n\n if (next > curr) {\n logger.debug(`isNewerVersion: Latest is newer (${next} > ${curr})`)\n return true\n }\n if (next < curr) {\n logger.debug(`isNewerVersion: Current is newer (${curr} > ${next})`)\n return false\n }\n }\n\n logger.debug('isNewerVersion: Versions are equal')\n return false\n } catch (error) {\n // If parsing fails, assume no update\n logger.debug(`isNewerVersion: Error comparing versions: ${error}`)\n return false\n }\n }\n}\n\n/**\n * Main entry point for update check\n * Call from CLI postAction hook\n */\nexport async function checkAndNotifyUpdate(\n currentVersion: string,\n packageName: string,\n installMethod: string\n): Promise<void> {\n logger.debug(`checkAndNotifyUpdate: Called with version=${currentVersion}, package=${packageName}, installMethod=${installMethod}`)\n try {\n // Only check for global installations\n if (installMethod !== 'global') {\n logger.debug(`checkAndNotifyUpdate: Skipping update check - not a global installation (method=${installMethod})`)\n return\n }\n\n logger.debug('checkAndNotifyUpdate: Creating UpdateNotifier instance')\n const notifier = new UpdateNotifier(currentVersion, packageName)\n\n logger.debug('checkAndNotifyUpdate: Calling checkForUpdates()')\n const result = await notifier.checkForUpdates()\n\n if (result !== null) {\n logger.debug(`checkAndNotifyUpdate: Got result, calling displayUpdateNotification`)\n notifier.displayUpdateNotification(result)\n } else {\n logger.debug('checkAndNotifyUpdate: Result was null, not displaying notification')\n }\n\n logger.debug('checkAndNotifyUpdate: Completed')\n } catch (error) {\n // All errors handled internally - this should never throw\n logger.debug(`checkAndNotifyUpdate: Unexpected error: ${error}`)\n }\n}\n"],"mappings":";;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,aAAa;AACtB,OAAO,WAAW;AAcX,IAAM,iBAAN,MAAqB;AAAA,EAK1B,YAAY,gBAAwB,aAAqB;AACvD,SAAK,iBAAiB;AACtB,SAAK,cAAc;AAEnB,UAAM,YAAY,KAAK,KAAK,GAAG,QAAQ,GAAG,WAAW,UAAU;AAC/D,SAAK,gBAAgB,KAAK,KAAK,WAAW,mBAAmB;AAC7D,WAAO,MAAM,uCAAuC,cAAc,aAAa,WAAW,eAAe,KAAK,aAAa,EAAE;AAAA,EAC/H;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAqD;AACzD,WAAO,MAAM,wCAAwC;AACrD,QAAI;AAEF,aAAO,MAAM,iCAAiC;AAC9C,YAAM,SAAS,MAAM,KAAK,eAAe;AACzC,UAAI,WAAW,MAAM;AACnB,eAAO,MAAM,iDAAiD,OAAO,aAAa,eAAe,IAAI,KAAK,OAAO,SAAS,EAAE,YAAY,CAAC,EAAE;AAC3I,cAAMA,mBAAkB,KAAK,eAAe,KAAK,gBAAgB,OAAO,aAAa;AACrF,eAAO,MAAM,iDAAiDA,gBAAe,EAAE;AAC/E,eAAO;AAAA,UACL,gBAAgB,KAAK;AAAA,UACrB,eAAe,OAAO;AAAA,UACtB,iBAAAA;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,wDAAwD;AAErE,YAAM,gBAAgB,MAAM,KAAK,mBAAmB;AACpD,UAAI,kBAAkB,MAAM;AAC1B,eAAO,MAAM,0DAA0D;AACvE,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,4CAA4C,aAAa,EAAE;AAGxE,aAAO,MAAM,kCAAkC;AAC/C,YAAM,KAAK,cAAc,aAAa;AAEtC,YAAM,kBAAkB,KAAK,eAAe,KAAK,gBAAgB,aAAa;AAC9E,aAAO,MAAM,sCAAsC,eAAe,aAAa,KAAK,cAAc,YAAY,aAAa,GAAG;AAE9H,aAAO;AAAA,QACL,gBAAgB,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,aAAO,MAAM,+CAA+C,KAAK,EAAE;AACnE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAmD;AAC/D,WAAO,MAAM,0CAA0C,KAAK,aAAa,EAAE;AAC3E,QAAI;AACF,UAAI,CAAC,GAAG,WAAW,KAAK,aAAa,GAAG;AACtC,eAAO,MAAM,2CAA2C;AACxD,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,qDAAqD;AAClE,YAAM,UAAU,MAAM,GAAG,SAAS,KAAK,eAAe,MAAM;AAC5D,aAAO,MAAM,uCAAuC,OAAO,EAAE;AAC7D,YAAM,QAAQ,KAAK,MAAM,OAAO;AAGhC,YAAM,mBAAmB,SAAS,QAAQ,IAAI,mCAAmC,MAAM,EAAE;AACzF,YAAM,iBAAiB,mBAAmB,KAAK;AAC/C,aAAO,MAAM,0CAA0C,gBAAgB,UAAU;AACjF,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,MAAM,MAAM,MAAM;AACxB,YAAM,WAAW,OAAO,KAAK,KAAK;AAClC,aAAO,MAAM,8BAA8B,SAAS,QAAQ,CAAC,CAAC,sBAAsB,mBAAmB,EAAE,SAAS;AAElH,UAAI,MAAM,MAAM,YAAY,gBAAgB;AAC1C,eAAO,MAAM,uDAAuD;AACpE,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,yDAAyD;AACtE,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,MAAM,wCAAwC,KAAK,EAAE;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAc,eAAsC;AAChE,WAAO,MAAM,uDAAuD,aAAa,EAAE;AACnF,QAAI;AAEF,YAAM,YAAY,KAAK,QAAQ,KAAK,aAAa;AACjD,aAAO,MAAM,mDAAmD,SAAS,EAAE;AAC3E,YAAM,GAAG,UAAU,SAAS;AAG5B,YAAM,QAA0B;AAAA,QAC9B,WAAW,KAAK,IAAI;AAAA,QACpB;AAAA,MACF;AACA,YAAM,YAAY,KAAK,UAAU,OAAO,MAAM,CAAC;AAC/C,aAAO,MAAM,sCAAsC,SAAS,EAAE;AAC9D,YAAM,GAAG,UAAU,KAAK,eAAe,WAAW,MAAM;AACxD,aAAO,MAAM,mDAAmD,KAAK,aAAa,EAAE;AAAA,IACtF,SAAS,OAAO;AAEd,aAAO,MAAM,uDAAuD,KAAK,aAAa,KAAK,KAAK,EAAE;AAAA,IACpG;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,0BAA0B,QAAiC;AACzD,WAAO,MAAM,8CAA8C,OAAO,eAAe,aAAa,OAAO,cAAc,YAAY,OAAO,aAAa,EAAE;AACrJ,QAAI,OAAO,iBAAiB;AAC1B,aAAO,MAAM,mEAAmE;AAGhF,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,OAAO,MAAM,KAAK,qBAAqB,OAAO,cAAc,WAAM,OAAO,aAAa,EAAE,CAAC;AACrG,cAAQ,IAAI,OAAO,MAAM,KAAK,gBAAgB,CAAC;AAC/C,cAAQ,IAAI,EAAE;AAAA,IAEhB,OAAO;AACL,aAAO,MAAM,uEAAuE;AAAA,IACtF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBAA6C;AACzD,WAAO,MAAM,gDAAgD,KAAK,WAAW,EAAE;AAC/E,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,MAAM,OAAO,CAAC,QAAQ,KAAK,aAAa,SAAS,GAAG;AAAA,QAC3E,SAAS;AAAA,MACX,CAAC;AACD,YAAM,UAAU,OAAO,KAAK;AAC5B,aAAO,MAAM,6CAA6C,OAAO,EAAE;AACnE,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,MAAM,4CAA4C,KAAK,EAAE;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,SAAiB,QAAyB;AAC/D,WAAO,MAAM,gDAAgD,OAAO,YAAY,MAAM,EAAE;AAExF,QAAI;AACF,YAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAK,SAAS,GAAG,EAAE,CAAC;AAChE,YAAM,cAAc,OAAO,MAAM,GAAG,EAAE,IAAI,OAAK,SAAS,GAAG,EAAE,CAAC;AAC9D,aAAO,MAAM,2CAA2C,aAAa,KAAK,IAAI,CAAC,cAAc,YAAY,KAAK,IAAI,CAAC,GAAG;AAEtH,eAAS,IAAI,GAAG,IAAI,KAAK,IAAI,aAAa,QAAQ,YAAY,MAAM,GAAG,KAAK;AAC1E,cAAM,OAAO,aAAa,CAAC,KAAK;AAChC,cAAM,OAAO,YAAY,CAAC,KAAK;AAE/B,eAAO,MAAM,kCAAkC,CAAC,aAAa,IAAI,YAAY,IAAI,EAAE;AAEnF,YAAI,OAAO,MAAM;AACf,iBAAO,MAAM,oCAAoC,IAAI,MAAM,IAAI,GAAG;AAClE,iBAAO;AAAA,QACT;AACA,YAAI,OAAO,MAAM;AACf,iBAAO,MAAM,qCAAqC,IAAI,MAAM,IAAI,GAAG;AACnE,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO,MAAM,oCAAoC;AACjD,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,aAAO,MAAM,6CAA6C,KAAK,EAAE;AACjE,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAMA,eAAsB,qBACpB,gBACA,aACA,eACe;AACf,SAAO,MAAM,6CAA6C,cAAc,aAAa,WAAW,mBAAmB,aAAa,EAAE;AAClI,MAAI;AAEF,QAAI,kBAAkB,UAAU;AAC9B,aAAO,MAAM,mFAAmF,aAAa,GAAG;AAChH;AAAA,IACF;AAEA,WAAO,MAAM,wDAAwD;AACrE,UAAM,WAAW,IAAI,eAAe,gBAAgB,WAAW;AAE/D,WAAO,MAAM,iDAAiD;AAC9D,UAAM,SAAS,MAAM,SAAS,gBAAgB;AAE9C,QAAI,WAAW,MAAM;AACnB,aAAO,MAAM,qEAAqE;AAClF,eAAS,0BAA0B,MAAM;AAAA,IAC3C,OAAO;AACL,aAAO,MAAM,oEAAoE;AAAA,IACnF;AAEA,WAAO,MAAM,iCAAiC;AAAA,EAChD,SAAS,OAAO;AAEd,WAAO,MAAM,2CAA2C,KAAK,EAAE;AAAA,EACjE;AACF;","names":["updateAvailable"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/update-notifier.ts"],"sourcesContent":["import os from 'os'\nimport path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport chalk from 'chalk'\nimport { logger } from './logger.js'\n\nexport interface UpdateCheckCache {\n lastCheck: number // timestamp\n latestVersion: string\n}\n\nexport interface UpdateCheckResult {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n}\n\nexport class UpdateNotifier {\n private cacheFilePath: string\n private currentVersion: string\n private packageName: string\n\n constructor(currentVersion: string, packageName: string) {\n this.currentVersion = currentVersion\n this.packageName = packageName\n // Cross-platform cache directory\n const configDir = path.join(os.homedir(), '.config', 'iloom-ai')\n this.cacheFilePath = path.join(configDir, 'update-check.json')\n logger.debug(`UpdateNotifier initialized: version=${currentVersion}, package=${packageName}, cachePath=${this.cacheFilePath}`)\n }\n\n /**\n * Check for updates, respecting 24hr cache\n * Returns UpdateCheckResult or null if check failed/not needed\n */\n async checkForUpdates(): Promise<UpdateCheckResult | null> {\n logger.debug('checkForUpdates: Starting update check')\n try {\n // Check cache first\n logger.debug('checkForUpdates: Checking cache')\n const cached = await this.getCachedCheck()\n if (cached !== null) {\n logger.debug(`checkForUpdates: Using cached result - latest=${cached.latestVersion}, lastCheck=${new Date(cached.lastCheck).toISOString()}`)\n const updateAvailable = this.isNewerVersion(this.currentVersion, cached.latestVersion)\n logger.debug(`checkForUpdates: Update available from cache: ${updateAvailable}`)\n return {\n currentVersion: this.currentVersion,\n latestVersion: cached.latestVersion,\n updateAvailable,\n }\n }\n\n logger.debug('checkForUpdates: No valid cache, querying npm registry')\n // Query npm registry\n const latestVersion = await this.fetchLatestVersion()\n if (latestVersion === null) {\n logger.debug('checkForUpdates: Failed to fetch latest version from npm')\n return null\n }\n\n logger.debug(`checkForUpdates: Fetched latest version: ${latestVersion}`)\n\n // Save to cache\n logger.debug('checkForUpdates: Saving to cache')\n await this.saveCacheFile(latestVersion)\n\n const updateAvailable = this.isNewerVersion(this.currentVersion, latestVersion)\n logger.debug(`checkForUpdates: Update available: ${updateAvailable} (current=${this.currentVersion}, latest=${latestVersion})`)\n\n return {\n currentVersion: this.currentVersion,\n latestVersion,\n updateAvailable,\n }\n } catch (error) {\n // Handle all errors gracefully - update check should never break user experience\n logger.debug(`checkForUpdates: Error during update check: ${error}`)\n return null\n }\n }\n\n /**\n * Read cache file, return null if stale or missing\n */\n private async getCachedCheck(): Promise<UpdateCheckCache | null> {\n logger.debug(`getCachedCheck: Checking cache file at ${this.cacheFilePath}`)\n try {\n if (!fs.existsSync(this.cacheFilePath)) {\n logger.debug('getCachedCheck: Cache file does not exist')\n return null\n }\n\n logger.debug('getCachedCheck: Cache file exists, reading contents')\n const content = await fs.readFile(this.cacheFilePath, 'utf8')\n logger.debug(`getCachedCheck: Cache file content: ${content}`)\n const cache = JSON.parse(content) as UpdateCheckCache\n\n // Check if cache is still fresh (< configurable hours)\n const cacheTimeoutMins = parseInt(process.env.ILOOM_UPDATE_CACHE_TIMEOUT_MINS ?? '60', 10) // Default 1 hour\n const cacheTimeoutMs = cacheTimeoutMins * 60 * 1000\n logger.debug(`getCachedCheck: Using cache timeout of ${cacheTimeoutMins} minutes`)\n const now = Date.now()\n const age = now - cache.lastCheck\n const ageHours = age / (60 * 60 * 1000)\n logger.debug(`getCachedCheck: Cache age: ${ageHours.toFixed(2)} hours (threshold: ${cacheTimeoutMins / 60} hours)`)\n\n if (now - cache.lastCheck < cacheTimeoutMs) {\n logger.debug('getCachedCheck: Cache is fresh, returning cached data')\n return cache\n }\n\n logger.debug('getCachedCheck: Cache is stale, will query npm registry')\n return null\n } catch (error) {\n // If cache is corrupted or unreadable, treat as missing\n logger.debug(`getCachedCheck: Error reading cache: ${error}`)\n return null\n }\n }\n\n /**\n * Save successful check to cache\n */\n private async saveCacheFile(latestVersion: string): Promise<void> {\n logger.debug(`saveCacheFile: Attempting to save cache for version ${latestVersion}`)\n try {\n // Ensure cache directory exists\n const configDir = path.dirname(this.cacheFilePath)\n logger.debug(`saveCacheFile: Ensuring cache directory exists: ${configDir}`)\n await fs.ensureDir(configDir)\n\n // Write cache file\n const cache: UpdateCheckCache = {\n lastCheck: Date.now(),\n latestVersion,\n }\n const cacheJson = JSON.stringify(cache, null, 2)\n logger.debug(`saveCacheFile: Writing cache file: ${cacheJson}`)\n await fs.writeFile(this.cacheFilePath, cacheJson, 'utf8')\n logger.debug(`saveCacheFile: Cache file saved successfully to ${this.cacheFilePath}`)\n } catch (error) {\n // Log debug message but don't throw - cache write failure shouldn't break anything\n logger.debug(`saveCacheFile: Failed to save update check cache to ${this.cacheFilePath}: ${error}`)\n }\n }\n\n /**\n * Display update notification to user\n */\n displayUpdateNotification(result: UpdateCheckResult): void {\n logger.debug(`displayUpdateNotification: updateAvailable=${result.updateAvailable}, current=${result.currentVersion}, latest=${result.latestVersion}`)\n if (result.updateAvailable) {\n logger.debug('displayUpdateNotification: Displaying update notification to user')\n // Simple, clear update notification\n /* eslint-disable no-console */\n console.log('')\n console.log(' ' + chalk.bold(`Update available: ${result.currentVersion} → ${result.latestVersion}`))\n console.log(' ' + chalk.bold('Run: il update'))\n console.log('')\n /* eslint-enable no-console */\n } else {\n logger.debug('displayUpdateNotification: No update available, skipping notification')\n }\n }\n\n /**\n * Query npm registry for latest version\n */\n private async fetchLatestVersion(): Promise<string | null> {\n logger.debug(`fetchLatestVersion: Querying npm for package ${this.packageName}`)\n try {\n const { stdout } = await execa('npm', ['view', this.packageName, 'version'], {\n timeout: 5000,\n })\n const version = stdout.trim()\n logger.debug(`fetchLatestVersion: npm returned version: ${version}`)\n return version\n } catch (error) {\n // Network errors, timeouts, npm not available, or package not found\n logger.debug(`fetchLatestVersion: Failed to query npm: ${error}`)\n return null\n }\n }\n\n /**\n * Compare semver versions\n * Returns true if latest > current\n */\n private isNewerVersion(current: string, latest: string): boolean {\n logger.debug(`isNewerVersion: Comparing versions - current=${current}, latest=${latest}`)\n // Simple version comparison: split by dots and compare numerically\n try {\n const currentParts = current.split('.').map(p => parseInt(p, 10))\n const latestParts = latest.split('.').map(p => parseInt(p, 10))\n logger.debug(`isNewerVersion: Parsed parts - current=[${currentParts.join(', ')}], latest=[${latestParts.join(', ')}]`)\n\n for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {\n const curr = currentParts[i] ?? 0\n const next = latestParts[i] ?? 0\n\n logger.debug(`isNewerVersion: Comparing part ${i}: current=${curr}, latest=${next}`)\n\n if (next > curr) {\n logger.debug(`isNewerVersion: Latest is newer (${next} > ${curr})`)\n return true\n }\n if (next < curr) {\n logger.debug(`isNewerVersion: Current is newer (${curr} > ${next})`)\n return false\n }\n }\n\n logger.debug('isNewerVersion: Versions are equal')\n return false\n } catch (error) {\n // If parsing fails, assume no update\n logger.debug(`isNewerVersion: Error comparing versions: ${error}`)\n return false\n }\n }\n}\n\n/**\n * Main entry point for update check\n * Call from CLI postAction hook\n */\nexport async function checkAndNotifyUpdate(\n currentVersion: string,\n packageName: string,\n installMethod: string,\n options?: { suppressOutput?: boolean }\n): Promise<void> {\n logger.debug(`checkAndNotifyUpdate: Called with version=${currentVersion}, package=${packageName}, installMethod=${installMethod}`)\n try {\n // Only check for global installations\n if (installMethod !== 'global') {\n logger.debug(`checkAndNotifyUpdate: Skipping update check - not a global installation (method=${installMethod})`)\n return\n }\n\n logger.debug('checkAndNotifyUpdate: Creating UpdateNotifier instance')\n const notifier = new UpdateNotifier(currentVersion, packageName)\n\n // Check for fake update flag (for testing purposes)\n const fakeUpdateEnv = process.env.ILOOM_FAKE_UPDATE_AVAILABLE\n if (fakeUpdateEnv === '1' || fakeUpdateEnv === 'true') {\n logger.debug('checkAndNotifyUpdate: ILOOM_FAKE_UPDATE_AVAILABLE is set, using fake update result')\n const fakeResult: UpdateCheckResult = {\n currentVersion,\n latestVersion: '99.99.99',\n updateAvailable: true,\n }\n if (!options?.suppressOutput) {\n logger.debug('checkAndNotifyUpdate: Displaying fake update notification')\n notifier.displayUpdateNotification(fakeResult)\n } else {\n logger.debug('checkAndNotifyUpdate: Suppressing fake update notification (suppressOutput=true)')\n }\n return\n }\n\n logger.debug('checkAndNotifyUpdate: Calling checkForUpdates()')\n const result = await notifier.checkForUpdates()\n\n if (result !== null && !options?.suppressOutput) {\n logger.debug(`checkAndNotifyUpdate: Got result, calling displayUpdateNotification`)\n notifier.displayUpdateNotification(result)\n } else if (result !== null && options?.suppressOutput) {\n logger.debug('checkAndNotifyUpdate: Suppressing update notification (suppressOutput=true)')\n } else {\n logger.debug('checkAndNotifyUpdate: Result was null, not displaying notification')\n }\n\n logger.debug('checkAndNotifyUpdate: Completed')\n } catch (error) {\n // All errors handled internally - this should never throw\n logger.debug(`checkAndNotifyUpdate: Unexpected error: ${error}`)\n }\n}\n"],"mappings":"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","names":["updateAvailable"]}
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
installDependencies,
|
|
8
8
|
runScript
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RD7I2Q2F.js";
|
|
10
10
|
import {
|
|
11
11
|
getPackageConfig,
|
|
12
12
|
hasScript
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XPKN3QWY.js";
|
|
14
14
|
import {
|
|
15
15
|
branchExists,
|
|
16
16
|
checkRemoteBranchStatus,
|
|
@@ -253,6 +253,7 @@ var LoomManager = class {
|
|
|
253
253
|
const { capabilities, binEntries } = await this.capabilityDetector.detectCapabilities(worktreePath);
|
|
254
254
|
await this.copyEnvironmentFiles(worktreePath);
|
|
255
255
|
await this.copyIloomSettings(worktreePath);
|
|
256
|
+
await this.copyIloomPackageLocal(worktreePath);
|
|
256
257
|
await this.copyClaudeSettings(worktreePath);
|
|
257
258
|
await this.copyGitIgnoredFiles(worktreePath);
|
|
258
259
|
const settingsData = await this.settings.loadSettings();
|
|
@@ -718,6 +719,27 @@ This PR was created automatically by iloom.`;
|
|
|
718
719
|
getLogger().warn(`Warning: Failed to copy settings.local.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
719
720
|
}
|
|
720
721
|
}
|
|
722
|
+
/**
|
|
723
|
+
* Copy iloom package local config (package.iloom.local.json) from main repo to worktree
|
|
724
|
+
* Always called regardless of project capabilities
|
|
725
|
+
* Follows the same pattern as copyIloomSettings()
|
|
726
|
+
* @param worktreePath Path to the worktree
|
|
727
|
+
*/
|
|
728
|
+
async copyIloomPackageLocal(worktreePath) {
|
|
729
|
+
const mainPackageLocalPath = path2.join(process.cwd(), ".iloom", "package.iloom.local.json");
|
|
730
|
+
try {
|
|
731
|
+
const worktreeIloomDir = path2.join(worktreePath, ".iloom");
|
|
732
|
+
await fs2.ensureDir(worktreeIloomDir);
|
|
733
|
+
const worktreePackageLocalPath = path2.join(worktreeIloomDir, "package.iloom.local.json");
|
|
734
|
+
if (await fs2.pathExists(worktreePackageLocalPath)) {
|
|
735
|
+
getLogger().debug("package.iloom.local.json already exists in worktree, skipping copy");
|
|
736
|
+
} else {
|
|
737
|
+
await this.environment.copyIfExists(mainPackageLocalPath, worktreePackageLocalPath);
|
|
738
|
+
}
|
|
739
|
+
} catch (error) {
|
|
740
|
+
getLogger().warn(`Warning: Failed to copy package.iloom.local.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
721
743
|
/**
|
|
722
744
|
* Copy Claude settings (settings.local.json) from main repo to worktree
|
|
723
745
|
* Always called regardless of project capabilities
|
|
@@ -968,6 +990,7 @@ This PR was created automatically by iloom.`;
|
|
|
968
990
|
const { capabilities, binEntries } = await this.capabilityDetector.detectCapabilities(worktreePath);
|
|
969
991
|
await this.copyEnvironmentFiles(worktreePath);
|
|
970
992
|
await this.copyIloomSettings(worktreePath);
|
|
993
|
+
await this.copyIloomPackageLocal(worktreePath);
|
|
971
994
|
await this.copyClaudeSettings(worktreePath);
|
|
972
995
|
await this.copyGitIgnoredFiles(worktreePath);
|
|
973
996
|
const settingsData = await this.settings.loadSettings();
|
|
@@ -2413,4 +2436,4 @@ export {
|
|
|
2413
2436
|
DatabaseManager,
|
|
2414
2437
|
ResourceCleanup
|
|
2415
2438
|
};
|
|
2416
|
-
//# sourceMappingURL=chunk-
|
|
2439
|
+
//# sourceMappingURL=chunk-QQFBMCAH.js.map
|