@stigmer/plugin-package 3.15.3-dev.20260916211208

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.
Files changed (173) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +66 -0
  3. package/detect.d.ts +50 -0
  4. package/detect.d.ts.map +1 -0
  5. package/detect.js +164 -0
  6. package/detect.js.map +1 -0
  7. package/dialects/claude.d.ts +30 -0
  8. package/dialects/claude.d.ts.map +1 -0
  9. package/dialects/claude.js +71 -0
  10. package/dialects/claude.js.map +1 -0
  11. package/dialects/codex.d.ts +18 -0
  12. package/dialects/codex.d.ts.map +1 -0
  13. package/dialects/codex.js +19 -0
  14. package/dialects/codex.js.map +1 -0
  15. package/dialects/cursor.d.ts +23 -0
  16. package/dialects/cursor.d.ts.map +1 -0
  17. package/dialects/cursor.js +63 -0
  18. package/dialects/cursor.js.map +1 -0
  19. package/dialects/manifest.d.ts +109 -0
  20. package/dialects/manifest.d.ts.map +1 -0
  21. package/dialects/manifest.js +194 -0
  22. package/dialects/manifest.js.map +1 -0
  23. package/dialects/open.d.ts +18 -0
  24. package/dialects/open.d.ts.map +1 -0
  25. package/dialects/open.js +47 -0
  26. package/dialects/open.js.map +1 -0
  27. package/documents.d.ts +43 -0
  28. package/documents.d.ts.map +1 -0
  29. package/documents.js +111 -0
  30. package/documents.js.map +1 -0
  31. package/files.d.ts +114 -0
  32. package/files.d.ts.map +1 -0
  33. package/files.js +187 -0
  34. package/files.js.map +1 -0
  35. package/frontmatter.d.ts +51 -0
  36. package/frontmatter.d.ts.map +1 -0
  37. package/frontmatter.js +61 -0
  38. package/frontmatter.js.map +1 -0
  39. package/index.d.ts +19 -0
  40. package/index.d.ts.map +1 -0
  41. package/index.js +17 -0
  42. package/index.js.map +1 -0
  43. package/messages.d.ts +39 -0
  44. package/messages.d.ts.map +1 -0
  45. package/messages.js +135 -0
  46. package/messages.js.map +1 -0
  47. package/normalise/ignored.d.ts +24 -0
  48. package/normalise/ignored.d.ts.map +1 -0
  49. package/normalise/ignored.js +68 -0
  50. package/normalise/ignored.js.map +1 -0
  51. package/normalise/mcp-servers.d.ts +47 -0
  52. package/normalise/mcp-servers.d.ts.map +1 -0
  53. package/normalise/mcp-servers.js +397 -0
  54. package/normalise/mcp-servers.js.map +1 -0
  55. package/normalise/overlay.d.ts +27 -0
  56. package/normalise/overlay.d.ts.map +1 -0
  57. package/normalise/overlay.js +67 -0
  58. package/normalise/overlay.js.map +1 -0
  59. package/normalise/skills.d.ts +31 -0
  60. package/normalise/skills.d.ts.map +1 -0
  61. package/normalise/skills.js +116 -0
  62. package/normalise/skills.js.map +1 -0
  63. package/normalise/sub-agents.d.ts +44 -0
  64. package/normalise/sub-agents.d.ts.map +1 -0
  65. package/normalise/sub-agents.js +168 -0
  66. package/normalise/sub-agents.js.map +1 -0
  67. package/normalise/variables.d.ts +27 -0
  68. package/normalise/variables.d.ts.map +1 -0
  69. package/normalise/variables.js +155 -0
  70. package/normalise/variables.js.map +1 -0
  71. package/outcome.d.ts +46 -0
  72. package/outcome.d.ts.map +1 -0
  73. package/outcome.js +21 -0
  74. package/outcome.js.map +1 -0
  75. package/package.json +40 -0
  76. package/placeholders.d.ts +41 -0
  77. package/placeholders.d.ts.map +1 -0
  78. package/placeholders.js +68 -0
  79. package/placeholders.js.map +1 -0
  80. package/read-plugin-package.d.ts +19 -0
  81. package/read-plugin-package.d.ts.map +1 -0
  82. package/read-plugin-package.js +67 -0
  83. package/read-plugin-package.js.map +1 -0
  84. package/src/__test-utils__/directory-files.ts +29 -0
  85. package/src/__test-utils__/read.ts +55 -0
  86. package/src/__tests__/adversarial.test.ts +434 -0
  87. package/src/__tests__/detect.test.ts +133 -0
  88. package/src/__tests__/files.test.ts +119 -0
  89. package/src/__tests__/fixtures/cursor-plugins/NOTICE +22 -0
  90. package/src/__tests__/fixtures/cursor-plugins/advisor/.cursor-plugin/plugin.json +33 -0
  91. package/src/__tests__/fixtures/cursor-plugins/advisor/CHANGELOG.md +8 -0
  92. package/src/__tests__/fixtures/cursor-plugins/advisor/LICENSE +21 -0
  93. package/src/__tests__/fixtures/cursor-plugins/advisor/README.md +87 -0
  94. package/src/__tests__/fixtures/cursor-plugins/advisor/agents/advisor-subagent.md +48 -0
  95. package/src/__tests__/fixtures/cursor-plugins/advisor/assets/avatar.png +0 -0
  96. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/capture-response.sh +20 -0
  97. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/hooks.json +27 -0
  98. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/lib.sh +61 -0
  99. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/mark-pending.sh +27 -0
  100. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/record-consult.sh +41 -0
  101. package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/stop-hook.sh +48 -0
  102. package/src/__tests__/fixtures/cursor-plugins/advisor/skills/advisor/SKILL.md +123 -0
  103. package/src/__tests__/fixtures/cursor-plugins/advisor/skills/advisor/references/briefing-template.md +44 -0
  104. package/src/__tests__/fixtures/cursor-plugins/github/.cursor-plugin/plugin.json +45 -0
  105. package/src/__tests__/fixtures/cursor-plugins/github/CHANGELOG.md +9 -0
  106. package/src/__tests__/fixtures/cursor-plugins/github/LICENSE +21 -0
  107. package/src/__tests__/fixtures/cursor-plugins/github/README.md +64 -0
  108. package/src/__tests__/fixtures/cursor-plugins/github/assets/logo.svg +0 -0
  109. package/src/__tests__/fixtures/cursor-plugins/github/mcp.json +11 -0
  110. package/src/__tests__/fixtures/cursor-plugins/playwright/.cursor-plugin/plugin.json +35 -0
  111. package/src/__tests__/fixtures/cursor-plugins/playwright/CHANGELOG.md +8 -0
  112. package/src/__tests__/fixtures/cursor-plugins/playwright/LICENSE +21 -0
  113. package/src/__tests__/fixtures/cursor-plugins/playwright/README.md +46 -0
  114. package/src/__tests__/fixtures/cursor-plugins/playwright/assets/logo.svg +0 -0
  115. package/src/__tests__/fixtures/cursor-plugins/playwright/mcp.json +8 -0
  116. package/src/__tests__/fixtures/cursor-plugins/salesforce/.cursor-plugin/plugin.json +48 -0
  117. package/src/__tests__/fixtures/cursor-plugins/salesforce/CHANGELOG.md +10 -0
  118. package/src/__tests__/fixtures/cursor-plugins/salesforce/LICENSE +21 -0
  119. package/src/__tests__/fixtures/cursor-plugins/salesforce/README.md +95 -0
  120. package/src/__tests__/fixtures/cursor-plugins/salesforce/assets/logo.svg +0 -0
  121. package/src/__tests__/fixtures/cursor-plugins/salesforce/mcp.json +12 -0
  122. package/src/__tests__/fixtures/cursor-plugins/thermos/.cursor-plugin/plugin.json +32 -0
  123. package/src/__tests__/fixtures/cursor-plugins/thermos/CHANGELOG.md +8 -0
  124. package/src/__tests__/fixtures/cursor-plugins/thermos/LICENSE +21 -0
  125. package/src/__tests__/fixtures/cursor-plugins/thermos/README.md +70 -0
  126. package/src/__tests__/fixtures/cursor-plugins/thermos/agents/thermo-nuclear-code-quality-review-subagent.md +23 -0
  127. package/src/__tests__/fixtures/cursor-plugins/thermos/agents/thermo-nuclear-review-subagent.md +28 -0
  128. package/src/__tests__/fixtures/cursor-plugins/thermos/assets/logo.png +0 -0
  129. package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermo-nuclear-code-quality-review/SKILL.md +192 -0
  130. package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermo-nuclear-review/SKILL.md +51 -0
  131. package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermos/SKILL.md +21 -0
  132. package/src/__tests__/fixtures/cursor-plugins/xero/.cursor-plugin/plugin.json +53 -0
  133. package/src/__tests__/fixtures/cursor-plugins/xero/CHANGELOG.md +9 -0
  134. package/src/__tests__/fixtures/cursor-plugins/xero/LICENSE +21 -0
  135. package/src/__tests__/fixtures/cursor-plugins/xero/README.md +79 -0
  136. package/src/__tests__/fixtures/cursor-plugins/xero/assets/logo.png +0 -0
  137. package/src/__tests__/fixtures/cursor-plugins/xero/mcp.json +16 -0
  138. package/src/__tests__/fixtures.test.ts +198 -0
  139. package/src/__tests__/mcp-servers.test.ts +120 -0
  140. package/src/__tests__/overlay-and-ignored.test.ts +65 -0
  141. package/src/__tests__/skills.test.ts +89 -0
  142. package/src/__tests__/sub-agents.test.ts +111 -0
  143. package/src/__tests__/variables.test.ts +94 -0
  144. package/src/detect.ts +189 -0
  145. package/src/dialects/claude.ts +90 -0
  146. package/src/dialects/codex.ts +24 -0
  147. package/src/dialects/cursor.ts +73 -0
  148. package/src/dialects/manifest.ts +237 -0
  149. package/src/dialects/open.ts +48 -0
  150. package/src/documents.ts +145 -0
  151. package/src/files.ts +213 -0
  152. package/src/frontmatter.ts +70 -0
  153. package/src/index.ts +59 -0
  154. package/src/messages.ts +206 -0
  155. package/src/normalise/ignored.ts +70 -0
  156. package/src/normalise/mcp-servers.ts +427 -0
  157. package/src/normalise/overlay.ts +71 -0
  158. package/src/normalise/skills.ts +126 -0
  159. package/src/normalise/sub-agents.ts +184 -0
  160. package/src/normalise/variables.ts +161 -0
  161. package/src/outcome.ts +122 -0
  162. package/src/placeholders.ts +74 -0
  163. package/src/read-plugin-package.ts +74 -0
  164. package/src/testing.ts +258 -0
  165. package/src/types.ts +189 -0
  166. package/testing.d.ts +106 -0
  167. package/testing.d.ts.map +1 -0
  168. package/testing.js +182 -0
  169. package/testing.js.map +1 -0
  170. package/types.d.ts +152 -0
  171. package/types.d.ts.map +1 -0
  172. package/types.js +19 -0
  173. package/types.js.map +1 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The Cursor manifest (`.cursor-plugin/plugin.json`).
