wicked-crew 0.7.26 → 0.7.27

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.
@@ -1,16 +1,53 @@
1
1
  /**
2
- * Where the shipped baseline comes from: the LIVE installed wicked-garden plugin.
2
+ * Where the shipped baseline comes from: the installed wicked-garden plugin.
3
3
  *
4
4
  * The daemon seeds (and refreshes) its skills root from the plugin Claude Code actually runs —
5
5
  * the marketplace cache under `<CLAUDE_CONFIG_DIR|~/.claude>/plugins/cache/wicked-garden/
6
- * wicked-garden/<version>` (highest version wins). That is the ONLY automatic source (design v3
7
- * §3/§8; codex review of #480): the hand-installed `<config dir>/plugins/wicked-garden` copy is the
8
- * exact stale artifact the operator's `clis.toml` hack pointed workers at (12.28.1 while the live
9
- * cache was 12.32.0 — design v3 §"Verified mechanics"), so it is never a fallback. NEVER a repo
10
- * checkout by default either. `WICKED_CREW_SKILLS_SOURCE` is the one explicit override — for
11
- * tests, and for an operator who deliberately wants a checkout or that hand copy. A machine without
12
- * the cache has no source at all: crew does not vendor garden — the seed says "install garden
13
- * first" loudly (`SkillsSourceUnavailableError`) and the runtime leaves the engine input unset.
6
+ * wicked-garden/<version>` (highest version wins). Design v3 §3/§8 (codex review of #480) made that
7
+ * the ONLY automatic source, because the hand-installed `<config dir>/plugins/wicked-garden` copy
8
+ * was the exact stale artifact the operator's `clis.toml` hack pointed workers at (12.28.1 while the
9
+ * live cache was 12.32.0 — design v3 §"Verified mechanics"). Amendment v3.6 (#490) admits that copy
10
+ * as a LAST resort — `npx wicked-installer install wicked-garden` lays it down without registering
11
+ * the marketplace, so an installer-only machine had no source at all — without hiding the difference:
12
+ *
13
+ * Design amendment v3.6 (verbatim):
14
+ * "Discovery order: (1) `WICKED_CREW_SKILLS_SOURCE` explicit override; (2) the marketplace cache
15
+ * `<config dir>/plugins/cache/wicked-garden/wicked-garden/<highest version>` for each dir in
16
+ * `CLAUDE_CONFIG_DIR` (may list several) else `~/.claude`; (3) LAST resort, the installer-managed
17
+ * copy `<config dir>/plugins/wicked-garden` for each of those dirs AND `~/.claude/plugins/wicked-garden`
18
+ * (garden's `install.mjs` hard-codes homedir), accepted only when its `.claude-plugin/plugin.json`
19
+ * parses with a `version`. A source of kind (3) is recorded in the baseline as `source.kind:
20
+ * 'installer-copy'` and surfaces a persistent WARNING finding `skills.source` in
21
+ * `GET /diagnostics.skills.findings` — 'seeded from the installer copy at <path>; register the plugin
22
+ * with Claude Code (marketplace) to receive marketplace updates' — so the daemon works on
23
+ * installer-only machines without hiding the difference. When BOTH a cache and a copy exist, the
24
+ * cache wins regardless of version; the copy is never preferred. Every source kind passes the same
25
+ * no-follow, closure and validation rules."
26
+ *
27
+ * How the automatic tiers walk (codex on #491, both passes): the config dirs are `CLAUDE_CONFIG_DIR`'s
28
+ * entries in the order listed (platform path delimiter) with the literal `~/.claude` appended once
29
+ * unless already listed — the default when the variable is unset. Each config dir is resolved exactly
30
+ * ONCE, at the top of discovery (`realpath` — the one link the automatic tiers follow: operators
31
+ * symlink `~/.claude`); that canonical root is carried through both tiers, every level below it that
32
+ * discovery touches — `plugins`, `cache`, the marketplace dir, the plugin dir, each version dir, the
33
+ * copy dir — is lstat-walked ON THE CANONICAL PATH, a symlink at any of them skips that candidate with
34
+ * a `symlink` finding (never followed), and a candidate's manifest is read only below that
35
+ * already-validated canonical dir — never through the spelled path, so a link retargeted mid-walk is
36
+ * never read. The recorded `PluginSource.path` is that canonical path. Tier (2) visits every dir in
37
+ * order and the FIRST dir holding a valid cache wins; inside a cache every entry is judged: a name
38
+ * must be a SemVer version by the semver.org grammar (no leading zeros in numeric identifiers, legal
39
+ * pre-release / build identifiers — else ignored with a finding), EVERY such dir's `plugin.json`
40
+ * version must equal its name (else skipped with a finding — every dir is validated, not only the
41
+ * winner; a manifest that does not parse is a `no-manifest` finding, never a crash), and the pick is
42
+ * the highest by SemVer PRECEDENCE (build metadata ignored for ordering,
43
+ * pre-release below release, numeric identifiers before alphanumeric) with a documented tie-break
44
+ * (`cacheDirOrder`). Tier (3) visits the same dirs in the same order; ANY cache beats ANY copy — a
45
+ * `~/.claude` cache beats a `$CLAUDE_CONFIG_DIR/plugins/wicked-garden` copy. What was passed over
46
+ * rides beside the answer as `DiscoveryFinding`s (the daemon logs them). NEVER a repo checkout by
47
+ * default. `WICKED_CREW_SKILLS_SOURCE` is the one explicit override — for tests, and for an operator
48
+ * who deliberately wants a checkout or some other plugin root. A machine with neither a cache nor a
49
+ * copy has no source at all: crew does not vendor garden — the seed says "install garden first"
50
+ * loudly (`SkillsSourceUnavailableError`) and the runtime leaves the engine input unset.
14
51
  *
15
52
  * # No-follow BELOW the root (codex round 6 on #480)
16
53
  *
@@ -27,17 +64,33 @@
27
64
  import { execFileSync } from 'node:child_process';
28
65
  import { existsSync, lstatSync, readdirSync, readlinkSync, realpathSync } from 'node:fs';
29
66
  import { homedir } from 'node:os';
30
- import { join, sep } from 'node:path';
67
+ import { delimiter, join, resolve, sep } from 'node:path';
31
68
  import { PLUGIN_NAME } from './frontmatter.js';
32
69
  import { readFileNoFollow } from './tree.js';
33
70
  /** Explicit plugin-source override — the seam tests and proof scripts aim at a fixture plugin. */
