@agentxm/registry-protocol 0.28.12 → 0.28.13

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 (131) hide show
  1. package/README.md +13 -5
  2. package/dist/src/unstable/publish/index.d.ts +1 -6
  3. package/dist/src/unstable/publish/index.js +1 -6
  4. package/dist/src/unstable/registry/discover-schema.d.ts +4 -4
  5. package/dist/src/unstable/registry/index.d.ts +1 -0
  6. package/dist/src/unstable/registry/index.js +1 -0
  7. package/dist/src/unstable/registry/version-selection.d.ts +22 -0
  8. package/dist/src/unstable/registry/version-selection.js +39 -0
  9. package/package.json +11 -192
  10. package/dist/src/unstable/content/agent-skills-standard.d.ts +0 -17
  11. package/dist/src/unstable/content/agent-skills-standard.js +0 -24
  12. package/dist/src/unstable/content/frontmatter.d.ts +0 -52
  13. package/dist/src/unstable/content/frontmatter.js +0 -115
  14. package/dist/src/unstable/content/index.d.ts +0 -11
  15. package/dist/src/unstable/content/index.js +0 -11
  16. package/dist/src/unstable/content/skill-content.d.ts +0 -43
  17. package/dist/src/unstable/content/skill-content.js +0 -184
  18. package/dist/src/unstable/content/skill-types.d.ts +0 -22
  19. package/dist/src/unstable/content/skill-types.js +0 -9
  20. package/dist/src/unstable/content/subagent-content.d.ts +0 -58
  21. package/dist/src/unstable/content/subagent-content.js +0 -101
  22. package/dist/src/unstable/knowledge/index.d.ts +0 -8
  23. package/dist/src/unstable/knowledge/index.js +0 -8
  24. package/dist/src/unstable/knowledge/knowledge-search.d.ts +0 -32
  25. package/dist/src/unstable/knowledge/knowledge-search.js +0 -147
  26. package/dist/src/unstable/knowledge/okf.d.ts +0 -86
  27. package/dist/src/unstable/knowledge/okf.js +0 -1090
  28. package/dist/src/unstable/lint/catalog/hook/decision-portability.d.ts +0 -4
  29. package/dist/src/unstable/lint/catalog/hook/decision-portability.js +0 -40
  30. package/dist/src/unstable/lint/catalog/hook/entrypoint-exists.d.ts +0 -4
  31. package/dist/src/unstable/lint/catalog/hook/entrypoint-exists.js +0 -39
  32. package/dist/src/unstable/lint/catalog/hook/envelope.d.ts +0 -6
  33. package/dist/src/unstable/lint/catalog/hook/envelope.js +0 -15
  34. package/dist/src/unstable/lint/catalog/hook/matcher-raw-portability.d.ts +0 -4
  35. package/dist/src/unstable/lint/catalog/hook/matcher-raw-portability.js +0 -51
  36. package/dist/src/unstable/lint/catalog/hook.d.ts +0 -4
  37. package/dist/src/unstable/lint/catalog/hook.js +0 -15
  38. package/dist/src/unstable/lint/catalog/knowledge/diagnostics.d.ts +0 -128
  39. package/dist/src/unstable/lint/catalog/knowledge/diagnostics.js +0 -78
  40. package/dist/src/unstable/lint/catalog/knowledge/envelope.d.ts +0 -6
  41. package/dist/src/unstable/lint/catalog/knowledge/envelope.js +0 -15
  42. package/dist/src/unstable/lint/catalog/knowledge.d.ts +0 -5
  43. package/dist/src/unstable/lint/catalog/knowledge.js +0 -9
  44. package/dist/src/unstable/lint/catalog/mcp-server/envelope.d.ts +0 -6
  45. package/dist/src/unstable/lint/catalog/mcp-server/envelope.js +0 -15
  46. package/dist/src/unstable/lint/catalog/mcp-server.d.ts +0 -4
  47. package/dist/src/unstable/lint/catalog/mcp-server.js +0 -4
  48. package/dist/src/unstable/lint/catalog/pack/manifest-keys-recognized.d.ts +0 -28
  49. package/dist/src/unstable/lint/catalog/pack/manifest-keys-recognized.js +0 -38
  50. package/dist/src/unstable/lint/catalog/pack/manifest-present.d.ts +0 -17
  51. package/dist/src/unstable/lint/catalog/pack/manifest-present.js +0 -24
  52. package/dist/src/unstable/lint/catalog/pack/manifest-schema-valid.d.ts +0 -25
  53. package/dist/src/unstable/lint/catalog/pack/manifest-schema-valid.js +0 -33
  54. package/dist/src/unstable/lint/catalog/pack-accessor/contexts.d.ts +0 -51
  55. package/dist/src/unstable/lint/catalog/pack-accessor/contexts.js +0 -45
  56. package/dist/src/unstable/lint/catalog/pack-accessor/vft.d.ts +0 -60
  57. package/dist/src/unstable/lint/catalog/pack-accessor/vft.js +0 -85
  58. package/dist/src/unstable/lint/catalog/pack.d.ts +0 -31
  59. package/dist/src/unstable/lint/catalog/pack.js +0 -36
  60. package/dist/src/unstable/lint/catalog/rule/envelope.d.ts +0 -6
  61. package/dist/src/unstable/lint/catalog/rule/envelope.js +0 -15
  62. package/dist/src/unstable/lint/catalog/rule.d.ts +0 -4
  63. package/dist/src/unstable/lint/catalog/rule.js +0 -4
  64. package/dist/src/unstable/lint/catalog/shared/envelope-rules.d.ts +0 -88
  65. package/dist/src/unstable/lint/catalog/shared/envelope-rules.js +0 -84
  66. package/dist/src/unstable/lint/catalog/shared/manifest-json.d.ts +0 -18
  67. package/dist/src/unstable/lint/catalog/shared/manifest-json.js +0 -28
  68. package/dist/src/unstable/lint/catalog/shared/manifest-present.d.ts +0 -25
  69. package/dist/src/unstable/lint/catalog/shared/manifest-present.js +0 -37
  70. package/dist/src/unstable/lint/catalog/shared/recommended-packs-rules.d.ts +0 -70
  71. package/dist/src/unstable/lint/catalog/shared/recommended-packs-rules.js +0 -139
  72. package/dist/src/unstable/lint/catalog/shared/schema-rule.d.ts +0 -57
  73. package/dist/src/unstable/lint/catalog/shared/schema-rule.js +0 -102
  74. package/dist/src/unstable/lint/catalog/skill/frontmatter-parseable.d.ts +0 -31
  75. package/dist/src/unstable/lint/catalog/skill/frontmatter-parseable.js +0 -148
  76. package/dist/src/unstable/lint/catalog/skill/frontmatter-standard-valid.d.ts +0 -13
  77. package/dist/src/unstable/lint/catalog/skill/frontmatter-standard-valid.js +0 -61
  78. package/dist/src/unstable/lint/catalog/skill/manifest-keys-recognized.d.ts +0 -26
  79. package/dist/src/unstable/lint/catalog/skill/manifest-keys-recognized.js +0 -41
  80. package/dist/src/unstable/lint/catalog/skill/manifest-present.d.ts +0 -23
  81. package/dist/src/unstable/lint/catalog/skill/manifest-present.js +0 -32
  82. package/dist/src/unstable/lint/catalog/skill/manifest-schema-valid.d.ts +0 -21
  83. package/dist/src/unstable/lint/catalog/skill/manifest-schema-valid.js +0 -36
  84. package/dist/src/unstable/lint/catalog/skill/recommended-packs-valid.d.ts +0 -8
  85. package/dist/src/unstable/lint/catalog/skill/recommended-packs-valid.js +0 -12
  86. package/dist/src/unstable/lint/catalog/skill/skill-md-present.d.ts +0 -17
  87. package/dist/src/unstable/lint/catalog/skill/skill-md-present.js +0 -37
  88. package/dist/src/unstable/lint/catalog/skill/standalone-declaration-valid.d.ts +0 -8
  89. package/dist/src/unstable/lint/catalog/skill/standalone-declaration-valid.js +0 -12
  90. package/dist/src/unstable/lint/catalog/skill-accessor/contexts.d.ts +0 -61
  91. package/dist/src/unstable/lint/catalog/skill-accessor/contexts.js +0 -55
  92. package/dist/src/unstable/lint/catalog/skill-accessor/vft.d.ts +0 -77
  93. package/dist/src/unstable/lint/catalog/skill-accessor/vft.js +0 -135
  94. package/dist/src/unstable/lint/catalog/skill.d.ts +0 -38
  95. package/dist/src/unstable/lint/catalog/skill.js +0 -53
  96. package/dist/src/unstable/lint/catalog/subagent/envelope.d.ts +0 -6
  97. package/dist/src/unstable/lint/catalog/subagent/envelope.js +0 -15
  98. package/dist/src/unstable/lint/catalog/subagent.d.ts +0 -4
  99. package/dist/src/unstable/lint/catalog/subagent.js +0 -4
  100. package/dist/src/unstable/lint/catalog-metadata.d.ts +0 -125
  101. package/dist/src/unstable/lint/catalog-metadata.js +0 -642
  102. package/dist/src/unstable/lint/compose-path.d.ts +0 -28
  103. package/dist/src/unstable/lint/compose-path.js +0 -64
  104. package/dist/src/unstable/lint/config.d.ts +0 -77
  105. package/dist/src/unstable/lint/config.js +0 -99
  106. package/dist/src/unstable/lint/context.d.ts +0 -239
  107. package/dist/src/unstable/lint/context.js +0 -17
  108. package/dist/src/unstable/lint/describe-document.d.ts +0 -31
  109. package/dist/src/unstable/lint/describe-document.js +0 -50
  110. package/dist/src/unstable/lint/evaluate.d.ts +0 -47
  111. package/dist/src/unstable/lint/evaluate.js +0 -73
  112. package/dist/src/unstable/lint/issues-to-findings.d.ts +0 -35
  113. package/dist/src/unstable/lint/issues-to-findings.js +0 -149
  114. package/dist/src/unstable/lint/publish.d.ts +0 -49
  115. package/dist/src/unstable/lint/publish.js +0 -86
  116. package/dist/src/unstable/lint/rule.d.ts +0 -97
  117. package/dist/src/unstable/lint/rule.js +0 -17
  118. package/dist/src/unstable/publish/archive-guardrails.d.ts +0 -39
  119. package/dist/src/unstable/publish/archive-guardrails.js +0 -250
  120. package/dist/src/unstable/publish/filtered-package-validation.d.ts +0 -24
  121. package/dist/src/unstable/publish/filtered-package-validation.js +0 -117
  122. package/dist/src/unstable/publish/ingest-limits.d.ts +0 -25
  123. package/dist/src/unstable/publish/ingest-limits.js +0 -41
  124. package/dist/src/unstable/publish/input-normalization.d.ts +0 -40
  125. package/dist/src/unstable/publish/input-normalization.js +0 -125
  126. package/dist/src/unstable/publish/manifest-policy.d.ts +0 -611
  127. package/dist/src/unstable/publish/manifest-policy.js +0 -196
  128. package/dist/src/unstable/publish/test-zip-helpers.d.ts +0 -13
  129. package/dist/src/unstable/publish/test-zip-helpers.js +0 -117
  130. package/dist/src/unstable/registry/release-age-policy.d.ts +0 -57
  131. package/dist/src/unstable/registry/release-age-policy.js +0 -117