3
+ *
4
+ * Cursor publishes a draft-07 schema for this file (`additionalProperties:
5
+ * false`, only `name` required); the known-field set below is that schema's
6
+ * key list, and `author` there carries `name` and `email` only. Component
7
+ * fields `skills`, `agents`, `rules`, `commands` are a path or an array of
8
+ * paths (the schema says "glob pattern(s) or path(s)"; every published
9
+ * plugin uses a `./`-prefixed directory, and a glob is refused rather than
10
+ * expanded). `mcpServers` is a path, an inline object, or an array of
11
+ * either. `variables` is a JSON Schema object whose `properties` are the
12
+ * variables a user is prompted for and whose `required` list marks the
13
+ * mandatory ones; Cursor has no sensitivity flag, so Stigmer treats every
14
+ * Cursor variable as a secret. `rules`, `commands`, `hooks`, `logo` and
15
+ * `minClientVersions` are recorded as ignored; `displayName`, `publisher`,
16
+ * `category` and `tags` are marketplace metadata Stigmer neither carries
17
+ * nor warns about.
18
+ */
19
+ import type { JsonObject } from "../documents.js";
20
+ import type { Findings } from "../messages.js";
21
+ import { type DialectManifest } from "./manifest.js";
22
+ export declare function readCursorManifest(object: JsonObject, path: string, findings: Findings): DialectManifest;
23
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/dialects/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,KAAK,eAAe,EAMrB,MAAM,eAAe,CAAC;AA0BvB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAkBxG"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * The Cursor manifest (`.cursor-plugin/plugin.json`).
3
+ *
4
+ * Cursor publishes a draft-07 schema for this file (`additionalProperties:
5
+ * false`, only `name` required); the known-field set below is that schema's
6
+ * key list, and `author` there carries `name` and `email` only. Component
7
+ * fields `skills`, `agents`, `rules`, `commands` are a path or an array of
8
+ * paths (the schema says "glob pattern(s) or path(s)"; every published
9
+ * plugin uses a `./`-prefixed directory, and a glob is refused rather than
10
+ * expanded). `mcpServers` is a path, an inline object, or an array of
11
+ * either. `variables` is a JSON Schema object whose `properties` are the
12
+ * variables a user is prompted for and whose `required` list marks the
13
+ * mandatory ones; Cursor has no sensitivity flag, so Stigmer treats every
14
+ * Cursor variable as a secret. `rules`, `commands`, `hooks`, `logo` and
15
+ * `minClientVersions` are recorded as ignored; `displayName`, `publisher`,
16
+ * `category` and `tags` are marketplace metadata Stigmer neither carries
17
+ * nor warns about.
18
+ */
19
+ import { ignoredFieldComponents, readDeclaredPaths, readIdentity, readMcpSources, warnUnknownFields, } from "./manifest.js";
20
+ const KNOWN_FIELDS = new Set([
21
+ "name",
22
+ "displayName",
23
+ "description",
24
+ "version",
25
+ "minClientVersions",
26
+ "author",
27
+ "publisher",
28
+ "homepage",
29
+ "repository",
30
+ "license",
31
+ "logo",
32
+ "keywords",
33
+ "category",
34
+ "tags",
35
+ "commands",
36
+ "agents",
37
+ "skills",
38
+ "rules",
39
+ "hooks",
40
+ "variables",
41
+ "mcpServers",
42
+ ]);
43
+ export function readCursorManifest(object, path, findings) {
44
+ warnUnknownFields(object, KNOWN_FIELDS, path, findings);
45
+ const identity = readIdentity(object, path, findings);
46
+ const skillPaths = readDeclaredPaths(object, "skills", path, findings) ?? [];
47
+ const agentPaths = readDeclaredPaths(object, "agents", path, findings);
48
+ const manifest = {
49
+ dialect: "cursor",
50
+ path,
51
+ identity,
52
+ skillPaths,
53
+ mcpConfigs: readMcpSources(object, "mcpServers", path, "cursor", findings),
54
+ ignored: ignoredFieldComponents(object, path),
55
+ };
56
+ if (agentPaths !== undefined)
57
+ manifest.agentPaths = agentPaths;
58
+ if (object["variables"] !== undefined) {
59
+ manifest.variables = { dialect: "cursor", value: object["variables"], manifest: path };
60
+ }
61
+ return manifest;
62
+ }
63
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/dialects/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAEL,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,MAAM;IACN,aAAa;IACb,aAAa;IACb,SAAS;IACT,mBAAmB;IACnB,QAAQ;IACR,WAAW;IACX,UAAU;IACV,YAAY;IACZ,SAAS;IACT,MAAM;IACN,UAAU;IACV,UAAU;IACV,MAAM;IACN,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,OAAO;IACP,WAAW;IACX,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,MAAkB,EAAE,IAAY,EAAE,QAAkB;IACrF,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC7E,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAmE;QAC/E,OAAO,EAAE,QAAQ;QACjB,IAAI;QACJ,QAAQ;QACR,UAAU;QACV,UAAU,EAAE,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC;QAC1E,OAAO,EAAE,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC;KAC9C,CAAC;IACF,IAAI,UAAU,KAAK,SAAS;QAAE,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/D,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;QACtC,QAAQ,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACzF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The intermediate every dialect reader reduces its manifest to, and the
3
+ * field-reading helpers they share.
4
+ *
5
+ * A `DialectManifest` says what one manifest CONTRIBUTES: identity fields,
6
+ * declared component paths, MCP configuration sources, a variables block,
7
+ * and the fields it carries that Stigmer records as ignored. It does not
8
+ * decide anything across manifests: precedence, name conflicts and default
9
+ * locations are `detect.ts`'s, and turning declarations into skills,
10
+ * servers and variables is `normalise/`'s. Keeping the readers to "what
11
+ * does this file say" is what lets a plugin carry a root manifest and a
12
+ * vendor manifest at once and have both read.
13
+ *
14
+ * Unknown fields WARN in every dialect (the open format says report and
15
+ * ignore; Cursor's own validator would reject them, but a warning serves
16
+ * the author and the install still works). A known field of the wrong type
17
+ * is fatal (`manifest-field-type`), the open format's rule for any
18
+ * violation other than an unknown field.
19
+ */
20
+ import { type JsonObject } from "../documents.js";
21
+ import type { Findings } from "../messages.js";
22
+ import type { IgnoredComponent, IgnoredComponentKind, PluginAuthor, PluginDialect } from "../types.js";
23
+ export interface PluginIdentity {
24
+ readonly name?: string;
25
+ readonly version?: string;
26
+ readonly description?: string;
27
+ readonly author?: PluginAuthor;
28
+ readonly homepage?: string;
29
+ readonly repository?: string;
30
+ readonly license?: string;
31
+ readonly keywords?: readonly string[];
32
+ }
33
+ /** A component path a manifest declared, normalised, with where it was declared. */
34
+ export interface DeclaredPath {
35
+ /** Plugin-relative, no leading `./`, no trailing slash; the root is `""`. */
36
+ readonly path: string;
37
+ /** The manifest that declared it, for messages. */
38
+ readonly manifest: string;
39
+ }
40
+ /** Where MCP server entries come from: a configuration file, or an object inline in a manifest. */
41
+ export type McpConfigSource = {
42
+ readonly kind: "file";
43
+ readonly path: string;
44
+ readonly dialect: PluginDialect;
45
+ readonly manifest: string;
46
+ } | {
47
+ readonly kind: "inline";
48
+ readonly manifest: string;
49
+ readonly servers: unknown;
50
+ readonly dialect: PluginDialect;
51
+ };
52
+ /** A variables block, raw, tagged with the dialect whose shape it takes. */
53
+ export type VariablesDeclaration = {
54
+ readonly dialect: "cursor";
55
+ readonly value: unknown;
56
+ readonly manifest: string;
57
+ } | {
58
+ readonly dialect: "claude";
59
+ readonly value: unknown;
60
+ readonly manifest: string;
61
+ };
62
+ export interface DialectManifest {
63
+ readonly dialect: PluginDialect;
64
+ readonly path: string;
65
+ readonly identity: PluginIdentity;
66
+ /** Declared skill paths; the default `skills/` is scanned regardless. */
67
+ readonly skillPaths: readonly DeclaredPath[];
68
+ /** Declared agent paths; `undefined` leaves the default `agents/` scan in force. */
69
+ readonly agentPaths?: readonly DeclaredPath[];
70
+ readonly mcpConfigs: readonly McpConfigSource[];
71
+ readonly variables?: VariablesDeclaration;
72
+ readonly ignored: readonly IgnoredComponent[];
73
+ }
74
+ /** Warn once per field the dialect does not define. */
75
+ export declare function warnUnknownFields(object: JsonObject, known: ReadonlySet<string>, path: string, findings: Findings): void;
76
+ /**
77
+ * The identity fields every dialect shares. `author` is an object in every
78
+ * dialect (Cursor's schema has no `url`; the extra key is a warning there,
79
+ * reported by the caller's known-field set for `author`).
80
+ */
81
+ export declare function readIdentity(object: JsonObject, path: string, findings: Findings): PluginIdentity;
82
+ /**
83
+ * A path field (`skills`, `agents`, ...) as declared paths. A value that is
84
+ * not a path (wrong prefix, escape, glob) is reported and dropped; the
85
+ * rest are kept, so one bad entry does not hide the others.
86
+ */
87
+ export declare function readDeclaredPaths(object: JsonObject, field: string, path: string, findings: Findings): readonly DeclaredPath[] | undefined;
88
+ /**
89
+ * A vendor `mcpServers` field: a path, an inline `mcpServers` object, or an
90
+ * array of either. Each becomes one source under the dialect's rules.
91
+ */
92
+ export declare function readMcpSources(object: JsonObject, field: string, path: string, dialect: PluginDialect, findings: Findings): readonly McpConfigSource[];
93
+ /**
94
+ * Manifest fields Stigmer reads past, recorded as ignored components at
95
+ * `<manifest>#<field>` when present. Shared across dialects; each names the
96
+ * fields it knows through `known` so the same field is never also an
97
+ * unknown-field warning.
98
+ */
99
+ export declare const IGNORED_FIELD_KINDS: Readonly<Record<string, IgnoredComponentKind>>;
100
+ export declare function ignoredFieldComponents(object: JsonObject, path: string): IgnoredComponent[];
101
+ /**
102
+ * `extensions` in a root manifest: every namespace with content is an
103
+ * ignored component (a client ignores namespaces it does not implement
104
+ * without validating them); an empty object, including Stigmer's own
105
+ * reserved `ai.stigmer`, is silent. A non-object `extensions` is the open
106
+ * format's one non-fatal type violation: reported and ignored.
107
+ */
108
+ export declare function extensionComponents(object: JsonObject, path: string, findings: Findings): IgnoredComponent[];
109
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/dialects/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The intermediate every dialect reader reduces its manifest to, and the
3
+ * field-reading helpers they share.
4
+ *
5
+ * A `DialectManifest` says what one manifest CONTRIBUTES: identity fields,
6
+ * declared component paths, MCP configuration sources, a variables block,
7
+ * and the fields it carries that Stigmer records as ignored. It does not
8
+ * decide anything across manifests: precedence, name conflicts and default
9
+ * locations are `detect.ts`'s, and turning declarations into skills,
10
+ * servers and variables is `normalise/`'s. Keeping the readers to "what
11
+ * does this file say" is what lets a plugin carry a root manifest and a
12
+ * vendor manifest at once and have both read.
13
+ *
14
+ * Unknown fields WARN in every dialect (the open format says report and
15
+ * ignore; Cursor's own validator would reject them, but a warning serves
16
+ * the author and the install still works). A known field of the wrong type
17
+ * is fatal (`manifest-field-type`), the open format's rule for any
18
+ * violation other than an unknown field.
19
+ */
20
+ import { fields, isJsonObject, optionalString, optionalStringArray, stringOrStringArray } from "../documents.js";
21
+ import { resolveDeclaredPath } from "../files.js";
22
+ /** Warn once per field the dialect does not define. */
23
+ export function warnUnknownFields(object, known, path, findings) {
24
+ for (const [name] of fields(object)) {
25
+ if (!known.has(name))
26
+ findings.warn("manifest-field-unknown", { path, subject: name });
27
+ }
28
+ }
29
+ /**
30
+ * The identity fields every dialect shares. `author` is an object in every
31
+ * dialect (Cursor's schema has no `url`; the extra key is a warning there,
32
+ * reported by the caller's known-field set for `author`).
33
+ */
34
+ export function readIdentity(object, path, findings) {
35
+ const identity = {};
36
+ const name = optionalString(object, "name", path, findings);
37
+ if (name !== undefined)
38
+ identity.name = name;
39
+ const version = optionalString(object, "version", path, findings);
40
+ if (version !== undefined)
41
+ identity.version = version;
42
+ const description = optionalString(object, "description", path, findings);
43
+ if (description !== undefined)
44
+ identity.description = description;
45
+ const homepage = optionalString(object, "homepage", path, findings);
46
+ if (homepage !== undefined)
47
+ identity.homepage = homepage;
48
+ const repository = optionalString(object, "repository", path, findings);
49
+ if (repository !== undefined)
50
+ identity.repository = repository;
51
+ const license = optionalString(object, "license", path, findings);
52
+ if (license !== undefined)
53
+ identity.license = license;
54
+ const keywords = optionalStringArray(object, "keywords", path, findings);
55
+ if (keywords !== undefined)
56
+ identity.keywords = keywords;
57
+ const author = readAuthor(object, path, findings);
58
+ if (author !== undefined)
59
+ identity.author = author;
60
+ return identity;
61
+ }
62
+ function readAuthor(object, path, findings) {
63
+ const value = object["author"];
64
+ if (value === undefined)
65
+ return undefined;
66
+ if (!isJsonObject(value)) {
67
+ findings.error("manifest-field-type", { path, subject: "author", detail: "an object" });
68
+ return undefined;
69
+ }
70
+ const author = {};
71
+ const name = optionalString(value, "name", path, findings);
72
+ if (name !== undefined)
73
+ author.name = name;
74
+ const email = optionalString(value, "email", path, findings);
75
+ if (email !== undefined)
76
+ author.email = email;
77
+ const url = optionalString(value, "url", path, findings);
78
+ if (url !== undefined)
79
+ author.url = url;
80
+ return author;
81
+ }
82
+ /**
83
+ * A path field (`skills`, `agents`, ...) as declared paths. A value that is
84
+ * not a path (wrong prefix, escape, glob) is reported and dropped; the
85
+ * rest are kept, so one bad entry does not hide the others.
86
+ */
87
+ export function readDeclaredPaths(object, field, path, findings) {
88
+ const values = stringOrStringArray(object, field, path, findings);
89
+ if (values === undefined)
90
+ return undefined;
91
+ const declared = [];
92
+ for (const value of values) {
93
+ const resolved = resolveDeclaredPath(value);
94
+ if (!resolved.ok) {
95
+ findings.error(resolved.kind, { path, subject: value });
96
+ continue;
97
+ }
98
+ declared.push({ path: resolved.path, manifest: path });
99
+ }
100
+ return declared;
101
+ }
102
+ /**
103
+ * A vendor `mcpServers` field: a path, an inline `mcpServers` object, or an
104
+ * array of either. Each becomes one source under the dialect's rules.
105
+ */
106
+ export function readMcpSources(object, field, path, dialect, findings) {
107
+ const value = object[field];
108
+ if (value === undefined)
109
+ return [];
110
+ const items = Array.isArray(value) ? value : [value];
111
+ const sources = [];
112
+ for (const item of items) {
113
+ if (typeof item === "string") {
114
+ const resolved = resolveDeclaredPath(item);
115
+ if (!resolved.ok) {
116
+ findings.error(resolved.kind, { path, subject: item });
117
+ continue;
118
+ }
119
+ sources.push({ kind: "file", path: resolved.path, dialect, manifest: path });
120
+ }
121
+ else if (isJsonObject(item)) {
122
+ sources.push({ kind: "inline", manifest: path, servers: item, dialect });
123
+ }
124
+ else {
125
+ findings.error("manifest-field-type", { path, subject: field, detail: "a path, an object, or an array of either" });
126
+ }
127
+ }
128
+ return sources;
129
+ }
130
+ /**
131
+ * Manifest fields Stigmer reads past, recorded as ignored components at
132
+ * `<manifest>#<field>` when present. Shared across dialects; each names the
133
+ * fields it knows through `known` so the same field is never also an
134
+ * unknown-field warning.
135
+ */
136
+ export const IGNORED_FIELD_KINDS = {
137
+ hooks: "hooks",
138
+ rules: "rules",
139
+ commands: "commands",
140
+ workflows: "workflows",
141
+ outputStyles: "output-styles",
142
+ lspServers: "lsp-servers",
143
+ channels: "channels",
144
+ dependencies: "dependencies",
145
+ defaultEnabled: "default-enabled",
146
+ minClientVersions: "min-client-versions",
147
+ logo: "logo",
148
+ apps: "apps",
149
+ };
150
+ export function ignoredFieldComponents(object, path) {
151
+ const ignored = [];
152
+ for (const [name, value] of fields(object)) {
153
+ const kind = IGNORED_FIELD_KINDS[name];
154
+ if (kind !== undefined)
155
+ ignored.push({ kind, path: `${path}#${name}` });
156
+ if (name === "experimental" && isJsonObject(value)) {
157
+ for (const [sub] of fields(value)) {
158
+ const subKind = EXPERIMENTAL_KINDS[sub];
159
+ if (subKind !== undefined)
160
+ ignored.push({ kind: subKind, path: `${path}#experimental.${sub}` });
161
+ }
162
+ }
163
+ }
164
+ return ignored;
165
+ }
166
+ const EXPERIMENTAL_KINDS = {
167
+ themes: "themes",
168
+ monitors: "monitors",
169
+ evals: "evals",
170
+ };
171
+ /**
172
+ * `extensions` in a root manifest: every namespace with content is an
173
+ * ignored component (a client ignores namespaces it does not implement
174
+ * without validating them); an empty object, including Stigmer's own
175
+ * reserved `ai.stigmer`, is silent. A non-object `extensions` is the open
176
+ * format's one non-fatal type violation: reported and ignored.
177
+ */
178
+ export function extensionComponents(object, path, findings) {
179
+ const value = object["extensions"];
180
+ if (value === undefined)
181
+ return [];
182
+ if (!isJsonObject(value)) {
183
+ findings.warn("manifest-extensions-invalid", { path });
184
+ return [];
185
+ }
186
+ const ignored = [];
187
+ for (const [namespace, content] of fields(value)) {
188
+ if (isJsonObject(content) && fields(content).length === 0)
189
+ continue;
190
+ ignored.push({ kind: "extension", path: `${path}#extensions.${namespace}` });
191
+ }
192
+ return ignored;
193
+ }
194
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/dialects/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The Agent Plugins 1.0.0 root manifest (`plugin.json`).
3
+ *
4
+ * The open format's manifest is closed and versioned: `$schema` is required
5
+ * and must be the canonical 1.0.0 identifier, the ten permitted fields are
6
+ * fixed, an unknown field is reported and ignored, and any other violation
7
+ * is fatal. Components live at fixed locations only (`skills/`, `mcp.json`),
8
+ * so this manifest declares no paths and no inline servers; `mcp.json` is
9
+ * read under the open format's rules by `detect.ts` when it exists.
10
+ * Client-specific data belongs under `extensions`, which Stigmer records as
11
+ * ignored per namespace (its own `ai.stigmer` namespace is reserved and
12
+ * empty today).
13
+ */
14
+ import { type JsonObject } from "../documents.js";
15
+ import { type Findings } from "../messages.js";
16
+ import { type DialectManifest } from "./manifest.js";
17
+ export declare function readOpenManifest(object: JsonObject, path: string, findings: Findings): DialectManifest;
18
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/dialects/open.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAiC,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,KAAK,eAAe,EAAwD,MAAM,eAAe,CAAC;AAe3G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAgBtG"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The Agent Plugins 1.0.0 root manifest (`plugin.json`).
3
+ *
4
+ * The open format's manifest is closed and versioned: `$schema` is required
5
+ * and must be the canonical 1.0.0 identifier, the ten permitted fields are
6
+ * fixed, an unknown field is reported and ignored, and any other violation
7
+ * is fatal. Components live at fixed locations only (`skills/`, `mcp.json`),
8
+ * so this manifest declares no paths and no inline servers; `mcp.json` is
9
+ * read under the open format's rules by `detect.ts` when it exists.
10
+ * Client-specific data belongs under `extensions`, which Stigmer records as
11
+ * ignored per namespace (its own `ai.stigmer` namespace is reserved and
12
+ * empty today).
13
+ */
14
+ import { describeValue } from "../documents.js";
15
+ import { AGENT_PLUGINS_MANIFEST_SCHEMA } from "../messages.js";
16
+ import { extensionComponents, readIdentity, warnUnknownFields } from "./manifest.js";
17
+ const KNOWN_FIELDS = new Set([
18
+ "$schema",
19
+ "name",
20
+ "version",
21
+ "description",
22
+ "author",
23
+ "homepage",
24
+ "repository",
25
+ "license",
26
+ "keywords",
27
+ "extensions",
28
+ ]);
29
+ export function readOpenManifest(object, path, findings) {
30
+ const schema = object["$schema"];
31
+ if (schema === undefined) {
32
+ findings.error("manifest-schema-missing", { path });
33
+ }
34
+ else if (schema !== AGENT_PLUGINS_MANIFEST_SCHEMA) {
35
+ findings.error("manifest-schema-unsupported", { path, detail: describeValue(schema) });
36
+ }
37
+ warnUnknownFields(object, KNOWN_FIELDS, path, findings);
38
+ return {
39
+ dialect: "agent-plugins",
40
+ path,
41
+ identity: readIdentity(object, path, findings),
42
+ skillPaths: [],
43
+ mcpConfigs: [],
44
+ ignored: extensionComponents(object, path, findings),
45
+ };
46
+ }
47
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/dialects/open.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,6BAA6B,EAAiB,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAwB,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE3G,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,SAAS;IACT,MAAM;IACN,SAAS;IACT,aAAa;IACb,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,SAAS;IACT,UAAU;IACV,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,UAAU,gBAAgB,CAAC,MAAkB,EAAE,IAAY,EAAE,QAAkB;IACnF,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,QAAQ,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;SAAM,IAAI,MAAM,KAAK,6BAA6B,EAAE,CAAC;QACpD,QAAQ,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACxD,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,IAAI;QACJ,QAAQ,EAAE,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;QAC9C,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,EAAE;QACd,OAAO,EAAE,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;KACrD,CAAC;AACJ,CAAC"}
package/documents.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Reading one document through its cap, and the JSON shape checks every
3
+ * dialect reader repeats.
4
+ *
5
+ * `readText` is the only place the library calls `PluginFiles.read`: the
6
+ * declared size is checked against the document class's cap first, the
7
+ * returned length second, and an over-cap document becomes a
8
+ * `document-too-large` finding instead of a read. The JSON helpers turn a
9
+ * parse failure into a finding of the caller's kind and leave the value
10
+ * `unknown`, so each reader narrows fields with the `expect*` helpers and
11
+ * reports a wrong type with the field's name rather than trusting a cast.
12
+ */
13
+ import { type PluginDocumentClass, type PluginFileIndex } from "./files.js";
14
+ import type { Findings } from "./messages.js";
15
+ import type { PluginErrorKind } from "./outcome.js";
16
+ /** The document's text, or `undefined` after a `document-too-large` finding. */
17
+ export declare function readText(index: PluginFileIndex, path: string, cls: PluginDocumentClass, findings: Findings): string | undefined;
18
+ /** The document's bytes, or `undefined` after a `document-too-large` finding. */
19
+ export declare function readBytes(index: PluginFileIndex, path: string, cls: PluginDocumentClass, findings: Findings): Uint8Array | undefined;
20
+ /** A parsed JSON object (non-null, non-array), or `undefined` after a finding of `kind`. */
21
+ export declare function parseJsonObject(text: string, path: string, kind: Extract<PluginErrorKind, "manifest-unreadable" | "mcp-config-unreadable">, findings: Findings): JsonObject | undefined;
22
+ export type JsonObject = Readonly<Record<string, unknown>>;
23
+ export declare function isJsonObject(value: unknown): value is JsonObject;
24
+ export declare function isStringArray(value: unknown): value is readonly string[];
25
+ export declare function isStringRecord(value: unknown): value is Readonly<Record<string, string>>;
26
+ /** A JSON value as a sentence can quote it: a string as itself, anything else serialised. */
27
+ export declare function describeValue(value: unknown): string;
28
+ /**
29
+ * The fields of `object`, in the document's own order. `Object.entries`
30
+ * reads own enumerable properties only, so a `__proto__` key in the JSON is
31
+ * just another entry here and never reaches a prototype.
32
+ */
33
+ export declare function fields(object: JsonObject): readonly (readonly [string, unknown])[];
34
+ /** A string field or `undefined`; a present non-string reports `manifest-field-type`. */
35
+ export declare function optionalString(object: JsonObject, field: string, path: string, findings: Findings): string | undefined;
36
+ /** A string-array field or `undefined`; a present non-array-of-strings reports `manifest-field-type`. */
37
+ export declare function optionalStringArray(object: JsonObject, field: string, path: string, findings: Findings): readonly string[] | undefined;
38
+ /**
39
+ * A field that may be one string or an array of strings (the vendor
40
+ * dialects' path fields), normalised to an array; `undefined` when absent.
41
+ */
42
+ export declare function stringOrStringArray(object: JsonObject, field: string, path: string, findings: Findings): readonly string[] | undefined;
43
+ //# sourceMappingURL=documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAsC,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAChH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,gFAAgF;AAChF,wBAAgB,QAAQ,CACtB,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,QAAQ,GACjB,MAAM,GAAG,SAAS,CAGpB;AAED,iFAAiF;AACjF,wBAAgB,SAAS,CACvB,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,QAAQ,GACjB,UAAU,GAAG,SAAS,CAgBxB;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE,qBAAqB,GAAG,uBAAuB,CAAC,EAC/E,QAAQ,EAAE,QAAQ,GACjB,UAAU,GAAG,SAAS,CAaxB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,MAAM,EAAE,CAExE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAExF;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAElF;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAQtH;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,SAAS,MAAM,EAAE,GAAG,SAAS,CAQ/B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,SAAS,MAAM,EAAE,GAAG,SAAS,CAO/B"}
package/documents.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Reading one document through its cap, and the JSON shape checks every
3
+ * dialect reader repeats.
4
+ *
5
+ * `readText` is the only place the library calls `PluginFiles.read`: the
6
+ * declared size is checked against the document class's cap first, the
7
+ * returned length second, and an over-cap document becomes a
8
+ * `document-too-large` finding instead of a read. The JSON helpers turn a
9
+ * parse failure into a finding of the caller's kind and leave the value
10
+ * `unknown`, so each reader narrows fields with the `expect*` helpers and
11
+ * reports a wrong type with the field's name rather than trusting a cast.
12
+ */
13
+ import { decodeUtf8, PLUGIN_DOCUMENT_LIMITS } from "./files.js";
14
+ /** The document's text, or `undefined` after a `document-too-large` finding. */
15
+ export function readText(index, path, cls, findings) {
16
+ const bytes = readBytes(index, path, cls, findings);
17
+ return bytes === undefined ? undefined : decodeUtf8(bytes);
18
+ }
19
+ /** The document's bytes, or `undefined` after a `document-too-large` finding. */
20
+ export function readBytes(index, path, cls, findings) {
21
+ const limit = PLUGIN_DOCUMENT_LIMITS[cls];
22
+ const entry = index.entry(path);
23
+ if (entry === undefined) {
24
+ throw new Error(`plugin file '${path}' is not listed`);
25
+ }
26
+ if (entry.size > limit) {
27
+ findings.error("document-too-large", { path, subject: String(entry.size), detail: String(limit) });
28
+ return undefined;
29
+ }
30
+ const bytes = index.files.read(path);
31
+ if (bytes.length > limit) {
32
+ findings.error("document-too-large", { path, subject: String(bytes.length), detail: String(limit) });
33
+ return undefined;
34
+ }
35
+ return bytes;
36
+ }
37
+ /** A parsed JSON object (non-null, non-array), or `undefined` after a finding of `kind`. */
38
+ export function parseJsonObject(text, path, kind, findings) {
39
+ let value;
40
+ try {
41
+ value = JSON.parse(text);
42
+ }
43
+ catch (error) {
44
+ findings.error(kind, { path, detail: error instanceof Error ? error.message : String(error) });
45
+ return undefined;
46
+ }
47
+ if (!isJsonObject(value)) {
48
+ findings.error(kind, { path, detail: "the document is not a JSON object" });
49
+ return undefined;
50
+ }
51
+ return value;
52
+ }
53
+ export function isJsonObject(value) {
54
+ return typeof value === "object" && value !== null && !Array.isArray(value);
55
+ }
56
+ export function isStringArray(value) {
57
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
58
+ }
59
+ export function isStringRecord(value) {
60
+ return isJsonObject(value) && Object.values(value).every((item) => typeof item === "string");
61
+ }
62
+ /** A JSON value as a sentence can quote it: a string as itself, anything else serialised. */
63
+ export function describeValue(value) {
64
+ return typeof value === "string" ? value : JSON.stringify(value);
65
+ }
66
+ /**
67
+ * The fields of `object`, in the document's own order. `Object.entries`
68
+ * reads own enumerable properties only, so a `__proto__` key in the JSON is
69
+ * just another entry here and never reaches a prototype.
70
+ */
71
+ export function fields(object) {
72
+ return Object.entries(object);
73
+ }
74
+ /** A string field or `undefined`; a present non-string reports `manifest-field-type`. */
75
+ export function optionalString(object, field, path, findings) {
76
+ const value = object[field];
77
+ if (value === undefined)
78
+ return undefined;
79
+ if (typeof value !== "string") {
80
+ findings.error("manifest-field-type", { path, subject: field, detail: "a string" });
81
+ return undefined;
82
+ }
83
+ return value;
84
+ }
85
+ /** A string-array field or `undefined`; a present non-array-of-strings reports `manifest-field-type`. */
86
+ export function optionalStringArray(object, field, path, findings) {
87
+ const value = object[field];
88
+ if (value === undefined)
89
+ return undefined;
90
+ if (!isStringArray(value)) {
91
+ findings.error("manifest-field-type", { path, subject: field, detail: "an array of strings" });
92
+ return undefined;
93
+ }
94
+ return value;
95
+ }
96
+ /**
97
+ * A field that may be one string or an array of strings (the vendor
98
+ * dialects' path fields), normalised to an array; `undefined` when absent.
99
+ */
100
+ export function stringOrStringArray(object, field, path, findings) {
101
+ const value = object[field];
102
+ if (value === undefined)
103
+ return undefined;
104
+ if (typeof value === "string")
105
+ return [value];
106
+ if (isStringArray(value))
107
+ return value;
108
+ findings.error("manifest-field-type", { path, subject: field, detail: "a string or an array of strings" });
109
+ return undefined;
110
+ }
111
+ //# sourceMappingURL=documents.js.map