34
71
  export const SKILLS_SOURCE_ENV = 'WICKED_CREW_SKILLS_SOURCE';
35
72
  /** Relative path of the Claude Code plugin manifest inside a plugin root. */
36
73
  export const PLUGIN_MANIFEST_REL = join('.claude-plugin', 'plugin.json');
37
- /** The Claude Code config dir the plugin cache lives under: `CLAUDE_CONFIG_DIR`, else `~/.claude`. */
38
- export function claudeConfigDir(env = process.env, home = homedir()) {
39
- const configured = env['CLAUDE_CONFIG_DIR'];
40
- return configured !== undefined && configured !== '' ? configured : join(home, '.claude');
74
+ /**
75
+ * The Claude Code config dirs discovery walks, IN ORDER: every non-empty entry of `CLAUDE_CONFIG_DIR`
76
+ * (it may list several, separated by the platform path delimiter) as listed, then the literal
77
+ * `~/.claude` appended once unless already listed — the default when the variable is unset, and the
78
+ * dir garden's `install.mjs` hard-codes (design v3.6; codex on #491). Spelled as given (the walk
79
+ * resolves each dir once); a dir listed twice is walked once.
80
+ */
81
+ export function claudeConfigDirs(env = process.env, home = homedir()) {
82
+ const dirs = [];
83
+ const seen = new Set();
84
+ for (const dir of [...(env['CLAUDE_CONFIG_DIR'] ?? '').split(delimiter), join(home, '.claude')]) {
85
+ if (dir === '')
86
+ continue;
87
+ const key = resolve(dir);
88
+ if (seen.has(key))
89
+ continue;
90
+ seen.add(key);
91
+ dirs.push(dir);
92
+ }
93
+ return dirs;
41
94
  }
42
95
  /**
43
96
  * A designated entry of the plugin source is a symlink — the seed/refresh is refused by name and
@@ -99,113 +152,154 @@ export function noFollowEntry(root, segments, sourceSpelling = root) {
99
152
  return cur;
100
153
  }
101
154
  /**
102
- * The plugin manifest's `version` at `dir`, or `null` when `dir` is not a plugin root. The manifest
103
- * is read NO-FOLLOW below the (once-resolved) root: a symlinked `.claude-plugin/` or `plugin.json`
104
- * throws `PluginSourceSymlinkError` — never a version read through a link (codex round 6).
155
+ * The plugin manifest's `version` at `dir`, or `null` when `dir` is not a plugin root — the root
156
+ * resolved once (`realPluginRoot`), then `manifestVersionBelow`. For the explicit override and
157
+ * `pluginSourceAt`; the automatic tiers never call this (they resolve the CONFIG dir once and read
158
+ * below the canonical candidate directly).
105
159
  */
106
160
  export function pluginVersionAt(dir) {
107
161
  const root = realPluginRoot(dir);
108
- if (root === null)
109
- return null;
110
- const manifest = noFollowEntry(root, PLUGIN_MANIFEST_REL.split(sep), dir);
162
+ return root === null ? null : manifestVersionBelow(root, dir);
163
+ }
164
+ /**
165
+ * The manifest `version` below an already-canonical plugin dir, or `null` when there is no
166
+ * `.claude-plugin/plugin.json` that PARSES with a non-empty string `version` — missing, not a
167
+ * regular file, not JSON, not an object, or versionless are all "not a plugin root" (design v3.6:
168
+ * "accepted only when its plugin.json parses with a version"; Copilot on #491: one corrupt manifest
169
+ * in a cache must skip that candidate, not take discovery down). NO-FOLLOW below the root and no
170
+ * re-resolution of the root itself: a symlinked `.claude-plugin/` or `plugin.json` throws
171
+ * `PluginSourceSymlinkError` — never a version read through a link (codex round 6) — and an I/O
172
+ * error reading the file stays an error. `spelling` is the root as the caller spelled it, for the
173
+ * symlink error.
174
+ */
175
+ export function manifestVersionBelow(root, spelling = root) {
176
+ const manifest = noFollowEntry(root, PLUGIN_MANIFEST_REL.split(sep), spelling);
111
177
  if (manifest === null || !lstatSync(manifest).isFile())
112
178
  return null;
113
- const parsed = JSON.parse(readFileNoFollow(manifest).toString('utf8')); // the entry the walk judged is the one read (v3.5 §3)
179
+ const text = readFileNoFollow(manifest).toString('utf8'); // the entry the walk judged is the one read (v3.5 §3)
180
+ let parsed;
181
+ try {
182
+ parsed = JSON.parse(text);
183
+ }
184
+ catch (err) {
185
+ if (err instanceof SyntaxError)
186
+ return null;
187
+ throw err;
188
+ }
114
189
  if (typeof parsed !== 'object' || parsed === null)
115
190
  return null;
116
191
  const version = parsed.version;
117
192
  return typeof version === 'string' && version !== '' ? version : null;
118
193
  }
119
194
  /**
120
- * A TOTAL order over version strings, so "highest version wins" never depends on `readdir` order
121
- * (Copilot on #480). Numeric dotted order first (`12.9.0` < `12.32.0`; a shorter release sorts
122
- * before a longer one with the same prefix; a non-integer segment sorts below any integer). A
123
- * prerelease suffix (`12.0.0-beta`, everything after the first `-`) sorts BELOW its release
124
- * (`12.0.0-beta` < `12.0.0`), and two prereleases compare identifier by identifier the semver way
125
- * (numeric identifiers numerically and before alphanumeric ones, then lexically, shorter first).
126
- * Distinct strings NEVER compare equal: whatever survives all of that (`12.00.0` vs `12.0.0`) is
127
- * ordered lexically.
195
+ * The official SemVer grammar (semver.org §BNF / the suggested regex): numeric identifiers without
196
+ * leading zeros, pre-release identifiers `[0-9A-Za-z-]` non-empty (numeric ones without leading
197
+ * zeros), build identifiers `[0-9A-Za-z-]` non-empty. `01.0.0`, `1.0.0-alpha..1`, `1.0.0-01`, `1.0`
198
+ * and `v1.0.0` are NOT versions.
128
199
  */
129
- export function compareVersions(a, b) {
130
- if (a === b)
131
- return 0;
132
- const [coreA, preA] = splitPrerelease(a);
133
- const [coreB, preB] = splitPrerelease(b);
134
- const core = compareDotted(coreA, coreB);
135
- if (core !== 0)
136
- return core;
137
- if (preA === null && preB !== null)
138
- return 1;
139
- if (preA !== null && preB === null)
140
- return -1;
141
- if (preA !== null && preB !== null) {
142
- const pre = comparePrerelease(preA, preB);
143
- if (pre !== 0)
144
- return pre;
145
- }
146
- return a < b ? -1 : 1;
200
+ const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
201
+ /** Parse a SemVer version, or `null` when the string is not one by the official grammar. */
202
+ export function parseSemver(v) {
203
+ const m = SEMVER_RE.exec(v);
204
+ if (m === null)
205
+ return null;
206
+ return {
207
+ major: m[1],
208
+ minor: m[2],
209
+ patch: m[3],
210
+ prerelease: m[4] === undefined ? [] : m[4].split('.'),
211
+ build: m[5] ?? null,
212
+ };
147
213
  }
148
- /** `12.0.0-beta.1` → [`12.0.0`, `beta.1`]; no `-` → [`v`, null]. */
149
- function splitPrerelease(v) {
150
- const dash = v.indexOf('-');
151
- return dash === -1 ? [v, null] : [v.slice(0, dash), v.slice(dash + 1)];
214
+ /** Two non-negative integers as digit strings without leading zeros (the SemVer grammar guarantees it): shorter is smaller, equal length compares lexically — exact at any magnitude. */
215
+ function compareNumeric(a, b) {
216
+ if (a.length !== b.length)
217
+ return a.length < b.length ? -1 : 1;
218
+ return a < b ? -1 : a > b ? 1 : 0;
152
219
  }
153
- /** Dotted numeric segments: shorter-first on a shared prefix, a non-integer segment below any integer. */
154
- function compareDotted(a, b) {
155
- const pa = a.split('.');
156
- const pb = b.split('.');
157
- const n = Math.max(pa.length, pb.length);
158
- for (let i = 0; i < n; i += 1) {
159
- const sa = pa[i];
160
- const sb = pb[i];
161
- if (sa === undefined)
162
- return -1;
163
- if (sb === undefined)
164
- return 1;
165
- const na = /^\d+$/.test(sa) ? Number(sa) : -1;
166
- const nb = /^\d+$/.test(sb) ? Number(sb) : -1;
167
- if (na !== nb)
168
- return na < nb ? -1 : 1;
220
+ /**
221
+ * SemVer PRECEDENCE (semver.org §11): major, minor, patch numerically; a pre-release version has
222
+ * LOWER precedence than its release; pre-release identifiers compare left to right — numeric ones
223
+ * numerically (losslessly — digit strings, never `number`), numeric before alphanumeric,
224
+ * alphanumeric ones in ASCII order, a shorter set lower when every preceding identifier is equal.
225
+ * Build metadata is IGNORED: `1.0.1` and `1.0.1+build`
226
+ * have equal precedence (0). Throws for a string that is not a SemVer version — callers validate
227
+ * names first (`parseSemver`).
228
+ */
229
+ export function compareSemver(a, b) {
230
+ const pa = parseSemver(a);
231
+ const pb = parseSemver(b);
232
+ if (pa === null || pb === null)
233
+ throw new TypeError(`compareSemver: not a SemVer version: ${pa === null ? a : b}`);
234
+ for (const part of ['major', 'minor', 'patch']) {
235
+ const c = compareNumeric(pa[part], pb[part]);
236
+ if (c !== 0)
237
+ return c;
169
238
  }
170
- return 0;
171
- }
172
- /** Semver prerelease identifiers: numeric before alphanumeric, numeric numerically, else lexically; shorter first. */
173
- function comparePrerelease(a, b) {
174
- const pa = a.split('.');
175
- const pb = b.split('.');
176
- const n = Math.max(pa.length, pb.length);
239
+ if (pa.prerelease.length === 0 || pb.prerelease.length === 0) {
240
+ if (pa.prerelease.length === pb.prerelease.length)
241
+ return 0;
242
+ return pa.prerelease.length === 0 ? 1 : -1;
243
+ }
244
+ const n = Math.max(pa.prerelease.length, pb.prerelease.length);
177
245
  for (let i = 0; i < n; i += 1) {
178
- const sa = pa[i];
179
- const sb = pb[i];
180
- if (sa === undefined)
246
+ const ia = pa.prerelease[i];
247
+ const ib = pb.prerelease[i];
248
+ if (ia === undefined)
181
249
  return -1;
182
- if (sb === undefined)
250
+ if (ib === undefined)
183
251
  return 1;
184
- const numA = /^\d+$/.test(sa);
185
- const numB = /^\d+$/.test(sb);
252
+ const numA = /^\d+$/.test(ia);
253
+ const numB = /^\d+$/.test(ib);
186
254
  if (numA && numB) {
187
- if (Number(sa) !== Number(sb))
188
- return Number(sa) < Number(sb) ? -1 : 1;
255
+ const c = compareNumeric(ia, ib);
256
+ if (c !== 0)
257
+ return c;
189
258
  continue;
190
259
  }
191
260
  if (numA !== numB)
192
261
  return numA ? -1 : 1;
193
- if (sa !== sb)
194
- return sa < sb ? -1 : 1;
262
+ if (ia !== ib)
263
+ return ia < ib ? -1 : 1;
195
264
  }
196
265
  return 0;
197
266
  }
198
267
  /**
199
- * Classify a plugin root: a git checkout when it carries `.git`; the installed plugin when it
200
- * sits under a `plugins/` directory (the marketplace cache or the hand-installed copy); anything
201
- * else is an explicit plugin-shaped directory (an unpacked tarball, a test fixture).
268
+ * The PICK order over cache version-directory names (all valid SemVer): the highest precedence
269
+ * first; for EQUAL precedence (names differing only in build metadata — `1.0.1` vs `1.0.1+build`)
270
+ * the plain release name (no build metadata) first, else the lexicographically smallest full name
271
+ * (`1.0.1+a` before `1.0.1+b`). A total order over distinct names, so the pick never depends on
272
+ * `readdir` or creation order (codex on #491).
273
+ */
274
+ export function cacheDirOrder(a, b) {
275
+ const precedence = compareSemver(b, a);
276
+ if (precedence !== 0)
277
+ return precedence;
278
+ if (a === b)
279
+ return 0;
280
+ const plainA = !a.includes('+');
281
+ const plainB = !b.includes('+');
282
+ if (plainA !== plainB)
283
+ return plainA ? -1 : 1;
284
+ return a < b ? -1 : 1;
285
+ }
286
+ /**
287
+ * Classify a plugin root by what it IS: a git checkout when it carries `.git`; the installer-managed
288
+ * copy when it is a `plugins/wicked-garden` directory (garden's `install.mjs` layout — design v3.6,
289
+ * so an explicit override aimed at that copy is recorded, and warned about, as the copy it is); the
290
+ * installed plugin when it sits anywhere else under a `plugins/` directory (the marketplace cache);
291
+ * anything else is an explicit plugin-shaped directory (an unpacked tarball, a test fixture).
202
292
  */
203
293
  export function classifySource(dir) {
204
294
  if (existsSync(join(dir, '.git')))
205
295
  return 'checkout';
206
- if (dir.split(sep).includes('plugins'))
207
- return 'claude-plugin-cache';
208
- return 'directory';
296
+ const segments = resolve(dir).split(sep);
297
+ if (!segments.includes('plugins'))
298
+ return 'directory';
299
+ const last = segments.length - 1;
300
+ if (segments[last] === PLUGIN_NAME && segments[last - 1] === 'plugins')
301
+ return 'installer-copy';
302
+ return 'claude-plugin-cache';
209
303
  }
210
304
  /** A `PluginSource` for an explicit plugin root, or `null` when it is not a plugin root. */
211
305
  export function pluginSourceAt(dir) {
@@ -216,30 +310,131 @@ export function pluginSourceAt(dir) {
216
310
  export function livePluginCacheDir(configDir) {
217
311
  return join(configDir, 'plugins', 'cache', PLUGIN_NAME, PLUGIN_NAME);
218
312
  }
313
+ /** The installer-managed copy (`npx wicked-installer install wicked-garden`, garden's `install.mjs`), for a config dir. */
314
+ export function installerCopyDir(configDir) {
315
+ return join(configDir, 'plugins', PLUGIN_NAME);
316
+ }
317
+ const CACHE_SEGMENTS = ['plugins', 'cache', PLUGIN_NAME, PLUGIN_NAME];
318
+ const COPY_SEGMENTS = ['plugins', PLUGIN_NAME];
219
319
  /**
220
- * Discover the live installed plugin: the explicit `WICKED_CREW_SKILLS_SOURCE` override, else the
221
- * highest version in the marketplace cache. NOTHING else — in particular not the hand-installed
222
- * `plugins/wicked-garden` copy (see the module header). `env`/`home` are injectable so tests never
223
- * read the developer's real config dir. Returns `null` when nothing is installed — the caller says
224
- * "install garden first" loudly.
320
+ * `noFollowEntry` from the once-resolved config dir, for the automatic tiers: a symlink among the
321
+ * walked segments becomes a `symlink` finding and the candidate is skipped — never followed; `null`
322
+ * also when the entry does not exist. Only a symlinked designated entry INSIDE a plugin root stays a
323
+ * thrown `PluginSourceSymlinkError` (`manifestVersionBelow`): that refusal is loud by design (codex
324
+ * round 6 on #480).
225
325
  */
226
- export function discoverLivePlugin(opts = {}) {
326
+ function noFollowBelow(root, segments, findings) {
327
+ try {
328
+ return noFollowEntry(root, segments);
329
+ }
330
+ catch (err) {
331
+ if (!(err instanceof PluginSourceSymlinkError))
332
+ throw err;
333
+ const path = join(root, ...err.entry.split('/'));
334
+ findings.push({ kind: 'symlink', path, message: `${path} is a symlink (-> ${err.target}); discovery never follows a link below the config dir — skipped` });
335
+ return null;
336
+ }
337
+ }
338
+ /**
339
+ * Tier (2) for ONE canonical config dir: the marketplace cache's version dirs, EVERY one judged
340
+ * (codex on #491): a name must parse as SemVer (else `non-semver-name`, ignored), the entry must be
341
+ * no link (else `symlink`, skipped), and its `plugin.json` — read below the canonical dir, never
342
+ * re-resolved — must exist with a `version` (else `no-manifest`) EQUAL to the name (else
343
+ * `version-mismatch`). The pick is the first agreeing dir in `cacheDirOrder` (highest precedence,
344
+ * documented tie-break); every other dir is still validated so a mismatch anywhere is a finding.
345
+ */
346
+ function cacheCandidate(root, findings, hooks) {
347
+ const cache = noFollowBelow(root, CACHE_SEGMENTS, findings);
348
+ if (cache === null || !lstatSync(cache).isDirectory())
349
+ return null;
350
+ const names = [];
351
+ for (const name of readdirSync(cache).sort()) {
352
+ const dir = join(cache, name);
353
+ if (parseSemver(name) === null) {
354
+ findings.push({ kind: 'non-semver-name', path: dir, message: `${dir}: the cache entry's name is not a valid SemVer version (semver.org); ignored` });
355
+ continue;
356
+ }
357
+ if (noFollowBelow(root, [...CACHE_SEGMENTS, name], findings) !== null)
358
+ names.push(name);
359
+ }
360
+ names.sort(cacheDirOrder);
361
+ let pick = null;
362
+ for (const name of names) {
363
+ const dir = join(cache, name);
364
+ hooks.beforeManifestRead?.(dir);
365
+ const version = manifestVersionBelow(dir); // a linked `.claude-plugin/` or `plugin.json` throws — loud, never a silent skip to another version
366
+ if (version === null) {
367
+ findings.push({ kind: 'no-manifest', path: dir, message: `${dir}: no .claude-plugin/plugin.json that parses with a version; skipped` });
368
+ continue;
369
+ }
370
+ if (version !== name) {
371
+ findings.push({ kind: 'version-mismatch', path: dir, message: `${dir}: plugin.json declares version ${version} but the directory is named ${name}; skipped` });
372
+ continue;
373
+ }
374
+ if (pick === null)
375
+ pick = { path: dir, kind: 'claude-plugin-cache', plugin_version: version };
376
+ }
377
+ return pick;
378
+ }
379
+ /** Tier (3) for ONE canonical config dir: its installer-managed copy — `plugins/wicked-garden` exists, is no link, and its `plugin.json` (read below the canonical dir) parses with a `version`. */
380
+ function copyCandidate(root, findings, hooks) {
381
+ const dir = noFollowBelow(root, COPY_SEGMENTS, findings);
382
+ if (dir === null || !lstatSync(dir).isDirectory())
383
+ return null;
384
+ hooks.beforeManifestRead?.(dir);
385
+ const version = manifestVersionBelow(dir);
386
+ if (version === null) {
387
+ findings.push({ kind: 'no-manifest', path: dir, message: `${dir} exists but has no .claude-plugin/plugin.json that parses with a version — not a plugin root; skipped` });
388
+ return null;
389
+ }
390
+ return { path: dir, kind: 'installer-copy', plugin_version: version };
391
+ }
392
+ /**
393
+ * Discover the installed plugin in the order design amendment v3.6 fixes (module header), with what
394
+ * was passed over: (1) the explicit `WICKED_CREW_SKILLS_SOURCE` override; (2) the FIRST config dir
395
+ * (as listed, `~/.claude` appended) holding a valid marketplace cache — the highest-precedence
396
+ * agreeing version dir inside it; (3) LAST resort, the first of those dirs holding a valid installer
397
+ * copy. ANY cache beats ANY copy. Each config dir is resolved exactly ONCE, here, and only its
398
+ * canonical root is handed to the tiers (two spellings of one dir walk once). `env`/`home` are
399
+ * injectable so tests never read the developer's real config dir. `source` is `null` when nothing is
400
+ * installed — the caller says "install garden first" loudly. A finding is reported once per entry
401
+ * even when both tiers meet it (a linked `plugins/`, say).
402
+ */
403
+ export function discoverLivePluginDetailed(opts = {}) {
227
404
  const env = opts.env ?? process.env;
228
405
  const home = opts.home ?? homedir();
406
+ const hooks = opts.hooks ?? {};
407
+ const findings = [];
229
408
  const override = env[SKILLS_SOURCE_ENV];
230
409
  if (override !== undefined && override !== '')
231
- return pluginSourceAt(override);
232
- const cache = livePluginCacheDir(claudeConfigDir(env, home));
233
- if (!existsSync(cache))
234
- return null;
235
- const versions = readdirSync(cache)
236
- .filter((entry) => pluginVersionAt(join(cache, entry)) !== null)
237
- .sort(compareVersions);
238
- const top = versions[versions.length - 1];
239
- if (top === undefined)
240
- return null;
241
- const dir = join(cache, top);
242
- return { path: dir, kind: 'claude-plugin-cache', plugin_version: pluginVersionAt(dir) ?? top };
410
+ return { source: pluginSourceAt(override), findings };
411
+ const roots = [];
412
+ for (const dir of claudeConfigDirs(env, home)) {
413
+ const root = realPluginRoot(dir); // the ONE realpath of a config dir in all of discovery
414
+ if (root !== null && !roots.includes(root))
415
+ roots.push(root);
416
+ }
417
+ let source = null;
418
+ for (const root of roots) {
419
+ source = cacheCandidate(root, findings, hooks);
420
+ if (source !== null)
421
+ break;
422
+ }
423
+ if (source === null) {
424
+ for (const root of roots) {
425
+ source = copyCandidate(root, findings, hooks);
426
+ if (source !== null)
427
+ break;
428
+ }
429
+ }
430
+ const seen = new Set();
431
+ return { source, findings: findings.filter((f) => !seen.has(`${f.kind}\0${f.path}`) && seen.add(`${f.kind}\0${f.path}`) !== undefined) };
432
+ }
433
+ /** `discoverLivePluginDetailed` answering the source alone; pass `findings` to collect what was passed over. */
434
+ export function discoverLivePlugin(opts = {}) {
435
+ const { source, findings } = discoverLivePluginDetailed(opts);
436
+ opts.findings?.push(...findings);
437
+ return source;
243
438
  }
244
439
  const GIT_TIMEOUT_MS = 5_000;
245
440
  /** The checkout's HEAD sha + dirty flag; `{null,false}` for a non-checkout source. */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-source.js","sourceRoot":"","sources":["../../src/skills/plugin-source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-source.js","sourceRoot":"","sources":["../../src/skills/plugin-source.ts"],"names":[],"mappings":"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"}
@@ -23,8 +23,8 @@ export declare class SkillsRootUnfencedError extends Error {
23
23
  }
24
24
  /**
25
25
  * The user-level CLI configuration directories wicked must never write (design v3.2 §1), for `home`:
26
- * codex, pi, copilot, opencode, Claude Code — the literal `~/.claude` AND the daemon's own
27
- * `CLAUDE_CONFIG_DIR` when it points elsewhere (that is the config dir the user's Claude reads).
26
+ * codex, pi, copilot, opencode, Claude Code — the literal `~/.claude` AND every dir the daemon's own
27
+ * `CLAUDE_CONFIG_DIR` lists when it points elsewhere (those are the config dirs the user's Claude reads).
28
28
  */
29
29
  export declare function userCliDirs(home?: string, env?: NodeJS.ProcessEnv): string[];
30
30
  /**
@@ -19,7 +19,7 @@
19
19
  import { lstatSync, realpathSync } from 'node:fs';
20
20
  import { homedir } from 'node:os';
21
21
  import { basename, dirname, join, resolve, sep } from 'node:path';
22
- import { claudeConfigDir } from './plugin-source.js';
22
+ import { claudeConfigDirs } from './plugin-source.js';
23
23
  /** The skills root would lie outside the state home or inside a user CLI directory — the daemon does not start. */
24
24
  export class SkillsRootUnfencedError extends Error {
25
25
  root;
@@ -32,8 +32,8 @@ export class SkillsRootUnfencedError extends Error {
32
32
  }
33
33
  /**
34
34
  * The user-level CLI configuration directories wicked must never write (design v3.2 §1), for `home`:
35
- * codex, pi, copilot, opencode, Claude Code — the literal `~/.claude` AND the daemon's own
36
- * `CLAUDE_CONFIG_DIR` when it points elsewhere (that is the config dir the user's Claude reads).
35
+ * codex, pi, copilot, opencode, Claude Code — the literal `~/.claude` AND every dir the daemon's own
36
+ * `CLAUDE_CONFIG_DIR` lists when it points elsewhere (those are the config dirs the user's Claude reads).
37
37
  */
38
38
  export function userCliDirs(home = homedir(), env = process.env) {
39
39
  const dirs = [
@@ -42,7 +42,7 @@ export function userCliDirs(home = homedir(), env = process.env) {
42
42
  join(home, '.copilot'),
43
43
  join(home, '.config', 'opencode'),
44
44
  join(home, '.claude'),
45
- claudeConfigDir(env, home),
45
+ ...claudeConfigDirs(env, home),
46
46
  ];
47
47
  return [...new Set(dirs.map((d) => resolve(d)))];
48
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"root-fence.js","sourceRoot":"","sources":["../../src/skills/root-fence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root-fence.js","sourceRoot":"","sources":["../../src/skills/root-fence.ts"],"names":[],"mappings":"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"}