@devcxl/opencode-cabbage 1.0.0 → 1.2.0
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 +19 -25
- package/README.zh.md +17 -23
- package/assets/agents/dev-lifecycle.md +208 -68
- package/assets/agents/team/architect.md +22 -4
- package/assets/agents/team/developer.md +13 -6
- package/assets/agents/team/goal-verify.md +4 -1
- package/assets/agents/team/researcher.md +59 -0
- package/assets/agents/team/reviewer.md +34 -18
- package/assets/commands/setup.md +1 -1
- package/assets/prompts/bootstrap.md +10 -9
- package/assets/prompts/stage-contract.md +25 -25
- package/assets/skills/flow-code/SKILL.md +23 -25
- package/assets/skills/flow-design/SKILL.md +94 -26
- package/assets/skills/flow-release/SKILL.md +41 -17
- package/assets/skills/flow-requirements/SKILL.md +19 -13
- package/assets/skills/flow-research/SKILL.md +77 -0
- package/assets/skills/flow-review/SKILL.md +55 -25
- package/assets/skills/flow-setup/SKILL.md +27 -24
- package/assets/skills/flow-tasks/SKILL.md +178 -35
- package/assets/skills/flow-tdd/SKILL.md +68 -40
- package/dist/kernel/context.js +12 -1
- package/dist/kernel/context.js.map +1 -1
- package/dist/kernel/permission.d.ts +1 -1
- package/dist/kernel/permission.js +9 -1
- package/dist/kernel/permission.js.map +1 -1
- package/dist/kernel/profile.js +5 -2
- package/dist/kernel/profile.js.map +1 -1
- package/dist/kernel/session-index.d.ts +12 -27
- package/dist/kernel/session-index.js +46 -80
- package/dist/kernel/session-index.js.map +1 -1
- package/dist/plugin/bootstrap.d.ts +0 -1
- package/dist/plugin/bootstrap.js +0 -3
- package/dist/plugin/bootstrap.js.map +1 -1
- package/dist/plugin/goal.d.ts +57 -6
- package/dist/plugin/goal.js +234 -86
- package/dist/plugin/goal.js.map +1 -1
- package/dist/plugin/prompt-lint.js +3 -12
- package/dist/plugin/prompt-lint.js.map +1 -1
- package/dist/plugin/prompts.d.ts +0 -1
- package/dist/plugin/prompts.js +0 -4
- package/dist/plugin/prompts.js.map +1 -1
- package/dist/plugin/server.d.ts +2 -5
- package/dist/plugin/server.js +260 -136
- package/dist/plugin/server.js.map +1 -1
- package/dist/plugin/skills.d.ts +7 -1
- package/dist/plugin/skills.js +75 -12
- package/dist/plugin/skills.js.map +1 -1
- package/dist/plugin.d.ts +0 -1
- package/dist/plugin.js +1 -4
- package/dist/plugin.js.map +1 -1
- package/dist/util/gh.d.ts +3 -9
- package/dist/util/gh.js +9 -11
- package/dist/util/gh.js.map +1 -1
- package/dist/util/paths.d.ts +6 -14
- package/dist/util/paths.js +12 -67
- package/dist/util/paths.js.map +1 -1
- package/package.json +5 -5
- package/assets/prompts/ADR-FORMAT.md +0 -45
- package/assets/prompts/PRD-FORMAT.md +0 -17
- package/assets/templates/gitignore +0 -5
- package/dist/kernel/caller.d.ts +0 -48
- package/dist/kernel/caller.js +0 -88
- package/dist/kernel/caller.js.map +0 -1
- package/dist/kernel/flow.d.ts +0 -166
- package/dist/kernel/flow.js +0 -387
- package/dist/kernel/flow.js.map +0 -1
- package/dist/kernel/legacy.d.ts +0 -19
- package/dist/kernel/legacy.js +0 -34
- package/dist/kernel/legacy.js.map +0 -1
- package/dist/kernel/records.d.ts +0 -87
- package/dist/kernel/records.js +0 -197
- package/dist/kernel/records.js.map +0 -1
- package/dist/kernel/release.d.ts +0 -104
- package/dist/kernel/release.js +0 -229
- package/dist/kernel/release.js.map +0 -1
- package/dist/kernel/review.d.ts +0 -34
- package/dist/kernel/review.js +0 -81
- package/dist/kernel/review.js.map +0 -1
- package/dist/kernel/setup.d.ts +0 -70
- package/dist/kernel/setup.js +0 -324
- package/dist/kernel/setup.js.map +0 -1
- package/dist/kernel/slug.d.ts +0 -23
- package/dist/kernel/slug.js +0 -67
- package/dist/kernel/slug.js.map +0 -1
- package/dist/kernel/task.d.ts +0 -208
- package/dist/kernel/task.js +0 -788
- package/dist/kernel/task.js.map +0 -1
- package/dist/kernel/tdd/adapter.d.ts +0 -49
- package/dist/kernel/tdd/adapter.js +0 -293
- package/dist/kernel/tdd/adapter.js.map +0 -1
- package/dist/kernel/tdd/digest.d.ts +0 -17
- package/dist/kernel/tdd/digest.js +0 -301
- package/dist/kernel/tdd/digest.js.map +0 -1
- package/dist/kernel/tdd/evaluator.d.ts +0 -38
- package/dist/kernel/tdd/evaluator.js +0 -185
- package/dist/kernel/tdd/evaluator.js.map +0 -1
- package/dist/kernel/tdd/evidence.d.ts +0 -42
- package/dist/kernel/tdd/evidence.js +0 -48
- package/dist/kernel/tdd/evidence.js.map +0 -1
- package/dist/kernel/tdd/state.d.ts +0 -79
- package/dist/kernel/tdd/state.js +0 -363
- package/dist/kernel/tdd/state.js.map +0 -1
- package/dist/kernel/types.d.ts +0 -180
- package/dist/kernel/types.js +0 -2
- package/dist/kernel/types.js.map +0 -1
- package/dist/kernel/worktree.d.ts +0 -45
- package/dist/kernel/worktree.js +0 -127
- package/dist/kernel/worktree.js.map +0 -1
- package/dist/plugin/flow-control.d.ts +0 -80
- package/dist/plugin/flow-control.js +0 -254
- package/dist/plugin/flow-control.js.map +0 -1
- package/dist/plugin/release-control.d.ts +0 -37
- package/dist/plugin/release-control.js +0 -304
- package/dist/plugin/release-control.js.map +0 -1
- package/dist/plugin/setup-control.d.ts +0 -45
- package/dist/plugin/setup-control.js +0 -80
- package/dist/plugin/setup-control.js.map +0 -1
- package/dist/plugin/task-control.d.ts +0 -90
- package/dist/plugin/task-control.js +0 -201
- package/dist/plugin/task-control.js.map +0 -1
- package/dist/plugin/tdd-checkpoint.d.ts +0 -118
- package/dist/plugin/tdd-checkpoint.js +0 -581
- package/dist/plugin/tdd-checkpoint.js.map +0 -1
- package/dist/util/shell.d.ts +0 -1
- package/dist/util/shell.js +0 -4
- package/dist/util/shell.js.map +0 -1
package/dist/kernel/records.d.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type { FlowRecordRef, TaskRecordRef } from "./types.js";
|
|
2
|
-
/** TDD evidence 受控 comment 的 marker(单个 comment 承载全部证据) */
|
|
3
|
-
export declare const EVIDENCE_MARKER_START = "<!-- cabbage-tdd-evidence:start -->";
|
|
4
|
-
export declare const EVIDENCE_MARKER_END = "<!-- cabbage-tdd-evidence:end -->";
|
|
5
|
-
/** Flow Record(Parent Issue)标签 */
|
|
6
|
-
export declare const FLOW_LABEL = "cabbage:flow";
|
|
7
|
-
/** 阶段标签前缀:cabbage:stage:<stage> */
|
|
8
|
-
export declare const STAGE_LABEL_PREFIX = "cabbage:stage:";
|
|
9
|
-
type GhFn = (args: string) => Promise<{
|
|
10
|
-
stdout: string;
|
|
11
|
-
stderr: string;
|
|
12
|
-
}>;
|
|
13
|
-
export declare function setRecordsGhExecutor(fn: GhFn | null): void;
|
|
14
|
-
/** 构造 marker 包裹的受控 comment body,START marker 行内携带 revision */
|
|
15
|
-
export declare function buildEvidenceCommentBody(block: string, revision: number): string;
|
|
16
|
-
/** 从受控 comment body 提取 revision 与 marker 区间内容;无 marker 或畸形返回 null */
|
|
17
|
-
export declare function extractEvidenceBlock(body: string): {
|
|
18
|
-
revision: number;
|
|
19
|
-
content: string;
|
|
20
|
-
} | null;
|
|
21
|
-
export interface CreateFlowRecordInput {
|
|
22
|
-
slug: string;
|
|
23
|
-
body: string;
|
|
24
|
-
}
|
|
25
|
-
/** 创建 Draft Parent Issue(Flow Record),打 cabbage:flow 标签 */
|
|
26
|
-
export declare function createFlowRecord(input: CreateFlowRecordInput): Promise<{
|
|
27
|
-
ok: true;
|
|
28
|
-
ref: FlowRecordRef;
|
|
29
|
-
} | {
|
|
30
|
-
ok: false;
|
|
31
|
-
error: string;
|
|
32
|
-
}>;
|
|
33
|
-
export declare function readFlowRecord(parentIssueNumber: number): Promise<{
|
|
34
|
-
ok: true;
|
|
35
|
-
body: string;
|
|
36
|
-
} | {
|
|
37
|
-
ok: false;
|
|
38
|
-
code: "NOT_FOUND";
|
|
39
|
-
error: string;
|
|
40
|
-
}>;
|
|
41
|
-
/**
|
|
42
|
-
* 乐观锁更新 Flow Record body:mutex 串行 + previousBody 比对。
|
|
43
|
-
* 比对不一致(外部并发修改)→ 重读最新 body 重试 1 次(retried: true)。
|
|
44
|
-
*/
|
|
45
|
-
export declare function updateFlowRecord(parentIssueNumber: number, previousBody: string, buildNewBody: (current: string) => string): Promise<{
|
|
46
|
-
ok: true;
|
|
47
|
-
retried: boolean;
|
|
48
|
-
} | {
|
|
49
|
-
ok: false;
|
|
50
|
-
error: string;
|
|
51
|
-
}>;
|
|
52
|
-
export interface CreateTaskRecordInput {
|
|
53
|
-
title: string;
|
|
54
|
-
body: string;
|
|
55
|
-
parentIssueNumber: number;
|
|
56
|
-
}
|
|
57
|
-
/** 创建关联 Parent 的 Sub Issue(Task Record) */
|
|
58
|
-
export declare function createTaskRecord(input: CreateTaskRecordInput): Promise<{
|
|
59
|
-
ok: true;
|
|
60
|
-
ref: TaskRecordRef;
|
|
61
|
-
} | {
|
|
62
|
-
ok: false;
|
|
63
|
-
error: string;
|
|
64
|
-
}>;
|
|
65
|
-
export interface TddEvidenceComment {
|
|
66
|
-
id: number;
|
|
67
|
-
body: string;
|
|
68
|
-
revision: number;
|
|
69
|
-
}
|
|
70
|
-
/** 读取 Task Record 的单个受控 evidence comment;不存在返回 null */
|
|
71
|
-
export declare function readTddEvidenceComment(issueNumber: number): Promise<TddEvidenceComment | null>;
|
|
72
|
-
/**
|
|
73
|
-
* 追加 TDD evidence 到 Task Record 的单个受控 comment:
|
|
74
|
-
* 无受控 comment → 新建(revision 1);有 → marker 区间内 append,revision+1(PATCH 更新)。
|
|
75
|
-
* mutex 按 issueNumber 串行;block 已存在则幂等跳过(追加不重复)。
|
|
76
|
-
*/
|
|
77
|
-
export declare function appendTddEvidence(issueNumber: number, block: string): Promise<{
|
|
78
|
-
ok: boolean;
|
|
79
|
-
revision: number;
|
|
80
|
-
error?: string;
|
|
81
|
-
}>;
|
|
82
|
-
/** 设置 Flow Record 的阶段标签:移除其它 cabbage:stage:*,添加当前阶段 */
|
|
83
|
-
export declare function setStageLabel(parentIssueNumber: number, stage: string): Promise<{
|
|
84
|
-
ok: boolean;
|
|
85
|
-
error?: string;
|
|
86
|
-
}>;
|
|
87
|
-
export {};
|
package/dist/kernel/records.js
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { gh as ghCli } from "../util/gh.js";
|
|
2
|
-
import { escapeShellArg } from "../util/shell.js";
|
|
3
|
-
import { KeyedMutex } from "./mutex.js";
|
|
4
|
-
/** TDD evidence 受控 comment 的 marker(单个 comment 承载全部证据) */
|
|
5
|
-
export const EVIDENCE_MARKER_START = "<!-- cabbage-tdd-evidence:start -->";
|
|
6
|
-
export const EVIDENCE_MARKER_END = "<!-- cabbage-tdd-evidence:end -->";
|
|
7
|
-
/** Flow Record(Parent Issue)标签 */
|
|
8
|
-
export const FLOW_LABEL = "cabbage:flow";
|
|
9
|
-
/** 阶段标签前缀:cabbage:stage:<stage> */
|
|
10
|
-
export const STAGE_LABEL_PREFIX = "cabbage:stage:";
|
|
11
|
-
let recordsGhExecutor = null;
|
|
12
|
-
export function setRecordsGhExecutor(fn) {
|
|
13
|
-
recordsGhExecutor = fn;
|
|
14
|
-
}
|
|
15
|
-
async function gh(args, timeout) {
|
|
16
|
-
if (recordsGhExecutor) {
|
|
17
|
-
return recordsGhExecutor(args);
|
|
18
|
-
}
|
|
19
|
-
return ghCli(args, timeout);
|
|
20
|
-
}
|
|
21
|
-
// ─── evidence comment 纯函数 ───
|
|
22
|
-
/** 构造 marker 包裹的受控 comment body,START marker 行内携带 revision */
|
|
23
|
-
export function buildEvidenceCommentBody(block, revision) {
|
|
24
|
-
return `${EVIDENCE_MARKER_START} revision:${revision}\n${block}\n${EVIDENCE_MARKER_END}`;
|
|
25
|
-
}
|
|
26
|
-
/** 从受控 comment body 提取 revision 与 marker 区间内容;无 marker 或畸形返回 null */
|
|
27
|
-
export function extractEvidenceBlock(body) {
|
|
28
|
-
const startIdx = body.indexOf(EVIDENCE_MARKER_START);
|
|
29
|
-
const endIdx = body.indexOf(EVIDENCE_MARKER_END);
|
|
30
|
-
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
const newlineAfterStart = body.indexOf("\n", startIdx);
|
|
34
|
-
if (newlineAfterStart === -1 || newlineAfterStart > endIdx) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
const header = body.slice(startIdx, newlineAfterStart);
|
|
38
|
-
const revisionMatch = header.match(/revision:(\d+)/);
|
|
39
|
-
if (!revisionMatch) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
const content = body.slice(newlineAfterStart + 1, endIdx).trim();
|
|
43
|
-
if (content === "") {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
return { revision: Number(revisionMatch[1]), content };
|
|
47
|
-
}
|
|
48
|
-
// ─── 记录写入互斥(按 issueNumber 串行) ───
|
|
49
|
-
const recordMutex = new KeyedMutex();
|
|
50
|
-
async function readBody(issueNumber) {
|
|
51
|
-
const { stdout } = await gh(`issue view ${issueNumber} --json body --jq .body`);
|
|
52
|
-
return stdout;
|
|
53
|
-
}
|
|
54
|
-
async function writeBody(issueNumber, body) {
|
|
55
|
-
const escaped = escapeShellArg(body);
|
|
56
|
-
await gh(`issue edit ${issueNumber} --body '${escaped}'`);
|
|
57
|
-
}
|
|
58
|
-
/** 创建 Draft Parent Issue(Flow Record),打 cabbage:flow 标签 */
|
|
59
|
-
export async function createFlowRecord(input) {
|
|
60
|
-
try {
|
|
61
|
-
const escapedBody = escapeShellArg(input.body);
|
|
62
|
-
const { stdout } = await gh(`issue create --title '${input.slug}' --body '${escapedBody}' --label '${FLOW_LABEL}' --draft --json number --jq .number`);
|
|
63
|
-
const number = Number(stdout.trim());
|
|
64
|
-
if (!Number.isInteger(number)) {
|
|
65
|
-
throw new Error(`invalid issue number: ${stdout}`);
|
|
66
|
-
}
|
|
67
|
-
return { ok: true, ref: { parentIssueNumber: number, slug: input.slug } };
|
|
68
|
-
}
|
|
69
|
-
catch (err) {
|
|
70
|
-
return { ok: false, error: String(err) };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export async function readFlowRecord(parentIssueNumber) {
|
|
74
|
-
try {
|
|
75
|
-
const { stdout } = await gh(`issue view ${parentIssueNumber} --json body --jq .body`);
|
|
76
|
-
return { ok: true, body: stdout };
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
return { ok: false, code: "NOT_FOUND", error: String(err) };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* 乐观锁更新 Flow Record body:mutex 串行 + previousBody 比对。
|
|
84
|
-
* 比对不一致(外部并发修改)→ 重读最新 body 重试 1 次(retried: true)。
|
|
85
|
-
*/
|
|
86
|
-
export async function updateFlowRecord(parentIssueNumber, previousBody, buildNewBody) {
|
|
87
|
-
return recordMutex.runExclusive(parentIssueNumber, async () => {
|
|
88
|
-
try {
|
|
89
|
-
const current = await readBody(parentIssueNumber);
|
|
90
|
-
if (current === previousBody) {
|
|
91
|
-
await writeBody(parentIssueNumber, buildNewBody(current));
|
|
92
|
-
return { ok: true, retried: false };
|
|
93
|
-
}
|
|
94
|
-
// 冲突:重读最新 body 重试 1 次
|
|
95
|
-
const latest = await readBody(parentIssueNumber);
|
|
96
|
-
await writeBody(parentIssueNumber, buildNewBody(latest));
|
|
97
|
-
return { ok: true, retried: true };
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
return { ok: false, error: String(err) };
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
/** 创建关联 Parent 的 Sub Issue(Task Record) */
|
|
105
|
-
export async function createTaskRecord(input) {
|
|
106
|
-
try {
|
|
107
|
-
const escapedBody = escapeShellArg(input.body);
|
|
108
|
-
const { stdout } = await gh(`issue create --title '${input.title}' --body '${escapedBody}' --parent ${input.parentIssueNumber} --json number --jq .number`);
|
|
109
|
-
const number = Number(stdout.trim());
|
|
110
|
-
if (!Number.isInteger(number)) {
|
|
111
|
-
throw new Error(`invalid issue number: ${stdout}`);
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
ok: true,
|
|
115
|
-
ref: { parentIssueNumber: input.parentIssueNumber, taskId: input.title, issueNumber: number },
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
return { ok: false, error: String(err) };
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/** 读取 Task Record 的单个受控 evidence comment;不存在返回 null */
|
|
123
|
-
export async function readTddEvidenceComment(issueNumber) {
|
|
124
|
-
try {
|
|
125
|
-
const { stdout } = await gh(`issue view ${issueNumber} --json comments --jq '[.comments[] | select(.body | contains("${EVIDENCE_MARKER_START}")) | {id: (.id|tonumber), body}] | first'`);
|
|
126
|
-
const trimmed = stdout.trim();
|
|
127
|
-
if (trimmed === "" || trimmed === "null") {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
const parsed = JSON.parse(trimmed);
|
|
131
|
-
const extracted = extractEvidenceBlock(parsed.body);
|
|
132
|
-
if (!extracted) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
return { id: parsed.id, body: parsed.body, revision: extracted.revision };
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* 追加 TDD evidence 到 Task Record 的单个受控 comment:
|
|
143
|
-
* 无受控 comment → 新建(revision 1);有 → marker 区间内 append,revision+1(PATCH 更新)。
|
|
144
|
-
* mutex 按 issueNumber 串行;block 已存在则幂等跳过(追加不重复)。
|
|
145
|
-
*/
|
|
146
|
-
export async function appendTddEvidence(issueNumber, block) {
|
|
147
|
-
return recordMutex.runExclusive(issueNumber, async () => {
|
|
148
|
-
try {
|
|
149
|
-
const existing = await readTddEvidenceComment(issueNumber);
|
|
150
|
-
if (!existing) {
|
|
151
|
-
const body = buildEvidenceCommentBody(block, 1);
|
|
152
|
-
await gh(`issue comment ${issueNumber} --body '${escapeShellArg(body)}'`);
|
|
153
|
-
return { ok: true, revision: 1 };
|
|
154
|
-
}
|
|
155
|
-
// 幂等:block 已在 marker 区间内,不重复追加
|
|
156
|
-
const extracted = extractEvidenceBlock(existing.body);
|
|
157
|
-
if (extracted && extracted.content.includes(block)) {
|
|
158
|
-
return { ok: true, revision: existing.revision };
|
|
159
|
-
}
|
|
160
|
-
const newBody = appendBlockToEvidenceBody(existing.body, block, existing.revision);
|
|
161
|
-
const repo = await gh("repo view --json nameWithOwner --jq .nameWithOwner");
|
|
162
|
-
await gh(`api repos/${repo.stdout.trim()}/issues/comments/${existing.id} -X PATCH -f body='${escapeShellArg(newBody)}'`);
|
|
163
|
-
return { ok: true, revision: existing.revision + 1 };
|
|
164
|
-
}
|
|
165
|
-
catch (err) {
|
|
166
|
-
return { ok: false, revision: 0, error: String(err) };
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
/** 在 END marker 前插入新 block,并将 START 行 revision 递增 */
|
|
171
|
-
function appendBlockToEvidenceBody(body, block, revision) {
|
|
172
|
-
const endIdx = body.indexOf(EVIDENCE_MARKER_END);
|
|
173
|
-
const prefix = body.slice(0, endIdx);
|
|
174
|
-
const suffix = body.slice(endIdx);
|
|
175
|
-
return `${prefix}${block}\n${suffix}`.replace(/(revision:)\d+/, `$1${revision + 1}`);
|
|
176
|
-
}
|
|
177
|
-
// ─── labels ───
|
|
178
|
-
/** 设置 Flow Record 的阶段标签:移除其它 cabbage:stage:*,添加当前阶段 */
|
|
179
|
-
export async function setStageLabel(parentIssueNumber, stage) {
|
|
180
|
-
try {
|
|
181
|
-
const { stdout } = await gh(`issue view ${parentIssueNumber} --json labels --jq '[.labels[].name] | join(" ") | tostring'`);
|
|
182
|
-
const currentLabels = stdout.trim() === "" ? [] : stdout.trim().split(" ");
|
|
183
|
-
const target = `${STAGE_LABEL_PREFIX}${stage}`;
|
|
184
|
-
const stale = currentLabels.filter(l => l.startsWith(STAGE_LABEL_PREFIX) && l !== target);
|
|
185
|
-
const args = [];
|
|
186
|
-
for (const label of stale) {
|
|
187
|
-
args.push(`--remove-label '${label}'`);
|
|
188
|
-
}
|
|
189
|
-
args.push(`--add-label '${target}'`);
|
|
190
|
-
await gh(`issue edit ${parentIssueNumber} ${args.join(" ")}`);
|
|
191
|
-
return { ok: true };
|
|
192
|
-
}
|
|
193
|
-
catch (err) {
|
|
194
|
-
return { ok: false, error: String(err) };
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
//# sourceMappingURL=records.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../src/kernel/records.ts"],"names":[],"mappings":"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"}
|
package/dist/kernel/release.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
export type ChangeCategory = "feature" | "fix" | "maintenance" | "docs" | "unclassified";
|
|
2
|
-
export type VersionType = "major" | "minor" | "patch";
|
|
3
|
-
export interface ReleaseChange {
|
|
4
|
-
sha: string;
|
|
5
|
-
title: string;
|
|
6
|
-
category: ChangeCategory;
|
|
7
|
-
breaking: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface Version {
|
|
10
|
-
major: number;
|
|
11
|
-
minor: number;
|
|
12
|
-
patch: number;
|
|
13
|
-
}
|
|
14
|
-
export interface VersionFileSpec {
|
|
15
|
-
path: string;
|
|
16
|
-
key: string;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* 解析版本文件规则(Profile `version file` 值):
|
|
20
|
-
* 形如 `package.json`(默认 $.version)或 `lib/version.json $.version`;
|
|
21
|
-
* json 路径必须为 `$.<key>` 形式,否则返回 null。
|
|
22
|
-
*/
|
|
23
|
-
export declare function parseVersionFileSpec(spec: string): VersionFileSpec | null;
|
|
24
|
-
/** 从 JSON 文本按 key 读取版本字符串;非字符串或解析失败返回 null */
|
|
25
|
-
export declare function readVersionFromJson(json: string, key: string): string | null;
|
|
26
|
-
/** 更新 JSON 文本中指定 key 的版本;保留缩进风格与结尾换行 */
|
|
27
|
-
export declare function updateVersionInJson(json: string, key: string, version: string): string;
|
|
28
|
-
export declare function parseVersion(raw: string): Version | null;
|
|
29
|
-
export declare function formatVersion(v: Version): string;
|
|
30
|
-
/** SemVer bump:major 重置 minor/patch,minor 重置 patch,patch +1 */
|
|
31
|
-
export declare function bumpVersion(current: Version, type: VersionType): Version;
|
|
32
|
-
/** 取最高 bump 级别:major > minor > patch */
|
|
33
|
-
export declare function highestBumpType(types: VersionType[]): VersionType;
|
|
34
|
-
type Classified = {
|
|
35
|
-
category: ChangeCategory;
|
|
36
|
-
breaking: boolean;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* 从 commit message 分类(conventional commits,关联 Flow/Task type):
|
|
40
|
-
* - breaking:`type!:` 或 body 含 `BREAKING CHANGE`
|
|
41
|
-
* - feat→feature、fix→fix、docs→docs、chore/refactor/build/ci/perf/test/merge→maintenance
|
|
42
|
-
* - 其余 → unclassified
|
|
43
|
-
*/
|
|
44
|
-
export declare function classifyCommitTitle(title: string): Classified;
|
|
45
|
-
export declare function classifyChanges(commits: {
|
|
46
|
-
sha: string;
|
|
47
|
-
title: string;
|
|
48
|
-
}[]): ReleaseChange[];
|
|
49
|
-
export type ProposeVersionResult = {
|
|
50
|
-
ok: true;
|
|
51
|
-
proposed: string;
|
|
52
|
-
type: VersionType;
|
|
53
|
-
} | {
|
|
54
|
-
ok: false;
|
|
55
|
-
code: "INVALID_VERSION";
|
|
56
|
-
message: string;
|
|
57
|
-
} | {
|
|
58
|
-
ok: false;
|
|
59
|
-
code: "UNCLASSIFIED_CHANGES";
|
|
60
|
-
unclassified: {
|
|
61
|
-
sha: string;
|
|
62
|
-
title: string;
|
|
63
|
-
}[];
|
|
64
|
-
message: string;
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* SemVer 提议:breaking→major(含 0.x)、feature→minor、fix/maintenance/docs→patch;
|
|
68
|
-
* 多变更取最高级别;存在未分类变更时拒绝(版本提议前必须分类)。
|
|
69
|
-
*/
|
|
70
|
-
export declare function proposeVersion(currentVersion: string, changes: ReleaseChange[]): ProposeVersionResult;
|
|
71
|
-
/** 按 tag 格式(如 v{version})构建 tag;缺省 v{version} */
|
|
72
|
-
export declare function buildTag(version: string, tagFormat: string): string;
|
|
73
|
-
/** tag 是否匹配格式(替换 {version} 为语义版本正则后整体匹配) */
|
|
74
|
-
export declare function validateTagFormat(tag: string, tagFormat: string): boolean;
|
|
75
|
-
/** 按分类聚合生成 Release Notes markdown;breaking 变更单独列出 */
|
|
76
|
-
export declare function buildReleaseNotes(version: string, changes: ReleaseChange[]): string;
|
|
77
|
-
export type GhFn = (args: string) => Promise<{
|
|
78
|
-
stdout: string;
|
|
79
|
-
stderr: string;
|
|
80
|
-
}>;
|
|
81
|
-
export declare function setReleaseGhExecutor(fn: GhFn | null): void;
|
|
82
|
-
/** 仓库上一 tag 名(tags 列表第一个);无 tag 返回 null */
|
|
83
|
-
export declare function latestTag(executor?: GhFn): Promise<string | null>;
|
|
84
|
-
/** 聚合上一 tag 之后 base 分支的全部 commit(sha + 首行标题) */
|
|
85
|
-
export declare function listCommitsSinceTag(tag: string, baseBranch: string, executor?: GhFn): Promise<{
|
|
86
|
-
sha: string;
|
|
87
|
-
title: string;
|
|
88
|
-
}[]>;
|
|
89
|
-
/** 远程已存在 tag 指向的 commit SHA;不存在返回 null */
|
|
90
|
-
export declare function existingTagSha(tag: string, executor?: GhFn): Promise<string | null>;
|
|
91
|
-
export type TagImmutabilityResult = {
|
|
92
|
-
ok: true;
|
|
93
|
-
reason?: string;
|
|
94
|
-
} | {
|
|
95
|
-
ok: false;
|
|
96
|
-
code: "TAG_ALREADY_EXISTS";
|
|
97
|
-
message: string;
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* tag 不可变校验:不得删除重打。
|
|
101
|
-
* 远程已存在且指向不同 SHA → 拒绝;指向同一 SHA → 幂等通过;不存在 → 可创建。
|
|
102
|
-
*/
|
|
103
|
-
export declare function validateTagImmutability(tag: string, expectedSha: string, executor?: GhFn): Promise<TagImmutabilityResult>;
|
|
104
|
-
export {};
|
package/dist/kernel/release.js
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { gh as ghCli } from "../util/gh.js";
|
|
2
|
-
/**
|
|
3
|
-
* 解析版本文件规则(Profile `version file` 值):
|
|
4
|
-
* 形如 `package.json`(默认 $.version)或 `lib/version.json $.version`;
|
|
5
|
-
* json 路径必须为 `$.<key>` 形式,否则返回 null。
|
|
6
|
-
*/
|
|
7
|
-
export function parseVersionFileSpec(spec) {
|
|
8
|
-
const trimmed = spec.trim();
|
|
9
|
-
if (trimmed === "")
|
|
10
|
-
return null;
|
|
11
|
-
const parts = trimmed.split(/\s+/);
|
|
12
|
-
if (parts.length === 1) {
|
|
13
|
-
return { path: parts[0], key: "version" };
|
|
14
|
-
}
|
|
15
|
-
const jsonPath = parts[parts.length - 1];
|
|
16
|
-
const key = jsonPath.startsWith("$.") ? jsonPath.slice(2) : "";
|
|
17
|
-
if (key === "")
|
|
18
|
-
return null;
|
|
19
|
-
return { path: parts.slice(0, -1).join(" "), key };
|
|
20
|
-
}
|
|
21
|
-
/** 从 JSON 文本按 key 读取版本字符串;非字符串或解析失败返回 null */
|
|
22
|
-
export function readVersionFromJson(json, key) {
|
|
23
|
-
try {
|
|
24
|
-
const value = JSON.parse(json)?.[key];
|
|
25
|
-
return typeof value === "string" ? value : null;
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/** 更新 JSON 文本中指定 key 的版本;保留缩进风格与结尾换行 */
|
|
32
|
-
export function updateVersionInJson(json, key, version) {
|
|
33
|
-
const parsed = JSON.parse(json);
|
|
34
|
-
parsed[key] = version;
|
|
35
|
-
const updated = JSON.stringify(parsed, null, 2);
|
|
36
|
-
return json.endsWith("\n") ? `${updated}\n` : updated;
|
|
37
|
-
}
|
|
38
|
-
// ─── 版本纯函数 ───
|
|
39
|
-
const VERSION_PATTERN = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
40
|
-
export function parseVersion(raw) {
|
|
41
|
-
const match = VERSION_PATTERN.exec(raw.trim());
|
|
42
|
-
if (!match)
|
|
43
|
-
return null;
|
|
44
|
-
return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) };
|
|
45
|
-
}
|
|
46
|
-
export function formatVersion(v) {
|
|
47
|
-
return `${v.major}.${v.minor}.${v.patch}`;
|
|
48
|
-
}
|
|
49
|
-
/** SemVer bump:major 重置 minor/patch,minor 重置 patch,patch +1 */
|
|
50
|
-
export function bumpVersion(current, type) {
|
|
51
|
-
switch (type) {
|
|
52
|
-
case "major":
|
|
53
|
-
return { major: current.major + 1, minor: 0, patch: 0 };
|
|
54
|
-
case "minor":
|
|
55
|
-
return { major: current.major, minor: current.minor + 1, patch: 0 };
|
|
56
|
-
case "patch":
|
|
57
|
-
return { major: current.major, minor: current.minor, patch: current.patch + 1 };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/** 取最高 bump 级别:major > minor > patch */
|
|
61
|
-
export function highestBumpType(types) {
|
|
62
|
-
if (types.includes("major"))
|
|
63
|
-
return "major";
|
|
64
|
-
if (types.includes("minor"))
|
|
65
|
-
return "minor";
|
|
66
|
-
return "patch";
|
|
67
|
-
}
|
|
68
|
-
const CONVENTIONAL_PATTERN = /^([a-z]+)(!)?(\([^)]*\))?:/;
|
|
69
|
-
const MAINTENANCE_TYPES = new Set(["chore", "refactor", "build", "ci", "perf", "test", "merge"]);
|
|
70
|
-
/**
|
|
71
|
-
* 从 commit message 分类(conventional commits,关联 Flow/Task type):
|
|
72
|
-
* - breaking:`type!:` 或 body 含 `BREAKING CHANGE`
|
|
73
|
-
* - feat→feature、fix→fix、docs→docs、chore/refactor/build/ci/perf/test/merge→maintenance
|
|
74
|
-
* - 其余 → unclassified
|
|
75
|
-
*/
|
|
76
|
-
export function classifyCommitTitle(title) {
|
|
77
|
-
const firstLine = title.split("\n")[0];
|
|
78
|
-
const breaking = /^[a-z]+!(:|\()/.test(firstLine) || title.includes("BREAKING CHANGE");
|
|
79
|
-
if (firstLine.startsWith("Merge ")) {
|
|
80
|
-
return { category: "maintenance", breaking };
|
|
81
|
-
}
|
|
82
|
-
const match = CONVENTIONAL_PATTERN.exec(firstLine);
|
|
83
|
-
if (!match)
|
|
84
|
-
return { category: "unclassified", breaking };
|
|
85
|
-
const type = match[1];
|
|
86
|
-
switch (type) {
|
|
87
|
-
case "feat":
|
|
88
|
-
return { category: "feature", breaking };
|
|
89
|
-
case "fix":
|
|
90
|
-
return { category: "fix", breaking };
|
|
91
|
-
case "docs":
|
|
92
|
-
return { category: "docs", breaking };
|
|
93
|
-
default:
|
|
94
|
-
if (MAINTENANCE_TYPES.has(type))
|
|
95
|
-
return { category: "maintenance", breaking };
|
|
96
|
-
return { category: "unclassified", breaking };
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export function classifyChanges(commits) {
|
|
100
|
-
return commits.map(commit => {
|
|
101
|
-
const { category, breaking } = classifyCommitTitle(commit.title);
|
|
102
|
-
return { sha: commit.sha, title: commit.title.split("\n")[0], category, breaking };
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* SemVer 提议:breaking→major(含 0.x)、feature→minor、fix/maintenance/docs→patch;
|
|
107
|
-
* 多变更取最高级别;存在未分类变更时拒绝(版本提议前必须分类)。
|
|
108
|
-
*/
|
|
109
|
-
export function proposeVersion(currentVersion, changes) {
|
|
110
|
-
const current = parseVersion(currentVersion);
|
|
111
|
-
if (!current) {
|
|
112
|
-
return { ok: false, code: "INVALID_VERSION", message: `Invalid current version: ${currentVersion}` };
|
|
113
|
-
}
|
|
114
|
-
const unclassified = changes
|
|
115
|
-
.filter(c => c.category === "unclassified")
|
|
116
|
-
.map(c => ({ sha: c.sha, title: c.title }));
|
|
117
|
-
if (unclassified.length > 0) {
|
|
118
|
-
return {
|
|
119
|
-
ok: false,
|
|
120
|
-
code: "UNCLASSIFIED_CHANGES",
|
|
121
|
-
unclassified,
|
|
122
|
-
message: `Unclassified changes must be classified before proposing a version (${unclassified.length} change(s))`,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
const breaking = changes.some(c => c.breaking);
|
|
126
|
-
const types = [];
|
|
127
|
-
for (const c of changes) {
|
|
128
|
-
if (c.category === "feature")
|
|
129
|
-
types.push("minor");
|
|
130
|
-
else if (c.category === "fix" || c.category === "maintenance" || c.category === "docs")
|
|
131
|
-
types.push("patch");
|
|
132
|
-
}
|
|
133
|
-
if (breaking)
|
|
134
|
-
types.push("major");
|
|
135
|
-
const type = highestBumpType(types);
|
|
136
|
-
return { ok: true, proposed: formatVersion(bumpVersion(current, type)), type };
|
|
137
|
-
}
|
|
138
|
-
// ─── tag ───
|
|
139
|
-
/** 按 tag 格式(如 v{version})构建 tag;缺省 v{version} */
|
|
140
|
-
export function buildTag(version, tagFormat) {
|
|
141
|
-
if (tagFormat.includes("{version}")) {
|
|
142
|
-
return tagFormat.replace("{version}", version);
|
|
143
|
-
}
|
|
144
|
-
return `v${version}`;
|
|
145
|
-
}
|
|
146
|
-
/** tag 是否匹配格式(替换 {version} 为语义版本正则后整体匹配) */
|
|
147
|
-
export function validateTagFormat(tag, tagFormat) {
|
|
148
|
-
const escaped = tagFormat.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\{version\\}", "(\\d+\\.\\d+\\.\\d+)");
|
|
149
|
-
return new RegExp(`^${escaped}$`).test(tag);
|
|
150
|
-
}
|
|
151
|
-
// ─── Release Notes ───
|
|
152
|
-
const SECTION_TITLES = [
|
|
153
|
-
["feature", "Features"],
|
|
154
|
-
["fix", "Fixes"],
|
|
155
|
-
["maintenance", "Maintenance"],
|
|
156
|
-
["docs", "Documentation"],
|
|
157
|
-
];
|
|
158
|
-
/** 按分类聚合生成 Release Notes markdown;breaking 变更单独列出 */
|
|
159
|
-
export function buildReleaseNotes(version, changes) {
|
|
160
|
-
const lines = [`## ${version}`];
|
|
161
|
-
const breaking = changes.filter(c => c.breaking);
|
|
162
|
-
if (breaking.length > 0) {
|
|
163
|
-
lines.push("", "### BREAKING CHANGES");
|
|
164
|
-
for (const c of breaking)
|
|
165
|
-
lines.push(`- ${c.title}`);
|
|
166
|
-
}
|
|
167
|
-
for (const [category, title] of SECTION_TITLES) {
|
|
168
|
-
const group = changes.filter(c => c.category === category);
|
|
169
|
-
if (group.length === 0)
|
|
170
|
-
continue;
|
|
171
|
-
lines.push("", `### ${title}`);
|
|
172
|
-
for (const c of group)
|
|
173
|
-
lines.push(`- ${c.title}`);
|
|
174
|
-
}
|
|
175
|
-
return lines.join("\n");
|
|
176
|
-
}
|
|
177
|
-
let releaseGhExecutor = null;
|
|
178
|
-
export function setReleaseGhExecutor(fn) {
|
|
179
|
-
releaseGhExecutor = fn;
|
|
180
|
-
}
|
|
181
|
-
/** 解析实际 gh 执行函数:显式 executor > 模块级 mock > 真实 gh CLI */
|
|
182
|
-
function ghFn(executor) {
|
|
183
|
-
return executor ?? releaseGhExecutor ?? ghCli;
|
|
184
|
-
}
|
|
185
|
-
/** 仓库上一 tag 名(tags 列表第一个);无 tag 返回 null */
|
|
186
|
-
export async function latestTag(executor) {
|
|
187
|
-
const { stdout } = await ghFn(executor)(`api repos/{owner}/{repo}/tags --jq '.[0].name'`);
|
|
188
|
-
const trimmed = stdout.trim();
|
|
189
|
-
if (trimmed === "" || trimmed === "null")
|
|
190
|
-
return null;
|
|
191
|
-
return trimmed;
|
|
192
|
-
}
|
|
193
|
-
/** 聚合上一 tag 之后 base 分支的全部 commit(sha + 首行标题) */
|
|
194
|
-
export async function listCommitsSinceTag(tag, baseBranch, executor) {
|
|
195
|
-
const { stdout } = await ghFn(executor)(`api repos/{owner}/{repo}/compare/${tag}...${baseBranch} --jq '.commits[] | {sha: .sha, title: (.commit.message | split("\\n")[0])}'`);
|
|
196
|
-
const trimmed = stdout.trim();
|
|
197
|
-
if (trimmed === "" || trimmed === "null")
|
|
198
|
-
return [];
|
|
199
|
-
const commits = JSON.parse(trimmed);
|
|
200
|
-
// jq 已截断首行,这里再截断一次(mock/调用方绕过 jq 时兜底)
|
|
201
|
-
return commits.map(c => ({ sha: c.sha, title: c.title.split("\n")[0] }));
|
|
202
|
-
}
|
|
203
|
-
/** 远程已存在 tag 指向的 commit SHA;不存在返回 null */
|
|
204
|
-
export async function existingTagSha(tag, executor) {
|
|
205
|
-
const { stdout } = await ghFn(executor)(`api repos/{owner}/{repo}/tags --jq '.[] | select(.name == "${tag}") | .commit.sha'`);
|
|
206
|
-
const trimmed = stdout.trim();
|
|
207
|
-
if (trimmed === "" || trimmed === "null")
|
|
208
|
-
return null;
|
|
209
|
-
return trimmed;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* tag 不可变校验:不得删除重打。
|
|
213
|
-
* 远程已存在且指向不同 SHA → 拒绝;指向同一 SHA → 幂等通过;不存在 → 可创建。
|
|
214
|
-
*/
|
|
215
|
-
export async function validateTagImmutability(tag, expectedSha, executor) {
|
|
216
|
-
const existing = await existingTagSha(tag, executor);
|
|
217
|
-
if (existing === null) {
|
|
218
|
-
return { ok: true };
|
|
219
|
-
}
|
|
220
|
-
if (existing === expectedSha) {
|
|
221
|
-
return { ok: true, reason: "tag already points at the expected commit (idempotent)" };
|
|
222
|
-
}
|
|
223
|
-
return {
|
|
224
|
-
ok: false,
|
|
225
|
-
code: "TAG_ALREADY_EXISTS",
|
|
226
|
-
message: `Tag ${tag} already exists at ${existing}, refusing to re-point it to ${expectedSha} (tags are immutable)`,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
//# sourceMappingURL=release.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"release.js","sourceRoot":"","sources":["../../src/kernel/release.ts"],"names":[],"mappings":"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"}
|