@fredericboyer/dev-team 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/bin/dev-team.js +1 -21
- package/dist/bin/dev-team.d.ts +1 -0
- package/dist/bin/dev-team.js +28 -0
- package/dist/bin/dev-team.js.map +1 -0
- package/dist/files.d.ts +51 -0
- package/dist/files.js +155 -0
- package/dist/files.js.map +1 -0
- package/dist/init.d.ts +4 -0
- package/dist/init.js +307 -0
- package/dist/init.js.map +1 -0
- package/dist/prompts.d.ts +25 -0
- package/dist/prompts.js +109 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scan.d.ts +15 -0
- package/dist/scan.js +187 -0
- package/dist/scan.js.map +1 -0
- package/dist/update.d.ts +5 -0
- package/dist/update.js +229 -0
- package/dist/update.js.map +1 -0
- package/package.json +30 -9
- package/templates/CLAUDE.md +18 -0
- package/templates/agent-memory/dev-team-architect/MEMORY.md +12 -0
- package/templates/agent-memory/dev-team-docs/MEMORY.md +12 -0
- package/templates/agent-memory/dev-team-release/MEMORY.md +12 -0
- package/templates/agents/dev-team-architect.md +62 -0
- package/templates/agents/dev-team-deming.md +2 -1
- package/templates/agents/dev-team-docs.md +63 -0
- package/templates/agents/dev-team-release.md +65 -0
- package/templates/hooks/dev-team-post-change-review.js +63 -10
- package/templates/hooks/dev-team-pre-commit-gate.js +12 -14
- package/templates/hooks/dev-team-safety-guard.js +21 -11
- package/templates/hooks/dev-team-task-loop.js +17 -9
- package/templates/hooks/dev-team-tdd-enforce.js +42 -23
- package/templates/skills/dev-team-audit/SKILL.md +85 -0
- package/templates/skills/dev-team-review/SKILL.md +68 -0
- package/lib/files.js +0 -160
- package/lib/init.js +0 -206
- package/lib/prompts.js +0 -123
|
@@ -8,12 +8,20 @@
|
|
|
8
8
|
* the file's domain. Advisory only — always exits 0.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
"use strict";
|
|
12
12
|
|
|
13
|
-
const path = require(
|
|
13
|
+
const path = require("path");
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
let input = {};
|
|
16
|
+
try {
|
|
17
|
+
input = JSON.parse(process.argv[2] || "{}");
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.warn(
|
|
20
|
+
`[dev-team post-change-review] Warning: Failed to parse hook input, allowing operation. ${err.message}`,
|
|
21
|
+
);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
const filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
|
|
17
25
|
|
|
18
26
|
if (!filePath) {
|
|
19
27
|
process.exit(0);
|
|
@@ -47,7 +55,7 @@ const SECURITY_PATTERNS = [
|
|
|
47
55
|
];
|
|
48
56
|
|
|
49
57
|
if (SECURITY_PATTERNS.some((p) => p.test(fullPath) || p.test(basename))) {
|
|
50
|
-
flags.push(
|
|
58
|
+
flags.push("@dev-team-szabo (security surface changed)");
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
// API/contract patterns → flag for Mori
|
|
@@ -63,7 +71,7 @@ const API_PATTERNS = [
|
|
|
63
71
|
];
|
|
64
72
|
|
|
65
73
|
if (API_PATTERNS.some((p) => p.test(fullPath))) {
|
|
66
|
-
flags.push(
|
|
74
|
+
flags.push("@dev-team-mori (API contract may affect UI)");
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
// Config/infra patterns → flag for Voss
|
|
@@ -79,7 +87,7 @@ const INFRA_PATTERNS = [
|
|
|
79
87
|
];
|
|
80
88
|
|
|
81
89
|
if (INFRA_PATTERNS.some((p) => p.test(fullPath))) {
|
|
82
|
-
flags.push(
|
|
90
|
+
flags.push("@dev-team-voss (architectural/config change)");
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
// Tooling patterns → flag for Deming
|
|
@@ -96,7 +104,52 @@ const TOOLING_PATTERNS = [
|
|
|
96
104
|
];
|
|
97
105
|
|
|
98
106
|
if (TOOLING_PATTERNS.some((p) => p.test(fullPath))) {
|
|
99
|
-
flags.push(
|
|
107
|
+
flags.push("@dev-team-deming (tooling change)");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Documentation patterns → flag for Docs
|
|
111
|
+
const DOC_PATTERNS = [
|
|
112
|
+
/readme/,
|
|
113
|
+
/changelog/,
|
|
114
|
+
/\.md$/,
|
|
115
|
+
/\.mdx$/,
|
|
116
|
+
/\/docs?\//,
|
|
117
|
+
/api-doc/,
|
|
118
|
+
/jsdoc/,
|
|
119
|
+
/typedoc/,
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
if (DOC_PATTERNS.some((p) => p.test(fullPath))) {
|
|
123
|
+
flags.push("@dev-team-docs (documentation changed)");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Architecture patterns → flag for Architect
|
|
127
|
+
const ARCH_PATTERNS = [
|
|
128
|
+
/\/adr\//,
|
|
129
|
+
/architecture/,
|
|
130
|
+
/\/modules?\//,
|
|
131
|
+
/\/layers?\//,
|
|
132
|
+
/\/core\//,
|
|
133
|
+
/\/domain\//,
|
|
134
|
+
/\/shared\//,
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
if (ARCH_PATTERNS.some((p) => p.test(fullPath))) {
|
|
138
|
+
flags.push("@dev-team-architect (architectural boundary touched)");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Release patterns → flag for Release
|
|
142
|
+
const RELEASE_PATTERNS = [
|
|
143
|
+
/package\.json$/,
|
|
144
|
+
/pyproject\.toml$/,
|
|
145
|
+
/cargo\.toml$/i,
|
|
146
|
+
/changelog/i,
|
|
147
|
+
/version/,
|
|
148
|
+
/\.github\/workflows\/.*release/,
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
if (RELEASE_PATTERNS.some((p) => p.test(fullPath))) {
|
|
152
|
+
flags.push("@dev-team-release (version/release artifact changed)");
|
|
100
153
|
}
|
|
101
154
|
|
|
102
155
|
// Always flag Knuth for non-test implementation files
|
|
@@ -104,11 +157,11 @@ const isTestFile = /\.(test|spec)\.|__tests__|\/tests?\//.test(fullPath);
|
|
|
104
157
|
const isCodeFile = /\.(js|ts|jsx|tsx|py|rb|go|java|rs|c|cpp|cs)$/.test(fullPath);
|
|
105
158
|
|
|
106
159
|
if (isCodeFile && !isTestFile) {
|
|
107
|
-
flags.push(
|
|
160
|
+
flags.push("@dev-team-knuth (new or changed code path to audit)");
|
|
108
161
|
}
|
|
109
162
|
|
|
110
163
|
if (flags.length > 0) {
|
|
111
|
-
console.log(`[dev-team review] Flag for review: ${flags.join(
|
|
164
|
+
console.log(`[dev-team review] Flag for review: ${flags.join(", ")}`);
|
|
112
165
|
}
|
|
113
166
|
|
|
114
167
|
process.exit(0);
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
* review agents if they were not consulted. Advisory — always exits 0.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
"use strict";
|
|
12
12
|
|
|
13
|
-
const { execFileSync } = require(
|
|
13
|
+
const { execFileSync } = require("child_process");
|
|
14
14
|
|
|
15
|
-
let stagedFiles =
|
|
15
|
+
let stagedFiles = "";
|
|
16
16
|
try {
|
|
17
|
-
stagedFiles = execFileSync(
|
|
18
|
-
encoding:
|
|
17
|
+
stagedFiles = execFileSync("git", ["diff", "--cached", "--name-only"], {
|
|
18
|
+
encoding: "utf-8",
|
|
19
19
|
timeout: 5000,
|
|
20
20
|
});
|
|
21
21
|
} catch {
|
|
@@ -23,7 +23,7 @@ try {
|
|
|
23
23
|
process.exit(0);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const files = stagedFiles.split(
|
|
26
|
+
const files = stagedFiles.split("\n").filter(Boolean);
|
|
27
27
|
|
|
28
28
|
if (files.length === 0) {
|
|
29
29
|
process.exit(0);
|
|
@@ -32,28 +32,26 @@ if (files.length === 0) {
|
|
|
32
32
|
const reminders = [];
|
|
33
33
|
|
|
34
34
|
const hasSecurityFiles = files.some((f) =>
|
|
35
|
-
/auth|login|password|token|session|crypto|secret|permission/.test(f)
|
|
35
|
+
/auth|login|password|token|session|crypto|secret|permission/.test(f),
|
|
36
36
|
);
|
|
37
37
|
if (hasSecurityFiles) {
|
|
38
|
-
reminders.push(
|
|
38
|
+
reminders.push("@dev-team-szabo for security review");
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const hasImplFiles = files.some(
|
|
42
|
-
(f) => /\.(js|ts|jsx|tsx|py|rb|go|java|rs)$/.test(f) && !/\.(test|spec)\./.test(f)
|
|
42
|
+
(f) => /\.(js|ts|jsx|tsx|py|rb|go|java|rs)$/.test(f) && !/\.(test|spec)\./.test(f),
|
|
43
43
|
);
|
|
44
44
|
if (hasImplFiles) {
|
|
45
|
-
reminders.push(
|
|
45
|
+
reminders.push("@dev-team-knuth for quality audit");
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const hasApiFiles = files.some((f) => /\/api\/|\/routes?\/|schema|\.graphql$/.test(f));
|
|
49
49
|
if (hasApiFiles) {
|
|
50
|
-
reminders.push(
|
|
50
|
+
reminders.push("@dev-team-mori for UI impact review");
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (reminders.length > 0) {
|
|
54
|
-
console.log(
|
|
55
|
-
`[dev-team pre-commit] Before committing, consider running: ${reminders.join(', ')}`
|
|
56
|
-
);
|
|
54
|
+
console.log(`[dev-team pre-commit] Before committing, consider running: ${reminders.join(", ")}`);
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
process.exit(0);
|
|
@@ -8,43 +8,53 @@
|
|
|
8
8
|
* Exit 2 = block, exit 0 = allow.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
"use strict";
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
let input = {};
|
|
14
|
+
try {
|
|
15
|
+
input = JSON.parse(process.argv[2] || "{}");
|
|
16
|
+
} catch (err) {
|
|
17
|
+
// SECURITY TRADEOFF: Failing open means parse errors bypass safety checks.
|
|
18
|
+
// We accept this because failing closed (exit 2) would block all Bash operations when input is malformed.
|
|
19
|
+
console.warn(
|
|
20
|
+
`[dev-team safety-guard] Warning: Failed to parse hook input, allowing operation. ${err.message}`,
|
|
21
|
+
);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
const command = (input.tool_input && input.tool_input.command) || "";
|
|
15
25
|
|
|
16
26
|
const BLOCKED_PATTERNS = [
|
|
17
27
|
{
|
|
18
28
|
pattern: /\brm\s+(-[^\s]*r[^\s]*|--recursive)\s+[^\s]*\s*\/\s*$/,
|
|
19
|
-
reason:
|
|
29
|
+
reason: "Recursive delete on root path is blocked.",
|
|
20
30
|
},
|
|
21
31
|
{
|
|
22
32
|
pattern: /\brm\s+(-[^\s]*r[^\s]*|--recursive)\s+.*~\//,
|
|
23
|
-
reason:
|
|
33
|
+
reason: "Recursive delete on home directory is blocked.",
|
|
24
34
|
},
|
|
25
35
|
{
|
|
26
36
|
pattern: /\bgit\s+push\s+.*--force\b.*\b(main|master)\b/,
|
|
27
|
-
reason:
|
|
37
|
+
reason: "Force push to main/master is blocked. Use a PR instead.",
|
|
28
38
|
},
|
|
29
39
|
{
|
|
30
40
|
pattern: /\bgit\s+push\s+.*\b(main|master)\b.*--force\b/,
|
|
31
|
-
reason:
|
|
41
|
+
reason: "Force push to main/master is blocked. Use a PR instead.",
|
|
32
42
|
},
|
|
33
43
|
{
|
|
34
44
|
pattern: /\bDROP\s+(TABLE|DATABASE)\b/i,
|
|
35
|
-
reason:
|
|
45
|
+
reason: "DROP TABLE/DATABASE is blocked. Use a migration instead.",
|
|
36
46
|
},
|
|
37
47
|
{
|
|
38
48
|
pattern: /\bchmod\s+777\b/,
|
|
39
|
-
reason:
|
|
49
|
+
reason: "chmod 777 is blocked. Use specific permissions instead.",
|
|
40
50
|
},
|
|
41
51
|
{
|
|
42
52
|
pattern: /\bcurl\b.*\|\s*(sh|bash|zsh)\b/,
|
|
43
|
-
reason:
|
|
53
|
+
reason: "Piping curl to a shell is blocked. Download and inspect scripts before executing.",
|
|
44
54
|
},
|
|
45
55
|
{
|
|
46
56
|
pattern: /\bwget\b.*\|\s*(sh|bash|zsh)\b/,
|
|
47
|
-
reason:
|
|
57
|
+
reason: "Piping wget to a shell is blocked. Download and inspect scripts before executing.",
|
|
48
58
|
},
|
|
49
59
|
];
|
|
50
60
|
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
* State file: .claude/dev-team-task.json (created by /dev-team:task skill)
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
"use strict";
|
|
17
17
|
|
|
18
|
-
const fs = require(
|
|
19
|
-
const path = require(
|
|
18
|
+
const fs = require("fs");
|
|
19
|
+
const path = require("path");
|
|
20
20
|
|
|
21
|
-
const STATE_FILE = path.join(process.cwd(),
|
|
21
|
+
const STATE_FILE = path.join(process.cwd(), ".claude", "dev-team-task.json");
|
|
22
22
|
|
|
23
23
|
// No state file means no active task loop — allow normal exit
|
|
24
24
|
if (!fs.existsSync(STATE_FILE)) {
|
|
@@ -27,10 +27,14 @@ if (!fs.existsSync(STATE_FILE)) {
|
|
|
27
27
|
|
|
28
28
|
let state;
|
|
29
29
|
try {
|
|
30
|
-
state = JSON.parse(fs.readFileSync(STATE_FILE,
|
|
30
|
+
state = JSON.parse(fs.readFileSync(STATE_FILE, "utf-8"));
|
|
31
31
|
} catch {
|
|
32
32
|
// Corrupted state file — clean up and allow exit
|
|
33
|
-
try {
|
|
33
|
+
try {
|
|
34
|
+
fs.unlinkSync(STATE_FILE);
|
|
35
|
+
} catch {
|
|
36
|
+
/* ignore */
|
|
37
|
+
}
|
|
34
38
|
process.exit(0);
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -39,9 +43,13 @@ const { prompt, iteration = 1, maxIterations = 10, sessionId } = state;
|
|
|
39
43
|
// Check iteration limit
|
|
40
44
|
if (iteration >= maxIterations) {
|
|
41
45
|
console.log(
|
|
42
|
-
`[dev-team task-loop] Max iterations (${maxIterations}) reached. Exiting loop. Review remaining issues manually
|
|
46
|
+
`[dev-team task-loop] Max iterations (${maxIterations}) reached. Exiting loop. Review remaining issues manually.`,
|
|
43
47
|
);
|
|
44
|
-
try {
|
|
48
|
+
try {
|
|
49
|
+
fs.unlinkSync(STATE_FILE);
|
|
50
|
+
} catch {
|
|
51
|
+
/* ignore */
|
|
52
|
+
}
|
|
45
53
|
process.exit(0);
|
|
46
54
|
}
|
|
47
55
|
|
|
@@ -56,7 +64,7 @@ try {
|
|
|
56
64
|
|
|
57
65
|
// Block exit and re-inject the task prompt
|
|
58
66
|
const output = JSON.stringify({
|
|
59
|
-
decision:
|
|
67
|
+
decision: "block",
|
|
60
68
|
reason: prompt,
|
|
61
69
|
systemMessage: `[dev-team task-loop] Iteration ${iteration + 1}/${maxIterations}. Review findings and address any [DEFECT] challenges. When no [DEFECT] remains, output <promise>DONE</promise> to exit the loop. To cancel: delete .claude/dev-team-task.json`,
|
|
62
70
|
});
|
|
@@ -12,13 +12,21 @@
|
|
|
12
12
|
* Exit 2 = block, exit 0 = allow.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
"use strict";
|
|
16
16
|
|
|
17
|
-
const { execFileSync } = require(
|
|
18
|
-
const path = require(
|
|
17
|
+
const { execFileSync } = require("child_process");
|
|
18
|
+
const path = require("path");
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
let input = {};
|
|
21
|
+
try {
|
|
22
|
+
input = JSON.parse(process.argv[2] || "{}");
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.warn(
|
|
25
|
+
`[dev-team tdd-enforce] Warning: Failed to parse hook input, allowing operation. ${err.message}`,
|
|
26
|
+
);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
const filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
|
|
22
30
|
|
|
23
31
|
if (!filePath) {
|
|
24
32
|
process.exit(0);
|
|
@@ -28,20 +36,27 @@ const basename = path.basename(filePath);
|
|
|
28
36
|
const ext = path.extname(filePath);
|
|
29
37
|
|
|
30
38
|
// Skip non-code files
|
|
31
|
-
const SKIP_EXTENSIONS = [
|
|
39
|
+
const SKIP_EXTENSIONS = [
|
|
40
|
+
".md",
|
|
41
|
+
".json",
|
|
42
|
+
".yml",
|
|
43
|
+
".yaml",
|
|
44
|
+
".toml",
|
|
45
|
+
".txt",
|
|
46
|
+
".css",
|
|
47
|
+
".svg",
|
|
48
|
+
".png",
|
|
49
|
+
".jpg",
|
|
50
|
+
".gif",
|
|
51
|
+
".ico",
|
|
52
|
+
".lock",
|
|
53
|
+
];
|
|
32
54
|
if (SKIP_EXTENSIONS.includes(ext)) {
|
|
33
55
|
process.exit(0);
|
|
34
56
|
}
|
|
35
57
|
|
|
36
58
|
// Skip if the file IS a test file
|
|
37
|
-
const TEST_PATTERNS = [
|
|
38
|
-
/\.test\./,
|
|
39
|
-
/\.spec\./,
|
|
40
|
-
/_test\./,
|
|
41
|
-
/\/__tests__\//,
|
|
42
|
-
/\/test\//,
|
|
43
|
-
/\/tests\//,
|
|
44
|
-
];
|
|
59
|
+
const TEST_PATTERNS = [/\.test\./, /\.spec\./, /_test\./, /\/__tests__\//, /\/test\//, /\/tests\//];
|
|
45
60
|
|
|
46
61
|
if (TEST_PATTERNS.some((p) => p.test(filePath))) {
|
|
47
62
|
process.exit(0);
|
|
@@ -64,10 +79,10 @@ if (SKIP_PATTERNS.some((p) => p.test(filePath))) {
|
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
// Check if any test file has been modified in this session
|
|
67
|
-
let changedFiles =
|
|
82
|
+
let changedFiles = "";
|
|
68
83
|
try {
|
|
69
|
-
changedFiles = execFileSync(
|
|
70
|
-
encoding:
|
|
84
|
+
changedFiles = execFileSync("git", ["diff", "--name-only"], {
|
|
85
|
+
encoding: "utf-8",
|
|
71
86
|
timeout: 5000,
|
|
72
87
|
});
|
|
73
88
|
} catch {
|
|
@@ -76,7 +91,7 @@ try {
|
|
|
76
91
|
}
|
|
77
92
|
|
|
78
93
|
const hasTestChanges = changedFiles
|
|
79
|
-
.split(
|
|
94
|
+
.split("\n")
|
|
80
95
|
.filter(Boolean)
|
|
81
96
|
.some((f) => TEST_PATTERNS.some((p) => p.test(f)));
|
|
82
97
|
|
|
@@ -88,19 +103,23 @@ if (hasTestChanges) {
|
|
|
88
103
|
// No test changes — check if a corresponding test file already exists.
|
|
89
104
|
// This allows refactoring (modifying existing tested code) without
|
|
90
105
|
// requiring the test file to also be modified.
|
|
91
|
-
const fs = require(
|
|
106
|
+
const fs = require("fs");
|
|
92
107
|
const dir = path.dirname(filePath);
|
|
93
108
|
const name = path.basename(filePath, ext);
|
|
94
109
|
|
|
95
110
|
const CANDIDATE_PATTERNS = [
|
|
96
111
|
path.join(dir, `${name}.test${ext}`),
|
|
97
112
|
path.join(dir, `${name}.spec${ext}`),
|
|
98
|
-
path.join(dir,
|
|
99
|
-
path.join(dir,
|
|
113
|
+
path.join(dir, "__tests__", `${name}${ext}`),
|
|
114
|
+
path.join(dir, "__tests__", `${name}.test${ext}`),
|
|
100
115
|
];
|
|
101
116
|
|
|
102
117
|
const hasExistingTests = CANDIDATE_PATTERNS.some((candidate) => {
|
|
103
|
-
try {
|
|
118
|
+
try {
|
|
119
|
+
return fs.statSync(candidate).isFile();
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
104
123
|
});
|
|
105
124
|
|
|
106
125
|
if (hasExistingTests) {
|
|
@@ -110,6 +129,6 @@ if (hasExistingTests) {
|
|
|
110
129
|
|
|
111
130
|
// No test changes AND no existing test file — block
|
|
112
131
|
console.error(
|
|
113
|
-
`[dev-team tdd-enforce] TDD violation: "${basename}" modified but no corresponding test file exists. Write tests first
|
|
132
|
+
`[dev-team tdd-enforce] TDD violation: "${basename}" modified but no corresponding test file exists. Write tests first.`,
|
|
114
133
|
);
|
|
115
134
|
process.exit(2);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-team:audit
|
|
3
|
+
description: Full codebase audit combining security, quality, and tooling assessments. Use to run a comprehensive scan with Szabo (security), Knuth (quality), and Deming (tooling) in parallel. Can be scoped to specific directories or file patterns.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Run a comprehensive audit of: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
1. Determine the audit scope:
|
|
11
|
+
- If a directory or file pattern is given, scope the audit to those paths
|
|
12
|
+
- If no argument, audit the entire codebase
|
|
13
|
+
- Respect `.gitignore` — skip `node_modules/`, `dist/`, build artifacts
|
|
14
|
+
|
|
15
|
+
2. The audit always spawns three specialist agents:
|
|
16
|
+
- **@dev-team-szabo** — Security audit
|
|
17
|
+
- **@dev-team-knuth** — Quality and correctness audit
|
|
18
|
+
- **@dev-team-deming** — Tooling and automation audit
|
|
19
|
+
|
|
20
|
+
## Execution
|
|
21
|
+
|
|
22
|
+
1. Spawn all three agents as **parallel background subagents** using the Agent tool with `subagent_type: "general-purpose"`.
|
|
23
|
+
|
|
24
|
+
2. Each agent's prompt must include:
|
|
25
|
+
- The agent's full definition (read from `.claude/agents/<agent>.md`)
|
|
26
|
+
- The scope (directory/pattern or "full codebase")
|
|
27
|
+
- Instruction to produce classified findings: `[DEFECT]`, `[RISK]`, `[QUESTION]`, `[SUGGESTION]`
|
|
28
|
+
- Instruction to read the actual code and tests for full context
|
|
29
|
+
|
|
30
|
+
3. Agent-specific instructions:
|
|
31
|
+
|
|
32
|
+
**Szabo (Security)**:
|
|
33
|
+
- Map all trust boundaries and entry points
|
|
34
|
+
- Check for OWASP Top 10 vulnerabilities
|
|
35
|
+
- Audit auth/authz flows end-to-end
|
|
36
|
+
- Review secret management and dependency vulnerabilities
|
|
37
|
+
|
|
38
|
+
**Knuth (Quality)**:
|
|
39
|
+
- Identify untested code paths and coverage gaps
|
|
40
|
+
- Find boundary conditions without tests
|
|
41
|
+
- Check assertion quality in existing tests
|
|
42
|
+
- Map test-to-requirement traceability
|
|
43
|
+
|
|
44
|
+
**Deming (Tooling)**:
|
|
45
|
+
- Inventory current tooling (linters, formatters, SAST, CI)
|
|
46
|
+
- Identify missing automation opportunities
|
|
47
|
+
- Check for stale dependencies and known vulnerabilities
|
|
48
|
+
- Evaluate CI pipeline efficiency
|
|
49
|
+
|
|
50
|
+
4. Wait for all agents to complete.
|
|
51
|
+
|
|
52
|
+
## Report
|
|
53
|
+
|
|
54
|
+
Produce a consolidated audit report:
|
|
55
|
+
|
|
56
|
+
### Executive summary
|
|
57
|
+
|
|
58
|
+
One paragraph summarizing the overall health of the codebase across all three domains.
|
|
59
|
+
|
|
60
|
+
### Security findings (@dev-team-szabo)
|
|
61
|
+
|
|
62
|
+
List all findings, grouped by classification:
|
|
63
|
+
- `[DEFECT]` — must fix
|
|
64
|
+
- `[RISK]` — should address
|
|
65
|
+
- `[QUESTION]` / `[SUGGESTION]` — consider
|
|
66
|
+
|
|
67
|
+
### Quality findings (@dev-team-knuth)
|
|
68
|
+
|
|
69
|
+
Same grouping. Include specific files and line references.
|
|
70
|
+
|
|
71
|
+
### Tooling findings (@dev-team-deming)
|
|
72
|
+
|
|
73
|
+
Same grouping. Include actionable recommendations.
|
|
74
|
+
|
|
75
|
+
### Priority matrix
|
|
76
|
+
|
|
77
|
+
| Priority | Finding | Agent | Action |
|
|
78
|
+
|----------|---------|-------|--------|
|
|
79
|
+
| P0 (fix now) | `[DEFECT]` items | ... | ... |
|
|
80
|
+
| P1 (fix soon) | `[RISK]` items | ... | ... |
|
|
81
|
+
| P2 (improve) | `[SUGGESTION]` items | ... | ... |
|
|
82
|
+
|
|
83
|
+
### Recommended next steps
|
|
84
|
+
|
|
85
|
+
Numbered list of concrete actions, ordered by priority. Each action should reference the specific finding it addresses.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-team:review
|
|
3
|
+
description: Orchestrated multi-agent parallel review. Use to review a PR, branch, or set of changes with multiple specialist agents simultaneously. Spawns agents based on changed file patterns and produces a unified review summary.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Run a multi-agent parallel review of: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
1. Determine what to review:
|
|
11
|
+
- If a PR number or branch is given, use `git diff` to get the changed files
|
|
12
|
+
- If a directory or file pattern is given, review those files
|
|
13
|
+
- If no argument, review all uncommitted changes (`git diff HEAD`)
|
|
14
|
+
|
|
15
|
+
2. Categorize changed files by domain to determine which agents to spawn:
|
|
16
|
+
|
|
17
|
+
| File pattern | Agent | Reason |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `auth`, `login`, `password`, `token`, `session`, `crypto`, `secret`, `permission`, `oauth`, `jwt`, `cors`, `csrf` | @dev-team-szabo | Security surface |
|
|
20
|
+
| `/api/`, `/routes/`, `schema`, `.graphql`, `.proto`, `openapi` | @dev-team-mori | API/UI contract |
|
|
21
|
+
| `docker`, `.env`, `config`, `migration`, `database`, `.sql`, `deploy` | @dev-team-voss | Infrastructure |
|
|
22
|
+
| `.github/workflows`, `.claude/`, `tsconfig`, `eslint`, `prettier`, `package.json` | @dev-team-deming | Tooling |
|
|
23
|
+
| `readme`, `changelog`, `.md`, `/docs/` | @dev-team-docs | Documentation |
|
|
24
|
+
| `/adr/`, `architecture`, `/core/`, `/domain/` | @dev-team-architect | Architecture |
|
|
25
|
+
| `package.json`, `version`, `changelog`, release workflows | @dev-team-release | Release artifacts |
|
|
26
|
+
| Any `.js`, `.ts`, `.py`, `.go`, `.java`, `.rs` (non-test) | @dev-team-knuth | Quality/coverage |
|
|
27
|
+
|
|
28
|
+
3. Always include @dev-team-szabo and @dev-team-knuth — they review all code changes.
|
|
29
|
+
|
|
30
|
+
## Execution
|
|
31
|
+
|
|
32
|
+
1. Spawn each selected agent as a **parallel background subagent** using the Agent tool with `subagent_type: "general-purpose"`.
|
|
33
|
+
|
|
34
|
+
2. Each agent's prompt must include:
|
|
35
|
+
- The agent's full definition (read from `.claude/agents/<agent>.md`)
|
|
36
|
+
- The list of changed files relevant to their domain
|
|
37
|
+
- Instruction to produce classified findings: `[DEFECT]`, `[RISK]`, `[QUESTION]`, `[SUGGESTION]`
|
|
38
|
+
- Instruction to read the actual code — not just the diff — for full context
|
|
39
|
+
|
|
40
|
+
3. Wait for all agents to complete.
|
|
41
|
+
|
|
42
|
+
## Report
|
|
43
|
+
|
|
44
|
+
Produce a unified review summary:
|
|
45
|
+
|
|
46
|
+
### Blocking findings ([DEFECT])
|
|
47
|
+
|
|
48
|
+
List all `[DEFECT]` findings from all agents. These must be resolved before merge.
|
|
49
|
+
|
|
50
|
+
Format each as:
|
|
51
|
+
```
|
|
52
|
+
**[DEFECT]** @agent-name — file:line
|
|
53
|
+
Description of the defect and why it blocks.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Advisory findings
|
|
57
|
+
|
|
58
|
+
Group by severity:
|
|
59
|
+
- **[RISK]** — likely failure modes
|
|
60
|
+
- **[QUESTION]** — decisions needing justification
|
|
61
|
+
- **[SUGGESTION]** — specific improvements
|
|
62
|
+
|
|
63
|
+
### Verdict
|
|
64
|
+
|
|
65
|
+
- **Approve** — No `[DEFECT]` findings. Advisory items noted.
|
|
66
|
+
- **Request changes** — `[DEFECT]` findings must be resolved.
|
|
67
|
+
|
|
68
|
+
State the verdict clearly. List what must be fixed for approval if requesting changes.
|