@stigmer/plugin-package 3.18.0-dev.20260918103812 → 3.18.0

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.
@@ -25,6 +25,13 @@
25
25
  * `readPluginPackage`; a consumer that wants to install it hands the same
26
26
  * directory to the walker it already uses. Keeping the two reads apart is
27
27
  * what lets a catalogue of eighty entries be listed without eighty reads.
28
+ *
29
+ * `readMarketplaceFile` is the same read without the tree: what the file
30
+ * declares, for a client that holds the file alone and asks only "does this
31
+ * source offer a plugin called X" before it pays for the tree (the CLI's
32
+ * bare-name search across GitHub sources fetches one small file per source
33
+ * instead of a zipball each). Whether the tree holds an entry is still
34
+ * `readMarketplace`'s to say, on the tree, before anything is installed.
28
35
  */
29
36
  import { hasPluginManifest, isValidPluginName } from "../detect.js";
30
37
  import { describeValue, isJsonObject, isStringArray } from "../documents.js";
@@ -43,6 +50,22 @@ export function hasMarketplaceFile(paths) {
43
50
  return false;
44
51
  }
45
52
  export function readMarketplace(files) {
53
+ return read(files, "tree");
54
+ }
55
+ /**
56
+ * The marketplace file as declared, the tree unverified: every entry with a
57
+ * readable source is offered, whether or not `files` holds its directory.
58
+ * For a client that has fetched the file alone; never for an install.
59
+ */
60
+ export function readMarketplaceFile(files) {
61
+ return read(files, "file");
62
+ }
63
+ /**
64
+ * `tree`: entries whose directory the tree lacks, or holds without a plugin
65
+ * manifest, are dropped with their warning. `file`: entries are taken as the
66
+ * file declares them, and the tree is not consulted.
67
+ */
68
+ function read(files, verify) {
46
69
  const findings = new MarketplaceFindings();
47
70
  const index = new PluginFileIndex(files);
48
71
  const located = locate(index);
@@ -56,7 +79,7 @@ export function readMarketplace(files) {
56
79
  return refused(findings);
57
80
  const name = readName(object, path, findings);
58
81
  const raw = readEntries(object, dialect, path, findings);
59
- const entries = offeredEntries(raw, index, path, findings);
82
+ const entries = verify === "tree" ? offeredEntries(raw, index, path, findings) : declaredEntries(raw);
60
83
  const defaults = resolveDefaults(object, raw, entries, dialect, path, findings);
61
84
  if (findings.errors.length > 0 || name === undefined)
62
85
  return refused(findings);
@@ -310,6 +333,20 @@ function offeredEntries(raw, index, path, findings) {
310
333
  }
311
334
  return offered;
312
335
  }
336
+ /** Every entry with a readable source, as the file declares it; the tree is not asked. */
337
+ function declaredEntries(raw) {
338
+ const declared = [];
339
+ for (const entry of raw) {
340
+ if (entry.dir === undefined)
341
+ continue;
342
+ declared.push({
343
+ name: entry.name,
344
+ dir: entry.dir,
345
+ ...(entry.description !== undefined && { description: entry.description }),
346
+ });
347
+ }
348
+ return declared;
349
+ }
313
350
  /** The files under `dir` as plugin-relative paths, so `hasPluginManifest` reads them as it reads a plugin's own listing. */
314
351
  function childFilesOf(index, dir) {
315
352
  const prefix = dir === "" ? "" : `${dir}/`;
@@ -1 +1 @@
1
- {"version":3,"file":"read-marketplace.js","sourceRoot":"","sources":["../../src/marketplace/read-marketplace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read-marketplace.js","sourceRoot":"","sources":["../../src/marketplace/read-marketplace.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigmer/plugin-package",
3
- "version": "3.18.0-dev.20260918103812",
3
+ "version": "3.18.0",
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,167 @@
1
+ /**
2
+ * The one preparation, reached three ways, and the small rules beside it.
3
+ *
4
+ * Pins: `preparePluginFromTree` over a lazily-read tree yields the CLI's
5
+ * recorded digest for the thermos fixture (the tripwire constant lives in
6
+ * `client-select-archive.test.ts`); it reads only the ignore files and the
7
+ * selected entries, never an ignored file's bytes; an over-cap selection is
8
+ * refused before any selected byte is read; a reader refusal is returned
9
+ * with the reader's findings. `isReleaseVersion`'s five cases, the two
10
+ * wrong answers the console and the CLI used to give among them.
11
+ * `rerootSingleDirectory` on the shapes a zip takes. The built-in sources'
12
+ * order, their reserved names, and that the official one is first.
13
+ */
14
+
15
+ import { readdirSync, readFileSync, statSync } from "node:fs";
16
+ import { fileURLToPath } from "node:url";
17
+
18
+ import { describe, expect, it } from "vitest";
19
+
20
+ import { BUILT_IN_MARKETPLACES, isBuiltInMarketplaceName } from "../client/builtin.js";
21
+ import { type LazyCandidate, preparePluginFromTree } from "../client/prepare.js";
22
+ import { OFFICIAL_MARKETPLACE_NAME } from "../client/refs.js";
23
+ import { isReleaseVersion } from "../client/release.js";
24
+ import { rerootSingleDirectory, stripDirectoryPrefix } from "../client/reroot.js";
25
+
26
+ const FIXTURES = fileURLToPath(new URL("./fixtures/cursor-plugins/", import.meta.url));
27
+ /** The CLI's digest for the thermos fixture, recorded in client-select-archive.test.ts. */
28
+ const THERMOS_DIGEST = "51bc4e5450e24762bb8515765c76bfe262f65c57f9afeda015c5818038396d5a";
29
+
30
+ const encoder = new TextEncoder();
31
+ const SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
32
+
33
+ function manifest(name: string): string {
34
+ return JSON.stringify({ $schema: SCHEMA, name, version: "1.0.0", description: `the ${name} plugin` });
35
+ }
36
+
37
+ /** A directory as a lazily-read tree, recording which paths were read. */
38
+ function lazyDirectory(root: string): { candidates: LazyCandidate[]; reads: string[] } {
39
+ const reads: string[] = [];
40
+ const candidates: LazyCandidate[] = [];
41
+ const walk = (dir: string, prefix: string): void => {
42
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
43
+ const path = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
44
+ const full = `${dir}/${entry.name}`;
45
+ if (entry.isDirectory()) walk(full, path);
46
+ else if (entry.isFile()) {
47
+ candidates.push({
48
+ path,
49
+ size: statSync(full).size,
50
+ read: async () => {
51
+ reads.push(path);
52
+ return new Uint8Array(readFileSync(full));
53
+ },
54
+ });
55
+ }
56
+ }
57
+ };
58
+ walk(root, "");
59
+ return { candidates, reads };
60
+ }
61
+
62
+ function lazyMemory(files: Record<string, string>): { candidates: LazyCandidate[]; reads: string[] } {
63
+ const reads: string[] = [];
64
+ const candidates = Object.entries(files).map(([path, text]) => {
65
+ const bytes = encoder.encode(text);
66
+ return {
67
+ path,
68
+ size: bytes.length,
69
+ read: async () => {
70
+ reads.push(path);
71
+ return bytes;
72
+ },
73
+ };
74
+ });
75
+ return { candidates, reads };
76
+ }
77
+
78
+ describe("preparePluginFromTree", () => {
79
+ it("yields the CLI's digest for the thermos fixture from a lazily-read tree", async () => {
80
+ const { candidates } = lazyDirectory(`${FIXTURES}thermos`);
81
+ const outcome = await preparePluginFromTree(candidates, { respectGitignore: true });
82
+ expect(outcome.ok).toBe(true);
83
+ if (!outcome.ok) return;
84
+ expect(outcome.prepared.digest).toBe(THERMOS_DIGEST);
85
+ expect(outcome.prepared.plugin.name).toBe("thermos");
86
+ expect(outcome.prepared.stats.filesIncluded).toBe(10);
87
+ });
88
+
89
+ it("reads the ignore file and the selected entries only, never an ignored file's bytes", async () => {
90
+ const tree = lazyMemory({
91
+ ".gitignore": "secrets.txt\n",
92
+ "plugin.json": manifest("quiet"),
93
+ "node_modules/left-pad/index.js": "module.exports = 1;",
94
+ "secrets.txt": "hunter2",
95
+ "skills/greet/SKILL.md": "---\nname: greet\ndescription: says hello\n---\nHello.",
96
+ });
97
+ const outcome = await preparePluginFromTree(tree.candidates, { respectGitignore: true });
98
+ expect(outcome.ok).toBe(true);
99
+ expect(tree.reads.sort()).toEqual([".gitignore", "plugin.json", "skills/greet/SKILL.md"]);
100
+ });
101
+
102
+ it("refuses an over-cap selection before a selected byte is read", async () => {
103
+ const tree = lazyMemory({
104
+ "plugin.json": manifest("heavy"),
105
+ "skills/big/SKILL.md": "x".repeat(2_000),
106
+ });
107
+ const outcome = await preparePluginFromTree(tree.candidates, { respectGitignore: true, maxBytes: 1_000 });
108
+ expect(outcome).toMatchObject({ ok: false, kind: "too-large", maxBytes: 1_000 });
109
+ if (outcome.ok || outcome.kind !== "too-large") return;
110
+ expect(outcome.selectedBytes).toBeGreaterThan(1_000);
111
+ expect(tree.reads).toEqual([]);
112
+ });
113
+
114
+ it("returns the reader's refusal with its findings when the tree is not a plugin", async () => {
115
+ const tree = lazyMemory({ "README.md": "not a plugin" });
116
+ const outcome = await preparePluginFromTree(tree.candidates, { respectGitignore: true });
117
+ expect(outcome.ok).toBe(false);
118
+ if (outcome.ok || outcome.kind !== "refused") throw new Error("expected the reader's refusal");
119
+ expect(outcome.errors.length).toBeGreaterThan(0);
120
+ });
121
+ });
122
+
123
+ describe("isReleaseVersion", () => {
124
+ it("accepts a release and a pre-release the lockstep publish covers", () => {
125
+ expect(isReleaseVersion("3.17.0")).toBe(true);
126
+ // The console used to call this a development build.
127
+ expect(isReleaseVersion("3.17.0-rc.1")).toBe(true);
128
+ });
129
+
130
+ it("refuses every shape a source or dev-channel build reports", () => {
131
+ // The CLI used to accept the bare stamp an unbundled server reports.
132
+ expect(isReleaseVersion("dev")).toBe(false);
133
+ expect(isReleaseVersion("0.0.0-dev")).toBe(false);
134
+ expect(isReleaseVersion("3.17.0-dev.20260918120000")).toBe(false);
135
+ expect(isReleaseVersion("3.17.0+build.5")).toBe(false);
136
+ expect(isReleaseVersion("")).toBe(false);
137
+ });
138
+ });
139
+
140
+ describe("rerootSingleDirectory", () => {
141
+ it("names the one directory every path is under", () => {
142
+ const paths = ["my-plugin/plugin.json", "my-plugin/skills/a/SKILL.md", "my-plugin/.gitignore"];
143
+ expect(rerootSingleDirectory(paths)).toBe("my-plugin");
144
+ expect(stripDirectoryPrefix(paths, "my-plugin")).toEqual(["plugin.json", "skills/a/SKILL.md", ".gitignore"]);
145
+ });
146
+
147
+ it("leaves a tree that is already rooted, or has two roots, alone", () => {
148
+ expect(rerootSingleDirectory(["plugin.json", "skills/a/SKILL.md"])).toBeNull();
149
+ expect(rerootSingleDirectory(["a/plugin.json", "b/plugin.json"])).toBeNull();
150
+ expect(rerootSingleDirectory(["a/plugin.json", "README.md"])).toBeNull();
151
+ expect(rerootSingleDirectory([])).toBeNull();
152
+ });
153
+ });
154
+
155
+ describe("BUILT_IN_MARKETPLACES", () => {
156
+ it("lists the official catalogue first, then the three vendors, each a reserved name", () => {
157
+ expect(BUILT_IN_MARKETPLACES.map((entry) => entry.name)).toEqual([
158
+ OFFICIAL_MARKETPLACE_NAME,
159
+ "cursor-plugins",
160
+ "claude-code-plugins",
161
+ "codex-plugins",
162
+ ]);
163
+ expect(BUILT_IN_MARKETPLACES[0]?.source).toEqual({ type: "official" });
164
+ for (const entry of BUILT_IN_MARKETPLACES) expect(isBuiltInMarketplaceName(entry.name)).toBe(true);
165
+ expect(isBuiltInMarketplaceName("acme-plugins")).toBe(false);
166
+ });
167
+ });
@@ -15,7 +15,7 @@ import { describe, expect, it } from "vitest";
15
15
 
16
16
  import { inMemoryPluginFiles, PLUGIN_DOCUMENT_LIMITS, type PluginFileEntry, type PluginFiles } from "../files.js";
17
17
  import type { Marketplace, MarketplaceErrorKind, MarketplaceFinding, MarketplaceReadOutcome, MarketplaceWarningKind } from "../marketplace/outcome.js";
18
- import { hasMarketplaceFile, readMarketplace } from "../marketplace/read-marketplace.js";
18
+ import { hasMarketplaceFile, readMarketplace, readMarketplaceFile } from "../marketplace/read-marketplace.js";
19
19
  import { cursorPlugin, openPlugin, type PluginFixture } from "../testing.js";
20
20
  import { directoryPluginFiles } from "../__test-utils__/directory-files.js";
21
21
  import { findingOf, type Kinds } from "../__test-utils__/read.js";
@@ -223,6 +223,18 @@ describe("the Cursor file, verbatim from cursor/plugins at c1c0a32, over a parti
223
223
  expect(new Set(outcome.warnings.map((w) => w.kind))).toEqual(new Set(["entry-directory-missing"]));
224
224
  });
225
225
 
226
+ it("read as a file alone, declares all seventy-nine with no directory warnings: the CLI's bare-name peek", () => {
227
+ const fileOnly = readMarketplaceFile(
228
+ inMemoryPluginFiles(new Map([[".cursor-plugin/marketplace.json", files.get(".cursor-plugin/marketplace.json")!]])),
229
+ );
230
+ const declared = accepted(fileOnly);
231
+ expect(declared.plugins).toHaveLength(79);
232
+ expect(declared.plugins.map((p) => p.name)).toContain("thermos");
233
+ expect(fileOnly.warnings.filter((w) => w.kind === "entry-directory-missing")).toEqual([]);
234
+ // Still refused for what the file itself gets wrong, exactly as the tree read is.
235
+ expect(readMarketplaceFile(inMemoryPluginFiles(new Map([["README.md", "x"]]))).ok).toBe(false);
236
+ });
237
+
226
238
  it("offers every entry when the whole catalogue is present (the sources all resolve inside the root)", () => {
227
239
  // Every source directory given one manifest, so the file's own shape is
228
240
  // proven independently of which plugins the fixtures vendor.
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The sources every client lists without being told: Stigmer's official
3
+ * catalogue and the three vendors' public ones.
4
+ *
5
+ * The product's promise is "bring your Cursor, Claude Code or Codex
6
+ * plugin", so the catalogues those vendors publish are on offer from the
7
+ * first screen, in the console's Marketplace and in `stigmer marketplace
8
+ * list`, without a user having to know a repository slug. They are code,
9
+ * not stored state: a client's remembered sources hold only what the user
10
+ * added, so the two clients cannot drift from each other and a vendor
11
+ * moving its repository is one release, not a migration. The names are
12
+ * reserved the way the official one is; a user can neither add nor remove
13
+ * them.
14
+ *
15
+ * Each vendor keeps its marketplace file at the repository root in its own
16
+ * location, all four of which `readMarketplace` reads (`.cursor-plugin/`,
17
+ * `.claude-plugin/`, `.agents/plugins/`). Measured on 2026-09-18 through
18
+ * the GitHub Trees API: 1,168, 1,594 and 7,746 entries respectively, none
19
+ * truncated, all under the console's 20,000-entry listing cap; Codex's
20
+ * catalogue names its entries as `{source: "local", path}` objects, which
21
+ * the reader accepts, and three of its 65 as remote sources, which it
22
+ * drops with its own sentence.
23
+ */
24
+
25
+ import type { GitHubMarketplaceSource } from "./refs.js";
26
+ import { OFFICIAL_MARKETPLACE_NAME } from "./refs.js";
27
+
28
+ /** A source a client ships with: named, described for a section heading, and either the official catalogue or a public GitHub tree. */
29
+ export interface BuiltInMarketplace {
30
+ readonly name: string;
31
+ /** One sentence for the Marketplace's section heading and `marketplace list`. */
32
+ readonly description: string;
33
+ readonly source: { readonly type: "official" } | GitHubMarketplaceSource;
34
+ }
35
+
36
+ /** In listing order: the official catalogue first, then the vendors in the order the product names them. */
37
+ export const BUILT_IN_MARKETPLACES: readonly BuiltInMarketplace[] = [
38
+ {
39
+ name: OFFICIAL_MARKETPLACE_NAME,
40
+ description: "Stigmer's official catalogue, published with each release.",
41
+ source: { type: "official" },
42
+ },
43
+ {
44
+ name: "cursor-plugins",
45
+ description: "Cursor's public plugin catalogue.",
46
+ source: { type: "github", repo: "cursor/plugins" },
47
+ },
48
+ {
49
+ name: "claude-code-plugins",
50
+ description: "Claude Code's public plugin catalogue.",
51
+ source: { type: "github", repo: "anthropics/claude-code" },
52
+ },
53
+ {
54
+ name: "codex-plugins",
55
+ description: "Codex's public plugin catalogue.",
56
+ source: { type: "github", repo: "openai/plugins" },
57
+ },
58
+ ];
59
+
60
+ const BUILT_IN_NAMES: ReadonlySet<string> = new Set(BUILT_IN_MARKETPLACES.map((entry) => entry.name));
61
+
62
+ /** Whether `name` is one a user may neither add nor remove. */
63
+ export function isBuiltInMarketplaceName(name: string): boolean {
64
+ return BUILT_IN_NAMES.has(name);
65
+ }
66
+
67
+ /** The one sentence every client refuses with when a user tries to add over or remove a built-in source. */
68
+ export function builtInSourceRefusal(name: string, act: "add" | "remove"): string {
69
+ switch (act) {
70
+ case "add":
71
+ return `'${name}' is a built-in source and cannot be added or replaced; choose another name`;
72
+ case "remove":
73
+ return `'${name}' is a built-in source and cannot be removed`;
74
+ default: {
75
+ const exhaustive: never = act;
76
+ return exhaustive;
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,160 @@
1
+ /**
2
+ * The preparation every client runs once it holds a tree: select the files
3
+ * a push carries, read the package and refuse what the reader refuses,
4
+ * archive, digest.
5
+ *
6
+ * Three clients arrive here with three kinds of tree: the CLI with a
7
+ * directory on disk, the console with a marketplace host's file listing,
8
+ * and the console again with a folder or a zip the user picked. What they
9
+ * do after selection is identical, and it is where the plugin's identity
10
+ * is made (the archive's bytes are `status.digest`), so it is written once.
11
+ * A parity test proves that one function reached three ways yields one
12
+ * digest for one tree; before this module each client carried its own copy
13
+ * of the chain and the test proved a coincidence.
14
+ *
15
+ * `preparePluginFromTree` is the lazy form for a tree whose bytes cost
16
+ * something to obtain (a fetch per file, a `File.arrayBuffer()`): it reads
17
+ * the two root ignore files, selects, refuses an over-cap selection before
18
+ * another byte moves, then reads only the files the archive will carry. A
19
+ * plugin folder holding a `node_modules/` costs its ignore file and its
20
+ * manifest, wherever the tree lives. The CLI keeps its own walk (a
21
+ * filesystem lets it skip a directory before listing it, which a flat tree
22
+ * cannot) and joins at `preparePluginArchive`.
23
+ *
24
+ * Refusals are returned, not thrown: each client renders the reader's
25
+ * findings in its own voice (the CLI's `pluginRefusal`, the console's
26
+ * `PluginReadRefusal`) and adds its own provenance around the result.
27
+ */
28
+
29
+ import type { PluginFiles } from "../files.js";
30
+ import type { PluginFinding } from "../outcome.js";
31
+ import { readPluginPackage } from "../read-plugin-package.js";
32
+ import type { PluginPackage } from "../types.js";
33
+ import { archivePlugin, digestArchive } from "./archive.js";
34
+ import {
35
+ type CandidateFile,
36
+ type SelectPluginFilesOptions,
37
+ type SelectionStats,
38
+ IGNORE_FILE_NAMES,
39
+ selectPluginFiles,
40
+ } from "./select.js";
41
+
42
+ /** What a client holds after preparation: the package as read, the bytes a push sends, and their identity. */
43
+ export interface PreparedPlugin {
44
+ readonly plugin: PluginPackage;
45
+ readonly warnings: readonly PluginFinding[];
46
+ /** The selected files, for the client that lists them (`push --dry-run`). */
47
+ readonly files: PluginFiles;
48
+ readonly stats: SelectionStats;
49
+ /** The exact bytes a push sends. */
50
+ readonly archive: Uint8Array;
51
+ /**
52
+ * SHA-256 of `archive`, lowercase hex: the identity the server records as
53
+ * `status.digest` (its digest is over the bytes it receives, and these are
54
+ * those bytes), so a client knows "already installed" without pushing.
55
+ */
56
+ readonly digest: string;
57
+ }
58
+
59
+ /** What an already-selected tree can come to: a prepared plugin, or the reader's refusal. */
60
+ export type PrepareArchiveOutcome =
61
+ | { readonly ok: true; readonly prepared: PreparedPlugin }
62
+ /** The reader refused the package; `errors` are its sentences, as `stigmer validate -f` prints them. */
63
+ | {
64
+ readonly ok: false;
65
+ readonly kind: "refused";
66
+ readonly errors: readonly PluginFinding[];
67
+ readonly warnings: readonly PluginFinding[];
68
+ };
69
+
70
+ /** What a lazily-read tree can come to: the above, or a refusal on size before its bytes were read. */
71
+ export type PreparePluginOutcome =
72
+ | PrepareArchiveOutcome
73
+ /** The selected files exceed the caller's `maxBytes`; nothing beyond the ignore files was read. */
74
+ | { readonly ok: false; readonly kind: "too-large"; readonly selectedBytes: number; readonly maxBytes: number };
75
+
76
+ /** A tree the client can list now and read later: a candidate with the promise of its bytes. */
77
+ export interface LazyCandidate extends CandidateFile {
78
+ read(): Promise<Uint8Array>;
79
+ }
80
+
81
+ export interface PrepareFromTreeOptions extends SelectPluginFilesOptions {
82
+ /**
83
+ * The most bytes the SELECTED files may total, refused before they are
84
+ * read. A client states its own budget (the console's is the archive cap
85
+ * a browser will hold in memory); omitted, nothing is refused here and
86
+ * the server's zip gate is the only limit.
87
+ */
88
+ readonly maxBytes?: number;
89
+ }
90
+
91
+ /**
92
+ * Read, refuse, archive and digest an already-selected tree. `selection`
93
+ * is what `selectPluginFiles` returns or what the CLI's walk builds in the
94
+ * same shape; its `files.read` must answer synchronously for every listed
95
+ * entry by now.
96
+ */
97
+ export async function preparePluginArchive(selection: {
98
+ readonly files: PluginFiles;
99
+ readonly stats: SelectionStats;
100
+ }): Promise<PrepareArchiveOutcome> {
101
+ const outcome = readPluginPackage(selection.files);
102
+ if (!outcome.ok) {
103
+ return { ok: false, kind: "refused", errors: outcome.errors, warnings: outcome.warnings };
104
+ }
105
+ const archive = archivePlugin(selection.files);
106
+ return {
107
+ ok: true,
108
+ prepared: {
109
+ plugin: outcome.plugin,
110
+ warnings: outcome.warnings,
111
+ files: selection.files,
112
+ stats: selection.stats,
113
+ archive,
114
+ digest: await digestArchive(archive),
115
+ },
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Prepare a tree whose bytes are obtained on demand. A byte is read only
121
+ * for a file that will be in the archive (plus the two root ignore files
122
+ * that decide which those are), and an over-cap selection is refused
123
+ * before any of them.
124
+ */
125
+ export async function preparePluginFromTree(
126
+ candidates: readonly LazyCandidate[],
127
+ options: PrepareFromTreeOptions,
128
+ ): Promise<PreparePluginOutcome> {
129
+ const byPath = new Map(candidates.map((candidate) => [candidate.path, candidate]));
130
+ const contents = new Map<string, Uint8Array>();
131
+ const fetchInto = async (path: string): Promise<void> => {
132
+ const candidate = byPath.get(path);
133
+ if (candidate === undefined) throw new Error(`plugin file '${path}' is not listed`);
134
+ contents.set(path, await candidate.read());
135
+ };
136
+ const read = (path: string): Uint8Array => {
137
+ const bytes = contents.get(path);
138
+ if (bytes === undefined) throw new Error(`plugin file '${path}' was not read before selection asked for it`);
139
+ return bytes;
140
+ };
141
+
142
+ // Phase 1: only the two files that shape the selection.
143
+ await Promise.all(
144
+ [IGNORE_FILE_NAMES.gitignore, IGNORE_FILE_NAMES.stigmerignore]
145
+ .filter((name) => byPath.has(name))
146
+ .map((name) => fetchInto(name)),
147
+ );
148
+ const { maxBytes, ...selectOptions } = options;
149
+ const selection = selectPluginFiles(candidates, read, selectOptions);
150
+
151
+ if (maxBytes !== undefined && selection.stats.totalSize > maxBytes) {
152
+ return { ok: false, kind: "too-large", selectedBytes: selection.stats.totalSize, maxBytes };
153
+ }
154
+
155
+ // Phase 2: exactly the files the archive carries.
156
+ await Promise.all(
157
+ selection.files.entries.filter((entry) => !contents.has(entry.path)).map((entry) => fetchInto(entry.path)),
158
+ );
159
+ return preparePluginArchive(selection);
160
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Whether a version string names a release the lockstep publish covers.
3
+ *
4
+ * The official catalogue (`@stigmer/plugins`) and the runtime packages are
5
+ * published at every release version and at every pre-release the release
6
+ * lane cuts (`X.Y.Z-rc.1` under the `next` tag), never for a source build
7
+ * (`dev`, `0.0.0-dev`) or a dev-channel stamp (`X.Y.Z-dev.<stamp>`). Two
8
+ * clients used to answer this with two different tests: the console
9
+ * accepted only `X.Y.Z` and called an `rc` server a development build; the
10
+ * CLI accepted anything without `-dev` and would have tried to acquire
11
+ * packages for the bare `dev` an unbundled server reports. One predicate,
12
+ * five cases pinned, no third opinion.
13
+ */
14
+
15
+ /**
16
+ * A semver core, optionally followed by a pre-release whose first
17
+ * identifier is not `dev`. Build metadata (`+…`) is not accepted: nothing
18
+ * publishes with it.
19
+ */
20
+ const RELEASE_PATTERN = /^\d+\.\d+\.\d+(?:-(?!dev(?:[.-]|$))[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
21
+
22
+ /** True for `3.17.0` and `3.17.0-rc.1`; false for `dev`, `0.0.0-dev` and `3.17.0-dev.20260918120000`. */
23
+ export function isReleaseVersion(version: string): boolean {
24
+ return RELEASE_PATTERN.test(version);
25
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The one directory a zipped folder wraps itself in, so the archive reads
3
+ * as the folder.
4
+ *
5
+ * `zip -r plugin.zip my-plugin/`, a Finder "Compress", and a browser's
6
+ * download of a repository all produce an archive whose every path begins
7
+ * with the folder's own name; the manifest a reader looks for at the root
8
+ * is then one level down. This decides, from the paths alone, whether that
9
+ * is the case: it is when every path shares exactly one leading directory
10
+ * and nothing sits beside it. A tree with a root file, or two top-level
11
+ * directories, is taken as it is; a reader that then finds no manifest says
12
+ * so in its own words.
13
+ *
14
+ * Pure over paths; the caller strips the prefix. Kept out of `select.ts`,
15
+ * which reasons about a tree that already has its root.
16
+ */
17
+
18
+ /** The shared leading directory of `paths`, or `null` when the tree is already rooted. */
19
+ export function rerootSingleDirectory(paths: readonly string[]): string | null {
20
+ let prefix: string | null = null;
21
+ for (const path of paths) {
22
+ const slash = path.indexOf("/");
23
+ if (slash <= 0) return null;
24
+ const head = path.slice(0, slash);
25
+ if (prefix === null) prefix = head;
26
+ else if (prefix !== head) return null;
27
+ }
28
+ return prefix;
29
+ }
30
+
31
+ /** `paths` with `prefix/` removed from each; the caller has established every path carries it. */
32
+ export function stripDirectoryPrefix(paths: readonly string[], prefix: string): string[] {
33
+ const cut = prefix.length + 1;
34
+ return paths.map((path) => path.slice(cut));
35
+ }