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.
- package/dist/skills/plugin-source.d.ts +149 -32
- package/dist/skills/plugin-source.d.ts.map +1 -1
- package/dist/skills/plugin-source.js +303 -108
- package/dist/skills/plugin-source.js.map +1 -1
- package/dist/skills/root-fence.d.ts +2 -2
- package/dist/skills/root-fence.js +4 -4
- package/dist/skills/root-fence.js.map +1 -1
- package/dist/skills/runtime.d.ts +19 -2
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +82 -8
- package/dist/skills/runtime.js.map +1 -1
- package/dist/skills/store.d.ts +2 -2
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +30 -9
- package/dist/skills/store.js.map +1 -1
- package/endpoint-manifest.json +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Where the shipped baseline comes from: the
|
|
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).
|
|
7
|
-
*
|
|
8
|
-
* exact stale artifact the operator's `clis.toml` hack pointed workers at (12.28.1 while the
|
|
9
|
-
* cache was 12.32.0 — design v3 §"Verified mechanics")
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
*
|
|
@@ -36,8 +73,14 @@ export interface PluginSource {
|
|
|
36
73
|
/** `version` from the plugin manifest. */
|
|
37
74
|
plugin_version: string;
|
|
38
75
|
}
|
|
39
|
-
/**
|
|
40
|
-
|
|
76
|
+
/**
|
|
77
|
+
* The Claude Code config dirs discovery walks, IN ORDER: every non-empty entry of `CLAUDE_CONFIG_DIR`
|
|
78
|
+
* (it may list several, separated by the platform path delimiter) as listed, then the literal
|
|
79
|
+
* `~/.claude` appended once unless already listed — the default when the variable is unset, and the
|
|
80
|
+
* dir garden's `install.mjs` hard-codes (design v3.6; codex on #491). Spelled as given (the walk
|
|
81
|
+
* resolves each dir once); a dir listed twice is walked once.
|
|
82
|
+
*/
|
|
83
|
+
export declare function claudeConfigDirs(env?: NodeJS.ProcessEnv, home?: string): string[];
|
|
41
84
|
/**
|
|
42
85
|
* A designated entry of the plugin source is a symlink — the seed/refresh is refused by name and
|
|
43
86
|
* nothing is copied (module header). `entry` is the plugin-relative POSIX path of the link.
|
|
@@ -61,42 +104,116 @@ export declare function realPluginRoot(dir: string): string | null;
|
|
|
61
104
|
*/
|
|
62
105
|
export declare function noFollowEntry(root: string, segments: ReadonlyArray<string>, sourceSpelling?: string): string | null;
|
|
63
106
|
/**
|
|
64
|
-
* The plugin manifest's `version` at `dir`, or `null` when `dir` is not a plugin root
|
|
65
|
-
*
|
|
66
|
-
*
|
|
107
|
+
* The plugin manifest's `version` at `dir`, or `null` when `dir` is not a plugin root — the root
|
|
108
|
+
* resolved once (`realPluginRoot`), then `manifestVersionBelow`. For the explicit override and
|
|
109
|
+
* `pluginSourceAt`; the automatic tiers never call this (they resolve the CONFIG dir once and read
|
|
110
|
+
* below the canonical candidate directly).
|
|
67
111
|
*/
|
|
68
112
|
export declare function pluginVersionAt(dir: string): string | null;
|
|
69
113
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
114
|
+
* The manifest `version` below an already-canonical plugin dir, or `null` when there is no
|
|
115
|
+
* `.claude-plugin/plugin.json` that PARSES with a non-empty string `version` — missing, not a
|
|
116
|
+
* regular file, not JSON, not an object, or versionless are all "not a plugin root" (design v3.6:
|
|
117
|
+
* "accepted only when its plugin.json parses with a version"; Copilot on #491: one corrupt manifest
|
|
118
|
+
* in a cache must skip that candidate, not take discovery down). NO-FOLLOW below the root and no
|
|
119
|
+
* re-resolution of the root itself: a symlinked `.claude-plugin/` or `plugin.json` throws
|
|
120
|
+
* `PluginSourceSymlinkError` — never a version read through a link (codex round 6) — and an I/O
|
|
121
|
+
* error reading the file stays an error. `spelling` is the root as the caller spelled it, for the
|
|
122
|
+
* symlink error.
|
|
123
|
+
*/
|
|
124
|
+
export declare function manifestVersionBelow(root: string, spelling?: string): string | null;
|
|
125
|
+
/**
|
|
126
|
+
* A parsed SemVer 2.0.0 version (semver.org). Numeric identifiers are kept as DIGIT STRINGS, never
|
|
127
|
+
* converted to `number`: above `Number.MAX_SAFE_INTEGER` adjacent values would collapse into one
|
|
128
|
+
* (`9007199254740992` == `9007199254740993` as doubles) and the tie-break would pick the lower dir
|
|
129
|
+
* (codex on #491). SemVer forbids leading zeros, so digit strings compare losslessly by length,
|
|
130
|
+
* then lexically (`compareNumeric`).
|
|
131
|
+
*/
|
|
132
|
+
export interface Semver {
|
|
133
|
+
major: string;
|
|
134
|
+
minor: string;
|
|
135
|
+
patch: string;
|
|
136
|
+
/** Dot-separated pre-release identifiers; empty for a release. */
|
|
137
|
+
prerelease: string[];
|
|
138
|
+
/** Build metadata after `+`, or `null`; ignored by precedence. */
|
|
139
|
+
build: string | null;
|
|
140
|
+
}
|
|
141
|
+
/** Parse a SemVer version, or `null` when the string is not one by the official grammar. */
|
|
142
|
+
export declare function parseSemver(v: string): Semver | null;
|
|
143
|
+
/**
|
|
144
|
+
* SemVer PRECEDENCE (semver.org §11): major, minor, patch numerically; a pre-release version has
|
|
145
|
+
* LOWER precedence than its release; pre-release identifiers compare left to right — numeric ones
|
|
146
|
+
* numerically (losslessly — digit strings, never `number`), numeric before alphanumeric,
|
|
147
|
+
* alphanumeric ones in ASCII order, a shorter set lower when every preceding identifier is equal.
|
|
148
|
+
* Build metadata is IGNORED: `1.0.1` and `1.0.1+build`
|
|
149
|
+
* have equal precedence (0). Throws for a string that is not a SemVer version — callers validate
|
|
150
|
+
* names first (`parseSemver`).
|
|
78
151
|
*/
|
|
79
|
-
export declare function
|
|
152
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
80
153
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
154
|
+
* The PICK order over cache version-directory names (all valid SemVer): the highest precedence
|
|
155
|
+
* first; for EQUAL precedence (names differing only in build metadata — `1.0.1` vs `1.0.1+build`)
|
|
156
|
+
* the plain release name (no build metadata) first, else the lexicographically smallest full name
|
|
157
|
+
* (`1.0.1+a` before `1.0.1+b`). A total order over distinct names, so the pick never depends on
|
|
158
|
+
* `readdir` or creation order (codex on #491).
|
|
159
|
+
*/
|
|
160
|
+
export declare function cacheDirOrder(a: string, b: string): number;
|
|
161
|
+
/**
|
|
162
|
+
* Classify a plugin root by what it IS: a git checkout when it carries `.git`; the installer-managed
|
|
163
|
+
* copy when it is a `plugins/wicked-garden` directory (garden's `install.mjs` layout — design v3.6,
|
|
164
|
+
* so an explicit override aimed at that copy is recorded, and warned about, as the copy it is); the
|
|
165
|
+
* installed plugin when it sits anywhere else under a `plugins/` directory (the marketplace cache);
|
|
166
|
+
* anything else is an explicit plugin-shaped directory (an unpacked tarball, a test fixture).
|
|
84
167
|
*/
|
|
85
168
|
export declare function classifySource(dir: string): SkillSourceKind;
|
|
86
169
|
/** A `PluginSource` for an explicit plugin root, or `null` when it is not a plugin root. */
|
|
87
170
|
export declare function pluginSourceAt(dir: string): PluginSource | null;
|
|
88
171
|
/** The marketplace cache dir the live plugin versions live under, for a config dir. */
|
|
89
172
|
export declare function livePluginCacheDir(configDir: string): string;
|
|
173
|
+
/** The installer-managed copy (`npx wicked-installer install wicked-garden`, garden's `install.mjs`), for a config dir. */
|
|
174
|
+
export declare function installerCopyDir(configDir: string): string;
|
|
175
|
+
/** Why discovery passed over something that EXISTS (an absent path is never a finding) — logged by the daemon, asserted by tests. */
|
|
176
|
+
export type DiscoveryFindingKind = 'symlink' | 'non-semver-name' | 'version-mismatch' | 'no-manifest';
|
|
177
|
+
export interface DiscoveryFinding {
|
|
178
|
+
kind: DiscoveryFindingKind;
|
|
179
|
+
/** The entry judged — the CANONICAL path (below the once-resolved config dir). */
|
|
180
|
+
path: string;
|
|
181
|
+
message: string;
|
|
182
|
+
}
|
|
183
|
+
/** What discovery answered and what it passed over on the way (design v3.6; codex on #491). */
|
|
184
|
+
export interface Discovery {
|
|
185
|
+
source: PluginSource | null;
|
|
186
|
+
findings: DiscoveryFinding[];
|
|
187
|
+
}
|
|
90
188
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* read the developer's real config dir. Returns `null` when nothing is installed — the caller says
|
|
95
|
-
* "install garden first" loudly.
|
|
189
|
+
* TEST SEAM for the TOCTOU probe (codex confirmation pass on #491): called with the canonical
|
|
190
|
+
* candidate dir just before its manifest is read, so a test can retarget the config-dir link
|
|
191
|
+
* mid-walk and prove the retargeted manifest is never read. The daemon passes nothing.
|
|
96
192
|
*/
|
|
97
|
-
export
|
|
193
|
+
export interface DiscoveryHooks {
|
|
194
|
+
beforeManifestRead?: (canonicalDir: string) => void;
|
|
195
|
+
}
|
|
196
|
+
export interface DiscoverOptions {
|
|
98
197
|
env?: NodeJS.ProcessEnv;
|
|
99
198
|
home?: string;
|
|
199
|
+
/** Test seam — see `DiscoveryHooks`. */
|
|
200
|
+
hooks?: DiscoveryHooks;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Discover the installed plugin in the order design amendment v3.6 fixes (module header), with what
|
|
204
|
+
* was passed over: (1) the explicit `WICKED_CREW_SKILLS_SOURCE` override; (2) the FIRST config dir
|
|
205
|
+
* (as listed, `~/.claude` appended) holding a valid marketplace cache — the highest-precedence
|
|
206
|
+
* agreeing version dir inside it; (3) LAST resort, the first of those dirs holding a valid installer
|
|
207
|
+
* copy. ANY cache beats ANY copy. Each config dir is resolved exactly ONCE, here, and only its
|
|
208
|
+
* canonical root is handed to the tiers (two spellings of one dir walk once). `env`/`home` are
|
|
209
|
+
* injectable so tests never read the developer's real config dir. `source` is `null` when nothing is
|
|
210
|
+
* installed — the caller says "install garden first" loudly. A finding is reported once per entry
|
|
211
|
+
* even when both tiers meet it (a linked `plugins/`, say).
|
|
212
|
+
*/
|
|
213
|
+
export declare function discoverLivePluginDetailed(opts?: DiscoverOptions): Discovery;
|
|
214
|
+
/** `discoverLivePluginDetailed` answering the source alone; pass `findings` to collect what was passed over. */
|
|
215
|
+
export declare function discoverLivePlugin(opts?: DiscoverOptions & {
|
|
216
|
+
findings?: DiscoveryFinding[];
|
|
100
217
|
}): PluginSource | null;
|
|
101
218
|
export interface GitState {
|
|
102
219
|
git_sha: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-source.d.ts","sourceRoot":"","sources":["../../src/skills/plugin-source.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-source.d.ts","sourceRoot":"","sources":["../../src/skills/plugin-source.ts"],"names":[],"mappings":"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"}
|