@@ -1,250 +0,0 @@
1
- import * as Data from "effect/Data";
2
- import * as Effect from "effect/Effect";
3
- export class ArchiveGuardrailError extends Data.TaggedError("ArchiveGuardrailError") {
4
- }
5
- const ZIP_EOCD_SIGNATURE = 0x06054b50;
6
- const ZIP_CDIR_SIGNATURE = 0x02014b50;
7
- export const ZIP_LOCAL_SIGNATURE = 0x04034b50;
8
- const COMPRESSION_STORE = 0;
9
- const COMPRESSION_DEFLATE = 8;
10
- const SUPPORTED_COMPRESSION = new Set([COMPRESSION_STORE, COMPRESSION_DEFLATE]);
11
- const S_IFLNK = 0xa000;
12
- const S_IFMT = 0xf000;
13
- const textDecoder = new TextDecoder();
14
- const DEFAULT_LIMITS = {
15
- maxEntries: 10_000,
16
- maxDecompressedBytes: 256 * 1024 * 1024,
17
- maxCompressionRatio: 100,
18
- };
19
- const findEocdOffset = (buf) => Effect.gen(function* () {
20
- const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
21
- const minOffset = Math.max(0, buf.length - 22 - 65535);
22
- for (let i = buf.length - 22; i >= minOffset; i--) {
23
- if (view.getUint32(i, true) === ZIP_EOCD_SIGNATURE) {
24
- return i;
25
- }
26
- }
27
- return yield* new ArchiveGuardrailError({
28
- code: "malformed_archive",
29
- message: "ZIP end-of-central-directory record not found.",
30
- });
31
- });
32
- export const parseZipCentralDirectory = (buf) => Effect.gen(function* () {
33
- if (buf.length < 22) {
34
- return yield* new ArchiveGuardrailError({
35
- code: "malformed_archive",
36
- message: "Archive too small to be a valid ZIP file.",
37
- });
38
- }
39
- const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
40
- if (view.getUint32(0, true) !== ZIP_LOCAL_SIGNATURE) {
41
- return yield* new ArchiveGuardrailError({
42
- code: "malformed_archive",
43
- message: "Archive does not start with a valid ZIP local file header signature.",
44
- });
45
- }
46
- const eocdOffset = yield* findEocdOffset(buf);
47
- const totalEntries = view.getUint16(eocdOffset + 10, true);
48
- const cdirSize = view.getUint32(eocdOffset + 12, true);
49
- const cdirOffset = view.getUint32(eocdOffset + 16, true);
50
- if (cdirOffset + cdirSize > buf.length) {
51
- return yield* new ArchiveGuardrailError({
52
- code: "malformed_archive",
53
- message: "Central directory offset and size exceed archive bounds.",
54
- });
55
- }
56
- const entries = [];
57
- let offset = cdirOffset;
58
- for (let i = 0; i < totalEntries; i++) {
59
- if (offset + 46 > buf.length) {
60
- return yield* new ArchiveGuardrailError({
61
- code: "malformed_archive",
62
- message: `Central directory entry ${i} exceeds archive bounds.`,
63
- });
64
- }
65
- const signature = view.getUint32(offset, true);
66
- if (signature !== ZIP_CDIR_SIGNATURE) {
67
- return yield* new ArchiveGuardrailError({
68
- code: "malformed_archive",
69
- message: `Invalid central directory entry signature at offset ${offset}.`,
70
- });
71
- }
72
- const compressionMethod = view.getUint16(offset + 10, true);
73
- const compressedSize = view.getUint32(offset + 20, true);
74
- const uncompressedSize = view.getUint32(offset + 24, true);
75
- const fileNameLength = view.getUint16(offset + 28, true);
76
- const extraFieldLength = view.getUint16(offset + 30, true);
77
- const fileCommentLength = view.getUint16(offset + 32, true);
78
- const externalAttributes = view.getUint32(offset + 38, true);
79
- const localHeaderOffset = view.getUint32(offset + 42, true);
80
- const fileNameStart = offset + 46;
81
- const fileNameEnd = fileNameStart + fileNameLength;
82
- if (fileNameEnd > buf.length) {
83
- return yield* new ArchiveGuardrailError({
84
- code: "malformed_archive",
85
- message: `File name for entry ${i} exceeds archive bounds.`,
86
- });
87
- }
88
- const fileName = textDecoder.decode(buf.slice(fileNameStart, fileNameEnd));
89
- entries.push({
90
- fileName,
91
- compressedSize,
92
- uncompressedSize,
93
- compressionMethod,
94
- externalAttributes,
95
- localHeaderOffset,
96
- });
97
- offset = fileNameEnd + extraFieldLength + fileCommentLength;
98
- }
99
- return entries;
100
- });
101
- const checkPathTraversal = (entries) => {
102
- for (const entry of entries) {
103
- const normalized = entry.fileName.replace(/\\/g, "/");
104
- if (normalized.includes("../") || normalized.includes("/..") || normalized === "..") {
105
- return Effect.fail(new ArchiveGuardrailError({
106
- code: "path_traversal",
107
- message: `Archive entry contains path traversal: "${entry.fileName}".`,
108
- entry: entry.fileName,
109
- }));
110
- }
111
- }
112
- return Effect.void;
113
- };
114
- const checkAbsolutePaths = (entries) => {
115
- for (const entry of entries) {
116
- const normalized = entry.fileName.replace(/\\/g, "/");
117
- if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized)) {
118
- return Effect.fail(new ArchiveGuardrailError({
119
- code: "absolute_path",
120
- message: `Archive entry contains an absolute path: "${entry.fileName}".`,
121
- entry: entry.fileName,
122
- }));
123
- }
124
- }
125
- return Effect.void;
126
- };
127
- const checkDuplicateEntries = (entries) => {
128
- const seen = new Set();
129
- for (const entry of entries) {
130
- const normalized = entry.fileName.toLowerCase();
131
- if (seen.has(normalized)) {
132
- return Effect.fail(new ArchiveGuardrailError({
133
- code: "duplicate_entry",
134
- message: `Archive contains duplicate entry: "${entry.fileName}".`,
135
- entry: entry.fileName,
136
- }));
137
- }
138
- seen.add(normalized);
139
- }
140
- return Effect.void;
141
- };
142
- const checkSymlinks = (entries) => {
143
- for (const entry of entries) {
144
- const unixMode = entry.externalAttributes >>> 16;
145
- if ((unixMode & S_IFMT) === S_IFLNK) {
146
- return Effect.fail(new ArchiveGuardrailError({
147
- code: "symlink_entry",
148
- message: `Archive contains symlink entry: "${entry.fileName}".`,
149
- entry: entry.fileName,
150
- }));
151
- }
152
- }
153
- return Effect.void;
154
- };
155
- const checkCompressionMethods = (entries) => {
156
- for (const entry of entries) {
157
- if (!SUPPORTED_COMPRESSION.has(entry.compressionMethod)) {
158
- return Effect.fail(new ArchiveGuardrailError({
159
- code: "unsupported_compression",
160
- message: `Archive entry uses unsupported compression method ${entry.compressionMethod}: "${entry.fileName}".`,
161
- entry: entry.fileName,
162
- }));
163
- }
164
- }
165
- return Effect.void;
166
- };
167
- const checkEntryCount = (entries, limits) => entries.length > limits.maxEntries
168
- ? Effect.fail(new ArchiveGuardrailError({
169
- code: "entry_count_exceeded",
170
- message: `Archive contains ${entries.length} entries, exceeding the maximum allowed ${limits.maxEntries}.`,
171
- }))
172
- : Effect.void;
173
- const checkDecompressedSize = (entries, limits) => {
174
- let totalUncompressed = 0;
175
- for (const entry of entries) {
176
- totalUncompressed += entry.uncompressedSize;
177
- if (totalUncompressed > limits.maxDecompressedBytes) {
178
- return Effect.fail(new ArchiveGuardrailError({
179
- code: "decompression_limit_exceeded",
180
- message: `Archive decompressed size exceeds maximum allowed ${limits.maxDecompressedBytes} bytes.`,
181
- entry: entry.fileName,
182
- }));
183
- }
184
- }
185
- return Effect.void;
186
- };
187
- const checkCompressionRatio = (entries, limits) => {
188
- for (const entry of entries) {
189
- if (entry.compressedSize === 0) {
190
- if (entry.uncompressedSize > 0) {
191
- return Effect.fail(new ArchiveGuardrailError({
192
- code: "compression_ratio_exceeded",
193
- message: `Archive entry "${entry.fileName}" exceeds maximum compression ratio.`,
194
- entry: entry.fileName,
195
- }));
196
- }
197
- continue;
198
- }
199
- const ratio = entry.uncompressedSize / entry.compressedSize;
200
- if (ratio > limits.maxCompressionRatio) {
201
- return Effect.fail(new ArchiveGuardrailError({
202
- code: "compression_ratio_exceeded",
203
- message: `Archive entry "${entry.fileName}" exceeds maximum compression ratio ${limits.maxCompressionRatio}.`,
204
- entry: entry.fileName,
205
- }));
206
- }
207
- }
208
- return Effect.void;
209
- };
210
- const FORBIDDEN_SEGMENTS = new Set(["node_modules", ".git"]);
211
- /**
212
- * Reject archives carrying build or secret leftovers: any `node_modules` or
213
- * `.git` path segment, and `.env` / `.env.*` files. Kept out of
214
- * {@link validateArchive} on purpose — that function is the registry ingest
215
- * contract, and archives accepted by earlier clients must keep ingesting.
216
- *
217
- * `.env*` matches the basename exactly (`.env`) or by dotted prefix
218
- * (`.env.local`, `.env.production`, and also `.env.example`), so sibling names
219
- * like `.envrc` and `environment.md` are unaffected.
220
- */
221
- export const checkForbiddenSourceEntries = (entries) => {
222
- for (const entry of entries) {
223
- const segments = entry.fileName.replace(/\\/g, "/").split("/");
224
- const basename = segments[segments.length - 1] ?? "";
225
- if (segments.some((segment) => FORBIDDEN_SEGMENTS.has(segment)) ||
226
- basename === ".env" ||
227
- basename.startsWith(".env.")) {
228
- return Effect.fail(new ArchiveGuardrailError({
229
- code: "forbidden_entry",
230
- message: `Archive contains a forbidden entry: "${entry.fileName}".`,
231
- entry: entry.fileName,
232
- }));
233
- }
234
- }
235
- return Effect.void;
236
- };
237
- export const validateArchive = (archiveBytes, limits) => Effect.gen(function* () {
238
- const appliedLimits = { ...DEFAULT_LIMITS, ...limits };
239
- const entries = yield* parseZipCentralDirectory(archiveBytes);
240
- yield* checkPathTraversal(entries);
241
- yield* checkAbsolutePaths(entries);
242
- yield* checkDuplicateEntries(entries);
243
- yield* checkSymlinks(entries);
244
- yield* checkCompressionMethods(entries);
245
- yield* checkEntryCount(entries, appliedLimits);
246
- yield* checkDecompressedSize(entries, appliedLimits);
247
- yield* checkCompressionRatio(entries, appliedLimits);
248
- return entries;
249
- });
250
- //# sourceMappingURL=archive-guardrails.js.map
@@ -1,24 +0,0 @@
1
- import * as Effect from "effect/Effect";
2
- import type { ExtensionType } from "@agentxm/extension-model/unstable/extensions";
3
- import type { ArchiveGuardrailError, ZipEntry } from "./archive-guardrails.js";
4
- import type { ResolvedManifest } from "./manifest-policy.js";
5
- declare const FilteredPackageError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
6
- readonly _tag: "FilteredPackageError";
7
- } & Readonly<A>;
8
- /** A type-specific package invariant failed against the filtered archive. */
9
- export declare class FilteredPackageError extends FilteredPackageError_base<{
10
- readonly code: "required_file_missing" | "content_invalid" | "reference_invalid";
11
- readonly detail: string;
12
- readonly path?: string;
13
- }> {
14
- }
15
- export interface ValidateFilteredPackageArgs {
16
- readonly type: ExtensionType;
17
- readonly entries: ReadonlyArray<ZipEntry>;
18
- readonly manifest: ResolvedManifest;
19
- readonly readEntry: (fileName: string) => Effect.Effect<Uint8Array, ArchiveGuardrailError | FilteredPackageError>;
20
- }
21
- /** Validate the complete type-specific package after Registry-only filtering. */
22
- export declare const validateFilteredPackage: (args: ValidateFilteredPackageArgs) => Effect.Effect<void, FilteredPackageError>;
23
- export {};
24
- //# sourceMappingURL=filtered-package-validation.d.ts.map
@@ -1,117 +0,0 @@
1
- import * as Data from "effect/Data";
2
- import * as Effect from "effect/Effect";
3
- import * as Option from "effect/Option";
4
- import { parseFrontmatterEffect } from "../content/frontmatter.js";
5
- import { inspectKnowledgeEntries } from "../knowledge/okf.js";
6
- import { parseSkillMd } from "../content/skill-content.js";
7
- import { parseSubagentMd } from "../content/subagent-content.js";
8
- /** A type-specific package invariant failed against the filtered archive. */
9
- export class FilteredPackageError extends Data.TaggedError("FilteredPackageError") {
10
- }
11
- const rawField = (raw, field) => typeof raw === "object" && raw !== null && !Array.isArray(raw)
12
- ? Reflect.get(raw, field)
13
- : undefined;
14
- const safeArchivePath = (value) => value.length > 0 &&
15
- !value.startsWith("/") &&
16
- !value.includes("\\") &&
17
- !value.split("/").some((segment) => segment === "" || segment === "." || segment === "..");
18
- const requireEntry = (entries, path) => {
19
- const found = entries.find((entry) => entry.fileName === path);
20
- return found === undefined
21
- ? Effect.fail(new FilteredPackageError({
22
- code: "required_file_missing",
23
- detail: `Filtered ${path} is required by this package type.`,
24
- path,
25
- }))
26
- : Effect.succeed(found);
27
- };
28
- const readText = (args, path) => Effect.gen(function* () {
29
- yield* requireEntry(args.entries, path);
30
- const bytes = yield* args.readEntry(path).pipe(Effect.mapError(() => new FilteredPackageError({
31
- code: "content_invalid",
32
- detail: `Could not read filtered package file "${path}".`,
33
- path,
34
- })));
35
- return new TextDecoder().decode(bytes);
36
- });
37
- /** Validate the complete type-specific package after Registry-only filtering. */
38
- export const validateFilteredPackage = (args) => Effect.gen(function* () {
39
- const name = args.manifest.identity.name;
40
- switch (args.type) {
41
- case "skill": {
42
- const path = "src/SKILL.md";
43
- const content = yield* readText(args, path);
44
- if (Option.isNone(parseSkillMd(content, name))) {
45
- return yield* new FilteredPackageError({
46
- code: "content_invalid",
47
- detail: `Filtered "${path}" must contain valid Agent Skill frontmatter whose name is "${name}".`,
48
- path,
49
- });
50
- }
51
- return;
52
- }
53
- case "subagent": {
54
- const path = `src/${name}.md`;
55
- const content = yield* readText(args, path);
56
- yield* parseSubagentMd(content, name).pipe(Effect.mapError(() => new FilteredPackageError({
57
- code: "content_invalid",
58
- detail: `Filtered "${path}" must contain valid subagent frontmatter whose name is "${name}".`,
59
- path,
60
- })));
61
- return;
62
- }
63
- case "rule": {
64
- const path = "src/RULE.md";
65
- const content = yield* readText(args, path);
66
- yield* parseFrontmatterEffect(content).pipe(Effect.mapError(() => new FilteredPackageError({
67
- code: "content_invalid",
68
- detail: `Filtered "${path}" contains invalid frontmatter.`,
69
- path,
70
- })));
71
- return;
72
- }
73
- case "hook": {
74
- const entrypoint = rawField(args.manifest.raw, "entrypoint");
75
- if (typeof entrypoint !== "string" || !safeArchivePath(entrypoint)) {
76
- return yield* new FilteredPackageError({
77
- code: "reference_invalid",
78
- detail: "Hook entrypoint must be a safe package-relative file path.",
79
- });
80
- }
81
- yield* requireEntry(args.entries, entrypoint);
82
- return;
83
- }
84
- case "knowledge": {
85
- if (rawField(args.manifest.raw, "bundleRoot") !== "src") {
86
- return yield* new FilteredPackageError({
87
- code: "reference_invalid",
88
- detail: "Knowledge bundleRoot must resolve to the filtered src directory.",
89
- });
90
- }
91
- yield* readText(args, "src/index.md");
92
- const sourcePrefix = "src/";
93
- const knowledgeEntries = args.entries
94
- .filter((entry) => entry.fileName.startsWith(sourcePrefix))
95
- .map((entry) => ({
96
- relativePath: entry.fileName.slice(sourcePrefix.length),
97
- type: "File",
98
- size: BigInt(entry.uncompressedSize),
99
- }));
100
- const inspection = yield* inspectKnowledgeEntries(knowledgeEntries, (relativePath) => readText(args, `${sourcePrefix}${relativePath}`));
101
- const errors = inspection.diagnostics.filter((diagnostic) => diagnostic.severity === "error");
102
- if (errors.length > 0) {
103
- return yield* new FilteredPackageError({
104
- code: "content_invalid",
105
- detail: `Filtered Knowledge bundle is invalid: ${errors
106
- .map((diagnostic) => `${diagnostic.relativePath}: ${diagnostic.message}`)
107
- .join("; ")}`,
108
- });
109
- }
110
- return;
111
- }
112
- case "mcp-server":
113
- case "pack":
114
- return;
115
- }
116
- });
117
- //# sourceMappingURL=filtered-package-validation.js.map
@@ -1,25 +0,0 @@
1
- import * as Result from "effect/Result";
2
- export declare const REGISTRY_PUBLISH_MAX_REQUEST_BYTES: number;
3
- export declare const REGISTRY_PUBLISH_MAX_ARCHIVE_BYTES: number;
4
- declare const IngestLimitError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
5
- readonly _tag: "IngestLimitError";
6
- } & Readonly<A>;
7
- export declare class IngestLimitError extends IngestLimitError_base<{
8
- readonly code: "ingest_request_too_large" | "ingest_archive_too_large" | "ingest_decompression_limit";
9
- readonly detail: string;
10
- readonly limit?: number;
11
- readonly actual?: number;
12
- }> {
13
- }
14
- declare const IngestUnsupportedContentTypeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
15
- readonly _tag: "IngestUnsupportedContentTypeError";
16
- } & Readonly<A>;
17
- export declare class IngestUnsupportedContentTypeError extends IngestUnsupportedContentTypeError_base<{
18
- readonly detail: string;
19
- }> {
20
- }
21
- export declare const enforceRequestSizeLimit: (contentLength: number | undefined, maxBytes?: number) => Result.Result<void, IngestLimitError>;
22
- export declare const enforceArchiveSizeLimit: (archiveBytes: number, maxBytes?: number) => Result.Result<void, IngestLimitError>;
23
- export declare const enforceArchiveContentType: (contentType: string | undefined) => Result.Result<void, IngestUnsupportedContentTypeError>;
24
- export {};
25
- //# sourceMappingURL=ingest-limits.d.ts.map
@@ -1,41 +0,0 @@
1
- import * as Data from "effect/Data";
2
- import * as Result from "effect/Result";
3
- export const REGISTRY_PUBLISH_MAX_REQUEST_BYTES = 35 * 1024 * 1024;
4
- export const REGISTRY_PUBLISH_MAX_ARCHIVE_BYTES = 25 * 1024 * 1024;
5
- export class IngestLimitError extends Data.TaggedError("IngestLimitError") {
6
- }
7
- export class IngestUnsupportedContentTypeError extends Data.TaggedError("IngestUnsupportedContentTypeError") {
8
- }
9
- export const enforceRequestSizeLimit = (contentLength, maxBytes = REGISTRY_PUBLISH_MAX_REQUEST_BYTES) => {
10
- if (contentLength !== undefined && contentLength > maxBytes) {
11
- return Result.fail(new IngestLimitError({
12
- code: "ingest_request_too_large",
13
- detail: `Request body exceeds maximum size of ${maxBytes} bytes.`,
14
- limit: maxBytes,
15
- actual: contentLength,
16
- }));
17
- }
18
- return Result.void;
19
- };
20
- export const enforceArchiveSizeLimit = (archiveBytes, maxBytes = REGISTRY_PUBLISH_MAX_ARCHIVE_BYTES) => {
21
- if (archiveBytes > maxBytes) {
22
- return Result.fail(new IngestLimitError({
23
- code: "ingest_archive_too_large",
24
- detail: `Archive exceeds maximum size of ${maxBytes} bytes.`,
25
- limit: maxBytes,
26
- actual: archiveBytes,
27
- }));
28
- }
29
- return Result.void;
30
- };
31
- const V1_ARCHIVE_CONTENT_TYPES = new Set(["application/zip"]);
32
- export const enforceArchiveContentType = (contentType) => {
33
- const normalized = contentType?.split(";")[0]?.trim().toLowerCase();
34
- if (!normalized || !V1_ARCHIVE_CONTENT_TYPES.has(normalized)) {
35
- return Result.fail(new IngestUnsupportedContentTypeError({
36
- detail: `Unsupported archive content type: ${contentType ?? "(none)"}. Supported: application/zip.`,
37
- }));
38
- }
39
- return Result.void;
40
- };
41
- //# sourceMappingURL=ingest-limits.js.map
@@ -1,40 +0,0 @@
1
- import * as Effect from "effect/Effect";
2
- import type { ExtensionName, ExtensionType } from "@agentxm/extension-model/unstable/extensions";
3
- import type { Handle } from "@agentxm/extension-model/unstable/extensions/handle";
4
- import { ArchiveGuardrailError, type ArchiveGuardrailLimits, type ZipEntry } from "./archive-guardrails.js";
5
- import { type IngestLimitError, type IngestUnsupportedContentTypeError } from "./ingest-limits.js";
6
- import { type ManifestError, type ResolvedManifest } from "./manifest-policy.js";
7
- import type { Version } from "@agentxm/extension-model/unstable/version-constraints";
8
- import { FilteredPackageError } from "./filtered-package-validation.js";
9
- export interface DeclaredPublishIdentity {
10
- readonly owner: Handle;
11
- readonly type: ExtensionType;
12
- readonly name: ExtensionName;
13
- readonly version: Version;
14
- }
15
- export interface PublishArchiveInput {
16
- readonly archiveBytes: Uint8Array;
17
- readonly archiveContentType?: string;
18
- readonly clientIntegrity?: string;
19
- }
20
- export interface NormalizePublishInputArgs {
21
- readonly declaredIdentity: DeclaredPublishIdentity;
22
- readonly archive: PublishArchiveInput;
23
- readonly digestHeader?: string;
24
- readonly readEntry?: (archiveBytes: Uint8Array, entry: ZipEntry) => Effect.Effect<Uint8Array, ArchiveGuardrailError>;
25
- readonly guardrailLimits?: ArchiveGuardrailLimits;
26
- }
27
- export interface PublishInput {
28
- readonly owner: Handle;
29
- readonly type: ExtensionType;
30
- readonly name: ExtensionName;
31
- readonly version: Version;
32
- readonly archiveBytes: Uint8Array;
33
- readonly archiveContentType: string;
34
- readonly manifest: ResolvedManifest;
35
- readonly clientIntegrity?: string;
36
- readonly digestHeader?: string;
37
- }
38
- export declare const defaultReadEntry: (archiveBytes: Uint8Array, entry: ZipEntry) => Effect.Effect<Uint8Array, ArchiveGuardrailError>;
39
- export declare const normalizePublishInput: (args: NormalizePublishInputArgs) => Effect.Effect<PublishInput, IngestLimitError | IngestUnsupportedContentTypeError | ArchiveGuardrailError | ManifestError | FilteredPackageError>;
40
- //# sourceMappingURL=input-normalization.d.ts.map
@@ -1,125 +0,0 @@
1
- import * as Effect from "effect/Effect";
2
- import { inflateRawSync } from "node:zlib";
3
- import { ArchiveGuardrailError, ZIP_LOCAL_SIGNATURE, validateArchive, } from "./archive-guardrails.js";
4
- import { enforceArchiveContentType, enforceArchiveSizeLimit, } from "./ingest-limits.js";
5
- import { resolveManifest, validateDeclaredManifestAlignment, } from "./manifest-policy.js";
6
- import { FilteredPackageError, validateFilteredPackage } from "./filtered-package-validation.js";
7
- const LOCAL_FILE_HEADER_SIZE = 30;
8
- export const defaultReadEntry = (archiveBytes, entry) => Effect.gen(function* () {
9
- const { localHeaderOffset, compressedSize, compressionMethod, fileName } = entry;
10
- if (localHeaderOffset + LOCAL_FILE_HEADER_SIZE > archiveBytes.length) {
11
- return yield* new ArchiveGuardrailError({
12
- code: "malformed_archive",
13
- message: `Local file header for entry "${fileName}" exceeds archive bounds.`,
14
- entry: fileName,
15
- });
16
- }
17
- const view = new DataView(archiveBytes.buffer, archiveBytes.byteOffset, archiveBytes.byteLength);
18
- const signature = view.getUint32(localHeaderOffset, true);
19
- if (signature !== ZIP_LOCAL_SIGNATURE) {
20
- return yield* new ArchiveGuardrailError({
21
- code: "malformed_archive",
22
- message: `Invalid local file header signature for entry "${fileName}".`,
23
- entry: fileName,
24
- });
25
- }
26
- const fileNameLength = view.getUint16(localHeaderOffset + 26, true);
27
- const extraFieldLength = view.getUint16(localHeaderOffset + 28, true);
28
- const dataStart = localHeaderOffset + LOCAL_FILE_HEADER_SIZE + fileNameLength + extraFieldLength;
29
- if (dataStart + compressedSize > archiveBytes.length) {
30
- return yield* new ArchiveGuardrailError({
31
- code: "malformed_archive",
32
- message: `Compressed data for entry "${fileName}" exceeds archive bounds.`,
33
- entry: fileName,
34
- });
35
- }
36
- const compressedData = archiveBytes.slice(dataStart, dataStart + compressedSize);
37
- if (compressionMethod === 0) {
38
- return compressedData;
39
- }
40
- if (compressionMethod === 8) {
41
- // Cap actual decompression at the declared (guardrail-validated) size so a
42
- // small deflate stream cannot expand into a memory bomb, and route any
43
- // inflate throw into the typed error channel instead of an uncaught defect.
44
- const result = yield* Effect.try({
45
- try: () => inflateRawSync(compressedData, { maxOutputLength: entry.uncompressedSize }),
46
- catch: (error) => {
47
- const errorCode = typeof error === "object" &&
48
- error !== null &&
49
- "code" in error &&
50
- typeof error.code === "string"
51
- ? error.code
52
- : "";
53
- return errorCode === "ERR_BUFFER_TOO_LARGE"
54
- ? new ArchiveGuardrailError({
55
- code: "decompression_limit_exceeded",
56
- message: `Entry "${fileName}" decompresses beyond its declared size of ${entry.uncompressedSize} bytes.`,
57
- entry: fileName,
58
- })
59
- : new ArchiveGuardrailError({
60
- code: "malformed_archive",
61
- message: `Failed to decompress entry "${fileName}".`,
62
- entry: fileName,
63
- });
64
- },
65
- });
66
- return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
67
- }
68
- return yield* new ArchiveGuardrailError({
69
- code: "unsupported_compression",
70
- message: `Unsupported compression method ${compressionMethod} for entry "${fileName}".`,
71
- entry: fileName,
72
- });
73
- });
74
- export const normalizePublishInput = (args) => Effect.gen(function* () {
75
- const { declaredIdentity, archive, digestHeader, guardrailLimits } = args;
76
- const entryReader = args.readEntry ?? defaultReadEntry;
77
- yield* Effect.fromResult(enforceArchiveContentType(archive.archiveContentType));
78
- yield* Effect.fromResult(enforceArchiveSizeLimit(archive.archiveBytes.length));
79
- const entries = yield* validateArchive(archive.archiveBytes, guardrailLimits);
80
- const manifest = yield* resolveManifest({
81
- type: declaredIdentity.type,
82
- entries,
83
- readEntry: (fileName) => {
84
- const entry = entries.find((candidate) => candidate.fileName === fileName);
85
- if (entry === undefined) {
86
- return Effect.fail(new ArchiveGuardrailError({
87
- code: "malformed_archive",
88
- message: `Entry "${fileName}" not found in archive.`,
89
- entry: fileName,
90
- }));
91
- }
92
- return entryReader(archive.archiveBytes, entry);
93
- },
94
- });
95
- yield* Effect.fromResult(validateDeclaredManifestAlignment(declaredIdentity, manifest.identity));
96
- yield* validateFilteredPackage({
97
- type: declaredIdentity.type,
98
- entries,
99
- manifest,
100
- readEntry: (fileName) => {
101
- const entry = entries.find((candidate) => candidate.fileName === fileName);
102
- return entry === undefined
103
- ? Effect.fail(new FilteredPackageError({
104
- code: "required_file_missing",
105
- detail: `Filtered package file "${fileName}" is missing.`,
106
- path: fileName,
107
- }))
108
- : entryReader(archive.archiveBytes, entry);
109
- },
110
- });
111
- return {
112
- owner: declaredIdentity.owner,
113
- type: declaredIdentity.type,
114
- name: declaredIdentity.name,
115
- version: declaredIdentity.version,
116
- archiveBytes: archive.archiveBytes,
117
- archiveContentType: archive.archiveContentType ?? "application/zip",
118
- manifest,
119
- ...(archive.clientIntegrity === undefined
120
- ? {}
121
- : { clientIntegrity: archive.clientIntegrity }),
122
- ...(digestHeader === undefined ? {} : { digestHeader }),
123
- };
124
- });
125
- //# sourceMappingURL=input-normalization.js.map