@stigmer/plugin-package 3.18.0 → 3.18.1-dev.20260919070736
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/client/presentation.d.ts +19 -0
- package/client/presentation.d.ts.map +1 -0
- package/client/presentation.js +44 -0
- package/client/presentation.js.map +1 -0
- package/client.d.ts +3 -0
- package/client.d.ts.map +1 -1
- package/client.js +3 -0
- package/client.js.map +1 -1
- package/detect.d.ts +7 -0
- package/detect.d.ts.map +1 -1
- package/detect.js +7 -0
- package/detect.js.map +1 -1
- package/files.d.ts +7 -0
- package/files.d.ts.map +1 -1
- package/files.js +7 -0
- package/files.js.map +1 -1
- package/index.d.ts +3 -1
- package/index.d.ts.map +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/presentation.d.ts +52 -0
- package/presentation.d.ts.map +1 -0
- package/presentation.js +151 -0
- package/presentation.js.map +1 -0
- package/src/__tests__/presentation.test.ts +161 -0
- package/src/client/presentation.ts +47 -0
- package/src/client.ts +3 -0
- package/src/detect.ts +8 -0
- package/src/files.ts +7 -0
- package/src/index.ts +3 -1
- package/src/presentation.ts +165 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plugin's presentation from a tree whose bytes cost something to obtain:
|
|
3
|
+
* the lazy twin of `readPluginPresentation`, as `preparePluginFromTree` is
|
|
4
|
+
* the lazy twin of the full read.
|
|
5
|
+
*
|
|
6
|
+
* A storefront lists a catalogue from one file and then shows a card per
|
|
7
|
+
* entry; the face on each card is in that entry's manifest, one small file
|
|
8
|
+
* in a directory the client has listed but not read. This reads exactly the
|
|
9
|
+
* manifest paths the listing shows (one, rarely two) and nothing else, then
|
|
10
|
+
* hands a `PluginFiles` whose `read` answers for those paths alone to the
|
|
11
|
+
* pure reader. A manifest that cannot be fetched contributes nothing, the
|
|
12
|
+
* pure reader's own rule for a manifest that cannot be parsed: a card is
|
|
13
|
+
* never refused, it is drawn with what arrived.
|
|
14
|
+
*/
|
|
15
|
+
import { type PluginPresentation } from "../presentation.js";
|
|
16
|
+
import type { LazyCandidate } from "./prepare.js";
|
|
17
|
+
/** The presentation of the plugin whose files `candidates` list, reading only its manifests. */
|
|
18
|
+
export declare function readPluginPresentationFromTree(candidates: readonly LazyCandidate[]): Promise<PluginPresentation>;
|
|
19
|
+
//# sourceMappingURL=presentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../src/client/presentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,KAAK,kBAAkB,EAA0B,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,gGAAgG;AAChG,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuBtH"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plugin's presentation from a tree whose bytes cost something to obtain:
|
|
3
|
+
* the lazy twin of `readPluginPresentation`, as `preparePluginFromTree` is
|
|
4
|
+
* the lazy twin of the full read.
|
|
5
|
+
*
|
|
6
|
+
* A storefront lists a catalogue from one file and then shows a card per
|
|
7
|
+
* entry; the face on each card is in that entry's manifest, one small file
|
|
8
|
+
* in a directory the client has listed but not read. This reads exactly the
|
|
9
|
+
* manifest paths the listing shows (one, rarely two) and nothing else, then
|
|
10
|
+
* hands a `PluginFiles` whose `read` answers for those paths alone to the
|
|
11
|
+
* pure reader. A manifest that cannot be fetched contributes nothing, the
|
|
12
|
+
* pure reader's own rule for a manifest that cannot be parsed: a card is
|
|
13
|
+
* never refused, it is drawn with what arrived.
|
|
14
|
+
*/
|
|
15
|
+
import { comparePaths } from "../files.js";
|
|
16
|
+
import { MANIFEST_LOCATIONS } from "../messages.js";
|
|
17
|
+
import { readPluginPresentation } from "../presentation.js";
|
|
18
|
+
const MANIFEST_PATHS = new Set(Object.values(MANIFEST_LOCATIONS));
|
|
19
|
+
/** The presentation of the plugin whose files `candidates` list, reading only its manifests. */
|
|
20
|
+
export async function readPluginPresentationFromTree(candidates) {
|
|
21
|
+
const contents = new Map();
|
|
22
|
+
await Promise.all(candidates
|
|
23
|
+
.filter((candidate) => MANIFEST_PATHS.has(candidate.path))
|
|
24
|
+
.map(async (candidate) => {
|
|
25
|
+
try {
|
|
26
|
+
contents.set(candidate.path, await candidate.read());
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Unfetchable is unreadable: the pure reader skips a manifest it cannot open.
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
const files = {
|
|
33
|
+
// `PluginFiles` promises a sorted listing; a host's tree order is its own.
|
|
34
|
+
entries: candidates.map(({ path, size }) => ({ path, size })).sort((a, b) => comparePaths(a.path, b.path)),
|
|
35
|
+
read: (path) => {
|
|
36
|
+
const bytes = contents.get(path);
|
|
37
|
+
if (bytes === undefined)
|
|
38
|
+
throw new Error(`plugin file '${path}' was not fetched for presentation`);
|
|
39
|
+
return bytes;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return readPluginPresentation(files);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=presentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.js","sourceRoot":"","sources":["../../src/client/presentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAoB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAA2B,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGrF,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAEvF,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,UAAoC;IACvF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC/C,MAAM,OAAO,CAAC,GAAG,CACf,UAAU;SACP,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACzD,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,8EAA8E;QAChF,CAAC;IACH,CAAC,CAAC,CACL,CAAC;IACF,MAAM,KAAK,GAAgB;QACzB,2EAA2E;QAC3E,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1G,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,oCAAoC,CAAC,CAAC;YACnG,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IACF,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
package/client.d.ts
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* the SHA-256 the server records;
|
|
18
18
|
* - the preparation (`prepare.ts`): select, read, refuse, archive, digest,
|
|
19
19
|
* once, for a tree on disk, on a host, or in a browser's memory;
|
|
20
|
+
* - the presentation (`presentation.ts`): a card's face from a listed
|
|
21
|
+
* tree, reading the entry's manifest and nothing else;
|
|
20
22
|
* - the grammars (`refs.ts`): an install ref and a GitHub marketplace
|
|
21
23
|
* source, with their refusal sentences;
|
|
22
24
|
* - the built-in sources (`builtin.ts`): the official catalogue and the
|
|
@@ -37,6 +39,7 @@ export { MatchResult, type Pattern, parsePattern } from "./client/ignore/pattern
|
|
|
37
39
|
export { type CandidateFile, type PluginSelection, type SelectPluginFilesOptions, type SelectionStats, IGNORE_FILE_NAMES, compareWalkOrder, selectPluginFiles, } from "./client/select.js";
|
|
38
40
|
export { DETERMINISTIC_ZIP_MTIME, archivePlugin, digestArchive } from "./client/archive.js";
|
|
39
41
|
export { type LazyCandidate, type PrepareArchiveOutcome, type PrepareFromTreeOptions, type PreparePluginOutcome, type PreparedPlugin, preparePluginArchive, preparePluginFromTree, } from "./client/prepare.js";
|
|
42
|
+
export { readPluginPresentationFromTree } from "./client/presentation.js";
|
|
40
43
|
export { type BuiltInMarketplace, BUILT_IN_MARKETPLACES, builtInSourceRefusal, isBuiltInMarketplaceName, } from "./client/builtin.js";
|
|
41
44
|
export { isReleaseVersion } from "./client/release.js";
|
|
42
45
|
export { rerootSingleDirectory, stripDirectoryPrefix } from "./client/reroot.js";
|
package/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,OAAO,EACP,MAAM,EACN,WAAW,EACX,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EACL,KAAK,kBAAkB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
|
package/client.js
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* the SHA-256 the server records;
|
|
18
18
|
* - the preparation (`prepare.ts`): select, read, refuse, archive, digest,
|
|
19
19
|
* once, for a tree on disk, on a host, or in a browser's memory;
|
|
20
|
+
* - the presentation (`presentation.ts`): a card's face from a listed
|
|
21
|
+
* tree, reading the entry's manifest and nothing else;
|
|
20
22
|
* - the grammars (`refs.ts`): an install ref and a GitHub marketplace
|
|
21
23
|
* source, with their refusal sentences;
|
|
22
24
|
* - the built-in sources (`builtin.ts`): the official catalogue and the
|
|
@@ -37,6 +39,7 @@ export { MatchResult, parsePattern } from "./client/ignore/pattern.js";
|
|
|
37
39
|
export { IGNORE_FILE_NAMES, compareWalkOrder, selectPluginFiles, } from "./client/select.js";
|
|
38
40
|
export { DETERMINISTIC_ZIP_MTIME, archivePlugin, digestArchive } from "./client/archive.js";
|
|
39
41
|
export { preparePluginArchive, preparePluginFromTree, } from "./client/prepare.js";
|
|
42
|
+
export { readPluginPresentationFromTree } from "./client/presentation.js";
|
|
40
43
|
export { BUILT_IN_MARKETPLACES, builtInSourceRefusal, isBuiltInMarketplaceName, } from "./client/builtin.js";
|
|
41
44
|
export { isReleaseVersion } from "./client/release.js";
|
|
42
45
|
export { rerootSingleDirectory, stripDirectoryPrefix } from "./client/reroot.js";
|
package/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAGL,OAAO,EACP,MAAM,EACN,WAAW,EACX,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,GACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAgB,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,EAKL,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAML,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAEL,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAKL,mBAAmB,EACnB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
|
package/detect.d.ts
CHANGED
|
@@ -30,6 +30,13 @@ import { type Findings } from "./messages.js";
|
|
|
30
30
|
import type { PluginDialect } from "./types.js";
|
|
31
31
|
/** The open format's `mcp.json`, a fixed location. */
|
|
32
32
|
export declare const OPEN_MCP_CONFIG = "mcp.json";
|
|
33
|
+
/**
|
|
34
|
+
* Every manifest location in the order that names a plugin: the root
|
|
35
|
+
* manifest, then the vendors. The one precedence the reader applies,
|
|
36
|
+
* exported so a partial read (`presentation.ts`) cannot rank the manifests
|
|
37
|
+
* differently from the full one.
|
|
38
|
+
*/
|
|
39
|
+
export declare const MANIFEST_PRECEDENCE: readonly PluginDialect[];
|
|
33
40
|
export interface ManifestSet {
|
|
34
41
|
/** The dialect that gave the plugin its identity. */
|
|
35
42
|
readonly dialect: PluginDialect;
|
package/detect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,KAAK,QAAQ,EAAsB,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sDAAsD;AACtD,eAAO,MAAM,eAAe,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,KAAK,QAAQ,EAAsB,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sDAAsD;AACtD,eAAO,MAAM,eAAe,aAAa,CAAC;AAK1C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,aAAa,EAA4C,CAAC;AAKrG,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;CACjD;AAED,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAIlE;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAmCnG;AAyDD,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
package/detect.js
CHANGED
|
@@ -34,6 +34,13 @@ import { MANIFEST_LOCATIONS } from "./messages.js";
|
|
|
34
34
|
export const OPEN_MCP_CONFIG = "mcp.json";
|
|
35
35
|
/** The vendor precedence when no root manifest exists. */
|
|
36
36
|
const VENDOR_PRECEDENCE = ["claude", "cursor", "codex"];
|
|
37
|
+
/**
|
|
38
|
+
* Every manifest location in the order that names a plugin: the root
|
|
39
|
+
* manifest, then the vendors. The one precedence the reader applies,
|
|
40
|
+
* exported so a partial read (`presentation.ts`) cannot rank the manifests
|
|
41
|
+
* differently from the full one.
|
|
42
|
+
*/
|
|
43
|
+
export const MANIFEST_PRECEDENCE = ["agent-plugins", ...VENDOR_PRECEDENCE];
|
|
37
44
|
const NAME_MAX_LENGTH = 64;
|
|
38
45
|
const NAME_PATTERN = /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/;
|
|
39
46
|
/** True when the directory holds any of the four manifests; the CLI's routing test. */
|
package/detect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
package/files.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export declare const PLUGIN_DOCUMENT_LIMITS: {
|
|
|
54
54
|
readonly subAgent: number;
|
|
55
55
|
/** A document under `ai.stigmer/`: a resource YAML. */
|
|
56
56
|
readonly overlay: number;
|
|
57
|
+
/**
|
|
58
|
+
* A plugin's logo, the image a storefront card shows. Checked from the
|
|
59
|
+
* listing's declared size before a client hands the file's URL to an
|
|
60
|
+
* `<img>`; measured across the three vendors' catalogues on 2026-09-18,
|
|
61
|
+
* the largest published logo is 361 KB and the median 7.5 KB.
|
|
62
|
+
*/
|
|
63
|
+
readonly logo: number;
|
|
57
64
|
/**
|
|
58
65
|
* A marketplace file in any dialect. The largest public catalogue
|
|
59
66
|
* (`cursor/plugins`, 79 entries with descriptions) is under 32 KB; the cap
|
package/files.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,oCAAoC;IACpC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;IACjC,8EAA8E;;IAE9E,iCAAiC;;IAEjC;;;;OAIG;;IAEH,yEAAyE;;IAEzE,uDAAuD;;IAEvD;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,sBAAsB,CAAC;AAQtE,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG,WAAW,CAkBhG;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,0HAA0H;AAC1H,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,uBAAuB,CAAC,CAAA;CAAE,CAAC;AAIzI;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAQtE;AAED,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,kDAAkD;AAClD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAGd,QAAQ,CAAC,KAAK,EAAE,WAAW;IAFvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;gBAEzC,KAAK,EAAE,WAAW;IAIvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIhD,wGAAwG;IACxG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAM1C,qDAAqD;IACrD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMjC,6EAA6E;IAC7E,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAYhD,0DAA0D;IAC1D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;CAU3C"}
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,oCAAoC;IACpC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;IACjC,8EAA8E;;IAE9E,iCAAiC;;IAEjC;;;;OAIG;;IAEH,yEAAyE;;IAEzE,uDAAuD;;IAEvD;;;;;OAKG;;IAEH;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,sBAAsB,CAAC;AAQtE,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG,WAAW,CAkBhG;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,0HAA0H;AAC1H,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,uBAAuB,CAAC,CAAA;CAAE,CAAC;AAIzI;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAQtE;AAED,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,kDAAkD;AAClD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAGd,QAAQ,CAAC,KAAK,EAAE,WAAW;IAFvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;gBAEzC,KAAK,EAAE,WAAW;IAIvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIhD,wGAAwG;IACxG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAM1C,qDAAqD;IACrD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMjC,6EAA6E;IAC7E,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAYhD,0DAA0D;IAC1D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;CAU3C"}
|
package/files.js
CHANGED
|
@@ -41,6 +41,13 @@ export const PLUGIN_DOCUMENT_LIMITS = {
|
|
|
41
41
|
subAgent: 1024 * 1024,
|
|
42
42
|
/** A document under `ai.stigmer/`: a resource YAML. */
|
|
43
43
|
overlay: 1024 * 1024,
|
|
44
|
+
/**
|
|
45
|
+
* A plugin's logo, the image a storefront card shows. Checked from the
|
|
46
|
+
* listing's declared size before a client hands the file's URL to an
|
|
47
|
+
* `<img>`; measured across the three vendors' catalogues on 2026-09-18,
|
|
48
|
+
* the largest published logo is 361 KB and the median 7.5 KB.
|
|
49
|
+
*/
|
|
50
|
+
logo: 1024 * 1024,
|
|
44
51
|
/**
|
|
45
52
|
* A marketplace file in any dialect. The largest public catalogue
|
|
46
53
|
* (`cursor/plugins`, 79 entries with descriptions) is under 32 KB; the cap
|
package/files.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* `@stigmer/plugin-package`: the public surface.
|
|
3
3
|
*
|
|
4
4
|
* `readPluginPackage` reads one plugin; `readMarketplace` reads a catalogue
|
|
5
|
-
* of them
|
|
5
|
+
* of them; `readPluginPresentation` reads what a card shows for one entry
|
|
6
|
+
* without opening the rest of it. Everything else here is what a consumer needs to supply its
|
|
6
7
|
* input (`PluginFiles`, the caps), route a directory (`MANIFEST_LOCATIONS`,
|
|
7
8
|
* `hasPluginManifest`, `MARKETPLACE_LOCATIONS`, `hasMarketplaceFile`), or
|
|
8
9
|
* render an outcome (the finding kinds and `isErrorKind`). The dialect
|
|
@@ -20,5 +21,6 @@ export { MARKETPLACE_LOCATIONS } from "./marketplace/messages.js";
|
|
|
20
21
|
export type { Marketplace, MarketplaceDialect, MarketplaceEntry, MarketplaceErrorKind, MarketplaceFinding, MarketplaceFindingKind, MarketplaceOwner, MarketplaceReadOutcome, MarketplaceWarningKind, } from "./marketplace/outcome.js";
|
|
21
22
|
export { hasMarketplaceFile, readMarketplace, readMarketplaceFile } from "./marketplace/read-marketplace.js";
|
|
22
23
|
export { readPluginPackage } from "./read-plugin-package.js";
|
|
24
|
+
export { type PluginPresentation, readPluginPresentation } from "./presentation.js";
|
|
23
25
|
export type { IgnoredComponent, IgnoredComponentKind, ModelAlias, ModelHint, OverlayDocument, OverlayNamedDocument, OverlayServerDocument, PluginAuthor, PluginDialect, PluginMcpServer, PluginPackage, PluginSkill, PluginSubAgent, PluginVariable, StigmerOverlay, } from "./types.js";
|
|
24
26
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,OAAO,EACP,cAAc,EACd,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,KAAK,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/index.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* `@stigmer/plugin-package`: the public surface.
|
|
3
3
|
*
|
|
4
4
|
* `readPluginPackage` reads one plugin; `readMarketplace` reads a catalogue
|
|
5
|
-
* of them
|
|
5
|
+
* of them; `readPluginPresentation` reads what a card shows for one entry
|
|
6
|
+
* without opening the rest of it. Everything else here is what a consumer needs to supply its
|
|
6
7
|
* input (`PluginFiles`, the caps), route a directory (`MANIFEST_LOCATIONS`,
|
|
7
8
|
* `hasPluginManifest`, `MARKETPLACE_LOCATIONS`, `hasMarketplaceFile`), or
|
|
8
9
|
* render an outcome (the finding kinds and `isErrorKind`). The dialect
|
|
@@ -18,4 +19,5 @@ export { PLACEHOLDER_PATTERN, VARIABLE_NAME_PATTERN } from "./placeholders.js";
|
|
|
18
19
|
export { MARKETPLACE_LOCATIONS } from "./marketplace/messages.js";
|
|
19
20
|
export { hasMarketplaceFile, readMarketplace, readMarketplaceFile } from "./marketplace/read-marketplace.js";
|
|
20
21
|
export { readPluginPackage } from "./read-plugin-package.js";
|
|
22
|
+
export { readPluginPresentation } from "./presentation.js";
|
|
21
23
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,GAKpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAU/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAYlE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAA2B,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/plugin-package",
|
|
3
|
-
"version": "3.18.
|
|
3
|
+
"version": "3.18.1-dev.20260919070736",
|
|
4
4
|
"description": "Reads an Agent Plugins package — the open 1.0.0 format and the Cursor, Claude Code and Codex dialects — into one normalised description of what Stigmer would install, refusing with one sentence per problem what Stigmer cannot carry; pure over an in-memory file reader, shared by the CLI's offline validation and the server's install. The ./client entry is what every installing client does identically: file selection, the deterministic archive and its digest, the marketplace grammars",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a storefront shows for a plugin before anyone installs it: a display
|
|
3
|
+
* name, a logo, an author, a version, a description, a category.
|
|
4
|
+
*
|
|
5
|
+
* This is a read apart from `readPluginPackage` on purpose. The full read
|
|
6
|
+
* decides what Stigmer INSTALLS and refuses what it cannot; a card must
|
|
7
|
+
* render for every entry a catalogue lists, refused or not, and must cost
|
|
8
|
+
* one manifest, not the plugin's whole tree. So this reader opens only the
|
|
9
|
+
* manifests present, takes what they say about appearance, and never
|
|
10
|
+
* reports a finding: an unreadable manifest contributes nothing, a wrong
|
|
11
|
+
* type is treated as absent, and the caller draws a fallback face.
|
|
12
|
+
*
|
|
13
|
+
* Which manifest speaks is the full reader's rule (`MANIFEST_PRECEDENCE`:
|
|
14
|
+
* the root manifest, then Claude, Cursor, Codex), so a plugin shipping two
|
|
15
|
+
* dialects is named the same way on a card and in an install. Identity
|
|
16
|
+
* fields (`name`, `version`, `description`, `author`) come from the first
|
|
17
|
+
* manifest that carries each; the presentation fields come from the
|
|
18
|
+
* dialects that define them: Cursor's top-level `displayName`, `logo` and
|
|
19
|
+
* `category`; the legacy Codex manifest's `interface.displayName`,
|
|
20
|
+
* `interface.logo` and `interface.category`. Claude Code's manifest and the
|
|
21
|
+
* open format define none, and a logo rule for the `ai.stigmer` extension
|
|
22
|
+
* namespace waits for the first official plugin that needs one.
|
|
23
|
+
*
|
|
24
|
+
* A logo is a path inside the plugin, and the card that shows it fetches it
|
|
25
|
+
* by URL from wherever the tree lives. So the path is kept only when it is
|
|
26
|
+
* contained, names an image by extension, is LISTED in the tree, and its
|
|
27
|
+
* declared size is under `PLUGIN_DOCUMENT_LIMITS.logo`; the library's rule
|
|
28
|
+
* that a cap is checked from declared sizes before a byte moves holds here
|
|
29
|
+
* too. Both spellings the vendors use (`assets/logo.png`, `./assets/logo.png`)
|
|
30
|
+
* are accepted, as the marketplace reader accepts both for a source.
|
|
31
|
+
*
|
|
32
|
+
* `logo` stays an ignored component in the full read: nothing in an
|
|
33
|
+
* Organization carries the image after an install, and the preview's "Not
|
|
34
|
+
* installed" line is true until the stored plugin does.
|
|
35
|
+
*/
|
|
36
|
+
import { type PluginFiles } from "./files.js";
|
|
37
|
+
import type { PluginAuthor } from "./types.js";
|
|
38
|
+
/** What a card shows for a plugin; every field optional, because every dialect may omit it. */
|
|
39
|
+
export interface PluginPresentation {
|
|
40
|
+
/** The name for people (`Thermos`); the install name stays `name`. */
|
|
41
|
+
readonly displayName?: string;
|
|
42
|
+
/** A plugin-relative path to an image the tree lists, verified as described in the module header. */
|
|
43
|
+
readonly logo?: string;
|
|
44
|
+
readonly author?: PluginAuthor;
|
|
45
|
+
readonly version?: string;
|
|
46
|
+
readonly description?: string;
|
|
47
|
+
/** The catalogue's own grouping word (`developer-tools`, `Productivity`), as written. */
|
|
48
|
+
readonly category?: string;
|
|
49
|
+
}
|
|
50
|
+
/** The appearance fields of every manifest present, merged in precedence order. */
|
|
51
|
+
export declare function readPluginPresentation(files: PluginFiles): PluginPresentation;
|
|
52
|
+
//# sourceMappingURL=presentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAwE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAGpH,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,YAAY,CAAC;AAE9D,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAKD,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,CAc7E"}
|
package/presentation.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a storefront shows for a plugin before anyone installs it: a display
|
|
3
|
+
* name, a logo, an author, a version, a description, a category.
|
|
4
|
+
*
|
|
5
|
+
* This is a read apart from `readPluginPackage` on purpose. The full read
|
|
6
|
+
* decides what Stigmer INSTALLS and refuses what it cannot; a card must
|
|
7
|
+
* render for every entry a catalogue lists, refused or not, and must cost
|
|
8
|
+
* one manifest, not the plugin's whole tree. So this reader opens only the
|
|
9
|
+
* manifests present, takes what they say about appearance, and never
|
|
10
|
+
* reports a finding: an unreadable manifest contributes nothing, a wrong
|
|
11
|
+
* type is treated as absent, and the caller draws a fallback face.
|
|
12
|
+
*
|
|
13
|
+
* Which manifest speaks is the full reader's rule (`MANIFEST_PRECEDENCE`:
|
|
14
|
+
* the root manifest, then Claude, Cursor, Codex), so a plugin shipping two
|
|
15
|
+
* dialects is named the same way on a card and in an install. Identity
|
|
16
|
+
* fields (`name`, `version`, `description`, `author`) come from the first
|
|
17
|
+
* manifest that carries each; the presentation fields come from the
|
|
18
|
+
* dialects that define them: Cursor's top-level `displayName`, `logo` and
|
|
19
|
+
* `category`; the legacy Codex manifest's `interface.displayName`,
|
|
20
|
+
* `interface.logo` and `interface.category`. Claude Code's manifest and the
|
|
21
|
+
* open format define none, and a logo rule for the `ai.stigmer` extension
|
|
22
|
+
* namespace waits for the first official plugin that needs one.
|
|
23
|
+
*
|
|
24
|
+
* A logo is a path inside the plugin, and the card that shows it fetches it
|
|
25
|
+
* by URL from wherever the tree lives. So the path is kept only when it is
|
|
26
|
+
* contained, names an image by extension, is LISTED in the tree, and its
|
|
27
|
+
* declared size is under `PLUGIN_DOCUMENT_LIMITS.logo`; the library's rule
|
|
28
|
+
* that a cap is checked from declared sizes before a byte moves holds here
|
|
29
|
+
* too. Both spellings the vendors use (`assets/logo.png`, `./assets/logo.png`)
|
|
30
|
+
* are accepted, as the marketplace reader accepts both for a source.
|
|
31
|
+
*
|
|
32
|
+
* `logo` stays an ignored component in the full read: nothing in an
|
|
33
|
+
* Organization carries the image after an install, and the preview's "Not
|
|
34
|
+
* installed" line is true until the stored plugin does.
|
|
35
|
+
*/
|
|
36
|
+
import { MANIFEST_PRECEDENCE } from "./detect.js";
|
|
37
|
+
import { decodeUtf8, isContainedPath, PLUGIN_DOCUMENT_LIMITS, PluginFileIndex } from "./files.js";
|
|
38
|
+
import { isJsonObject } from "./documents.js";
|
|
39
|
+
import { MANIFEST_LOCATIONS } from "./messages.js";
|
|
40
|
+
/** The image extensions a browser renders in an `<img>`; a logo named otherwise is not shown. */
|
|
41
|
+
const LOGO_EXTENSIONS = new Set(["png", "svg", "jpg", "jpeg", "webp", "gif"]);
|
|
42
|
+
/** The appearance fields of every manifest present, merged in precedence order. */
|
|
43
|
+
export function readPluginPresentation(files) {
|
|
44
|
+
const index = new PluginFileIndex(files);
|
|
45
|
+
const presentation = {};
|
|
46
|
+
for (const dialect of MANIFEST_PRECEDENCE) {
|
|
47
|
+
const object = readManifest(index, MANIFEST_LOCATIONS[dialect]);
|
|
48
|
+
if (object === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
const contribution = contributionOf(dialect, object, index);
|
|
51
|
+
for (const key of Object.keys(contribution)) {
|
|
52
|
+
if (presentation[key] === undefined)
|
|
53
|
+
Object.assign(presentation, { [key]: contribution[key] });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return presentation;
|
|
57
|
+
}
|
|
58
|
+
/** The manifest at `path` as an object, or `undefined` for anything a card should not stumble on. */
|
|
59
|
+
function readManifest(index, path) {
|
|
60
|
+
const entry = index.entry(path);
|
|
61
|
+
if (entry === undefined || entry.size > PLUGIN_DOCUMENT_LIMITS.manifest)
|
|
62
|
+
return undefined;
|
|
63
|
+
let bytes;
|
|
64
|
+
try {
|
|
65
|
+
bytes = index.files.read(path);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
if (bytes.length > PLUGIN_DOCUMENT_LIMITS.manifest)
|
|
71
|
+
return undefined;
|
|
72
|
+
let value;
|
|
73
|
+
try {
|
|
74
|
+
value = JSON.parse(decodeUtf8(bytes));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
return isJsonObject(value) ? value : undefined;
|
|
80
|
+
}
|
|
81
|
+
function contributionOf(dialect, object, index) {
|
|
82
|
+
const identity = identityOf(object);
|
|
83
|
+
switch (dialect) {
|
|
84
|
+
case "cursor":
|
|
85
|
+
return { ...identity, ...appearanceOf(object, index) };
|
|
86
|
+
case "codex": {
|
|
87
|
+
const surface = object["interface"];
|
|
88
|
+
return isJsonObject(surface) ? { ...identity, ...appearanceOf(surface, index) } : identity;
|
|
89
|
+
}
|
|
90
|
+
case "agent-plugins":
|
|
91
|
+
case "claude":
|
|
92
|
+
return identity;
|
|
93
|
+
default: {
|
|
94
|
+
const exhaustive = dialect;
|
|
95
|
+
return exhaustive;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** The identity fields every dialect shares, typed loosely: a wrong type is absent, never a finding. */
|
|
100
|
+
function identityOf(object) {
|
|
101
|
+
const author = authorOf(object["author"]);
|
|
102
|
+
return {
|
|
103
|
+
...optional("version", object["version"]),
|
|
104
|
+
...optional("description", object["description"]),
|
|
105
|
+
...(author !== undefined && { author }),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** `displayName`, `logo` and `category` from an object that carries them at its top level (a Cursor manifest, a Codex `interface`). */
|
|
109
|
+
function appearanceOf(object, index) {
|
|
110
|
+
const logo = logoPath(object["logo"], index);
|
|
111
|
+
return {
|
|
112
|
+
...optional("displayName", object["displayName"]),
|
|
113
|
+
...optional("category", object["category"]),
|
|
114
|
+
...(logo !== undefined && { logo }),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function authorOf(value) {
|
|
118
|
+
if (!isJsonObject(value))
|
|
119
|
+
return undefined;
|
|
120
|
+
const author = {
|
|
121
|
+
...optional("name", value["name"]),
|
|
122
|
+
...optional("email", value["email"]),
|
|
123
|
+
...optional("url", value["url"]),
|
|
124
|
+
};
|
|
125
|
+
return Object.keys(author).length === 0 ? undefined : author;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A declared logo as a plugin-relative path the tree lists, or nothing.
|
|
129
|
+
* `./` is stripped (Codex's spelling); an absolute path, a `..` segment, a
|
|
130
|
+
* URL, a non-image extension, an unlisted file or an over-cap file all
|
|
131
|
+
* mean "no logo", never a refusal.
|
|
132
|
+
*/
|
|
133
|
+
function logoPath(value, index) {
|
|
134
|
+
if (typeof value !== "string")
|
|
135
|
+
return undefined;
|
|
136
|
+
const path = value.startsWith("./") ? value.slice(2) : value;
|
|
137
|
+
if (!isContainedPath(path))
|
|
138
|
+
return undefined;
|
|
139
|
+
const dot = path.lastIndexOf(".");
|
|
140
|
+
if (dot === -1 || !LOGO_EXTENSIONS.has(path.slice(dot + 1).toLowerCase()))
|
|
141
|
+
return undefined;
|
|
142
|
+
const entry = index.entry(path);
|
|
143
|
+
if (entry === undefined || entry.size > PLUGIN_DOCUMENT_LIMITS.logo)
|
|
144
|
+
return undefined;
|
|
145
|
+
return path;
|
|
146
|
+
}
|
|
147
|
+
/** `{ [key]: value }` when `value` is a non-empty string; `{}` otherwise. */
|
|
148
|
+
function optional(key, value) {
|
|
149
|
+
return typeof value === "string" && value !== "" ? { [key]: value } : {};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=presentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.js","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presentation read, the one a storefront card runs.
|
|
3
|
+
*
|
|
4
|
+
* Pins: the vendored Cursor fixtures yield their `displayName`, `logo`,
|
|
5
|
+
* `category` and author (thermos, a PNG; playwright, an SVG); a Codex
|
|
6
|
+
* manifest yields the same fields from `interface`, with the `./` spelling
|
|
7
|
+
* stripped; a Claude manifest and an open manifest yield identity only; a
|
|
8
|
+
* root manifest names the plugin ahead of a vendor manifest beside it,
|
|
9
|
+
* while the vendor manifest still lends its appearance; a logo that is
|
|
10
|
+
* absent from the listing, over the cap, not an image, a URL or an escape
|
|
11
|
+
* is dropped without a finding; an unparseable manifest contributes nothing
|
|
12
|
+
* and the read still answers. The lazy twin reads exactly the manifests
|
|
13
|
+
* listed and no other file, and treats a fetch that rejects as a manifest
|
|
14
|
+
* that is not there.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
import { describe, expect, it } from "vitest";
|
|
20
|
+
|
|
21
|
+
import { type LazyCandidate } from "../client/prepare.js";
|
|
22
|
+
import { readPluginPresentationFromTree } from "../client/presentation.js";
|
|
23
|
+
import { inMemoryPluginFiles, PLUGIN_DOCUMENT_LIMITS } from "../files.js";
|
|
24
|
+
import { MANIFEST_LOCATIONS } from "../messages.js";
|
|
25
|
+
import { readPluginPresentation } from "../presentation.js";
|
|
26
|
+
import { claudePlugin, codexPlugin, cursorPlugin, openPlugin, withFile, type PluginFixture } from "../testing.js";
|
|
27
|
+
import { directoryPluginFiles } from "../__test-utils__/directory-files.js";
|
|
28
|
+
|
|
29
|
+
const FIXTURES = fileURLToPath(new URL("./fixtures/cursor-plugins/", import.meta.url));
|
|
30
|
+
const PNG_BYTES = new Uint8Array([0x89, 0x50, 0x4e, 0x47]);
|
|
31
|
+
|
|
32
|
+
function present(files: PluginFixture) {
|
|
33
|
+
return readPluginPresentation(inMemoryPluginFiles(files));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("readPluginPresentation over the vendored Cursor fixtures", () => {
|
|
37
|
+
it("thermos: display name, PNG logo, category, author", () => {
|
|
38
|
+
const presentation = readPluginPresentation(directoryPluginFiles(`${FIXTURES}thermos`));
|
|
39
|
+
expect(presentation).toEqual({
|
|
40
|
+
displayName: "Thermos",
|
|
41
|
+
logo: "assets/logo.png",
|
|
42
|
+
category: "developer-tools",
|
|
43
|
+
version: "1.0.0",
|
|
44
|
+
description: expect.stringContaining("Thermo-nuclear branch review"),
|
|
45
|
+
author: { name: "Cursor", email: "plugins@cursor.com" },
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("playwright: an SVG logo is an image too", () => {
|
|
50
|
+
const presentation = readPluginPresentation(directoryPluginFiles(`${FIXTURES}playwright`));
|
|
51
|
+
expect(presentation.displayName).toBe("Playwright");
|
|
52
|
+
expect(presentation.logo).toBe("assets/logo.svg");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("the dialects that carry appearance", () => {
|
|
57
|
+
it("a Cursor manifest speaks at its top level", () => {
|
|
58
|
+
const files = withFile(
|
|
59
|
+
cursorPlugin({ manifest: { displayName: "GitHub", logo: "assets/logo.png", category: "integrations", author: { name: "Cursor" } } }),
|
|
60
|
+
"assets/logo.png",
|
|
61
|
+
PNG_BYTES,
|
|
62
|
+
);
|
|
63
|
+
expect(present(files)).toMatchObject({ displayName: "GitHub", logo: "assets/logo.png", category: "integrations", author: { name: "Cursor" } });
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("a legacy Codex manifest speaks through `interface`, and `./` is stripped from its logo", () => {
|
|
67
|
+
const files = withFile(
|
|
68
|
+
codexPlugin({
|
|
69
|
+
version: "6.0.1",
|
|
70
|
+
manifest: { interface: { displayName: "Airtable", logo: "./assets/logo.png", category: "Productivity", developerName: "Airtable" } },
|
|
71
|
+
}),
|
|
72
|
+
"assets/logo.png",
|
|
73
|
+
PNG_BYTES,
|
|
74
|
+
);
|
|
75
|
+
expect(present(files)).toEqual({ displayName: "Airtable", logo: "assets/logo.png", category: "Productivity", version: "6.0.1" });
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("a Claude manifest and an open manifest yield identity only", () => {
|
|
79
|
+
expect(present(claudePlugin({ version: "1.0.0", description: "Reviews pull requests.", manifest: { author: { name: "Anthropic" } } }))).toEqual({
|
|
80
|
+
version: "1.0.0",
|
|
81
|
+
description: "Reviews pull requests.",
|
|
82
|
+
author: { name: "Anthropic" },
|
|
83
|
+
});
|
|
84
|
+
const open = present(openPlugin({ version: "2.0.0", description: "The assistant." }));
|
|
85
|
+
expect(open.displayName).toBeUndefined();
|
|
86
|
+
expect(open.logo).toBeUndefined();
|
|
87
|
+
expect(open.version).toBe("2.0.0");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("a root manifest names the plugin first; a vendor manifest beside it still lends its appearance", () => {
|
|
91
|
+
let files = openPlugin({ version: "3.0.0", description: "From the root manifest." });
|
|
92
|
+
files = withFile(
|
|
93
|
+
files,
|
|
94
|
+
MANIFEST_LOCATIONS.cursor,
|
|
95
|
+
JSON.stringify({ name: "plugin", version: "1.0.0", description: "From the Cursor manifest.", displayName: "Plugin", logo: "assets/logo.png" }),
|
|
96
|
+
);
|
|
97
|
+
files = withFile(files, "assets/logo.png", PNG_BYTES);
|
|
98
|
+
expect(present(files)).toMatchObject({ version: "3.0.0", description: "From the root manifest.", displayName: "Plugin", logo: "assets/logo.png" });
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe("a logo that cannot be shown is no logo, never a finding", () => {
|
|
103
|
+
const cases: readonly [string, string, PluginFixture | undefined][] = [
|
|
104
|
+
["not listed", "assets/missing.png", undefined],
|
|
105
|
+
["a URL", "https://example.com/logo.png", undefined],
|
|
106
|
+
["an escape", "../logo.png", undefined],
|
|
107
|
+
["not an image", "assets/logo.txt", withFile(cursorPlugin(), "assets/logo.txt", "text")],
|
|
108
|
+
["over the cap", "assets/huge.png", withFile(cursorPlugin(), "assets/huge.png", new Uint8Array(PLUGIN_DOCUMENT_LIMITS.logo + 1))],
|
|
109
|
+
];
|
|
110
|
+
for (const [label, logo, base] of cases) {
|
|
111
|
+
it(label, () => {
|
|
112
|
+
const files = withFile(base ?? cursorPlugin(), MANIFEST_LOCATIONS.cursor, JSON.stringify({ name: "plugin", displayName: "Plugin", logo }));
|
|
113
|
+
const presentation = present(files);
|
|
114
|
+
expect(presentation.displayName).toBe("Plugin");
|
|
115
|
+
expect(presentation.logo).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
it("a wrong type is absent", () => {
|
|
120
|
+
const files = withFile(cursorPlugin(), MANIFEST_LOCATIONS.cursor, JSON.stringify({ name: "plugin", displayName: 7, logo: ["assets/logo.png"], author: "Cursor" }));
|
|
121
|
+
expect(present(files)).toEqual({});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("an unparseable manifest contributes nothing and the read answers", () => {
|
|
125
|
+
const files = withFile(cursorPlugin({ version: "1.0.0" }), MANIFEST_LOCATIONS.cursor, "{ not json");
|
|
126
|
+
expect(present(files)).toEqual({});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("readPluginPresentationFromTree", () => {
|
|
131
|
+
function lazy(files: PluginFixture, reads: string[], failing: ReadonlySet<string> = new Set()): LazyCandidate[] {
|
|
132
|
+
const encoder = new TextEncoder();
|
|
133
|
+
return [...files.entries()].map(([path, content]) => {
|
|
134
|
+
const bytes = typeof content === "string" ? encoder.encode(content) : content;
|
|
135
|
+
return {
|
|
136
|
+
path,
|
|
137
|
+
size: bytes.length,
|
|
138
|
+
read: async () => {
|
|
139
|
+
reads.push(path);
|
|
140
|
+
if (failing.has(path)) throw new Error(`cannot read ${path}`);
|
|
141
|
+
return bytes;
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
it("reads exactly the manifests listed and no other file", async () => {
|
|
148
|
+
const reads: string[] = [];
|
|
149
|
+
const files = withFile(cursorPlugin({ manifest: { displayName: "Thermos", logo: "assets/logo.png" }, skills: [{ name: "review" }] }), "assets/logo.png", PNG_BYTES);
|
|
150
|
+
const presentation = await readPluginPresentationFromTree(lazy(files, reads));
|
|
151
|
+
expect(presentation).toMatchObject({ displayName: "Thermos", logo: "assets/logo.png" });
|
|
152
|
+
expect(reads).toEqual([MANIFEST_LOCATIONS.cursor]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("a manifest whose fetch rejects is a manifest that is not there", async () => {
|
|
156
|
+
const reads: string[] = [];
|
|
157
|
+
const files = cursorPlugin({ manifest: { displayName: "Thermos" } });
|
|
158
|
+
const presentation = await readPluginPresentationFromTree(lazy(files, reads, new Set([MANIFEST_LOCATIONS.cursor])));
|
|
159
|
+
expect(presentation).toEqual({});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plugin's presentation from a tree whose bytes cost something to obtain:
|
|
3
|
+
* the lazy twin of `readPluginPresentation`, as `preparePluginFromTree` is
|
|
4
|
+
* the lazy twin of the full read.
|
|
5
|
+
*
|
|
6
|
+
* A storefront lists a catalogue from one file and then shows a card per
|
|
7
|
+
* entry; the face on each card is in that entry's manifest, one small file
|
|
8
|
+
* in a directory the client has listed but not read. This reads exactly the
|
|
9
|
+
* manifest paths the listing shows (one, rarely two) and nothing else, then
|
|
10
|
+
* hands a `PluginFiles` whose `read` answers for those paths alone to the
|
|
11
|
+
* pure reader. A manifest that cannot be fetched contributes nothing, the
|
|
12
|
+
* pure reader's own rule for a manifest that cannot be parsed: a card is
|
|
13
|
+
* never refused, it is drawn with what arrived.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { comparePaths, type PluginFiles } from "../files.js";
|
|
17
|
+
import { MANIFEST_LOCATIONS } from "../messages.js";
|
|
18
|
+
import { type PluginPresentation, readPluginPresentation } from "../presentation.js";
|
|
19
|
+
import type { LazyCandidate } from "./prepare.js";
|
|
20
|
+
|
|
21
|
+
const MANIFEST_PATHS: ReadonlySet<string> = new Set(Object.values(MANIFEST_LOCATIONS));
|
|
22
|
+
|
|
23
|
+
/** The presentation of the plugin whose files `candidates` list, reading only its manifests. */
|
|
24
|
+
export async function readPluginPresentationFromTree(candidates: readonly LazyCandidate[]): Promise<PluginPresentation> {
|
|
25
|
+
const contents = new Map<string, Uint8Array>();
|
|
26
|
+
await Promise.all(
|
|
27
|
+
candidates
|
|
28
|
+
.filter((candidate) => MANIFEST_PATHS.has(candidate.path))
|
|
29
|
+
.map(async (candidate) => {
|
|
30
|
+
try {
|
|
31
|
+
contents.set(candidate.path, await candidate.read());
|
|
32
|
+
} catch {
|
|
33
|
+
// Unfetchable is unreadable: the pure reader skips a manifest it cannot open.
|
|
34
|
+
}
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
const files: PluginFiles = {
|
|
38
|
+
// `PluginFiles` promises a sorted listing; a host's tree order is its own.
|
|
39
|
+
entries: candidates.map(({ path, size }) => ({ path, size })).sort((a, b) => comparePaths(a.path, b.path)),
|
|
40
|
+
read: (path) => {
|
|
41
|
+
const bytes = contents.get(path);
|
|
42
|
+
if (bytes === undefined) throw new Error(`plugin file '${path}' was not fetched for presentation`);
|
|
43
|
+
return bytes;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
return readPluginPresentation(files);
|
|
47
|
+
}
|
package/src/client.ts
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* the SHA-256 the server records;
|
|
18
18
|
* - the preparation (`prepare.ts`): select, read, refuse, archive, digest,
|
|
19
19
|
* once, for a tree on disk, on a host, or in a browser's memory;
|
|
20
|
+
* - the presentation (`presentation.ts`): a card's face from a listed
|
|
21
|
+
* tree, reading the entry's manifest and nothing else;
|
|
20
22
|
* - the grammars (`refs.ts`): an install ref and a GitHub marketplace
|
|
21
23
|
* source, with their refusal sentences;
|
|
22
24
|
* - the built-in sources (`builtin.ts`): the official catalogue and the
|
|
@@ -65,6 +67,7 @@ export {
|
|
|
65
67
|
preparePluginArchive,
|
|
66
68
|
preparePluginFromTree,
|
|
67
69
|
} from "./client/prepare.js";
|
|
70
|
+
export { readPluginPresentationFromTree } from "./client/presentation.js";
|
|
68
71
|
export {
|
|
69
72
|
type BuiltInMarketplace,
|
|
70
73
|
BUILT_IN_MARKETPLACES,
|
package/src/detect.ts
CHANGED
|
@@ -41,6 +41,14 @@ export const OPEN_MCP_CONFIG = "mcp.json";
|
|
|
41
41
|
/** The vendor precedence when no root manifest exists. */
|
|
42
42
|
const VENDOR_PRECEDENCE: readonly Exclude<PluginDialect, "agent-plugins">[] = ["claude", "cursor", "codex"];
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Every manifest location in the order that names a plugin: the root
|
|
46
|
+
* manifest, then the vendors. The one precedence the reader applies,
|
|
47
|
+
* exported so a partial read (`presentation.ts`) cannot rank the manifests
|
|
48
|
+
* differently from the full one.
|
|
49
|
+
*/
|
|
50
|
+
export const MANIFEST_PRECEDENCE: readonly PluginDialect[] = ["agent-plugins", ...VENDOR_PRECEDENCE];
|
|
51
|
+
|
|
44
52
|
const NAME_MAX_LENGTH = 64;
|
|
45
53
|
const NAME_PATTERN = /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/;
|
|
46
54
|
|
package/src/files.ts
CHANGED
|
@@ -58,6 +58,13 @@ export const PLUGIN_DOCUMENT_LIMITS = {
|
|
|
58
58
|
subAgent: 1024 * 1024,
|
|
59
59
|
/** A document under `ai.stigmer/`: a resource YAML. */
|
|
60
60
|
overlay: 1024 * 1024,
|
|
61
|
+
/**
|
|
62
|
+
* A plugin's logo, the image a storefront card shows. Checked from the
|
|
63
|
+
* listing's declared size before a client hands the file's URL to an
|
|
64
|
+
* `<img>`; measured across the three vendors' catalogues on 2026-09-18,
|
|
65
|
+
* the largest published logo is 361 KB and the median 7.5 KB.
|
|
66
|
+
*/
|
|
67
|
+
logo: 1024 * 1024,
|
|
61
68
|
/**
|
|
62
69
|
* A marketplace file in any dialect. The largest public catalogue
|
|
63
70
|
* (`cursor/plugins`, 79 entries with descriptions) is under 32 KB; the cap
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* `@stigmer/plugin-package`: the public surface.
|
|
3
3
|
*
|
|
4
4
|
* `readPluginPackage` reads one plugin; `readMarketplace` reads a catalogue
|
|
5
|
-
* of them
|
|
5
|
+
* of them; `readPluginPresentation` reads what a card shows for one entry
|
|
6
|
+
* without opening the rest of it. Everything else here is what a consumer needs to supply its
|
|
6
7
|
* input (`PluginFiles`, the caps), route a directory (`MANIFEST_LOCATIONS`,
|
|
7
8
|
* `hasPluginManifest`, `MARKETPLACE_LOCATIONS`, `hasMarketplaceFile`), or
|
|
8
9
|
* render an outcome (the finding kinds and `isErrorKind`). The dialect
|
|
@@ -56,6 +57,7 @@ export type {
|
|
|
56
57
|
} from "./marketplace/outcome.js";
|
|
57
58
|
export { hasMarketplaceFile, readMarketplace, readMarketplaceFile } from "./marketplace/read-marketplace.js";
|
|
58
59
|
export { readPluginPackage } from "./read-plugin-package.js";
|
|
60
|
+
export { type PluginPresentation, readPluginPresentation } from "./presentation.js";
|
|
59
61
|
export type {
|
|
60
62
|
IgnoredComponent,
|
|
61
63
|
IgnoredComponentKind,
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a storefront shows for a plugin before anyone installs it: a display
|
|
3
|
+
* name, a logo, an author, a version, a description, a category.
|
|
4
|
+
*
|
|
5
|
+
* This is a read apart from `readPluginPackage` on purpose. The full read
|
|
6
|
+
* decides what Stigmer INSTALLS and refuses what it cannot; a card must
|
|
7
|
+
* render for every entry a catalogue lists, refused or not, and must cost
|
|
8
|
+
* one manifest, not the plugin's whole tree. So this reader opens only the
|
|
9
|
+
* manifests present, takes what they say about appearance, and never
|
|
10
|
+
* reports a finding: an unreadable manifest contributes nothing, a wrong
|
|
11
|
+
* type is treated as absent, and the caller draws a fallback face.
|
|
12
|
+
*
|
|
13
|
+
* Which manifest speaks is the full reader's rule (`MANIFEST_PRECEDENCE`:
|
|
14
|
+
* the root manifest, then Claude, Cursor, Codex), so a plugin shipping two
|
|
15
|
+
* dialects is named the same way on a card and in an install. Identity
|
|
16
|
+
* fields (`name`, `version`, `description`, `author`) come from the first
|
|
17
|
+
* manifest that carries each; the presentation fields come from the
|
|
18
|
+
* dialects that define them: Cursor's top-level `displayName`, `logo` and
|
|
19
|
+
* `category`; the legacy Codex manifest's `interface.displayName`,
|
|
20
|
+
* `interface.logo` and `interface.category`. Claude Code's manifest and the
|
|
21
|
+
* open format define none, and a logo rule for the `ai.stigmer` extension
|
|
22
|
+
* namespace waits for the first official plugin that needs one.
|
|
23
|
+
*
|
|
24
|
+
* A logo is a path inside the plugin, and the card that shows it fetches it
|
|
25
|
+
* by URL from wherever the tree lives. So the path is kept only when it is
|
|
26
|
+
* contained, names an image by extension, is LISTED in the tree, and its
|
|
27
|
+
* declared size is under `PLUGIN_DOCUMENT_LIMITS.logo`; the library's rule
|
|
28
|
+
* that a cap is checked from declared sizes before a byte moves holds here
|
|
29
|
+
* too. Both spellings the vendors use (`assets/logo.png`, `./assets/logo.png`)
|
|
30
|
+
* are accepted, as the marketplace reader accepts both for a source.
|
|
31
|
+
*
|
|
32
|
+
* `logo` stays an ignored component in the full read: nothing in an
|
|
33
|
+
* Organization carries the image after an install, and the preview's "Not
|
|
34
|
+
* installed" line is true until the stored plugin does.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { MANIFEST_PRECEDENCE } from "./detect.js";
|
|
38
|
+
import { decodeUtf8, isContainedPath, PLUGIN_DOCUMENT_LIMITS, PluginFileIndex, type PluginFiles } from "./files.js";
|
|
39
|
+
import { isJsonObject, type JsonObject } from "./documents.js";
|
|
40
|
+
import { MANIFEST_LOCATIONS } from "./messages.js";
|
|
41
|
+
import type { PluginAuthor, PluginDialect } from "./types.js";
|
|
42
|
+
|
|
43
|
+
/** What a card shows for a plugin; every field optional, because every dialect may omit it. */
|
|
44
|
+
export interface PluginPresentation {
|
|
45
|
+
/** The name for people (`Thermos`); the install name stays `name`. */
|
|
46
|
+
readonly displayName?: string;
|
|
47
|
+
/** A plugin-relative path to an image the tree lists, verified as described in the module header. */
|
|
48
|
+
readonly logo?: string;
|
|
49
|
+
readonly author?: PluginAuthor;
|
|
50
|
+
readonly version?: string;
|
|
51
|
+
readonly description?: string;
|
|
52
|
+
/** The catalogue's own grouping word (`developer-tools`, `Productivity`), as written. */
|
|
53
|
+
readonly category?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The image extensions a browser renders in an `<img>`; a logo named otherwise is not shown. */
|
|
57
|
+
const LOGO_EXTENSIONS: ReadonlySet<string> = new Set(["png", "svg", "jpg", "jpeg", "webp", "gif"]);
|
|
58
|
+
|
|
59
|
+
/** The appearance fields of every manifest present, merged in precedence order. */
|
|
60
|
+
export function readPluginPresentation(files: PluginFiles): PluginPresentation {
|
|
61
|
+
const index = new PluginFileIndex(files);
|
|
62
|
+
const presentation: { -readonly [K in keyof PluginPresentation]: PluginPresentation[K] } = {};
|
|
63
|
+
|
|
64
|
+
for (const dialect of MANIFEST_PRECEDENCE) {
|
|
65
|
+
const object = readManifest(index, MANIFEST_LOCATIONS[dialect]);
|
|
66
|
+
if (object === undefined) continue;
|
|
67
|
+
const contribution = contributionOf(dialect, object, index);
|
|
68
|
+
for (const key of Object.keys(contribution) as (keyof PluginPresentation)[]) {
|
|
69
|
+
if (presentation[key] === undefined) Object.assign(presentation, { [key]: contribution[key] });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return presentation;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The manifest at `path` as an object, or `undefined` for anything a card should not stumble on. */
|
|
77
|
+
function readManifest(index: PluginFileIndex, path: string): JsonObject | undefined {
|
|
78
|
+
const entry = index.entry(path);
|
|
79
|
+
if (entry === undefined || entry.size > PLUGIN_DOCUMENT_LIMITS.manifest) return undefined;
|
|
80
|
+
let bytes: Uint8Array;
|
|
81
|
+
try {
|
|
82
|
+
bytes = index.files.read(path);
|
|
83
|
+
} catch {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
if (bytes.length > PLUGIN_DOCUMENT_LIMITS.manifest) return undefined;
|
|
87
|
+
let value: unknown;
|
|
88
|
+
try {
|
|
89
|
+
value = JSON.parse(decodeUtf8(bytes));
|
|
90
|
+
} catch {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return isJsonObject(value) ? value : undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function contributionOf(dialect: PluginDialect, object: JsonObject, index: PluginFileIndex): PluginPresentation {
|
|
97
|
+
const identity = identityOf(object);
|
|
98
|
+
switch (dialect) {
|
|
99
|
+
case "cursor":
|
|
100
|
+
return { ...identity, ...appearanceOf(object, index) };
|
|
101
|
+
case "codex": {
|
|
102
|
+
const surface = object["interface"];
|
|
103
|
+
return isJsonObject(surface) ? { ...identity, ...appearanceOf(surface, index) } : identity;
|
|
104
|
+
}
|
|
105
|
+
case "agent-plugins":
|
|
106
|
+
case "claude":
|
|
107
|
+
return identity;
|
|
108
|
+
default: {
|
|
109
|
+
const exhaustive: never = dialect;
|
|
110
|
+
return exhaustive;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The identity fields every dialect shares, typed loosely: a wrong type is absent, never a finding. */
|
|
116
|
+
function identityOf(object: JsonObject): PluginPresentation {
|
|
117
|
+
const author = authorOf(object["author"]);
|
|
118
|
+
return {
|
|
119
|
+
...optional("version", object["version"]),
|
|
120
|
+
...optional("description", object["description"]),
|
|
121
|
+
...(author !== undefined && { author }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** `displayName`, `logo` and `category` from an object that carries them at its top level (a Cursor manifest, a Codex `interface`). */
|
|
126
|
+
function appearanceOf(object: JsonObject, index: PluginFileIndex): PluginPresentation {
|
|
127
|
+
const logo = logoPath(object["logo"], index);
|
|
128
|
+
return {
|
|
129
|
+
...optional("displayName", object["displayName"]),
|
|
130
|
+
...optional("category", object["category"]),
|
|
131
|
+
...(logo !== undefined && { logo }),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function authorOf(value: unknown): PluginAuthor | undefined {
|
|
136
|
+
if (!isJsonObject(value)) return undefined;
|
|
137
|
+
const author: { -readonly [K in keyof PluginAuthor]: PluginAuthor[K] } = {
|
|
138
|
+
...optional("name", value["name"]),
|
|
139
|
+
...optional("email", value["email"]),
|
|
140
|
+
...optional("url", value["url"]),
|
|
141
|
+
};
|
|
142
|
+
return Object.keys(author).length === 0 ? undefined : author;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A declared logo as a plugin-relative path the tree lists, or nothing.
|
|
147
|
+
* `./` is stripped (Codex's spelling); an absolute path, a `..` segment, a
|
|
148
|
+
* URL, a non-image extension, an unlisted file or an over-cap file all
|
|
149
|
+
* mean "no logo", never a refusal.
|
|
150
|
+
*/
|
|
151
|
+
function logoPath(value: unknown, index: PluginFileIndex): string | undefined {
|
|
152
|
+
if (typeof value !== "string") return undefined;
|
|
153
|
+
const path = value.startsWith("./") ? value.slice(2) : value;
|
|
154
|
+
if (!isContainedPath(path)) return undefined;
|
|
155
|
+
const dot = path.lastIndexOf(".");
|
|
156
|
+
if (dot === -1 || !LOGO_EXTENSIONS.has(path.slice(dot + 1).toLowerCase())) return undefined;
|
|
157
|
+
const entry = index.entry(path);
|
|
158
|
+
if (entry === undefined || entry.size > PLUGIN_DOCUMENT_LIMITS.logo) return undefined;
|
|
159
|
+
return path;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** `{ [key]: value }` when `value` is a non-empty string; `{}` otherwise. */
|
|
163
|
+
function optional<K extends string>(key: K, value: unknown): Partial<Record<K, string>> {
|
|
164
|
+
return typeof value === "string" && value !== "" ? ({ [key]: value } as Record<K, string>) : {};
|
|
165
|
+
}
|