@ritualai/cli 0.7.10 → 0.7.12

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 (31) hide show
  1. package/dist/commands/doctor.js +246 -18
  2. package/dist/commands/doctor.js.map +1 -1
  3. package/dist/commands/init.js +139 -9
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/agents/configure-mcp.js +40 -10
  8. package/dist/lib/agents/configure-mcp.js.map +1 -1
  9. package/dist/lib/claude-code-scopes.js +140 -0
  10. package/dist/lib/claude-code-scopes.js.map +1 -0
  11. package/dist/lib/node-managers.js +114 -0
  12. package/dist/lib/node-managers.js.map +1 -0
  13. package/dist/lib/npm-registry.js +107 -0
  14. package/dist/lib/npm-registry.js.map +1 -0
  15. package/dist/lib/skill-bundles.js +62 -0
  16. package/dist/lib/skill-bundles.js.map +1 -0
  17. package/dist/lib/skill-manifest.js +53 -0
  18. package/dist/lib/skill-manifest.js.map +1 -0
  19. package/package.json +74 -73
  20. package/skills/claude-code/ritual/.ritual-bundle.json +4 -0
  21. package/skills/claude-code/ritual/references/build-flow.md +75 -12
  22. package/skills/codex/ritual/.ritual-bundle.json +4 -0
  23. package/skills/codex/ritual/references/build-flow.md +75 -12
  24. package/skills/cursor/ritual/.ritual-bundle.json +4 -0
  25. package/skills/cursor/ritual/references/build-flow.md +75 -12
  26. package/skills/gemini/ritual/.ritual-bundle.json +4 -0
  27. package/skills/gemini/ritual/references/build-flow.md +75 -12
  28. package/skills/kiro/ritual/.ritual-bundle.json +4 -0
  29. package/skills/kiro/ritual/references/build-flow.md +75 -12
  30. package/skills/vscode/ritual/.ritual-bundle.json +4 -0
  31. package/skills/vscode/ritual/references/build-flow.md +75 -12
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAClD,4CAAsD;AACtD,qDAA4D;AAE5D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,IAAA,qCAAsB,GAAE,CAAC,CAAC;AAEpC,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CACN,gBAAgB,EAChB,kFAAkF,CAClF;KACA,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;KACvE,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,MAAM,CACN,kBAAkB,EAClB,kMAAkM,CAClM;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,kBAAkB,EAClB,oIAAoI,CACpI;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iFAAiF,CAAC;KAC9F,MAAM,CACN,OAAO,EACP,6IAA6I,CAC7I;KACA,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,iEAAiE;AACjE,+DAA+D;AAC/D,kDAAkD;AAClD,MAAM,KAAK,GAAG,OAAO;KACnB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oEAAoE,CAAC,CAAC;AAEpF,KAAK;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CACN,kBAAkB,EAClB,0FAA0F,CAC1F;KACA,MAAM,CAAC,aAAa,EAAE,8DAA8D,CAAC;KACrF,MAAM,CAAC,0BAAkB,CAAC,CAAC;AAE7B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAClD,4CAAsD;AACtD,qDAA4D;AAE5D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,IAAA,qCAAsB,GAAE,CAAC,CAAC;AAEpC,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CACN,gBAAgB,EAChB,kFAAkF,CAClF;KACA,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;KACvE,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,MAAM,CACN,kBAAkB,EAClB,kMAAkM,CAClM;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,MAAM,CACN,eAAe,EACf,oOAAoO,CACpO;KACA,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,kBAAkB,EAClB,oIAAoI,CACpI;KACA,MAAM,CACN,OAAO,EACP,wFAAwF,CACxF;KACA,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iFAAiF,CAAC;KAC9F,MAAM,CACN,OAAO,EACP,6IAA6I,CAC7I;KACA,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,iEAAiE;AACjE,+DAA+D;AAC/D,kDAAkD;AAClD,MAAM,KAAK,GAAG,OAAO;KACnB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oEAAoE,CAAC,CAAC;AAEpF,KAAK;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CACN,kBAAkB,EAClB,0FAA0F,CAC1F;KACA,MAAM,CAAC,aAAa,EAAE,8DAA8D,CAAC;KACrF,MAAM,CAAC,0BAAkB,CAAC,CAAC;AAE7B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
@@ -55,6 +55,33 @@ function configureMcpForAgent(provider, registration) {
55
55
  * We re-register idempotently by removing-then-adding (the CLI errors
56
56
  * on a duplicate name). The `try/catch` around remove is intentional —
57
57
  * "not found" is fine; we just want a clean slate.
58
+ *
59
+ * Scope reconciliation (added 2026-05-14, CLI 0.7.12):
60
+ *
61
+ * Claude Code stores MCP entries in three scopes:
62
+ * - `user` → top-level `mcpServers.<name>` in ~/.claude.json
63
+ * - `local` → `projects["<cwd>"].mcpServers.<name>` in ~/.claude.json
64
+ * - `project` → a separate `.mcp.json` file in the project root
65
+ * (typically checked into git)
66
+ *
67
+ * Claude Code's in-session lookup prefers `local` over `user` when
68
+ * working inside a project. Before this commit we only removed from
69
+ * `--scope user` before re-adding — which meant any stale `local`
70
+ * entry (left behind by a manual `claude mcp add` or by an older
71
+ * version of this CLI) would survive every `ritual init`, silently
72
+ * shadow the fresh user-scope entry, and leave in-project sessions
73
+ * 401-ing on a revoked token. Mike hit this on 2026-05-14: a fresh
74
+ * `ritual init` minted a working user-scope token, but his
75
+ * django-oscar Claude Code session kept failing because the local
76
+ * scope still held the revoked predecessor.
77
+ *
78
+ * We now sweep BOTH writable scopes (`local` + `user`) before adding.
79
+ * `project` scope (the on-disk `.mcp.json`) is deliberately left
80
+ * alone — that file is often committed to the repo, and silently
81
+ * deleting from it would be a surprise change to a tracked file. If
82
+ * a project-scoped entry exists, `ritual doctor` surfaces it (see
83
+ * lib/claude-code-scopes.ts + the doctor sections that consume it)
84
+ * so the user knows where to look manually.
58
85
  */
59
86
  function configureViaCliCommand(_provider, registration) {
60
87
  const config = {
@@ -62,17 +89,20 @@ function configureViaCliCommand(_provider, registration) {
62
89
  url: registration.url,
63
90
  headers: { Authorization: `Bearer ${registration.token}` },
64
91
  };
65
- // 1. Remove any existing entry, swallowing errors.
66
- try {
67
- (0, node_child_process_1.execSync)(`claude mcp remove ${SERVER_NAME} --scope user`, { stdio: 'pipe' });
68
- }
69
- catch {
70
- /* not found — fine */
92
+ // 1. Remove from every writable scope. Skip `project` scope —
93
+ // .mcp.json is typically a tracked file.
94
+ for (const scope of ['local', 'user']) {
95
+ try {
96
+ (0, node_child_process_1.execSync)(`claude mcp remove ${SERVER_NAME} --scope ${scope}`, { stdio: 'pipe' });
97
+ }
98
+ catch {
99
+ /* not found in that scope — fine */
100
+ }
71
101
  }
72
- // 2. Add the fresh entry. Escape the JSON for the shell.
73
- // Using single-quote wrap is safe because the JSON contains no
74
- // single quotes (object keys + string values are all double-quoted
75
- // in JSON-stringify output).
102
+ // 2. Add the fresh entry under user scope. Escape the JSON for
103
+ // the shell. Using single-quote wrap is safe because the JSON
104
+ // contains no single quotes (object keys + string values are all
105
+ // double-quoted in JSON-stringify output).
76
106
  const json = JSON.stringify(config);
77
107
  (0, node_child_process_1.execSync)(`claude mcp add-json --scope user ${SERVER_NAME} '${json}'`, {
78
108
  stdio: 'pipe',
@@ -1 +1 @@
1
- {"version":3,"file":"configure-mcp.js","sourceRoot":"","sources":["../../../src/lib/agents/configure-mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configure-mcp.js","sourceRoot":"","sources":["../../../src/lib/agents/configure-mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RITUAL_SERVER_NAME = void 0;
4
+ exports.findRitualScopeEntries = findRitualScopeEntries;
5
+ exports.findShadowingEntries = findShadowingEntries;
6
+ exports.fixCommandFor = fixCommandFor;
7
+ const node_fs_1 = require("node:fs");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = require("node:path");
10
+ /**
11
+ * Server name used by `ritual init`. Kept in sync with
12
+ * `agents/configure-mcp.ts`'s SERVER_NAME constant.
13
+ */
14
+ exports.RITUAL_SERVER_NAME = 'ritual';
15
+ /**
16
+ * Pull a Bearer token out of an MCP entry's Authorization header.
17
+ * Defensive — entries can have absent / lower-cased / mis-prefixed
18
+ * headers; we return null and let the caller surface "non-bearer".
19
+ */
20
+ function extractBearer(entry) {
21
+ const headers = entry.headers ?? {};
22
+ // Try the conventional casing first, then case-insensitive fallback.
23
+ const authRaw = headers['Authorization'] ??
24
+ Object.entries(headers).find(([k]) => k.toLowerCase() === 'authorization')?.[1];
25
+ if (typeof authRaw !== 'string')
26
+ return null;
27
+ const m = authRaw.match(/^Bearer\s+(\S+)$/);
28
+ return m ? m[1] : null;
29
+ }
30
+ /**
31
+ * Read and JSON.parse a file, returning null on absent/corrupt.
32
+ * Doctor's job is to surface state, not to be the file repair tool —
33
+ * if `~/.claude.json` is corrupt the user has bigger problems and
34
+ * Claude Code itself would be broken; we just report nothing here.
35
+ */
36
+ function readJsonSafely(path) {
37
+ if (!(0, node_fs_1.existsSync)(path))
38
+ return null;
39
+ try {
40
+ return JSON.parse((0, node_fs_1.readFileSync)(path, 'utf-8'));
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Build the full list of ritual entries across all three scopes for
48
+ * a given project context. `cwd` is the project we want `local` and
49
+ * `project` scopes resolved against — usually `process.cwd()` from
50
+ * the caller, but parameterized for testability.
51
+ *
52
+ * Returned in precedence order: `project` first, then `local`, then
53
+ * `user`. Callers that just want "what's actually being used right
54
+ * now" can take the first entry. Callers that want to detect drift
55
+ * (doctor) iterate all of them.
56
+ */
57
+ function findRitualScopeEntries(cwd = process.cwd(), home = (0, node_os_1.homedir)()) {
58
+ const out = [];
59
+ // 1. Project scope — .mcp.json at the project root.
60
+ const projectMcpPath = (0, node_path_1.join)(cwd, '.mcp.json');
61
+ const projectMcp = readJsonSafely(projectMcpPath);
62
+ const projectEntry = projectMcp?.mcpServers?.[exports.RITUAL_SERVER_NAME];
63
+ if (projectEntry?.url) {
64
+ out.push({
65
+ scope: 'project',
66
+ configPath: projectMcpPath,
67
+ projectPath: cwd,
68
+ url: projectEntry.url,
69
+ bearerToken: extractBearer(projectEntry),
70
+ });
71
+ }
72
+ // 2. Local + user scope — both live inside ~/.claude.json.
73
+ const claudeJsonPath = (0, node_path_1.join)(home, '.claude.json');
74
+ const claudeJson = readJsonSafely(claudeJsonPath);
75
+ // On macOS, `process.cwd()` may return a symlink-resolved path
76
+ // (`/private/var/...`) while Claude Code's stored project key may
77
+ // be the user-facing form (`/var/...`) — or vice versa. Try both
78
+ // forms before giving up. In production this almost never matters
79
+ // (real project paths like `/Users/<name>/Development/<repo>` have
80
+ // no symlinks in the prefix) but tempdir-based tests exercise it.
81
+ let realCwd = cwd;
82
+ try {
83
+ realCwd = (0, node_fs_1.realpathSync)(cwd);
84
+ }
85
+ catch {
86
+ /* cwd doesn't exist or unreadable — fall back to literal */
87
+ }
88
+ const localEntry = claudeJson?.projects?.[cwd]?.mcpServers?.[exports.RITUAL_SERVER_NAME] ??
89
+ (realCwd !== cwd
90
+ ? claudeJson?.projects?.[realCwd]?.mcpServers?.[exports.RITUAL_SERVER_NAME]
91
+ : undefined);
92
+ if (localEntry?.url) {
93
+ out.push({
94
+ scope: 'local',
95
+ configPath: claudeJsonPath,
96
+ projectPath: cwd,
97
+ url: localEntry.url,
98
+ bearerToken: extractBearer(localEntry),
99
+ });
100
+ }
101
+ const userEntry = claudeJson?.mcpServers?.[exports.RITUAL_SERVER_NAME];
102
+ if (userEntry?.url) {
103
+ out.push({
104
+ scope: 'user',
105
+ configPath: claudeJsonPath,
106
+ url: userEntry.url,
107
+ bearerToken: extractBearer(userEntry),
108
+ });
109
+ }
110
+ return out;
111
+ }
112
+ /**
113
+ * Detect shadow drift: more than one entry exists across scopes AND
114
+ * the higher-precedence entry's bearer differs from the user-scope
115
+ * entry's. Returns the offending higher-precedence entries (which
116
+ * is what doctor surfaces as actionable).
117
+ *
118
+ * If only `user` is present, returns []. If `project` or `local`
119
+ * holds the SAME token as `user`, returns [] (no drift — just a
120
+ * scope-redundancy, harmless). If they hold different tokens, the
121
+ * shadowing entry is returned for cleanup.
122
+ */
123
+ function findShadowingEntries(entries) {
124
+ const userEntry = entries.find((e) => e.scope === 'user');
125
+ if (!userEntry || !userEntry.bearerToken)
126
+ return [];
127
+ return entries.filter((e) => e.scope !== 'user' &&
128
+ e.bearerToken !== null &&
129
+ e.bearerToken !== userEntry.bearerToken);
130
+ }
131
+ /**
132
+ * Convenience: the `claude mcp remove ritual -s <scope>` line a user
133
+ * should run to clean up a specific entry. Returns the literal
134
+ * command string so doctor can render it inline in the actionable
135
+ * fix-it text.
136
+ */
137
+ function fixCommandFor(entry) {
138
+ return `claude mcp remove ${exports.RITUAL_SERVER_NAME} -s ${entry.scope}`;
139
+ }
140
+ //# sourceMappingURL=claude-code-scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-scopes.js","sourceRoot":"","sources":["../../src/lib/claude-code-scopes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reportNodeManagers = reportNodeManagers;
4
+ exports.findDeadHyphenatedInstalls = findDeadHyphenatedInstalls;
5
+ exports.findShadowedInstalls = findShadowedInstalls;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_os_1 = require("node:os");
8
+ const node_path_1 = require("node:path");
9
+ /**
10
+ * Read a single `package.json` and extract `{ name, version }`.
11
+ * Returns null on any read/parse failure — caller treats absence as
12
+ * "no install at this path", not as an error.
13
+ */
14
+ function readPackageInfo(path) {
15
+ try {
16
+ const raw = (0, node_fs_1.readFileSync)(path, 'utf-8');
17
+ const parsed = JSON.parse(raw);
18
+ if (typeof parsed.name !== 'string' || typeof parsed.version !== 'string')
19
+ return null;
20
+ return { name: parsed.name, version: parsed.version };
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /**
27
+ * Given a directory we believe contains one or more Node version
28
+ * installations as immediate subdirectories, probe each for the two
29
+ * ritual packages. `nodeVersionDirPattern` describes how to derive the
30
+ * `lib/node_modules` location from each version dir.
31
+ *
32
+ * fnm layout: ~/.local/share/fnm/node-versions/v20.19.2/installation/lib/node_modules
33
+ * nvm layout: ~/.nvm/versions/node/v20.19.2/lib/node_modules
34
+ * asdf layout: ~/.asdf/installs/nodejs/20.19.2/.npm/lib/node_modules
35
+ */
36
+ function scanVersionRoot(manager, versionsRoot, libPathFromVersion) {
37
+ if (!(0, node_fs_1.existsSync)(versionsRoot))
38
+ return [];
39
+ let versionDirs;
40
+ try {
41
+ versionDirs = (0, node_fs_1.readdirSync)(versionsRoot, { withFileTypes: true })
42
+ .filter((d) => d.isDirectory())
43
+ .map((d) => d.name);
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ const out = [];
49
+ const packageNames = ['@ritualai/cli', '@ritual-ai/cli'];
50
+ for (const versionDir of versionDirs) {
51
+ const nodeModules = libPathFromVersion((0, node_path_1.join)(versionsRoot, versionDir));
52
+ for (const pkg of packageNames) {
53
+ const pkgJson = (0, node_path_1.join)(nodeModules, ...pkg.split('/'), 'package.json');
54
+ const info = readPackageInfo(pkgJson);
55
+ if (!info)
56
+ continue;
57
+ if (info.name !== pkg)
58
+ continue;
59
+ out.push({
60
+ manager,
61
+ nodeVersion: versionDir,
62
+ packageName: pkg,
63
+ version: info.version,
64
+ packageJsonPath: pkgJson,
65
+ });
66
+ }
67
+ }
68
+ return out;
69
+ }
70
+ /**
71
+ * Build the full report. Each manager is probed at its canonical
72
+ * install root; absence of a root is treated as "manager not used,"
73
+ * not an error. The aggregate `anyManagerPresent` is true if at least
74
+ * one root existed (whether or not it had ritual installs).
75
+ *
76
+ * NB: this does NOT probe the currently-active Node's global path —
77
+ * that's already reflected in `process.version` and the doctor reports
78
+ * it separately. The point of this report is shadowing detection: what
79
+ * other Node versions exist that you might silently fall through to.
80
+ */
81
+ function reportNodeManagers(home = (0, node_os_1.homedir)()) {
82
+ const fnmRoot = (0, node_path_1.join)(home, '.local', 'share', 'fnm', 'node-versions');
83
+ const nvmRoot = (0, node_path_1.join)(home, '.nvm', 'versions', 'node');
84
+ const asdfRoot = (0, node_path_1.join)(home, '.asdf', 'installs', 'nodejs');
85
+ const anyManagerPresent = (0, node_fs_1.existsSync)(fnmRoot) || (0, node_fs_1.existsSync)(nvmRoot) || (0, node_fs_1.existsSync)(asdfRoot);
86
+ const installs = [
87
+ ...scanVersionRoot('fnm', fnmRoot, (v) => (0, node_path_1.join)(v, 'installation', 'lib', 'node_modules')),
88
+ ...scanVersionRoot('nvm', nvmRoot, (v) => (0, node_path_1.join)(v, 'lib', 'node_modules')),
89
+ // asdf's node plugin uses npm's per-version prefix under `.npm`.
90
+ // This is the path npm itself writes to when you `npm i -g`
91
+ // under an asdf-managed Node.
92
+ ...scanVersionRoot('asdf', asdfRoot, (v) => (0, node_path_1.join)(v, '.npm', 'lib', 'node_modules')),
93
+ ];
94
+ return { anyManagerPresent, installs };
95
+ }
96
+ /**
97
+ * Pull just the dead-package installs out of a report. Used by doctor
98
+ * to render a louder warning — having `@ritual-ai/cli` installed
99
+ * anywhere is always a problem (it's the dead 0.1.x legacy), regardless
100
+ * of whether the *current* shell picks it up.
101
+ */
102
+ function findDeadHyphenatedInstalls(report) {
103
+ return report.installs.filter((i) => i.packageName === '@ritual-ai/cli');
104
+ }
105
+ /**
106
+ * Pull installs that are NOT the version of `currentVersion` (and not
107
+ * the dead hyphenated package — that's a separate, louder warning).
108
+ * These are "you've got a stale install on another Node version that
109
+ * will surface when fnm switches under you" candidates.
110
+ */
111
+ function findShadowedInstalls(report, currentVersion) {
112
+ return report.installs.filter((i) => i.packageName === '@ritualai/cli' && i.version !== currentVersion);
113
+ }
114
+ //# sourceMappingURL=node-managers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-managers.js","sourceRoot":"","sources":["../../src/lib/node-managers.ts"],"names":[],"mappings":";;AAiIA,gDAiBC;AAQD,gEAEC;AAQD,oDAOC;AA3KD,qCAAgE;AAChE,qCAAkC;AAClC,yCAAiC;AAoDjC;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAY;IACpC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwC,CAAC;QACtE,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvF,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,eAAe,CACvB,OAAoB,EACpB,YAAoB,EACpB,kBAAkD;IAElD,IAAI,CAAC,IAAA,oBAAU,EAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAEzC,IAAI,WAAqB,CAAC;IAC1B,IAAI,CAAC;QACJ,WAAW,GAAG,IAAA,qBAAW,EAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,MAAM,YAAY,GAAmC,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;IAEzF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAA,gBAAI,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;QACvE,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;YACrE,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG;gBAAE,SAAS;YAChC,GAAG,CAAC,IAAI,CAAC;gBACR,OAAO;gBACP,WAAW,EAAE,UAAU;gBACvB,WAAW,EAAE,GAAG;gBAChB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,eAAe,EAAE,OAAO;aACxB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAAC,IAAI,GAAG,IAAA,iBAAO,GAAE;IAClD,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAA,gBAAI,EAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE3D,MAAM,iBAAiB,GAAG,IAAA,oBAAU,EAAC,OAAO,CAAC,IAAI,IAAA,oBAAU,EAAC,OAAO,CAAC,IAAI,IAAA,oBAAU,EAAC,QAAQ,CAAC,CAAC;IAE7F,MAAM,QAAQ,GAAoB;QACjC,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAI,EAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QACzF,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAI,EAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QACzE,iEAAiE;QACjE,4DAA4D;QAC5D,8BAA8B;QAC9B,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAI,EAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;KACnF,CAAC;IAEF,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,0BAA0B,CAAC,MAAyB;IACnE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,gBAAgB,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CACnC,MAAyB,EACzB,cAAsB;IAEtB,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,eAAe,IAAI,CAAC,CAAC,OAAO,KAAK,cAAc,CACxE,CAAC;AACH,CAAC"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLatestNpmVersion = getLatestNpmVersion;
4
+ exports.isNewerVersion = isNewerVersion;
5
+ const node_https_1 = require("node:https");
6
+ /**
7
+ * Fetch the latest published version of an npm package from the public
8
+ * registry. Used by `ritual doctor` to surface "you're on 0.7.10 but
9
+ * 0.7.11 is available."
10
+ *
11
+ * Pure HTTPS — no dependency on a registry client library. We hit the
12
+ * package metadata endpoint and read `dist-tags.latest`, which is what
13
+ * `npm view <pkg> version` returns.
14
+ *
15
+ * Hard timeout because `ritual doctor` runs synchronously in the user's
16
+ * terminal and a hung network call would hang the diagnostic. Caller
17
+ * should treat null as "couldn't determine" (e.g. offline, registry
18
+ * down, corporate proxy) rather than "package doesn't exist."
19
+ *
20
+ * Why we don't use `child_process.execSync('npm view ...')`:
21
+ * - Shells out to `npm`, which loads ~600ms of Node startup just for
22
+ * the registry round-trip.
23
+ * - Adds an implicit dependency on `npm` being on PATH (we don't
24
+ * enforce that — a user could be on pnpm or yarn).
25
+ * - Surfaces npm's stderr noise (deprecation warnings, etc.) to the
26
+ * diagnostic output.
27
+ */
28
+ async function getLatestNpmVersion(packageName, timeoutMs = 2000) {
29
+ return new Promise((resolve) => {
30
+ // Encode scoped package names (`@scope/name`) for the URL path.
31
+ // `encodeURIComponent` turns `@` into `%40` and `/` into `%2F`,
32
+ // which is the registry's expected form for scoped packages.
33
+ const encoded = encodeURIComponent(packageName);
34
+ const url = `https://registry.npmjs.org/${encoded}`;
35
+ const req = (0, node_https_1.request)(url, {
36
+ method: 'GET',
37
+ headers: {
38
+ // Slim metadata response — full doc is megabytes for
39
+ // packages with long publish histories. `abbreviated`
40
+ // returns only the fields we need (~5KB).
41
+ Accept: 'application/vnd.npm.install-v1+json',
42
+ 'User-Agent': '@ritualai/cli (doctor)',
43
+ },
44
+ }, (res) => {
45
+ if (res.statusCode !== 200) {
46
+ res.resume(); // drain and discard
47
+ resolve(null);
48
+ return;
49
+ }
50
+ const chunks = [];
51
+ res.on('data', (c) => chunks.push(c));
52
+ res.on('end', () => {
53
+ try {
54
+ const body = Buffer.concat(chunks).toString('utf-8');
55
+ const parsed = JSON.parse(body);
56
+ const latest = parsed['dist-tags']?.latest;
57
+ resolve(typeof latest === 'string' ? latest : null);
58
+ }
59
+ catch {
60
+ resolve(null);
61
+ }
62
+ });
63
+ res.on('error', () => resolve(null));
64
+ });
65
+ req.setTimeout(timeoutMs, () => {
66
+ req.destroy();
67
+ resolve(null);
68
+ });
69
+ req.on('error', () => resolve(null));
70
+ req.end();
71
+ });
72
+ }
73
+ /**
74
+ * Loose semver compare: return true iff `latest` is strictly newer than
75
+ * `installed`. Tolerates `0.0.0-unknown` (used when we can't read our
76
+ * own version) by treating it as "always outdated" — which surfaces a
77
+ * loud error in doctor rather than silently passing.
78
+ *
79
+ * We deliberately don't pull in `semver` as a dep here — the cost
80
+ * (parse error handling, prerelease semantics, range syntax) isn't
81
+ * justified for a one-call compare. Splitting on '.' and comparing as
82
+ * numeric tuples is sufficient for our 0.X.Y release line.
83
+ */
84
+ function isNewerVersion(installed, latest) {
85
+ if (installed === latest)
86
+ return false;
87
+ if (installed === '0.0.0-unknown')
88
+ return true;
89
+ const parse = (v) => v
90
+ .split('-')[0] // strip prerelease (e.g. -beta.1)
91
+ .split('.')
92
+ .map((s) => Number.parseInt(s, 10))
93
+ .map((n) => (Number.isFinite(n) ? n : 0));
94
+ const a = parse(installed);
95
+ const b = parse(latest);
96
+ const len = Math.max(a.length, b.length);
97
+ for (let i = 0; i < len; i++) {
98
+ const ai = a[i] ?? 0;
99
+ const bi = b[i] ?? 0;
100
+ if (bi > ai)
101
+ return true;
102
+ if (bi < ai)
103
+ return false;
104
+ }
105
+ return false;
106
+ }
107
+ //# sourceMappingURL=npm-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-registry.js","sourceRoot":"","sources":["../../src/lib/npm-registry.ts"],"names":[],"mappings":";;AAwBA,kDAsDC;AAaD,wCAqBC;AAhHD,2CAAqD;AAErD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,UAAU,mBAAmB,CACxC,WAAmB,EACnB,SAAS,GAAG,IAAI;IAEhB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,gEAAgE;QAChE,gEAAgE;QAChE,6DAA6D;QAC7D,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,8BAA8B,OAAO,EAAE,CAAC;QAEpD,MAAM,GAAG,GAAG,IAAA,oBAAY,EACvB,GAAG,EACH;YACC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACR,qDAAqD;gBACrD,sDAAsD;gBACtD,0CAA0C;gBAC1C,MAAM,EAAE,qCAAqC;gBAC7C,YAAY,EAAE,wBAAwB;aACtC;SACD,EACD,CAAC,GAAG,EAAE,EAAE;YACP,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC5B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,oBAAoB;gBAClC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO;YACR,CAAC;YACD,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBAClB,IAAI,CAAC;oBACJ,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAE7B,CAAC;oBACF,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;oBAC3C,OAAO,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACR,OAAO,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC;YACF,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC,CACD,CAAC;QAEF,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE;YAC9B,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,GAAG,CAAC,GAAG,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,SAAiB,EAAE,MAAc;IAC/D,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,SAAS,KAAK,eAAe;QAAE,OAAO,IAAI,CAAC;IAE/C,MAAM,KAAK,GAAG,CAAC,CAAS,EAAY,EAAE,CACrC,CAAC;SACC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kCAAkC;SAChD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5C,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findLocalSkillBundles = findLocalSkillBundles;
4
+ exports.findStaleBundles = findStaleBundles;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const providers_1 = require("./agents/providers");
8
+ const skill_manifest_1 = require("./skill-manifest");
9
+ /**
10
+ * Walk every known provider's `projectSkillDir` under `projectDir` and
11
+ * collect each child directory as a candidate skill bundle. Reads each
12
+ * manifest and compares to `cliVersion`.
13
+ *
14
+ * Hidden directories (those starting with `.`) are skipped — they're
15
+ * either dotfiles or our own manifest companions, never skill dirs.
16
+ *
17
+ * `cliVersion` is passed in (rather than read from package-info here)
18
+ * so tests can inject a fixed value.
19
+ */
20
+ function findLocalSkillBundles(projectDir, cliVersion) {
21
+ const found = [];
22
+ for (const provider of providers_1.PROVIDERS) {
23
+ const skillRoot = (0, node_path_1.join)(projectDir, provider.projectSkillDir);
24
+ if (!(0, node_fs_1.existsSync)(skillRoot))
25
+ continue;
26
+ let entries;
27
+ try {
28
+ entries = (0, node_fs_1.readdirSync)(skillRoot, { withFileTypes: true })
29
+ .filter((d) => d.isDirectory() && !d.name.startsWith('.'))
30
+ .map((d) => d.name);
31
+ }
32
+ catch {
33
+ continue;
34
+ }
35
+ for (const skillName of entries) {
36
+ const path = (0, node_path_1.join)(skillRoot, skillName);
37
+ // Defensive: a non-directory slipping through (race, symlink
38
+ // loop) just gets skipped.
39
+ try {
40
+ if (!(0, node_fs_1.statSync)(path).isDirectory())
41
+ continue;
42
+ }
43
+ catch {
44
+ continue;
45
+ }
46
+ const manifest = (0, skill_manifest_1.readSkillManifest)(path);
47
+ const drift = (0, skill_manifest_1.compareToCliVersion)(manifest, cliVersion);
48
+ found.push({ provider, skillName, path, drift });
49
+ }
50
+ }
51
+ return found;
52
+ }
53
+ /**
54
+ * Subset of bundles whose drift status indicates a refresh would help.
55
+ * Both `drift` (manifest present, version mismatch) AND `unknown`
56
+ * (manifest missing — pre-0.7.11 bundle) are considered actionable:
57
+ * running `ritual init --skills-only` is the same fix for either case.
58
+ */
59
+ function findStaleBundles(bundles) {
60
+ return bundles.filter((b) => b.drift.kind === 'drift' || b.drift.kind === 'unknown');
61
+ }
62
+ //# sourceMappingURL=skill-bundles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-bundles.js","sourceRoot":"","sources":["../../src/lib/skill-bundles.ts"],"names":[],"mappings":";;AAqCA,sDAgCC;AAQD,4CAEC;AA/ED,qCAA4D;AAC5D,yCAAiC;AACjC,kDAAmE;AACnE,qDAA4F;AAuB5F;;;;;;;;;;GAUG;AACH,SAAgB,qBAAqB,CAAC,UAAkB,EAAE,UAAkB;IAC3E,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,qBAAS,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,UAAU,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAA,oBAAU,EAAC,SAAS,CAAC;YAAE,SAAS;QAErC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACJ,OAAO,GAAG,IAAA,qBAAW,EAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;iBACvD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;iBACzD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACR,SAAS;QACV,CAAC;QAED,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACxC,6DAA6D;YAC7D,2BAA2B;YAC3B,IAAI,CAAC;gBACJ,IAAI,CAAC,IAAA,kBAAQ,EAAC,IAAI,CAAC,CAAC,WAAW,EAAE;oBAAE,SAAS;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACR,SAAS;YACV,CAAC;YACD,MAAM,QAAQ,GAAG,IAAA,kCAAiB,EAAC,IAAI,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,IAAA,oCAAmB,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,OAA2B;IAC3D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANIFEST_FILENAME = void 0;
4
+ exports.writeSkillManifest = writeSkillManifest;
5
+ exports.readSkillManifest = readSkillManifest;
6
+ exports.compareToCliVersion = compareToCliVersion;
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = require("node:path");
9
+ exports.MANIFEST_FILENAME = '.ritual-bundle.json';
10
+ /**
11
+ * Write a manifest into `dir`. Used by the build-skills script.
12
+ *
13
+ * Always overwrites. `dir` must exist — caller is responsible for
14
+ * mkdir.
15
+ */
16
+ function writeSkillManifest(dir, manifest) {
17
+ const path = (0, node_path_1.join)(dir, exports.MANIFEST_FILENAME);
18
+ (0, node_fs_1.writeFileSync)(path, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
19
+ }
20
+ /**
21
+ * Read a manifest from `dir`. Returns `null` if absent or unparseable.
22
+ *
23
+ * Never throws — drift checks are best-effort and an unreadable
24
+ * manifest just means "we can't tell," not "crash the doctor."
25
+ */
26
+ function readSkillManifest(dir) {
27
+ const path = (0, node_path_1.join)(dir, exports.MANIFEST_FILENAME);
28
+ if (!(0, node_fs_1.existsSync)(path))
29
+ return null;
30
+ try {
31
+ const raw = (0, node_fs_1.readFileSync)(path, 'utf-8');
32
+ const parsed = JSON.parse(raw);
33
+ if (typeof parsed.cliVersion !== 'string' || parsed.cliVersion.length === 0) {
34
+ return null;
35
+ }
36
+ if (typeof parsed.builtAt !== 'string' || parsed.builtAt.length === 0) {
37
+ return null;
38
+ }
39
+ return { cliVersion: parsed.cliVersion, builtAt: parsed.builtAt };
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ function compareToCliVersion(manifest, cliVersion) {
46
+ if (!manifest)
47
+ return { kind: 'unknown' };
48
+ if (manifest.cliVersion === cliVersion) {
49
+ return { kind: 'in-sync', bundleVersion: manifest.cliVersion };
50
+ }
51
+ return { kind: 'drift', bundleVersion: manifest.cliVersion, cliVersion };
52
+ }
53
+ //# sourceMappingURL=skill-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-manifest.js","sourceRoot":"","sources":["../../src/lib/skill-manifest.ts"],"names":[],"mappings":";;;AA0CA,gDAGC;AAQD,8CAgBC;AAkBD,kDASC;AAhGD,qCAAkE;AAClE,yCAAiC;AAiCpB,QAAA,iBAAiB,GAAG,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,GAAW,EAAE,QAA6B;IAC5E,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,yBAAiB,CAAC,CAAC;IAC1C,IAAA,uBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,GAAW;IAC5C,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,yBAAiB,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiC,CAAC;QAC/D,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAkBD,SAAgB,mBAAmB,CAClC,QAAoC,EACpC,UAAkB;IAElB,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1C,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;AAC1E,CAAC"}