release-skill 0.2.1 → 0.2.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +21 -0
- package/INSTALL.md +183 -21
- package/INSTALL.zh-CN.md +160 -16
- package/README.md +112 -11
- package/README.zh-CN.md +73 -10
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/claude/schemas/release-plan.schema.json +44 -2
- package/adapters/claude/schemas/release-project.schema.json +46 -4
- package/adapters/claude/schemas/release-run.schema.json +1 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/codex/schemas/release-plan.schema.json +44 -2
- package/adapters/codex/schemas/release-project.schema.json +46 -4
- package/adapters/codex/schemas/release-run.schema.json +1 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/kimi/schemas/release-plan.schema.json +44 -2
- package/adapters/kimi/schemas/release-project.schema.json +46 -4
- package/adapters/kimi/schemas/release-run.schema.json +1 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +4 -2
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/workbuddy/schemas/release-plan.schema.json +44 -2
- package/adapters/workbuddy/schemas/release-project.schema.json +46 -4
- package/adapters/workbuddy/schemas/release-run.schema.json +1 -0
- package/bin/release-skill-cli.mjs +46 -4
- package/bin/release-skill.bundle.mjs +1718 -600
- package/package.json +1 -1
- package/references/02-project-config.md +7 -0
- package/references/06-adapter-contract.md +21 -2
- package/schemas/release-plan.schema.json +44 -2
- package/schemas/release-project.schema.json +46 -4
- package/schemas/release-run.schema.json +1 -0
- package/scripts/sync-public-files.mjs +8 -4
- package/src/adapters/contract.mjs +1 -0
- package/src/adapters/plugin-marketplace.mjs +536 -23
- package/src/commands/assess.mjs +50 -1
- package/src/commands/prepare.mjs +273 -9
- package/src/commands/publish.mjs +1 -0
- package/src/commands/reconcile.mjs +1 -0
- package/src/commands/setup.mjs +7 -3
- package/src/commands/verify.mjs +2 -0
- package/src/core/checkpoints.mjs +7 -2
- package/src/core/plan.mjs +97 -4
- package/src/core/verification-gates.mjs +1 -1
- package/src/platforms/codebuddy.mjs +618 -0
- package/src/platforms/registry.mjs +100 -5
- package/src/producers/build-adapters.mjs +21 -13
package/src/core/plan.mjs
CHANGED
|
@@ -776,6 +776,19 @@ export function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
776
776
|
);
|
|
777
777
|
}
|
|
778
778
|
|
|
779
|
+
// External independent marketplace form: the distribution declares
|
|
780
|
+
// marketplaceRepo, so the install targets the external marketplace
|
|
781
|
+
// repository instead of publicRepo. Only platforms with a marketplace
|
|
782
|
+
// add capability (marketplaceRefForm !== null: claude=name, codex=sha)
|
|
783
|
+
// may carry it; kimi/codebuddy fail closed. Inline form (no
|
|
784
|
+
// marketplaceRepo) keeps every assertion below byte-for-byte.
|
|
785
|
+
const externalMarketplace = dist.marketplaceRepo !== undefined && dist.marketplaceRepo !== null;
|
|
786
|
+
if (externalMarketplace && platform.marketplaceRefForm === null) {
|
|
787
|
+
failures.push(
|
|
788
|
+
`unit "${unitId}", action "${action.id}": ${platform.distributionType} distribution declares marketplaceRepo but the platform has no marketplace add capability`,
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
779
792
|
// Parameter checks
|
|
780
793
|
_checkRequired(action, 'parameters.consumer', action.parameters?.consumer, platform.id, unitId, failures);
|
|
781
794
|
_checkRequired(action, 'parameters.plugin', action.parameters?.plugin, plugin, unitId, failures);
|
|
@@ -792,12 +805,53 @@ export function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
792
805
|
`unit "${unitId}", action "${action.id}": parameters.marketplace is "${action.parameters.marketplace}", expected optional legacy value "${marketplace}"`,
|
|
793
806
|
);
|
|
794
807
|
}
|
|
795
|
-
|
|
808
|
+
if (externalMarketplace) {
|
|
809
|
+
// External form: the install repo is the external marketplace repo,
|
|
810
|
+
// not publicRepo; marketplaceLocation is the action-level marker.
|
|
811
|
+
_checkRequired(action, 'parameters.repo', action.parameters?.repo, dist.marketplaceRepo, unitId, failures);
|
|
812
|
+
_checkRequired(action, 'parameters.marketplaceLocation', action.parameters?.marketplaceLocation, 'external', unitId, failures);
|
|
813
|
+
} else {
|
|
814
|
+
_checkRequired(action, 'parameters.repo', action.parameters?.repo, publicRepo, unitId, failures);
|
|
815
|
+
}
|
|
796
816
|
_checkRequired(action, 'parameters.version', action.parameters?.version, targetVersion, unitId, failures);
|
|
797
817
|
_checkRequired(action, 'parameters.entrySkill', action.parameters?.entrySkill, entrySkill, unitId, failures);
|
|
798
818
|
if (production) {
|
|
819
|
+
// snapshotPath/manifestDigest always bind the unit's own frozen
|
|
820
|
+
// snapshot — the payload authority is unchanged for external form.
|
|
799
821
|
_checkRequired(action, 'parameters.snapshotPath', action.parameters?.snapshotPath, frozen?.path, unitId, failures);
|
|
800
|
-
|
|
822
|
+
if (externalMarketplace) {
|
|
823
|
+
// The add-ref is frozen online by prepare (codex=commit sha,
|
|
824
|
+
// claude=default branch name) and cannot be re-derived offline;
|
|
825
|
+
// validate structural safety plus self-consistency with expected.ref.
|
|
826
|
+
const ref = action.parameters?.ref;
|
|
827
|
+
if (ref === undefined || ref === null) {
|
|
828
|
+
failures.push(
|
|
829
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is missing, expected the frozen external marketplace add-ref`,
|
|
830
|
+
);
|
|
831
|
+
} else if (!_isStructurallySafeExternalRef(ref)) {
|
|
832
|
+
failures.push(
|
|
833
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is not a structurally safe ref: ${JSON.stringify(ref)}`,
|
|
834
|
+
);
|
|
835
|
+
} else if (ref !== action.expected?.ref) {
|
|
836
|
+
failures.push(
|
|
837
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is "${ref}", expected self-consistent expected.ref "${action.expected?.ref}"`,
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
// marketplaceCommitSha is the frozen 40-hex marketplace HEAD
|
|
841
|
+
// (online freeze, offline completeness — same model as manifestDigest).
|
|
842
|
+
const sha = action.parameters?.marketplaceCommitSha;
|
|
843
|
+
if (sha === undefined || sha === null) {
|
|
844
|
+
failures.push(
|
|
845
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplaceCommitSha is missing, expected a frozen 40-hex commit sha`,
|
|
846
|
+
);
|
|
847
|
+
} else if (typeof sha !== 'string' || !EXTERNAL_MARKETPLACE_SHA_RE.test(sha)) {
|
|
848
|
+
failures.push(
|
|
849
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplaceCommitSha must be a 40-hex commit sha, got: ${JSON.stringify(sha)}`,
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
} else {
|
|
853
|
+
_checkRequired(action, 'parameters.ref', action.parameters?.ref, expectedTag, unitId, failures);
|
|
854
|
+
}
|
|
801
855
|
_checkRequired(action, 'parameters.manifestDigest', action.parameters?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
802
856
|
}
|
|
803
857
|
// timeoutMs is mandatory for all marketplace install actions.
|
|
@@ -840,8 +894,15 @@ export function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
840
894
|
_checkRequired(action, 'expected.entrySkill', action.expected?.entrySkill, entrySkill, unitId, failures);
|
|
841
895
|
if (production) {
|
|
842
896
|
_checkRequired(action, 'expected.consumer', action.expected?.consumer, platform.id, unitId, failures);
|
|
843
|
-
|
|
844
|
-
|
|
897
|
+
if (externalMarketplace) {
|
|
898
|
+
_checkRequired(action, 'expected.repo', action.expected?.repo, dist.marketplaceRepo, unitId, failures);
|
|
899
|
+
_checkRequired(action, 'expected.ref', action.expected?.ref, action.parameters?.ref, unitId, failures);
|
|
900
|
+
_checkRequired(action, 'expected.marketplaceLocation', action.expected?.marketplaceLocation, 'external', unitId, failures);
|
|
901
|
+
_checkRequired(action, 'expected.marketplaceCommitSha', action.expected?.marketplaceCommitSha, action.parameters?.marketplaceCommitSha, unitId, failures);
|
|
902
|
+
} else {
|
|
903
|
+
_checkRequired(action, 'expected.repo', action.expected?.repo, publicRepo, unitId, failures);
|
|
904
|
+
_checkRequired(action, 'expected.ref', action.expected?.ref, expectedTag, unitId, failures);
|
|
905
|
+
}
|
|
845
906
|
_checkRequired(action, 'expected.entrySkillFound', action.expected?.entrySkillFound, true, unitId, failures);
|
|
846
907
|
_checkRequired(action, 'expected.manifestDigest', action.expected?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
847
908
|
}
|
|
@@ -946,3 +1007,35 @@ function _checkRequired(action, fieldPath, actual, expected, unitId, failures) {
|
|
|
946
1007
|
);
|
|
947
1008
|
}
|
|
948
1009
|
}
|
|
1010
|
+
|
|
1011
|
+
// External independent marketplace form (external-marketplace): a frozen
|
|
1012
|
+
// marketplace HEAD commit sha is a 40-char lowercase hex string.
|
|
1013
|
+
const EXTERNAL_MARKETPLACE_SHA_RE = /^[0-9a-f]{40}$/;
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* Structural safety check for an externally frozen marketplace add-ref.
|
|
1017
|
+
*
|
|
1018
|
+
* The add-ref (codex=commit sha, claude=default branch name) is frozen online
|
|
1019
|
+
* by prepare and cannot be re-derived offline; full injection-safety validation
|
|
1020
|
+
* already happened at freeze time (plugin-marketplace `validateSafeRef`). The
|
|
1021
|
+
* offline completeness gate re-checks structural well-formedness so a tampered
|
|
1022
|
+
* or corrupted frozen ref fails closed here too. Mirrors that validator's rules.
|
|
1023
|
+
*
|
|
1024
|
+
* @param {unknown} ref
|
|
1025
|
+
* @returns {boolean}
|
|
1026
|
+
*/
|
|
1027
|
+
function _isStructurallySafeExternalRef(ref) {
|
|
1028
|
+
if (typeof ref !== 'string' || ref.length === 0) return false;
|
|
1029
|
+
if (/[\x00-\x1f]/.test(ref)) return false;
|
|
1030
|
+
if (ref.startsWith('-')) return false;
|
|
1031
|
+
if (ref.includes('\\')) return false;
|
|
1032
|
+
if (ref.includes('//')) return false;
|
|
1033
|
+
if (ref.startsWith('/') || ref.endsWith('/')) return false;
|
|
1034
|
+
if (ref.endsWith('.')) return false;
|
|
1035
|
+
if (ref.endsWith('.lock')) return false;
|
|
1036
|
+
if (ref.includes('@{')) return false;
|
|
1037
|
+
if (ref === '@') return false;
|
|
1038
|
+
if (ref.includes('..')) return false;
|
|
1039
|
+
if (/[;|&`$(){}]/.test(ref)) return false;
|
|
1040
|
+
return /^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(ref);
|
|
1041
|
+
}
|
|
@@ -57,7 +57,7 @@ function validateGate(gate) {
|
|
|
57
57
|
if (!gate.scope || typeof gate.scope.unit !== 'string') {
|
|
58
58
|
throw gateError(gate, 'must declare scope.unit');
|
|
59
59
|
}
|
|
60
|
-
if (gate.phase === 'consumer-verify' && !['npm', 'claude-plugin', 'codex-plugin', 'kimi-plugin'].includes(gate.scope.distribution)) {
|
|
60
|
+
if (gate.phase === 'consumer-verify' && !['npm', 'claude-plugin', 'codex-plugin', 'kimi-plugin', 'codebuddy-plugin'].includes(gate.scope.distribution)) {
|
|
61
61
|
throw gateError(gate, 'consumer-verify must declare a supported scope.distribution');
|
|
62
62
|
}
|
|
63
63
|
if (!Array.isArray(gate.command) || gate.command.length === 0 || gate.command.some((value) => typeof value !== 'string')) {
|