u-foo 1.7.5 → 1.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/README.md +9 -1
- package/README.zh-CN.md +9 -1
- package/bin/ufoo.js +4 -2
- package/package.json +1 -1
- package/src/agent/cliRunner.js +3 -2
- package/src/agent/ucodeBootstrap.js +5 -3
- package/src/agent/ufooAgent.js +184 -5
- package/src/assistant/constants.js +1 -1
- package/src/chat/commandExecutor.js +98 -3
- package/src/chat/commands.js +7 -0
- package/src/chat/completionController.js +40 -0
- package/src/chat/daemonMessageRouter.js +21 -1
- package/src/chat/dashboardKeyController.js +55 -3
- package/src/chat/dashboardView.js +31 -5
- package/src/chat/index.js +152 -36
- package/src/chat/inputListenerController.js +14 -0
- package/src/chat/inputSubmitHandler.js +9 -5
- package/src/chat/transientAgentState.js +64 -0
- package/src/cli/groupCoreCommands.js +21 -12
- package/src/cli.js +23 -1
- package/src/daemon/groupOrchestrator.js +581 -97
- package/src/daemon/index.js +418 -3
- package/src/daemon/ops.js +25 -7
- package/src/daemon/promptLoop.js +16 -0
- package/src/daemon/promptRequest.js +126 -2
- package/src/daemon/reporting.js +18 -0
- package/src/daemon/soloBootstrap.js +435 -0
- package/src/daemon/status.js +5 -1
- package/src/globalMode.js +33 -0
- package/src/group/bootstrap.js +157 -0
- package/src/group/promptProfiles.js +646 -0
- package/src/group/templateValidation.js +99 -0
- package/src/group/validateTemplate.js +36 -5
- package/src/init/index.js +13 -7
- package/src/report/store.js +6 -0
- package/src/shared/eventContract.js +1 -0
- package/templates/groups/{dev-basic.json → build-lane.json} +38 -34
- package/templates/groups/product-discovery.json +79 -0
- package/templates/groups/ui-polish.json +87 -0
- package/templates/groups/verify-ship.json +79 -0
- package/templates/groups/research-quick.json +0 -49
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { loadPromptProfileRegistry } = require("./promptProfiles");
|
|
4
|
+
const { resolveTemplateReference } = require("./templates");
|
|
5
|
+
const { validateTemplate } = require("./validateTemplate");
|
|
6
|
+
|
|
7
|
+
function asTrimmedString(value) {
|
|
8
|
+
if (typeof value !== "string") return "";
|
|
9
|
+
return value.trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function formatResolveErrors(errors = []) {
|
|
13
|
+
if (!Array.isArray(errors) || errors.length === 0) return "";
|
|
14
|
+
return errors
|
|
15
|
+
.map((item) => `${item.filePath}: ${item.error || item.message || "unknown error"}`)
|
|
16
|
+
.join("; ");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function resolveTemplateTarget(projectRoot, target, options = {}) {
|
|
20
|
+
const rawTarget = asTrimmedString(target);
|
|
21
|
+
if (!rawTarget) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
error: "template target is required",
|
|
25
|
+
entry: null,
|
|
26
|
+
resolveErrors: [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const resolved = resolveTemplateReference(projectRoot, rawTarget, {
|
|
31
|
+
allowPath: options.allowPath !== false,
|
|
32
|
+
cwd: options.cwd || projectRoot,
|
|
33
|
+
...(options.templatesOptions || {}),
|
|
34
|
+
});
|
|
35
|
+
if (!resolved.entry) {
|
|
36
|
+
const details = formatResolveErrors(resolved.errors || []);
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
error: details
|
|
40
|
+
? `failed to load template "${rawTarget}": ${details}`
|
|
41
|
+
: `template not found: ${rawTarget}`,
|
|
42
|
+
entry: null,
|
|
43
|
+
resolveErrors: resolved.errors || [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
ok: true,
|
|
49
|
+
error: "",
|
|
50
|
+
entry: resolved.entry,
|
|
51
|
+
resolveErrors: resolved.errors || [],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function validateTemplateEntry(projectRoot, entry, options = {}) {
|
|
56
|
+
const promptRegistry = loadPromptProfileRegistry(projectRoot, options.promptProfilesOptions || {});
|
|
57
|
+
if (promptRegistry.errors.length > 0) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
error: "prompt profile registry invalid",
|
|
61
|
+
errors: promptRegistry.errors.slice(),
|
|
62
|
+
entry,
|
|
63
|
+
promptRegistry,
|
|
64
|
+
promptProfiles: [],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = validateTemplate(entry.data, { promptProfileRegistry: promptRegistry });
|
|
69
|
+
return {
|
|
70
|
+
ok: result.ok,
|
|
71
|
+
error: result.ok ? "" : "template validation failed",
|
|
72
|
+
errors: result.errors || [],
|
|
73
|
+
entry,
|
|
74
|
+
promptRegistry,
|
|
75
|
+
promptProfiles: result.promptProfiles || [],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function validateTemplateTarget(projectRoot, target, options = {}) {
|
|
80
|
+
const resolved = resolveTemplateTarget(projectRoot, target, options);
|
|
81
|
+
if (!resolved.ok || !resolved.entry) {
|
|
82
|
+
return {
|
|
83
|
+
ok: false,
|
|
84
|
+
error: resolved.error,
|
|
85
|
+
errors: resolved.resolveErrors || [],
|
|
86
|
+
entry: null,
|
|
87
|
+
promptRegistry: null,
|
|
88
|
+
promptProfiles: [],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return validateTemplateEntry(projectRoot, resolved.entry, options);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
formatResolveErrors,
|
|
96
|
+
resolveTemplateTarget,
|
|
97
|
+
validateTemplateEntry,
|
|
98
|
+
validateTemplateTarget,
|
|
99
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const ALLOWED_AGENT_TYPES = new Set(["codex", "claude", "ucode"]);
|
|
3
|
+
const ALLOWED_AGENT_TYPES = new Set(["auto", "codex", "claude", "ucode"]);
|
|
4
|
+
const { resolvePromptProfileReference } = require("./promptProfiles");
|
|
4
5
|
|
|
5
6
|
function isPlainObject(value) {
|
|
6
7
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -93,12 +94,14 @@ function detectDependsCycle(agents = []) {
|
|
|
93
94
|
return null;
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
function validateTemplate(doc) {
|
|
97
|
+
function validateTemplate(doc, options = {}) {
|
|
97
98
|
const errors = [];
|
|
99
|
+
const promptProfiles = [];
|
|
100
|
+
const promptProfileRegistry = options.promptProfileRegistry || null;
|
|
98
101
|
|
|
99
102
|
if (!isPlainObject(doc)) {
|
|
100
103
|
addError(errors, "$", "template document must be a JSON object");
|
|
101
|
-
return { ok: false, errors };
|
|
104
|
+
return { ok: false, errors, promptProfiles };
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
if (!Number.isInteger(doc.schema_version) || doc.schema_version < 1) {
|
|
@@ -121,7 +124,7 @@ function validateTemplate(doc) {
|
|
|
121
124
|
|
|
122
125
|
if (!Array.isArray(doc.agents) || doc.agents.length === 0) {
|
|
123
126
|
addError(errors, "agents", "agents must be a non-empty array");
|
|
124
|
-
return { ok: false, errors };
|
|
127
|
+
return { ok: false, errors, promptProfiles };
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
const knownNicknames = new Set();
|
|
@@ -156,6 +159,34 @@ function validateTemplate(doc) {
|
|
|
156
159
|
if (!Number.isInteger(agent.startup_order) || agent.startup_order < 0) {
|
|
157
160
|
addError(errors, `${basePath}.startup_order`, "startup_order must be an integer >= 0");
|
|
158
161
|
}
|
|
162
|
+
|
|
163
|
+
if (agent.prompt_profile !== undefined) {
|
|
164
|
+
const requestedProfile = asTrimmedString(agent.prompt_profile);
|
|
165
|
+
if (!requestedProfile) {
|
|
166
|
+
addError(errors, `${basePath}.prompt_profile`, "prompt_profile must be a non-empty string");
|
|
167
|
+
} else if (promptProfileRegistry) {
|
|
168
|
+
const resolvedProfile = resolvePromptProfileReference(promptProfileRegistry, requestedProfile);
|
|
169
|
+
if (!resolvedProfile) {
|
|
170
|
+
addError(
|
|
171
|
+
errors,
|
|
172
|
+
`${basePath}.prompt_profile`,
|
|
173
|
+
`unknown prompt_profile "${requestedProfile}"`
|
|
174
|
+
);
|
|
175
|
+
} else {
|
|
176
|
+
promptProfiles.push({
|
|
177
|
+
index: i,
|
|
178
|
+
agent_id: asTrimmedString(agent.id),
|
|
179
|
+
nickname,
|
|
180
|
+
requested_profile: requestedProfile,
|
|
181
|
+
resolved_profile: resolvedProfile.id,
|
|
182
|
+
display_name: resolvedProfile.display_name || resolvedProfile.id,
|
|
183
|
+
short_name: resolvedProfile.short_name || "",
|
|
184
|
+
profile_source: resolvedProfile.source || "",
|
|
185
|
+
deprecated: resolvedProfile.deprecated === true,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
159
190
|
}
|
|
160
191
|
|
|
161
192
|
for (let i = 0; i < doc.agents.length; i += 1) {
|
|
@@ -225,7 +256,7 @@ function validateTemplate(doc) {
|
|
|
225
256
|
);
|
|
226
257
|
}
|
|
227
258
|
|
|
228
|
-
return { ok: errors.length === 0, errors };
|
|
259
|
+
return { ok: errors.length === 0, errors, promptProfiles };
|
|
229
260
|
}
|
|
230
261
|
|
|
231
262
|
module.exports = {
|
package/src/init/index.js
CHANGED
|
@@ -19,20 +19,25 @@ class UfooInit {
|
|
|
19
19
|
async init(options = {}) {
|
|
20
20
|
const modules = (options.modules || "context").split(",");
|
|
21
21
|
const project = options.project || process.cwd();
|
|
22
|
+
const controllerMode = options.controllerMode === true;
|
|
22
23
|
|
|
23
24
|
console.log("=== ufoo init ===");
|
|
24
25
|
console.log(`Project directory: ${project}`);
|
|
25
26
|
console.log(`Modules: ${modules.join(", ")}`);
|
|
26
27
|
console.log();
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
if (!controllerMode) {
|
|
30
|
+
// 确保 AGENTS.md 和 CLAUDE.md 存在
|
|
31
|
+
this.ensureAgentsFiles(project);
|
|
32
|
+
}
|
|
30
33
|
|
|
31
34
|
// 初始化核心
|
|
32
|
-
this.initCore(project);
|
|
35
|
+
this.initCore(project, { controllerMode });
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
if (!controllerMode) {
|
|
38
|
+
// 初始化 AGENTS.md 模板
|
|
39
|
+
this.injectAgentsTemplate(project);
|
|
40
|
+
}
|
|
36
41
|
|
|
37
42
|
// 初始化各模块
|
|
38
43
|
for (const module of modules) {
|
|
@@ -82,8 +87,9 @@ class UfooInit {
|
|
|
82
87
|
/**
|
|
83
88
|
* 初始化核心 .ufoo 目录
|
|
84
89
|
*/
|
|
85
|
-
initCore(project) {
|
|
90
|
+
initCore(project, options = {}) {
|
|
86
91
|
console.log("[core] Initializing .ufoo core...");
|
|
92
|
+
const controllerMode = options.controllerMode === true;
|
|
87
93
|
|
|
88
94
|
const ufooDir = path.join(project, ".ufoo");
|
|
89
95
|
if (!fs.existsSync(ufooDir)) {
|
|
@@ -94,7 +100,7 @@ class UfooInit {
|
|
|
94
100
|
const docsLink = path.join(ufooDir, "docs");
|
|
95
101
|
const projectDocs = path.join(project, "docs");
|
|
96
102
|
|
|
97
|
-
if (fs.existsSync(projectDocs)) {
|
|
103
|
+
if (!controllerMode && fs.existsSync(projectDocs)) {
|
|
98
104
|
const linkStat = this.safeLstat(docsLink);
|
|
99
105
|
if (linkStat) {
|
|
100
106
|
fs.unlinkSync(docsLink);
|
package/src/report/store.js
CHANGED
|
@@ -216,6 +216,11 @@ function listControllerInboxEntries(projectRoot, controllerId = "ufoo-agent", op
|
|
|
216
216
|
return rows.slice(rows.length - num);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
function countControllerInboxEntries(projectRoot, controllerId = "ufoo-agent") {
|
|
220
|
+
const file = getControllerInboxFile(projectRoot, controllerId);
|
|
221
|
+
return parseJsonLines(file).length;
|
|
222
|
+
}
|
|
223
|
+
|
|
219
224
|
function clearControllerInbox(projectRoot, controllerId = "ufoo-agent") {
|
|
220
225
|
const file = getControllerInboxFile(projectRoot, controllerId);
|
|
221
226
|
try {
|
|
@@ -326,6 +331,7 @@ module.exports = {
|
|
|
326
331
|
getControllerInboxFile,
|
|
327
332
|
appendControllerInboxEntry,
|
|
328
333
|
listControllerInboxEntries,
|
|
334
|
+
countControllerInboxEntries,
|
|
329
335
|
clearControllerInbox,
|
|
330
336
|
consumeControllerInboxEntries,
|
|
331
337
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"template": {
|
|
4
|
-
"id": "
|
|
5
|
-
"alias": "
|
|
6
|
-
"name": "
|
|
4
|
+
"id": "build-lane",
|
|
5
|
+
"alias": "build-lane",
|
|
6
|
+
"name": "Build Lane"
|
|
7
7
|
},
|
|
8
8
|
"defaults": {
|
|
9
9
|
"launch_mode": "auto",
|
|
@@ -11,68 +11,72 @@
|
|
|
11
11
|
},
|
|
12
12
|
"agents": [
|
|
13
13
|
{
|
|
14
|
-
"id": "
|
|
15
|
-
"nickname": "
|
|
16
|
-
"type": "
|
|
17
|
-
"role": "
|
|
18
|
-
"prompt_profile": "
|
|
14
|
+
"id": "architect",
|
|
15
|
+
"nickname": "architect",
|
|
16
|
+
"type": "auto",
|
|
17
|
+
"role": "define slices and architecture constraints",
|
|
18
|
+
"prompt_profile": "system-architect",
|
|
19
19
|
"accept_from": [],
|
|
20
|
-
"report_to": [
|
|
20
|
+
"report_to": [
|
|
21
|
+
"builder",
|
|
22
|
+
"reviewer"
|
|
23
|
+
],
|
|
21
24
|
"startup_order": 1,
|
|
22
25
|
"depends_on": []
|
|
23
26
|
},
|
|
24
27
|
{
|
|
25
|
-
"id": "
|
|
26
|
-
"nickname": "
|
|
27
|
-
"type": "
|
|
28
|
-
"role": "
|
|
29
|
-
"prompt_profile": "
|
|
28
|
+
"id": "builder",
|
|
29
|
+
"nickname": "builder",
|
|
30
|
+
"type": "auto",
|
|
31
|
+
"role": "implement approved slices",
|
|
32
|
+
"prompt_profile": "implementation-lead",
|
|
30
33
|
"accept_from": [
|
|
31
|
-
"
|
|
34
|
+
"architect",
|
|
35
|
+
"reviewer"
|
|
32
36
|
],
|
|
33
37
|
"report_to": [
|
|
34
|
-
"
|
|
38
|
+
"reviewer"
|
|
35
39
|
],
|
|
36
40
|
"startup_order": 2,
|
|
37
41
|
"depends_on": [
|
|
38
|
-
"
|
|
42
|
+
"architect"
|
|
39
43
|
]
|
|
40
44
|
},
|
|
41
45
|
{
|
|
42
|
-
"id": "
|
|
43
|
-
"nickname": "
|
|
44
|
-
"type": "
|
|
45
|
-
"role": "
|
|
46
|
-
"prompt_profile": "
|
|
46
|
+
"id": "reviewer",
|
|
47
|
+
"nickname": "reviewer",
|
|
48
|
+
"type": "auto",
|
|
49
|
+
"role": "review correctness and risk",
|
|
50
|
+
"prompt_profile": "review-critic",
|
|
47
51
|
"accept_from": [
|
|
48
|
-
"
|
|
49
|
-
"
|
|
52
|
+
"architect",
|
|
53
|
+
"builder"
|
|
50
54
|
],
|
|
51
55
|
"report_to": [
|
|
52
|
-
"
|
|
56
|
+
"builder"
|
|
53
57
|
],
|
|
54
58
|
"startup_order": 3,
|
|
55
59
|
"depends_on": [
|
|
56
|
-
"
|
|
57
|
-
"
|
|
60
|
+
"architect",
|
|
61
|
+
"builder"
|
|
58
62
|
]
|
|
59
63
|
}
|
|
60
64
|
],
|
|
61
65
|
"edges": [
|
|
62
66
|
{
|
|
63
|
-
"from": "
|
|
64
|
-
"to": "
|
|
67
|
+
"from": "architect",
|
|
68
|
+
"to": "builder",
|
|
65
69
|
"kind": "task"
|
|
66
70
|
},
|
|
67
71
|
{
|
|
68
|
-
"from": "
|
|
69
|
-
"to": "
|
|
70
|
-
"kind": "
|
|
72
|
+
"from": "builder",
|
|
73
|
+
"to": "reviewer",
|
|
74
|
+
"kind": "review"
|
|
71
75
|
},
|
|
72
76
|
{
|
|
73
|
-
"from": "
|
|
77
|
+
"from": "reviewer",
|
|
74
78
|
"to": "builder",
|
|
75
|
-
"kind": "
|
|
79
|
+
"kind": "task"
|
|
76
80
|
}
|
|
77
81
|
]
|
|
78
82
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"template": {
|
|
4
|
+
"id": "product-discovery",
|
|
5
|
+
"alias": "product-discovery",
|
|
6
|
+
"name": "Product Discovery"
|
|
7
|
+
},
|
|
8
|
+
"defaults": {
|
|
9
|
+
"launch_mode": "auto",
|
|
10
|
+
"start_timeout_ms": 15000
|
|
11
|
+
},
|
|
12
|
+
"agents": [
|
|
13
|
+
{
|
|
14
|
+
"id": "facilitator",
|
|
15
|
+
"nickname": "facilitator",
|
|
16
|
+
"type": "auto",
|
|
17
|
+
"role": "clarify the real problem and define a narrow wedge",
|
|
18
|
+
"prompt_profile": "discovery-facilitator",
|
|
19
|
+
"accept_from": [],
|
|
20
|
+
"report_to": [
|
|
21
|
+
"challenger",
|
|
22
|
+
"architect"
|
|
23
|
+
],
|
|
24
|
+
"startup_order": 1,
|
|
25
|
+
"depends_on": []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "challenger",
|
|
29
|
+
"nickname": "challenger",
|
|
30
|
+
"type": "auto",
|
|
31
|
+
"role": "challenge scope and leverage",
|
|
32
|
+
"prompt_profile": "scope-challenger",
|
|
33
|
+
"accept_from": [
|
|
34
|
+
"facilitator"
|
|
35
|
+
],
|
|
36
|
+
"report_to": [
|
|
37
|
+
"architect"
|
|
38
|
+
],
|
|
39
|
+
"startup_order": 2,
|
|
40
|
+
"depends_on": [
|
|
41
|
+
"facilitator"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "architect",
|
|
46
|
+
"nickname": "architect",
|
|
47
|
+
"type": "auto",
|
|
48
|
+
"role": "translate approved scope into a technical plan",
|
|
49
|
+
"prompt_profile": "system-architect",
|
|
50
|
+
"accept_from": [
|
|
51
|
+
"facilitator",
|
|
52
|
+
"challenger"
|
|
53
|
+
],
|
|
54
|
+
"report_to": [],
|
|
55
|
+
"startup_order": 3,
|
|
56
|
+
"depends_on": [
|
|
57
|
+
"facilitator",
|
|
58
|
+
"challenger"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"edges": [
|
|
63
|
+
{
|
|
64
|
+
"from": "facilitator",
|
|
65
|
+
"to": "challenger",
|
|
66
|
+
"kind": "task"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"from": "facilitator",
|
|
70
|
+
"to": "architect",
|
|
71
|
+
"kind": "task"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"from": "challenger",
|
|
75
|
+
"to": "architect",
|
|
76
|
+
"kind": "review"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"template": {
|
|
4
|
+
"id": "ui-polish",
|
|
5
|
+
"alias": "ui-polish",
|
|
6
|
+
"name": "UI Polish"
|
|
7
|
+
},
|
|
8
|
+
"defaults": {
|
|
9
|
+
"launch_mode": "auto",
|
|
10
|
+
"start_timeout_ms": 15000
|
|
11
|
+
},
|
|
12
|
+
"agents": [
|
|
13
|
+
{
|
|
14
|
+
"id": "designer",
|
|
15
|
+
"nickname": "designer",
|
|
16
|
+
"type": "auto",
|
|
17
|
+
"role": "audit the interface and rank design polish issues",
|
|
18
|
+
"prompt_profile": "design-critic",
|
|
19
|
+
"accept_from": [],
|
|
20
|
+
"report_to": [
|
|
21
|
+
"refiner",
|
|
22
|
+
"qa"
|
|
23
|
+
],
|
|
24
|
+
"startup_order": 1,
|
|
25
|
+
"depends_on": []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "refiner",
|
|
29
|
+
"nickname": "refiner",
|
|
30
|
+
"type": "auto",
|
|
31
|
+
"role": "implement focused UI and interaction refinements",
|
|
32
|
+
"prompt_profile": "frontend-refiner",
|
|
33
|
+
"accept_from": [
|
|
34
|
+
"designer",
|
|
35
|
+
"qa"
|
|
36
|
+
],
|
|
37
|
+
"report_to": [
|
|
38
|
+
"qa"
|
|
39
|
+
],
|
|
40
|
+
"startup_order": 2,
|
|
41
|
+
"depends_on": [
|
|
42
|
+
"designer"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "qa",
|
|
47
|
+
"nickname": "qa",
|
|
48
|
+
"type": "auto",
|
|
49
|
+
"role": "validate polish changes and catch UX regressions",
|
|
50
|
+
"prompt_profile": "qa-driver",
|
|
51
|
+
"accept_from": [
|
|
52
|
+
"designer",
|
|
53
|
+
"refiner"
|
|
54
|
+
],
|
|
55
|
+
"report_to": [
|
|
56
|
+
"refiner"
|
|
57
|
+
],
|
|
58
|
+
"startup_order": 3,
|
|
59
|
+
"depends_on": [
|
|
60
|
+
"designer",
|
|
61
|
+
"refiner"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"edges": [
|
|
66
|
+
{
|
|
67
|
+
"from": "designer",
|
|
68
|
+
"to": "refiner",
|
|
69
|
+
"kind": "task"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"from": "designer",
|
|
73
|
+
"to": "qa",
|
|
74
|
+
"kind": "review"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"from": "refiner",
|
|
78
|
+
"to": "qa",
|
|
79
|
+
"kind": "task"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"from": "qa",
|
|
83
|
+
"to": "refiner",
|
|
84
|
+
"kind": "review"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"template": {
|
|
4
|
+
"id": "verify-ship",
|
|
5
|
+
"alias": "verify-ship",
|
|
6
|
+
"name": "Verify and Ship"
|
|
7
|
+
},
|
|
8
|
+
"defaults": {
|
|
9
|
+
"launch_mode": "auto",
|
|
10
|
+
"start_timeout_ms": 15000
|
|
11
|
+
},
|
|
12
|
+
"agents": [
|
|
13
|
+
{
|
|
14
|
+
"id": "qa",
|
|
15
|
+
"nickname": "qa",
|
|
16
|
+
"type": "auto",
|
|
17
|
+
"role": "validate user flows and capture defects",
|
|
18
|
+
"prompt_profile": "qa-driver",
|
|
19
|
+
"accept_from": [],
|
|
20
|
+
"report_to": [
|
|
21
|
+
"debugger",
|
|
22
|
+
"release"
|
|
23
|
+
],
|
|
24
|
+
"startup_order": 1,
|
|
25
|
+
"depends_on": []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "debugger",
|
|
29
|
+
"nickname": "debugger",
|
|
30
|
+
"type": "auto",
|
|
31
|
+
"role": "identify root cause for hard failures",
|
|
32
|
+
"prompt_profile": "debug-investigator",
|
|
33
|
+
"accept_from": [
|
|
34
|
+
"qa"
|
|
35
|
+
],
|
|
36
|
+
"report_to": [
|
|
37
|
+
"release"
|
|
38
|
+
],
|
|
39
|
+
"startup_order": 2,
|
|
40
|
+
"depends_on": [
|
|
41
|
+
"qa"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "release",
|
|
46
|
+
"nickname": "release",
|
|
47
|
+
"type": "auto",
|
|
48
|
+
"role": "judge release readiness and blockers",
|
|
49
|
+
"prompt_profile": "release-coordinator",
|
|
50
|
+
"accept_from": [
|
|
51
|
+
"qa",
|
|
52
|
+
"debugger"
|
|
53
|
+
],
|
|
54
|
+
"report_to": [],
|
|
55
|
+
"startup_order": 3,
|
|
56
|
+
"depends_on": [
|
|
57
|
+
"qa",
|
|
58
|
+
"debugger"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"edges": [
|
|
63
|
+
{
|
|
64
|
+
"from": "qa",
|
|
65
|
+
"to": "debugger",
|
|
66
|
+
"kind": "task"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"from": "qa",
|
|
70
|
+
"to": "release",
|
|
71
|
+
"kind": "task"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"from": "debugger",
|
|
75
|
+
"to": "release",
|
|
76
|
+
"kind": "review"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": 1,
|
|
3
|
-
"template": {
|
|
4
|
-
"id": "research-quick",
|
|
5
|
-
"alias": "research-quick",
|
|
6
|
-
"name": "Research Quick"
|
|
7
|
-
},
|
|
8
|
-
"defaults": {
|
|
9
|
-
"launch_mode": "auto",
|
|
10
|
-
"start_timeout_ms": 10000
|
|
11
|
-
},
|
|
12
|
-
"agents": [
|
|
13
|
-
{
|
|
14
|
-
"id": "researcher",
|
|
15
|
-
"nickname": "researcher",
|
|
16
|
-
"type": "claude",
|
|
17
|
-
"role": "collect references and summarize findings",
|
|
18
|
-
"prompt_profile": "research-scan",
|
|
19
|
-
"accept_from": [],
|
|
20
|
-
"report_to": [],
|
|
21
|
-
"startup_order": 1,
|
|
22
|
-
"depends_on": []
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"id": "coder",
|
|
26
|
-
"nickname": "coder",
|
|
27
|
-
"type": "codex",
|
|
28
|
-
"role": "prototype and verify implementation",
|
|
29
|
-
"prompt_profile": "rapid-prototype",
|
|
30
|
-
"accept_from": [
|
|
31
|
-
"researcher"
|
|
32
|
-
],
|
|
33
|
-
"report_to": [
|
|
34
|
-
"researcher"
|
|
35
|
-
],
|
|
36
|
-
"startup_order": 2,
|
|
37
|
-
"depends_on": [
|
|
38
|
-
"researcher"
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
"edges": [
|
|
43
|
-
{
|
|
44
|
-
"from": "researcher",
|
|
45
|
-
"to": "coder",
|
|
46
|
-
"kind": "task"
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
}
|