release-skill 0.1.1 → 0.1.4
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 +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +89 -0
- package/INSTALL.md +216 -5
- package/INSTALL.zh-CN.md +358 -0
- package/README.md +411 -67
- package/README.zh-CN.md +377 -59
- 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 +79284 -0
- package/adapters/claude/bin/release-skill.mjs +34 -0
- package/adapters/claude/native/safe-write/binding.gyp +40 -0
- package/adapters/claude/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/claude/native/safe-write/prebuilds.json +24 -0
- package/adapters/claude/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/claude/schemas/.render-manifest.json +37 -0
- package/adapters/claude/schemas/approval-record.schema.json +115 -0
- package/adapters/claude/schemas/artifact-lock.schema.json +111 -0
- package/adapters/claude/schemas/artifact-plan.schema.json +52 -0
- package/adapters/claude/schemas/artifact-policy.schema.json +76 -0
- package/adapters/claude/schemas/evidence-event.schema.json +89 -0
- package/adapters/claude/schemas/release-plan.schema.json +860 -0
- package/adapters/claude/schemas/release-project.schema.json +736 -0
- package/adapters/claude/schemas/release-run.schema.json +342 -0
- package/adapters/claude/skills/release-assess/SKILL.md +5 -6
- package/adapters/claude/skills/release-help/SKILL.md +14 -18
- package/adapters/claude/skills/release-prepare/SKILL.md +16 -6
- package/adapters/claude/skills/release-publish/SKILL.md +7 -7
- package/adapters/claude/skills/release-reconcile/SKILL.md +6 -6
- package/adapters/claude/skills/release-setup/SKILL.md +95 -0
- package/adapters/claude/skills/release-verify/SKILL.md +7 -7
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +79284 -0
- package/adapters/codex/bin/release-skill.mjs +34 -0
- package/adapters/codex/native/safe-write/binding.gyp +40 -0
- package/adapters/codex/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/codex/native/safe-write/prebuilds.json +24 -0
- package/adapters/codex/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/codex/schemas/.render-manifest.json +37 -0
- package/adapters/codex/schemas/approval-record.schema.json +115 -0
- package/adapters/codex/schemas/artifact-lock.schema.json +111 -0
- package/adapters/codex/schemas/artifact-plan.schema.json +52 -0
- package/adapters/codex/schemas/artifact-policy.schema.json +76 -0
- package/adapters/codex/schemas/evidence-event.schema.json +89 -0
- package/adapters/codex/schemas/release-plan.schema.json +860 -0
- package/adapters/codex/schemas/release-project.schema.json +736 -0
- package/adapters/codex/schemas/release-run.schema.json +342 -0
- package/adapters/codex/skills/release-assess/SKILL.md +12 -6
- package/adapters/codex/skills/release-help/SKILL.md +21 -18
- package/adapters/codex/skills/release-prepare/SKILL.md +23 -6
- package/adapters/codex/skills/release-publish/SKILL.md +14 -7
- package/adapters/codex/skills/release-reconcile/SKILL.md +13 -6
- package/adapters/codex/skills/release-setup/SKILL.md +102 -0
- package/adapters/codex/skills/release-verify/SKILL.md +14 -7
- package/bin/release-skill-cli.mjs +807 -0
- package/bin/release-skill.bundle.mjs +79284 -0
- package/bin/release-skill.mjs +23 -732
- package/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/native/safe-write/prebuilds.json +22 -2
- package/native/safe-write/src/safe_write.cc +11 -2
- package/package.json +8 -2
- package/references/02-project-config.md +55 -4
- package/references/05-evidence-and-errors.md +6 -2
- package/schemas/release-plan.schema.json +556 -65
- package/schemas/release-project.schema.json +406 -29
- package/schemas/release-run.schema.json +165 -18
- package/scripts/build-bundle.mjs +133 -0
- package/skills/release-assess/SKILL.md +5 -6
- package/skills/release-help/SKILL.md +14 -18
- package/skills/release-prepare/SKILL.md +16 -6
- package/skills/release-publish/SKILL.md +7 -7
- package/skills/release-reconcile/SKILL.md +6 -6
- package/skills/release-setup/SKILL.md +95 -0
- package/skills/release-verify/SKILL.md +7 -7
- package/skills-src/release-assess/SKILL.md +5 -6
- package/skills-src/release-help/SKILL.md +14 -18
- package/skills-src/release-prepare/SKILL.md +16 -6
- package/skills-src/release-publish/SKILL.md +7 -7
- package/skills-src/release-reconcile/SKILL.md +6 -6
- package/skills-src/release-setup/SKILL.md +95 -0
- package/skills-src/release-verify/SKILL.md +7 -7
- package/src/adapters/contract.mjs +3 -0
- package/src/adapters/git-github.mjs +84 -2
- package/src/adapters/npm.mjs +5 -13
- package/src/adapters/plugin-marketplace.mjs +132 -52
- package/src/adapters/push-snapshot.mjs +84 -17
- package/src/artifacts/policy.mjs +4 -7
- package/src/artifacts/safe-fs-backend-internal.mjs +69 -21
- package/src/commands/prepare.mjs +244 -20
- package/src/commands/publish.mjs +46 -0
- package/src/commands/reconcile.mjs +152 -0
- package/src/commands/setup.mjs +1525 -0
- package/src/commands/verify.mjs +122 -26
- package/src/core/approval.mjs +4 -6
- package/src/core/config.mjs +42 -8
- package/src/core/errors.mjs +4 -0
- package/src/core/pkg-root.mjs +22 -0
- package/src/core/plan.mjs +132 -4
- package/src/core/previous-public-baseline.mjs +21 -1
- package/src/core/run.mjs +4 -4
- package/src/core/trusted-resource.mjs +96 -0
- package/src/core/verification-gates.mjs +451 -0
- package/src/docs/version-gate.mjs +164 -0
- package/src/producers/build-adapters.mjs +512 -55
- package/src/snapshot/frozen.mjs +221 -7
- package/src/snapshot/public-map.mjs +7 -4
- package/src/snapshot/scan.mjs +2 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Release docs version consistency gate.
|
|
3
|
+
*
|
|
4
|
+
* README, INSTALL, and CHANGELOG are human-maintained content. A release
|
|
5
|
+
* freezes only the current truth: prepare/publish never rewrite or refresh
|
|
6
|
+
* these docs. Maintainers must update the docs first, then prepare, review,
|
|
7
|
+
* and approve. This gate makes version drift fail closed before release:
|
|
8
|
+
*
|
|
9
|
+
* - the English README, Chinese README, English INSTALL, and Chinese
|
|
10
|
+
* INSTALL each carry a machine-readable current release version marker
|
|
11
|
+
* whose value equals package.json.version exactly;
|
|
12
|
+
* - CHANGELOG.md carries a formal `## [<version>]` heading for the current
|
|
13
|
+
* package version (a body mention or an internal candidate note does not
|
|
14
|
+
* substitute for the heading).
|
|
15
|
+
*
|
|
16
|
+
* The gate is a pure read-only check; it never edits files. It is wired into
|
|
17
|
+
* the package test suite so `pnpm test:release` blocks a prepare when docs
|
|
18
|
+
* have drifted from the package version.
|
|
19
|
+
*
|
|
20
|
+
* @module src/docs/version-gate
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { readFile } from 'node:fs/promises';
|
|
24
|
+
import { join } from 'node:path';
|
|
25
|
+
|
|
26
|
+
/** The machine-readable marker tag carried by every public doc file. */
|
|
27
|
+
export const RELEASE_VERSION_MARKER_TAG = 'release-skill:release-version';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Marker pattern. The value is captured; e.g.
|
|
31
|
+
* <!-- release-skill:release-version: 0.1.4 -->
|
|
32
|
+
* Global: every occurrence is validated so a stale duplicate cannot hide.
|
|
33
|
+
*/
|
|
34
|
+
const MARKER_PATTERN = new RegExp(
|
|
35
|
+
`<!--\\s*${RELEASE_VERSION_MARKER_TAG}:\\s*([^\\s>]+)\\s*-->`,
|
|
36
|
+
'g',
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
/** Public docs that must carry the marker, in both languages. */
|
|
40
|
+
export const VERSIONED_DOC_FILES = [
|
|
41
|
+
'README.md',
|
|
42
|
+
'README.zh-CN.md',
|
|
43
|
+
'INSTALL.md',
|
|
44
|
+
'INSTALL.zh-CN.md',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Escape a string for literal use inside a RegExp.
|
|
51
|
+
* @param {string} text
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
54
|
+
function escapeRegExp(text) {
|
|
55
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extract every release-version marker value from doc content.
|
|
60
|
+
* @param {string} content
|
|
61
|
+
* @returns {string[]}
|
|
62
|
+
*/
|
|
63
|
+
export function extractReleaseVersionMarkers(content) {
|
|
64
|
+
return [...String(content ?? '').matchAll(MARKER_PATTERN)].map((match) => match[1]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Render the canonical marker line for a version.
|
|
69
|
+
* @param {string} version
|
|
70
|
+
* @returns {string}
|
|
71
|
+
*/
|
|
72
|
+
export function renderReleaseVersionMarker(version) {
|
|
73
|
+
return `<!-- ${RELEASE_VERSION_MARKER_TAG}: ${version} -->`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate that the human-maintained release docs in `packageDir` agree with
|
|
78
|
+
* package.json.version. Read-only; never writes.
|
|
79
|
+
*
|
|
80
|
+
* @param {object} options
|
|
81
|
+
* @param {string} options.packageDir Directory containing package.json and
|
|
82
|
+
* the public docs.
|
|
83
|
+
* @returns {Promise<{
|
|
84
|
+
* passed: boolean,
|
|
85
|
+
* version: string | null,
|
|
86
|
+
* markers: Record<string, string[]>,
|
|
87
|
+
* changelogHeading: boolean,
|
|
88
|
+
* failures: string[],
|
|
89
|
+
* }>}
|
|
90
|
+
*/
|
|
91
|
+
export async function validateDocsVersionConsistency({ packageDir }) {
|
|
92
|
+
const failures = [];
|
|
93
|
+
const markers = {};
|
|
94
|
+
let changelogHeading = false;
|
|
95
|
+
let version = null;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const pkg = JSON.parse(await readFile(join(packageDir, 'package.json'), 'utf8'));
|
|
99
|
+
if (typeof pkg.version === 'string' && pkg.version.length > 0) {
|
|
100
|
+
version = pkg.version;
|
|
101
|
+
}
|
|
102
|
+
} catch (error) {
|
|
103
|
+
failures.push(`package.json: cannot read package version (${error?.code ?? error?.message ?? 'unknown error'})`);
|
|
104
|
+
}
|
|
105
|
+
if (version === null) {
|
|
106
|
+
failures.push('package.json: version is missing; docs version gate fails closed');
|
|
107
|
+
} else if (!SEMVER_PATTERN.test(version)) {
|
|
108
|
+
failures.push(`package.json: version "${version}" is not a valid semver value`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (version !== null) {
|
|
112
|
+
for (const file of VERSIONED_DOC_FILES) {
|
|
113
|
+
let content;
|
|
114
|
+
try {
|
|
115
|
+
content = await readFile(join(packageDir, file), 'utf8');
|
|
116
|
+
} catch {
|
|
117
|
+
failures.push(`${file}: missing; release docs must ship in both languages`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const found = extractReleaseVersionMarkers(content);
|
|
121
|
+
markers[file] = found;
|
|
122
|
+
if (found.length === 0) {
|
|
123
|
+
failures.push(
|
|
124
|
+
`${file}: missing machine-readable release version marker "${renderReleaseVersionMarker(version)}"`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
for (const value of found) {
|
|
128
|
+
if (value !== version) {
|
|
129
|
+
failures.push(
|
|
130
|
+
`${file}: release version marker "${value}" does not match package version "${version}"; ` +
|
|
131
|
+
'update the docs first, then prepare, review, and approve',
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let changelog;
|
|
138
|
+
try {
|
|
139
|
+
changelog = await readFile(join(packageDir, 'CHANGELOG.md'), 'utf8');
|
|
140
|
+
} catch {
|
|
141
|
+
failures.push('CHANGELOG.md: missing');
|
|
142
|
+
}
|
|
143
|
+
if (changelog !== undefined) {
|
|
144
|
+
// A formal heading starts a line: "## [0.1.4]" optionally followed by a
|
|
145
|
+
// date. A body mention ("0.1.4 was an internal candidate...") does not
|
|
146
|
+
// substitute for the heading.
|
|
147
|
+
changelogHeading = new RegExp(`^##\\s*\\[${escapeRegExp(version)}\\](?:\\s|$)`, 'm').test(changelog);
|
|
148
|
+
if (!changelogHeading) {
|
|
149
|
+
failures.push(
|
|
150
|
+
`CHANGELOG.md: missing formal "## [${version}]" heading for the current package version; ` +
|
|
151
|
+
'internal unreleased candidates may be explained in the body but cannot replace the entry',
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
passed: failures.length === 0,
|
|
159
|
+
version,
|
|
160
|
+
markers,
|
|
161
|
+
changelogHeading,
|
|
162
|
+
failures,
|
|
163
|
+
};
|
|
164
|
+
}
|