@shrkcrft/packs 0.1.0-alpha.1 → 0.1.0-alpha.11
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/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
SharkCraft pack discovery + loading: scan node_modules for sharkcraft manifests and surface contributions.
|
|
4
4
|
|
|
5
|
-
Part of [SharkCraft](https://github.com/
|
|
5
|
+
Part of [SharkCraft](https://github.com/shrkcrft/sharkcraft) — a deterministic, local-first toolkit that gives AI coding agents durable project context. See the main repo for documentation, examples, and the `shrk` CLI.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -17,12 +17,27 @@ export interface DiscoverPacksOptions {
|
|
|
17
17
|
verifySignatures?: boolean;
|
|
18
18
|
/** Override the secret used for signature verification. */
|
|
19
19
|
packSecret?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Skip the process-level discovery cache. The cache is keyed by
|
|
22
|
+
* projectRoot + lockfile mtime, so installs/upgrades invalidate it
|
|
23
|
+
* automatically. Pass `noCache: true` to force a fresh scan (e.g.
|
|
24
|
+
* after editing a manifest in place during a long-running process).
|
|
25
|
+
*/
|
|
26
|
+
noCache?: boolean;
|
|
20
27
|
}
|
|
28
|
+
/** Clear the process-level pack-discovery cache. Tests use this. */
|
|
29
|
+
export declare function clearPackDiscoveryCache(): void;
|
|
21
30
|
/**
|
|
22
31
|
* Walk `<projectRoot>/node_modules/` (+ any extra roots) and surface every
|
|
23
32
|
* package whose `package.json` declares a `sharkcraft` field. For each, load
|
|
24
33
|
* the manifest and run validatePackManifest. Returns a structured discovery
|
|
25
34
|
* result; never throws on individual pack failures.
|
|
35
|
+
*
|
|
36
|
+
* The result is cached at process-level keyed by projectRoot + lock-file
|
|
37
|
+
* mtime, so repeated calls within a single CLI invocation (or MCP server
|
|
38
|
+
* session) skip the node_modules walk. The cache invalidates automatically
|
|
39
|
+
* on any install/upgrade and is bypassed entirely when signature
|
|
40
|
+
* verification is requested or extra roots are supplied.
|
|
26
41
|
*/
|
|
27
42
|
export declare function discoverPacks(options: DiscoverPacksOptions): Promise<IPackDiscoveryResult>;
|
|
28
43
|
//# sourceMappingURL=discover-packs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover-packs.d.ts","sourceRoot":"","sources":["../../src/discovery/discover-packs.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAmB,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAqHxF,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"discover-packs.d.ts","sourceRoot":"","sources":["../../src/discovery/discover-packs.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAmB,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAqHxF,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmDD,oEAAoE;AACpE,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAqJhG"}
|
|
@@ -6,7 +6,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
-
import { existsSync, readdirSync, readFileSync, realpathSync } from 'node:fs';
|
|
9
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
10
10
|
import * as nodePath from 'node:path';
|
|
11
11
|
import { pathToFileURL } from 'node:url';
|
|
12
12
|
import { PACK_SECRET_ENV, validatePackManifest, verifyPackManifest, } from '@shrkcrft/plugin-api';
|
|
@@ -120,16 +120,72 @@ function* scanNodeModules(nodeModulesPath) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
+
const discoveryCache = new Map();
|
|
124
|
+
function lockFingerprintFor(projectRoot) {
|
|
125
|
+
// Try each known lock file in order; first existing one wins. mtimeMs
|
|
126
|
+
// changes every install, so it's a tight invalidation signal.
|
|
127
|
+
const candidates = ['bun.lockb', 'bun.lock', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'];
|
|
128
|
+
for (const name of candidates) {
|
|
129
|
+
const p = nodePath.join(projectRoot, name);
|
|
130
|
+
if (existsSync(p)) {
|
|
131
|
+
try {
|
|
132
|
+
const st = statSync(p);
|
|
133
|
+
return `${name}:${st.mtimeMs}:${st.size}`;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// fall through and try the next candidate
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// No lock file — also cache by node_modules mtime as a fallback.
|
|
141
|
+
const nm = nodePath.join(projectRoot, 'node_modules');
|
|
142
|
+
if (existsSync(nm)) {
|
|
143
|
+
try {
|
|
144
|
+
const st = statSync(nm);
|
|
145
|
+
return `node_modules:${st.mtimeMs}`;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// ignore
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return 'none';
|
|
152
|
+
}
|
|
153
|
+
function cacheKeyOf(key) {
|
|
154
|
+
return `${key.projectRoot}::${key.lockFingerprint}`;
|
|
155
|
+
}
|
|
156
|
+
/** Clear the process-level pack-discovery cache. Tests use this. */
|
|
157
|
+
export function clearPackDiscoveryCache() {
|
|
158
|
+
discoveryCache.clear();
|
|
159
|
+
}
|
|
123
160
|
/**
|
|
124
161
|
* Walk `<projectRoot>/node_modules/` (+ any extra roots) and surface every
|
|
125
162
|
* package whose `package.json` declares a `sharkcraft` field. For each, load
|
|
126
163
|
* the manifest and run validatePackManifest. Returns a structured discovery
|
|
127
164
|
* result; never throws on individual pack failures.
|
|
165
|
+
*
|
|
166
|
+
* The result is cached at process-level keyed by projectRoot + lock-file
|
|
167
|
+
* mtime, so repeated calls within a single CLI invocation (or MCP server
|
|
168
|
+
* session) skip the node_modules walk. The cache invalidates automatically
|
|
169
|
+
* on any install/upgrade and is bypassed entirely when signature
|
|
170
|
+
* verification is requested or extra roots are supplied.
|
|
128
171
|
*/
|
|
129
172
|
export async function discoverPacks(options) {
|
|
130
173
|
const projectRoot = nodePath.resolve(options.projectRoot);
|
|
131
174
|
const nodeModulesPath = nodePath.join(projectRoot, 'node_modules');
|
|
132
175
|
const nodeModulesExists = existsSync(nodeModulesPath);
|
|
176
|
+
// Cache lookup — only when the caller doesn't disable it AND when no
|
|
177
|
+
// signature-verification or extra-root option might change the answer.
|
|
178
|
+
const cacheable = !options.noCache &&
|
|
179
|
+
!options.verifySignatures &&
|
|
180
|
+
(!options.extraRoots || options.extraRoots.length === 0);
|
|
181
|
+
const cacheKey = cacheable
|
|
182
|
+
? cacheKeyOf({ projectRoot, lockFingerprint: lockFingerprintFor(projectRoot) })
|
|
183
|
+
: null;
|
|
184
|
+
if (cacheKey) {
|
|
185
|
+
const cached = discoveryCache.get(cacheKey);
|
|
186
|
+
if (cached)
|
|
187
|
+
return cached;
|
|
188
|
+
}
|
|
133
189
|
const result = {
|
|
134
190
|
projectRoot,
|
|
135
191
|
nodeModulesPath,
|
|
@@ -247,5 +303,8 @@ export async function discoverPacks(options) {
|
|
|
247
303
|
}
|
|
248
304
|
}
|
|
249
305
|
}
|
|
306
|
+
if (cacheKey) {
|
|
307
|
+
discoveryCache.set(cacheKey, result);
|
|
308
|
+
}
|
|
250
309
|
return result;
|
|
251
310
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shrkcrft/packs",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"description": "SharkCraft pack discovery + loading: scan node_modules for sharkcraft manifests and surface contributions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
9
|
+
"types": "./dist/index.d.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
|
+
"bun": "./src/index.ts",
|
|
13
14
|
"import": "./dist/index.js",
|
|
14
15
|
"default": "./dist/index.js"
|
|
15
16
|
}
|
|
@@ -21,12 +22,12 @@
|
|
|
21
22
|
],
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|
|
24
|
-
"url": "git+https://github.com/
|
|
25
|
+
"url": "git+https://github.com/shrkcrft/sharkcraft.git",
|
|
25
26
|
"directory": "packages/packs"
|
|
26
27
|
},
|
|
27
|
-
"homepage": "https://github.com/
|
|
28
|
+
"homepage": "https://github.com/shrkcrft/sharkcraft",
|
|
28
29
|
"bugs": {
|
|
29
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/shrkcrft/sharkcraft/issues"
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
|
32
33
|
"sharkcraft",
|
|
@@ -41,8 +42,8 @@
|
|
|
41
42
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
45
|
-
"@shrkcrft/plugin-api": "^0.1.0-alpha.
|
|
45
|
+
"@shrkcrft/core": "^0.1.0-alpha.11",
|
|
46
|
+
"@shrkcrft/plugin-api": "^0.1.0-alpha.11"
|
|
46
47
|
},
|
|
47
48
|
"publishConfig": {
|
|
48
49
|
"access": "public"
|