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.
Files changed (108) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.codex-plugin/plugin.json +3 -3
  4. package/CHANGELOG.md +89 -0
  5. package/INSTALL.md +216 -5
  6. package/INSTALL.zh-CN.md +358 -0
  7. package/README.md +411 -67
  8. package/README.zh-CN.md +377 -59
  9. package/adapters/claude/.claude-plugin/marketplace.json +1 -1
  10. package/adapters/claude/.claude-plugin/plugin.json +1 -1
  11. package/adapters/claude/bin/release-skill.bundle.mjs +79284 -0
  12. package/adapters/claude/bin/release-skill.mjs +34 -0
  13. package/adapters/claude/native/safe-write/binding.gyp +40 -0
  14. package/adapters/claude/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  15. package/adapters/claude/native/safe-write/prebuilds.json +24 -0
  16. package/adapters/claude/native/safe-write/src/safe_write.cc +2032 -0
  17. package/adapters/claude/schemas/.render-manifest.json +37 -0
  18. package/adapters/claude/schemas/approval-record.schema.json +115 -0
  19. package/adapters/claude/schemas/artifact-lock.schema.json +111 -0
  20. package/adapters/claude/schemas/artifact-plan.schema.json +52 -0
  21. package/adapters/claude/schemas/artifact-policy.schema.json +76 -0
  22. package/adapters/claude/schemas/evidence-event.schema.json +89 -0
  23. package/adapters/claude/schemas/release-plan.schema.json +860 -0
  24. package/adapters/claude/schemas/release-project.schema.json +736 -0
  25. package/adapters/claude/schemas/release-run.schema.json +342 -0
  26. package/adapters/claude/skills/release-assess/SKILL.md +5 -6
  27. package/adapters/claude/skills/release-help/SKILL.md +14 -18
  28. package/adapters/claude/skills/release-prepare/SKILL.md +16 -6
  29. package/adapters/claude/skills/release-publish/SKILL.md +7 -7
  30. package/adapters/claude/skills/release-reconcile/SKILL.md +6 -6
  31. package/adapters/claude/skills/release-setup/SKILL.md +95 -0
  32. package/adapters/claude/skills/release-verify/SKILL.md +7 -7
  33. package/adapters/codex/.codex-plugin/plugin.json +2 -2
  34. package/adapters/codex/bin/release-skill.bundle.mjs +79284 -0
  35. package/adapters/codex/bin/release-skill.mjs +34 -0
  36. package/adapters/codex/native/safe-write/binding.gyp +40 -0
  37. package/adapters/codex/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  38. package/adapters/codex/native/safe-write/prebuilds.json +24 -0
  39. package/adapters/codex/native/safe-write/src/safe_write.cc +2032 -0
  40. package/adapters/codex/schemas/.render-manifest.json +37 -0
  41. package/adapters/codex/schemas/approval-record.schema.json +115 -0
  42. package/adapters/codex/schemas/artifact-lock.schema.json +111 -0
  43. package/adapters/codex/schemas/artifact-plan.schema.json +52 -0
  44. package/adapters/codex/schemas/artifact-policy.schema.json +76 -0
  45. package/adapters/codex/schemas/evidence-event.schema.json +89 -0
  46. package/adapters/codex/schemas/release-plan.schema.json +860 -0
  47. package/adapters/codex/schemas/release-project.schema.json +736 -0
  48. package/adapters/codex/schemas/release-run.schema.json +342 -0
  49. package/adapters/codex/skills/release-assess/SKILL.md +12 -6
  50. package/adapters/codex/skills/release-help/SKILL.md +21 -18
  51. package/adapters/codex/skills/release-prepare/SKILL.md +23 -6
  52. package/adapters/codex/skills/release-publish/SKILL.md +14 -7
  53. package/adapters/codex/skills/release-reconcile/SKILL.md +13 -6
  54. package/adapters/codex/skills/release-setup/SKILL.md +102 -0
  55. package/adapters/codex/skills/release-verify/SKILL.md +14 -7
  56. package/bin/release-skill-cli.mjs +807 -0
  57. package/bin/release-skill.bundle.mjs +79284 -0
  58. package/bin/release-skill.mjs +23 -732
  59. package/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
  60. package/native/safe-write/prebuilds.json +22 -2
  61. package/native/safe-write/src/safe_write.cc +11 -2
  62. package/package.json +8 -2
  63. package/references/02-project-config.md +55 -4
  64. package/references/05-evidence-and-errors.md +6 -2
  65. package/schemas/release-plan.schema.json +556 -65
  66. package/schemas/release-project.schema.json +406 -29
  67. package/schemas/release-run.schema.json +165 -18
  68. package/scripts/build-bundle.mjs +133 -0
  69. package/skills/release-assess/SKILL.md +5 -6
  70. package/skills/release-help/SKILL.md +14 -18
  71. package/skills/release-prepare/SKILL.md +16 -6
  72. package/skills/release-publish/SKILL.md +7 -7
  73. package/skills/release-reconcile/SKILL.md +6 -6
  74. package/skills/release-setup/SKILL.md +95 -0
  75. package/skills/release-verify/SKILL.md +7 -7
  76. package/skills-src/release-assess/SKILL.md +5 -6
  77. package/skills-src/release-help/SKILL.md +14 -18
  78. package/skills-src/release-prepare/SKILL.md +16 -6
  79. package/skills-src/release-publish/SKILL.md +7 -7
  80. package/skills-src/release-reconcile/SKILL.md +6 -6
  81. package/skills-src/release-setup/SKILL.md +95 -0
  82. package/skills-src/release-verify/SKILL.md +7 -7
  83. package/src/adapters/contract.mjs +3 -0
  84. package/src/adapters/git-github.mjs +84 -2
  85. package/src/adapters/npm.mjs +5 -13
  86. package/src/adapters/plugin-marketplace.mjs +132 -52
  87. package/src/adapters/push-snapshot.mjs +84 -17
  88. package/src/artifacts/policy.mjs +4 -7
  89. package/src/artifacts/safe-fs-backend-internal.mjs +69 -21
  90. package/src/commands/prepare.mjs +244 -20
  91. package/src/commands/publish.mjs +46 -0
  92. package/src/commands/reconcile.mjs +152 -0
  93. package/src/commands/setup.mjs +1525 -0
  94. package/src/commands/verify.mjs +122 -26
  95. package/src/core/approval.mjs +4 -6
  96. package/src/core/config.mjs +42 -8
  97. package/src/core/errors.mjs +4 -0
  98. package/src/core/pkg-root.mjs +22 -0
  99. package/src/core/plan.mjs +132 -4
  100. package/src/core/previous-public-baseline.mjs +21 -1
  101. package/src/core/run.mjs +4 -4
  102. package/src/core/trusted-resource.mjs +96 -0
  103. package/src/core/verification-gates.mjs +451 -0
  104. package/src/docs/version-gate.mjs +164 -0
  105. package/src/producers/build-adapters.mjs +512 -55
  106. package/src/snapshot/frozen.mjs +221 -7
  107. package/src/snapshot/public-map.mjs +7 -4
  108. 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
+ }