@dawipong/opcflow 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +141 -76
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -837,6 +837,71 @@ var init_kind = __esm({
|
|
|
837
837
|
}
|
|
838
838
|
});
|
|
839
839
|
|
|
840
|
+
// core/roles.ts
|
|
841
|
+
function getRoleRegistry(config) {
|
|
842
|
+
const merged = {};
|
|
843
|
+
for (const [role, spec] of Object.entries(DEFAULT_ROLE_REGISTRY)) merged[role] = { ...spec };
|
|
844
|
+
for (const [role, kinds] of Object.entries(config.roleProduces ?? {})) {
|
|
845
|
+
merged[role] = { ...merged[role] ?? { produces: [] }, produces: kinds };
|
|
846
|
+
}
|
|
847
|
+
for (const [role, override] of Object.entries(config.roles ?? {})) {
|
|
848
|
+
merged[role] = { ...merged[role] ?? { produces: [] }, ...override };
|
|
849
|
+
}
|
|
850
|
+
return merged;
|
|
851
|
+
}
|
|
852
|
+
function ownerRoleOf(config, kind) {
|
|
853
|
+
for (const [role, spec] of Object.entries(getRoleRegistry(config))) {
|
|
854
|
+
if (spec.produces.includes(kind)) return role;
|
|
855
|
+
}
|
|
856
|
+
if (kind === "code") return "developer";
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
var DEFAULT_ROLE_REGISTRY;
|
|
860
|
+
var init_roles = __esm({
|
|
861
|
+
"core/roles.ts"() {
|
|
862
|
+
"use strict";
|
|
863
|
+
init_kind();
|
|
864
|
+
DEFAULT_ROLE_REGISTRY = {
|
|
865
|
+
"product-manager": {
|
|
866
|
+
produces: ["project", "roles", "glossary", "flow", "module-prd", "page-prd"]
|
|
867
|
+
},
|
|
868
|
+
architect: {
|
|
869
|
+
produces: ["db-doc", "api-doc"],
|
|
870
|
+
requires: [{ desc: "PM \u4EA7\u51FA(\u6A21\u5757/\u9875\u9762 PRD)", kinds: PM_KINDS }],
|
|
871
|
+
dispatch: [
|
|
872
|
+
{ at: "module", endpoint: "common", content: "\u8BBE\u8BA1 {module} \u6A21\u5757\u6570\u636E\u5E93" },
|
|
873
|
+
{ at: "module", endpoint: "service", content: "\u8BBE\u8BA1 {module} \u6A21\u5757 API \u6587\u6863" }
|
|
874
|
+
]
|
|
875
|
+
},
|
|
876
|
+
designer: {
|
|
877
|
+
produces: ["design-system", "design-prompt", "prototype"],
|
|
878
|
+
requires: [{ desc: "PM \u4EA7\u51FA(\u6A21\u5757/\u9875\u9762 PRD)", kinds: PM_KINDS }],
|
|
879
|
+
dispatch: [
|
|
880
|
+
{ at: "endpoint", ifMissingKind: "design-system", produces: ["design-system"], content: "\u5EFA\u7ACB {endpoint} \u7AEF\u8BBE\u8BA1\u7CFB\u7EDF(\u8BE5\u7AEF\u9996\u4E2A\u9875\u9762\u8BBE\u8BA1\u524D\u7F6E)" },
|
|
881
|
+
{ at: "page", produces: ["design-prompt", "prototype"], content: "\u8BBE\u8BA1 {endpoint}/{page} \u9875\u9762(\u63D0\u793A\u8BCD+\u539F\u578B)" }
|
|
882
|
+
]
|
|
883
|
+
},
|
|
884
|
+
developer: {
|
|
885
|
+
produces: ["code"],
|
|
886
|
+
requires: [
|
|
887
|
+
{ desc: "\u6570\u636E\u5E93\u6587\u6863", kinds: ["db-doc"] },
|
|
888
|
+
{ desc: "API \u6587\u6863", kinds: ["api-doc"], when: { endpointNot: "service" } },
|
|
889
|
+
{ desc: "designer {endpoint} \u8BBE\u8BA1\u7A3F", kinds: ["design-prompt", "prototype"], when: { endpointNot: "service" } }
|
|
890
|
+
],
|
|
891
|
+
dispatch: [
|
|
892
|
+
{ at: "module", endpoint: "service", content: "\u5B9E\u73B0 {module} \u6A21\u5757 service \u7AEF" },
|
|
893
|
+
{ at: "page", content: "\u5B9E\u73B0 {endpoint}/{page} \u9875\u9762" }
|
|
894
|
+
],
|
|
895
|
+
onQaFail: "rework"
|
|
896
|
+
},
|
|
897
|
+
qa: {
|
|
898
|
+
produces: ["acceptance"],
|
|
899
|
+
dispatch: [{ at: "page", type: "qa", content: "\u9A8C\u6536 {endpoint}/{page} \u9875\u9762" }]
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
|
|
840
905
|
// core/derive.ts
|
|
841
906
|
var derive_exports = {};
|
|
842
907
|
__export(derive_exports, {
|
|
@@ -974,31 +1039,22 @@ function levelFilter(level, task) {
|
|
|
974
1039
|
}
|
|
975
1040
|
}
|
|
976
1041
|
function producedKinds(ctx, task) {
|
|
977
|
-
const
|
|
978
|
-
if (
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
return
|
|
982
|
-
}
|
|
983
|
-
function existRequirements(task) {
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
return [{ desc: "\u6570\u636E\u5E93\u6587\u6863", level: "exist", kinds: ["db-doc"], filter: { module: m } }];
|
|
992
|
-
}
|
|
993
|
-
return [
|
|
994
|
-
{ desc: "\u6570\u636E\u5E93\u6587\u6863", level: "exist", kinds: ["db-doc"], filter: { module: m } },
|
|
995
|
-
{ desc: "API \u6587\u6863", level: "exist", kinds: ["api-doc"], filter: { module: m } },
|
|
996
|
-
{ desc: `designer ${task.endpoint} \u8BBE\u8BA1\u7A3F`, level: "exist", kinds: ["design-prompt", "prototype"], filter: { module: m, endpoint: task.endpoint } }
|
|
997
|
-
];
|
|
998
|
-
}
|
|
999
|
-
default:
|
|
1000
|
-
return [];
|
|
1042
|
+
const spec = getRoleRegistry(ctx.config)[task.role];
|
|
1043
|
+
if (!spec) return [];
|
|
1044
|
+
const wantPage = !!task.page;
|
|
1045
|
+
const rule = (spec.dispatch ?? []).find((d) => (wantPage ? d.at === "page" : d.at !== "page") && d.produces);
|
|
1046
|
+
return rule?.produces ?? spec.produces;
|
|
1047
|
+
}
|
|
1048
|
+
function existRequirements(ctx, task) {
|
|
1049
|
+
const spec = getRoleRegistry(ctx.config)[task.role];
|
|
1050
|
+
const reqs = [];
|
|
1051
|
+
for (const r of spec?.requires ?? []) {
|
|
1052
|
+
if (r.when?.endpoint && task.endpoint !== r.when.endpoint) continue;
|
|
1053
|
+
if (r.when?.endpointNot && task.endpoint === r.when.endpointNot) continue;
|
|
1054
|
+
const filter = r.kinds.includes("design-prompt") || r.kinds.includes("prototype") ? { module: task.module, endpoint: task.endpoint } : { module: task.module };
|
|
1055
|
+
reqs.push({ desc: r.desc.replaceAll("{endpoint}", task.endpoint ?? ""), level: "exist", kinds: r.kinds, filter });
|
|
1001
1056
|
}
|
|
1057
|
+
return reqs;
|
|
1002
1058
|
}
|
|
1003
1059
|
function approvedRequirements(ctx, task) {
|
|
1004
1060
|
const registry = getKindRegistry(ctx.config);
|
|
@@ -1027,8 +1083,7 @@ function approvedRequirements(ctx, task) {
|
|
|
1027
1083
|
}
|
|
1028
1084
|
function claimRequirements(ctx, task) {
|
|
1029
1085
|
if (task.type !== "build" && task.type !== "qa") return [];
|
|
1030
|
-
|
|
1031
|
-
return [...existRequirements(task), ...approvedRequirements(ctx, task)];
|
|
1086
|
+
return [...existRequirements(ctx, task), ...approvedRequirements(ctx, task)];
|
|
1032
1087
|
}
|
|
1033
1088
|
function requirementSatisfied(ctx, req, matched) {
|
|
1034
1089
|
if (req.level === "exist") return matched.length > 0;
|
|
@@ -1154,6 +1209,7 @@ var init_gates = __esm({
|
|
|
1154
1209
|
init_derive();
|
|
1155
1210
|
init_kind();
|
|
1156
1211
|
init_lints();
|
|
1212
|
+
init_roles();
|
|
1157
1213
|
}
|
|
1158
1214
|
});
|
|
1159
1215
|
|
|
@@ -1800,11 +1856,7 @@ var init_artifact_commands = __esm({
|
|
|
1800
1856
|
import { existsSync as existsSync6 } from "node:fs";
|
|
1801
1857
|
import { join as join7 } from "node:path";
|
|
1802
1858
|
function ownerRole(ctx, kind) {
|
|
1803
|
-
|
|
1804
|
-
if (kinds.includes(kind)) return role;
|
|
1805
|
-
}
|
|
1806
|
-
if (kind === "code") return "developer";
|
|
1807
|
-
return null;
|
|
1859
|
+
return ownerRoleOf(ctx.config, kind);
|
|
1808
1860
|
}
|
|
1809
1861
|
function openReviewTargetKeys(ctx, artifactId) {
|
|
1810
1862
|
const rows = ctx.db.prepare(
|
|
@@ -1948,15 +2000,20 @@ var init_sync_command = __esm({
|
|
|
1948
2000
|
init_events();
|
|
1949
2001
|
init_git();
|
|
1950
2002
|
init_kind();
|
|
2003
|
+
init_roles();
|
|
1951
2004
|
init_artifact_commands();
|
|
1952
2005
|
}
|
|
1953
2006
|
});
|
|
1954
2007
|
|
|
1955
2008
|
// core/commands/task.commands.ts
|
|
2009
|
+
function getRoleRegistryOwner(ctx, kind) {
|
|
2010
|
+
return ownerRoleOf(ctx.config, kind) ?? "qa";
|
|
2011
|
+
}
|
|
1956
2012
|
function createTask(ctx, p) {
|
|
1957
2013
|
const type = p.type ?? "build";
|
|
1958
2014
|
if (!VALID_TYPES.includes(type)) throw new Error(`\u65E0\u6548\u7684\u4EFB\u52A1\u7C7B\u578B: ${type},\u53EF\u9009\u503C: ${VALID_TYPES.join(", ")}`);
|
|
1959
|
-
|
|
2015
|
+
const validRoles = Object.keys(getRoleRegistry(ctx.config));
|
|
2016
|
+
if (!validRoles.includes(p.role)) throw new Error(`\u65E0\u6548\u7684\u89D2\u8272: ${p.role},\u53EF\u9009\u503C: ${validRoles.join(", ")}`);
|
|
1960
2017
|
const module = normalizeModule(p.module, ctx.config);
|
|
1961
2018
|
const tx = ctx.db.transaction(() => {
|
|
1962
2019
|
const result = ctx.db.prepare(
|
|
@@ -2051,11 +2108,12 @@ function updateTask(ctx, { id, status, operator, force = false }) {
|
|
|
2051
2108
|
return { id, warnings };
|
|
2052
2109
|
}
|
|
2053
2110
|
function spawnFollowupQa(ctx, reworkTask) {
|
|
2111
|
+
const qaRole = getRoleRegistryOwner(ctx, "acceptance");
|
|
2054
2112
|
const tx = ctx.db.transaction(() => {
|
|
2055
2113
|
const result = ctx.db.prepare(
|
|
2056
2114
|
`INSERT INTO tasks (module, role, endpoint, page, type, status, assignee, creator, content)
|
|
2057
|
-
VALUES (?,
|
|
2058
|
-
).run(reworkTask.module, reworkTask.endpoint, reworkTask.page, `[\u590D\u9A8C] rework #${reworkTask.id} \u5DF2\u5B8C\u6210,\u8BF7\u91CD\u65B0\u9A8C\u6536`);
|
|
2115
|
+
VALUES (?, ?, ?, ?, 'qa', 'pending', ?, 'system', ?)`
|
|
2116
|
+
).run(reworkTask.module, qaRole, reworkTask.endpoint, reworkTask.page, qaRole, `[\u590D\u9A8C] rework #${reworkTask.id} \u5DF2\u5B8C\u6210,\u8BF7\u91CD\u65B0\u9A8C\u6536`);
|
|
2059
2117
|
const qaId = result.lastInsertRowid;
|
|
2060
2118
|
logEvent(ctx.db, {
|
|
2061
2119
|
entityType: "task",
|
|
@@ -2215,7 +2273,7 @@ function getTaskDetail(ctx, id) {
|
|
|
2215
2273
|
}
|
|
2216
2274
|
return { task, events, outputs, staleness: taskStaleness(ctx.db, id) };
|
|
2217
2275
|
}
|
|
2218
|
-
var VALID_STATUS, VALID_TYPES
|
|
2276
|
+
var VALID_STATUS, VALID_TYPES;
|
|
2219
2277
|
var init_task_commands = __esm({
|
|
2220
2278
|
"core/commands/task.commands.ts"() {
|
|
2221
2279
|
"use strict";
|
|
@@ -2225,11 +2283,11 @@ var init_task_commands = __esm({
|
|
|
2225
2283
|
init_git();
|
|
2226
2284
|
init_gh();
|
|
2227
2285
|
init_kind();
|
|
2286
|
+
init_roles();
|
|
2228
2287
|
init_artifact_commands();
|
|
2229
2288
|
init_sync_command();
|
|
2230
2289
|
VALID_STATUS = ["pending", "in_progress", "completed", "cancelled"];
|
|
2231
2290
|
VALID_TYPES = ["build", "review", "qa", "hotfix", "baseline", "legacy", "rework"];
|
|
2232
|
-
VALID_ROLES = ["product-manager", "architect", "designer", "developer", "qa"];
|
|
2233
2291
|
}
|
|
2234
2292
|
});
|
|
2235
2293
|
|
|
@@ -2752,7 +2810,8 @@ var init_scan_command = __esm({
|
|
|
2752
2810
|
// core/commands/qa.command.ts
|
|
2753
2811
|
function recordQaResult(ctx, p) {
|
|
2754
2812
|
const task = getTaskRow(ctx, p.id);
|
|
2755
|
-
|
|
2813
|
+
const acceptanceRole = ownerRoleOf(ctx.config, "acceptance") ?? "qa";
|
|
2814
|
+
if (task.role !== acceptanceRole) throw new Error(`\u4EFB\u52A1 #${p.id} \u4E0D\u662F ${acceptanceRole} \u4EFB\u52A1`);
|
|
2756
2815
|
if (task.assignee !== p.operator) throw new Error(`\u53EA\u6709\u6267\u884C\u4EBA\u624D\u80FD\u8BB0\u5F55\u9A8C\u6536\u7ED3\u679C`);
|
|
2757
2816
|
if (p.result === "fail" && !p.reason?.trim()) throw new Error(`\u9A8C\u6536\u4E0D\u901A\u8FC7\u5FC5\u987B\u9644\u539F\u56E0,\u5B83\u5C06\u6210\u4E3A rework \u4EFB\u52A1\u7684\u5185\u5BB9`);
|
|
2758
2817
|
const eventName = p.result === "pass" ? "qa_passed" : "qa_failed";
|
|
@@ -2780,11 +2839,12 @@ function recordQaResult(ctx, p) {
|
|
|
2780
2839
|
}
|
|
2781
2840
|
return { reworkTaskId: null };
|
|
2782
2841
|
}
|
|
2842
|
+
const reworkRole = ownerRoleOf(ctx.config, "code") ?? "developer";
|
|
2783
2843
|
const tx2 = ctx.db.transaction(() => {
|
|
2784
2844
|
const result = ctx.db.prepare(
|
|
2785
2845
|
`INSERT INTO tasks (module, role, endpoint, page, type, status, assignee, creator, content)
|
|
2786
|
-
VALUES (?,
|
|
2787
|
-
).run(task.module, task.endpoint, task.page, `[\u8FD4\u5DE5] QA #${task.id} \u9A8C\u6536\u4E0D\u901A\u8FC7:${p.reason}`);
|
|
2846
|
+
VALUES (?, ?, ?, ?, 'rework', 'pending', ?, 'system', ?)`
|
|
2847
|
+
).run(task.module, reworkRole, task.endpoint, task.page, reworkRole, `[\u8FD4\u5DE5] QA #${task.id} \u9A8C\u6536\u4E0D\u901A\u8FC7:${p.reason}`);
|
|
2788
2848
|
const reworkId = result.lastInsertRowid;
|
|
2789
2849
|
logEvent(ctx.db, {
|
|
2790
2850
|
entityType: "task",
|
|
@@ -2804,6 +2864,7 @@ var init_qa_command = __esm({
|
|
|
2804
2864
|
"core/commands/qa.command.ts"() {
|
|
2805
2865
|
"use strict";
|
|
2806
2866
|
init_events();
|
|
2867
|
+
init_roles();
|
|
2807
2868
|
init_artifact_commands();
|
|
2808
2869
|
init_task_commands();
|
|
2809
2870
|
}
|
|
@@ -3019,35 +3080,25 @@ function planModule(ctx, moduleRaw, creator = "product-manager") {
|
|
|
3019
3080
|
}
|
|
3020
3081
|
const pagePrds = byKind("page-prd").filter((a) => a.endpoint && a.page && existsSync10(join12(ctx.root, a.path)));
|
|
3021
3082
|
const endpoints = [...new Set(pagePrds.map((a) => a.endpoint))];
|
|
3022
|
-
const
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3083
|
+
const registry = getRoleRegistry(ctx.config);
|
|
3084
|
+
const interp = (tpl, v) => tpl.replaceAll("{module}", v.module).replaceAll("{endpoint}", v.endpoint ?? "").replaceAll("{page}", v.page ?? "");
|
|
3085
|
+
const desired = [];
|
|
3086
|
+
for (const role of ctx.config.pipeline) {
|
|
3087
|
+
for (const d of registry[role]?.dispatch ?? []) {
|
|
3088
|
+
if (d.at === "module") {
|
|
3089
|
+
desired.push({ role, endpoint: d.endpoint ?? null, page: null, type: d.type ?? "build", assignee: role, content: interp(d.content, { module }) });
|
|
3090
|
+
} else if (d.at === "endpoint") {
|
|
3091
|
+
for (const endpoint of endpoints) {
|
|
3092
|
+
if (d.ifMissingKind && artifacts.some((a) => a.kind === d.ifMissingKind && a.endpoint === endpoint)) continue;
|
|
3093
|
+
desired.push({ role, endpoint, page: null, type: d.type ?? "build", assignee: role, content: interp(d.content, { module, endpoint }) });
|
|
3094
|
+
}
|
|
3095
|
+
} else {
|
|
3096
|
+
for (const prd of pagePrds) {
|
|
3097
|
+
desired.push({ role, endpoint: prd.endpoint, page: prd.page, type: d.type ?? "build", assignee: role, content: interp(d.content, { module, endpoint: prd.endpoint, page: prd.page }) });
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3038
3100
|
}
|
|
3039
3101
|
}
|
|
3040
|
-
for (const prd of pagePrds) {
|
|
3041
|
-
desired.push(
|
|
3042
|
-
{ role: "designer", endpoint: prd.endpoint, page: prd.page, type: "build", assignee: "designer", content: `\u8BBE\u8BA1 ${prd.endpoint}/${prd.page} \u9875\u9762(\u63D0\u793A\u8BCD+\u539F\u578B)` },
|
|
3043
|
-
{ role: "developer", endpoint: prd.endpoint, page: prd.page, type: "build", assignee: "developer", content: `\u5B9E\u73B0 ${prd.endpoint}/${prd.page} \u9875\u9762` },
|
|
3044
|
-
{ role: "qa", endpoint: prd.endpoint, page: prd.page, type: "qa", assignee: "qa", content: `\u9A8C\u6536 ${prd.endpoint}/${prd.page} \u9875\u9762` }
|
|
3045
|
-
);
|
|
3046
|
-
}
|
|
3047
|
-
const activeRoles = new Set(ctx.config.pipeline);
|
|
3048
|
-
const filtered = desired.filter((d) => activeRoles.has(d.role));
|
|
3049
|
-
desired.length = 0;
|
|
3050
|
-
desired.push(...filtered);
|
|
3051
3102
|
const exists = ctx.db.prepare(
|
|
3052
3103
|
`SELECT COUNT(*) AS c FROM tasks
|
|
3053
3104
|
WHERE module IS ? AND role = ? AND endpoint IS ? AND page IS ? AND type = ? AND status != 'cancelled'`
|
|
@@ -3092,6 +3143,7 @@ var init_plan_command = __esm({
|
|
|
3092
3143
|
init_derive();
|
|
3093
3144
|
init_events();
|
|
3094
3145
|
init_kind();
|
|
3146
|
+
init_roles();
|
|
3095
3147
|
init_task_commands();
|
|
3096
3148
|
}
|
|
3097
3149
|
});
|
|
@@ -3142,7 +3194,7 @@ var init_install_hooks_command = __esm({
|
|
|
3142
3194
|
});
|
|
3143
3195
|
|
|
3144
3196
|
// core/commands/gen-agents.command.ts
|
|
3145
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync6,
|
|
3197
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
3146
3198
|
import { dirname as dirname3, join as join14 } from "node:path";
|
|
3147
3199
|
function expandPath(ctx, kind) {
|
|
3148
3200
|
const spec = getKindRegistry(ctx.config)[kind];
|
|
@@ -3211,13 +3263,19 @@ function genAgents(ctx, templatesDir) {
|
|
|
3211
3263
|
return content;
|
|
3212
3264
|
};
|
|
3213
3265
|
const adapters = resolvePlatforms(ctx.config.platforms);
|
|
3214
|
-
const
|
|
3266
|
+
const registry = getRoleRegistry(ctx.config);
|
|
3215
3267
|
const written = [];
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3268
|
+
const projectTplDir = join14(ctx.root, "docs/workbench/templates/agents", lang);
|
|
3269
|
+
for (const role of [...new Set(ctx.config.pipeline)]) {
|
|
3270
|
+
if (!registry[role]) {
|
|
3271
|
+
throw new Error(`pipeline \u89D2\u8272 ${role} \u672A\u5728\u89D2\u8272\u6CE8\u518C\u8868\u4E2D\u5B9A\u4E49(\u5185\u7F6E\u6216 config.roles)`);
|
|
3272
|
+
}
|
|
3273
|
+
const candidates = [join14(projectTplDir, `${role}.md`), join14(dir, `${role}.md`)];
|
|
3274
|
+
const file = candidates.find((f) => existsSync12(f));
|
|
3275
|
+
if (!file) {
|
|
3276
|
+
throw new Error(`\u89D2\u8272 ${role} \u7F3A\u5C11 agent \u6A21\u677F:\u81EA\u5B9A\u4E49\u89D2\u8272\u8BF7\u63D0\u4F9B docs/workbench/templates/agents/${lang}/${role}.md`);
|
|
3277
|
+
}
|
|
3278
|
+
const tpl = parseTemplate(readFileSync6(file, "utf-8"));
|
|
3221
3279
|
for (const adapter of adapters) {
|
|
3222
3280
|
const memory = adapter.memoryBlock(role, lang);
|
|
3223
3281
|
const spec = {
|
|
@@ -3242,6 +3300,7 @@ var init_gen_agents_command = __esm({
|
|
|
3242
3300
|
"use strict";
|
|
3243
3301
|
init_config();
|
|
3244
3302
|
init_kind();
|
|
3303
|
+
init_roles();
|
|
3245
3304
|
init_platforms();
|
|
3246
3305
|
TRUST_PROTOCOL_ZH = `## \u4FE1\u4EFB\u534F\u8BAE(\u6700\u9AD8\u4F18\u5148\u7EA7)
|
|
3247
3306
|
|
|
@@ -3365,11 +3424,13 @@ function intakeIssues(ctx) {
|
|
|
3365
3424
|
continue;
|
|
3366
3425
|
}
|
|
3367
3426
|
const isBug = issue.labels.some((l) => l.name.toLowerCase() === "bug");
|
|
3427
|
+
const bugRole = ctx.config.intake?.bugRole ?? "developer";
|
|
3428
|
+
const defaultRole = ctx.config.intake?.defaultRole ?? "product-manager";
|
|
3368
3429
|
const id = createTask(ctx, {
|
|
3369
|
-
role: isBug ?
|
|
3370
|
-
endpoint:
|
|
3430
|
+
role: isBug ? bugRole : defaultRole,
|
|
3431
|
+
endpoint: null,
|
|
3371
3432
|
type: isBug ? "hotfix" : "build",
|
|
3372
|
-
assignee: isBug ?
|
|
3433
|
+
assignee: isBug ? bugRole : defaultRole,
|
|
3373
3434
|
creator: "intake",
|
|
3374
3435
|
content: `[gh#${issue.number}] ${issue.title}
|
|
3375
3436
|
${issue.url}`,
|
|
@@ -3553,6 +3614,7 @@ __export(core_exports, {
|
|
|
3553
3614
|
CONFIG_FILENAME: () => CONFIG_FILENAME,
|
|
3554
3615
|
CURRENT_SCHEMA_VERSION: () => CURRENT_SCHEMA_VERSION,
|
|
3555
3616
|
DEFAULT_KIND_REGISTRY: () => DEFAULT_KIND_REGISTRY,
|
|
3617
|
+
DEFAULT_ROLE_REGISTRY: () => DEFAULT_ROLE_REGISTRY,
|
|
3556
3618
|
KIND_TIERS: () => KIND_TIERS,
|
|
3557
3619
|
META_KINDS: () => META_KINDS,
|
|
3558
3620
|
MIGRATIONS: () => MIGRATIONS,
|
|
@@ -3586,6 +3648,7 @@ __export(core_exports, {
|
|
|
3586
3648
|
genAgents: () => genAgents,
|
|
3587
3649
|
getAdapter: () => getAdapter,
|
|
3588
3650
|
getKindRegistry: () => getKindRegistry,
|
|
3651
|
+
getRoleRegistry: () => getRoleRegistry,
|
|
3589
3652
|
getTaskDetail: () => getTaskDetail,
|
|
3590
3653
|
getTaskRow: () => getTaskRow,
|
|
3591
3654
|
gitHead: () => gitHead,
|
|
@@ -3614,6 +3677,7 @@ __export(core_exports, {
|
|
|
3614
3677
|
openWorkbench: () => openWorkbench,
|
|
3615
3678
|
openWorkbenchAt: () => openWorkbenchAt,
|
|
3616
3679
|
ownerRole: () => ownerRole,
|
|
3680
|
+
ownerRoleOf: () => ownerRoleOf,
|
|
3617
3681
|
planModule: () => planModule,
|
|
3618
3682
|
prototypeEndorsed: () => prototypeEndorsed,
|
|
3619
3683
|
recordNote: () => recordNote,
|
|
@@ -3651,6 +3715,7 @@ var init_core = __esm({
|
|
|
3651
3715
|
init_hash();
|
|
3652
3716
|
init_events();
|
|
3653
3717
|
init_kind();
|
|
3718
|
+
init_roles();
|
|
3654
3719
|
init_platforms();
|
|
3655
3720
|
init_derive();
|
|
3656
3721
|
init_lints();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dawipong/opcflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Spec-anchored, drift-enforced execution layer for AI coding agents — artifact DAG, trust gates, multi-role pipeline; generates agents/MCP/hooks for Claude Code, Codex, OpenCode & Cursor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Dawi",
|