oasis_test 0.1.62 → 0.1.63
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/dist/index.js +674 -296
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,6 +34,197 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
mod
|
|
35
35
|
));
|
|
36
36
|
|
|
37
|
+
// ../core/src/content-type-handler.ts
|
|
38
|
+
function deliverableSubmit(ctx) {
|
|
39
|
+
const id = ctx.artifactId;
|
|
40
|
+
if (ctx.action === "integrate") {
|
|
41
|
+
return `- \`oasis integrate ${id} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2014\u2014 **\u6536\u53E3\u4E13\u7528**\uFF1A\u628A\u4F60\u5728 deliverable/ \u5408\u6210\u7684\u6574\u5408\u7248\u843D\u4E3A\u65B0 head\uFF08\u7CFB\u7EDF\u5185\u90E8\u4F1A\u628A\u961F\u5217\u91CC\u5176\u4F59\u5F85\u843D\u7248\u672C\u4E00\u5E76\u5E76\u8FDB\u6765\uFF09\u3002**\u7EDD\u4E0D\u8981\u7528 propose / advance \u4EA4\u96C6\u6210**\uFF08\u90A3\u4F1A\u628A\u96C6\u6210\u5F53\u6210\u53C8\u4E00\u4E2A\u5E76\u5217\u7248\u672C\u3001\u843D\u9519\u7248\u672C\uFF09\u3002`;
|
|
42
|
+
}
|
|
43
|
+
if (ctx.isPart) {
|
|
44
|
+
return `- \`oasis propose ${id} --part <\u4F60\u7684\u90E8\u4EF6> --file <\u6587\u4EF6> --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u4EA7\u51FA\u3002\`--part\` \u5FC5\u987B\u662F\u5206\u914D\u7ED9\u4F60\u7684\u90A3\u4E2A\u90E8\u4EF6\u540D\uFF1B\`--file\` \u6307\u5411\u4F60\u5199\u597D\u7684\u5185\u5BB9\u6587\u4EF6\uFF08\u90E8\u4EF6\u662F\u72EC\u7ACB\u788E\u7247\uFF0C\u5199\u4F60\u81EA\u5DF1\u7684\uFF09\uFF1B\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u505A\u4E86\u5565\u3002\u4EA7\u5B8C\u5373\u53EF\u6536\u5DE5\uFF0C\u96C6\u6210\u7531 owner \u505A\u3002`;
|
|
45
|
+
}
|
|
46
|
+
return `- \`oasis propose ${id} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4EA7\u7269\u7684\u65B0\u4E00\u7248\u3002\`--from-dir\` \u6307\u5411\u4F60\u7F16\u8F91\u540E\u7684 deliverable/\uFF08\u7CFB\u7EDF\u636E\u76EE\u5F55\u7B97\u8FD9\u7248\u3001\u5E76\u548C\u4E0A\u4E00\u7248 diff\uFF09\uFF1B\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u6539\u4E86\u5565\uFF08\u7ED9\u8BC4\u5BA1/\u540E\u4EBA\u770B\uFF0C\u4E0D\u7528\u50CF git commit \u90A3\u4E48\u7EC6\uFF09\u3002`;
|
|
47
|
+
}
|
|
48
|
+
function handlerFor(repos, contentType) {
|
|
49
|
+
if (repos?.some((r) => r.remote)) return codeHandler;
|
|
50
|
+
if (contentType === "media") return mediaHandler;
|
|
51
|
+
return textHandler;
|
|
52
|
+
}
|
|
53
|
+
function handlerForType(contentType) {
|
|
54
|
+
if (contentType === void 0) return void 0;
|
|
55
|
+
if (contentType === "code") return codeHandler;
|
|
56
|
+
if (contentType === "media") return mediaHandler;
|
|
57
|
+
return textHandler;
|
|
58
|
+
}
|
|
59
|
+
var slug, textHandler, codeHandler, mediaHandler;
|
|
60
|
+
var init_content_type_handler = __esm({
|
|
61
|
+
"../core/src/content-type-handler.ts"() {
|
|
62
|
+
"use strict";
|
|
63
|
+
slug = (id) => id.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
64
|
+
textHandler = {
|
|
65
|
+
produceInstructions(ctx) {
|
|
66
|
+
const { artifactId } = ctx;
|
|
67
|
+
if (ctx.part !== void 0) {
|
|
68
|
+
return [
|
|
69
|
+
`\u628A\u4F60\u8FD9\u4E2A\u90E8\u4EF6 \`${ctx.part}\` \u7684\u5B8C\u6574\u5185\u5BB9\u5199\u8FDB\u672C\u5730\u6587\u4EF6\uFF0C\u7136\u540E**\u53EA\u6267\u884C\u8FD9\u4E00\u6B65**\uFF1A`,
|
|
70
|
+
`\`oasis propose ${artifactId} --file <\u6587\u4EF6> --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\`\u3002`,
|
|
71
|
+
`**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D\u8981 advance\u3001\u4E0D\u8981 conclude**\u3002\u7B49\u6240\u6709\u5144\u5F1F\u90E8\u4EF6\u90FD\u4EA7\u51FA\u540E\uFF0C\u7CFB\u7EDF\u4F1A\u628A\u5404\u90E8\u4EF6\u96C6\u6210\u6210\u4E00\u7248\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`,
|
|
72
|
+
``,
|
|
73
|
+
`> \u26A0 \u5927\u6587\u4EF6\u52A1\u5FC5**\u589E\u91CF\u5199**\uFF08Write \u9AA8\u67B6 \u2192 Edit \u5206\u6B21\u8FFD\u52A0\uFF09\uFF0C\u522B\u4E00\u6B21\u6027\u5410\u6574\u4E2A\u5927\u6587\u4EF6\uFF08\u6709\u8F93\u51FA token \u4E0A\u9650\uFF09\u3002`
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
if (ctx.unionInto !== void 0) {
|
|
77
|
+
return [
|
|
78
|
+
`\u4F60\u4EA7\u51FA\u7684\u662F**\u6574\u4F53\u4EA4\u4ED8\u7269\u7684\u4E00\u4E2A\u6A21\u5757**\uFF0C\u4F1A\u88AB\u673A\u68B0\u5E76\u5165 \`${ctx.unionInto}\`\uFF08\u6309\u6587\u4EF6\u540D\u5408\u5E76\uFF09\u3002`,
|
|
79
|
+
`\u628A\u4F60\u8D1F\u8D23\u7684\u6587\u4EF6\u5199\u8FDB\u4E00\u4E2A**\u76EE\u5F55**\uFF08\u6587\u4EF6\u540D\u5373\u5B83\u5728\u6700\u7EC8\u4EA4\u4ED8\u7269\u91CC\u7684\u8DEF\u5F84\uFF0C\u5982 \`combat.js\`\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
80
|
+
`\`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\` \u2192 \`oasis conclude ${artifactId}\`\u3002`,
|
|
81
|
+
`**\u53EA\u5199\u4F60\u8FD9\u4E2A\u6A21\u5757\u7684\u6587\u4EF6\uFF0C\u4E0D\u8981\u78B0\u522B\u7684\u6A21\u5757\u7684\u6587\u4EF6**\uFF08\u540C\u540D\u4F1A\u8986\u76D6\u522B\u4EBA\u7684\uFF09\u3002\u4E25\u683C\u9075\u5B88\u4E0A\u6E38 tech-design \u7EA6\u5B9A\u7684\u63A5\u53E3/\u5168\u5C40\u547D\u540D\uFF0C\u6A21\u5757\u95F4\u624D\u80FD\u62FC\u5F97\u8D77\u6765\u3002`,
|
|
82
|
+
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
return [
|
|
86
|
+
ctx.hasHead ? `\u4F60\u7684\u4EA4\u4ED8\u7269\u5728 \`./deliverable/\` \u2014\u2014 \u91CC\u9762\u5DF2\u662F**\u5F53\u524D\u7248\u672C\u7684\u5B8C\u6574\u5185\u5BB9**\uFF0C\u76F4\u63A5\u5728\u5B83\u4E0A\u9762\u589E\u5220\u6539\u3002` : `\u4F60\u7684\u4EA4\u4ED8\u7269\u76EE\u5F55\u662F \`./deliverable/\`\uFF08\u5F53\u524D\u4E3A\u7A7A\u2014\u2014\u8FD9\u662F\u5168\u65B0\u4EA7\u7269\uFF0C\u5728\u5176\u4E2D\u4EA7\u51FA\u9996\u7248\u5185\u5BB9\uFF09\u3002`,
|
|
87
|
+
`- \u6700\u7EC8\u4EA7\u7269\u53EA\u653E \`deliverable/\`\uFF1B\u4E34\u65F6\u6587\u4EF6\uFF08\u8349\u7A3F/\u811A\u672C/\u5B9E\u9A8C\uFF09\u653E\u5230**\u522B\u5904**\uFF0C\u522B\u7559\u5728 \`deliverable/\` \u91CC\u3002`,
|
|
88
|
+
`- \u6539\u597D\u540E\u6574\u76EE\u5F55\u63D0\u4EA4\uFF1A\`oasis propose ${artifactId} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\``,
|
|
89
|
+
` \u2192 \u7CFB\u7EDF\u81EA\u52A8\u843D\u5730\u4E3A\u65B0\u7248\u672C\uFF08**\u65E0\u9700 advance**\uFF09\uFF1B\u6574\u4E2A\u4EA4\u4ED8\u7269**\u771F\u6B63\u5B8C\u6574**\u4E86\u518D \`oasis conclude ${artifactId}\`\u3002`,
|
|
90
|
+
...ctx.hasHead ? [`\uFF08\`deliverable/\` \u672C\u5C31\u662F head \u7684\u5B8C\u6574\u526F\u672C\u2014\u2014\u4F60\u4EA4\u7684\u4E00\u5B9A\u662F\u5B8C\u6574\u7248\uFF0C\u4E0D\u4F1A\u4E22\u5DF2\u6709\u5185\u5BB9\u3002\uFF09`] : [],
|
|
91
|
+
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
92
|
+
];
|
|
93
|
+
},
|
|
94
|
+
integrateInstructions(ctx) {
|
|
95
|
+
const parts = ctx.queuedPartLabels.map((p2) => `\`${p2}\``).join("\u3001") || "\uFF08\u961F\u5217\u4E3A\u7A7A\uFF09";
|
|
96
|
+
return [
|
|
97
|
+
`\u5404\u90E8\u4EF6\u4ECE**\u5171\u540C\u7956\u5148 H** \u5206\u5934\u4EA7\u51FA\u3001\u5404\u6539\u5404\u5757\uFF1A\u6BCF\u6761\u5185\u5BB9\u5728 \`parts/<\u540D>/CONTENT.md\`\uFF08\u6216\u5176\u5C55\u5F00\u6587\u4EF6\uFF09\u91CC\uFF08${parts}\uFF09\uFF0CH \u7684\u5185\u5BB9\u5728 \`deliverable/\`\uFF08\u4ECE\u96F6\u5206\u89E3\u5219\u4E3A\u7A7A\uFF09\u3002`,
|
|
98
|
+
`\u628A\u5B83\u4EEC\u5408\u6210\u4E00\u4E2A\u5B8C\u6574\u7684\u6574\u5408\u7248**\u5C31\u5730\u5199\u8FDB \`deliverable/\`**\u2014\u2014**\u4EE5 H \u4E3A\u5E95**\u3001\u628A\u5404\u90E8\u4EF6\u6539\u52A8**\u5168\u5E76\u8FDB\u6765**\uFF08\u5355\u6587\u4EF6 \`deliverable/CONTENT.md\`\uFF0C\u591A\u6587\u4EF6\u94FA\u6210\u591A\u4E2A\u6587\u4EF6\uFF1B\u5927\u6587\u4EF6\u589E\u91CF\u5199\uFF1AWrite \u9AA8\u67B6 \u2192 Edit \u8FFD\u52A0\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
99
|
+
`\`oasis integrate ${ctx.artifactId} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${ctx.artifactId}\`\u3002`,
|
|
100
|
+
``,
|
|
101
|
+
`**\u5FE0\u5B9E\u5408\u5E76\u3001\u522B\u4E22\u4EFB\u4F55\u90E8\u4EF6**\uFF1B\u63A5\u53E3/\u547D\u540D\u5BF9\u4E0D\u9F50\u5C31\u6309\u4E0A\u6E38\u89C4\u683C\u6821\u6B63\uFF0C\u8BA9 N \u4E2A\u90E8\u4EF6\u62FC\u6210\u4E00\u4E2A\u81EA\u6D3D\u6574\u4F53\u3002`
|
|
102
|
+
];
|
|
103
|
+
},
|
|
104
|
+
submitInstruction: deliverableSubmit,
|
|
105
|
+
collectionStrategy: { kind: "inline" },
|
|
106
|
+
mergeMode: "oasis-queue"
|
|
107
|
+
};
|
|
108
|
+
codeHandler = {
|
|
109
|
+
produceInstructions(ctx) {
|
|
110
|
+
const { artifactId } = ctx;
|
|
111
|
+
const repos = ctx.repos ?? [];
|
|
112
|
+
const r0 = repos[0];
|
|
113
|
+
if (ctx.part !== void 0) {
|
|
114
|
+
const work = `feat/${slug(artifactId)}__${slug(ctx.part)}`;
|
|
115
|
+
const feat2 = `feat/${slug(artifactId)}`;
|
|
116
|
+
const dev = r0?.develop ?? "develop";
|
|
117
|
+
return [
|
|
118
|
+
`\u4F60\u4EA7\u51FA\u7684\u662F\u9879\u76EE **${ctx.projectName ?? "?"}** \u7684\u4EE3\u7801\u3001\u4E14\u53EA\u662F\u90E8\u4EF6 \`${ctx.part}\`\u2014\u2014\u5185\u5BB9\u6D3B\u5728 git \u91CC\u3002\u4F60**\u53EA\u7BA1\u4EA7\u51FA\u4F60\u8FD9\u5757\u3001push \u4F60\u81EA\u5DF1\u7684\u5DE5\u4F5C\u5206\u652F**\uFF1B\`oasis propose\` \u65F6**\u7CFB\u7EDF\u4F1A\u628A\u5B83\u5E72\u51C0\u5408\u8FDB\u5DE5\u5355\u5206\u652F \`${feat2}\`**\uFF08\u4E0D\u7528\u4F60\u624B\u52A8\u5408\u3001\u4E5F\u4E0D\u7528\u7B49 owner \u5408\uFF09\u3002`,
|
|
119
|
+
`1. \`git clone ${r0?.remote ?? "<remote>"} repos/${r0?.id ?? "<id>"}\` \u2192 \`cd repos/${r0?.id ?? "<id>"}\` \u2192 \u4ECE\u4E3B\u5E72\u8D77\u4F60\u7684\u5DE5\u4F5C\u5206\u652F\uFF1A\`git checkout ${dev} && git checkout -b ${work}\``,
|
|
120
|
+
`2. \u5B9E\u73B0\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u6539\u52A8\uFF08\u4E25\u5B88\u4E0A\u6E38\u63A5\u53E3\u7EA6\u5B9A\uFF09\u3001\u81EA\u67E5\u80FD\u6784\u5EFA/\u80FD\u8DD1\u3001\`git commit\``,
|
|
121
|
+
`3. **\u53EA\u63A8\u4F60\u81EA\u5DF1\u7684\u5DE5\u4F5C\u5206\u652F**\uFF1A\`git push -u origin ${work}\`\uFF08**\u522B\u78B0 \`${feat2}\`**\u2014\u2014\u5408\u5E76\u4EA4\u7ED9\u7CFB\u7EDF\uFF09`,
|
|
122
|
+
`4. \u56DE\u62A5\uFF1A\`oasis propose ${artifactId} --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD>"\`\uFF08\u7CFB\u7EDF\u628A \`${work}\` \u5E72\u51C0\u5408\u8FDB \`${feat2}\` \u518D\u6536\u96C6\uFF1B**\u82E5\u4E0E \`${feat2}\` \u51B2\u7A81\u4F1A\u5F53\u573A\u6253\u56DE**\u2014\u2014\u6309\u63D0\u793A \`git fetch && git rebase origin/${feat2}\` \u89E3\u5B8C\u51B2\u7A81\u3001\`git push -f origin ${work}\` \u540E\u91CD\u65B0 propose\uFF09`,
|
|
123
|
+
`**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D conclude**\u3002\u5404\u90E8\u4EF6\u90FD\u5E76\u5B8C\u540E\u7531 owner \u9A8C\u6574\u4F53\u6536\u53E3\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
const feat = `feat/${slug(artifactId)}`;
|
|
127
|
+
if (ctx.isFinalize) {
|
|
128
|
+
const r02 = repos[0];
|
|
129
|
+
return [
|
|
130
|
+
`\u4F60\u662F **${ctx.projectName ?? "?"}** \u4EE3\u7801\u4EA4\u4ED8\u7269\u7684 owner\uFF0C\u6765**\u6536\u53E3**\uFF1A\u5404\u90E8\u4EF6\u5DF2\u5404\u81EA\u5E76\u5165**\u5DE5\u5355\u5206\u652F \`${feat}\`**\uFF08\u6BCF\u4E2A part \u5E72\u5B8C\u81EA\u5DF1 merge \u8FDB\u6765\u3001\u89E3\u4E86\u5404\u81EA\u51B2\u7A81\uFF09\u3002\u4F60**\u4E0D\u7528\u518D\u9010\u6761\u5408\u5E76**\uFF0C\u53EA\u9A8C\u6574\u4F53 + \u6536\u53E3\uFF1A`,
|
|
131
|
+
`1. \`git clone ${r02?.remote ?? "<remote>"} repos/${r02?.id ?? "<id>"}\` \u2192 \`cd repos/${r02?.id ?? "<id>"} && git fetch && git checkout ${feat}\`\uFF08**\u662F\u5DF2\u5B58\u5728\u7684\u5DE5\u5355\u5206\u652F\u3001\u542B\u5404\u90E8\u4EF6\u5168\u90E8\u6539\u52A8**\uFF0C\u4E0D\u662F\u4ECE\u4E3B\u5E72\u65B0\u5EFA\uFF09\u3002\u591A\u4ED3\u5219\u5BF9\u6BCF\u4E2A\u78B0\u8FC7\u7684\u4ED3\u540C\u6837 checkout \`${feat}\`\u3002`,
|
|
132
|
+
`2. **\u9A8C\u6574\u4F53\u80FD\u6784\u5EFA / \u80FD\u8DD1**\uFF08\u8FD9\u624D\u662F\u4F60 owner \u7684\u5224\u65AD\u6D3B\uFF09\uFF1B\u6709\u6B8B\u7559\u95EE\u9898\uFF08\u63A5\u53E3\u6CA1\u5BF9\u9F50 / \u6784\u5EFA\u5931\u8D25 / \u90E8\u4EF6\u8854\u63A5\u5904\u8981\u6536\u5C3E\uFF09\u2192 \u5C31\u5730\u4FEE\u3001\`git commit\`\u3001\`git push origin ${feat}\`\u3002`,
|
|
133
|
+
`3. \`oasis propose ${artifactId} --reason "<\u6536\u53E3\u8BF4\u660E>"\`\uFF08\u7CFB\u7EDF\u4ECE\u5404\u4ED3 \`${feat}\` \u6536\u5168 {\u4ED3\u5E93\u2192\u63D0\u4EA4} = \u5168\u90E8\u4EF6\u6574\u5408\u6001\uFF09\u2192 \`oasis conclude ${artifactId}\`\uFF08conclude \u540E\u9010\u4ED3 gated \u5408\u8FDB\u4E3B\u5E72\uFF09\u3002`,
|
|
134
|
+
``,
|
|
135
|
+
`**\u4F60\u8FD9\u7EA7\u662F\u628A\u5173\u6574\u4F53\u81EA\u6D3D + \u6536\u53E3\u6210\u4EA4\u4ED8\u7248\uFF0C\u4E0D\u662F\u91CD\u65B0\u5B9E\u73B0**\u2014\u2014\u5404\u90E8\u4EF6\u7684\u5B9E\u73B0\u5DF2\u5728\u5B83\u4EEC\u5404\u81EA\u6536\u5C3E\u65F6\u5E76\u8FDB \`${feat}\` \u4E86\u3002**\u522B\u7528 \`oasis integrate\`**\uFF1A\u4EE3\u7801\u6536\u53E3\u5C31\u8D70 \`propose\`\uFF08git-native\uFF09\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
const repoLines = repos.map((r) => ` - \`${r.id}\`\uFF1A${r.remote ?? "<remote>"}\uFF08\u4E3B\u5E72 \`${r.develop}\`\uFF09`);
|
|
139
|
+
const short = (s2) => s2.slice(0, 12);
|
|
140
|
+
const versionLine = (() => {
|
|
141
|
+
if (!(ctx.hasHead && ctx.headExternalRef)) return [];
|
|
142
|
+
const ref2 = ctx.headExternalRef;
|
|
143
|
+
if (ref2.trim().startsWith("{")) {
|
|
144
|
+
try {
|
|
145
|
+
const m2 = JSON.parse(ref2);
|
|
146
|
+
const parts = Object.entries(m2).map(([id, sha2]) => `\`${id}\` @ \`${short(sha2)}\``);
|
|
147
|
+
return [`> **\u5F53\u524D\u7248\u672C**\uFF08\u4F60\u4E0A\u4E00\u7248\uFF0C\u5DF2\u5E76\u5165\u5404\u4ED3\u4E3B\u5E72\uFF09\uFF1A${parts.join("\uFF0C")}\u2014\u2014clone \u4E3B\u5E72\u5373\u5728\u5B83\u4E4B\u4E0A\u6539\uFF0C\u522B\u4ECE\u5934\u5199\u3002`];
|
|
148
|
+
} catch {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return [`> **\u5F53\u524D\u7248\u672C**\uFF08\u4F60\u4E0A\u4E00\u7248\uFF0C\u5DF2\u5E76\u5165\u4E3B\u5E72\uFF09\uFF1A\`${repos[0]?.id ?? "<\u4E3B\u4ED3>"}\` @ \`${short(ref2)}\`\u2014\u2014clone \u4E3B\u5E72\u5373\u5728\u5B83\u4E4B\u4E0A\u6539\uFF0C\u522B\u4ECE\u5934\u5199\u3002`];
|
|
152
|
+
})();
|
|
153
|
+
return [
|
|
154
|
+
`\u4F60\u4EA7\u51FA\u7684\u662F\u9879\u76EE **${ctx.projectName ?? "?"}** \u7684\u4EE3\u7801\u2014\u2014**\u5185\u5BB9\u76F4\u63A5\u6D3B\u5728 git \u4ED3\u5E93\u91CC**\uFF0C\u4F60\u50CF\u5F00\u53D1\u8005\u4E00\u6837\u5728 git \u91CC\u5E72\uFF0C\u4EA7\u7269\u4E0D\u8FDB Oasis \u6863\u6848\u67DC\u3002`,
|
|
155
|
+
``,
|
|
156
|
+
`\u672C\u9879\u76EE\u7684\u4EE3\u7801\u4ED3\u5E93\uFF08\u4F1E\u4ED3\uFF0C\u672C\u673A\u51ED\u8BC1\u5DF2\u914D\u597D\uFF1B**\u53EA\u52A8\u4F60\u9700\u8981\u6539\u7684\uFF0C\u4E0D\u78B0\u7684\u4E0D\u7528 clone**\uFF09\uFF1A`,
|
|
157
|
+
...repoLines,
|
|
158
|
+
`> \u636E\u4F60\u7684**\u4E0A\u6E38\u8F93\u5165**\u5224\u65AD\u672C\u5DE5\u5355\u8BE5\u843D\u5728**\u54EA\u4E2A**\u4ED3\uFF0C\u518D\u5BF9\u7167\u4E0A\u9762\u9879\u76EE\u73B0\u6709\u7684\u4ED3\uFF1A\u9700\u8981\u7684\u4ED3**\u5728\u6E05\u5355\u91CC** \u2192 \u53EA\u5728\u90A3\u4E2A\u4ED3\u91CC\u5E72\uFF1B**\u4E0D\u5728**\uFF08\u9879\u76EE\u6709\u522B\u7684\u4ED3\u3001\u4F46\u6CA1\u6709\u4F60\u9700\u8981\u7684\u90A3\u4E2A\uFF09\u2192 \u522B\u51D1\u5408\u7528\u522B\u7684\u4ED3\uFF0C\u7528 \`oasis gap ${artifactId} --desc "<\u7F3A\u54EA\u4E2A\u4ED3\u53CA\u7528\u9014>"\` \u62A5\u7F3A\u53E3\u3002`,
|
|
159
|
+
...versionLine,
|
|
160
|
+
``,
|
|
161
|
+
`### \u5DE5\u4F5C\u6D41\u7A0B\uFF08git-native\uFF0C\u4F1E\u4ED3\uFF09`,
|
|
162
|
+
`1. \u5BF9**\u6BCF\u4E2A\u4F60\u8981\u6539\u7684\u4ED3\u5E93**\uFF1A\`git clone <remote> repos/<id>\` \u2192 \`cd repos/<id> && git checkout <\u4E3B\u5E72> && git checkout -b ${feat}\``,
|
|
163
|
+
`2. \u57FA\u4E8E \`inputs/\`\uFF08\u4E0A\u6E38\u89C4\u683C\uFF09\u5B9E\u73B0\u6539\u52A8\u2014\u2014clone \u4E0B\u6765\u7684\u4E3B\u5E72\u5DF2\u542B\u6B64\u524D\u5DF2\u5E76\u5165\u7684\u4EE3\u7801\uFF0C**\u5728\u5B83\u4E4B\u4E0A\u6539**`,
|
|
164
|
+
`3. \u6BCF\u4E2A\u6539\u8FC7\u7684\u4ED3\u5E93\uFF1A\u81EA\u67E5\uFF08\u8BED\u6CD5/\u6784\u5EFA/\u80FD\u8DD1\uFF09\uFF0C\`git commit\`\uFF0C\`git push -u origin ${feat}\``,
|
|
165
|
+
`4. \u56DE\u62A5 Oasis\uFF1A\`oasis propose ${artifactId} --reason "<\u4E00\u53E5\u8BDD>"\` \u2192 \`oasis conclude ${artifactId}\``,
|
|
166
|
+
` **\u4E0D\u7528\u62A5 commit sha**\u2014\u2014\u7CFB\u7EDF\u4F1A\u53BB\u5404\u4ED3\u5E93\u7684 \`${feat}\` \u5206\u652F\u81EA\u52A8\u6536\u96C6\u4F60\u7684\u63D0\u4EA4\uFF0C\u62FC\u6210 {\u4ED3\u5E93\u2192\u63D0\u4EA4} \u6E05\u5355\uFF1B\u6CA1\u78B0\u7684\u4ED3\u5E93\uFF08\`${feat}\` \u65E0\u65B0\u63D0\u4EA4\uFF09\u4E0D\u8BA1\u5165\u3002`,
|
|
167
|
+
``,
|
|
168
|
+
`**\u4E0D\u8981\u63A8\u4E3B\u5E72\u3001\u4E0D\u8981\u81EA\u5DF1\u5408\u5E76**\u2014\u2014\u96C6\u6210\u7531\u7CFB\u7EDF\u5728 conclude \u540E\u9010\u4ED3\u628A\u5173\u5408\u5E76\u3002\u7248\u672C\u5386\u53F2 diff \u4F60\u81EA\u5DF1 \`git log -p\` \u5373\u53EF\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
169
|
+
];
|
|
170
|
+
},
|
|
171
|
+
integrateInstructions(ctx) {
|
|
172
|
+
const { artifactId } = ctx;
|
|
173
|
+
const r0 = ctx.repos?.[0];
|
|
174
|
+
const feat = `feat/${slug(artifactId)}`;
|
|
175
|
+
return [
|
|
176
|
+
`\u8FD9\u662F\u4EE3\u7801\u2014\u2014\u5404\u90E8\u4EF6**\u5DF2\u81EA\u884C\u5E76\u5165\u5DE5\u5355\u5206\u652F \`${feat}\`**\uFF08\u6BCF\u4E2A part \u5E72\u5B8C\u81EA\u5DF1 merge \u8FDB\u6765\u3001\u89E3\u4E86\u5404\u81EA\u7684\u51B2\u7A81\uFF09\u3002\u4F60 owner **\u4E0D\u7528\u518D\u9010\u6761\u5408\u5E76**\uFF0C\u53EA\u9A8C\u6574\u4F53 + \u6536\u53E3\uFF1A`,
|
|
177
|
+
`1. \`git clone ${r0?.remote ?? "<remote>"} repos/${r0?.id ?? "<id>"}\` \u2192 \`git checkout ${feat}\`\uFF0C**\u9A8C\u6574\u4F53\u80FD\u6784\u5EFA/\u80FD\u8DD1**\uFF08\u8FD9\u624D\u662F\u4F60 owner \u7684\u5224\u65AD\u6D3B\uFF09\u3002`,
|
|
178
|
+
`2. \u82E5\u6709\u6B8B\u7559\u95EE\u9898\uFF08\u63A5\u53E3\u6CA1\u5BF9\u9F50\u3001\u6784\u5EFA\u5931\u8D25\u3001\u90E8\u4EF6\u8854\u63A5\u5904\u8981\u6536\u5C3E\uFF09\u2192 \u5C31\u5730\u4FEE\u3001\`git commit\`\u3001\`git push origin ${feat}\`\u3002`,
|
|
179
|
+
`3. \`oasis integrate ${artifactId} --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${artifactId}\`\uFF08\u7CFB\u7EDF\u4ECE \`${feat}\` \u6536\u96C6\u6574\u5408\u7248\uFF1Bconclude \u540E\u9010\u4ED3\u540C\u6B65\u8FDB develop\uFF09\u3002`,
|
|
180
|
+
``,
|
|
181
|
+
`**\u4F60\u8FD9\u7EA7\u662F\u628A\u5173\u6574\u4F53\u81EA\u6D3D\u3001\u4E0D\u662F\u91CD\u65B0\u5408\u5E76**\u2014\u2014\u5408\u5E76\u5DF2\u7ECF\u5728\u5404\u90E8\u4EF6\u6536\u5C3E\u65F6\u5404\u81EA\u505A\u5B8C\u4E86\u3002`
|
|
182
|
+
];
|
|
183
|
+
},
|
|
184
|
+
submitInstruction(ctx) {
|
|
185
|
+
const id = ctx.artifactId;
|
|
186
|
+
if (ctx.action === "integrate") {
|
|
187
|
+
return `- \`oasis integrate ${id} --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2014\u2014 **\u6536\u53E3\u4E13\u7528**\uFF1A\u628A\u5DE5\u5355\u5206\u652F\u7684\u6574\u5408\u7248\u843D\u4E3A R\\*\uFF08\u7CFB\u7EDF\u4ECE git \u6536\u96C6\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002**\u7EDD\u4E0D\u8981\u7528 propose/advance \u4EA4\u96C6\u6210**\u3002`;
|
|
188
|
+
}
|
|
189
|
+
if (ctx.isPart) {
|
|
190
|
+
return `- \`oasis propose ${id} --part <\u4F60\u7684\u90E8\u4EF6> --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u4EA7\u51FA\uFF08\u4EE3\u7801\uFF1A\u4F60 push \u4F60\u7684\u5DE5\u4F5C\u5206\u652F\uFF0C\u7CFB\u7EDF\u628A\u5B83\u5E72\u51C0\u5408\u8FDB\u5DE5\u5355\u5206\u652F\u518D\u6536\u96C6\uFF1B\u51B2\u7A81\u4F1A\u6253\u56DE\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002\`--part\` \u5FC5\u987B\u662F\u5206\u914D\u7ED9\u4F60\u7684\u90E8\u4EF6\u540D\u3002\u4EA7\u5B8C\u5373\u53EF\u6536\u5DE5\u3002`;
|
|
191
|
+
}
|
|
192
|
+
return `- \`oasis propose ${id} --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4EA7\u7269\u7684\u65B0\u4E00\u7248\uFF08\u4EE3\u7801\uFF1A\u4F60\u5DF2 push \u5230\u5DE5\u5355\u5206\u652F\uFF0C\u7CFB\u7EDF\u4ECE\u5404\u4ED3\u6536\u96C6 {\u4ED3\u5E93\u2192\u63D0\u4EA4}\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u6539\u4E86\u5565\u3002`;
|
|
193
|
+
},
|
|
194
|
+
collectionStrategy: { kind: "external-git" },
|
|
195
|
+
mergeMode: "external-ff"
|
|
196
|
+
// Phase B:code git-native——part 直接 FF、owner produce 收口(见 §9.1/§9.5)
|
|
197
|
+
};
|
|
198
|
+
mediaHandler = {
|
|
199
|
+
produceInstructions(ctx) {
|
|
200
|
+
const { artifactId } = ctx;
|
|
201
|
+
if (ctx.part !== void 0) {
|
|
202
|
+
return [
|
|
203
|
+
`\u4F60\u4EA7\u51FA\u7684\u662F**\u5A92\u4F53**\u4EA4\u4ED8\u7269\u7684\u4E00\u4E2A\u90E8\u4EF6 \`${ctx.part}\`\uFF08\u89C6\u9891/\u97F3\u9891/\u56FE\u7B49\uFF09\u3002\u628A\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u6210\u54C1\u6587\u4EF6\u5199\u8FDB\u672C\u5730\uFF0C\u7136\u540E**\u53EA\u8FD9\u4E00\u6B65**\uFF1A`,
|
|
204
|
+
`\`oasis propose ${artifactId} --file <\u6210\u54C1\u6587\u4EF6> --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD>"\`\u3002**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D conclude**\uFF0C\u7B49\u5404\u90E8\u4EF6\u9F50\u4E86 owner \u6536\u53E3\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
return [
|
|
208
|
+
ctx.hasHead ? `\u4F60\u7684\u4EA4\u4ED8\u7269\u5728 \`./deliverable/\`\uFF08\u5A92\u4F53\u6210\u54C1\uFF1A\u89C6\u9891/\u97F3\u9891/\u56FE\u7B49\uFF09\u2014\u2014\u5728\u5B83\u57FA\u7840\u4E0A\u66F4\u65B0/\u66FF\u6362\u3002` : `\u4F60\u7684\u4EA4\u4ED8\u7269\u76EE\u5F55\u662F \`./deliverable/\`\uFF08\u5F53\u524D\u4E3A\u7A7A\u2014\u2014\u4EA7\u51FA\u9996\u7248\u6210\u54C1\uFF09\u3002`,
|
|
209
|
+
`\u628A**\u6E32\u67D3/\u5BFC\u51FA\u597D\u7684\u6210\u54C1\u6587\u4EF6**\u653E\u8FDB \`deliverable/\`\uFF08\u6309\u4EA4\u4ED8\u8981\u6C42\u7684\u683C\u5F0F\uFF0C\u5982 mp4/wav/png\uFF1B\u5927\u4E8C\u8FDB\u5236\u76F4\u63A5\u653E\uFF0C\u522B\u585E\u8FDB\u6587\u672C\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
210
|
+
`\`oasis propose ${artifactId} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\` \u2192 \u6574\u4F53\u5B8C\u6574\u4E86\u518D \`oasis conclude ${artifactId}\`\u3002`,
|
|
211
|
+
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\uFF08\u811A\u672C/\u5206\u955C/\u7D20\u6750\u6CA1\u5C31\u7EEA\uFF09\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
212
|
+
];
|
|
213
|
+
},
|
|
214
|
+
integrateInstructions(ctx) {
|
|
215
|
+
const parts = ctx.queuedPartLabels.map((p2) => `\`${p2}\``).join("\u3001") || "\uFF08\u961F\u5217\u4E3A\u7A7A\uFF09";
|
|
216
|
+
return [
|
|
217
|
+
`\u5404\u90E8\u4EF6\u7684\u6210\u54C1\u5728 \`parts/<\u540D>/\`\uFF08${parts}\uFF09\u3002\u628A\u5B83\u4EEC\u6C47\u6210**\u6700\u7EC8\u6210\u54C1**\u653E\u8FDB \`deliverable/\`\uFF08\u6309\u4EA4\u4ED8\u683C\u5F0F\u3001\u987A\u5E8F/\u62FC\u63A5\u6B63\u786E\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
218
|
+
`\`oasis integrate ${ctx.artifactId} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${ctx.artifactId}\`\u3002**\u522B\u4E22\u4EFB\u4F55\u90E8\u4EF6**\u3002`
|
|
219
|
+
];
|
|
220
|
+
},
|
|
221
|
+
submitInstruction: deliverableSubmit,
|
|
222
|
+
collectionStrategy: { kind: "inline" },
|
|
223
|
+
mergeMode: "oasis-queue"
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
37
228
|
// ../core/src/read-model.ts
|
|
38
229
|
function emptyReadModel() {
|
|
39
230
|
return {
|
|
@@ -78,6 +269,7 @@ function fold(model, op) {
|
|
|
78
269
|
workspace: p2.workspace,
|
|
79
270
|
persistence: p2.persistence ?? "temp",
|
|
80
271
|
createdVia: p2.createdVia,
|
|
272
|
+
...p2.isFinalOutput !== void 0 ? { isFinalOutput: p2.isFinalOutput } : {},
|
|
81
273
|
...p2.title !== void 0 ? { title: p2.title } : {},
|
|
82
274
|
...p2.description !== void 0 ? { description: p2.description } : {},
|
|
83
275
|
...p2.docType !== void 0 ? { docType: p2.docType } : {},
|
|
@@ -944,10 +1136,38 @@ function computeCascadeActions(model, schema) {
|
|
|
944
1136
|
}
|
|
945
1137
|
return out;
|
|
946
1138
|
}
|
|
1139
|
+
function advanceableHead(model, schema, id) {
|
|
1140
|
+
if (lifecycleOf(model, id) !== "active") return null;
|
|
1141
|
+
const head = queueOf(model, id)[0];
|
|
1142
|
+
if (!head) return null;
|
|
1143
|
+
if (isStale(model, head)) return null;
|
|
1144
|
+
if (pendingConcludeAttempt(model, id)) return null;
|
|
1145
|
+
const artifact = model.artifacts.get(id);
|
|
1146
|
+
const typeDef = schema.get(artifact.type);
|
|
1147
|
+
const isExternalFF = handlerForType(typeDef?.contentType)?.mergeMode === "external-ff";
|
|
1148
|
+
const eagerFF = head.part === void 0 || (artifact.parts ?? []).length <= 1 || isExternalFF;
|
|
1149
|
+
if (!eagerFF) return null;
|
|
1150
|
+
const proposerIsAgent = head.author.startsWith("actor:agent:");
|
|
1151
|
+
const requiresHumanReview = proposerIsAgent && (head.resolves !== void 0 ? head.resolves.some((annId) => {
|
|
1152
|
+
const a = model.annotations.get(annId);
|
|
1153
|
+
return a !== void 0 && isHumanChangeRequest(a);
|
|
1154
|
+
}) : hasOpenHumanChangeRequest(model, id));
|
|
1155
|
+
if (requiresHumanReview) return null;
|
|
1156
|
+
return head;
|
|
1157
|
+
}
|
|
1158
|
+
function computeAdvanceableRevisions(model, schema) {
|
|
1159
|
+
const out = [];
|
|
1160
|
+
for (const a of model.artifacts.values()) {
|
|
1161
|
+
const rev = advanceableHead(model, schema, a.id);
|
|
1162
|
+
if (rev) out.push({ artifactId: a.id, revisionId: rev.id });
|
|
1163
|
+
}
|
|
1164
|
+
return out;
|
|
1165
|
+
}
|
|
947
1166
|
var CorruptLogError, STRUCTURAL_OP_KINDS, ROUND_LIMIT_MARKER, PENDING_ROLE_PREFIX, PENDING_UNASSIGNED;
|
|
948
1167
|
var init_read_model = __esm({
|
|
949
1168
|
"../core/src/read-model.ts"() {
|
|
950
1169
|
"use strict";
|
|
1170
|
+
init_content_type_handler();
|
|
951
1171
|
CorruptLogError = class extends Error {
|
|
952
1172
|
name = "CorruptLogError";
|
|
953
1173
|
constructor(op, detail) {
|
|
@@ -1036,197 +1256,6 @@ var init_content_handler = __esm({
|
|
|
1036
1256
|
}
|
|
1037
1257
|
});
|
|
1038
1258
|
|
|
1039
|
-
// ../core/src/content-type-handler.ts
|
|
1040
|
-
function deliverableSubmit(ctx) {
|
|
1041
|
-
const id = ctx.artifactId;
|
|
1042
|
-
if (ctx.action === "integrate") {
|
|
1043
|
-
return `- \`oasis integrate ${id} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2014\u2014 **\u6536\u53E3\u4E13\u7528**\uFF1A\u628A\u4F60\u5728 deliverable/ \u5408\u6210\u7684\u6574\u5408\u7248\u843D\u4E3A\u65B0 head\uFF08\u7CFB\u7EDF\u5185\u90E8\u4F1A\u628A\u961F\u5217\u91CC\u5176\u4F59\u5F85\u843D\u7248\u672C\u4E00\u5E76\u5E76\u8FDB\u6765\uFF09\u3002**\u7EDD\u4E0D\u8981\u7528 propose / advance \u4EA4\u96C6\u6210**\uFF08\u90A3\u4F1A\u628A\u96C6\u6210\u5F53\u6210\u53C8\u4E00\u4E2A\u5E76\u5217\u7248\u672C\u3001\u843D\u9519\u7248\u672C\uFF09\u3002`;
|
|
1044
|
-
}
|
|
1045
|
-
if (ctx.isPart) {
|
|
1046
|
-
return `- \`oasis propose ${id} --part <\u4F60\u7684\u90E8\u4EF6> --file <\u6587\u4EF6> --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u4EA7\u51FA\u3002\`--part\` \u5FC5\u987B\u662F\u5206\u914D\u7ED9\u4F60\u7684\u90A3\u4E2A\u90E8\u4EF6\u540D\uFF1B\`--file\` \u6307\u5411\u4F60\u5199\u597D\u7684\u5185\u5BB9\u6587\u4EF6\uFF08\u90E8\u4EF6\u662F\u72EC\u7ACB\u788E\u7247\uFF0C\u5199\u4F60\u81EA\u5DF1\u7684\uFF09\uFF1B\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u505A\u4E86\u5565\u3002\u4EA7\u5B8C\u5373\u53EF\u6536\u5DE5\uFF0C\u96C6\u6210\u7531 owner \u505A\u3002`;
|
|
1047
|
-
}
|
|
1048
|
-
return `- \`oasis propose ${id} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4EA7\u7269\u7684\u65B0\u4E00\u7248\u3002\`--from-dir\` \u6307\u5411\u4F60\u7F16\u8F91\u540E\u7684 deliverable/\uFF08\u7CFB\u7EDF\u636E\u76EE\u5F55\u7B97\u8FD9\u7248\u3001\u5E76\u548C\u4E0A\u4E00\u7248 diff\uFF09\uFF1B\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u6539\u4E86\u5565\uFF08\u7ED9\u8BC4\u5BA1/\u540E\u4EBA\u770B\uFF0C\u4E0D\u7528\u50CF git commit \u90A3\u4E48\u7EC6\uFF09\u3002`;
|
|
1049
|
-
}
|
|
1050
|
-
function handlerFor(repos, contentType) {
|
|
1051
|
-
if (repos?.some((r) => r.remote)) return codeHandler;
|
|
1052
|
-
if (contentType === "media") return mediaHandler;
|
|
1053
|
-
return textHandler;
|
|
1054
|
-
}
|
|
1055
|
-
function handlerForType(contentType) {
|
|
1056
|
-
if (contentType === void 0) return void 0;
|
|
1057
|
-
if (contentType === "code") return codeHandler;
|
|
1058
|
-
if (contentType === "media") return mediaHandler;
|
|
1059
|
-
return textHandler;
|
|
1060
|
-
}
|
|
1061
|
-
var slug, textHandler, codeHandler, mediaHandler;
|
|
1062
|
-
var init_content_type_handler = __esm({
|
|
1063
|
-
"../core/src/content-type-handler.ts"() {
|
|
1064
|
-
"use strict";
|
|
1065
|
-
slug = (id) => id.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
1066
|
-
textHandler = {
|
|
1067
|
-
produceInstructions(ctx) {
|
|
1068
|
-
const { artifactId } = ctx;
|
|
1069
|
-
if (ctx.part !== void 0) {
|
|
1070
|
-
return [
|
|
1071
|
-
`\u628A\u4F60\u8FD9\u4E2A\u90E8\u4EF6 \`${ctx.part}\` \u7684\u5B8C\u6574\u5185\u5BB9\u5199\u8FDB\u672C\u5730\u6587\u4EF6\uFF0C\u7136\u540E**\u53EA\u6267\u884C\u8FD9\u4E00\u6B65**\uFF1A`,
|
|
1072
|
-
`\`oasis propose ${artifactId} --file <\u6587\u4EF6> --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\`\u3002`,
|
|
1073
|
-
`**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D\u8981 advance\u3001\u4E0D\u8981 conclude**\u3002\u7B49\u6240\u6709\u5144\u5F1F\u90E8\u4EF6\u90FD\u4EA7\u51FA\u540E\uFF0C\u7CFB\u7EDF\u4F1A\u628A\u5404\u90E8\u4EF6\u96C6\u6210\u6210\u4E00\u7248\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`,
|
|
1074
|
-
``,
|
|
1075
|
-
`> \u26A0 \u5927\u6587\u4EF6\u52A1\u5FC5**\u589E\u91CF\u5199**\uFF08Write \u9AA8\u67B6 \u2192 Edit \u5206\u6B21\u8FFD\u52A0\uFF09\uFF0C\u522B\u4E00\u6B21\u6027\u5410\u6574\u4E2A\u5927\u6587\u4EF6\uFF08\u6709\u8F93\u51FA token \u4E0A\u9650\uFF09\u3002`
|
|
1076
|
-
];
|
|
1077
|
-
}
|
|
1078
|
-
if (ctx.unionInto !== void 0) {
|
|
1079
|
-
return [
|
|
1080
|
-
`\u4F60\u4EA7\u51FA\u7684\u662F**\u6574\u4F53\u4EA4\u4ED8\u7269\u7684\u4E00\u4E2A\u6A21\u5757**\uFF0C\u4F1A\u88AB\u673A\u68B0\u5E76\u5165 \`${ctx.unionInto}\`\uFF08\u6309\u6587\u4EF6\u540D\u5408\u5E76\uFF09\u3002`,
|
|
1081
|
-
`\u628A\u4F60\u8D1F\u8D23\u7684\u6587\u4EF6\u5199\u8FDB\u4E00\u4E2A**\u76EE\u5F55**\uFF08\u6587\u4EF6\u540D\u5373\u5B83\u5728\u6700\u7EC8\u4EA4\u4ED8\u7269\u91CC\u7684\u8DEF\u5F84\uFF0C\u5982 \`combat.js\`\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
1082
|
-
`\`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\` \u2192 \`oasis conclude ${artifactId}\`\u3002`,
|
|
1083
|
-
`**\u53EA\u5199\u4F60\u8FD9\u4E2A\u6A21\u5757\u7684\u6587\u4EF6\uFF0C\u4E0D\u8981\u78B0\u522B\u7684\u6A21\u5757\u7684\u6587\u4EF6**\uFF08\u540C\u540D\u4F1A\u8986\u76D6\u522B\u4EBA\u7684\uFF09\u3002\u4E25\u683C\u9075\u5B88\u4E0A\u6E38 tech-design \u7EA6\u5B9A\u7684\u63A5\u53E3/\u5168\u5C40\u547D\u540D\uFF0C\u6A21\u5757\u95F4\u624D\u80FD\u62FC\u5F97\u8D77\u6765\u3002`,
|
|
1084
|
-
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1085
|
-
];
|
|
1086
|
-
}
|
|
1087
|
-
return [
|
|
1088
|
-
ctx.hasHead ? `\u4F60\u7684\u4EA4\u4ED8\u7269\u5728 \`./deliverable/\` \u2014\u2014 \u91CC\u9762\u5DF2\u662F**\u5F53\u524D\u7248\u672C\u7684\u5B8C\u6574\u5185\u5BB9**\uFF0C\u76F4\u63A5\u5728\u5B83\u4E0A\u9762\u589E\u5220\u6539\u3002` : `\u4F60\u7684\u4EA4\u4ED8\u7269\u76EE\u5F55\u662F \`./deliverable/\`\uFF08\u5F53\u524D\u4E3A\u7A7A\u2014\u2014\u8FD9\u662F\u5168\u65B0\u4EA7\u7269\uFF0C\u5728\u5176\u4E2D\u4EA7\u51FA\u9996\u7248\u5185\u5BB9\uFF09\u3002`,
|
|
1089
|
-
`- \u6700\u7EC8\u4EA7\u7269\u53EA\u653E \`deliverable/\`\uFF1B\u4E34\u65F6\u6587\u4EF6\uFF08\u8349\u7A3F/\u811A\u672C/\u5B9E\u9A8C\uFF09\u653E\u5230**\u522B\u5904**\uFF0C\u522B\u7559\u5728 \`deliverable/\` \u91CC\u3002`,
|
|
1090
|
-
`- \u6539\u597D\u540E\u6574\u76EE\u5F55\u63D0\u4EA4\uFF1A\`oasis propose ${artifactId} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\``,
|
|
1091
|
-
` \u2192 \u7CFB\u7EDF\u81EA\u52A8\u843D\u5730\u4E3A\u65B0\u7248\u672C\uFF08**\u65E0\u9700 advance**\uFF09\uFF1B\u6574\u4E2A\u4EA4\u4ED8\u7269**\u771F\u6B63\u5B8C\u6574**\u4E86\u518D \`oasis conclude ${artifactId}\`\u3002`,
|
|
1092
|
-
...ctx.hasHead ? [`\uFF08\`deliverable/\` \u672C\u5C31\u662F head \u7684\u5B8C\u6574\u526F\u672C\u2014\u2014\u4F60\u4EA4\u7684\u4E00\u5B9A\u662F\u5B8C\u6574\u7248\uFF0C\u4E0D\u4F1A\u4E22\u5DF2\u6709\u5185\u5BB9\u3002\uFF09`] : [],
|
|
1093
|
-
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1094
|
-
];
|
|
1095
|
-
},
|
|
1096
|
-
integrateInstructions(ctx) {
|
|
1097
|
-
const parts = ctx.queuedPartLabels.map((p2) => `\`${p2}\``).join("\u3001") || "\uFF08\u961F\u5217\u4E3A\u7A7A\uFF09";
|
|
1098
|
-
return [
|
|
1099
|
-
`\u5404\u90E8\u4EF6\u4ECE**\u5171\u540C\u7956\u5148 H** \u5206\u5934\u4EA7\u51FA\u3001\u5404\u6539\u5404\u5757\uFF1A\u6BCF\u6761\u5185\u5BB9\u5728 \`parts/<\u540D>/CONTENT.md\`\uFF08\u6216\u5176\u5C55\u5F00\u6587\u4EF6\uFF09\u91CC\uFF08${parts}\uFF09\uFF0CH \u7684\u5185\u5BB9\u5728 \`deliverable/\`\uFF08\u4ECE\u96F6\u5206\u89E3\u5219\u4E3A\u7A7A\uFF09\u3002`,
|
|
1100
|
-
`\u628A\u5B83\u4EEC\u5408\u6210\u4E00\u4E2A\u5B8C\u6574\u7684\u6574\u5408\u7248**\u5C31\u5730\u5199\u8FDB \`deliverable/\`**\u2014\u2014**\u4EE5 H \u4E3A\u5E95**\u3001\u628A\u5404\u90E8\u4EF6\u6539\u52A8**\u5168\u5E76\u8FDB\u6765**\uFF08\u5355\u6587\u4EF6 \`deliverable/CONTENT.md\`\uFF0C\u591A\u6587\u4EF6\u94FA\u6210\u591A\u4E2A\u6587\u4EF6\uFF1B\u5927\u6587\u4EF6\u589E\u91CF\u5199\uFF1AWrite \u9AA8\u67B6 \u2192 Edit \u8FFD\u52A0\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
1101
|
-
`\`oasis integrate ${ctx.artifactId} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${ctx.artifactId}\`\u3002`,
|
|
1102
|
-
``,
|
|
1103
|
-
`**\u5FE0\u5B9E\u5408\u5E76\u3001\u522B\u4E22\u4EFB\u4F55\u90E8\u4EF6**\uFF1B\u63A5\u53E3/\u547D\u540D\u5BF9\u4E0D\u9F50\u5C31\u6309\u4E0A\u6E38\u89C4\u683C\u6821\u6B63\uFF0C\u8BA9 N \u4E2A\u90E8\u4EF6\u62FC\u6210\u4E00\u4E2A\u81EA\u6D3D\u6574\u4F53\u3002`
|
|
1104
|
-
];
|
|
1105
|
-
},
|
|
1106
|
-
submitInstruction: deliverableSubmit,
|
|
1107
|
-
collectionStrategy: { kind: "inline" },
|
|
1108
|
-
mergeMode: "oasis-queue"
|
|
1109
|
-
};
|
|
1110
|
-
codeHandler = {
|
|
1111
|
-
produceInstructions(ctx) {
|
|
1112
|
-
const { artifactId } = ctx;
|
|
1113
|
-
const repos = ctx.repos ?? [];
|
|
1114
|
-
const r0 = repos[0];
|
|
1115
|
-
if (ctx.part !== void 0) {
|
|
1116
|
-
const work = `feat/${slug(artifactId)}__${slug(ctx.part)}`;
|
|
1117
|
-
const feat2 = `feat/${slug(artifactId)}`;
|
|
1118
|
-
const dev = r0?.develop ?? "develop";
|
|
1119
|
-
return [
|
|
1120
|
-
`\u4F60\u4EA7\u51FA\u7684\u662F\u9879\u76EE **${ctx.projectName ?? "?"}** \u7684\u4EE3\u7801\u3001\u4E14\u53EA\u662F\u90E8\u4EF6 \`${ctx.part}\`\u2014\u2014\u5185\u5BB9\u6D3B\u5728 git \u91CC\u3002\u4F60**\u53EA\u7BA1\u4EA7\u51FA\u4F60\u8FD9\u5757\u3001push \u4F60\u81EA\u5DF1\u7684\u5DE5\u4F5C\u5206\u652F**\uFF1B\`oasis propose\` \u65F6**\u7CFB\u7EDF\u4F1A\u628A\u5B83\u5E72\u51C0\u5408\u8FDB\u5DE5\u5355\u5206\u652F \`${feat2}\`**\uFF08\u4E0D\u7528\u4F60\u624B\u52A8\u5408\u3001\u4E5F\u4E0D\u7528\u7B49 owner \u5408\uFF09\u3002`,
|
|
1121
|
-
`1. \`git clone ${r0?.remote ?? "<remote>"} repos/${r0?.id ?? "<id>"}\` \u2192 \`cd repos/${r0?.id ?? "<id>"}\` \u2192 \u4ECE\u4E3B\u5E72\u8D77\u4F60\u7684\u5DE5\u4F5C\u5206\u652F\uFF1A\`git checkout ${dev} && git checkout -b ${work}\``,
|
|
1122
|
-
`2. \u5B9E\u73B0\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u6539\u52A8\uFF08\u4E25\u5B88\u4E0A\u6E38\u63A5\u53E3\u7EA6\u5B9A\uFF09\u3001\u81EA\u67E5\u80FD\u6784\u5EFA/\u80FD\u8DD1\u3001\`git commit\``,
|
|
1123
|
-
`3. **\u53EA\u63A8\u4F60\u81EA\u5DF1\u7684\u5DE5\u4F5C\u5206\u652F**\uFF1A\`git push -u origin ${work}\`\uFF08**\u522B\u78B0 \`${feat2}\`**\u2014\u2014\u5408\u5E76\u4EA4\u7ED9\u7CFB\u7EDF\uFF09`,
|
|
1124
|
-
`4. \u56DE\u62A5\uFF1A\`oasis propose ${artifactId} --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD>"\`\uFF08\u7CFB\u7EDF\u628A \`${work}\` \u5E72\u51C0\u5408\u8FDB \`${feat2}\` \u518D\u6536\u96C6\uFF1B**\u82E5\u4E0E \`${feat2}\` \u51B2\u7A81\u4F1A\u5F53\u573A\u6253\u56DE**\u2014\u2014\u6309\u63D0\u793A \`git fetch && git rebase origin/${feat2}\` \u89E3\u5B8C\u51B2\u7A81\u3001\`git push -f origin ${work}\` \u540E\u91CD\u65B0 propose\uFF09`,
|
|
1125
|
-
`**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D conclude**\u3002\u5404\u90E8\u4EF6\u90FD\u5E76\u5B8C\u540E\u7531 owner \u9A8C\u6574\u4F53\u6536\u53E3\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1126
|
-
];
|
|
1127
|
-
}
|
|
1128
|
-
const feat = `feat/${slug(artifactId)}`;
|
|
1129
|
-
if (ctx.isFinalize) {
|
|
1130
|
-
const r02 = repos[0];
|
|
1131
|
-
return [
|
|
1132
|
-
`\u4F60\u662F **${ctx.projectName ?? "?"}** \u4EE3\u7801\u4EA4\u4ED8\u7269\u7684 owner\uFF0C\u6765**\u6536\u53E3**\uFF1A\u5404\u90E8\u4EF6\u5DF2\u5404\u81EA\u5E76\u5165**\u5DE5\u5355\u5206\u652F \`${feat}\`**\uFF08\u6BCF\u4E2A part \u5E72\u5B8C\u81EA\u5DF1 merge \u8FDB\u6765\u3001\u89E3\u4E86\u5404\u81EA\u51B2\u7A81\uFF09\u3002\u4F60**\u4E0D\u7528\u518D\u9010\u6761\u5408\u5E76**\uFF0C\u53EA\u9A8C\u6574\u4F53 + \u6536\u53E3\uFF1A`,
|
|
1133
|
-
`1. \`git clone ${r02?.remote ?? "<remote>"} repos/${r02?.id ?? "<id>"}\` \u2192 \`cd repos/${r02?.id ?? "<id>"} && git fetch && git checkout ${feat}\`\uFF08**\u662F\u5DF2\u5B58\u5728\u7684\u5DE5\u5355\u5206\u652F\u3001\u542B\u5404\u90E8\u4EF6\u5168\u90E8\u6539\u52A8**\uFF0C\u4E0D\u662F\u4ECE\u4E3B\u5E72\u65B0\u5EFA\uFF09\u3002\u591A\u4ED3\u5219\u5BF9\u6BCF\u4E2A\u78B0\u8FC7\u7684\u4ED3\u540C\u6837 checkout \`${feat}\`\u3002`,
|
|
1134
|
-
`2. **\u9A8C\u6574\u4F53\u80FD\u6784\u5EFA / \u80FD\u8DD1**\uFF08\u8FD9\u624D\u662F\u4F60 owner \u7684\u5224\u65AD\u6D3B\uFF09\uFF1B\u6709\u6B8B\u7559\u95EE\u9898\uFF08\u63A5\u53E3\u6CA1\u5BF9\u9F50 / \u6784\u5EFA\u5931\u8D25 / \u90E8\u4EF6\u8854\u63A5\u5904\u8981\u6536\u5C3E\uFF09\u2192 \u5C31\u5730\u4FEE\u3001\`git commit\`\u3001\`git push origin ${feat}\`\u3002`,
|
|
1135
|
-
`3. \`oasis propose ${artifactId} --reason "<\u6536\u53E3\u8BF4\u660E>"\`\uFF08\u7CFB\u7EDF\u4ECE\u5404\u4ED3 \`${feat}\` \u6536\u5168 {\u4ED3\u5E93\u2192\u63D0\u4EA4} = \u5168\u90E8\u4EF6\u6574\u5408\u6001\uFF09\u2192 \`oasis conclude ${artifactId}\`\uFF08conclude \u540E\u9010\u4ED3 gated \u5408\u8FDB\u4E3B\u5E72\uFF09\u3002`,
|
|
1136
|
-
``,
|
|
1137
|
-
`**\u4F60\u8FD9\u7EA7\u662F\u628A\u5173\u6574\u4F53\u81EA\u6D3D + \u6536\u53E3\u6210\u4EA4\u4ED8\u7248\uFF0C\u4E0D\u662F\u91CD\u65B0\u5B9E\u73B0**\u2014\u2014\u5404\u90E8\u4EF6\u7684\u5B9E\u73B0\u5DF2\u5728\u5B83\u4EEC\u5404\u81EA\u6536\u5C3E\u65F6\u5E76\u8FDB \`${feat}\` \u4E86\u3002**\u522B\u7528 \`oasis integrate\`**\uFF1A\u4EE3\u7801\u6536\u53E3\u5C31\u8D70 \`propose\`\uFF08git-native\uFF09\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1138
|
-
];
|
|
1139
|
-
}
|
|
1140
|
-
const repoLines = repos.map((r) => ` - \`${r.id}\`\uFF1A${r.remote ?? "<remote>"}\uFF08\u4E3B\u5E72 \`${r.develop}\`\uFF09`);
|
|
1141
|
-
const short = (s2) => s2.slice(0, 12);
|
|
1142
|
-
const versionLine = (() => {
|
|
1143
|
-
if (!(ctx.hasHead && ctx.headExternalRef)) return [];
|
|
1144
|
-
const ref2 = ctx.headExternalRef;
|
|
1145
|
-
if (ref2.trim().startsWith("{")) {
|
|
1146
|
-
try {
|
|
1147
|
-
const m2 = JSON.parse(ref2);
|
|
1148
|
-
const parts = Object.entries(m2).map(([id, sha2]) => `\`${id}\` @ \`${short(sha2)}\``);
|
|
1149
|
-
return [`> **\u5F53\u524D\u7248\u672C**\uFF08\u4F60\u4E0A\u4E00\u7248\uFF0C\u5DF2\u5E76\u5165\u5404\u4ED3\u4E3B\u5E72\uFF09\uFF1A${parts.join("\uFF0C")}\u2014\u2014clone \u4E3B\u5E72\u5373\u5728\u5B83\u4E4B\u4E0A\u6539\uFF0C\u522B\u4ECE\u5934\u5199\u3002`];
|
|
1150
|
-
} catch {
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
return [`> **\u5F53\u524D\u7248\u672C**\uFF08\u4F60\u4E0A\u4E00\u7248\uFF0C\u5DF2\u5E76\u5165\u4E3B\u5E72\uFF09\uFF1A\`${repos[0]?.id ?? "<\u4E3B\u4ED3>"}\` @ \`${short(ref2)}\`\u2014\u2014clone \u4E3B\u5E72\u5373\u5728\u5B83\u4E4B\u4E0A\u6539\uFF0C\u522B\u4ECE\u5934\u5199\u3002`];
|
|
1154
|
-
})();
|
|
1155
|
-
return [
|
|
1156
|
-
`\u4F60\u4EA7\u51FA\u7684\u662F\u9879\u76EE **${ctx.projectName ?? "?"}** \u7684\u4EE3\u7801\u2014\u2014**\u5185\u5BB9\u76F4\u63A5\u6D3B\u5728 git \u4ED3\u5E93\u91CC**\uFF0C\u4F60\u50CF\u5F00\u53D1\u8005\u4E00\u6837\u5728 git \u91CC\u5E72\uFF0C\u4EA7\u7269\u4E0D\u8FDB Oasis \u6863\u6848\u67DC\u3002`,
|
|
1157
|
-
``,
|
|
1158
|
-
`\u672C\u9879\u76EE\u7684\u4EE3\u7801\u4ED3\u5E93\uFF08\u4F1E\u4ED3\uFF0C\u672C\u673A\u51ED\u8BC1\u5DF2\u914D\u597D\uFF1B**\u53EA\u52A8\u4F60\u9700\u8981\u6539\u7684\uFF0C\u4E0D\u78B0\u7684\u4E0D\u7528 clone**\uFF09\uFF1A`,
|
|
1159
|
-
...repoLines,
|
|
1160
|
-
`> \u636E\u4F60\u7684**\u4E0A\u6E38\u8F93\u5165**\u5224\u65AD\u672C\u5DE5\u5355\u8BE5\u843D\u5728**\u54EA\u4E2A**\u4ED3\uFF0C\u518D\u5BF9\u7167\u4E0A\u9762\u9879\u76EE\u73B0\u6709\u7684\u4ED3\uFF1A\u9700\u8981\u7684\u4ED3**\u5728\u6E05\u5355\u91CC** \u2192 \u53EA\u5728\u90A3\u4E2A\u4ED3\u91CC\u5E72\uFF1B**\u4E0D\u5728**\uFF08\u9879\u76EE\u6709\u522B\u7684\u4ED3\u3001\u4F46\u6CA1\u6709\u4F60\u9700\u8981\u7684\u90A3\u4E2A\uFF09\u2192 \u522B\u51D1\u5408\u7528\u522B\u7684\u4ED3\uFF0C\u7528 \`oasis gap ${artifactId} --desc "<\u7F3A\u54EA\u4E2A\u4ED3\u53CA\u7528\u9014>"\` \u62A5\u7F3A\u53E3\u3002`,
|
|
1161
|
-
...versionLine,
|
|
1162
|
-
``,
|
|
1163
|
-
`### \u5DE5\u4F5C\u6D41\u7A0B\uFF08git-native\uFF0C\u4F1E\u4ED3\uFF09`,
|
|
1164
|
-
`1. \u5BF9**\u6BCF\u4E2A\u4F60\u8981\u6539\u7684\u4ED3\u5E93**\uFF1A\`git clone <remote> repos/<id>\` \u2192 \`cd repos/<id> && git checkout <\u4E3B\u5E72> && git checkout -b ${feat}\``,
|
|
1165
|
-
`2. \u57FA\u4E8E \`inputs/\`\uFF08\u4E0A\u6E38\u89C4\u683C\uFF09\u5B9E\u73B0\u6539\u52A8\u2014\u2014clone \u4E0B\u6765\u7684\u4E3B\u5E72\u5DF2\u542B\u6B64\u524D\u5DF2\u5E76\u5165\u7684\u4EE3\u7801\uFF0C**\u5728\u5B83\u4E4B\u4E0A\u6539**`,
|
|
1166
|
-
`3. \u6BCF\u4E2A\u6539\u8FC7\u7684\u4ED3\u5E93\uFF1A\u81EA\u67E5\uFF08\u8BED\u6CD5/\u6784\u5EFA/\u80FD\u8DD1\uFF09\uFF0C\`git commit\`\uFF0C\`git push -u origin ${feat}\``,
|
|
1167
|
-
`4. \u56DE\u62A5 Oasis\uFF1A\`oasis propose ${artifactId} --reason "<\u4E00\u53E5\u8BDD>"\` \u2192 \`oasis conclude ${artifactId}\``,
|
|
1168
|
-
` **\u4E0D\u7528\u62A5 commit sha**\u2014\u2014\u7CFB\u7EDF\u4F1A\u53BB\u5404\u4ED3\u5E93\u7684 \`${feat}\` \u5206\u652F\u81EA\u52A8\u6536\u96C6\u4F60\u7684\u63D0\u4EA4\uFF0C\u62FC\u6210 {\u4ED3\u5E93\u2192\u63D0\u4EA4} \u6E05\u5355\uFF1B\u6CA1\u78B0\u7684\u4ED3\u5E93\uFF08\`${feat}\` \u65E0\u65B0\u63D0\u4EA4\uFF09\u4E0D\u8BA1\u5165\u3002`,
|
|
1169
|
-
``,
|
|
1170
|
-
`**\u4E0D\u8981\u63A8\u4E3B\u5E72\u3001\u4E0D\u8981\u81EA\u5DF1\u5408\u5E76**\u2014\u2014\u96C6\u6210\u7531\u7CFB\u7EDF\u5728 conclude \u540E\u9010\u4ED3\u628A\u5173\u5408\u5E76\u3002\u7248\u672C\u5386\u53F2 diff \u4F60\u81EA\u5DF1 \`git log -p\` \u5373\u53EF\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1171
|
-
];
|
|
1172
|
-
},
|
|
1173
|
-
integrateInstructions(ctx) {
|
|
1174
|
-
const { artifactId } = ctx;
|
|
1175
|
-
const r0 = ctx.repos?.[0];
|
|
1176
|
-
const feat = `feat/${slug(artifactId)}`;
|
|
1177
|
-
return [
|
|
1178
|
-
`\u8FD9\u662F\u4EE3\u7801\u2014\u2014\u5404\u90E8\u4EF6**\u5DF2\u81EA\u884C\u5E76\u5165\u5DE5\u5355\u5206\u652F \`${feat}\`**\uFF08\u6BCF\u4E2A part \u5E72\u5B8C\u81EA\u5DF1 merge \u8FDB\u6765\u3001\u89E3\u4E86\u5404\u81EA\u7684\u51B2\u7A81\uFF09\u3002\u4F60 owner **\u4E0D\u7528\u518D\u9010\u6761\u5408\u5E76**\uFF0C\u53EA\u9A8C\u6574\u4F53 + \u6536\u53E3\uFF1A`,
|
|
1179
|
-
`1. \`git clone ${r0?.remote ?? "<remote>"} repos/${r0?.id ?? "<id>"}\` \u2192 \`git checkout ${feat}\`\uFF0C**\u9A8C\u6574\u4F53\u80FD\u6784\u5EFA/\u80FD\u8DD1**\uFF08\u8FD9\u624D\u662F\u4F60 owner \u7684\u5224\u65AD\u6D3B\uFF09\u3002`,
|
|
1180
|
-
`2. \u82E5\u6709\u6B8B\u7559\u95EE\u9898\uFF08\u63A5\u53E3\u6CA1\u5BF9\u9F50\u3001\u6784\u5EFA\u5931\u8D25\u3001\u90E8\u4EF6\u8854\u63A5\u5904\u8981\u6536\u5C3E\uFF09\u2192 \u5C31\u5730\u4FEE\u3001\`git commit\`\u3001\`git push origin ${feat}\`\u3002`,
|
|
1181
|
-
`3. \`oasis integrate ${artifactId} --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${artifactId}\`\uFF08\u7CFB\u7EDF\u4ECE \`${feat}\` \u6536\u96C6\u6574\u5408\u7248\uFF1Bconclude \u540E\u9010\u4ED3\u540C\u6B65\u8FDB develop\uFF09\u3002`,
|
|
1182
|
-
``,
|
|
1183
|
-
`**\u4F60\u8FD9\u7EA7\u662F\u628A\u5173\u6574\u4F53\u81EA\u6D3D\u3001\u4E0D\u662F\u91CD\u65B0\u5408\u5E76**\u2014\u2014\u5408\u5E76\u5DF2\u7ECF\u5728\u5404\u90E8\u4EF6\u6536\u5C3E\u65F6\u5404\u81EA\u505A\u5B8C\u4E86\u3002`
|
|
1184
|
-
];
|
|
1185
|
-
},
|
|
1186
|
-
submitInstruction(ctx) {
|
|
1187
|
-
const id = ctx.artifactId;
|
|
1188
|
-
if (ctx.action === "integrate") {
|
|
1189
|
-
return `- \`oasis integrate ${id} --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2014\u2014 **\u6536\u53E3\u4E13\u7528**\uFF1A\u628A\u5DE5\u5355\u5206\u652F\u7684\u6574\u5408\u7248\u843D\u4E3A R\\*\uFF08\u7CFB\u7EDF\u4ECE git \u6536\u96C6\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002**\u7EDD\u4E0D\u8981\u7528 propose/advance \u4EA4\u96C6\u6210**\u3002`;
|
|
1190
|
-
}
|
|
1191
|
-
if (ctx.isPart) {
|
|
1192
|
-
return `- \`oasis propose ${id} --part <\u4F60\u7684\u90E8\u4EF6> --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u4EA7\u51FA\uFF08\u4EE3\u7801\uFF1A\u4F60 push \u4F60\u7684\u5DE5\u4F5C\u5206\u652F\uFF0C\u7CFB\u7EDF\u628A\u5B83\u5E72\u51C0\u5408\u8FDB\u5DE5\u5355\u5206\u652F\u518D\u6536\u96C6\uFF1B\u51B2\u7A81\u4F1A\u6253\u56DE\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002\`--part\` \u5FC5\u987B\u662F\u5206\u914D\u7ED9\u4F60\u7684\u90E8\u4EF6\u540D\u3002\u4EA7\u5B8C\u5373\u53EF\u6536\u5DE5\u3002`;
|
|
1193
|
-
}
|
|
1194
|
-
return `- \`oasis propose ${id} --reason "<\u4E00\u53E5\u8BDD>"\` \u2014\u2014 \u63D0\u4EA4\u4EA7\u7269\u7684\u65B0\u4E00\u7248\uFF08\u4EE3\u7801\uFF1A\u4F60\u5DF2 push \u5230\u5DE5\u5355\u5206\u652F\uFF0C\u7CFB\u7EDF\u4ECE\u5404\u4ED3\u6536\u96C6 {\u4ED3\u5E93\u2192\u63D0\u4EA4}\uFF1B\u89C1\u300C\u600E\u4E48\u63D0\u4EA4\u300D\uFF09\u3002\`--reason\` \u4E00\u53E5\u8BDD\u8BF4\u6E05\u6539\u4E86\u5565\u3002`;
|
|
1195
|
-
},
|
|
1196
|
-
collectionStrategy: { kind: "external-git" },
|
|
1197
|
-
mergeMode: "external-ff"
|
|
1198
|
-
// Phase B:code git-native——part 直接 FF、owner produce 收口(见 §9.1/§9.5)
|
|
1199
|
-
};
|
|
1200
|
-
mediaHandler = {
|
|
1201
|
-
produceInstructions(ctx) {
|
|
1202
|
-
const { artifactId } = ctx;
|
|
1203
|
-
if (ctx.part !== void 0) {
|
|
1204
|
-
return [
|
|
1205
|
-
`\u4F60\u4EA7\u51FA\u7684\u662F**\u5A92\u4F53**\u4EA4\u4ED8\u7269\u7684\u4E00\u4E2A\u90E8\u4EF6 \`${ctx.part}\`\uFF08\u89C6\u9891/\u97F3\u9891/\u56FE\u7B49\uFF09\u3002\u628A\u4F60\u8FD9\u4E2A\u90E8\u4EF6\u7684\u6210\u54C1\u6587\u4EF6\u5199\u8FDB\u672C\u5730\uFF0C\u7136\u540E**\u53EA\u8FD9\u4E00\u6B65**\uFF1A`,
|
|
1206
|
-
`\`oasis propose ${artifactId} --file <\u6210\u54C1\u6587\u4EF6> --part ${ctx.part} --reason "<\u4E00\u53E5\u8BDD>"\`\u3002**\u5230\u6B64\u4E3A\u6B62\u2014\u2014\u4E0D conclude**\uFF0C\u7B49\u5404\u90E8\u4EF6\u9F50\u4E86 owner \u6536\u53E3\u3002**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1207
|
-
];
|
|
1208
|
-
}
|
|
1209
|
-
return [
|
|
1210
|
-
ctx.hasHead ? `\u4F60\u7684\u4EA4\u4ED8\u7269\u5728 \`./deliverable/\`\uFF08\u5A92\u4F53\u6210\u54C1\uFF1A\u89C6\u9891/\u97F3\u9891/\u56FE\u7B49\uFF09\u2014\u2014\u5728\u5B83\u57FA\u7840\u4E0A\u66F4\u65B0/\u66FF\u6362\u3002` : `\u4F60\u7684\u4EA4\u4ED8\u7269\u76EE\u5F55\u662F \`./deliverable/\`\uFF08\u5F53\u524D\u4E3A\u7A7A\u2014\u2014\u4EA7\u51FA\u9996\u7248\u6210\u54C1\uFF09\u3002`,
|
|
1211
|
-
`\u628A**\u6E32\u67D3/\u5BFC\u51FA\u597D\u7684\u6210\u54C1\u6587\u4EF6**\u653E\u8FDB \`deliverable/\`\uFF08\u6309\u4EA4\u4ED8\u8981\u6C42\u7684\u683C\u5F0F\uFF0C\u5982 mp4/wav/png\uFF1B\u5927\u4E8C\u8FDB\u5236\u76F4\u63A5\u653E\uFF0C\u522B\u585E\u8FDB\u6587\u672C\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
1212
|
-
`\`oasis propose ${artifactId} --from-dir deliverable/ --reason "<\u4E00\u53E5\u8BDD\u7406\u7531>"\` \u2192 \u6574\u4F53\u5B8C\u6574\u4E86\u518D \`oasis conclude ${artifactId}\`\u3002`,
|
|
1213
|
-
`**\u522B\u7F16\u9020\uFF1B\u7F3A\u524D\u7F6E\uFF08\u811A\u672C/\u5206\u955C/\u7D20\u6750\u6CA1\u5C31\u7EEA\uFF09\u6309\u751F\u4EA7\u8005\u5B88\u5219\u8D70 oasis gap**\u3002`
|
|
1214
|
-
];
|
|
1215
|
-
},
|
|
1216
|
-
integrateInstructions(ctx) {
|
|
1217
|
-
const parts = ctx.queuedPartLabels.map((p2) => `\`${p2}\``).join("\u3001") || "\uFF08\u961F\u5217\u4E3A\u7A7A\uFF09";
|
|
1218
|
-
return [
|
|
1219
|
-
`\u5404\u90E8\u4EF6\u7684\u6210\u54C1\u5728 \`parts/<\u540D>/\`\uFF08${parts}\uFF09\u3002\u628A\u5B83\u4EEC\u6C47\u6210**\u6700\u7EC8\u6210\u54C1**\u653E\u8FDB \`deliverable/\`\uFF08\u6309\u4EA4\u4ED8\u683C\u5F0F\u3001\u987A\u5E8F/\u62FC\u63A5\u6B63\u786E\uFF09\uFF0C\u7136\u540E\uFF1A`,
|
|
1220
|
-
`\`oasis integrate ${ctx.artifactId} --from-dir deliverable/ --reason "<\u96C6\u6210\u8BF4\u660E>"\` \u2192 \`oasis conclude ${ctx.artifactId}\`\u3002**\u522B\u4E22\u4EFB\u4F55\u90E8\u4EF6**\u3002`
|
|
1221
|
-
];
|
|
1222
|
-
},
|
|
1223
|
-
submitInstruction: deliverableSubmit,
|
|
1224
|
-
collectionStrategy: { kind: "inline" },
|
|
1225
|
-
mergeMode: "oasis-queue"
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
});
|
|
1229
|
-
|
|
1230
1259
|
// ../core/src/diff.ts
|
|
1231
1260
|
function lineDiff(oldText, newText, capLines = 60) {
|
|
1232
1261
|
const a = oldText.split("\n");
|
|
@@ -1344,9 +1373,11 @@ var init_op_payloads = __esm({
|
|
|
1344
1373
|
});
|
|
1345
1374
|
|
|
1346
1375
|
// ../contract/src/artifact.ts
|
|
1376
|
+
var DELIVERY_SUMMARY_ARTIFACT_TYPE;
|
|
1347
1377
|
var init_artifact = __esm({
|
|
1348
1378
|
"../contract/src/artifact.ts"() {
|
|
1349
1379
|
"use strict";
|
|
1380
|
+
DELIVERY_SUMMARY_ARTIFACT_TYPE = "delivery-summary";
|
|
1350
1381
|
}
|
|
1351
1382
|
});
|
|
1352
1383
|
|
|
@@ -2044,6 +2075,7 @@ var init_kernel = __esm({
|
|
|
2044
2075
|
// §6.1/§6.3:工作流节点(auto/prereq/seed)默认 persistent;随手 scratch 默认 temp
|
|
2045
2076
|
persistence: args.persistence ?? (createdVia === "manual-spawn" ? "temp" : "persistent"),
|
|
2046
2077
|
createdVia,
|
|
2078
|
+
...args.isFinalOutput !== void 0 ? { isFinalOutput: args.isFinalOutput } : {},
|
|
2047
2079
|
inputs,
|
|
2048
2080
|
...args.title !== void 0 ? { title: args.title } : {},
|
|
2049
2081
|
...args.description !== void 0 ? { description: args.description } : {},
|
|
@@ -2069,7 +2101,8 @@ var init_kernel = __esm({
|
|
|
2069
2101
|
}
|
|
2070
2102
|
/** routing 兜底(pending → 实派)与改派 */
|
|
2071
2103
|
async assignOwner(args) {
|
|
2072
|
-
this.artifactOrThrow(args.artifactId);
|
|
2104
|
+
const artifact = this.artifactOrThrow(args.artifactId);
|
|
2105
|
+
this.assertDeliverySummaryStructureMutable([artifact.id], args.actor, "\u6539\u6D3E\u8D1F\u8D23\u4EBA");
|
|
2073
2106
|
const payload = { owner: args.owner };
|
|
2074
2107
|
await this.commit(args.artifactId, args.actor, "assign_owner", args.artifactId, payload);
|
|
2075
2108
|
}
|
|
@@ -2232,6 +2265,28 @@ var init_kernel = __esm({
|
|
|
2232
2265
|
landed.push(head);
|
|
2233
2266
|
}
|
|
2234
2267
|
}
|
|
2268
|
+
/**
|
|
2269
|
+
* 冻结孤儿自愈(ADR 0069):把「本该自动落地却撞冻结没落」的 fresh 队首补落地。
|
|
2270
|
+
* 每落一条都对 **live model** 重算 `advanceableHead`(staleness 用落完上一条后的**新** head)——
|
|
2271
|
+
* 链式(Z.base=刚落的 X)顺序落完;竞争(Z.base=旧 head)落第一条后转 stale 自动停,不盲连落。
|
|
2272
|
+
* 尽力而为:撞显式冻结(`this.frozen`,纯投影看不见)或落地异常即停,留下次解冻 / serve 60s 循环兜底。
|
|
2273
|
+
* 钩子(`submitReview` 评审解冻后)与 serve 政策循环共用此方法。actor 记为 `actor:system`(系统协调动作)。
|
|
2274
|
+
*/
|
|
2275
|
+
async advanceOrphans(artifactId) {
|
|
2276
|
+
const landed = [];
|
|
2277
|
+
for (; ; ) {
|
|
2278
|
+
if (this.frozen.has(artifactId)) break;
|
|
2279
|
+
const rev = advanceableHead(this.model, this.schema, artifactId);
|
|
2280
|
+
if (!rev) break;
|
|
2281
|
+
try {
|
|
2282
|
+
await this.landHead(artifactId, SYSTEM_ACTOR, rev);
|
|
2283
|
+
landed.push(rev);
|
|
2284
|
+
} catch {
|
|
2285
|
+
break;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
return landed;
|
|
2289
|
+
}
|
|
2235
2290
|
/**
|
|
2236
2291
|
* group-commit(spec §5.5):队首 stale + 检查贵 + 多条竞争 → owner 把**整队 drain** 进一次集成。
|
|
2237
2292
|
* batch = 全部排队项(含排在 stale 队首之后的 fresh 项——严格 FIFO 下它们反正动不了,
|
|
@@ -2441,6 +2496,7 @@ var init_kernel = __esm({
|
|
|
2441
2496
|
await this.commit(args.artifactId, args.actor, "submit_review", attempt.head, payload, void 0, args.hand);
|
|
2442
2497
|
const status = attemptStatus(this.model, attempt);
|
|
2443
2498
|
if (status === "satisfied") await this.fireTriggers(args.artifactId);
|
|
2499
|
+
if (status !== "pending") await this.advanceOrphans(args.artifactId);
|
|
2444
2500
|
return { status };
|
|
2445
2501
|
}
|
|
2446
2502
|
async fireTriggers(artifactId) {
|
|
@@ -2757,6 +2813,7 @@ var init_kernel = __esm({
|
|
|
2757
2813
|
this.ensureActive(args.artifactId);
|
|
2758
2814
|
const artifact = this.artifactOrThrow(args.artifactId);
|
|
2759
2815
|
this.artifactOrThrow(args.to);
|
|
2816
|
+
this.assertDeliverySummaryStructureMutable([args.artifactId, args.to], args.actor, "\u4FEE\u6539\u8FDE\u7EBF");
|
|
2760
2817
|
if (args.to === args.artifactId) throw new KernelError("\u4E0D\u80FD\u4F9D\u8D56\u81EA\u5DF1");
|
|
2761
2818
|
if (artifact.inputs.some((e) => e.to === args.to)) {
|
|
2762
2819
|
throw new KernelError(`\u4F9D\u8D56\u8FB9\u5DF2\u5B58\u5728: ${args.artifactId} \u2192 ${args.to}`);
|
|
@@ -2829,7 +2886,7 @@ var init_kernel = __esm({
|
|
|
2829
2886
|
const keep = args.preserveEdgesAmong;
|
|
2830
2887
|
for (const edge of this.edgesTouching(args.artifactId)) {
|
|
2831
2888
|
if (keep?.has(edge.artifactId) && keep.has(edge.to)) continue;
|
|
2832
|
-
await this.
|
|
2889
|
+
await this.unlinkInputUnchecked({ artifactId: edge.artifactId, to: edge.to, actor: args.actor });
|
|
2833
2890
|
}
|
|
2834
2891
|
}
|
|
2835
2892
|
const payload = {
|
|
@@ -2924,6 +2981,11 @@ var init_kernel = __esm({
|
|
|
2924
2981
|
}
|
|
2925
2982
|
/** 治理断边(§11.3/§11.6:边即可见性拓扑——产线用法应经 Intervention 获得 preview) */
|
|
2926
2983
|
async unlinkInput(args) {
|
|
2984
|
+
this.assertDeliverySummaryStructureMutable([args.artifactId, args.to], args.actor, "\u4FEE\u6539\u8FDE\u7EBF");
|
|
2985
|
+
await this.unlinkInputUnchecked(args);
|
|
2986
|
+
}
|
|
2987
|
+
/** cancel 级联仍须能机械断边;这条内部路径保留原调用者审计身份,但不开放给人工命令。 */
|
|
2988
|
+
async unlinkInputUnchecked(args) {
|
|
2927
2989
|
this.ensureActive(args.artifactId);
|
|
2928
2990
|
const artifact = this.artifactOrThrow(args.artifactId);
|
|
2929
2991
|
if (!artifact.inputs.some((e) => e.to === args.to)) {
|
|
@@ -2932,6 +2994,25 @@ var init_kernel = __esm({
|
|
|
2932
2994
|
const payload = { to: args.to };
|
|
2933
2995
|
await this.commit(args.artifactId, args.actor, "unlink_input", args.artifactId, payload);
|
|
2934
2996
|
}
|
|
2997
|
+
assertDeliverySummaryStructureMutable(ids, actor, action) {
|
|
2998
|
+
if (actor === SYSTEM_ACTOR) return;
|
|
2999
|
+
const summary = ids.map((id) => this.model.artifacts.get(id)).find((a) => a?.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
3000
|
+
if (!summary) return;
|
|
3001
|
+
throw new KernelError(
|
|
3002
|
+
`\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u4EBA\u5DE5${action}\uFF08${summary.id}\uFF09\u3002\u8BF7\u4FEE\u6539\u5176\u5B83\u4E1A\u52A1\u8282\u70B9\u5E76\u91CD\u65B0\u89C4\u5212\u672B\u7AEF\u95ED\u73AF\u3002`
|
|
3003
|
+
);
|
|
3004
|
+
}
|
|
3005
|
+
/** 已落图的交付汇总只允许系统改结构;建单 plan 中首次原子 spawn 不受影响。 */
|
|
3006
|
+
assertDeliverySummaryIntervention(plan, actor) {
|
|
3007
|
+
if (actor === SYSTEM_ACTOR) return;
|
|
3008
|
+
for (const op of plan.ops) {
|
|
3009
|
+
if (op.action === "edit" || op.action === "assign") {
|
|
3010
|
+
this.assertDeliverySummaryStructureMutable([op.artifactId], actor, op.action === "edit" ? "\u7F16\u8F91\u8282\u70B9\u5B9A\u4E49" : "\u6539\u6D3E\u8D1F\u8D23\u4EBA");
|
|
3011
|
+
} else if (op.action === "link" || op.action === "unlink") {
|
|
3012
|
+
this.assertDeliverySummaryStructureMutable([op.artifactId, op.to], actor, "\u4FEE\u6539\u8FDE\u7EBF");
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
2935
3016
|
// ── Intervention(§11.7):结构变更的原子单位 ────────────────────────────
|
|
2936
3017
|
/**
|
|
2937
3018
|
* 预检(②终态校验 + ③advisory + ④爆炸半径)。preview 白送:
|
|
@@ -3127,6 +3208,7 @@ ${res.candidates.map((c) => ` - ${c.type}:${c.title ?? "(\u65E0title)"} \u2192
|
|
|
3127
3208
|
*/
|
|
3128
3209
|
async applyIntervention(plan, baseSeqs, actor) {
|
|
3129
3210
|
plan = this.resolveInterventionRefs(plan);
|
|
3211
|
+
this.assertDeliverySummaryIntervention(plan, actor);
|
|
3130
3212
|
const { changeClass, nonMonotonicOps } = classifyIntervention(plan);
|
|
3131
3213
|
if (changeClass === "C" && !isHumanActor(actor)) {
|
|
3132
3214
|
throw new KernelError(
|
|
@@ -3226,6 +3308,7 @@ ${res.candidates.map((c) => ` - ${c.type}:${c.title ?? "(\u65E0title)"} \u2192
|
|
|
3226
3308
|
workspace: op.workspace ?? "ws:default",
|
|
3227
3309
|
persistence: "persistent",
|
|
3228
3310
|
createdVia: isPrereqFill(spawnId) ? "prereq" : "manual-spawn",
|
|
3311
|
+
...op.isFinalOutput !== void 0 ? { isFinalOutput: op.isFinalOutput } : {},
|
|
3229
3312
|
...op.title !== void 0 ? { title: op.title } : {},
|
|
3230
3313
|
...op.description !== void 0 ? { description: op.description } : {},
|
|
3231
3314
|
...op.docType !== void 0 ? { docType: op.docType } : {},
|
|
@@ -3371,9 +3454,9 @@ ${res.candidates.map((c) => ` - ${c.type}:${c.title ?? "(\u65E0title)"} \u2192
|
|
|
3371
3454
|
/** sealed = 不再接受变更(§7.1);annotation / reject 不在此列(结案后补注与清理仍允许) */
|
|
3372
3455
|
ensureActive(artifactId) {
|
|
3373
3456
|
const lifecycle = lifecycleOf(this.model, artifactId);
|
|
3374
|
-
if (lifecycle
|
|
3375
|
-
|
|
3376
|
-
}
|
|
3457
|
+
if (lifecycle === "active") return;
|
|
3458
|
+
const why = lifecycle === "sealed:frozen" ? "\u6B64\u8282\u70B9\u5DF2\u88AB\u51BB\u7ED3\uFF08sealed:frozen\uFF09\uFF1A\u4FDD\u7559\u73B0\u6709\u4EA7\u51FA\u3001\u6682\u505C\u4E00\u5207\u6539\u52A8\uFF0C\u4E0D\u63A5\u53D7\u4EFB\u4F55\u63D0\u4EA4\u6216\u4FEE\u6539\u3002\u8981\u7EE7\u7EED\u987B\u7531\u4EBA\u5728\u6539\u56FE\u91CC reopen \u89E3\u51BB\uFF1B\u4F60\u82E5\u662F agent\u3001\u786E\u6709\u5FC5\u8981\u6539\uFF0C\u8BF7\u63D0 gap \u8BF4\u660E\u8BC9\u6C42" : lifecycle === "sealed:cancelled" ? "\u6B64\u8282\u70B9\u5DF2\u88AB\u53D6\u6D88\u5E9F\u5F03\uFF08sealed:cancelled\uFF09\uFF1A\u4F9D\u8D56\u8FB9\u5DF2\u65AD\uFF0C\u4E0D\u518D\u63A5\u53D7\u4EFB\u4F55\u4FEE\u6539" : lifecycle === "sealed:accepted" ? "\u6B64\u8282\u70B9\u5DF2\u9A8C\u6536\u7ED3\u6848\uFF08sealed:accepted\uFF09\uFF1A\u4E0D\u518D\u63A5\u53D7\u4FEE\u6539\uFF1B\u786E\u9700\u6539\u52A8\u8BF7\u5148 reopen" : `artifact is ${lifecycle}, no further changes`;
|
|
3459
|
+
throw new KernelError(`${why}: ${artifactId}`);
|
|
3377
3460
|
}
|
|
3378
3461
|
artifactOrThrow(id) {
|
|
3379
3462
|
const artifact = this.model.artifacts.get(id);
|
|
@@ -3842,6 +3925,37 @@ async function assembleContext(args) {
|
|
|
3842
3925
|
...partSpec?.deps && partSpec.deps.length > 0 ? [`- \u4F60\u4F9D\u8D56\u7684\u5144\u5F1F\u90E8\u4EF6\uFF08\u5DF2\u5148\u4EA7\u51FA\uFF0C\u89C1\u90BB\u57DF/\u5F53\u524D\u5185\u5BB9\uFF09\uFF1A${partSpec.deps.join("\u3001")}`] : [],
|
|
3843
3926
|
`- \u4E25\u5B88\u4E0A\u6E38\u7EA6\u5B9A\u7684\u63A5\u53E3/\u547D\u540D\uFF0C\u5404\u90E8\u4EF6\u624D\u62FC\u5F97\u8D77\u6765\u3002\u96C6\u6210\u7531\u7CFB\u7EDF\u5728\u5404\u90E8\u4EF6\u9F50\u4E86\u540E\u6536\u53E3\uFF0C**\u4E0D\u5F52\u4F60\u505A**\u3002`
|
|
3844
3927
|
] : [],
|
|
3928
|
+
// integrate:把「当初为什么这么切」铺给收口人。此前它只拿到部件**名字**(handler 的 queuedPartLabels)
|
|
3929
|
+
// 与各部件的产出内容,看不到 spec——而边界("只改你名下目录 X")、契约("面向契约类型编程、测试用 fake")、
|
|
3930
|
+
// 逐条交付清单全在 `add_part.payload.spec` 里(实测每条上千字)。少了它,integrate 只能看着几坨产出猜:
|
|
3931
|
+
// 某块是不是越界改了别人的文件、合起来 typecheck 红是预期内还是真 bug、某块是不是压根没做完。
|
|
3932
|
+
// 这些是 owner 当初**外化**过的决策依据,本该每轮递给它——不该靠续会话去继承(best-effort、换节点即失效、
|
|
3933
|
+
// 冷启动 runtime 不支持,且 whole produce 那轮结束时各部件**尚未动工**,续过来反而是陈旧心智)。
|
|
3934
|
+
// 守卫 queuedParts.length:队列为空不是真正的 integrate 场景(computeIntegrateJobs 只在有排队产出时派发),
|
|
3935
|
+
// 此时把所有已声明部件列成「缺块」既无意义又污染 TASK.md。
|
|
3936
|
+
...integrating && queuedParts.length > 0 ? (() => {
|
|
3937
|
+
const defined = artifact.parts ?? [];
|
|
3938
|
+
const queuedNames = new Set(queuedParts.map((p2) => p2.part));
|
|
3939
|
+
const missing = defined.filter((d) => !queuedNames.has(d.name));
|
|
3940
|
+
const lines = [``, `**\u672C\u4EA7\u7269\u5F53\u521D\u88AB\u5E76\u884C\u5206\u89E3\u6210 ${defined.length || queuedParts.length} \u4E2A\u90E8\u4EF6\uFF0C\u4F60\u73B0\u5728\u8981\u628A\u5B83\u4EEC\u5408\u6210\u5B8C\u6574\u7684\u4E00\u7248\u3002\u5F53\u521D\u6BCF\u5757\u662F\u8FD9\u4E48\u5207\u7684\uFF1A**`];
|
|
3941
|
+
for (const q of queuedParts) {
|
|
3942
|
+
const def = defined.find((d) => d.name === q.part);
|
|
3943
|
+
lines.push(``, `### \u90E8\u4EF6 \`${q.part}\`${def?.deps?.length ? `\uFF08\u4F9D\u8D56\uFF1A${def.deps.join("\u3001")}\uFF09` : ""}`);
|
|
3944
|
+
lines.push(`- \u5185\u5BB9\u5728 \`parts/${slug2(q.part)}/\``);
|
|
3945
|
+
lines.push(
|
|
3946
|
+
def?.spec ? `- \u5F53\u521D\u8981\u6C42\u5B83\u4EA7\u51FA\uFF1A
|
|
3947
|
+
${def.spec.split("\n").map((l) => ` > ${l}`).join("\n")}` : `- \uFF08\u65E0 spec \u8BB0\u5F55${def ? "" : "\uFF1B\u8BE5 revision \u672A\u6807 part\uFF0C\u6309\u5185\u5BB9\u81EA\u884C\u5224\u65AD"}\uFF09`
|
|
3948
|
+
);
|
|
3949
|
+
}
|
|
3950
|
+
for (const m2 of missing) {
|
|
3951
|
+
lines.push(``, `### \u26A0 \u90E8\u4EF6 \`${m2.name}\` \u2014\u2014 **\u5B9A\u4E49\u4E86\u4F46\u6CA1\u6709\u4EA7\u51FA\u6392\u961F**`);
|
|
3952
|
+
if (m2.spec) lines.push(`- \u5F53\u521D\u8981\u6C42\u5B83\u4EA7\u51FA\uFF1A
|
|
3953
|
+
${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
3954
|
+
lines.push(`- **\u7F3A\u8FD9\u4E00\u5757**\uFF1A\u5148\u5224\u65AD\u80FD\u4E0D\u80FD\u5408\uFF1B\u4E0D\u80FD\u5C31\u522B\u786C\u5408\uFF0C\`oasis add-revision\` \u628A\u5B83\u6D3E\u51FA\u53BB\u8865\u3002`);
|
|
3955
|
+
}
|
|
3956
|
+
lines.push(``, `\u5408\u5E76\u65F6\u6309\u5404\u5757\u5F53\u521D\u7EA6\u5B9A\u7684\u8FB9\u754C\u4E0E\u63A5\u53E3\u5BF9\u9F50\uFF1B\u67D0\u5757\u6CA1\u505A\u5230\u5B83 spec \u8981\u6C42\u7684\uFF0C\u4F60\u53EF\u4EE5 \`oasis add-revision\` \u6253\u56DE\u53BB\u8865\uFF0C\u4E0D\u5FC5\u81EA\u5DF1\u66FF\u5B83\u5199\u3002`);
|
|
3957
|
+
return lines;
|
|
3958
|
+
})() : [],
|
|
3845
3959
|
``,
|
|
3846
3960
|
`## \u600E\u4E48\u63D0\u4EA4`,
|
|
3847
3961
|
``,
|
|
@@ -3867,28 +3981,15 @@ async function assembleContext(args) {
|
|
|
3867
3981
|
})
|
|
3868
3982
|
];
|
|
3869
3983
|
})() : canvasMode ? [
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
` oasis design status ${artifactId}`,
|
|
3875
|
-
``,
|
|
3876
|
-
`- \u677F\u4E0A**\u5DF2\u6709\u8DD1\u5B8C\u7684\u4EA4\u4ED8\u7269**\uFF08\u4E0A\u4E00\u4E2A\u4F1A\u8BDD\u59D4\u6258\u7684\u5F15\u64CE\u8DD1\u5B8C\u4E86\uFF0C\u8D27\u6CA1\u4EBA\u6536\uFF09\u2192 \`--pull\` \u62C9\u5230\u672C\u5730**\u76F4\u63A5\u8FDB\u300C\u8BFB\u4EA7\u7269\u300D**\uFF0C\u522B\u91CD\u8DD1\u5F15\u64CE\u767D\u70E7 20-40 \u5206\u949F\uFF1B`,
|
|
3877
|
-
`- **\u5F15\u64CE\u8FD8\u5728\u8DD1** \u2192 \u522B\u518D\u8D77\u65B0\u8F6E\uFF1B\u8FC7\u51E0\u5206\u949F\u518D status\uFF0C\u6216\u672C\u8F6E\u6536\u5DE5\uFF08\u5F15\u64CE\u5728\u670D\u52A1\u7AEF\u81EA\u5DF1\u8DD1\u5B8C\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u6765\u53D6\uFF09\uFF1B`,
|
|
3878
|
-
`- \u4EC0\u4E48\u90FD\u6CA1\u6709 \u2192 \u8D77\u9996\u8F6E\u3002`,
|
|
3984
|
+
// 内核只出「你产什么 + 内核权威锚点」——**设计工作流散文全在你的人设(identity/AGENTS.md「产出流程」)**,
|
|
3985
|
+
// 那是单一真源、改它=改配置不发版(提案 design-conversational-driving 治本,2026-07-17)。这里不重复正文,
|
|
3986
|
+
// 只钉住内核唯一不能漂的两件事:真实 artifactId、缺前置的逃生口 gap。
|
|
3987
|
+
`\u4F60\u8D1F\u8D23 **design \u4EA7\u7269 \`${artifactId}\`**\uFF0C\u8FD0\u884C\u5728**\u901A\u7528\u8FD0\u884C\u65F6**\u4E0A\u2014\u2014\u4F60\u662F\u7532\u65B9\u8BBE\u8BA1\u8D1F\u8D23\u4EBA\uFF0C\u591A\u8F6E\u5BF9\u8BDD\u9A71\u52A8**\u534F\u4F5C\u753B\u677F\u5F15\u64CE**\u6253\u78E8\u754C\u9762\u7A3F\u3002`,
|
|
3879
3988
|
``,
|
|
3880
|
-
`**\
|
|
3989
|
+
`**\u5B8C\u6574\u5DE5\u4F5C\u6D41\uFF08\u600E\u4E48\u53D6\u8D27/\u8D77\u8F6E/\u8BFB\u4EA7\u7269/\u4EA4\u7A3F/\u522B\u624B\u6539\u677F\u6587\u4EF6\u2026\uFF09\u89C1\u4F60\u7684\u4EBA\u8BBE \`identity/AGENTS.md\` \u7684\u300C\u4EA7\u51FA\u6D41\u7A0B\uFF08design \u4EA7\u7269\uFF09\u300D**\u2014\u2014\u628A\u91CC\u9762 \`<artifactId>\` \u90FD\u6362\u6210\u672C\u4EA7\u7269 \`${artifactId}\`\u3002`,
|
|
3881
3990
|
``,
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
``,
|
|
3885
|
-
`\u5F15\u64CE\u4E00\u8F6E\u8981 13\u201344 \u5206\u949F\uFF0C\u5728 od \u670D\u52A1\u7AEF\u81EA\u5DF1\u8DD1\u3001**\u4E0E\u4F60\u7684\u4F1A\u8BDD\u751F\u6B7B\u65E0\u5173**\u2014\u2014\`--async\` \u4E0B\u5355\u5373\u8FD4\uFF0C**\u4E0D\u8981\u81EA\u5DF1\u53D1\u660E\u963B\u585E\u7B49\u5F85\u3001\u66F4\u522B\u7528 \`timeout\` \u5305\u547D\u4EE4**\u3002\u4E0B\u5355\u540E\u6BCF\u9694\u51E0\u5206\u949F \`oasis design status\` \u770B\u4E00\u773C\uFF1B\u4E00\u76F4\u6CA1\u5B8C\u4E5F\u53EF\u4EE5\u6536\u5DE5\uFF0C\u4E0B\u6B21\u6D3E\u53D1\u5148 status \u53D6\u8D27\u3002`,
|
|
3886
|
-
``,
|
|
3887
|
-
`**\u6BCF\u4E00\u8F6E\u7684\u95ED\u73AF\uFF08\u522B\u8DF3\u6B65\uFF09**\uFF1A`,
|
|
3888
|
-
`1. **\u5582\u9971\u5B83**\uFF1A\u9996\u8F6E \`--message\` \u628A\u8BBE\u8BA1\u9700\u6C42\u8FDE\u540C**\u771F\u5B9E\u793A\u4F8B\u6570\u636E**\u4E00\u8D77\u7ED9\u8DB3\u2014\u2014\u5F15\u64CE\u53EA\u62FF\u5230 \`DESIGN_BRIEF.md\`/\`inputs/\`\uFF0CPRD \u91CC\u6CA1\u6709\u7684 mock \u6570\u636E\u5B83\u4F1A**\u81EA\u5DF1\u7F16**\uFF08\u66FE\u628A\u5A74\u513F\u770B\u62A4\u5668\u7F16\u6210\u8033\u673A\uFF09\u3002\u771F\u5B9E\u4E1A\u52A1\u6570\u636E\uFF08\u4EA7\u54C1/\u4E70\u5BB6/\u8BA2\u5355\u7B49\uFF09\u5728\u54EA\u3001\u957F\u4EC0\u4E48\u6837\uFF0C\u4F60**\u5FC5\u987B\u5728 message \u91CC\u5199\u6E05\u6216\u544A\u8BC9\u5B83\u53BB\u54EA\u53D6**\uFF1B`,
|
|
3889
|
-
`2. **\u8BFB\u4EA7\u7269**\uFF1A\`oasis design status ${artifactId} --pull\` \u628A\u4EA4\u4ED8\u7269\u62C9\u5230\u672C\u5730\u2014\u2014**\u6253\u5F00 \`index.html\` \u771F\u8BFB\u4E00\u904D**\uFF0C\u5BF9\u7167 \`DESIGN_BRIEF.md\` \u4E0E \`inputs/\` \u6838\uFF1A\u6570\u636E\u5BF9\u4E0D\u5BF9\uFF1F\u72B6\u6001/\u8FB9\u754C\u6001\u5168\u4E0D\u5168\uFF1F\u6709\u6CA1\u6709\u7F16\u9020\uFF1F`,
|
|
3890
|
-
`3. **\u51B3\u5B9A**\uFF1A\u591F\u597D \u2192 \`oasis propose ${artifactId} --from-dir <\u62C9\u4E0B\u6765\u7684\u76EE\u5F55> --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"\` \u4EA4\u7A3F\uFF1B\u8FD8\u5DEE \u2192 \`--turn continue\` **\u518D\u4E00\u8F6E**\u6253\u78E8\uFF1B\u9047\u5230**\u4F60\u4E5F\u5B9A\u4E0D\u4E86\u7684\u53D6\u820D**\uFF08\u5982\u67D0\u6001\u7528\u54EA\u4E2A\u4E70\u5BB6\u627F\u8F7D\uFF09\u2192 \u5199\u8FDB acceptance.md \u7684\u300C\u5F00\u653E\u95EE\u9898\u300D\uFF0C\u6216 \`oasis gap ${artifactId} --desc "<\u8981\u4EBA\u5B9A\u4EC0\u4E48>"\` \u5192\u6CE1\u7ED9\u4EBA\uFF1B`,
|
|
3891
|
-
`- **\u522B\u628A\u7B2C\u4E00\u7248\u76F2\u76EE propose**\u2014\u2014\u5148\u8BFB\u3001\u5148\u81EA\u68C0\u3001\u4E0D\u591F\u5C31\u518D\u4E00\u8F6E\uFF0C\u6BD4 propose \u51FA\u53BB\u88AB\u4E0B\u6E38\u6253\u56DE\u3001\u7ED5\u6574\u5F20\u56FE\u4E00\u5708\u4FBF\u5B9C\u5F97\u591A\uFF1B`,
|
|
3991
|
+
`\u5185\u6838\u53EA\u5728\u6B64\u9489\u4E24\u6761\u4E0D\u53EF\u6F02\u7684\uFF1A`,
|
|
3992
|
+
`- **\u4EA4\u7A3F\u8D70 \`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "\u2026"\`**\uFF08proposed \u624D\u8FDB\u7248\u672C\u53F2\u3001\u4E0B\u6E38\u624D\u62FF\u5F97\u5230\uFF1B\u4E0D propose = head \u4ECD \u2205\uFF09\uFF1B`,
|
|
3892
3993
|
`- \u7F3A**\u8FD8\u4E0D\u5B58\u5728\u7684\u4E0A\u6E38\u524D\u7F6E**\u505A\u4E0D\u4E0B\u53BB \u2192 \`oasis gap ${artifactId} --desc "<\u7F3A\u4EC0\u4E48>"\` \u62A5\u7F3A\u53E3\u540E\u6536\u5DE5\u3002`
|
|
3893
3994
|
] : (() => {
|
|
3894
3995
|
const codeRepo = args.codeRepo ?? null;
|
|
@@ -3944,7 +4045,7 @@ async function assembleContext(args) {
|
|
|
3944
4045
|
``,
|
|
3945
4046
|
...canvasMode ? [
|
|
3946
4047
|
`## \u5173\u4E8E\u5DE5\u5177`,
|
|
3947
|
-
`oasis CLI \u5DF2\u6CE8\u5165\uFF08\`OASIS_SERVER\` / \`OASIS_TOKEN\` \u5C31\u7EEA\uFF0C\u65E0\u9700\u914D\u7F6E\uFF09\
|
|
4048
|
+
`oasis CLI \u5DF2\u6CE8\u5165\uFF08\`OASIS_SERVER\` / \`OASIS_TOKEN\` \u5C31\u7EEA\uFF0C\u65E0\u9700\u914D\u7F6E\uFF09\u3002\u8BBE\u8BA1\u5DE5\u4F5C\u6D41\u7528\u54EA\u4E9B\u547D\u4EE4\u3001\u600E\u4E48\u7528\uFF0C\u89C1\u4F60\u7684\u4EBA\u8BBE \`identity/AGENTS.md\` \u7684\u300C\u4EA7\u51FA\u6D41\u7A0B\u300D\u3002\u8BBE\u8BA1\u9700\u6C42\u89C1\u672C\u76EE\u5F55 \`DESIGN_BRIEF.md\`\uFF0C\u4E0A\u6E38\u8F93\u5165\u5728 \`inputs/\`\u3002`
|
|
3948
4049
|
] : commandReference({
|
|
3949
4050
|
artifactId,
|
|
3950
4051
|
action: args.action ?? "produce",
|
|
@@ -3972,14 +4073,14 @@ async function assembleContext(args) {
|
|
|
3972
4073
|
(s2) => `- ${s2.upstream}: pin=${s2.pinned ?? "\u2205"} \u2192 \u6700\u65B0 ${s2.latest}${s2.upstreamCancelled ? "\uFF08\u26A0 \u4E0A\u6E38\u5DF2 cancelled\uFF09" : ""}`
|
|
3973
4074
|
)
|
|
3974
4075
|
] : [],
|
|
3975
|
-
//
|
|
4076
|
+
// 画板模式:守则正文(甲方多轮/读产物再交/喂真数据/别本地手改板…)在人设 identity/AGENTS.md,此处不重复。
|
|
4077
|
+
// 只留内核锚点:你产哪一个、不归你定的别硬编。你在通用 runtime、CLI 齐全(design chat/propose/gap 都能用)。
|
|
3976
4078
|
...canvasMode ? [
|
|
3977
4079
|
``,
|
|
3978
4080
|
`## \u751F\u4EA7\u8005\u5B88\u5219\uFF08\u753B\u677F\u7248\uFF09`,
|
|
3979
|
-
`- \
|
|
4081
|
+
`- **\u5B8C\u6574\u8BBE\u8BA1\u5DE5\u4F5C\u6D41\u5B88\u5219\u89C1\u4F60\u7684\u4EBA\u8BBE \`identity/AGENTS.md\`\u300C\u4EA7\u51FA\u6D41\u7A0B\u300D**\uFF08\u600E\u4E48\u53D6\u8D27/\u8D77\u8F6E/\u8BFB\u4EA7\u7269/\u4EA4\u7A3F/\u522B\u624B\u6539\u677F\u6587\u4EF6\u7B49\uFF09\u3002`,
|
|
3980
4082
|
`- \u4F60\u53EA\u4EA7**\u8FD9\u4E00\u4E2A**\u8BBE\u8BA1\u4EA7\u7269\uFF1B**\u4E0D\u5F52\u4F60\u5B9A\u7684\u51B3\u7B56\u522B\u786C\u7F16**\uFF08\u4F1A\u88AB\u6253\u56DE\uFF09\u2014\u2014\u62FF\u4E0D\u51C6\u7684\u53D6\u820D\u5199\u8FDB acceptance.md \u7684\u300C\u5F00\u653E\u95EE\u9898\u300D\uFF0C\u6216 \`oasis gap\` \u5192\u6CE1\u7ED9\u4EBA\u3002`,
|
|
3981
4083
|
`- \u5FE0\u5B9E\u4E8E task-context/ \u91CC\u7684\u4E0A\u6E38\u8F93\u5165\uFF08PRD/\u603B\u7EB2\uFF09\uFF1B\u4E0E\u4E0A\u6E38\u51B2\u7A81\u5904\u4EE5\u4E0A\u6E38\u4E3A\u51C6\uFF0C\u5E76\u5728\u5F00\u653E\u95EE\u9898\u91CC\u6807\u6CE8\u5F02\u8BAE\u3002`,
|
|
3982
|
-
`- \u771F\u5B9E\u793A\u4F8B\u6570\u636E\uFF08\u4EA7\u54C1/\u4E70\u5BB6/\u8BA2\u5355\u7B49\uFF09**\u5FC5\u987B\u5728 \`--message\` \u91CC\u5582\u7ED9\u5F15\u64CE**\u2014\u2014\u5B83\u62FF\u4E0D\u5230\u7684\u4E1C\u897F\u4F1A\u81EA\u5DF1\u7F16\uFF0C\u522B\u8BA9\u5B83\u66FF\u4F60\u9020\u6570\u636E\u3002`,
|
|
3983
4084
|
`- \u754C\u9762\u7A3F\u5FC5\u987B**\u771F\u5B9E\u53EF\u6253\u5F00**\uFF08\u81EA\u5305\u542B HTML\uFF09\uFF0C\u522B\u4EA4\u793A\u610F\u63CF\u8FF0\u3002`
|
|
3984
4085
|
] : [],
|
|
3985
4086
|
// review 会话不产出、不该给生产者守则(它只投票,守则的 propose/conclude/gap/add-revision 全不适用)
|
|
@@ -135290,6 +135391,100 @@ var init_workorder_drafts = __esm({
|
|
|
135290
135391
|
});
|
|
135291
135392
|
|
|
135292
135393
|
// ../server/src/governance/draft-edit.ts
|
|
135394
|
+
function assertNotDeliverySummary(draft, ids, action) {
|
|
135395
|
+
const summary = ids.map((id) => spawnById(draft, id)).find((o) => o?.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
135396
|
+
if (!summary) return;
|
|
135397
|
+
throw new Error(`\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u4EBA\u5DE5${action}\uFF1B\u8BF7\u4FEE\u6539\u5176\u5B83\u4E1A\u52A1\u8282\u70B9\uFF0C\u7CFB\u7EDF\u4F1A\u91CD\u65B0\u5224\u65AD\u672B\u7AEF\u95ED\u73AF\u3002`);
|
|
135398
|
+
}
|
|
135399
|
+
function reconcileDeliverySummaryPlan(draft) {
|
|
135400
|
+
const summaries = spawnOps(draft).filter((op) => op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
135401
|
+
const business = spawnOps(draft).filter((op) => op.type !== "brief" && op.type !== DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
135402
|
+
const businessIds = new Set(business.map((op) => op.id));
|
|
135403
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
135404
|
+
for (const op of business) {
|
|
135405
|
+
for (const edge of op.inputs ?? []) if (businessIds.has(edge.to)) consumed.add(edge.to);
|
|
135406
|
+
}
|
|
135407
|
+
for (const op of draft.plan.ops) {
|
|
135408
|
+
if (op.action === "link" && businessIds.has(op.artifactId) && businessIds.has(op.to)) consumed.add(op.to);
|
|
135409
|
+
}
|
|
135410
|
+
const terminals = business.filter((op) => !consumed.has(op.id));
|
|
135411
|
+
const finals = business.filter((op) => op.isFinalOutput === true);
|
|
135412
|
+
const directFinal = finals.length === 1 && terminals.length === 1 && finals[0].id === terminals[0].id;
|
|
135413
|
+
if (business.length === 0 || directFinal) {
|
|
135414
|
+
const summaryIds2 = new Set(summaries.map((op) => op.id));
|
|
135415
|
+
draft.plan.ops = draft.plan.ops.filter((op) => {
|
|
135416
|
+
if (op.action === "spawn" && op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE) return false;
|
|
135417
|
+
if (op.action === "link" || op.action === "unlink") return !summaryIds2.has(op.artifactId) && !summaryIds2.has(op.to);
|
|
135418
|
+
if (op.action === "annotate" || op.action === "edit" || op.action === "assign") return !summaryIds2.has(op.artifactId);
|
|
135419
|
+
return true;
|
|
135420
|
+
});
|
|
135421
|
+
return;
|
|
135422
|
+
}
|
|
135423
|
+
const existing = summaries[0];
|
|
135424
|
+
const used = new Set(spawnOps(draft).map((op) => op.id));
|
|
135425
|
+
const brief = spawnOps(draft).find((op) => op.type === "brief");
|
|
135426
|
+
const manager = typeof brief?.fields?.["manager"] === "string" ? brief.fields["manager"] : void 0;
|
|
135427
|
+
const owner = existing?.owner ?? manager ?? (draft.draftedBy.startsWith("actor:agent:") ? draft.draftedBy : PENDING_UNASSIGNED);
|
|
135428
|
+
const summary = {
|
|
135429
|
+
action: "spawn",
|
|
135430
|
+
id: existing?.id ?? deriveArtifactId(DELIVERY_SUMMARY_ARTIFACT_TYPE, draft.workspace, "\u4EA4\u4ED8\u6C47\u603B", used),
|
|
135431
|
+
type: DELIVERY_SUMMARY_ARTIFACT_TYPE,
|
|
135432
|
+
workspace: draft.workspace,
|
|
135433
|
+
owner,
|
|
135434
|
+
title: "\u4EA4\u4ED8\u6C47\u603B",
|
|
135435
|
+
description: existing?.description ?? SUMMARY_TASK_BOOK,
|
|
135436
|
+
inputs: terminals.map((op) => ({ to: op.id, required: true })),
|
|
135437
|
+
isFinalOutput: true
|
|
135438
|
+
};
|
|
135439
|
+
const summaryIds = new Set(summaries.map((op) => op.id));
|
|
135440
|
+
draft.plan.ops = draft.plan.ops.filter((op) => {
|
|
135441
|
+
if (op.action === "spawn" && op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE) return false;
|
|
135442
|
+
if (op.action === "link" || op.action === "unlink") return !summaryIds.has(op.artifactId) && !summaryIds.has(op.to);
|
|
135443
|
+
if (op.action === "annotate" || op.action === "edit" || op.action === "assign") return !summaryIds.has(op.artifactId);
|
|
135444
|
+
return true;
|
|
135445
|
+
});
|
|
135446
|
+
draft.plan.ops.push(summary);
|
|
135447
|
+
}
|
|
135448
|
+
function assertDeliverySummaryPlanIntegrity(submitted, trusted) {
|
|
135449
|
+
const summaries = (plan) => (plan?.ops ?? []).filter((op) => op.action === "spawn" && op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
135450
|
+
const actual = summaries(submitted);
|
|
135451
|
+
const expected = summaries(trusted);
|
|
135452
|
+
if (!trusted && actual.length === 0) return;
|
|
135453
|
+
if (!trusted) throw new Error("\u4EA4\u4ED8\u6C47\u603B\u5FC5\u987B\u6765\u81EA\u670D\u52A1\u7AEF\u751F\u6210\u7684\u5EFA\u5355\u8349\u6848\uFF0C\u4E0D\u80FD\u7531\u5BA2\u6237\u7AEF\u81EA\u884C\u521B\u5EFA\u3002");
|
|
135454
|
+
if (actual.length !== expected.length) throw new Error("\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u5220\u9664\u6216\u65B0\u589E\u3002");
|
|
135455
|
+
const protectedShape = (op) => ({
|
|
135456
|
+
id: op.id,
|
|
135457
|
+
type: op.type,
|
|
135458
|
+
owner: op.owner,
|
|
135459
|
+
workspace: op.workspace,
|
|
135460
|
+
title: op.title,
|
|
135461
|
+
description: op.description,
|
|
135462
|
+
fields: op.fields,
|
|
135463
|
+
inputs: op.inputs ?? [],
|
|
135464
|
+
isFinalOutput: op.isFinalOutput
|
|
135465
|
+
});
|
|
135466
|
+
for (const expectedSummary of expected) {
|
|
135467
|
+
const actualSummary = actual.find((op) => op.id === expectedSummary.id);
|
|
135468
|
+
if (!actualSummary || JSON.stringify(protectedShape(actualSummary)) !== JSON.stringify(protectedShape(expectedSummary))) {
|
|
135469
|
+
throw new Error("\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7684\u8282\u70B9\u3001\u8D1F\u8D23\u4EBA\u3001\u4EFB\u52A1\u4E66\u548C\u8FDE\u7EBF\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u4EBA\u5DE5\u4FEE\u6539\u3002");
|
|
135470
|
+
}
|
|
135471
|
+
const protectedIds = /* @__PURE__ */ new Set([expectedSummary.id]);
|
|
135472
|
+
for (const op of submitted.ops) {
|
|
135473
|
+
if ((op.action === "edit" || op.action === "assign") && protectedIds.has(op.artifactId)) {
|
|
135474
|
+
throw new Error("\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u8FFD\u52A0\u4EBA\u5DE5\u7F16\u8F91\u6216\u6539\u6D3E\u64CD\u4F5C\u3002");
|
|
135475
|
+
}
|
|
135476
|
+
if ((op.action === "link" || op.action === "unlink") && (protectedIds.has(op.artifactId) || protectedIds.has(op.to))) {
|
|
135477
|
+
throw new Error("\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7684\u8FDE\u7EBF\u7531\u7CFB\u7EDF\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u8FFD\u52A0\u4EBA\u5DE5\u8FDE\u7EBF\u64CD\u4F5C\u3002");
|
|
135478
|
+
}
|
|
135479
|
+
}
|
|
135480
|
+
}
|
|
135481
|
+
const expectedMarkers = new Map(trusted.ops.filter((op) => op.action === "spawn" && !!op.id).map((op) => [op.id, op.isFinalOutput === true]));
|
|
135482
|
+
for (const op of submitted.ops) {
|
|
135483
|
+
if (op.action === "spawn" && op.id && expectedMarkers.has(op.id) && op.isFinalOutput === true !== expectedMarkers.get(op.id)) {
|
|
135484
|
+
throw new Error("\u8282\u70B9\u7684\u6700\u7EC8\u7ED3\u679C\u89D2\u8272\u7531\u52A8\u6001\u89C4\u5212\u7EF4\u62A4\uFF0C\u4E0D\u80FD\u4EBA\u5DE5\u4FEE\u6539\u3002");
|
|
135485
|
+
}
|
|
135486
|
+
}
|
|
135487
|
+
}
|
|
135293
135488
|
function resolveRef(ref2, draft) {
|
|
135294
135489
|
const res = resolveNodeRef(ref2, candidatesOf(draft));
|
|
135295
135490
|
if (res.ok) return res.id;
|
|
@@ -135300,6 +135495,9 @@ function resolveRef(ref2, draft) {
|
|
|
135300
135495
|
function editDraftPlan(draft, op) {
|
|
135301
135496
|
switch (op.action) {
|
|
135302
135497
|
case "spawn": {
|
|
135498
|
+
if (op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE) {
|
|
135499
|
+
throw new Error("\u300C\u4EA4\u4ED8\u6C47\u603B\u300D\u7531\u7CFB\u7EDF\u6309\u52A8\u6001\u534F\u4F5C\u56FE\u81EA\u52A8\u521B\u5EFA\uFF0C\u4E0D\u80FD\u624B\u52A8\u65B0\u589E\u3002");
|
|
135500
|
+
}
|
|
135303
135501
|
const title = op.title?.trim();
|
|
135304
135502
|
if (!title) throw new Error("\u7ED9\u8349\u6848\u52A0\u8282\u70B9\u8981 --title\uFF08\u636E (type,title) \u6D3E\u751F id\uFF09");
|
|
135305
135503
|
if (candidatesOf(draft).some((c) => c.type === op.type && (c.title ?? "").toLowerCase() === title.toLowerCase()))
|
|
@@ -135321,6 +135519,7 @@ function editDraftPlan(draft, op) {
|
|
|
135321
135519
|
}
|
|
135322
135520
|
case "edit": {
|
|
135323
135521
|
const id = resolveRef(op.artifactId, draft);
|
|
135522
|
+
assertNotDeliverySummary(draft, [id], "\u7F16\u8F91\u8282\u70B9\u5B9A\u4E49");
|
|
135324
135523
|
const target = spawnOps(draft).find((o) => o.id === id);
|
|
135325
135524
|
if (!target) throw new Error(`\u8349\u6848\u91CC\u6CA1\u6709\u8282\u70B9 ${id} \u7684 spawn`);
|
|
135326
135525
|
if (op.title !== void 0) target.title = op.title;
|
|
@@ -135331,12 +135530,14 @@ function editDraftPlan(draft, op) {
|
|
|
135331
135530
|
case "link": {
|
|
135332
135531
|
const consumer = resolveRef(op.artifactId, draft);
|
|
135333
135532
|
const upstream = resolveRef(op.to, draft);
|
|
135533
|
+
assertNotDeliverySummary(draft, [consumer, upstream], "\u4FEE\u6539\u8FDE\u7EBF");
|
|
135334
135534
|
draft.plan.ops.push({ action: "link", artifactId: consumer, to: upstream, ...op.required !== void 0 ? { required: op.required } : {} });
|
|
135335
135535
|
break;
|
|
135336
135536
|
}
|
|
135337
135537
|
case "unlink": {
|
|
135338
135538
|
const consumer = resolveRef(op.artifactId, draft);
|
|
135339
135539
|
const upstream = resolveRef(op.to, draft);
|
|
135540
|
+
assertNotDeliverySummary(draft, [consumer, upstream], "\u4FEE\u6539\u8FDE\u7EBF");
|
|
135340
135541
|
draft.plan.ops = draft.plan.ops.filter((o) => !(o.action === "link" && o.artifactId === consumer && o.to === upstream));
|
|
135341
135542
|
for (const o of draft.plan.ops) if (o.action === "spawn" && o.id === consumer && o.inputs) o.inputs = o.inputs.filter((e) => e.to !== upstream);
|
|
135342
135543
|
break;
|
|
@@ -135344,6 +135545,7 @@ function editDraftPlan(draft, op) {
|
|
|
135344
135545
|
case "seal": {
|
|
135345
135546
|
if (op.reason !== "cancelled") throw new Error(`\u8349\u6848\u8282\u70B9\u53EA\u652F\u6301 cancel\uFF08\u5220\u9664\uFF09\uFF0C\u4E0D\u652F\u6301 ${op.reason}\u2014\u2014\u8282\u70B9\u8FD8\u6CA1\u843D\u5E93`);
|
|
135346
135547
|
const id = resolveRef(op.artifactId, draft);
|
|
135548
|
+
assertNotDeliverySummary(draft, [id], "\u5220\u9664\u8282\u70B9");
|
|
135347
135549
|
draft.plan.ops = draft.plan.ops.filter((o) => {
|
|
135348
135550
|
if (o.action === "spawn" && o.id === id) return false;
|
|
135349
135551
|
if (o.action === "annotate" && o.artifactId === id) return false;
|
|
@@ -135356,14 +135558,24 @@ function editDraftPlan(draft, op) {
|
|
|
135356
135558
|
default:
|
|
135357
135559
|
throw new Error(`\u8349\u6848\u7F16\u8F91\u6682\u4E0D\u652F\u6301 ${op.action}\uFF08\u8349\u6848\u9636\u6BB5\u53EA\u652F\u6301 spawn / edit / link / unlink / cancel\uFF09`);
|
|
135358
135560
|
}
|
|
135561
|
+
reconcileDeliverySummaryPlan(draft);
|
|
135359
135562
|
}
|
|
135360
|
-
var spawnOps, candidatesOf;
|
|
135563
|
+
var spawnOps, candidatesOf, spawnById, SUMMARY_TASK_BOOK;
|
|
135361
135564
|
var init_draft_edit = __esm({
|
|
135362
135565
|
"../server/src/governance/draft-edit.ts"() {
|
|
135363
135566
|
"use strict";
|
|
135567
|
+
init_src();
|
|
135364
135568
|
init_src2();
|
|
135365
135569
|
spawnOps = (draft) => draft.plan.ops.filter((o) => o.action === "spawn" && !!o.id);
|
|
135366
135570
|
candidatesOf = (draft) => spawnOps(draft).map((o) => ({ id: o.id, type: o.type, ...o.title ? { title: o.title } : {} }));
|
|
135571
|
+
spawnById = (draft, id) => spawnOps(draft).find((o) => o.id === id);
|
|
135572
|
+
SUMMARY_TASK_BOOK = [
|
|
135573
|
+
"# \u4EA4\u4ED8\u6C47\u603B\u4EFB\u52A1\u4E66",
|
|
135574
|
+
"",
|
|
135575
|
+
"\u4F60\u662F\u672C\u5DE5\u5355\u534F\u8C03\u8005\uFF0C\u8D1F\u8D23\u628A\u534F\u4F5C\u6D41\u5DF2\u7ECF\u4EA7\u51FA\u7684\u6700\u7EC8\u7ED3\u679C\u6574\u7406\u6210\u7528\u6237\u53EF\u4EE5\u76F4\u63A5\u9886\u53D6\u548C\u4F7F\u7528\u7684\u4E00\u4EFD\u5B8C\u6574\u4EA4\u4ED8\u3002",
|
|
135576
|
+
"\u8FD9\u4E0D\u662F\u9A8C\u6536\u8282\u70B9\uFF1A\u4E0D\u8981\u91CD\u65B0\u6D4B\u8BD5\u3001\u4E0D\u8981\u5224\u5B9A\u901A\u8FC7\u3001\u4E0D\u8981\u6C42\u7528\u6237\u7B7E\u6536\u3002",
|
|
135577
|
+
"\u8F93\u51FA\u987B\u8BF4\u660E\u7528\u6237\u62FF\u5230\u4E86\u4EC0\u4E48\u3001\u5728\u54EA\u91CC\u62FF\u3001\u600E\u4E48\u4F7F\u7528\u3001\u5F53\u524D\u662F\u54EA\u4E00\u7248\uFF1B\u53EA\u5F15\u7528\u8F93\u5165\u53CA\u5176\u4E0A\u6E38\u7684\u771F\u5B9E\u4EA7\u7269\u3002"
|
|
135578
|
+
].join("\n");
|
|
135367
135579
|
}
|
|
135368
135580
|
});
|
|
135369
135581
|
|
|
@@ -135630,7 +135842,7 @@ async function plannerAvailableActors(registry2) {
|
|
|
135630
135842
|
}
|
|
135631
135843
|
async function plannerArtifactTypes(schema, registry2) {
|
|
135632
135844
|
if (!registry2) {
|
|
135633
|
-
return schema.filter((def) => def.name !== "brief").map((def) => ({
|
|
135845
|
+
return schema.filter((def) => def.name !== "brief" && def.name !== DELIVERY_SUMMARY_ARTIFACT_TYPE).map((def) => ({
|
|
135634
135846
|
name: def.name,
|
|
135635
135847
|
...def.ownerRole ? { ownerRole: def.ownerRole } : {},
|
|
135636
135848
|
contentType: def.contentType,
|
|
@@ -135639,7 +135851,7 @@ async function plannerArtifactTypes(schema, registry2) {
|
|
|
135639
135851
|
}
|
|
135640
135852
|
const actors = await plannerAvailableActors(registry2);
|
|
135641
135853
|
const staffableRoles = new Set(actors.flatMap((actor) => actor.roles));
|
|
135642
|
-
return schema.filter((def) => def.name !== "brief" && (def.ownerRole === void 0 || staffableRoles.has(def.ownerRole))).map((def) => ({
|
|
135854
|
+
return schema.filter((def) => def.name !== "brief" && def.name !== DELIVERY_SUMMARY_ARTIFACT_TYPE && (def.ownerRole === void 0 || staffableRoles.has(def.ownerRole))).map((def) => ({
|
|
135643
135855
|
name: def.name,
|
|
135644
135856
|
...def.ownerRole ? { ownerRole: def.ownerRole } : {},
|
|
135645
135857
|
contentType: def.contentType
|
|
@@ -135734,7 +135946,8 @@ async function buildDynamicWorkorderPlan(input) {
|
|
|
135734
135946
|
...def.ownerRole ? { role: def.ownerRole } : {},
|
|
135735
135947
|
owner: ownerActor,
|
|
135736
135948
|
dependsOn: node.dependsOn,
|
|
135737
|
-
...node.brief ? { brief: node.brief } : {}
|
|
135949
|
+
...node.brief ? { brief: node.brief } : {},
|
|
135950
|
+
...node.isFinalOutput ? { isFinalOutput: true } : {}
|
|
135738
135951
|
});
|
|
135739
135952
|
}
|
|
135740
135953
|
} else {
|
|
@@ -135749,11 +135962,12 @@ async function buildDynamicWorkorderPlan(input) {
|
|
|
135749
135962
|
const ownerActor = owner?.actor ?? (!def.ownerRole ? PENDING_UNASSIGNED : type === primaryType ? input.actor : `pending:role:${def.ownerRole}`);
|
|
135750
135963
|
if (enforceStaffing && def.ownerRole && !owner?.actor && type !== primaryType) continue;
|
|
135751
135964
|
const id = type === primaryType ? primaryId : `artifact:${type}:${slug5}`;
|
|
135752
|
-
availableNodes.push({ type, id, ...def.ownerRole ? { role: def.ownerRole } : {}, owner: ownerActor });
|
|
135965
|
+
availableNodes.push({ type, id, ...def.ownerRole ? { role: def.ownerRole } : {}, owner: ownerActor, ...type === primaryType ? { isFinalOutput: true } : {} });
|
|
135753
135966
|
}
|
|
135754
135967
|
}
|
|
135755
135968
|
for (const node of availableNodes) {
|
|
135756
135969
|
const inputs = agentGraph ? agentEdgesFor(node.dependsOn ?? [], availableNodes, briefId, issues) : ruleEdgesFor(node.type, availableNodes, briefId);
|
|
135970
|
+
node.inputs = inputs;
|
|
135757
135971
|
const shortTitle = node.title ?? (!agentGraph && node.type === "prd" && issues.length > 0 ? "\u964D\u7EA7\u65B9\u6848\u6587\u6863" : labelForType(node.type));
|
|
135758
135972
|
const briefBody = node.brief ?? taskBookFor(node.type, input.description, node.role, issues, agentGraph?.notes, shortTitle);
|
|
135759
135973
|
ops.push({
|
|
@@ -135767,10 +135981,59 @@ async function buildDynamicWorkorderPlan(input) {
|
|
|
135767
135981
|
// 所有类型(含 document)统一:description = 完整任务书,直接进 owner 的 TASK.md,**不再造 open 人类 annotation**
|
|
135768
135982
|
//(那条 annotation 默认 kind=change-request、触发 hasOpenHumanChangeRequest 焊死自动合并 + 假审核,是迁移遗留)。
|
|
135769
135983
|
// document 的 docType/title 走独立字段;老文档缺独立字段的仍由 decodeDocumentDescription 兜底解析 description(保留)。
|
|
135770
|
-
description: briefBody
|
|
135984
|
+
description: briefBody,
|
|
135985
|
+
...node.isFinalOutput ? { isFinalOutput: true } : {}
|
|
135771
135986
|
});
|
|
135772
135987
|
spawned.push({ id: node.id, type: node.type, role: node.role, owner: node.owner });
|
|
135773
135988
|
}
|
|
135989
|
+
if (availableNodes.length > 0) {
|
|
135990
|
+
const consumed = new Set(availableNodes.flatMap((node) => (node.inputs ?? []).map((edge) => edge.to)));
|
|
135991
|
+
const terminalNodes = availableNodes.filter((node) => !consumed.has(node.id));
|
|
135992
|
+
const finalNodes = availableNodes.filter((node) => node.isFinalOutput);
|
|
135993
|
+
const directFinal = finalNodes.length === 1 && terminalNodes.length === 1 && finalNodes[0].id === terminalNodes[0].id;
|
|
135994
|
+
if (agentGraph && finalNodes.length === 0) {
|
|
135995
|
+
issues.push({
|
|
135996
|
+
code: "planner_invalid",
|
|
135997
|
+
severity: "warning",
|
|
135998
|
+
message: "pm_agent \u6CA1\u6709\u6807\u8BB0\u76F4\u63A5\u56DE\u7B54\u7528\u6237\u9700\u6C42\u7684\u6700\u7EC8\u7ED3\u679C\u8282\u70B9\uFF0C\u7CFB\u7EDF\u5DF2\u7528\u4EA4\u4ED8\u6C47\u603B\u515C\u5E95\u3002"
|
|
135999
|
+
});
|
|
136000
|
+
}
|
|
136001
|
+
if (directFinal) {
|
|
136002
|
+
} else {
|
|
136003
|
+
const summaryDef = schemaByName.get(DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
136004
|
+
if (!summaryDef) {
|
|
136005
|
+
issues.push({
|
|
136006
|
+
code: "missing_artifact_type",
|
|
136007
|
+
severity: "blocking",
|
|
136008
|
+
artifactType: DELIVERY_SUMMARY_ARTIFACT_TYPE,
|
|
136009
|
+
message: `\u7F3A\u5C11\u7CFB\u7EDF ArtifactType ${DELIVERY_SUMMARY_ARTIFACT_TYPE}\uFF0C\u672C\u6B21\u65E0\u6CD5\u521B\u5EFA\u4EA4\u4ED8\u6C47\u603B\u8282\u70B9\u3002`
|
|
136010
|
+
});
|
|
136011
|
+
} else if (terminalNodes.length > 0) {
|
|
136012
|
+
const summaryId = deriveArtifactId(DELIVERY_SUMMARY_ARTIFACT_TYPE, input.workspace, "\u4EA4\u4ED8\u6C47\u603B", usedIds);
|
|
136013
|
+
const summaryOwner = input.aiActorId ?? (input.actor.startsWith("actor:agent:") ? input.actor : PENDING_UNASSIGNED);
|
|
136014
|
+
if (summaryOwner === PENDING_UNASSIGNED) {
|
|
136015
|
+
issues.push({
|
|
136016
|
+
code: "missing_owner",
|
|
136017
|
+
severity: "blocking",
|
|
136018
|
+
artifactType: DELIVERY_SUMMARY_ARTIFACT_TYPE,
|
|
136019
|
+
message: "\u4EA4\u4ED8\u6C47\u603B\u5FC5\u987B\u7531\u672C\u5DE5\u5355\u7BA1\u7406\u8005\u8D1F\u8D23\uFF0C\u4F46\u5F53\u524D brief \u6CA1\u6709 manager\uFF1B\u8BF7\u5148\u6307\u5B9A\u7BA1\u7406\u8005\u3002"
|
|
136020
|
+
});
|
|
136021
|
+
}
|
|
136022
|
+
ops.push({
|
|
136023
|
+
action: "spawn",
|
|
136024
|
+
id: summaryId,
|
|
136025
|
+
type: DELIVERY_SUMMARY_ARTIFACT_TYPE,
|
|
136026
|
+
owner: summaryOwner,
|
|
136027
|
+
workspace: input.workspace,
|
|
136028
|
+
title: "\u4EA4\u4ED8\u6C47\u603B",
|
|
136029
|
+
inputs: terminalNodes.map((node) => ({ to: node.id, required: true })),
|
|
136030
|
+
description: deliverySummaryTaskBook(finalNodes, terminalNodes),
|
|
136031
|
+
isFinalOutput: true
|
|
136032
|
+
});
|
|
136033
|
+
spawned.push({ id: summaryId, type: DELIVERY_SUMMARY_ARTIFACT_TYPE, owner: summaryOwner });
|
|
136034
|
+
}
|
|
136035
|
+
}
|
|
136036
|
+
}
|
|
135774
136037
|
return {
|
|
135775
136038
|
plan: {
|
|
135776
136039
|
reason: `\u52A8\u6001\u89C4\u5212\u5DE5\u5355\uFF1A${displayTitle}`,
|
|
@@ -135815,15 +136078,19 @@ function buildPmAgentPlannerPrompt(input) {
|
|
|
135815
136078
|
"",
|
|
135816
136079
|
JSON.stringify({
|
|
135817
136080
|
nodes: [
|
|
135818
|
-
{ type: "prd", title: "\u9700\u6C42\u4E0E\u8303\u56F4\u8BF4\u660E", dependsOn: ["brief"], brief: "\u8FD9\u4E2A\u8282\u70B9\u5177\u4F53\u8981\u505A\u4EC0\u4E48\u7684\u89C4\u683C\uFF1A\u4EA7\u51FA\u4EC0\u4E48\u3001\u8981\u70B9\u3001\u7EA6\u675F" },
|
|
135819
|
-
{ type: "research", title: "\u7ADE\u54C1\u8C03\u7814", dependsOn: ["brief"], brief: "\u2026" },
|
|
135820
|
-
{ type: "dev", title: "\
|
|
136081
|
+
{ type: "prd", title: "\u9700\u6C42\u4E0E\u8303\u56F4\u8BF4\u660E", dependsOn: ["brief"], brief: "\u8FD9\u4E2A\u8282\u70B9\u5177\u4F53\u8981\u505A\u4EC0\u4E48\u7684\u89C4\u683C\uFF1A\u4EA7\u51FA\u4EC0\u4E48\u3001\u8981\u70B9\u3001\u7EA6\u675F", isFinalOutput: false },
|
|
136082
|
+
{ type: "research", title: "\u7ADE\u54C1\u8C03\u7814", dependsOn: ["brief"], brief: "\u2026", isFinalOutput: false },
|
|
136083
|
+
{ type: "dev", title: "\u4EA7\u54C1\u5B9E\u73B0", dependsOn: ["prd:\u9700\u6C42\u4E0E\u8303\u56F4\u8BF4\u660E"], brief: "\u4EA7\u51FA\u7528\u6237\u9700\u8981\u7684\u4EA7\u54C1\u548C\u4F7F\u7528\u8BF4\u660E", isFinalOutput: true },
|
|
136084
|
+
{ type: "qa", title: "\u8D28\u91CF\u68C0\u67E5", dependsOn: ["dev:\u4EA7\u54C1\u5B9E\u73B0"], brief: "\u68C0\u67E5\u4EA7\u54C1\u662F\u5426\u53EF\u7528", isFinalOutput: false }
|
|
135821
136085
|
],
|
|
135822
136086
|
notes: ["\u53EF\u9009\uFF1A\u89C4\u5212\u7406\u7531\u6216\u98CE\u9669\u63D0\u793A"]
|
|
135823
136087
|
}, null, 2),
|
|
135824
136088
|
"",
|
|
135825
136089
|
"\u89C4\u5219\uFF1A",
|
|
135826
136090
|
"- brief \u6839\u8282\u70B9\u7531\u7CFB\u7EDF\u56FA\u5B9A\u521B\u5EFA\uFF0C\u4F60\u4E0D\u8981\u628A brief \u5199\u8FDB nodes\u3002",
|
|
136091
|
+
`- ${DELIVERY_SUMMARY_ARTIFACT_TYPE}\uFF08\u4EA4\u4ED8\u6C47\u603B\uFF09\u7531\u7CFB\u7EDF\u56FA\u5B9A\u521B\u5EFA\uFF0C\u4F60\u4E0D\u8981\u628A\u5B83\u5199\u8FDB nodes\u3002`,
|
|
136092
|
+
"- \u6BCF\u4E2A\u8282\u70B9\u5FC5\u987B\u7ED9 isFinalOutput\u3002true \u8868\u793A\u8BE5\u8282\u70B9\u7684\u4EA7\u7269\u76F4\u63A5\u56DE\u7B54\u7528\u6237\u9700\u6C42\uFF1B\u5B83\u4E0D\u662F\u8BC4\u5BA1\u3001QA \u6216\u662F\u5426\u5B8C\u6210\u7684\u72B6\u6001\u3002\u8FC7\u7A0B/\u652F\u6491/\u95F8\u95E8\u8282\u70B9\u5199 false\u3002",
|
|
136093
|
+
"- \u81F3\u5C11\u4E00\u4E2A\u8282\u70B9\u5E94\u4E3A isFinalOutput:true\u3002\u4F8B\uFF1A\u53EA\u505A\u4E00\u4EFD PRD \u65F6 PRD=true\uFF1B\u4E09\u4EFD\u5E73\u884C\u8C03\u7814\u6C47\u5165\u4E00\u4EFD\u7EFC\u5408\u62A5\u544A\u65F6\u53EA\u6807\u7EFC\u5408\u62A5\u544A=true\uFF1B\u505A\u4EA7\u54C1\u65F6\u4EA7\u51FA\u4EA7\u54C1\u548C\u4F7F\u7528\u8BF4\u660E\u7684\u5B9E\u73B0\u8282\u70B9=true\uFF0C\u800C\u90E8\u7F72/QA=false\u3002",
|
|
135827
136094
|
"- type \u53EA\u80FD\u4ECE\u4E0A\u9762\u3010\u53EF\u7528 ArtifactType\u3011\u76EE\u5F55\u91CC\u9009\uFF08\u4EE5\u6CE8\u5165\u76EE\u5F55\u4E3A\u51C6\uFF09\u3002",
|
|
135828
136095
|
"- \u6BCF\u4E2A\u8282\u70B9\u5FC5\u7ED9 title\uFF08\u226420\u5B57\u3001\u7528\u6765\u533A\u5206\u8282\u70B9\uFF09+ brief\uFF08\u8FD9\u4E2A\u8282\u70B9\u8981\u4EA7\u51FA\u4EC0\u4E48\u7684\u89C4\u683C\uFF0C\u522B\u5957\u6A21\u677F\u3001\u522B\u53EA\u5199\u7C7B\u578B\u540D\uFF09\u3002",
|
|
135829
136096
|
'- \u3010\u53EF\u6709\u591A\u4E2A\u540C type \u8282\u70B9\u3011\uFF0C\u7528\u4E0D\u540C title \u533A\u5206\uFF08\u5982\u4E24\u4E2A prd\uFF1A"\u524D\u7AEF\u9700\u6C42"\u3001"\u540E\u7AEF\u9700\u6C42"\uFF1B\u591A\u4EFD\u8C03\u7814\u62A5\u544A\u5404\u53D6\u5176\u540D\uFF09\u3002',
|
|
@@ -135850,7 +136117,8 @@ function parseAgentWorkorderPlan(text) {
|
|
|
135850
136117
|
type: n.type.trim().toLowerCase(),
|
|
135851
136118
|
...Array.isArray(n.dependsOn) ? { dependsOn: n.dependsOn.filter((x2) => typeof x2 === "string").map((x2) => x2.trim().toLowerCase()).filter(Boolean) } : {},
|
|
135852
136119
|
...typeof n.title === "string" && n.title.trim() ? { title: n.title.trim() } : {},
|
|
135853
|
-
...typeof n.brief === "string" && n.brief.trim() ? { brief: n.brief.trim() } : {}
|
|
136120
|
+
...typeof n.brief === "string" && n.brief.trim() ? { brief: n.brief.trim() } : {},
|
|
136121
|
+
...n.isFinalOutput === true ? { isFinalOutput: true } : {}
|
|
135854
136122
|
});
|
|
135855
136123
|
}
|
|
135856
136124
|
if (nodes.length === 0) return null;
|
|
@@ -135926,13 +136194,14 @@ function desiredArtifacts(primaryType, description) {
|
|
|
135926
136194
|
return ["prd", "research", "design", "adr", "dev", "qa"].filter((type) => wanted.has(type));
|
|
135927
136195
|
}
|
|
135928
136196
|
function normalizeAgentPlan(plan, validTypes) {
|
|
135929
|
-
const allowed = validTypes.map((t) => t.trim().toLowerCase()).filter((t) => t !== "brief");
|
|
136197
|
+
const allowed = validTypes.map((t) => t.trim().toLowerCase()).filter((t) => t !== "brief" && t !== DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
135930
136198
|
const nodes = [];
|
|
135931
136199
|
const seen = /* @__PURE__ */ new Set();
|
|
135932
136200
|
const dupTitles = [];
|
|
135933
136201
|
for (const node of plan.nodes) {
|
|
135934
136202
|
const type = node.type.trim().toLowerCase();
|
|
135935
136203
|
if (type === "brief") continue;
|
|
136204
|
+
if (type === DELIVERY_SUMMARY_ARTIFACT_TYPE) continue;
|
|
135936
136205
|
if (!allowed.includes(type)) continue;
|
|
135937
136206
|
const title = (node.title?.trim() || labelForType(type)).slice(0, 40);
|
|
135938
136207
|
const key = `${type}:${title.toLowerCase()}`;
|
|
@@ -135945,7 +136214,8 @@ function normalizeAgentPlan(plan, validTypes) {
|
|
|
135945
136214
|
type,
|
|
135946
136215
|
title,
|
|
135947
136216
|
dependsOn: node.dependsOn?.map((d) => d.trim()).filter(Boolean) ?? [],
|
|
135948
|
-
...node.brief ? { brief: node.brief } : {}
|
|
136217
|
+
...node.brief ? { brief: node.brief } : {},
|
|
136218
|
+
...node.isFinalOutput ? { isFinalOutput: true } : {}
|
|
135949
136219
|
});
|
|
135950
136220
|
}
|
|
135951
136221
|
return nodes.length > 0 ? { nodes, dupTitles, ...plan.notes?.length ? { notes: plan.notes } : {} } : null;
|
|
@@ -136023,6 +136293,29 @@ ${plannerNotes.map((note) => `- ${note}`).join("\n")}` : "";
|
|
|
136023
136293
|
notes
|
|
136024
136294
|
].join("\n");
|
|
136025
136295
|
}
|
|
136296
|
+
function deliverySummaryTaskBook(finalNodes, terminalNodes) {
|
|
136297
|
+
const labels = (nodes) => nodes.map((node) => node.title ?? labelForType(node.type));
|
|
136298
|
+
return [
|
|
136299
|
+
"# \u4EA4\u4ED8\u6C47\u603B\u4EFB\u52A1\u4E66",
|
|
136300
|
+
"",
|
|
136301
|
+
"\u4F60\u662F\u672C\u5DE5\u5355\u534F\u8C03\u8005\uFF0C\u8D1F\u8D23\u628A\u534F\u4F5C\u6D41\u5DF2\u7ECF\u4EA7\u51FA\u7684\u6700\u7EC8\u7ED3\u679C\u6574\u7406\u6210\u7528\u6237\u53EF\u4EE5\u76F4\u63A5\u9886\u53D6\u548C\u4F7F\u7528\u7684\u4E00\u4EFD\u5B8C\u6574\u4EA4\u4ED8\u3002",
|
|
136302
|
+
"\u8FD9\u4E0D\u662F\u9A8C\u6536\u8282\u70B9\uFF1A\u4E0D\u8981\u91CD\u65B0\u6D4B\u8BD5\u3001\u4E0D\u8981\u5224\u5B9A\u901A\u8FC7\u3001\u4E0D\u8981\u6C42\u7528\u6237\u7B7E\u6536\uFF0C\u4E5F\u4E0D\u8981\u628A\u6240\u6709\u8FC7\u7A0B\u8282\u70B9\u90FD\u585E\u8FDB\u6765\u3002",
|
|
136303
|
+
"",
|
|
136304
|
+
"## \u89C4\u5212\u8BC6\u522B\u7684\u6700\u7EC8\u7ED3\u679C\u8282\u70B9",
|
|
136305
|
+
...finalNodes.length > 0 ? labels(finalNodes).map((item) => `- ${item}`) : ["- \u89C4\u5212\u672A\u660E\u786E\u6807\u8BB0\uFF1B\u8BF7\u6839\u636E\u5DE5\u5355\u9700\u6C42\u548C\u8F93\u5165\u4EA7\u7269\u6574\u7406\u771F\u5B9E\u4EA4\u4ED8\u3002"],
|
|
136306
|
+
"",
|
|
136307
|
+
"## \u672C\u8282\u70B9\u76F4\u63A5\u627F\u63A5\u7684\u534F\u4F5C\u6D41\u7EC8\u70B9",
|
|
136308
|
+
...labels(terminalNodes).map((item) => `- ${item}`),
|
|
136309
|
+
"",
|
|
136310
|
+
"## \u8F93\u51FA\u5FC5\u987B\u56DE\u7B54",
|
|
136311
|
+
"- \u6211\u62FF\u5230\u4E86\u4EC0\u4E48\uFF1A\u4EA7\u54C1\u3001\u6587\u6863\u3001\u65B9\u6848\u3001\u4ED3\u5E93\u6216\u5176\u5B83\u76F4\u63A5\u56DE\u7B54\u9700\u6C42\u7684\u7ED3\u679C\u3002",
|
|
136312
|
+
"- \u5728\u54EA\u91CC\u62FF\uFF1A\u7ED9\u51FA\u53EF\u8BBF\u95EE\u5730\u5740\u3001\u4E0B\u8F7D\u4F4D\u7F6E\u3001\u4ED3\u5E93/\u7248\u672C\u6216\u5176\u5B83\u51C6\u786E\u5B9A\u4F4D\u3002",
|
|
136313
|
+
"- \u63A5\u4E0B\u6765\u600E\u4E48\u7528\uFF1A\u7ED9\u51FA\u5B89\u88C5\u3001\u6253\u5F00\u3001\u4E0A\u4F20\u3001\u6388\u6743\u6216\u4E3B\u8981\u64CD\u4F5C\u6B65\u9AA4\u3002",
|
|
136314
|
+
"- \u5F53\u524D\u662F\u54EA\u4E00\u7248\uFF1A\u5F15\u7528\u5404\u4E0A\u6E38\u5F53\u524D\u4EA4\u4ED8\u7248\u672C\uFF1B\u4E0A\u6E38\u53D8\u5316\u540E\u751F\u6210\u65B0\u7684\u5B8C\u6574\u6C47\u603B\u7248\u672C\uFF0C\u4E0D\u8986\u76D6\u5386\u53F2\u3002",
|
|
136315
|
+
"",
|
|
136316
|
+
"\u53EA\u5F15\u7528\u8F93\u5165\u8282\u70B9\u53CA\u5176\u4E0A\u6E38\u91CC\u7684\u771F\u5B9E\u4EA7\u7269\uFF0C\u4E0D\u8981\u81C6\u9020\u94FE\u63A5\u6216\u5B8C\u6210\u60C5\u51B5\u3002\u7F3A\u5C11\u53EF\u9886\u53D6\u7ED3\u679C\u6216\u5FC5\u8981\u4F7F\u7528\u8BF4\u660E\u65F6\uFF0C\u7528 `oasis gap` \u660E\u786E\u62A5\u544A\uFF0C\u8865\u9F50\u524D\u4E0D\u8981 conclude\u3002"
|
|
136317
|
+
].join("\n");
|
|
136318
|
+
}
|
|
136026
136319
|
function dedupeIssues(issues) {
|
|
136027
136320
|
const seen = /* @__PURE__ */ new Set();
|
|
136028
136321
|
const out = [];
|
|
@@ -136042,7 +136335,8 @@ function labelForType(type) {
|
|
|
136042
136335
|
design: "\u8BBE\u8BA1",
|
|
136043
136336
|
adr: "\u6280\u672F\u65B9\u6848",
|
|
136044
136337
|
dev: "\u5B9E\u73B0",
|
|
136045
|
-
qa: "\u6D4B\u8BD5\u9A8C\u6536"
|
|
136338
|
+
qa: "\u6D4B\u8BD5\u9A8C\u6536",
|
|
136339
|
+
[DELIVERY_SUMMARY_ARTIFACT_TYPE]: "\u4EA4\u4ED8\u6C47\u603B"
|
|
136046
136340
|
};
|
|
136047
136341
|
return labels[type] ?? type;
|
|
136048
136342
|
}
|
|
@@ -136054,16 +136348,26 @@ var DEFAULT_TYPES, WORKORDER_SPEC_PREFIX;
|
|
|
136054
136348
|
var init_planner = __esm({
|
|
136055
136349
|
"../server/src/domains/collab/planner.ts"() {
|
|
136056
136350
|
"use strict";
|
|
136351
|
+
init_src();
|
|
136057
136352
|
init_src2();
|
|
136058
136353
|
init_identity();
|
|
136059
136354
|
DEFAULT_TYPES = [
|
|
136060
|
-
// brief 的 goal/acceptanceCriteria
|
|
136355
|
+
// brief 的 goal/acceptanceCriteria 现在是【自定义字段】
|
|
136356
|
+
//(Phase 3,替代旧 OASIS_WORKORDER_SPEC 批注,铲 #1 死锁根)。
|
|
136061
136357
|
// brief 不绑岗位:内置产物,owner 恒 = 发起人本人(决策 0026)——ownerRole 从不被解析。
|
|
136062
136358
|
{ name: "brief", contentType: "text", fieldDefs: [
|
|
136063
136359
|
{ name: "goal", type: "string", description: "\u4E00\u53E5\u8BDD\u76EE\u6807\uFF1A\u8FD9\u4E2A\u5DE5\u5355\u8981\u8FBE\u6210\u4EC0\u4E48" },
|
|
136064
136360
|
{ name: "acceptanceCriteria", type: "string[]", description: "\u9A8C\u6536\u6761\u76EE\uFF08\u6EE1\u8DB3\u5373\u7B97\u5B8C\u6210\uFF09" },
|
|
136065
136361
|
{ name: "manager", type: "string", description: "\u672C\u5DE5\u5355\u7BA1\u7406\u8005 agent\uFF08\u966A\u53D1\u8D77\u4EBA\u804A\u51FA\u6B64\u5355\u7684 AI \u5B9E\u4F8B\uFF09\uFF1A\u8D1F\u8D23\u672C\u5DE5\u5355\u7684\u534F\u8C03/\u515C\u5E95\uFF0C\u641E\u4E0D\u5B9A\u5347\u7EA7\u7ED9 owner\uFF08\u51B3\u7B56 0026\uFF09" }
|
|
136066
136362
|
] },
|
|
136363
|
+
{
|
|
136364
|
+
name: DELIVERY_SUMMARY_ARTIFACT_TYPE,
|
|
136365
|
+
contentType: "text",
|
|
136366
|
+
description: "\u7CFB\u7EDF\u751F\u6210\u7684\u5DE5\u5355\u672B\u7AEF\u95ED\u73AF\uFF1A\u7531\u672C\u5DE5\u5355\u7BA1\u7406\u8005\u628A\u534F\u4F5C\u6D41\u91CC\u7684\u6700\u7EC8\u7ED3\u679C\u6574\u7406\u6210\u4E00\u4EFD\u53EF\u9886\u53D6\u3001\u53EF\u5B9A\u4F4D\u3001\u53EF\u4F7F\u7528\u7684\u4EA4\u4ED8\uFF1B\u4E0D\u627F\u62C5\u9A8C\u6536\u3002",
|
|
136367
|
+
// 交付汇总是普通文本产物节点,视觉沿用 PRD 的 blue;不另造“封箱/验收”身份。
|
|
136368
|
+
appearance: { accent: "blue" },
|
|
136369
|
+
cascade: "auto"
|
|
136370
|
+
},
|
|
136067
136371
|
{ name: "prd", contentType: "text", ownerRole: "pm" },
|
|
136068
136372
|
{ name: "research", contentType: "text", ownerRole: "research" },
|
|
136069
136373
|
{ name: "design", contentType: "text", ownerRole: "designer" },
|
|
@@ -136214,6 +136518,7 @@ function buildWorkorderDetail(model, workspaceId, resolveActor, resolveProject,
|
|
|
136214
136518
|
};
|
|
136215
136519
|
};
|
|
136216
136520
|
const runtimeByArtifact = buildRuntimeByArtifact(dispatchJournal, ref2);
|
|
136521
|
+
const hasDeliverySummary = arts.some((a) => a.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
136217
136522
|
const nodes = arts.map((a) => {
|
|
136218
136523
|
const info = nodeInfo(model, a);
|
|
136219
136524
|
const observedRuntime = runtimeByArtifact.get(a.id);
|
|
@@ -136242,6 +136547,7 @@ function buildWorkorderDetail(model, workspaceId, resolveActor, resolveProject,
|
|
|
136242
136547
|
queue: info.queueLen,
|
|
136243
136548
|
blocked: blockedOf(model, a.id).blocked,
|
|
136244
136549
|
owner: ref2(a.owner),
|
|
136550
|
+
...(hasDeliverySummary ? a.type === DELIVERY_SUMMARY_ARTIFACT_TYPE : a.isFinalOutput === true) ? { isFinalOutput: true } : {},
|
|
136245
136551
|
// 封存原因透出:stage 只到 "sealed" 粒度,原因(accepted/cancelled/frozen)另给,供前端区分展示。
|
|
136246
136552
|
...lifecycle !== "active" ? { sealedReason: lifecycle.slice("sealed:".length) } : {},
|
|
136247
136553
|
...runtime ? { runtime } : {},
|
|
@@ -136315,6 +136621,7 @@ function buildWorkorderDraftDetail(draft, resolveActor, typeReviewerPreview) {
|
|
|
136315
136621
|
return { id, ...extra?.name ? { name: extra.name } : {}, ...extra?.role ? { role: extra.role } : {}, ...extra?.avatar ? { avatar: extra.avatar } : {} };
|
|
136316
136622
|
};
|
|
136317
136623
|
const spawns = draft.plan.ops.filter((op) => op.action === "spawn" && !!op.id);
|
|
136624
|
+
const hasDeliverySummary = spawns.some((op) => op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE);
|
|
136318
136625
|
const nodes = spawns.map((op) => {
|
|
136319
136626
|
const manual = draft.plan.ops.find((o) => o.action === "edit" && o.artifactId === op.id)?.reviewers?.filter((r) => r.source === "manual").map((r) => r.actor) ?? [];
|
|
136320
136627
|
const typePv = typeReviewerPreview?.(op.type) ?? null;
|
|
@@ -136328,6 +136635,7 @@ function buildWorkorderDraftDetail(draft, resolveActor, typeReviewerPreview) {
|
|
|
136328
136635
|
queue: 0,
|
|
136329
136636
|
blocked: false,
|
|
136330
136637
|
owner: ref2(op.owner ?? draft.draftedBy),
|
|
136638
|
+
...(hasDeliverySummary ? op.type === DELIVERY_SUMMARY_ARTIFACT_TYPE : op.isFinalOutput === true) ? { isFinalOutput: true } : {},
|
|
136331
136639
|
...pv ? { reviewers: pv.reviewers.map((r) => ({ actor: ref2(r.actor), source: r.source })), quorum: pv.quorum, typeName: pv.typeName } : {}
|
|
136332
136640
|
};
|
|
136333
136641
|
});
|
|
@@ -136606,6 +136914,7 @@ var init_workorder_detail = __esm({
|
|
|
136606
136914
|
"../server/src/domains/collab/workorder-detail.ts"() {
|
|
136607
136915
|
"use strict";
|
|
136608
136916
|
init_src2();
|
|
136917
|
+
init_src();
|
|
136609
136918
|
init_node_state();
|
|
136610
136919
|
init_stall();
|
|
136611
136920
|
init_workorders();
|
|
@@ -137503,10 +137812,11 @@ async function runCommand(kernel, blobs, oplog, actor, command, args, ctx = {})
|
|
|
137503
137812
|
const goal = optStr(args, "goal");
|
|
137504
137813
|
const rawCriteria = args["acceptance_criteria"] ?? args["acceptanceCriteria"];
|
|
137505
137814
|
const acceptanceCriteria = Array.isArray(rawCriteria) ? rawCriteria.filter((x2) => typeof x2 === "string" && x2.trim().length > 0).map((x2) => x2.trim()) : void 0;
|
|
137506
|
-
const briefForPlanner =
|
|
137507
|
-
|
|
137508
|
-
|
|
137509
|
-
${acceptanceCriteria.map((c) => `- ${c}`).join("\n")}` :
|
|
137815
|
+
const briefForPlanner = [
|
|
137816
|
+
brief,
|
|
137817
|
+
...acceptanceCriteria && acceptanceCriteria.length > 0 ? [`\u9A8C\u6536\u6807\u51C6\uFF1A
|
|
137818
|
+
${acceptanceCriteria.map((c) => `- ${c}`).join("\n")}`] : []
|
|
137819
|
+
].join("\n\n");
|
|
137510
137820
|
const agentIssues = [];
|
|
137511
137821
|
let agentPlan = null;
|
|
137512
137822
|
const inlinePlan = args["plan"];
|
|
@@ -137654,7 +137964,6 @@ ${acceptanceCriteria.map((c) => `- ${c}`).join("\n")}` : brief;
|
|
|
137654
137964
|
return annotation !== void 0 && isHumanChangeRequest(annotation);
|
|
137655
137965
|
}) : hasOpenHumanChangeRequest2(kernel, artifactId));
|
|
137656
137966
|
const changeRequestParent = resolves !== void 0 ? latestDeclaredRevisionAnchor(kernel, resolves) : isAgent(actor) ? latestOpenHumanChangeRequestParent(kernel, artifactId) : void 0;
|
|
137657
|
-
const holdForReview = args["holdForReview"] === true || args["review"] === true;
|
|
137658
137967
|
const continuation = args["continuation"];
|
|
137659
137968
|
if (continuation !== void 0 && (continuation === null || typeof continuation !== "object" || continuation.checkpoint !== true || continuation.continue !== true)) {
|
|
137660
137969
|
throw new Error("continuation \u5FC5\u987B\u662F { checkpoint: true, continue: true }");
|
|
@@ -137678,7 +137987,7 @@ ${acceptanceCriteria.map((c) => `- ${c}`).join("\n")}` : brief;
|
|
|
137678
137987
|
const typeDefForLand = artForLand ? ctx.schema?.find((t) => t.name === artForLand.type) : void 0;
|
|
137679
137988
|
const isExternalFF = handlerForType(typeDefForLand?.contentType)?.mergeMode === "external-ff";
|
|
137680
137989
|
let landed = false;
|
|
137681
|
-
if (!
|
|
137990
|
+
if (!requiresHumanReview && qBefore === 0 && (revision.part === void 0 || parts.length <= 1 || isExternalFF)) {
|
|
137682
137991
|
try {
|
|
137683
137992
|
const r = await kernel.advanceQueue(artifactId, actor);
|
|
137684
137993
|
landed = r.landed.some((x2) => x2.id === revision.id);
|
|
@@ -137686,7 +137995,8 @@ ${acceptanceCriteria.map((c) => `- ${c}`).join("\n")}` : brief;
|
|
|
137686
137995
|
} catch {
|
|
137687
137996
|
}
|
|
137688
137997
|
}
|
|
137689
|
-
|
|
137998
|
+
const tail = landed ? " \u2192 \u5DF2\u843D\u5730\u4E3A head" : requiresHumanReview ? " \u2192 \u7B49\u5F85\u4EBA\u5DE5\u5BA1\u6838" : pendingConcludeAttempt(kernel.model, artifactId) ? " \u2192 \u5DF2\u5165\u961F\uFF1B\u5F53\u524D\u4EA7\u7269\u6B63\u5728\u6536\u5C3E\u8BC4\u5BA1\uFF08\u6682\u51BB\u7ED3\uFF09\uFF0C\u8BC4\u5BA1\u51FA\u7ED3\u679C\u3001\u89E3\u51BB\u540E\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u628A\u5B83\u843D\u4E3A head\u2014\u2014\u65E0\u9700\u91CD\u8BD5" : kernel.isFrozen(artifactId) ? " \u2192 \u5DF2\u5165\u961F\uFF1B\u5F53\u524D\u4EA7\u7269\u88AB\u51BB\u7ED3\uFF08\u96C6\u6210/\u6539\u56FE\u4E2D\uFF09\uFF0C\u89E3\u51BB\u540E\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u63A8\u8FDB\u2014\u2014\u65E0\u9700\u91CD\u8BD5" : "";
|
|
137999
|
+
return { message: `proposed ${revision.id} base=${revision.base ?? "\u2205"}\uFF08${revision.contentKind}\uFF09${revision.part ? ` part=${revision.part}` : ""}${tail}`, data: revision };
|
|
137690
138000
|
}
|
|
137691
138001
|
case "merge": {
|
|
137692
138002
|
const revisionId = optStr(args, "revisionId");
|
|
@@ -138530,6 +138840,8 @@ async function startOasisServer(opts) {
|
|
|
138530
138840
|
);
|
|
138531
138841
|
return;
|
|
138532
138842
|
}
|
|
138843
|
+
const trustedDraft = targetWs && opts.workorderDrafts ? await opts.workorderDrafts.forWorkspace(targetWs) : void 0;
|
|
138844
|
+
assertDeliverySummaryPlanIntegrity(body.plan, trustedDraft?.plan);
|
|
138533
138845
|
const principalRegistry = engine.registry ?? opts.registry;
|
|
138534
138846
|
if (principalRegistry) {
|
|
138535
138847
|
const principalErrors = await validateWorkorderPrincipals(body.plan, body.briefArtifactId, (id) => principalRegistry.getActor(id));
|
|
@@ -138685,71 +138997,26 @@ async function startOasisServer(opts) {
|
|
|
138685
138997
|
try {
|
|
138686
138998
|
const body = JSON.parse(rawBody || "{}");
|
|
138687
138999
|
const ctx = resolveDiscussContext(engine.kernel.model, body, actor ?? void 0);
|
|
138688
|
-
let retainedRt = opts.retainedSession?.(
|
|
138689
|
-
body.annotationId ? { annotationId: body.annotationId, ...ctx.anchorArtifactId ? { artifactId: ctx.anchorArtifactId } : {} } : body
|
|
138690
|
-
);
|
|
138691
|
-
if (!retainedRt && opts.escalateDiscussRetain && body.artifactId) {
|
|
138692
|
-
const raw = opts.escalateDiscussRetain.get(`esc:${body.artifactId}`);
|
|
138693
|
-
if (raw) {
|
|
138694
|
-
try {
|
|
138695
|
-
const rec = JSON.parse(raw);
|
|
138696
|
-
if (rec.runtimeSessionId && rec.human === ctx.ownerId) retainedRt = rec.runtimeSessionId;
|
|
138697
|
-
} catch {
|
|
138698
|
-
}
|
|
138699
|
-
}
|
|
138700
|
-
}
|
|
138701
|
-
if (retainedRt && body.draftId && opts.escalateDiscussRetain) {
|
|
138702
|
-
const claimKey = `draftclaim:${body.draftId}`;
|
|
138703
|
-
const claimer = opts.escalateDiscussRetain.get(claimKey);
|
|
138704
|
-
if (claimer && claimer !== ctx.ownerId) retainedRt = void 0;
|
|
138705
|
-
else if (!claimer) opts.escalateDiscussRetain.set(claimKey, ctx.ownerId);
|
|
138706
|
-
}
|
|
138707
139000
|
const chatStore = opts.chatSession;
|
|
138708
139001
|
const baseItemKey = body.draftId ? `draft:${body.draftId}` : body.annotationId ? `ann:${body.annotationId}` : `esc:${body.artifactId}`;
|
|
138709
139002
|
const itemKey = `${baseItemKey}:${ctx.ownerId}`;
|
|
138710
139003
|
let chatSessionId;
|
|
138711
|
-
let createdThisCall = false;
|
|
138712
139004
|
if (chatStore) {
|
|
138713
139005
|
const { randomUUID: randomUUID22 } = await import("node:crypto");
|
|
138714
139006
|
const known = discussSessions.get(itemKey);
|
|
138715
139007
|
if (known && await chatStore.getSession(known).catch(() => null)) chatSessionId = known;
|
|
138716
139008
|
if (!chatSessionId) {
|
|
138717
139009
|
chatSessionId = randomUUID22();
|
|
138718
|
-
createdThisCall = true;
|
|
138719
139010
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
138720
139011
|
const title = `\u89E3\u51B3\uFF1A${ctx.seed.slice(ctx.seed.indexOf("\uFF1A") + 1, ctx.seed.indexOf("\uFF1A") + 25) || "\u5DE5\u5355\u5361\u70B9"}`;
|
|
138721
139012
|
const reg0 = (await resolveEngine(currentCompanyId).catch(() => null))?.registry ?? opts.registry;
|
|
138722
139013
|
const mgrBinding = reg0 ? await reg0.getBinding(ctx.managerId).catch(() => null) : null;
|
|
138723
139014
|
const managerNodeId = mgrBinding?.status === "active" ? mgrBinding.nodeId : "";
|
|
138724
139015
|
const managerRuntimeKind = mgrBinding?.status === "active" ? mgrBinding.runtimeKind : void 0;
|
|
138725
|
-
await chatStore.createSession({ id: chatSessionId, humanActorId: ctx.ownerId, aiActorId: ctx.managerId, runtimeId: managerNodeId, ...managerRuntimeKind ? { runtimeKind: managerRuntimeKind } : {}, runtimeSessionId:
|
|
139016
|
+
await chatStore.createSession({ id: chatSessionId, humanActorId: ctx.ownerId, aiActorId: ctx.managerId, runtimeId: managerNodeId, ...managerRuntimeKind ? { runtimeKind: managerRuntimeKind } : {}, runtimeSessionId: null, title, touchedAt: now, createdAt: now, workspace: ctx.workspace }).catch(() => void 0);
|
|
138726
139017
|
await chatStore.linkWorkOrder(chatSessionId, ctx.workspace).catch(() => void 0);
|
|
138727
139018
|
}
|
|
138728
139019
|
discussSessions.set(itemKey, chatSessionId);
|
|
138729
|
-
await chatStore.appendMessage({ id: randomUUID22(), sessionId: chatSessionId, role: "user", content: ctx.seed, createdAt: (/* @__PURE__ */ new Date()).toISOString() }).catch(() => void 0);
|
|
138730
|
-
}
|
|
138731
|
-
let session;
|
|
138732
|
-
try {
|
|
138733
|
-
session = await opts.dispatchChat({ actorId: ctx.managerId, message: ctx.seed, workspace: ctx.workspace, ...retainedRt ? { sessionId: retainedRt } : {}, ...chatSessionId ? { chatSessionId } : {} });
|
|
138734
|
-
} catch (err) {
|
|
138735
|
-
if (createdThisCall && chatStore && chatSessionId) {
|
|
138736
|
-
await chatStore.deleteSession(chatSessionId).catch(() => void 0);
|
|
138737
|
-
discussSessions.delete(itemKey);
|
|
138738
|
-
}
|
|
138739
|
-
throw err;
|
|
138740
|
-
}
|
|
138741
|
-
if (chatStore && chatSessionId) {
|
|
138742
|
-
const sid = chatSessionId;
|
|
138743
|
-
let reply = "";
|
|
138744
|
-
session.onOutput((chunk) => {
|
|
138745
|
-
reply += chunk;
|
|
138746
|
-
});
|
|
138747
|
-
void session.done.then(async () => {
|
|
138748
|
-
const { randomUUID: randomUUID22 } = await import("node:crypto");
|
|
138749
|
-
if (reply || session.runId) {
|
|
138750
|
-
await chatStore.appendMessage({ id: randomUUID22(), sessionId: sid, role: "assistant", content: reply, createdAt: (/* @__PURE__ */ new Date()).toISOString(), ...session.runId ? { runId: session.runId } : {} }).catch(() => void 0);
|
|
138751
|
-
}
|
|
138752
|
-
}).catch(() => void 0);
|
|
138753
139020
|
}
|
|
138754
139021
|
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ sessionId: chatSessionId ?? null, managerId: ctx.managerId, workspace: ctx.workspace }));
|
|
138755
139022
|
} catch (err) {
|
|
@@ -147373,12 +147640,12 @@ function scrubLeakyEnv(env) {
|
|
|
147373
147640
|
}
|
|
147374
147641
|
function classifyExit(result) {
|
|
147375
147642
|
if (!result) return void 0;
|
|
147376
|
-
|
|
147377
|
-
|
|
147378
|
-
if (
|
|
147379
|
-
|
|
147380
|
-
if (
|
|
147381
|
-
return
|
|
147643
|
+
if (result.stop_reason === "max_tokens") return "output-limit";
|
|
147644
|
+
const subtypeSaysError = String(result.subtype ?? "").startsWith("error");
|
|
147645
|
+
if (result.is_error !== true && !subtypeSaysError) return "clean";
|
|
147646
|
+
const status = Number(result.api_error_status);
|
|
147647
|
+
if (status === 429 || status === 529) return "rate-limit";
|
|
147648
|
+
return "error";
|
|
147382
147649
|
}
|
|
147383
147650
|
var import_node_child_process7, import_node_crypto13, fs10, path9, readline, ONE_SHOT_UNSAFE_TOOLS, ClaudeCodeAdapter;
|
|
147384
147651
|
var init_claude_code = __esm({
|
|
@@ -157408,7 +157675,7 @@ ${body || "\uFF08\u672A\u586B\u5199\uFF09"}`;
|
|
|
157408
157675
|
"\u7531\u300C\u5267\u672C \xB7 Bug \u4FEE\u590D\u300D\u53D1\u8D77\u3002"
|
|
157409
157676
|
].join("\n");
|
|
157410
157677
|
const plan = {
|
|
157411
|
-
nodes: BUG_FIX_STRUCTURE.map((n) => ({ type: n.type, title: n.title, dependsOn: n.dependsOn, brief: n.brief(title) }))
|
|
157678
|
+
nodes: BUG_FIX_STRUCTURE.map((n) => ({ type: n.type, title: n.title, dependsOn: n.dependsOn, brief: n.brief(title), ...n.isFinalOutput ? { isFinalOutput: true } : {} }))
|
|
157412
157679
|
};
|
|
157413
157680
|
return {
|
|
157414
157681
|
produces: "workorder",
|
|
@@ -157470,7 +157737,8 @@ var init_registry2 = __esm({
|
|
|
157470
157737
|
title: "\u590D\u73B0\u9A8C\u8BC1\u4E0E\u56DE\u5F52",
|
|
157471
157738
|
dependsOn: ["dev:\u4FEE\u590D\u5B9E\u73B0"],
|
|
157472
157739
|
role: "\u6D4B\u8BD5",
|
|
157473
|
-
brief: () => `\u6309 brief \u91CC\u7684\u590D\u73B0\u6B65\u9AA4\u9A8C\u8BC1 bug \u5DF2\u4FEE\u590D\uFF08\u4E0D\u518D\u590D\u73B0\uFF09\uFF1B\u8865\u5145\u5E76\u8FD0\u884C\u56DE\u5F52\u7528\u4F8B\uFF0C\u786E\u8BA4\u6CA1\u6709\u5F15\u5165\u65B0\u56DE\u5F52\u3002\u4EA7\u51FA\u6D4B\u8BD5\u62A5\u544A\u3002
|
|
157740
|
+
brief: () => `\u6309 brief \u91CC\u7684\u590D\u73B0\u6B65\u9AA4\u9A8C\u8BC1 bug \u5DF2\u4FEE\u590D\uFF08\u4E0D\u518D\u590D\u73B0\uFF09\uFF1B\u8865\u5145\u5E76\u8FD0\u884C\u56DE\u5F52\u7528\u4F8B\uFF0C\u786E\u8BA4\u6CA1\u6709\u5F15\u5165\u65B0\u56DE\u5F52\u3002\u4EA7\u51FA\u6D4B\u8BD5\u62A5\u544A\u3002`,
|
|
157741
|
+
isFinalOutput: true
|
|
157474
157742
|
}
|
|
157475
157743
|
];
|
|
157476
157744
|
BUILTIN2 = {
|
|
@@ -159072,6 +159340,94 @@ var init_builtin_skills = __esm({
|
|
|
159072
159340
|
}
|
|
159073
159341
|
});
|
|
159074
159342
|
|
|
159343
|
+
// ../server/src/design/board-watch.ts
|
|
159344
|
+
function decideBoardLetter(c, nowMs, quietMs) {
|
|
159345
|
+
if (c.boardMtime === null) return false;
|
|
159346
|
+
if (!c.hasRevision) return false;
|
|
159347
|
+
if (c.lastOpAtMs === null || c.boardMtime <= c.lastOpAtMs) return false;
|
|
159348
|
+
if (nowMs - c.boardMtime < quietMs) return false;
|
|
159349
|
+
if (c.hasOpenWatchLetter) return false;
|
|
159350
|
+
if (c.lastWatchMtime !== null && c.boardMtime <= c.lastWatchMtime) return false;
|
|
159351
|
+
return true;
|
|
159352
|
+
}
|
|
159353
|
+
var MARKER_PREFIX, boardWatchMarker, parseMarker, BoardWatcher;
|
|
159354
|
+
var init_board_watch = __esm({
|
|
159355
|
+
"../server/src/design/board-watch.ts"() {
|
|
159356
|
+
"use strict";
|
|
159357
|
+
init_src2();
|
|
159358
|
+
MARKER_PREFIX = "[od-board-watch mtime:";
|
|
159359
|
+
boardWatchMarker = (mtimeMs) => `${MARKER_PREFIX}${mtimeMs}]`;
|
|
159360
|
+
parseMarker = (body) => {
|
|
159361
|
+
const i = body.indexOf(MARKER_PREFIX);
|
|
159362
|
+
if (i < 0) return null;
|
|
159363
|
+
const n = Number.parseInt(body.slice(i + MARKER_PREFIX.length), 10);
|
|
159364
|
+
return Number.isFinite(n) ? n : null;
|
|
159365
|
+
};
|
|
159366
|
+
BoardWatcher = class {
|
|
159367
|
+
constructor(deps) {
|
|
159368
|
+
this.deps = deps;
|
|
159369
|
+
}
|
|
159370
|
+
/** 查一块板的交付物(排 task-context/、只算带 artifactManifest 的)。404/网络错 → null(板不存在)。 */
|
|
159371
|
+
async boardFiles(boardKey) {
|
|
159372
|
+
const fetchImpl = this.deps.fetchImpl ?? fetch;
|
|
159373
|
+
try {
|
|
159374
|
+
const res = await fetchImpl(`${this.deps.odBase}/api/projects/${encodeURIComponent(boardKey)}/files`);
|
|
159375
|
+
if (!res.ok) return null;
|
|
159376
|
+
const body = await res.json();
|
|
159377
|
+
return (body.files ?? []).filter((f2) => !f2.path.startsWith("task-context/") && f2.artifactManifest !== void 0).map((f2) => ({ path: f2.path, kind: f2.kind ?? null, mtime: f2.mtime ?? null }));
|
|
159378
|
+
} catch {
|
|
159379
|
+
return null;
|
|
159380
|
+
}
|
|
159381
|
+
}
|
|
159382
|
+
async tick(now = Date.now()) {
|
|
159383
|
+
const { kernel, boardKeyOf, log: log3 } = this.deps;
|
|
159384
|
+
const quietMs = this.deps.quietMs ?? 10 * 6e4;
|
|
159385
|
+
const maxPerTick = this.deps.maxLettersPerTick ?? 2;
|
|
159386
|
+
const actor = this.deps.actor ?? "actor:system";
|
|
159387
|
+
const model = kernel.model;
|
|
159388
|
+
let written = 0;
|
|
159389
|
+
for (const a of model.artifacts.values()) {
|
|
159390
|
+
if (a.type !== "design") continue;
|
|
159391
|
+
if (lifecycleOf(model, a.id) !== "active") continue;
|
|
159392
|
+
if (written >= maxPerTick) {
|
|
159393
|
+
log3?.(`[board-watch] \u672C\u8F6E\u5199\u4FE1\u5DF2\u8FBE\u4E0A\u9650 ${maxPerTick}\uFF0C\u5176\u4F59\u677F\u4E0B\u8F6E\u518D\u770B`);
|
|
159394
|
+
break;
|
|
159395
|
+
}
|
|
159396
|
+
const boardKey = boardKeyOf(a.id);
|
|
159397
|
+
const files = await this.boardFiles(boardKey);
|
|
159398
|
+
if (!files || files.length === 0) continue;
|
|
159399
|
+
const boardMtime = files.reduce((mx, f2) => f2.mtime !== null && (mx === null || f2.mtime > mx) ? f2.mtime : mx, null);
|
|
159400
|
+
const watchLetters = annotationsOf(model, a.id).filter((x2) => x2.author === actor && parseMarker(x2.body) !== null);
|
|
159401
|
+
const lastOpAt = model.lastOpAt.get(a.id);
|
|
159402
|
+
const candidate = {
|
|
159403
|
+
boardMtime,
|
|
159404
|
+
hasRevision: revisionsOf(model, a.id).length > 0,
|
|
159405
|
+
lastOpAtMs: lastOpAt ? Date.parse(lastOpAt) : null,
|
|
159406
|
+
hasOpenWatchLetter: watchLetters.some((x2) => x2.state === "open"),
|
|
159407
|
+
lastWatchMtime: watchLetters.reduce((mx, x2) => {
|
|
159408
|
+
const m2 = parseMarker(x2.body);
|
|
159409
|
+
return m2 !== null && (mx === null || m2 > mx) ? m2 : mx;
|
|
159410
|
+
}, null)
|
|
159411
|
+
};
|
|
159412
|
+
if (!decideBoardLetter(candidate, now, quietMs)) continue;
|
|
159413
|
+
const newest = files.filter((f2) => f2.mtime !== null && candidate.lastOpAtMs !== null && f2.mtime > candidate.lastOpAtMs).sort((x2, y) => (y.mtime ?? 0) - (x2.mtime ?? 0));
|
|
159414
|
+
const listed = (newest.length > 0 ? newest : files).slice(0, 5).map((f2) => `- ${f2.path}\uFF08${f2.kind ?? "?"}\uFF09\xB7 ${f2.mtime ? new Date(f2.mtime).toISOString() : "?"}`).join("\n");
|
|
159415
|
+
const body = [
|
|
159416
|
+
boardWatchMarker(boardMtime),
|
|
159417
|
+
`\u753B\u677F ${boardKey} \u4E0A\u6709 Oasis \u4E4B\u5916\u7684\u65B0\u52A8\u9759\uFF08\u4EBA\u5728\u677F\u4E0A\u5BF9\u8BDD/\u6539\u7A3F\uFF0C\u6216\u5F15\u64CE\u4EA7\u4E86\u6CA1\u4EBA\u6536\u7684\u65B0\u7248\uFF09\uFF0C\u6BD4\u672C\u4EA7\u7269\u6700\u8FD1\u4E00\u6B21\u64CD\u4F5C\uFF08${lastOpAt ?? "?"}\uFF09\u65B0\u3001\u4E14\u5DF2\u9759\u9ED8 ${Math.round(quietMs / 6e4)} \u5206\u949F\uFF1A`,
|
|
159418
|
+
listed,
|
|
159419
|
+
``,
|
|
159420
|
+
`\u8BF7\u53D6\u8D27\u6838\u5BF9\uFF1A\`oasis design status ${a.id} --pull\` \u2192 \u5185\u5BB9\u5408\u610F\u5C31 \`oasis propose ${a.id} --from-dir <\u76EE\u5F55> --reason "<\u6536\u5F55\u677F\u4E0A\u4EBA\u5DE5\u8FED\u4EE3>"\` \u6536\u5F55\u4E3A\u65B0\u7248\u672C\uFF1B\u4E0D\u5408\u610F/\u4E0D\u5FC5\u6536\u5F55\uFF0C\u56DE\u5E16\u8BF4\u660E\u540E\u6309 wontfix \u5904\u7406\u5373\u53EF\uFF08\u540C\u4E00\u7248\u4E0D\u4F1A\u518D\u6765\u4FE1\uFF09\u3002`
|
|
159421
|
+
].join("\n");
|
|
159422
|
+
await kernel.annotate({ artifactId: a.id, actor, body, kind: "comment" });
|
|
159423
|
+
written++;
|
|
159424
|
+
log3?.(`[board-watch] ${a.id} \u2190 \u677F ${boardKey} \u6709\u65B0\u5185\u5BB9\uFF08mtime=${new Date(boardMtime).toISOString()}\uFF09\u2192 \u5DF2\u5199\u4FE1\u5524 owner`);
|
|
159425
|
+
}
|
|
159426
|
+
}
|
|
159427
|
+
};
|
|
159428
|
+
}
|
|
159429
|
+
});
|
|
159430
|
+
|
|
159075
159431
|
// ../server/src/index.ts
|
|
159076
159432
|
var init_src7 = __esm({
|
|
159077
159433
|
"../server/src/index.ts"() {
|
|
@@ -159128,6 +159484,7 @@ var init_src7 = __esm({
|
|
|
159128
159484
|
init_workorder_drafts();
|
|
159129
159485
|
init_builtin_skills();
|
|
159130
159486
|
init_connector_skills();
|
|
159487
|
+
init_board_watch();
|
|
159131
159488
|
}
|
|
159132
159489
|
});
|
|
159133
159490
|
|
|
@@ -169845,6 +170202,14 @@ async function startServe(opts) {
|
|
|
169845
170202
|
console.error(`[cascade] ${action.artifactId} \u5931\u8D25: ${String(err)}`);
|
|
169846
170203
|
}
|
|
169847
170204
|
}
|
|
170205
|
+
for (const { artifactId } of computeAdvanceableRevisions(kernel.model, schemaMap)) {
|
|
170206
|
+
try {
|
|
170207
|
+
const landed = await kernel.advanceOrphans(artifactId);
|
|
170208
|
+
for (const rev of landed) console.log(`[self-heal] ${artifactId} \u8865\u843D\u5B64\u513F\u961F\u9996 ${rev.id}\uFF08\u89E3\u51BB\u540E\u9057\u7559\uFF0C60s \u5FAA\u73AF\u515C\u5E95\uFF09`);
|
|
170209
|
+
} catch (err) {
|
|
170210
|
+
console.error(`[self-heal] ${artifactId} \u8865\u843D\u5931\u8D25: ${String(err)}`);
|
|
170211
|
+
}
|
|
170212
|
+
}
|
|
169848
170213
|
for (const a of kernel.model.artifacts.values()) {
|
|
169849
170214
|
if (!a.owner.startsWith("actor:human:")) continue;
|
|
169850
170215
|
if (lifecycleOf(kernel.model, a.id) !== "active") continue;
|
|
@@ -170083,6 +170448,18 @@ async function startServe(opts) {
|
|
|
170083
170448
|
const automationTimer = setInterval(() => {
|
|
170084
170449
|
void automationScheduler.tick().catch((err) => console.error(`[automation-scheduler] tick \u5931\u8D25: ${String(err)}`));
|
|
170085
170450
|
}, 3e4);
|
|
170451
|
+
let boardWatchTimer;
|
|
170452
|
+
const boardWatchFlag = (process.env["OASIS_BOARD_WATCH"] ?? "").trim().toLowerCase();
|
|
170453
|
+
if (!["0", "false", "off"].includes(boardWatchFlag)) {
|
|
170454
|
+
const odBase = (process.env["OASIS_OPEN_DESIGN_URL"] ?? "http://127.0.0.1:7457").replace(/\/$/, "");
|
|
170455
|
+
const boardWatcher = new BoardWatcher({ kernel, odBase, boardKeyOf: deriveBoardKey, log: (m2) => console.log(m2) });
|
|
170456
|
+
boardWatchTimer = setInterval(() => {
|
|
170457
|
+
void boardWatcher.tick().catch((err) => console.error(`[board-watch] tick \u5931\u8D25: ${String(err)}`));
|
|
170458
|
+
}, 6e4);
|
|
170459
|
+
console.log(`[serve] \u753B\u677F\u76D1\u89C6\u5668\u5DF2\u542F\u7528\uFF08od=${odBase}\uFF0C\u9759\u9ED8\u7A97 10min\uFF0C\u6BCF\u8F6E\u4E0A\u9650 2 \u5C01\u4FE1\uFF1BOASIS_BOARD_WATCH=0 \u53EF\u5173\uFF09`);
|
|
170460
|
+
} else {
|
|
170461
|
+
console.log(`[serve] \u753B\u677F\u76D1\u89C6\u5668\u5DF2\u88AB OASIS_BOARD_WATCH=${boardWatchFlag} \u663E\u5F0F\u5173\u95ED`);
|
|
170462
|
+
}
|
|
170086
170463
|
return {
|
|
170087
170464
|
baseUrl: server.baseUrl,
|
|
170088
170465
|
operatorToken,
|
|
@@ -170095,6 +170472,7 @@ async function startServe(opts) {
|
|
|
170095
170472
|
if (livenessTimer) clearInterval(livenessTimer);
|
|
170096
170473
|
if (orphanSweepTimer) clearInterval(orphanSweepTimer);
|
|
170097
170474
|
clearInterval(automationTimer);
|
|
170475
|
+
if (boardWatchTimer) clearInterval(boardWatchTimer);
|
|
170098
170476
|
clearInterval(serverHeartbeatTimer);
|
|
170099
170477
|
hub?.close();
|
|
170100
170478
|
await server.close();
|
|
@@ -172403,7 +172781,7 @@ ${res.warning}`);
|
|
|
172403
172781
|
init_src6();
|
|
172404
172782
|
|
|
172405
172783
|
// src/index.ts
|
|
172406
|
-
var PKG_VERSION = true ? "0.1.
|
|
172784
|
+
var PKG_VERSION = true ? "0.1.63" : "dev";
|
|
172407
172785
|
var OASIS_DIR = path21.join(os9.homedir(), ".oasis");
|
|
172408
172786
|
var CONFIG_FILE = path21.join(OASIS_DIR, "node-config.json");
|
|
172409
172787
|
var PID_FILE = path21.join(OASIS_DIR, "node.pid");
|