@vibe-agent-toolkit/agent-skills 0.2.0-rc.10 → 0.2.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -13
- package/dist/builder.d.ts +24 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +135 -62
- package/dist/builder.js.map +1 -1
- package/dist/bundle-copy.d.ts +31 -0
- package/dist/bundle-copy.d.ts.map +1 -0
- package/dist/bundle-copy.js +50 -0
- package/dist/bundle-copy.js.map +1 -0
- package/dist/evidence/derive-observations.d.ts +2 -2
- package/dist/evidence/derive-observations.d.ts.map +1 -1
- package/dist/evidence/derive-observations.js +4 -4
- package/dist/evidence/derive-observations.js.map +1 -1
- package/dist/evidence/types.d.ts +2 -2
- package/dist/evidence/types.d.ts.map +1 -1
- package/dist/files-config.d.ts +9 -2
- package/dist/files-config.d.ts.map +1 -1
- package/dist/files-config.js +116 -109
- package/dist/files-config.js.map +1 -1
- package/dist/import.d.ts +21 -2
- package/dist/import.d.ts.map +1 -1
- package/dist/import.js +46 -31
- package/dist/import.js.map +1 -1
- package/dist/index.d.ts +13 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/inventory/index.d.ts +2 -1
- package/dist/inventory/index.d.ts.map +1 -1
- package/dist/inventory/index.js +1 -1
- package/dist/inventory/index.js.map +1 -1
- package/dist/inventory/serialize.d.ts +5796 -22
- package/dist/inventory/serialize.d.ts.map +1 -1
- package/dist/inventory/serialize.js +145 -33
- package/dist/inventory/serialize.js.map +1 -1
- package/dist/inventory/types.d.ts +3 -3
- package/dist/inventory/types.d.ts.map +1 -1
- package/dist/packaging-errors.d.ts +73 -0
- package/dist/packaging-errors.d.ts.map +1 -0
- package/dist/packaging-errors.js +96 -0
- package/dist/packaging-errors.js.map +1 -0
- package/dist/plugin-distribution-layout.d.ts +9 -3
- package/dist/plugin-distribution-layout.d.ts.map +1 -1
- package/dist/plugin-distribution-layout.js +19 -8
- package/dist/plugin-distribution-layout.js.map +1 -1
- package/dist/post-build-checks.d.ts +1 -1
- package/dist/post-build-checks.d.ts.map +1 -1
- package/dist/post-build-checks.js +36 -30
- package/dist/post-build-checks.js.map +1 -1
- package/dist/projection/skill-extent.d.ts +2 -2
- package/dist/projection/skill-extent.js +2 -2
- package/dist/skill-packager.d.ts +188 -8
- package/dist/skill-packager.d.ts.map +1 -1
- package/dist/skill-packager.js +688 -351
- package/dist/skill-packager.js.map +1 -1
- package/dist/skill-source/content-hash.d.ts +1 -0
- package/dist/skill-source/content-hash.d.ts.map +1 -1
- package/dist/skill-source/content-hash.js +16 -9
- package/dist/skill-source/content-hash.js.map +1 -1
- package/dist/skill-source/fetch-cache.d.ts +7 -1
- package/dist/skill-source/fetch-cache.d.ts.map +1 -1
- package/dist/skill-source/fetch-cache.js +54 -27
- package/dist/skill-source/fetch-cache.js.map +1 -1
- package/dist/skill-source/git-clone.d.ts +18 -0
- package/dist/skill-source/git-clone.d.ts.map +1 -1
- package/dist/skill-source/git-clone.js +207 -24
- package/dist/skill-source/git-clone.js.map +1 -1
- package/dist/skill-source/resolve-skill-source.d.ts +15 -0
- package/dist/skill-source/resolve-skill-source.d.ts.map +1 -1
- package/dist/skill-source/resolve-skill-source.js +23 -1
- package/dist/skill-source/resolve-skill-source.js.map +1 -1
- package/dist/skill-source/source-errors.d.ts +40 -0
- package/dist/skill-source/source-errors.d.ts.map +1 -0
- package/dist/skill-source/source-errors.js +47 -0
- package/dist/skill-source/source-errors.js.map +1 -0
- package/dist/skill-source/sources/npm-source.d.ts +25 -3
- package/dist/skill-source/sources/npm-source.d.ts.map +1 -1
- package/dist/skill-source/sources/npm-source.js +76 -19
- package/dist/skill-source/sources/npm-source.js.map +1 -1
- package/dist/skill-source/sources/path-source.js +1 -1
- package/dist/skill-source/sources/path-source.js.map +1 -1
- package/dist/skill-source/sources/url-source.d.ts +10 -4
- package/dist/skill-source/sources/url-source.d.ts.map +1 -1
- package/dist/skill-source/sources/url-source.js +107 -45
- package/dist/skill-source/sources/url-source.js.map +1 -1
- package/dist/skill-source/sources/vendored-source.js +1 -1
- package/dist/skill-source/sources/vendored-source.js.map +1 -1
- package/dist/skill-source/sources/workspace-source.d.ts.map +1 -1
- package/dist/skill-source/sources/workspace-source.js +6 -11
- package/dist/skill-source/sources/workspace-source.js.map +1 -1
- package/dist/skill-source/stage.d.ts +12 -0
- package/dist/skill-source/stage.d.ts.map +1 -1
- package/dist/skill-source/stage.js +65 -34
- package/dist/skill-source/stage.js.map +1 -1
- package/dist/skill-source/types.d.ts +7 -0
- package/dist/skill-source/types.d.ts.map +1 -1
- package/dist/skill-test/baseline-delta.d.ts +27 -27
- package/dist/skill-test/baseline-integrity.d.ts +9 -9
- package/dist/skill-test/build-hook.d.ts +8 -1
- package/dist/skill-test/build-hook.d.ts.map +1 -1
- package/dist/skill-test/build-hook.js +3 -2
- package/dist/skill-test/build-hook.js.map +1 -1
- package/dist/skill-test/eval-fragment.d.ts +19 -6
- package/dist/skill-test/eval-fragment.d.ts.map +1 -1
- package/dist/skill-test/eval-fragment.js +5 -4
- package/dist/skill-test/eval-fragment.js.map +1 -1
- package/dist/skill-test/eval-grader.d.ts.map +1 -1
- package/dist/skill-test/eval-grader.js +6 -3
- package/dist/skill-test/eval-grader.js.map +1 -1
- package/dist/skill-test/eval-inputs.d.ts +10 -4
- package/dist/skill-test/eval-inputs.d.ts.map +1 -1
- package/dist/skill-test/eval-inputs.js +93 -42
- package/dist/skill-test/eval-inputs.js.map +1 -1
- package/dist/skill-test/eval-suite-isolation.d.ts +1 -1
- package/dist/skill-test/eval-suite-isolation.d.ts.map +1 -1
- package/dist/skill-test/eval-suite-isolation.js +30 -9
- package/dist/skill-test/eval-suite-isolation.js.map +1 -1
- package/dist/skill-test/evals-template.d.ts.map +1 -1
- package/dist/skill-test/evals-template.js +4 -3
- package/dist/skill-test/evals-template.js.map +1 -1
- package/dist/skill-test/failure-reason.d.ts +83 -2
- package/dist/skill-test/failure-reason.d.ts.map +1 -1
- package/dist/skill-test/failure-reason.js +93 -4
- package/dist/skill-test/failure-reason.js.map +1 -1
- package/dist/skill-test/friction-schema.d.ts +53 -10
- package/dist/skill-test/friction-schema.d.ts.map +1 -1
- package/dist/skill-test/friction-schema.js +28 -2
- package/dist/skill-test/friction-schema.js.map +1 -1
- package/dist/skill-test/grader-text.d.ts +1 -1
- package/dist/skill-test/grader-text.js +2 -2
- package/dist/skill-test/harness-location.d.ts +14 -3
- package/dist/skill-test/harness-location.d.ts.map +1 -1
- package/dist/skill-test/harness-location.js +41 -15
- package/dist/skill-test/harness-location.js.map +1 -1
- package/dist/skill-test/index.d.ts +2 -2
- package/dist/skill-test/index.d.ts.map +1 -1
- package/dist/skill-test/index.js +2 -2
- package/dist/skill-test/index.js.map +1 -1
- package/dist/skill-test/lock.d.ts +15 -21
- package/dist/skill-test/lock.d.ts.map +1 -1
- package/dist/skill-test/lock.js +29 -42
- package/dist/skill-test/lock.js.map +1 -1
- package/dist/skill-test/pipeline.d.ts.map +1 -1
- package/dist/skill-test/pipeline.js +30 -29
- package/dist/skill-test/pipeline.js.map +1 -1
- package/dist/skill-test/plugin-layout.d.ts +4 -3
- package/dist/skill-test/plugin-layout.d.ts.map +1 -1
- package/dist/skill-test/plugin-layout.js +4 -3
- package/dist/skill-test/plugin-layout.js.map +1 -1
- package/dist/skill-test/preflight.d.ts +20 -3
- package/dist/skill-test/preflight.d.ts.map +1 -1
- package/dist/skill-test/preflight.js +49 -15
- package/dist/skill-test/preflight.js.map +1 -1
- package/dist/skill-test/run-harness.d.ts +68 -34
- package/dist/skill-test/run-harness.d.ts.map +1 -1
- package/dist/skill-test/run-harness.js +244 -116
- package/dist/skill-test/run-harness.js.map +1 -1
- package/dist/skill-test/staging.d.ts +6 -0
- package/dist/skill-test/staging.d.ts.map +1 -1
- package/dist/skill-test/staging.js +56 -29
- package/dist/skill-test/staging.js.map +1 -1
- package/dist/skill-test/vendor-manifest.d.ts.map +1 -1
- package/dist/skill-test/vendor-manifest.js +7 -5
- package/dist/skill-test/vendor-manifest.js.map +1 -1
- package/dist/skill-zip-layout.d.ts +45 -0
- package/dist/skill-zip-layout.d.ts.map +1 -0
- package/dist/skill-zip-layout.js +64 -0
- package/dist/skill-zip-layout.js.map +1 -0
- package/dist/test-input.d.ts.map +1 -1
- package/dist/test-input.js +4 -3
- package/dist/test-input.js.map +1 -1
- package/dist/validators/agent-instruction-presence.d.ts +4 -1
- package/dist/validators/agent-instruction-presence.d.ts.map +1 -1
- package/dist/validators/agent-instruction-presence.js +8 -4
- package/dist/validators/agent-instruction-presence.js.map +1 -1
- package/dist/validators/bundled-resource-link-detection.d.ts +4 -1
- package/dist/validators/bundled-resource-link-detection.d.ts.map +1 -1
- package/dist/validators/bundled-resource-link-detection.js +16 -8
- package/dist/validators/bundled-resource-link-detection.js.map +1 -1
- package/dist/validators/compat-detectors.js +1 -1
- package/dist/validators/compat-detectors.js.map +1 -1
- package/dist/validators/describe-issues.d.ts +18 -0
- package/dist/validators/describe-issues.d.ts.map +1 -0
- package/dist/validators/describe-issues.js +40 -0
- package/dist/validators/describe-issues.js.map +1 -0
- package/dist/validators/format-detection.d.ts.map +1 -1
- package/dist/validators/format-detection.js +31 -23
- package/dist/validators/format-detection.js.map +1 -1
- package/dist/validators/frontmatter-validation.d.ts +7 -0
- package/dist/validators/frontmatter-validation.d.ts.map +1 -1
- package/dist/validators/frontmatter-validation.js +249 -11
- package/dist/validators/frontmatter-validation.js.map +1 -1
- package/dist/validators/marketplace-validator.d.ts +25 -0
- package/dist/validators/marketplace-validator.d.ts.map +1 -1
- package/dist/validators/marketplace-validator.js +62 -21
- package/dist/validators/marketplace-validator.js.map +1 -1
- package/dist/validators/packaged-size-limit.d.ts +6 -9
- package/dist/validators/packaged-size-limit.d.ts.map +1 -1
- package/dist/validators/packaged-size-limit.js +2 -2
- package/dist/validators/packaged-size-limit.js.map +1 -1
- package/dist/validators/packaging-validator.d.ts +37 -12
- package/dist/validators/packaging-validator.d.ts.map +1 -1
- package/dist/validators/packaging-validator.js +107 -41
- package/dist/validators/packaging-validator.js.map +1 -1
- package/dist/validators/plugin-hosted-shape.d.ts.map +1 -1
- package/dist/validators/plugin-hosted-shape.js +6 -5
- package/dist/validators/plugin-hosted-shape.js.map +1 -1
- package/dist/validators/referenced-path-missing.d.ts +1 -1
- package/dist/validators/referenced-path-missing.d.ts.map +1 -1
- package/dist/validators/referenced-path-missing.js +12 -8
- package/dist/validators/referenced-path-missing.js.map +1 -1
- package/dist/validators/registry-validator.d.ts.map +1 -1
- package/dist/validators/registry-validator.js +21 -25
- package/dist/validators/registry-validator.js.map +1 -1
- package/dist/validators/skill-validator.d.ts.map +1 -1
- package/dist/validators/skill-validator.js +49 -18
- package/dist/validators/skill-validator.js.map +1 -1
- package/dist/validators/types.d.ts +28 -14
- package/dist/validators/types.d.ts.map +1 -1
- package/dist/validators/unified-validator.d.ts.map +1 -1
- package/dist/validators/unified-validator.js +5 -6
- package/dist/validators/unified-validator.js.map +1 -1
- package/dist/walk-link-graph.js +3 -1
- package/dist/walk-link-graph.js.map +1 -1
- package/package.json +7 -7
- package/schemas/friction-report.json +3 -3
- package/dist/fs-attribution.d.ts +0 -45
- package/dist/fs-attribution.d.ts.map +0 -1
- package/dist/fs-attribution.js +0 -57
- package/dist/fs-attribution.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-observations.js","sourceRoot":"","sources":["../../src/evidence/derive-observations.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"derive-observations.js","sourceRoot":"","sources":["../../src/evidence/derive-observations.ts"],"names":[],"mappings":"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"}
|
package/dist/evidence/types.d.ts
CHANGED
|
@@ -40,8 +40,8 @@ export interface PatternDefinition {
|
|
|
40
40
|
export interface Observation {
|
|
41
41
|
/** Validation code (e.g. 'CAPABILITY_LOCAL_SHELL'). */
|
|
42
42
|
code: string;
|
|
43
|
-
/** Human-readable claim. */
|
|
44
|
-
|
|
43
|
+
/** Human-readable claim, one sentence. Never `summary`: that name always means severity counts. */
|
|
44
|
+
description: string;
|
|
45
45
|
/** Payload specific to the observation code. */
|
|
46
46
|
payload?: Record<string, unknown>;
|
|
47
47
|
/** patternId[] of evidence records that support this observation. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evidence/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oCAAoC;AACpC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,IAAI,CAAC;AAE3C,mDAAmD;AACnD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evidence/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oCAAoC;AACpC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,IAAI,CAAC;AAE3C,mDAAmD;AACnD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B"}
|
package/dist/files-config.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export interface AppliedFilesConfig {
|
|
|
53
53
|
*
|
|
54
54
|
* Returned rather than written to a `warn` sink because a file vanishing from
|
|
55
55
|
* a bundle is a build FINDING, not a log line: it has to reach the structured
|
|
56
|
-
* report (`
|
|
56
|
+
* report's counts (`summary`), or a CI consumer reads `warnings: 0` for a build
|
|
57
57
|
* that silently shipped less than the config asked for.
|
|
58
58
|
*/
|
|
59
59
|
dropped: DroppedGlobMatch[];
|
|
@@ -184,8 +184,15 @@ export interface ApplyFilesConfigOptions {
|
|
|
184
184
|
* missing dest. Intended to be called after a copy operation to assert the
|
|
185
185
|
* copy was faithful. Exported so it can be tested directly without running a
|
|
186
186
|
* full applyFilesConfig round-trip.
|
|
187
|
+
*
|
|
188
|
+
* The check reads BOTH trees, so each read is guarded as the side it touches: a
|
|
189
|
+
* source the OS will not read is the skill's refusal, a dest it will not stat or
|
|
190
|
+
* read is the output's. One guard over the whole pair coded a dest-side errno as
|
|
191
|
+
* the skill's, with a remedy pointing at the source.
|
|
192
|
+
*
|
|
193
|
+
* @param subject - The `files:` entry, phrased for the refusal's message
|
|
187
194
|
*/
|
|
188
|
-
export declare function verifyFilesIntegrity(pairs: {
|
|
195
|
+
export declare function verifyFilesIntegrity(subject: string, pairs: {
|
|
189
196
|
absSource: string;
|
|
190
197
|
absDest: string;
|
|
191
198
|
}[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files-config.d.ts","sourceRoot":"","sources":["../src/files-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"files-config.d.ts","sourceRoot":"","sources":["../src/files-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA6BlE,YAAY,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AA6JpE,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;;;;;;;OAQG;IACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,YAAY,EAAE,MAAM,GACnB,eAAe,EAAE,CAEnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,YAAY,EAAE,MAAM,GACnB,eAAe,EAAE,CAEnB;AAkDD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,EACrB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAcpB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,GAAG,SAAS,EACtC,QAAQ,EAAE,cAAc,EAAE,GAAG,SAAS,GACrC,cAAc,EAAE,CA6ClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,EAAE,CAEnF;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,uCAAuC;IACvC,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GAC9C,IAAI,CAUN;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAyBf;AA6QD,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,iFAAiF;IACjF,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,8EAA8E;IAC9E,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAChC;;;;;;;;;;OAUG;IACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,SAAS,cAAc,EAAE,EACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,oBAAoB,CAAC,CA8D/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,oBAAoB,EAC9B,YAAY,EAAE,MAAM,GACnB,eAAe,EAAE,CA2BnB;AAmOD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmCjG"}
|
package/dist/files-config.js
CHANGED
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
* - Computing deferred paths for validation
|
|
8
8
|
* - Copying declared build artifacts into a skill output dir (every build path)
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { dirname } from 'node:path';
|
|
13
|
-
import { fileContentHash, globMagicRemainder, hasParentTraversalSegment, isFilesystemAccessError, isGlob, issueLocation, safePath, staticGlobBase, toForwardSlash, toForwardSlashAnyPlatform, } from '@vibe-agent-toolkit/utils';
|
|
10
|
+
import { lstat } from 'node:fs/promises';
|
|
11
|
+
import { classifyFsFault, fileContentHash, followedKind, followedStatSync, fsFaultOf, globMagicRemainder, hasParentTraversalSegment, isGlob, isLinkChainRefusedError, forEachInOrder, issueLocation, mapWithConcurrency, safePath, staticGlobBase, toForwardSlash, toForwardSlashAnyPlatform, withFsFault, withFsFaultSync, } from '@vibe-agent-toolkit/utils';
|
|
14
12
|
import { glob } from 'glob';
|
|
15
13
|
import picomatch from 'picomatch';
|
|
16
|
-
import {
|
|
14
|
+
import { copyIntoBundle } from './bundle-copy.js';
|
|
15
|
+
import { packagingInputError } from './packaging-errors.js';
|
|
17
16
|
import { materializeIssue } from './validators/rule-engine/index.js';
|
|
18
17
|
import { isNeverPackagedBasename } from './validators/validation-rules.js';
|
|
19
18
|
/**
|
|
@@ -75,10 +74,10 @@ async function partitionRegularFiles(matches, absoluteBase) {
|
|
|
75
74
|
// caller's sorted order regardless of completion order — `droppedRel` and
|
|
76
75
|
// `nonRegularRel` are rendered into error messages an adopter reads, and a set
|
|
77
76
|
// that reshuffles between runs is a diff for no reason.
|
|
78
|
-
const copyable = await mapWithConcurrency(matches,
|
|
77
|
+
const copyable = await mapWithConcurrency(matches, (rel) =>
|
|
79
78
|
// joinUnderRoot asserts the match stays under absoluteBase, the same guard the
|
|
80
79
|
// copy loop applies before reading it.
|
|
81
|
-
isCopyableFile(safePath.joinUnderRoot(absoluteBase, rel)));
|
|
80
|
+
isCopyableFile(safePath.joinUnderRoot(absoluteBase, rel), absoluteBase));
|
|
82
81
|
const regular = [];
|
|
83
82
|
const nonRegular = [];
|
|
84
83
|
for (const [i, rel] of matches.entries()) {
|
|
@@ -86,25 +85,6 @@ async function partitionRegularFiles(matches, absoluteBase) {
|
|
|
86
85
|
}
|
|
87
86
|
return { regular, nonRegular };
|
|
88
87
|
}
|
|
89
|
-
/**
|
|
90
|
-
* Enough parallelism to hide per-call latency, low enough to stay far from the
|
|
91
|
-
* default file-descriptor ceiling even with several skills building at once.
|
|
92
|
-
*/
|
|
93
|
-
const STAT_CONCURRENCY = 16;
|
|
94
|
-
/** `Promise.all`-shaped, but with at most `limit` calls in flight. Order preserved. */
|
|
95
|
-
async function mapWithConcurrency(items, limit, fn) {
|
|
96
|
-
const results = Array.from({ length: items.length });
|
|
97
|
-
let next = 0;
|
|
98
|
-
const worker = async () => {
|
|
99
|
-
while (next < items.length) {
|
|
100
|
-
const i = next++;
|
|
101
|
-
// Non-null: `i` is always a valid index, guarded by the loop condition.
|
|
102
|
-
results[i] = await fn(items[i]);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
106
|
-
return results;
|
|
107
|
-
}
|
|
108
88
|
/**
|
|
109
89
|
* Whether `copyFile` can read this path as a stream of bytes.
|
|
110
90
|
*
|
|
@@ -114,17 +94,25 @@ async function mapWithConcurrency(items, limit, fn) {
|
|
|
114
94
|
* would move. A dangling link, or one resolving to a directory, throws from `stat`
|
|
115
95
|
* and is reported as not copyable rather than escaping as the build's whole
|
|
116
96
|
* explanation.
|
|
97
|
+
*
|
|
98
|
+
* The link is followed only once its chain is read beneath `within` (the glob's
|
|
99
|
+
* base, in the operator's project): a chain VAT will not hand the kernel — a link
|
|
100
|
+
* to a network or device path — is a refusal on the source side, thrown, never a
|
|
101
|
+
* quiet "not copyable".
|
|
117
102
|
*/
|
|
118
|
-
async function isCopyableFile(absPath) {
|
|
103
|
+
async function isCopyableFile(absPath, within) {
|
|
119
104
|
try {
|
|
120
105
|
const linkStat = await lstat(absPath);
|
|
121
106
|
if (linkStat.isFile())
|
|
122
107
|
return true;
|
|
123
108
|
if (!linkStat.isSymbolicLink())
|
|
124
109
|
return false;
|
|
125
|
-
return (await
|
|
110
|
+
return (await followedKind(absPath, within)) === 'file';
|
|
126
111
|
}
|
|
127
112
|
catch (error) {
|
|
113
|
+
if (isLinkChainRefusedError(error)) {
|
|
114
|
+
throw classifyFsFault(error, { side: 'source', origin: 'content', action: `examine ${absPath}` });
|
|
115
|
+
}
|
|
128
116
|
// Unreadable or dangling. Not copyable is the honest answer, and the caller
|
|
129
117
|
// reports it as a named finding — which is strictly more than the raw errno
|
|
130
118
|
// this replaces ever gave.
|
|
@@ -132,9 +120,14 @@ async function isCopyableFile(absPath) {
|
|
|
132
120
|
// Narrowed to filesystem errors on purpose: a bare `catch {}` here would
|
|
133
121
|
// answer "not a regular file" to a bug in our own code, silently converting a
|
|
134
122
|
// defect into a routine skip. Same predicate the audit walk uses, from one
|
|
135
|
-
// shared source so the two cannot drift.
|
|
136
|
-
|
|
123
|
+
// shared source so the two cannot drift. A machine that ran out (`exhausted`,
|
|
124
|
+
// `busy`) says nothing about the match: thrown, classified, never a skip.
|
|
125
|
+
const faultClass = fsFaultOf(error)?.faultClass;
|
|
126
|
+
if (faultClass === undefined)
|
|
137
127
|
throw error;
|
|
128
|
+
if (faultClass === 'exhausted' || faultClass === 'busy') {
|
|
129
|
+
throw classifyFsFault(error, { side: 'source', origin: 'content', action: `examine ${absPath}` });
|
|
130
|
+
}
|
|
138
131
|
return false;
|
|
139
132
|
}
|
|
140
133
|
}
|
|
@@ -155,8 +148,16 @@ async function isCopyableFile(absPath) {
|
|
|
155
148
|
* text is kept verbatim inside it, because it is what distinguishes a permission
|
|
156
149
|
* problem from a full disk from a vanished mount.
|
|
157
150
|
*/
|
|
158
|
-
|
|
159
|
-
return
|
|
151
|
+
function attributed(entry, absPath, projectRoot, work) {
|
|
152
|
+
return withFsFault({ side: 'source', origin: 'content', action: `read ${entrySubject(entry, absPath, projectRoot)}` }, () => Promise.resolve(work()));
|
|
153
|
+
}
|
|
154
|
+
/** How a failure names a `files:` entry: the `source:` the author wrote, and where it resolved. */
|
|
155
|
+
function entrySubject(entry, absPath, projectRoot) {
|
|
156
|
+
return `files: source '${entry.source}' resolved to ${anchoredPath(absPath, projectRoot)}`;
|
|
157
|
+
}
|
|
158
|
+
/** Copy one file a `files:` entry names into the bundle, each side's refusal coded as that side's. */
|
|
159
|
+
function copyEntryFile(entry, absSource, bundle, projectRoot) {
|
|
160
|
+
return copyIntoBundle(entrySubject(entry, absSource, projectRoot), absSource, bundle.root, bundle.dest);
|
|
160
161
|
}
|
|
161
162
|
/**
|
|
162
163
|
* Turn never-package drops into reportable findings.
|
|
@@ -217,7 +218,7 @@ function globMatchesToIssues(matches, locationRoot, code) {
|
|
|
217
218
|
*
|
|
218
219
|
* Load-bearing for every THROWN message in this module, not only for issue
|
|
219
220
|
* locations: `applyFilesConfig`'s throws reach `vat skills build`'s stdout
|
|
220
|
-
* verbatim as `
|
|
221
|
+
* verbatim as a `SKILL_PACKAGING_FAILED` finding's `message`, so an absolute path there publishes the
|
|
221
222
|
* developer's home directory into whatever issue or CI log the report is pasted
|
|
222
223
|
* into. Build-report messages are project-relative, never absolute.
|
|
223
224
|
*/
|
|
@@ -311,7 +312,7 @@ export function mergeFilesConfig(defaults, perSkill) {
|
|
|
311
312
|
for (const entry of perSkill) {
|
|
312
313
|
const normalized = normalizeRelPath(entry.dest);
|
|
313
314
|
if (destSet.has(normalized)) {
|
|
314
|
-
throw
|
|
315
|
+
throw packagingInputError(`Duplicate dest in per-skill files config: '${entry.dest}'. ` +
|
|
315
316
|
`Each dest must be unique within a skill's files configuration.`);
|
|
316
317
|
}
|
|
317
318
|
destSet.add(normalized);
|
|
@@ -369,30 +370,38 @@ export function explicitFilesConfigDests(files) {
|
|
|
369
370
|
* missing dest. Intended to be called after a copy operation to assert the
|
|
370
371
|
* copy was faithful. Exported so it can be tested directly without running a
|
|
371
372
|
* full applyFilesConfig round-trip.
|
|
373
|
+
*
|
|
374
|
+
* The check reads BOTH trees, so each read is guarded as the side it touches: a
|
|
375
|
+
* source the OS will not read is the skill's refusal, a dest it will not stat or
|
|
376
|
+
* read is the output's. One guard over the whole pair coded a dest-side errno as
|
|
377
|
+
* the skill's, with a remedy pointing at the source.
|
|
378
|
+
*
|
|
379
|
+
* @param subject - The `files:` entry, phrased for the refusal's message
|
|
372
380
|
*/
|
|
373
|
-
export function verifyFilesIntegrity(pairs) {
|
|
381
|
+
export function verifyFilesIntegrity(subject, pairs) {
|
|
374
382
|
for (const { absSource, absDest } of pairs) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
// problem on the dest was reported as "dest file missing", sending the author
|
|
378
|
-
// to look for a file that is sitting right there. Only a real ENOENT is
|
|
379
|
-
// missing; anything else is the filesystem refusing the path, and is rethrown
|
|
380
|
-
// for the caller to attribute to the `files:` entry.
|
|
381
|
-
try {
|
|
382
|
-
statSync(absDest);
|
|
383
|
-
}
|
|
384
|
-
catch (error) {
|
|
385
|
-
if (error.code !== 'ENOENT')
|
|
386
|
-
throw error;
|
|
387
|
-
throw new Error(`files: integrity check failed — dest file missing: ${toForwardSlash(absDest)}`);
|
|
388
|
-
}
|
|
389
|
-
const srcHash = fileContentHash(absSource);
|
|
390
|
-
const dstHash = fileContentHash(absDest);
|
|
383
|
+
const srcHash = withFsFaultSync({ side: 'source', origin: 'content', action: `read ${subject} for verification` }, () => fileContentHash(absSource));
|
|
384
|
+
const dstHash = withFsFaultSync({ side: 'destination', shapeFromSource: true, action: `verify ${subject} in the bundle` }, () => destContentHash(absDest));
|
|
391
385
|
if (srcHash !== dstHash) {
|
|
392
386
|
throw new Error(`files: integrity check failed — content mismatch at dest: ${toForwardSlash(absDest)}`);
|
|
393
387
|
}
|
|
394
388
|
}
|
|
395
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* The dest's content hash. A followed `stat` in a guard rather than `existsSync`,
|
|
392
|
+
* because `existsSync` answers FALSE for a file that is present but unreadable —
|
|
393
|
+
* so a permissions problem on the dest was reported as "dest file missing",
|
|
394
|
+
* sending the author to look for a file that is sitting right there. Only
|
|
395
|
+
* resolving to nothing is missing; anything else is the filesystem refusing the
|
|
396
|
+
* path, and is rethrown for the caller's guard to code.
|
|
397
|
+
*/
|
|
398
|
+
function destContentHash(absDest) {
|
|
399
|
+
// The dest is the file this build just wrote — VAT's own path, so it is its own tree.
|
|
400
|
+
if (followedStatSync(absDest, absDest) === undefined) {
|
|
401
|
+
throw new Error(`files: integrity check failed — dest file missing: ${toForwardSlash(absDest)}`);
|
|
402
|
+
}
|
|
403
|
+
return fileContentHash(absDest);
|
|
404
|
+
}
|
|
396
405
|
/**
|
|
397
406
|
* Verify that the on-disk contents of a glob entry's dest subtree EXACTLY match
|
|
398
407
|
* the set of rel paths the copy step intended to write — no missing, no extra.
|
|
@@ -449,31 +458,36 @@ export async function verifyDestSet(destDir, expectedRel, source) {
|
|
|
449
458
|
* Throws on missing source or if source is a directory.
|
|
450
459
|
*/
|
|
451
460
|
async function copyNonGlobEntry(entry, absoluteSource, projectRoot, skillOutputDir) {
|
|
452
|
-
// `
|
|
461
|
+
// A followed `stat` in a guard, not `existsSync`: `existsSync` swallows EACCES and
|
|
453
462
|
// answers FALSE, so a source the process merely cannot REACH — one under a
|
|
454
463
|
// directory it lacks permission to traverse — was reported as "does not exist".
|
|
455
464
|
// For a `dist/` source that also appended `buildArtifactHint`, telling the
|
|
456
465
|
// author to run a build that would not have helped: a confidently wrong
|
|
457
|
-
// diagnosis plus a confidently wrong remedy. Only
|
|
458
|
-
// else is the filesystem refusing the path, and `attributed`
|
|
459
|
-
//
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
466
|
+
// diagnosis plus a confidently wrong remedy. Only resolving to nothing is absence; anything
|
|
467
|
+
// else is the filesystem refusing the path, and `attributed` names the entry.
|
|
468
|
+
//
|
|
469
|
+
// The source's `stat` is guarded as well as its copy. Guarding the copy alone
|
|
470
|
+
// left a source under a directory the process cannot traverse escaping as a bare
|
|
471
|
+
// errno — and an EXPLICIT entry is the spelling that unambiguously says "ship
|
|
472
|
+
// this file", so the build owes its author an error that names it back. (The two
|
|
473
|
+
// deliberate errors below carry no errno, so `attributed` passes them through.)
|
|
474
|
+
//
|
|
475
|
+
// The source is crawled beneath the project root: its link chain is read by its
|
|
476
|
+
// text before the kernel follows it, and a chain VAT will not hand the kernel is
|
|
477
|
+
// a refusal `attributed` names, never "does not exist".
|
|
478
|
+
await attributed(entry, absoluteSource, projectRoot, () => {
|
|
479
|
+
const sourceStat = followedStatSync(absoluteSource, projectRoot);
|
|
480
|
+
if (sourceStat === undefined) {
|
|
481
|
+
throw packagingInputError(`files: source '${entry.source}' does not exist (resolved to ${anchoredPath(absoluteSource, projectRoot)}).${buildArtifactHint(entry.source)}`);
|
|
482
|
+
}
|
|
483
|
+
if (sourceStat.isDirectory()) {
|
|
484
|
+
throw packagingInputError(`files: source '${entry.source}' is a directory; use a glob like '${entry.source}/**/*' to copy its contents.`);
|
|
485
|
+
}
|
|
486
|
+
});
|
|
472
487
|
// joinUnderRoot rejects a dest that escapes the skill output dir (absolute /
|
|
473
488
|
// drive-letter / '..'), defense-in-depth beyond the schema refine.
|
|
474
489
|
const absoluteDest = safePath.joinUnderRoot(skillOutputDir, entry.dest);
|
|
475
|
-
await
|
|
476
|
-
await copyFile(absoluteSource, absoluteDest);
|
|
490
|
+
await copyEntryFile(entry, absoluteSource, { root: skillOutputDir, dest: absoluteDest }, projectRoot);
|
|
477
491
|
return { relDest: normalizeRelPath(entry.dest), absSource: absoluteSource, absDest: absoluteDest };
|
|
478
492
|
}
|
|
479
493
|
/**
|
|
@@ -497,7 +511,7 @@ async function copyNonGlobEntry(entry, absoluteSource, projectRoot, skillOutputD
|
|
|
497
511
|
async function expandGlobEntry(entry, projectRoot) {
|
|
498
512
|
const remainder = globMagicRemainder(entry.source);
|
|
499
513
|
if (hasParentTraversalSegment(remainder)) {
|
|
500
|
-
throw
|
|
514
|
+
throw packagingInputError(`files: source '${entry.source}' (glob) has a '..' segment in its glob portion ('${remainder}'); ` +
|
|
501
515
|
`parent-directory traversal is not allowed after the static base.`);
|
|
502
516
|
}
|
|
503
517
|
const absoluteBase = safePath.resolve(safePath.join(projectRoot, staticGlobBase(entry.source)));
|
|
@@ -550,17 +564,17 @@ async function expandGlobEntry(entry, projectRoot) {
|
|
|
550
564
|
async function copyGlobEntry(entry, projectRoot, skillOutputDir) {
|
|
551
565
|
const { absoluteBase, allMatches, kept: matches, droppedRel, dropped, nonRegularRel, nonRegular, } = await expandGlobEntry(entry, projectRoot);
|
|
552
566
|
// Project-relative in both throws below: these messages are published verbatim
|
|
553
|
-
// as `
|
|
567
|
+
// as a `SKILL_PACKAGING_FAILED` finding's `message` (see {@link anchoredPath}).
|
|
554
568
|
const reportedBase = anchoredPath(absoluteBase, projectRoot);
|
|
555
569
|
if (allMatches.length === 0) {
|
|
556
|
-
throw
|
|
570
|
+
throw packagingInputError(`files: source '${entry.source}' (glob) matched no files under ${reportedBase} — has your build run?`);
|
|
557
571
|
}
|
|
558
572
|
// Ordered BEFORE the never-package throw because it is the more specific
|
|
559
573
|
// diagnosis: if the entry nets nothing shippable and nothing it netted was even
|
|
560
574
|
// a file, "all of them are never packaged" names the wrong cause and its
|
|
561
575
|
// remediation ("declare an explicit source: entry") would not work if followed.
|
|
562
576
|
if (matches.length === 0 && droppedRel.length === 0) {
|
|
563
|
-
throw
|
|
577
|
+
throw packagingInputError(`files: source '${entry.source}' (glob) matched ${allMatches.length} path(s) under ${reportedBase}, ` +
|
|
564
578
|
`but none of them is a regular file (a symlink to a directory, a FIFO, a socket or a device node ` +
|
|
565
579
|
`cannot be packaged): ${nonRegularRel.join(', ')}. ` +
|
|
566
580
|
`Point the glob at files, or replace the link with the directory it targets.`);
|
|
@@ -578,7 +592,7 @@ async function copyGlobEntry(entry, projectRoot, skillOutputDir) {
|
|
|
578
592
|
? ''
|
|
579
593
|
: ` A further ${nonRegularRel.length.toString()} match(es) are not regular files and could not ` +
|
|
580
594
|
`be packaged either: ${nonRegularRel.join(', ')}.`;
|
|
581
|
-
throw
|
|
595
|
+
throw packagingInputError(`files: source '${entry.source}' (glob) matched ${allMatches.length} file(s) under ${reportedBase}, ` +
|
|
582
596
|
`but all of them are never packaged into a skill bundle: ${droppedRel.join(', ')}. ` +
|
|
583
597
|
// NOT "widen the glob": the filter is on basename and applies at any width, so a
|
|
584
598
|
// wider glob clears this error while still shipping none of these files — advice
|
|
@@ -593,7 +607,8 @@ async function copyGlobEntry(entry, projectRoot, skillOutputDir) {
|
|
|
593
607
|
// which equals the matched `rel` for files actually copied — the expected set
|
|
594
608
|
// verifyDestSet diffs the on-disk subtree against.
|
|
595
609
|
const rels = [];
|
|
596
|
-
|
|
610
|
+
// In order: bundle writes, where the first failure names the first match.
|
|
611
|
+
await forEachInOrder(matches, async (rel) => {
|
|
597
612
|
// joinUnderRoot asserts each matched file stays under absoluteBase (read) and
|
|
598
613
|
// that the rebased dest stays under the skill output dir (write) — H1/H2
|
|
599
614
|
// defense-in-depth against a traversal that slipped past earlier guards.
|
|
@@ -611,14 +626,11 @@ async function copyGlobEntry(entry, projectRoot, skillOutputDir) {
|
|
|
611
626
|
// the author DECLARED and expects in the bundle, so shipping silently without
|
|
612
627
|
// it would change the artifact behind their back. A non-regular match can
|
|
613
628
|
// never be packaged at all, which is why that one degrades instead.
|
|
614
|
-
await
|
|
615
|
-
await mkdir(dirname(absDest), { recursive: true });
|
|
616
|
-
await copyFile(absSource, absDest);
|
|
617
|
-
});
|
|
629
|
+
await copyEntryFile(entry, absSource, { root: skillOutputDir, dest: absDest }, projectRoot);
|
|
618
630
|
copied.push(relDest);
|
|
619
631
|
pairs.push({ absSource, absDest });
|
|
620
632
|
rels.push(toForwardSlash(rel));
|
|
621
|
-
}
|
|
633
|
+
});
|
|
622
634
|
return { copied, pairs, rels, dropped, skipped: nonRegular };
|
|
623
635
|
}
|
|
624
636
|
/**
|
|
@@ -666,9 +678,10 @@ export async function collectPreBuildGlobFindings(filesConfig, projectRoot) {
|
|
|
666
678
|
const allRefused = [];
|
|
667
679
|
const unmatched = [];
|
|
668
680
|
const skipped = [];
|
|
669
|
-
|
|
681
|
+
// In order: `expandGlobEntry`'s throws must fire in `copyGlobEntry`'s order.
|
|
682
|
+
await forEachInOrder(filesConfig, async (entry) => {
|
|
670
683
|
if (!isGlob(entry.source))
|
|
671
|
-
|
|
684
|
+
return;
|
|
672
685
|
// A '..' segment in the magic remainder is a malformed pattern that
|
|
673
686
|
// `expandGlobEntry` refuses to expand. It is the BUILD's error to raise (and
|
|
674
687
|
// `copyGlobEntry` does); a pre-build gate asking "what would this do?" must not
|
|
@@ -683,7 +696,7 @@ export async function collectPreBuildGlobFindings(filesConfig, projectRoot) {
|
|
|
683
696
|
// pattern in `SkillFileEntrySchema.source` the way `dest` already is — at which
|
|
684
697
|
// point this line becomes defense-in-depth against a config that cannot load.
|
|
685
698
|
if (hasParentTraversalSegment(globMagicRemainder(entry.source)))
|
|
686
|
-
|
|
699
|
+
return;
|
|
687
700
|
const expansion = await expandGlobEntry(entry, projectRoot);
|
|
688
701
|
const absBase = toForwardSlash(expansion.absoluteBase);
|
|
689
702
|
// The two predicates below are `copyGlobEntry`'s two throws, in its order and
|
|
@@ -694,7 +707,7 @@ export async function collectPreBuildGlobFindings(filesConfig, projectRoot) {
|
|
|
694
707
|
// exactly the misdirection the second error was written to avoid.
|
|
695
708
|
if (expansion.allMatches.length === 0) {
|
|
696
709
|
unmatched.push({ source: entry.source, absBase });
|
|
697
|
-
|
|
710
|
+
return;
|
|
698
711
|
}
|
|
699
712
|
// Reported for EVERY entry that has them, including ones that go on to be
|
|
700
713
|
// `allRefused` below — unlike the per-file drops, which that verdict
|
|
@@ -706,7 +719,7 @@ export async function collectPreBuildGlobFindings(filesConfig, projectRoot) {
|
|
|
706
719
|
// Matched only non-files. `allRefused` would name the never-package list as
|
|
707
720
|
// the cause, which is not what happened, and its remediation would not work.
|
|
708
721
|
// The `skipped` findings just pushed carry this entry on their own.
|
|
709
|
-
|
|
722
|
+
return;
|
|
710
723
|
}
|
|
711
724
|
if (expansion.kept.length === 0) {
|
|
712
725
|
// Supersedes this entry's per-file drops rather than adding to them: the
|
|
@@ -718,10 +731,10 @@ export async function collectPreBuildGlobFindings(filesConfig, projectRoot) {
|
|
|
718
731
|
absBase,
|
|
719
732
|
absRefused: expansion.dropped.map((d) => d.absFile),
|
|
720
733
|
});
|
|
721
|
-
|
|
734
|
+
return;
|
|
722
735
|
}
|
|
723
736
|
dropped.push(...expansion.dropped.filter((d) => !shippedDests.has(normalizeRelPath(d.dest))));
|
|
724
|
-
}
|
|
737
|
+
});
|
|
725
738
|
return { dropped, allRefused, unmatched, skipped };
|
|
726
739
|
}
|
|
727
740
|
/**
|
|
@@ -798,7 +811,7 @@ function assertFileShapedDest(entry) {
|
|
|
798
811
|
while (base.endsWith('/'))
|
|
799
812
|
base = base.slice(0, -1);
|
|
800
813
|
const suggested = `${base}/${entry.source.slice(entry.source.lastIndexOf('/') + 1)}`;
|
|
801
|
-
throw
|
|
814
|
+
throw packagingInputError(`files: dest '${entry.dest}' names a directory, but a non-glob entry copies ONE file to ONE path. ` +
|
|
802
815
|
`Name the output file itself (e.g. dest: '${normalizeRelPath(suggested)}'), ` +
|
|
803
816
|
`or use a glob source to copy a whole subtree.`);
|
|
804
817
|
}
|
|
@@ -831,15 +844,7 @@ async function applyNonGlobFileEntry(fileEntry, opts, bundledFileSet) {
|
|
|
831
844
|
: undefined,
|
|
832
845
|
};
|
|
833
846
|
}
|
|
834
|
-
|
|
835
|
-
// copy alone left the source `statSync` outside — so a source under a directory
|
|
836
|
-
// the process cannot traverse still escaped as a bare errno, which is the same
|
|
837
|
-
// defect one call earlier. An EXPLICIT entry is the spelling that unambiguously
|
|
838
|
-
// says "ship this file", so a bare errno here is if anything worse than on a
|
|
839
|
-
// glob: the author named the path, and the build owes them an error that names
|
|
840
|
-
// it back. (`copyNonGlobEntry`'s own deliberate errors — "does not exist", "is a
|
|
841
|
-
// directory" — carry no errno, so `attributed` passes them through untouched.)
|
|
842
|
-
const { relDest, absSource, absDest } = await attributed(fileEntry, absoluteSource, opts.projectRoot, () => copyNonGlobEntry(fileEntry, absoluteSource, opts.projectRoot, opts.skillOutputDir));
|
|
847
|
+
const { relDest, absSource, absDest } = await copyNonGlobEntry(fileEntry, absoluteSource, opts.projectRoot, opts.skillOutputDir);
|
|
843
848
|
return {
|
|
844
849
|
dests: [relDest],
|
|
845
850
|
dropped: [],
|
|
@@ -869,17 +874,16 @@ function relUnderDest(destRoot, dest) {
|
|
|
869
874
|
* rather than being weakened into a permissive one.
|
|
870
875
|
*/
|
|
871
876
|
async function runDeferredIntegrity(pending, allDests, skillOutputDir, projectRoot) {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
// hashes both sides, so an unreadable source or dest surfaces here as a raw
|
|
875
|
-
// errno carrying an absolute path and no entry name — the same defect the
|
|
876
|
-
// copy loop had, in the one lane that had not been routed through the guard.
|
|
877
|
+
// In order: the first refusal is named in config order.
|
|
878
|
+
await forEachInOrder(pending, async ({ entry, pairs, rels }) => {
|
|
877
879
|
// Anchored at the ENTRY, not at `pairs[0]`: any of the entry's files can be
|
|
878
880
|
// the one that failed, and naming the first while the errno names another is
|
|
879
|
-
// worse than naming none. The errno itself carries the offending path
|
|
880
|
-
|
|
881
|
+
// worse than naming none. The errno itself carries the offending path, and
|
|
882
|
+
// each read is coded by the tree it touched (see `verifyFilesIntegrity`).
|
|
883
|
+
const subject = entrySubject(entry, safePath.resolve(safePath.join(projectRoot, entry.source)), projectRoot);
|
|
884
|
+
verifyFilesIntegrity(subject, pairs);
|
|
881
885
|
if (rels === undefined)
|
|
882
|
-
|
|
886
|
+
return;
|
|
883
887
|
const destRoot = normalizeRelPath(entry.dest);
|
|
884
888
|
const expected = new Set(rels);
|
|
885
889
|
for (const dest of allDests) {
|
|
@@ -887,8 +891,10 @@ async function runDeferredIntegrity(pending, allDests, skillOutputDir, projectRo
|
|
|
887
891
|
if (rel !== null && rel !== '')
|
|
888
892
|
expected.add(rel);
|
|
889
893
|
}
|
|
890
|
-
|
|
891
|
-
|
|
894
|
+
const destDir = safePath.joinUnderRoot(skillOutputDir, entry.dest);
|
|
895
|
+
// Lists the bundle the build just wrote: a refusal is the output's.
|
|
896
|
+
await withFsFault({ side: 'destination', shapeFromSource: true, action: `verify ${subject} in the bundle` }, () => verifyDestSet(destDir, [...expected], entry.source));
|
|
897
|
+
});
|
|
892
898
|
}
|
|
893
899
|
export async function applyFilesConfig(opts) {
|
|
894
900
|
const bundledFileSet = new Set((opts.bundledFiles ?? []).map((f) => toForwardSlash(f)));
|
|
@@ -896,7 +902,8 @@ export async function applyFilesConfig(opts) {
|
|
|
896
902
|
const dropped = [];
|
|
897
903
|
const skipped = [];
|
|
898
904
|
const pending = [];
|
|
899
|
-
|
|
905
|
+
// In order: ordered writes — a later entry may overwrite an earlier dest, and the last one wins.
|
|
906
|
+
await forEachInOrder(opts.filesConfig, async (fileEntry) => {
|
|
900
907
|
const outcome = isGlob(fileEntry.source)
|
|
901
908
|
? await applyGlobFileEntry(fileEntry, opts)
|
|
902
909
|
: await applyNonGlobFileEntry(fileEntry, opts, bundledFileSet);
|
|
@@ -905,7 +912,7 @@ export async function applyFilesConfig(opts) {
|
|
|
905
912
|
skipped.push(...outcome.skipped);
|
|
906
913
|
if (outcome.pending)
|
|
907
914
|
pending.push(outcome.pending);
|
|
908
|
-
}
|
|
915
|
+
});
|
|
909
916
|
await runDeferredIntegrity(pending, dests, opts.skillOutputDir, opts.projectRoot);
|
|
910
917
|
// A drop is only worth reporting if the file genuinely did not ship. In the
|
|
911
918
|
// escape-hatch config the guide prescribes — a glob over a subtree plus an
|