multi-agents-custom 2.0.0 → 2.1.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 +97 -11
- package/dist/chunk-PDPF4T5Z.mjs +1762 -0
- package/dist/cli/index.js +1108 -67
- package/dist/cli/index.mjs +151 -64
- package/dist/index.d.mts +286 -5
- package/dist/index.d.ts +286 -5
- package/dist/index.js +1658 -7
- package/dist/index.mjs +687 -1
- package/package.json +1 -1
- package/dist/chunk-C62CM2KR.mjs +0 -795
package/dist/cli/index.mjs
CHANGED
|
@@ -1,83 +1,170 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
ConfigGenerator
|
|
4
|
-
|
|
3
|
+
ConfigGenerator,
|
|
4
|
+
MasterAgent
|
|
5
|
+
} from "../chunk-PDPF4T5Z.mjs";
|
|
5
6
|
|
|
6
7
|
// src/cli/index.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
help: false
|
|
15
|
-
};
|
|
16
|
-
for (const arg of argv) {
|
|
17
|
-
if (arg === "--help" || arg === "-h") {
|
|
18
|
-
config.help = true;
|
|
19
|
-
} else if (arg === "--overwrite") {
|
|
20
|
-
config.overwrite = true;
|
|
21
|
-
} else if (arg === "--quiet" || arg === "-q") {
|
|
22
|
-
config.verbose = false;
|
|
23
|
-
} else if (arg.startsWith("--targets=")) {
|
|
24
|
-
const raw = arg.slice("--targets=".length).split(",").map((s) => s.trim());
|
|
25
|
-
const valid = raw.filter((t) => VALID_TARGETS.includes(t));
|
|
26
|
-
if (valid.length !== raw.length) {
|
|
27
|
-
const invalid = raw.filter((t) => !VALID_TARGETS.includes(t));
|
|
28
|
-
console.error(`Unknown target(s): ${invalid.join(", ")}. Valid: ${VALID_TARGETS.join(", ")}`);
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
config.targets = valid.length === 1 ? valid[0] : valid;
|
|
32
|
-
} else if (arg.startsWith("--root=")) {
|
|
33
|
-
config.projectRoot = arg.slice("--root=".length);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return config;
|
|
8
|
+
import * as readline from "readline";
|
|
9
|
+
var VALID_TARGETS = ["cursor", "copilot", "qwen", "antigravity"];
|
|
10
|
+
function createReadlineInterface() {
|
|
11
|
+
return readline.createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout
|
|
14
|
+
});
|
|
37
15
|
}
|
|
38
|
-
function
|
|
16
|
+
function printBanner() {
|
|
39
17
|
console.log(`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.github/prompts/ \u2014 GitHub Copilot prompt files (*.prompt.md)
|
|
45
|
-
.qwen/ \u2014 Qwen instruction files (*.md)
|
|
46
|
-
.antigravity/ \u2014 Antigravity persona files (*.md)
|
|
47
|
-
|
|
48
|
-
Options:
|
|
49
|
-
--targets=<list> Comma-separated list of tools to target.
|
|
50
|
-
Valid: cursor, copilot, qwen, antigravity, all
|
|
51
|
-
Default: all
|
|
52
|
-
--root=<path> Project root directory. Default: current working directory
|
|
53
|
-
--overwrite Overwrite existing config files (default: skip existing)
|
|
54
|
-
--quiet, -q Suppress progress output
|
|
55
|
-
--help, -h Show this help message
|
|
56
|
-
`);
|
|
18
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
19
|
+
\u2551 Multi-Agents Custom - AI Tool Config Generator \u2551
|
|
20
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
21
|
+
`);
|
|
57
22
|
}
|
|
58
|
-
async function
|
|
59
|
-
|
|
60
|
-
|
|
23
|
+
async function askQuestion(rl, question) {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
rl.question(question, (answer) => {
|
|
26
|
+
resolve(answer.trim());
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async function askYesNo(rl, question, defaultValue = true) {
|
|
31
|
+
const defaultStr = defaultValue ? "Y/n" : "y/N";
|
|
32
|
+
const answer = await askQuestion(rl, `${question} (${defaultStr}): `);
|
|
33
|
+
if (answer === "") {
|
|
34
|
+
return defaultValue;
|
|
61
35
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
36
|
+
return ["y", "yes", "Y"].includes(answer.toLowerCase());
|
|
37
|
+
}
|
|
38
|
+
async function selectLanguage(rl) {
|
|
39
|
+
console.log("\n\u{1F310} Step 1: Select Output Language");
|
|
40
|
+
console.log(" Choose the language for generated agent config file content:\n");
|
|
41
|
+
console.log(" 1) en \u2014 English (default)");
|
|
42
|
+
console.log(" 2) vi \u2014 Ti\u1EBFng Vi\u1EC7t");
|
|
43
|
+
const answer = await askQuestion(rl, "\n Enter choice [1]: ");
|
|
44
|
+
return answer.trim() === "2" || answer.trim().toLowerCase() === "vi" ? "vi" : "en";
|
|
45
|
+
}
|
|
46
|
+
async function selectTargets(rl) {
|
|
47
|
+
console.log("\n\u{1F4E6} Step 2: Select AI Tools to Configure");
|
|
48
|
+
console.log(" Choose which AI tools you want to generate config files for:\n");
|
|
49
|
+
const targets = [];
|
|
50
|
+
const descriptions = {
|
|
51
|
+
cursor: "Cursor IDE (.cursor/rules/*.mdc)",
|
|
52
|
+
copilot: "GitHub Copilot (.github/prompts/*.prompt.md)",
|
|
53
|
+
qwen: "Qwen Code (.qwen/*.md)",
|
|
54
|
+
antigravity: "AntiGravity (.antigravity/*.md)"
|
|
55
|
+
};
|
|
56
|
+
for (const target of VALID_TARGETS) {
|
|
57
|
+
const selected = await askYesNo(rl, ` ${target} - ${descriptions[target]}`, true);
|
|
58
|
+
if (selected) {
|
|
59
|
+
targets.push(target);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (targets.length === 0) {
|
|
63
|
+
console.log("\n\u26A0\uFE0F No tools selected. Defaulting to all tools.");
|
|
64
|
+
return "all";
|
|
68
65
|
}
|
|
69
|
-
if (
|
|
70
|
-
|
|
66
|
+
if (targets.length === VALID_TARGETS.length) {
|
|
67
|
+
console.log("\n\u2713 All tools selected.");
|
|
68
|
+
return "all";
|
|
71
69
|
}
|
|
72
|
-
|
|
70
|
+
return targets;
|
|
71
|
+
}
|
|
72
|
+
async function getProjectRoot(rl, defaultRoot) {
|
|
73
|
+
console.log("\n\u{1F4C1} Step 3: Project Root Directory");
|
|
74
|
+
const answer = await askQuestion(rl, ` Enter project root path [${defaultRoot}]: `);
|
|
75
|
+
return answer || defaultRoot;
|
|
76
|
+
}
|
|
77
|
+
async function askOverwrite(rl) {
|
|
78
|
+
console.log("\n\u26A0\uFE0F Step 4: Overwrite Existing Files");
|
|
79
|
+
return await askYesNo(rl, " Overwrite existing config files if they exist?", false);
|
|
80
|
+
}
|
|
81
|
+
async function askMasterAgent(rl) {
|
|
82
|
+
console.log("\n\u{1F916} Step 5: Master Agent Orchestration");
|
|
83
|
+
const useMaster = await askYesNo(rl, " Run the Master Agent to orchestrate the pipeline?", false);
|
|
84
|
+
if (useMaster) {
|
|
85
|
+
const prompt = await askQuestion(rl, " Enter your feature description: ");
|
|
86
|
+
return { master: true, prompt: prompt || void 0 };
|
|
87
|
+
}
|
|
88
|
+
return { master: false };
|
|
89
|
+
}
|
|
90
|
+
async function runInteractiveSetup() {
|
|
91
|
+
const rl = createReadlineInterface();
|
|
73
92
|
try {
|
|
93
|
+
printBanner();
|
|
94
|
+
console.log("\u{1F44B} Welcome! This wizard will help you set up AI tool configurations.");
|
|
95
|
+
console.log(" Press Ctrl+C at any time to cancel.\n");
|
|
96
|
+
const installRoot = process.env.INIT_CWD ?? process.cwd();
|
|
97
|
+
const language = await selectLanguage(rl);
|
|
98
|
+
const targets = await selectTargets(rl);
|
|
99
|
+
const projectRoot = await getProjectRoot(rl, installRoot);
|
|
100
|
+
const overwrite = await askOverwrite(rl);
|
|
101
|
+
const { master, prompt } = await askMasterAgent(rl);
|
|
102
|
+
console.log("\n\u{1F4CB} Configuration Summary:");
|
|
103
|
+
console.log(` Language: ${language === "vi" ? "\u{1F1FB}\u{1F1F3} Ti\u1EBFng Vi\u1EC7t" : "\u{1F1EC}\u{1F1E7} English"}`);
|
|
104
|
+
console.log(` Targets: ${targets === "all" ? "All tools" : targets.join(", ")}`);
|
|
105
|
+
console.log(` Project Root: ${projectRoot}`);
|
|
106
|
+
console.log(` Overwrite Existing: ${overwrite ? "Yes" : "No"}`);
|
|
107
|
+
console.log(` Master Agent: ${master ? "Yes" : "No"}${prompt ? ` - "${prompt}"` : ""}`);
|
|
108
|
+
const confirm = await askYesNo(rl, "\n\u2705 Proceed with this configuration?", true);
|
|
109
|
+
if (!confirm) {
|
|
110
|
+
console.log("\n\u274C Installation cancelled.");
|
|
111
|
+
rl.close();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
rl.close();
|
|
115
|
+
const config = {
|
|
116
|
+
targets,
|
|
117
|
+
projectRoot,
|
|
118
|
+
language,
|
|
119
|
+
overwrite,
|
|
120
|
+
verbose: true,
|
|
121
|
+
master,
|
|
122
|
+
prompt
|
|
123
|
+
};
|
|
124
|
+
if (master && prompt) {
|
|
125
|
+
const masterAgent = MasterAgent.getInstance();
|
|
126
|
+
console.log(`
|
|
127
|
+
\x1B[35m[MasterAgent]\x1B[0m Orchestrating: "${prompt}"
|
|
128
|
+
`);
|
|
129
|
+
for await (const event of masterAgent.run(prompt)) {
|
|
130
|
+
const icon = event.type === "success" ? "\u2705" : event.type === "error" ? "\u274C" : "\u2139\uFE0F";
|
|
131
|
+
process.stdout.write(`${icon} [${event.agentId}] ${event.message}
|
|
132
|
+
`);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const generator = new ConfigGenerator(config);
|
|
74
137
|
const result = await generator.generate();
|
|
75
|
-
if (
|
|
138
|
+
if (result.success) {
|
|
139
|
+
console.log("\n\u2705 Configuration generated successfully!");
|
|
140
|
+
} else {
|
|
141
|
+
console.log("\n\u274C Failed to generate configuration.");
|
|
76
142
|
process.exit(1);
|
|
77
143
|
}
|
|
78
144
|
} catch (err) {
|
|
79
|
-
|
|
145
|
+
rl.close();
|
|
146
|
+
console.error("\n\u274C Error during setup:", err);
|
|
80
147
|
process.exit(1);
|
|
81
148
|
}
|
|
82
149
|
}
|
|
150
|
+
async function main() {
|
|
151
|
+
if (process.env.SKIP_MULTI_AGENTS_POSTINSTALL === "1") {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const isCI = process.env.CI === "true" || !process.stdin.isTTY;
|
|
155
|
+
if (isCI) {
|
|
156
|
+
const installRoot = process.env.INIT_CWD ?? process.cwd();
|
|
157
|
+
const config = {
|
|
158
|
+
targets: "all",
|
|
159
|
+
projectRoot: installRoot,
|
|
160
|
+
overwrite: false,
|
|
161
|
+
verbose: true,
|
|
162
|
+
master: false
|
|
163
|
+
};
|
|
164
|
+
const generator = new ConfigGenerator(config);
|
|
165
|
+
await generator.generate();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
await runInteractiveSetup();
|
|
169
|
+
}
|
|
83
170
|
main();
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,77 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Supported AI tool targets that can receive generated config files.
|
|
3
5
|
*/
|
|
4
6
|
type ToolTarget = 'cursor' | 'copilot' | 'qwen' | 'antigravity' | 'all';
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
8
|
+
* Supported output languages for generated config file content.
|
|
9
|
+
* @default 'en'
|
|
10
|
+
*/
|
|
11
|
+
type Language = 'en' | 'vi';
|
|
12
|
+
/**
|
|
13
|
+
* The six agent roles in the software development pipeline.
|
|
7
14
|
*/
|
|
8
|
-
type AgentRole = 'pm' | 'ba' | 'techlead' | 'developer' | 'tester';
|
|
15
|
+
type AgentRole = 'pm' | 'ba' | 'techlead' | 'developer' | 'devlead' | 'tester';
|
|
16
|
+
type ReviewSeverity = 'BLOCKER' | 'MAJOR' | 'MINOR';
|
|
17
|
+
type ReviewCategory = 'DESIGN' | 'QUALITY' | 'OWASP';
|
|
18
|
+
/** A single file included in a code-change diff */
|
|
19
|
+
interface DiffFile {
|
|
20
|
+
/** Repo-relative path to the changed file */
|
|
21
|
+
filePath: string;
|
|
22
|
+
/** File content before the change (empty string for new files) */
|
|
23
|
+
before: string;
|
|
24
|
+
/** File content after the change */
|
|
25
|
+
after: string;
|
|
26
|
+
}
|
|
27
|
+
/** Set of changed files representing a developer's completed change-set */
|
|
28
|
+
interface Diff {
|
|
29
|
+
/** Kebab-case feature identifier */
|
|
30
|
+
featureName: string;
|
|
31
|
+
/** Individual file changes */
|
|
32
|
+
files: DiffFile[];
|
|
33
|
+
}
|
|
34
|
+
/** Input context passed to the DevLeadAgent for a review cycle */
|
|
35
|
+
interface ReviewContext {
|
|
36
|
+
/** Kebab-case feature identifier */
|
|
37
|
+
featureName: string;
|
|
38
|
+
/** Code diff to review */
|
|
39
|
+
diff: Diff;
|
|
40
|
+
/** Path to docs/ai/implementation/feature-{name}.md */
|
|
41
|
+
implementationDocPath: string;
|
|
42
|
+
/** Path to docs/ai/design/feature-{name}.md */
|
|
43
|
+
designDocPath: string;
|
|
44
|
+
}
|
|
45
|
+
/** A single inline review comment produced by a checker */
|
|
46
|
+
interface Finding {
|
|
47
|
+
/** Source file or doc path where the issue was found */
|
|
48
|
+
file: string;
|
|
49
|
+
/** Line number (null for doc-level findings) */
|
|
50
|
+
line: number | null;
|
|
51
|
+
/** Impact on pipeline advancement */
|
|
52
|
+
severity: ReviewSeverity;
|
|
53
|
+
/** Which checker raised this finding */
|
|
54
|
+
category: ReviewCategory;
|
|
55
|
+
/** OWASP Top 10 category label (only set when category === 'OWASP') */
|
|
56
|
+
owaspCategory: string | null;
|
|
57
|
+
/** Human-readable description of the issue */
|
|
58
|
+
message: string;
|
|
59
|
+
/** Optional remediation suggestion */
|
|
60
|
+
suggestion: string | null;
|
|
61
|
+
}
|
|
62
|
+
/** Aggregated output of a full Dev Lead review cycle */
|
|
63
|
+
interface ReviewReport {
|
|
64
|
+
/** Feature being reviewed */
|
|
65
|
+
featureName: string;
|
|
66
|
+
/** ISO-8601 review timestamp */
|
|
67
|
+
timestamp: string;
|
|
68
|
+
/** PASS = no BLOCKERs; CHANGES_REQUESTED = at least one BLOCKER */
|
|
69
|
+
outcome: 'PASS' | 'CHANGES_REQUESTED';
|
|
70
|
+
/** All inline comments from all checkers */
|
|
71
|
+
findings: Finding[];
|
|
72
|
+
/** Prose summary of the review */
|
|
73
|
+
summary: string;
|
|
74
|
+
}
|
|
9
75
|
/**
|
|
10
76
|
* A single agent persona definition used to generate config files.
|
|
11
77
|
*/
|
|
@@ -40,6 +106,11 @@ interface GeneratorConfig {
|
|
|
40
106
|
* Per-agent overrides for system prompts or metadata.
|
|
41
107
|
*/
|
|
42
108
|
agents?: Partial<Record<AgentRole, Partial<AgentPersona>>>;
|
|
109
|
+
/**
|
|
110
|
+
* Language for generated config file content.
|
|
111
|
+
* @default 'en'
|
|
112
|
+
*/
|
|
113
|
+
language?: Language;
|
|
43
114
|
/**
|
|
44
115
|
* Whether to overwrite existing config files.
|
|
45
116
|
* @default false
|
|
@@ -138,9 +209,219 @@ declare class ConfigGenerator {
|
|
|
138
209
|
*/
|
|
139
210
|
declare const DEFAULT_PERSONAS: AgentPersona[];
|
|
140
211
|
/**
|
|
141
|
-
* Returns all default personas, optionally merged with per-role overrides
|
|
212
|
+
* Returns all default personas, optionally merged with per-role overrides
|
|
213
|
+
* and/or translated to the specified language.
|
|
214
|
+
*
|
|
215
|
+
* Language translation is applied first, then per-role overrides on top.
|
|
216
|
+
*
|
|
217
|
+
* @param overrides Optional per-role overrides for system prompts or metadata.
|
|
218
|
+
* @param language Output language for generated content. Defaults to 'en'.
|
|
219
|
+
*/
|
|
220
|
+
declare function buildPersonas(overrides?: Partial<Record<string, Partial<AgentPersona>>>, language?: Language): AgentPersona[];
|
|
221
|
+
|
|
222
|
+
interface Message {
|
|
223
|
+
role: 'user' | 'assistant' | 'system';
|
|
224
|
+
content: string;
|
|
225
|
+
}
|
|
226
|
+
declare enum AgentStatus {
|
|
227
|
+
IDLE = "IDLE",
|
|
228
|
+
PLANNING = "PLANNING",
|
|
229
|
+
EXECUTING = "EXECUTING",
|
|
230
|
+
REVIEWING = "REVIEWING"
|
|
231
|
+
}
|
|
232
|
+
interface AIContext {
|
|
233
|
+
sessionId: string;
|
|
234
|
+
history: Message[];
|
|
235
|
+
documents: Map<string, string>;
|
|
236
|
+
status: AgentStatus;
|
|
237
|
+
}
|
|
238
|
+
interface AgentProgressEvent {
|
|
239
|
+
agentId: string;
|
|
240
|
+
message: string;
|
|
241
|
+
type: 'info' | 'success' | 'warning' | 'error';
|
|
242
|
+
}
|
|
243
|
+
declare abstract class BaseAgent {
|
|
244
|
+
abstract id: string;
|
|
245
|
+
abstract run(context: AIContext): Promise<string>;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
interface AgentExecutionResult {
|
|
249
|
+
agentId: string;
|
|
250
|
+
success: boolean;
|
|
251
|
+
output: string;
|
|
252
|
+
error?: string;
|
|
253
|
+
}
|
|
254
|
+
declare class MasterAgent extends EventEmitter {
|
|
255
|
+
private static instance;
|
|
256
|
+
private context;
|
|
257
|
+
private workflowQueue;
|
|
258
|
+
private executionResults;
|
|
259
|
+
private constructor();
|
|
260
|
+
static getInstance(): MasterAgent;
|
|
261
|
+
run(input: string): AsyncGenerator<AgentProgressEvent>;
|
|
262
|
+
private planWorkflow;
|
|
263
|
+
private executeAgent;
|
|
264
|
+
private buildAgentContext;
|
|
265
|
+
private simulateAgentExecution;
|
|
266
|
+
private generatePMOutput;
|
|
267
|
+
private generateBAOutput;
|
|
268
|
+
private generateTechLeadOutput;
|
|
269
|
+
private generateDeveloperOutput;
|
|
270
|
+
private generateDevLeadOutput;
|
|
271
|
+
private generateTesterOutput;
|
|
272
|
+
getContext(): AIContext;
|
|
273
|
+
getExecutionResults(): Map<AgentRole, AgentExecutionResult>;
|
|
274
|
+
reset(): void;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Design Adherence Checker.
|
|
279
|
+
*
|
|
280
|
+
* Compares the code diff and implementation doc against the approved design doc,
|
|
281
|
+
* flagging deviations from agreed components, data models, and API contracts.
|
|
142
282
|
*/
|
|
143
|
-
declare
|
|
283
|
+
declare class DesignChecker {
|
|
284
|
+
/**
|
|
285
|
+
* @param diff Set of changed files.
|
|
286
|
+
* @param implDoc Content of docs/ai/implementation/feature-{name}.md.
|
|
287
|
+
* @param designDoc Content of docs/ai/design/feature-{name}.md.
|
|
288
|
+
*/
|
|
289
|
+
check(diff: Diff, implDoc: string, designDoc: string): Finding[];
|
|
290
|
+
/**
|
|
291
|
+
* Extract bold component names from the design doc Components table.
|
|
292
|
+
* Matches `**ComponentName**` patterns.
|
|
293
|
+
*/
|
|
294
|
+
extractComponents(designDoc: string): string[];
|
|
295
|
+
/**
|
|
296
|
+
* Extract interface/type names from the design doc API/Data-model sections.
|
|
297
|
+
* Matches `interface FooBar` or `type FooBar` patterns.
|
|
298
|
+
*/
|
|
299
|
+
extractInterfaces(designDoc: string): string[];
|
|
300
|
+
private checkComponentPresence;
|
|
301
|
+
private checkInterfaceConformance;
|
|
302
|
+
private checkNoNewUnlistedExports;
|
|
303
|
+
private checkImplDocCoverage;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Code Quality Checker.
|
|
308
|
+
*
|
|
309
|
+
* Applies coding standards to the diff: naming conventions, function length,
|
|
310
|
+
* TypeScript strict-mode compliance, TODO comments, and unsafe patterns.
|
|
311
|
+
*/
|
|
312
|
+
declare class QualityChecker {
|
|
313
|
+
private static readonly MAX_FUNCTION_LINES;
|
|
314
|
+
/**
|
|
315
|
+
* @param diff Set of changed files to analyse.
|
|
316
|
+
*/
|
|
317
|
+
check(diff: Diff): Finding[];
|
|
318
|
+
private checkAnyUsage;
|
|
319
|
+
private checkFunctionLength;
|
|
320
|
+
private checkMissingReturnTypes;
|
|
321
|
+
private checkTodoComments;
|
|
322
|
+
private checkConsoleStatements;
|
|
323
|
+
private checkNonNullAssertions;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* OWASP Security Checker.
|
|
328
|
+
*
|
|
329
|
+
* Scans modified TypeScript files for OWASP Top 10 security issues:
|
|
330
|
+
* A01 — Broken Access Control
|
|
331
|
+
* A02 — Cryptographic Failures
|
|
332
|
+
* A03 — Injection (SQL, command, eval)
|
|
333
|
+
* A05 — Security Misconfiguration
|
|
334
|
+
* A07 — Identification and Authentication Failures
|
|
335
|
+
* A10 — Server-Side Request Forgery (SSRF)
|
|
336
|
+
*/
|
|
337
|
+
declare class OWASPChecker {
|
|
338
|
+
/**
|
|
339
|
+
* @param diff Set of changed files to analyse.
|
|
340
|
+
*/
|
|
341
|
+
check(diff: Diff): Finding[];
|
|
342
|
+
private checkHardcodedSecrets;
|
|
343
|
+
private checkWeakCrypto;
|
|
344
|
+
private checkInjection;
|
|
345
|
+
private checkMissingAuthChecks;
|
|
346
|
+
private checkSSRF;
|
|
347
|
+
private checkInsecureConfigs;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Review Report Builder.
|
|
352
|
+
*
|
|
353
|
+
* Aggregates findings from all checkers into a structured ReviewReport.
|
|
354
|
+
* Outcome logic:
|
|
355
|
+
* - CHANGES_REQUESTED if any finding has severity === 'BLOCKER'
|
|
356
|
+
* - PASS otherwise (MAJOR/MINOR findings are surfaced but do not block)
|
|
357
|
+
*/
|
|
358
|
+
declare class ReportBuilder {
|
|
359
|
+
/**
|
|
360
|
+
* @param featureName Kebab-case feature name.
|
|
361
|
+
* @param findings All findings from all checkers.
|
|
362
|
+
*/
|
|
363
|
+
build(featureName: string, findings: Finding[]): ReviewReport;
|
|
364
|
+
private buildSummary;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
type ConfirmationResult = {
|
|
368
|
+
decision: 'approved';
|
|
369
|
+
} | {
|
|
370
|
+
decision: 'rejected';
|
|
371
|
+
note: string;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* Human Confirmation Gate.
|
|
375
|
+
*
|
|
376
|
+
* Prints the ReviewReport to stdout and blocks until the user inputs
|
|
377
|
+
* `/approve` or `/reject [optional note]`.
|
|
378
|
+
*
|
|
379
|
+
* Pipeline behaviour:
|
|
380
|
+
* /approve → report is passed to the Tester as read-only context
|
|
381
|
+
* /reject → report + optional note re-queued to Developer as context
|
|
382
|
+
*/
|
|
383
|
+
declare class ConfirmationGate {
|
|
384
|
+
/**
|
|
385
|
+
* Display the report and wait for human confirmation.
|
|
386
|
+
*
|
|
387
|
+
* @param report The completed ReviewReport from the ReportBuilder.
|
|
388
|
+
* @returns The human's decision plus any rejection note.
|
|
389
|
+
*/
|
|
390
|
+
wait(report: ReviewReport): Promise<ConfirmationResult>;
|
|
391
|
+
private printReport;
|
|
392
|
+
private promptUser;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* DevLeadAgent — Phase 4.5: Code Review Gate.
|
|
397
|
+
*
|
|
398
|
+
* Positioned between the Developer and Tester agents in the pipeline.
|
|
399
|
+
* Orchestrates three checkers (Design, Quality, OWASP), builds a structured
|
|
400
|
+
* ReviewReport, persists it to docs/ai/review/, then waits for human
|
|
401
|
+
* confirmation before allowing the pipeline to advance.
|
|
402
|
+
*/
|
|
403
|
+
declare class DevLeadAgent {
|
|
404
|
+
private readonly designChecker;
|
|
405
|
+
private readonly qualityChecker;
|
|
406
|
+
private readonly owaspChecker;
|
|
407
|
+
private readonly reportBuilder;
|
|
408
|
+
private readonly confirmationGate;
|
|
409
|
+
constructor(designChecker?: DesignChecker, qualityChecker?: QualityChecker, owaspChecker?: OWASPChecker, reportBuilder?: ReportBuilder, confirmationGate?: ConfirmationGate);
|
|
410
|
+
/**
|
|
411
|
+
* Run a full review cycle for a feature's code changes.
|
|
412
|
+
*
|
|
413
|
+
* 1. Loads the design doc and implementation doc from disk.
|
|
414
|
+
* 2. Runs all three checkers against the diff.
|
|
415
|
+
* 3. Builds and persists the ReviewReport.
|
|
416
|
+
* 4. Presents the report to the human and waits for /approve or /reject.
|
|
417
|
+
*
|
|
418
|
+
* @returns The completed ReviewReport (includes human decision in calling context).
|
|
419
|
+
* @throws If required doc files cannot be read.
|
|
420
|
+
*/
|
|
421
|
+
review(context: ReviewContext): Promise<ReviewReport>;
|
|
422
|
+
private readDoc;
|
|
423
|
+
private persistReport;
|
|
424
|
+
}
|
|
144
425
|
|
|
145
426
|
/**
|
|
146
427
|
* Generates `.cursor/rules/<role>.mdc` files.
|
|
@@ -221,4 +502,4 @@ declare class Logger {
|
|
|
221
502
|
heading(msg: string): void;
|
|
222
503
|
}
|
|
223
504
|
|
|
224
|
-
export { type AgentPersona, type AgentRole, AntigravityWriter, ConfigGenerator, CopilotWriter, CursorWriter, DEFAULT_PERSONAS, type GeneratorConfig, type GeneratorResult, type IProviderWriter, Logger, QwenWriter, type ToolTarget, type WriteResult, buildPersonas, resolveWriters };
|
|
505
|
+
export { type AIContext, type AgentExecutionResult, type AgentPersona, type AgentProgressEvent, type AgentRole, AgentStatus, AntigravityWriter, BaseAgent, ConfigGenerator, CopilotWriter, CursorWriter, DEFAULT_PERSONAS, DevLeadAgent, type Diff, type DiffFile, type Finding, type GeneratorConfig, type GeneratorResult, type IProviderWriter, type Language, Logger, MasterAgent, type Message, QwenWriter, type ReviewCategory, type ReviewContext, type ReviewReport, type ReviewSeverity, type ToolTarget, type WriteResult, buildPersonas, resolveWriters };
|