@vibe-agent-toolkit/cli 0.2.0-rc.6 → 0.2.0-rc.7
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 +4 -4
- package/dist/bin.js +41 -158
- package/dist/bin.js.map +1 -1
- package/dist/command-loaders.d.ts +2 -2
- package/dist/command-loaders.d.ts.map +1 -1
- package/dist/command-loaders.js +4 -2
- package/dist/command-loaders.js.map +1 -1
- package/dist/commands/ard/emit.d.ts +104 -0
- package/dist/commands/ard/emit.d.ts.map +1 -0
- package/dist/commands/ard/emit.js +223 -0
- package/dist/commands/ard/emit.js.map +1 -0
- package/dist/commands/ard/index.d.ts +12 -0
- package/dist/commands/ard/index.d.ts.map +1 -0
- package/dist/commands/ard/index.js +79 -0
- package/dist/commands/ard/index.js.map +1 -0
- package/dist/commands/ard/surfaces.d.ts +56 -0
- package/dist/commands/ard/surfaces.d.ts.map +1 -0
- package/dist/commands/ard/surfaces.js +150 -0
- package/dist/commands/ard/surfaces.js.map +1 -0
- package/dist/commands/audit.d.ts +75 -8
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +605 -140
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/claude/budget.d.ts +13 -0
- package/dist/commands/claude/budget.d.ts.map +1 -1
- package/dist/commands/claude/budget.js +80 -28
- package/dist/commands/claude/budget.js.map +1 -1
- package/dist/commands/claude/context.js +1 -1
- package/dist/commands/claude/context.js.map +1 -1
- package/dist/commands/claude/marketplace/validate.d.ts +55 -22
- package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
- package/dist/commands/claude/marketplace/validate.js +380 -75
- package/dist/commands/claude/marketplace/validate.js.map +1 -1
- package/dist/commands/claude/org/skills.d.ts +84 -3
- package/dist/commands/claude/org/skills.d.ts.map +1 -1
- package/dist/commands/claude/org/skills.js +218 -46
- package/dist/commands/claude/org/skills.js.map +1 -1
- package/dist/commands/claude/plugin/build.d.ts +8 -0
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +16 -2
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.d.ts +72 -0
- package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
- package/dist/commands/claude/plugin/tree-copy.js +215 -10
- package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
- package/dist/commands/corpus/index.d.ts.map +1 -1
- package/dist/commands/corpus/index.js +3 -0
- package/dist/commands/corpus/index.js.map +1 -1
- package/dist/commands/corpus/report.d.ts +0 -1
- package/dist/commands/corpus/report.d.ts.map +1 -1
- package/dist/commands/corpus/report.js +0 -1
- package/dist/commands/corpus/report.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts +58 -1
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +90 -15
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/corpus/scan.d.ts.map +1 -1
- package/dist/commands/corpus/scan.js +0 -1
- package/dist/commands/corpus/scan.js.map +1 -1
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +96 -18
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/okf/index.d.ts +11 -0
- package/dist/commands/okf/index.d.ts.map +1 -0
- package/dist/commands/okf/index.js +102 -0
- package/dist/commands/okf/index.js.map +1 -0
- package/dist/commands/okf/validate.d.ts +82 -0
- package/dist/commands/okf/validate.d.ts.map +1 -0
- package/dist/commands/okf/validate.js +157 -0
- package/dist/commands/okf/validate.js.map +1 -0
- package/dist/commands/phase-utils.d.ts +19 -3
- package/dist/commands/phase-utils.d.ts.map +1 -1
- package/dist/commands/phase-utils.js +26 -5
- package/dist/commands/phase-utils.js.map +1 -1
- package/dist/commands/rag/index-command.d.ts +27 -2
- package/dist/commands/rag/index-command.d.ts.map +1 -1
- package/dist/commands/rag/index-command.js +44 -7
- package/dist/commands/rag/index-command.js.map +1 -1
- package/dist/commands/rag/index.d.ts.map +1 -1
- package/dist/commands/rag/index.js +2 -0
- package/dist/commands/rag/index.js.map +1 -1
- package/dist/commands/resources/check-progress.d.ts +3 -0
- package/dist/commands/resources/check-progress.d.ts.map +1 -1
- package/dist/commands/resources/check-progress.js +6 -0
- package/dist/commands/resources/check-progress.js.map +1 -1
- package/dist/commands/resources/check.d.ts +33 -4
- package/dist/commands/resources/check.d.ts.map +1 -1
- package/dist/commands/resources/check.js +131 -44
- package/dist/commands/resources/check.js.map +1 -1
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +41 -9
- package/dist/commands/resources/index.js.map +1 -1
- package/dist/commands/resources/query.d.ts +18 -1
- package/dist/commands/resources/query.d.ts.map +1 -1
- package/dist/commands/resources/query.js +29 -4
- package/dist/commands/resources/query.js.map +1 -1
- package/dist/commands/resources/validate.d.ts +29 -0
- package/dist/commands/resources/validate.d.ts.map +1 -1
- package/dist/commands/resources/validate.js +116 -13
- package/dist/commands/resources/validate.js.map +1 -1
- package/dist/commands/skill/review.d.ts.map +1 -1
- package/dist/commands/skill/review.js +9 -2
- package/dist/commands/skill/review.js.map +1 -1
- package/dist/commands/skill/test/run.d.ts.map +1 -1
- package/dist/commands/skill/test/run.js +21 -6
- package/dist/commands/skill/test/run.js.map +1 -1
- package/dist/commands/skills/build.d.ts.map +1 -1
- package/dist/commands/skills/build.js +16 -3
- package/dist/commands/skills/build.js.map +1 -1
- package/dist/commands/skills/list.d.ts +2 -1
- package/dist/commands/skills/list.d.ts.map +1 -1
- package/dist/commands/skills/list.js +31 -9
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/skill-discovery.d.ts +40 -1
- package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
- package/dist/commands/skills/skill-discovery.js +32 -3
- package/dist/commands/skills/skill-discovery.js.map +1 -1
- package/dist/commands/skills/validate-command.d.ts.map +1 -1
- package/dist/commands/skills/validate-command.js +11 -3
- package/dist/commands/skills/validate-command.js.map +1 -1
- package/dist/commands/skills/validate.d.ts +66 -7
- package/dist/commands/skills/validate.d.ts.map +1 -1
- package/dist/commands/skills/validate.js +133 -29
- package/dist/commands/skills/validate.js.map +1 -1
- package/dist/commands/verify.d.ts +94 -3
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +192 -45
- package/dist/commands/verify.js.map +1 -1
- package/dist/skill-resolution/packaging-config.d.ts +49 -5
- package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
- package/dist/skill-resolution/packaging-config.js +59 -19
- package/dist/skill-resolution/packaging-config.js.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
- package/dist/skill-resolution/resolve-skill-reference.js +6 -3
- package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
- package/dist/utils/command-error.d.ts +31 -0
- package/dist/utils/command-error.d.ts.map +1 -1
- package/dist/utils/command-error.js +45 -0
- package/dist/utils/command-error.js.map +1 -1
- package/dist/utils/edge-lens-evaluation.d.ts +83 -0
- package/dist/utils/edge-lens-evaluation.d.ts.map +1 -0
- package/dist/utils/edge-lens-evaluation.js +110 -0
- package/dist/utils/edge-lens-evaluation.js.map +1 -0
- package/dist/utils/optional-backend.d.ts +5 -4
- package/dist/utils/optional-backend.d.ts.map +1 -1
- package/dist/utils/optional-backend.js +5 -4
- package/dist/utils/optional-backend.js.map +1 -1
- package/dist/utils/project-root-policy.d.ts +20 -0
- package/dist/utils/project-root-policy.d.ts.map +1 -1
- package/dist/utils/project-root-policy.js +32 -0
- package/dist/utils/project-root-policy.js.map +1 -1
- package/dist/utils/projection-query.d.ts +41 -4
- package/dist/utils/projection-query.d.ts.map +1 -1
- package/dist/utils/projection-query.js +44 -10
- package/dist/utils/projection-query.js.map +1 -1
- package/dist/utils/projection-store.d.ts +41 -15
- package/dist/utils/projection-store.d.ts.map +1 -1
- package/dist/utils/projection-store.js +65 -18
- package/dist/utils/projection-store.js.map +1 -1
- package/dist/utils/repeatable-option.d.ts +37 -0
- package/dist/utils/repeatable-option.d.ts.map +1 -0
- package/dist/utils/repeatable-option.js +39 -0
- package/dist/utils/repeatable-option.js.map +1 -0
- package/dist/utils/resource-loader.d.ts +4 -3
- package/dist/utils/resource-loader.d.ts.map +1 -1
- package/dist/utils/resource-loader.js +61 -30
- package/dist/utils/resource-loader.js.map +1 -1
- package/dist/utils/root-argv.d.ts +53 -0
- package/dist/utils/root-argv.d.ts.map +1 -0
- package/dist/utils/root-argv.js +215 -0
- package/dist/utils/root-argv.js.map +1 -0
- package/dist/utils/run-integrity.d.ts +95 -0
- package/dist/utils/run-integrity.d.ts.map +1 -0
- package/dist/utils/run-integrity.js +102 -0
- package/dist/utils/run-integrity.js.map +1 -0
- package/dist/utils/sqlite-experimental-warning.d.ts +69 -0
- package/dist/utils/sqlite-experimental-warning.d.ts.map +1 -0
- package/dist/utils/sqlite-experimental-warning.js +144 -0
- package/dist/utils/sqlite-experimental-warning.js.map +1 -0
- package/dist/utils/user-context-scanner.d.ts +8 -0
- package/dist/utils/user-context-scanner.d.ts.map +1 -1
- package/dist/utils/user-context-scanner.js +4 -0
- package/dist/utils/user-context-scanner.js.map +1 -1
- package/dist/utils/validate-help-files.d.ts.map +1 -1
- package/dist/utils/validate-help-files.js +9 -2
- package/dist/utils/validate-help-files.js.map +1 -1
- package/docs/audit.md +120 -7
- package/docs/doctor.md +6 -6
- package/docs/index.md +1 -1
- package/docs/rag.md +3 -1
- package/docs/resources.md +5 -1
- package/docs/skills.md +47 -62
- package/package.json +18 -18
|
@@ -296,11 +296,28 @@ export interface ZipInspection {
|
|
|
296
296
|
* ZIP lane reach the same verdict about the same content.
|
|
297
297
|
*/
|
|
298
298
|
readonly neverUploaded: readonly string[];
|
|
299
|
+
/**
|
|
300
|
+
* Every markdown member, inflated, shaped as the parts the directory lane
|
|
301
|
+
* hands {@link warnUnportableReferences} — so the ZIP lane runs the SAME
|
|
302
|
+
* checks over the same content rather than a second implementation of them.
|
|
303
|
+
*
|
|
304
|
+
* Markdown only, and only within {@link MAX_INSPECTED_DOCUMENT_BYTES} an
|
|
305
|
+
* entry: these detectors read prose, and inflating an archive's binaries to
|
|
306
|
+
* hand them to a reader that skips them is work spent to produce nothing.
|
|
307
|
+
*/
|
|
308
|
+
readonly documents: readonly MultipartFile[];
|
|
309
|
+
/**
|
|
310
|
+
* The archive's top-level directory, when it has one — the prefix
|
|
311
|
+
* {@link bundleRelativeName} strips so a finding is located in the same
|
|
312
|
+
* namespace a `validation.allow` glob is matched in. `undefined` for an
|
|
313
|
+
* archive whose SKILL.md sits at the root, which has no prefix to strip.
|
|
314
|
+
*/
|
|
315
|
+
readonly bundleRoot: string | undefined;
|
|
299
316
|
}
|
|
300
317
|
/**
|
|
301
318
|
* What a ZIP will weigh AFTER the API expands it, read from the archive's own
|
|
302
|
-
* central directory — plus the name its inner SKILL.md declares,
|
|
303
|
-
*
|
|
319
|
+
* central directory — plus the name its inner SKILL.md declares, any answer key
|
|
320
|
+
* it carries, and the markdown members the portability checks read.
|
|
304
321
|
*
|
|
305
322
|
* 🔑 **The API expands a ZIP and applies the ceiling to the UNCOMPRESSED total,
|
|
306
323
|
* not to the archive.** Measured against the live API by an adopter: a
|
|
@@ -332,7 +349,7 @@ export interface ZipInspection {
|
|
|
332
349
|
* caller's uncompressed-total gate, so the ceiling this function exists to
|
|
333
350
|
* enforce could not protect the inflation this function performed. Nothing is
|
|
334
351
|
* written to disk — that part stands — but the decompression is now ordered
|
|
335
|
-
* after the total is known and bounded by {@link
|
|
352
|
+
* after the total is known and bounded by {@link MAX_INSPECTED_DOCUMENT_BYTES},
|
|
336
353
|
* so an archive declaring a 4 GiB SKILL.md is enumerated and never inflated.
|
|
337
354
|
*/
|
|
338
355
|
export declare function inspectZipArchive(zipPath: string): Promise<ZipInspection | undefined>;
|
|
@@ -447,6 +464,70 @@ export declare function summarizeNpmInstall(source: string, results: readonly Sk
|
|
|
447
464
|
* Upload a local skill directory or ZIP file. Exported for testing.
|
|
448
465
|
*/
|
|
449
466
|
export declare function installFromLocal(source: string, titleOverride: string | undefined, client: OrgApiClient, logger: UploadLogger): Promise<object>;
|
|
467
|
+
/** One version the sweep could not delete, and the reason it gave. */
|
|
468
|
+
export interface VersionDeleteFailure {
|
|
469
|
+
readonly version: string;
|
|
470
|
+
readonly reason: string;
|
|
471
|
+
}
|
|
472
|
+
/** What a `--all` sweep did to the versions it was handed. */
|
|
473
|
+
export interface VersionSweep {
|
|
474
|
+
/** Versions this run destroyed. Irreversible, and the record of it. */
|
|
475
|
+
readonly deleted: readonly string[];
|
|
476
|
+
/** Versions still there, each with why. Empty means the sweep is complete. */
|
|
477
|
+
readonly failures: readonly VersionDeleteFailure[];
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Delete every version handed in, and keep going when one refuses.
|
|
481
|
+
*
|
|
482
|
+
* 🚨 **One refusal is a fact about ONE version.** This loop used to return on the
|
|
483
|
+
* first one, so every version after it was never ATTEMPTED — not failed, not
|
|
484
|
+
* reported, unexamined. Deleting a workspace skill requires deleting every
|
|
485
|
+
* version first, so the operator was left with a skill that could not be deleted,
|
|
486
|
+
* a report that named one problem out of an unknown number, and no way to tell
|
|
487
|
+
* from the output which versions were still there. A transient refusal on version
|
|
488
|
+
* 2 of 30 hid the state of the other 28.
|
|
489
|
+
*
|
|
490
|
+
* The sweep therefore ATTEMPTS all of them and reports both lists. The caller
|
|
491
|
+
* decides what the outcome means: some deleted plus some failed is a run that
|
|
492
|
+
* happened and went wrong (exit 1, with the record); nothing deleted at all is
|
|
493
|
+
* the ending the command's help documents as exit 2.
|
|
494
|
+
*
|
|
495
|
+
* ⛔ It deliberately does NOT stop early on a repeated failure. A "the API is
|
|
496
|
+
* clearly down, give up" heuristic is how the abandoned-versions defect reads
|
|
497
|
+
* from inside: the whole value here is that every version's state is KNOWN when
|
|
498
|
+
* the command ends.
|
|
499
|
+
*/
|
|
500
|
+
export declare function deleteEveryVersion(client: Pick<OrgApiClient, 'deleteSkillVersion'>, skillId: string, versions: readonly string[], logger: UploadLogger): Promise<VersionSweep>;
|
|
501
|
+
/**
|
|
502
|
+
* Every version the sweep could not delete, and why — the one sentence both the
|
|
503
|
+
* published report and the exit-2 throw are built from, so the two endings never
|
|
504
|
+
* describe the same run differently.
|
|
505
|
+
*/
|
|
506
|
+
export declare function describeVersionSweepFailures(failures: readonly VersionDeleteFailure[]): string;
|
|
507
|
+
/** What {@link reportHalfDeleted} needs to describe a run that destroyed some of what it was asked to. */
|
|
508
|
+
export interface HalfDeletedReport {
|
|
509
|
+
readonly skillId: string;
|
|
510
|
+
readonly deletedVersions: readonly string[];
|
|
511
|
+
/** Versions still present. Empty when the sweep completed and the SKILL delete is what failed. */
|
|
512
|
+
readonly failedVersions: readonly string[];
|
|
513
|
+
readonly error: string;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* The document a `--all` run publishes when it destroyed something and then did
|
|
517
|
+
* not finish.
|
|
518
|
+
*
|
|
519
|
+
* 🔑 The deleted list is a RECORD, not a progress counter. Version deletion is
|
|
520
|
+
* irreversible, so a failure part-way through leaves a workspace nobody can
|
|
521
|
+
* reconstruct — and throwing here would end on `handleCommandError`'s exit 2
|
|
522
|
+
* ("the run could not happen") and DISCARD the document. It happened, and it
|
|
523
|
+
* destroyed things the operator now has no other list of. So the lists travel
|
|
524
|
+
* with the failure and the run ends 1: it happened, and its outcome is wrong.
|
|
525
|
+
*
|
|
526
|
+
* `failedVersions` is the other half, and the half a re-run needs: what is still
|
|
527
|
+
* there. Without it the operator knows what they lost and not what they still
|
|
528
|
+
* have to deal with.
|
|
529
|
+
*/
|
|
530
|
+
export declare function reportHalfDeleted(report: HalfDeletedReport): OrgCommandFailure;
|
|
450
531
|
export declare function createOrgSkillsCommand(): Command;
|
|
451
532
|
export {};
|
|
452
533
|
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/org/skills.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../../src/commands/claude/org/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -459,19 +459,23 @@ export function resolveSourceArgument(source) {
|
|
|
459
459
|
: safePath.resolve(process.cwd(), source);
|
|
460
460
|
}
|
|
461
461
|
/**
|
|
462
|
-
* The largest
|
|
462
|
+
* The largest single markdown member this will decompress to read.
|
|
463
463
|
*
|
|
464
464
|
* Not a limit on what may be PUBLISHED — the API's own ceiling decides that, and
|
|
465
|
-
* a bigger document simply goes unread rather than refused. It bounds the
|
|
466
|
-
*
|
|
465
|
+
* a bigger document simply goes unread rather than refused. It bounds the
|
|
466
|
+
* allocations this module performs on attacker-supplied metadata: `getData()`
|
|
467
467
|
* inflates whatever `header.size` claims, and a header can claim anything. A
|
|
468
|
-
* megabyte is two orders of magnitude above any real
|
|
468
|
+
* megabyte is two orders of magnitude above any real skill document.
|
|
469
|
+
*
|
|
470
|
+
* ⚠️ It is a PER-ENTRY bound. The total is bounded separately, and more
|
|
471
|
+
* tightly: nothing is inflated at all until the archive's declared uncompressed
|
|
472
|
+
* total is known to be within {@link API_SKILL_MAX_UPLOAD_BYTES}.
|
|
469
473
|
*/
|
|
470
|
-
const
|
|
474
|
+
const MAX_INSPECTED_DOCUMENT_BYTES = 1024 * 1024;
|
|
471
475
|
/**
|
|
472
476
|
* What a ZIP will weigh AFTER the API expands it, read from the archive's own
|
|
473
|
-
* central directory — plus the name its inner SKILL.md declares,
|
|
474
|
-
*
|
|
477
|
+
* central directory — plus the name its inner SKILL.md declares, any answer key
|
|
478
|
+
* it carries, and the markdown members the portability checks read.
|
|
475
479
|
*
|
|
476
480
|
* 🔑 **The API expands a ZIP and applies the ceiling to the UNCOMPRESSED total,
|
|
477
481
|
* not to the archive.** Measured against the live API by an adopter: a
|
|
@@ -503,7 +507,7 @@ const MAX_INSPECTED_SKILL_MD_BYTES = 1024 * 1024;
|
|
|
503
507
|
* caller's uncompressed-total gate, so the ceiling this function exists to
|
|
504
508
|
* enforce could not protect the inflation this function performed. Nothing is
|
|
505
509
|
* written to disk — that part stands — but the decompression is now ordered
|
|
506
|
-
* after the total is known and bounded by {@link
|
|
510
|
+
* after the total is known and bounded by {@link MAX_INSPECTED_DOCUMENT_BYTES},
|
|
507
511
|
* so an archive declaring a 4 GiB SKILL.md is enumerated and never inflated.
|
|
508
512
|
*/
|
|
509
513
|
export async function inspectZipArchive(zipPath) {
|
|
@@ -530,14 +534,68 @@ export async function inspectZipArchive(zipPath) {
|
|
|
530
534
|
const neverUploaded = files
|
|
531
535
|
.map(entry => toForwardSlash(entry.entryName))
|
|
532
536
|
.filter(name => name.split('/').some(segment => NEVER_UPLOADED_DIR_NAMES.has(segment)));
|
|
533
|
-
// PASS 2 — the
|
|
537
|
+
// PASS 2 — the entries worth inflating, and only once the total says this
|
|
534
538
|
// archive is not already refused. An over-ceiling archive is about to be
|
|
535
539
|
// rejected by the caller, so inflating anything out of it would be work spent
|
|
536
540
|
// on an upload that cannot happen.
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
+
if (uncompressedBytes > API_SKILL_MAX_UPLOAD_BYTES) {
|
|
542
|
+
return { uncompressedBytes, declaredName: undefined, neverUploaded, documents: [], bundleRoot: undefined };
|
|
543
|
+
}
|
|
544
|
+
const elected = electShallowestSkillMd(files);
|
|
545
|
+
return {
|
|
546
|
+
uncompressedBytes,
|
|
547
|
+
declaredName: declaredNameOf(elected),
|
|
548
|
+
neverUploaded,
|
|
549
|
+
documents: inflateMarkdownMembers(files),
|
|
550
|
+
bundleRoot: archiveRootOf(elected?.entryName),
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Every markdown member of the archive, as an upload part.
|
|
555
|
+
*
|
|
556
|
+
* 🔑 This exists so the ZIP lane can run the portability family through the ONE
|
|
557
|
+
* function the directory lane runs it through. Until it did, `install <zip>`
|
|
558
|
+
* performed none of the checks `install --help` promises of "every markdown
|
|
559
|
+
* document in the bundle": the archive went to `sendSkillUpload` as one opaque
|
|
560
|
+
* part, and an operator following the documented contract got silence where they
|
|
561
|
+
* were promised warnings. Routing the parts back through
|
|
562
|
+
* {@link warnUnportableReferences} keeps ONE implementation of the checks — a
|
|
563
|
+
* second copy of the three collector calls is how the two lanes start disagreeing.
|
|
564
|
+
*
|
|
565
|
+
* An entry that will not inflate is SKIPPED, never fatal: this module's standing
|
|
566
|
+
* position is that an archive VAT cannot read is not an archive VAT should block,
|
|
567
|
+
* and the checks it feeds only ever warn.
|
|
568
|
+
*/
|
|
569
|
+
function inflateMarkdownMembers(files) {
|
|
570
|
+
const documents = [];
|
|
571
|
+
for (const entry of files) {
|
|
572
|
+
const filename = toForwardSlash(entry.entryName);
|
|
573
|
+
if (!filename.toLowerCase().endsWith('.md'))
|
|
574
|
+
continue;
|
|
575
|
+
if (entry.header.size > MAX_INSPECTED_DOCUMENT_BYTES)
|
|
576
|
+
continue;
|
|
577
|
+
try {
|
|
578
|
+
documents.push({ fieldName: 'files[]', filename, content: entry.getData() });
|
|
579
|
+
}
|
|
580
|
+
catch {
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return documents;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* The directory the elected SKILL.md sits in, which is the archive's bundle root.
|
|
588
|
+
*
|
|
589
|
+
* `my-skill/SKILL.md` roots the bundle at `my-skill`; a SKILL.md at the archive
|
|
590
|
+
* root has no prefix, and neither does an archive with no SKILL.md at all. ZIP
|
|
591
|
+
* fixes `/` as the entry separator, so this reads the format rather than handling
|
|
592
|
+
* a host path.
|
|
593
|
+
*/
|
|
594
|
+
function archiveRootOf(entryName) {
|
|
595
|
+
if (entryName === undefined)
|
|
596
|
+
return undefined;
|
|
597
|
+
const cut = toForwardSlash(entryName).lastIndexOf('/');
|
|
598
|
+
return cut === -1 ? undefined : entryName.slice(0, cut);
|
|
541
599
|
}
|
|
542
600
|
/**
|
|
543
601
|
* The SKILL.md nearest the archive root, which is the one whose `name` the API
|
|
@@ -605,7 +663,7 @@ function zipEntryDepth(entryName) {
|
|
|
605
663
|
* computed from headers, so failing here costs only the name.
|
|
606
664
|
*/
|
|
607
665
|
function declaredNameOf(entry) {
|
|
608
|
-
if (entry === undefined || entry.header.size >
|
|
666
|
+
if (entry === undefined || entry.header.size > MAX_INSPECTED_DOCUMENT_BYTES)
|
|
609
667
|
return undefined;
|
|
610
668
|
try {
|
|
611
669
|
return declaredSkillNameIn(entry.getData().toString('utf8'));
|
|
@@ -650,7 +708,10 @@ function requireDeclaredName(skillMdPath) {
|
|
|
650
708
|
* skill dir — nothing inside the tree to withhold.
|
|
651
709
|
*/
|
|
652
710
|
async function declaredTestInputPaths(skillDir) {
|
|
653
|
-
|
|
711
|
+
// `'refuse'`: an upload that cannot tell which paths are test input might
|
|
712
|
+
// publish an answer key. The throw is reported per skill by the install
|
|
713
|
+
// loop's catch (logged, and counted in its failures) — never swallowed.
|
|
714
|
+
const config = await resolveSkillPackagingConfig(safePath.join(skillDir, 'SKILL.md'), 'refuse');
|
|
654
715
|
const declared = config?.test?.evals;
|
|
655
716
|
if (declared === undefined)
|
|
656
717
|
return new Set();
|
|
@@ -805,7 +866,7 @@ async function prepareSkillUpload(skillDir, titleOverride, logger) {
|
|
|
805
866
|
// Resolved HERE rather than plumbed out of `collectSkillUploadFiles`, which is
|
|
806
867
|
// exported and deliberately resolves its own so no caller can hand it a config
|
|
807
868
|
// with the exclusion skipped.
|
|
808
|
-
const packaging = await resolveSkillPackagingConfig(skillMdPath);
|
|
869
|
+
const packaging = await resolveSkillPackagingConfig(skillMdPath, 'refuse');
|
|
809
870
|
warnUnportableReferences(files, dirName, packaging?.validation, logger);
|
|
810
871
|
return { displayTitle, files, dirName };
|
|
811
872
|
}
|
|
@@ -1169,9 +1230,102 @@ async function installZipArchive(sourcePath, titleOverride, client, logger) {
|
|
|
1169
1230
|
+ `SKILL.md inside declares name "${inspected.declaredName}". Every version will carry `
|
|
1170
1231
|
+ `the declared name. Pass --title "${inspected.declaredName}" to make them agree.`);
|
|
1171
1232
|
}
|
|
1233
|
+
// 🚨 The SAME function the directory lane calls, over the archive's own
|
|
1234
|
+
// markdown. Until this line existed, `install <zip>` ran NONE of the
|
|
1235
|
+
// portability checks its `--help` promises of "every markdown document in
|
|
1236
|
+
// the bundle" — the archive went straight to `sendSkillUpload`, so the
|
|
1237
|
+
// adopter finding that produced the family (10 of 54 skills referencing a
|
|
1238
|
+
// path outside their own tree, published green and unable to run) was
|
|
1239
|
+
// invisible on the lane most likely to carry a hand-built bundle.
|
|
1240
|
+
//
|
|
1241
|
+
// ⚠️ NO validation config, and that is a real narrowing, stated in the
|
|
1242
|
+
// help text. `validation.allow` / `validation.severity` are resolved by
|
|
1243
|
+
// walking up from a skill's SKILL.md to its governing project — and an
|
|
1244
|
+
// archive member has no path on disk to walk up from, the same reason a
|
|
1245
|
+
// config-declared eval-suite location is unreadable here. So a waiver that
|
|
1246
|
+
// silences `vat skills build` does NOT silence this lane. The checks only
|
|
1247
|
+
// warn, so the cost of the narrowing is noise, never a blocked publish;
|
|
1248
|
+
// the cost of skipping them was silence on a documented promise.
|
|
1249
|
+
warnUnportableReferences(inspected.documents, inspected.bundleRoot, undefined, logger);
|
|
1172
1250
|
}
|
|
1173
1251
|
return sendSkillUpload(client, displayTitle, files);
|
|
1174
1252
|
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Delete every version handed in, and keep going when one refuses.
|
|
1255
|
+
*
|
|
1256
|
+
* 🚨 **One refusal is a fact about ONE version.** This loop used to return on the
|
|
1257
|
+
* first one, so every version after it was never ATTEMPTED — not failed, not
|
|
1258
|
+
* reported, unexamined. Deleting a workspace skill requires deleting every
|
|
1259
|
+
* version first, so the operator was left with a skill that could not be deleted,
|
|
1260
|
+
* a report that named one problem out of an unknown number, and no way to tell
|
|
1261
|
+
* from the output which versions were still there. A transient refusal on version
|
|
1262
|
+
* 2 of 30 hid the state of the other 28.
|
|
1263
|
+
*
|
|
1264
|
+
* The sweep therefore ATTEMPTS all of them and reports both lists. The caller
|
|
1265
|
+
* decides what the outcome means: some deleted plus some failed is a run that
|
|
1266
|
+
* happened and went wrong (exit 1, with the record); nothing deleted at all is
|
|
1267
|
+
* the ending the command's help documents as exit 2.
|
|
1268
|
+
*
|
|
1269
|
+
* ⛔ It deliberately does NOT stop early on a repeated failure. A "the API is
|
|
1270
|
+
* clearly down, give up" heuristic is how the abandoned-versions defect reads
|
|
1271
|
+
* from inside: the whole value here is that every version's state is KNOWN when
|
|
1272
|
+
* the command ends.
|
|
1273
|
+
*/
|
|
1274
|
+
export async function deleteEveryVersion(client, skillId, versions, logger) {
|
|
1275
|
+
const deleted = [];
|
|
1276
|
+
const failures = [];
|
|
1277
|
+
for (const version of versions) {
|
|
1278
|
+
try {
|
|
1279
|
+
await client.deleteSkillVersion(skillId, version);
|
|
1280
|
+
}
|
|
1281
|
+
catch (error) {
|
|
1282
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1283
|
+
failures.push({ version, reason });
|
|
1284
|
+
logger.info(` ⚠ version ${version} was not deleted: ${reason}`);
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1287
|
+
deleted.push(version);
|
|
1288
|
+
logger.info(` Deleted version ${version}`);
|
|
1289
|
+
}
|
|
1290
|
+
return { deleted, failures };
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Every version the sweep could not delete, and why — the one sentence both the
|
|
1294
|
+
* published report and the exit-2 throw are built from, so the two endings never
|
|
1295
|
+
* describe the same run differently.
|
|
1296
|
+
*/
|
|
1297
|
+
export function describeVersionSweepFailures(failures) {
|
|
1298
|
+
return failures.map(failure => `${failure.version}: ${failure.reason}`).join('; ');
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* The document a `--all` run publishes when it destroyed something and then did
|
|
1302
|
+
* not finish.
|
|
1303
|
+
*
|
|
1304
|
+
* 🔑 The deleted list is a RECORD, not a progress counter. Version deletion is
|
|
1305
|
+
* irreversible, so a failure part-way through leaves a workspace nobody can
|
|
1306
|
+
* reconstruct — and throwing here would end on `handleCommandError`'s exit 2
|
|
1307
|
+
* ("the run could not happen") and DISCARD the document. It happened, and it
|
|
1308
|
+
* destroyed things the operator now has no other list of. So the lists travel
|
|
1309
|
+
* with the failure and the run ends 1: it happened, and its outcome is wrong.
|
|
1310
|
+
*
|
|
1311
|
+
* `failedVersions` is the other half, and the half a re-run needs: what is still
|
|
1312
|
+
* there. Without it the operator knows what they lost and not what they still
|
|
1313
|
+
* have to deal with.
|
|
1314
|
+
*/
|
|
1315
|
+
export function reportHalfDeleted(report) {
|
|
1316
|
+
const { skillId, deletedVersions, failedVersions } = report;
|
|
1317
|
+
return orgCommandFailure({
|
|
1318
|
+
id: skillId,
|
|
1319
|
+
deleted: false,
|
|
1320
|
+
deletedVersions,
|
|
1321
|
+
failedVersions,
|
|
1322
|
+
error: report.error,
|
|
1323
|
+
note: `${String(deletedVersions.length)} version(s) of ${skillId} were deleted and cannot be `
|
|
1324
|
+
+ `restored; ${String(failedVersions.length)} could not be deleted and are still there. `
|
|
1325
|
+
+ 'The skill itself still exists — the API refuses a skill that still has versions. '
|
|
1326
|
+
+ 'Re-run `--all` once the cause is cleared: it will attempt only what is left.',
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1175
1329
|
// ── Commands ───────────────────────────────────────────────────────────
|
|
1176
1330
|
export function createOrgSkillsCommand() {
|
|
1177
1331
|
const command = new Command('skills');
|
|
@@ -1279,9 +1433,16 @@ Description:
|
|
|
1279
1433
|
the non-portable reference, non-portable command, and unqualified MCP tool-name
|
|
1280
1434
|
checks — the ones that catch a skill referencing a path outside its own tree,
|
|
1281
1435
|
which cannot resolve once the API publishes it alone. These WARN and never
|
|
1282
|
-
block
|
|
1283
|
-
|
|
1284
|
-
|
|
1436
|
+
block. Run \`vat audit <dir>\` for the full report.
|
|
1437
|
+
|
|
1438
|
+
A ZIP faces the same three checks: its markdown members are read out of the
|
|
1439
|
+
archive and run through them, so a hand-built bundle is not the quiet lane.
|
|
1440
|
+
The one difference is the config. On a DIRECTORY, \`validation.allow\` /
|
|
1441
|
+
\`validation.severity\` from the governing vibe-agent-toolkit.config.yaml are
|
|
1442
|
+
honoured, so a waiver that makes \`vat skills build\` green makes this quiet
|
|
1443
|
+
too. On a ZIP there is no directory to resolve that config from — the same
|
|
1444
|
+
reason a config-declared eval-suite location is invisible here — so the checks
|
|
1445
|
+
run UNWAIVED and a warning you have already waived elsewhere will still print.
|
|
1285
1446
|
|
|
1286
1447
|
There are TWO size gates and a ZIP faces both. The REQUEST gate weighs the
|
|
1287
1448
|
multipart body — file bytes plus about 156 bytes of framing per file — against
|
|
@@ -1325,14 +1486,11 @@ Examples:
|
|
|
1325
1486
|
// travels with the failure, and the run ends 1: it happened, and its
|
|
1326
1487
|
// outcome is wrong.
|
|
1327
1488
|
const deletedVersions = [];
|
|
1328
|
-
const halfDeleted = (error) =>
|
|
1329
|
-
|
|
1330
|
-
deleted: false,
|
|
1489
|
+
const halfDeleted = (error, failedVersions) => reportHalfDeleted({
|
|
1490
|
+
skillId,
|
|
1331
1491
|
deletedVersions,
|
|
1492
|
+
failedVersions,
|
|
1332
1493
|
error: error instanceof Error ? error.message : String(error),
|
|
1333
|
-
note: `${String(deletedVersions.length)} version(s) of ${skillId} were deleted before this `
|
|
1334
|
-
+ 'failed and cannot be restored. The skill itself still exists. Re-run '
|
|
1335
|
-
+ '`--all` once the cause is cleared; the versions listed here are already gone.',
|
|
1336
1494
|
});
|
|
1337
1495
|
if (options.all) {
|
|
1338
1496
|
const versions = await autopaginateSkills(client, skillVersionsPath(skillId));
|
|
@@ -1340,21 +1498,25 @@ Examples:
|
|
|
1340
1498
|
// "Found …", not "Deleting …": nothing has been deleted at this point
|
|
1341
1499
|
// and the very next call can be refused. Cf. `installFromLocal`.
|
|
1342
1500
|
logger.info(`Found ${String(versionData.length)} version(s) of ${skillId} to delete first`);
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1501
|
+
// ATTEMPTS every version, whatever any one of them answers. See
|
|
1502
|
+
// `deleteEveryVersion`: returning on the first refusal left the rest
|
|
1503
|
+
// unexamined, and the skill undeletable with no record of what remained.
|
|
1504
|
+
const sweep = await deleteEveryVersion(client, skillId, versionData.map(v => v.version), logger);
|
|
1505
|
+
deletedVersions.push(...sweep.deleted);
|
|
1506
|
+
if (sweep.failures.length > 0) {
|
|
1507
|
+
const detail = describeVersionSweepFailures(sweep.failures);
|
|
1508
|
+
// Nothing was destroyed, so there is no record worth publishing and
|
|
1509
|
+
// "could not happen" (exit 2, via the throw) is the honest ending —
|
|
1510
|
+
// the same rule as before, now decided on the WHOLE sweep rather than
|
|
1511
|
+
// on its first refusal.
|
|
1512
|
+
if (deletedVersions.length === 0) {
|
|
1513
|
+
throw new Error(`No version of ${skillId} could be deleted, so the skill was left alone. `
|
|
1514
|
+
+ `${String(sweep.failures.length)} attempt(s) failed — ${detail}`);
|
|
1346
1515
|
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
if (deletedVersions.length === 0)
|
|
1352
|
-
throw error;
|
|
1353
|
-
logger.info(` ⚠ version ${ver.version} was not deleted`);
|
|
1354
|
-
return halfDeleted(error);
|
|
1355
|
-
}
|
|
1356
|
-
deletedVersions.push(ver.version);
|
|
1357
|
-
logger.info(` Deleted version ${ver.version}`);
|
|
1516
|
+
// The skill delete is not attempted: the API refuses a skill that still
|
|
1517
|
+
// has versions, so it would spend a round trip to be told what is
|
|
1518
|
+
// already known here.
|
|
1519
|
+
return halfDeleted(new Error(detail), sweep.failures.map(failure => failure.version));
|
|
1358
1520
|
}
|
|
1359
1521
|
}
|
|
1360
1522
|
logger.info(`Deleting skill: ${skillId}`);
|
|
@@ -1369,7 +1531,9 @@ Examples:
|
|
|
1369
1531
|
catch (error) {
|
|
1370
1532
|
if (deletedVersions.length === 0)
|
|
1371
1533
|
throw error;
|
|
1372
|
-
|
|
1534
|
+
// The sweep completed — every version is gone — and the SKILL delete is
|
|
1535
|
+
// what failed, so nothing is left in `failedVersions`.
|
|
1536
|
+
return halfDeleted(error, []);
|
|
1373
1537
|
}
|
|
1374
1538
|
const deleted = reportDelete(raw, skillId, SKILL_DELETED_TYPES);
|
|
1375
1539
|
return deletedVersions.length === 0
|
|
@@ -1389,16 +1553,24 @@ Description:
|
|
|
1389
1553
|
delete every version and then the skill in one command; without it, delete the
|
|
1390
1554
|
versions yourself with \`vat claude org skills versions delete\` first.
|
|
1391
1555
|
|
|
1392
|
-
--all deletes irreversibly and in a loop
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1556
|
+
--all deletes irreversibly and in a loop, and it ATTEMPTS EVERY VERSION even
|
|
1557
|
+
when one refuses — one refusal is a fact about one version, not about the ones
|
|
1558
|
+
after it. When the sweep ends with anything left, the versions it destroyed are
|
|
1559
|
+
listed under deletedVersions, the ones still there under failedVersions, and
|
|
1560
|
+
the run exits 1 — the run happened, and its outcome is wrong. The skill itself
|
|
1561
|
+
is then left alone, because the API refuses a skill that still has versions.
|
|
1562
|
+
It exits 2 only when nothing was deleted at all.
|
|
1563
|
+
|
|
1564
|
+
A version delete whose response is lost is replayed, and the replay is answered
|
|
1565
|
+
404 because the first attempt already removed it. That 404 is read as the
|
|
1566
|
+
delete it is, not as a failure — the version appears under deletedVersions.
|
|
1396
1567
|
|
|
1397
1568
|
Exit Codes:
|
|
1398
1569
|
0 - The skill was deleted
|
|
1399
1570
|
1 - The run completed and the skill was NOT deleted: the API named a different
|
|
1400
|
-
outcome, or --all destroyed some versions and
|
|
1401
|
-
2 - The run could not happen: no API key,
|
|
1571
|
+
outcome, or --all destroyed some versions and could not destroy the rest
|
|
1572
|
+
2 - The run could not happen: no API key, the first request was refused, or
|
|
1573
|
+
--all deleted no version at all
|
|
1402
1574
|
|
|
1403
1575
|
Example:
|
|
1404
1576
|
$ vat claude org skills delete skill_abc123 --all
|