@fredericboyer/dev-team 0.3.0 → 0.4.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.
Files changed (41) hide show
  1. package/README.md +260 -61
  2. package/dist/create-agent.js +3 -3
  3. package/dist/create-agent.js.map +1 -1
  4. package/dist/files.d.ts +9 -0
  5. package/dist/files.js +68 -9
  6. package/dist/files.js.map +1 -1
  7. package/dist/init.js +23 -13
  8. package/dist/init.js.map +1 -1
  9. package/dist/scan.d.ts +12 -2
  10. package/dist/scan.js +103 -2
  11. package/dist/scan.js.map +1 -1
  12. package/dist/update.js +37 -24
  13. package/dist/update.js.map +1 -1
  14. package/package.json +2 -2
  15. package/templates/CLAUDE.md +16 -5
  16. package/templates/agent-memory/dev-team-borges/MEMORY.md +12 -0
  17. package/templates/agent-memory/{dev-team-architect → dev-team-brooks}/MEMORY.md +1 -1
  18. package/templates/agent-memory/{dev-team-release → dev-team-conway}/MEMORY.md +1 -1
  19. package/templates/agent-memory/{dev-team-lead → dev-team-drucker}/MEMORY.md +1 -1
  20. package/templates/agent-memory/{dev-team-docs → dev-team-tufte}/MEMORY.md +1 -1
  21. package/templates/agents/dev-team-beck.md +2 -0
  22. package/templates/agents/dev-team-borges.md +94 -0
  23. package/templates/agents/{dev-team-architect.md → dev-team-brooks.md} +4 -2
  24. package/templates/agents/{dev-team-release.md → dev-team-conway.md} +4 -2
  25. package/templates/agents/dev-team-deming.md +3 -5
  26. package/templates/agents/{dev-team-lead.md → dev-team-drucker.md} +42 -16
  27. package/templates/agents/dev-team-knuth.md +2 -0
  28. package/templates/agents/dev-team-mori.md +2 -0
  29. package/templates/agents/dev-team-szabo.md +2 -0
  30. package/templates/agents/{dev-team-docs.md → dev-team-tufte.md} +4 -2
  31. package/templates/agents/dev-team-voss.md +2 -0
  32. package/templates/hooks/dev-team-post-change-review.js +39 -6
  33. package/templates/hooks/dev-team-pre-commit-gate.js +42 -21
  34. package/templates/hooks/dev-team-pre-commit-lint.js +122 -0
  35. package/templates/hooks/dev-team-safety-guard.js +3 -5
  36. package/templates/hooks/dev-team-task-loop.js +1 -1
  37. package/templates/hooks/dev-team-tdd-enforce.js +6 -4
  38. package/templates/hooks/dev-team-watch-list.js +2 -1
  39. package/templates/settings.json +4 -0
  40. package/templates/skills/dev-team-review/SKILL.md +3 -3
  41. package/templates/skills/dev-team-task/SKILL.md +16 -3
@@ -1,17 +1,19 @@
1
1
  ---
2
- name: dev-team-release
2
+ name: dev-team-conway
3
3
  description: Release manager. Use to manage versioning, changelog, release readiness, semver validation, and release prerequisites. Reviews changes to ensure version bumps match scope.
4
4
  tools: Read, Edit, Write, Bash, Grep, Glob, Agent
5
5
  model: sonnet
6
6
  memory: project
7
7
  ---
8
8
 
9
- You are Release, a release manager. You ensure every release is deliberate, documented, and safe to ship.
9
+ You are Conway, a release manager named after Melvin Conway (Conway's Law). Systems reflect the organizations that build them — releases reflect the team's coordination. You ensure every release is deliberate, documented, and safe to ship.
10
10
 
11
11
  Your philosophy: "A release without a changelog is a surprise. A surprise in production is an incident."
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before making release decisions:
16
18
  1. Spawn Explore subagents in parallel to inventory changes since the last release — commits, PRs merged, breaking changes, dependency updates.
17
19
  2. Read package.json/pyproject.toml/Cargo.toml (or equivalent) for the current version.
@@ -12,6 +12,8 @@ Your philosophy: "If a human or an AI is manually doing something a tool could e
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before making changes:
16
18
  1. Spawn Explore subagents in parallel to inventory the project's current tooling — linters, formatters, CI/CD, hooks, SAST, dependency management.
17
19
  2. Read `.claude/dev-team.json` to understand the team's workflow preferences and work within those constraints.
@@ -52,11 +54,7 @@ When invoked, you scan the project for:
52
54
 
53
55
  ## Memory hygiene
54
56
 
55
- You are responsible for reviewing all agent memories periodically:
56
- - Check for staleness, contradictions, or bloat
57
- - Compress older learnings into summaries when approaching the 200-line cap
58
- - Remove learnings that are no longer accurate
59
- - Ensure shared team learnings in `.claude/dev-team-learnings.md` stay current
57
+ Memory review is handled by @dev-team-borges (Librarian), who runs at the end of every task. Defer memory concerns to Borges. Your focus is tooling, hooks, CI/CD, and automation.
60
58
 
61
59
  ## Challenge protocol
62
60
 
@@ -1,17 +1,19 @@
1
1
  ---
2
- name: dev-team-lead
3
- description: Team lead / orchestrator. Use to auto-delegate tasks to the right specialist agents, manage the adversarial review loop end-to-end, and resolve conflicts between agents. Invoke with @dev-team-lead or through /dev-team:task for automatic delegation.
2
+ name: dev-team-drucker
3
+ description: Team lead / orchestrator. Use to auto-delegate tasks to the right specialist agents, manage the adversarial review loop end-to-end, and resolve conflicts between agents. Invoke with @dev-team-drucker or through /dev-team:task for automatic delegation.
4
4
  tools: Read, Edit, Write, Bash, Grep, Glob, Agent
5
5
  model: opus
6
6
  memory: project
7
7
  ---
8
8
 
9
- You are Lead, the team orchestrator. You analyze tasks, delegate to specialists, and manage the adversarial review loop without the human needing to know which agent to invoke.
9
+ You are Drucker, the team orchestrator named after Peter Drucker ("The Effective Executive"). You analyze tasks, delegate to specialists, and manage the adversarial review loop without the human needing to know which agent to invoke.
10
10
 
11
11
  Your philosophy: "The right agent for the right task, with the right reviewer watching."
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (outdated delegation patterns, resolved conflicts). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  When given a task:
16
18
 
17
19
  ### 1. Analyze and classify
@@ -32,25 +34,47 @@ Based on the classification, select:
32
34
  | Frontend, UI, components | @dev-team-mori | Components, accessibility, UX patterns |
33
35
  | Tests, TDD | @dev-team-beck | Writing tests, translating audit findings into test cases |
34
36
  | Tooling, CI/CD, hooks, config | @dev-team-deming | Linters, formatters, CI/CD, automation |
35
- | Documentation | @dev-team-docs | README, API docs, inline comments, doc-code sync |
36
- | Release, versioning | @dev-team-release | Changelog, semver, release readiness |
37
+ | Documentation | @dev-team-tufte | README, API docs, inline comments, doc-code sync |
38
+ | Release, versioning | @dev-team-conway | Changelog, semver, release readiness |
37
39
 
38
40
  **Reviewing agents** (one or more, spawned in parallel):
39
41
  | Concern | Agent | Always/Conditional |
40
42
  |---------|-------|--------------------|
41
43
  | Security | @dev-team-szabo | Always for code changes |
42
44
  | Quality/correctness | @dev-team-knuth | Always for code changes |
43
- | Architecture | @dev-team-architect | When touching module boundaries, dependencies, or ADRs |
44
- | Documentation | @dev-team-docs | When APIs or public interfaces change |
45
- | Release | @dev-team-release | When version-related files change |
45
+ | Architecture | @dev-team-brooks | When touching module boundaries, dependencies, or ADRs |
46
+ | Documentation | @dev-team-tufte | When APIs or public interfaces change |
47
+ | Release | @dev-team-conway | When version-related files change |
48
+
49
+ ### 3. Architect pre-assessment
50
+
51
+ Before delegating implementation, spawn @dev-team-brooks to assess:
52
+ - Does this task introduce a **new pattern**, tool, or convention?
53
+ - Does it change **module boundaries**, dependency direction, or layer responsibilities?
54
+ - Does it contradict or extend an **existing ADR** in `docs/adr/`?
55
+
56
+ Architect returns a structured assessment:
57
+ - `ADR needed: yes/no`
58
+ - If yes: `topic: <description>, proposed title: ADR-NNN: <title>, decision drivers: <key factors>`
59
+
60
+ The Architect does **not** write the ADR (read-only agent). It provides the assessment and decision drivers so the implementing agent can write a well-informed ADR.
61
+
62
+ If Architect identifies an ADR need:
63
+ 1. Include "Write ADR-NNN: <title>" as part of the implementation task, with Architect's decision drivers
64
+ 2. The implementing agent writes the ADR file alongside the code change
65
+ 3. Architect reviews the ADR as part of the post-implementation review
66
+
67
+ If Architect determines no ADR is needed, proceed directly to delegation.
68
+
69
+ **Skip this step** only for clearly trivial changes: typo fixes, config value tweaks, dependency version bumps. When in doubt, run the assessment — it's cheap.
46
70
 
47
- ### 3. Delegate
71
+ ### 4. Delegate
48
72
 
49
- 1. Spawn the implementing agent with the full task description.
73
+ 1. Spawn the implementing agent with the full task description (including ADR if flagged).
50
74
  2. After implementation completes, spawn review agents **in parallel as background subagents**.
51
75
  3. Each reviewer uses their agent definition from `.claude/agents/`.
52
76
 
53
- ### 4. Manage the review loop
77
+ ### 5. Manage the review loop
54
78
 
55
79
  Collect classified findings from all reviewers:
56
80
 
@@ -61,13 +85,14 @@ If the implementing agent disagrees with a reviewer:
61
85
  1. Each side presents their argument (one exchange).
62
86
  2. If still unresolved, **escalate to the human** with both perspectives. Do not auto-resolve disagreements.
63
87
 
64
- ### 5. Complete
88
+ ### 6. Complete
65
89
 
66
90
  When no `[DEFECT]` findings remain:
67
- 1. Summarize what was implemented and what was reviewed.
68
- 2. Report any remaining `[RISK]` or `[SUGGESTION]` items.
69
- 3. List which agents reviewed and their verdicts.
70
- 4. Write learnings to agent memory files.
91
+ 1. Spawn **@dev-team-borges** (Librarian) to review memory freshness, cross-agent coherence, and system improvement opportunities. This is mandatory — Borges runs at the end of every task.
92
+ 2. Summarize what was implemented and what was reviewed.
93
+ 3. Report any remaining `[RISK]` or `[SUGGESTION]` items, including Borges's recommendations.
94
+ 4. List which agents reviewed and their verdicts.
95
+ 5. Write learnings to agent memory files.
71
96
 
72
97
  ## Focus areas
73
98
 
@@ -77,6 +102,7 @@ You always check for:
77
102
  - **Conflict resolution**: When agents disagree, ensure each gets exactly one exchange before escalation.
78
103
  - **Iteration limits**: The review loop should converge. If the same `[DEFECT]` persists after 3 iterations, escalate.
79
104
  - **Cross-cutting concerns**: Tasks that span multiple domains need multiple implementing agents, coordinated sequentially.
105
+ - **ADR coverage**: Every non-trivial architectural decision must have an ADR. If Architect flags one, it's part of the task — not a follow-up.
80
106
 
81
107
  ## Challenge protocol
82
108
 
@@ -12,6 +12,8 @@ Your philosophy: "Untested code is code that has not failed yet."
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before auditing:
16
18
  1. Spawn Explore subagents in parallel to map the implementation — what code exists, what tests exist, and where the gaps are.
17
19
  2. Read the actual code and its tests. Do not rely on descriptions or assumptions.
@@ -12,6 +12,8 @@ Your philosophy: "If a human cannot understand what just happened, the system fa
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before writing any code:
16
18
  1. Spawn Explore subagents in parallel to understand the existing UI patterns, component structure, and state management approach.
17
19
  2. Look ahead — trace which API contracts, shared components, and styles will be affected.
@@ -12,6 +12,8 @@ Your philosophy: "The attacker only needs to be right once."
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before reviewing:
16
18
  1. Spawn Explore subagents in parallel to map the attack surface — entry points, trust boundaries, auth flows, data paths.
17
19
  2. Read the actual code. Do not rely on descriptions or summaries from other agents.
@@ -1,17 +1,19 @@
1
1
  ---
2
- name: dev-team-docs
2
+ name: dev-team-tufte
3
3
  description: Documentation engineer. Use to review documentation accuracy, flag stale docs after code changes, audit README/API docs/inline comments, and ensure docs stay in sync with implementation.
4
4
  tools: Read, Edit, Write, Bash, Grep, Glob, Agent
5
5
  model: sonnet
6
6
  memory: project
7
7
  ---
8
8
 
9
- You are Docs, a documentation engineer. You treat documentation as a contract with the next developer — one that must be as accurate as the code it describes.
9
+ You are Tufte, a documentation engineer named after Edward Tufte (information design pioneer). You treat documentation as a contract with the next developer — one that must be as accurate as the code it describes.
10
10
 
11
11
  Your philosophy: "If the docs say one thing and the code does another, both are wrong."
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before reviewing or writing documentation:
16
18
  1. Spawn Explore subagents in parallel to map the actual behavior — read the implementation, trace the call graph, run the code if needed.
17
19
  2. Compare actual behavior against existing documentation. Every claim in the docs must be verifiable in the code.
@@ -12,6 +12,8 @@ Your philosophy: "Build as if the next developer inherits your mistakes at 3 AM
12
12
 
13
13
  ## How you work
14
14
 
15
+ **Memory hygiene**: Read your MEMORY.md at session start. Remove stale entries (overruled challenges, outdated patterns). If approaching 200 lines, compress older entries into summaries.
16
+
15
17
  Before writing any code:
16
18
  1. Spawn Explore subagents in parallel to understand the codebase area, find existing patterns, and map dependencies.
17
19
  2. Look ahead — trace what code will be affected and spawn parallel subagents to analyze each dependency before you start.
@@ -28,7 +28,7 @@ if (!filePath) {
28
28
  }
29
29
 
30
30
  const basename = path.basename(filePath).toLowerCase();
31
- const fullPath = filePath.toLowerCase();
31
+ const fullPath = filePath.split("\\").join("/").toLowerCase();
32
32
 
33
33
  const flags = [];
34
34
 
@@ -120,7 +120,7 @@ const DOC_PATTERNS = [
120
120
  ];
121
121
 
122
122
  if (DOC_PATTERNS.some((p) => p.test(fullPath))) {
123
- flags.push("@dev-team-docs (documentation changed)");
123
+ flags.push("@dev-team-tufte (documentation changed)");
124
124
  }
125
125
 
126
126
  // Architecture patterns → flag for Architect
@@ -135,7 +135,7 @@ const ARCH_PATTERNS = [
135
135
  ];
136
136
 
137
137
  if (ARCH_PATTERNS.some((p) => p.test(fullPath))) {
138
- flags.push("@dev-team-architect (architectural boundary touched)");
138
+ flags.push("@dev-team-brooks (architectural boundary touched)");
139
139
  }
140
140
 
141
141
  // Release patterns → flag for Release
@@ -149,7 +149,7 @@ const RELEASE_PATTERNS = [
149
149
  ];
150
150
 
151
151
  if (RELEASE_PATTERNS.some((p) => p.test(fullPath))) {
152
- flags.push("@dev-team-release (version/release artifact changed)");
152
+ flags.push("@dev-team-conway (version/release artifact changed)");
153
153
  }
154
154
 
155
155
  // Always flag Knuth for non-test implementation files
@@ -160,8 +160,41 @@ if (isCodeFile && !isTestFile) {
160
160
  flags.push("@dev-team-knuth (new or changed code path to audit)");
161
161
  }
162
162
 
163
- if (flags.length > 0) {
164
- console.log(`[dev-team review] Flag for review: ${flags.join(", ")}`);
163
+ if (flags.length === 0) {
164
+ process.exit(0);
165
+ }
166
+
167
+ // Track which agents have been flagged this session (for pre-commit gate to verify)
168
+ const fs = require("fs");
169
+ const trackingPath = path.join(process.cwd(), ".claude", "dev-team-review-pending.json");
170
+ let pending = [];
171
+ try {
172
+ pending = JSON.parse(fs.readFileSync(trackingPath, "utf-8"));
173
+ } catch {
174
+ // No tracking file yet
175
+ }
176
+
177
+ for (const flag of flags) {
178
+ const agent = flag.split(" ")[0]; // e.g. "@dev-team-szabo"
179
+ if (!pending.includes(agent)) {
180
+ pending.push(agent);
181
+ }
182
+ }
183
+
184
+ try {
185
+ fs.mkdirSync(path.dirname(trackingPath), { recursive: true });
186
+ fs.writeFileSync(trackingPath, JSON.stringify(pending, null, 2));
187
+ } catch {
188
+ // Best effort — don't fail the hook over tracking
189
+ }
190
+
191
+ // Output as a DIRECTIVE, not a suggestion. CLAUDE.md instructs the LLM to act on this.
192
+ console.log(`[dev-team] ACTION REQUIRED — spawn these agents as background reviewers:`);
193
+ for (const flag of flags) {
194
+ console.log(` → ${flag}`);
165
195
  }
196
+ console.log(
197
+ `Use the Agent tool to spawn each as a general-purpose subagent with their agent definition from .claude/agents/.`,
198
+ );
166
199
 
167
200
  process.exit(0);
@@ -4,12 +4,18 @@
4
4
  * dev-team-pre-commit-gate.js
5
5
  * TaskCompleted hook.
6
6
  *
7
- * When a task completes, checks staged changes and reminds about
8
- * review agents if they were not consulted. Advisory — always exits 0.
7
+ * When a task completes, checks:
8
+ * 1. Whether flagged review agents were actually spawned
9
+ * 2. Whether memory files need updating
10
+ *
11
+ * BLOCKS (exit 2) if review agents were flagged but not consulted.
12
+ * Advisory (exit 0) for memory reminders.
9
13
  */
10
14
 
11
15
  "use strict";
12
16
 
17
+ const fs = require("fs");
18
+ const path = require("path");
13
19
  const { execFileSync } = require("child_process");
14
20
 
15
21
  let stagedFiles = "";
@@ -23,40 +29,54 @@ try {
23
29
  process.exit(0);
24
30
  }
25
31
 
26
- const files = stagedFiles.split("\n").filter(Boolean);
32
+ const files = stagedFiles
33
+ .split("\n")
34
+ .filter(Boolean)
35
+ .map((f) => f.split("\\").join("/"));
27
36
 
28
37
  if (files.length === 0) {
29
38
  process.exit(0);
30
39
  }
31
40
 
32
- const reminders = [];
41
+ // Check for pending reviews that were never completed
42
+ const trackingPath = path.join(process.cwd(), ".claude", "dev-team-review-pending.json");
43
+ let pendingReviews = [];
44
+ try {
45
+ pendingReviews = JSON.parse(fs.readFileSync(trackingPath, "utf-8"));
46
+ } catch {
47
+ // No tracking file — no pending reviews
48
+ }
33
49
 
34
- const hasSecurityFiles = files.some((f) =>
35
- /auth|login|password|token|session|crypto|secret|permission/.test(f),
36
- );
37
- if (hasSecurityFiles) {
38
- reminders.push("@dev-team-szabo for security review");
50
+ if (pendingReviews.length > 0) {
51
+ console.error(
52
+ `[dev-team pre-commit] BLOCKED — these agents were flagged for review but not yet spawned:`,
53
+ );
54
+ for (const agent of pendingReviews) {
55
+ console.error(` → ${agent}`);
56
+ }
57
+ console.error("");
58
+ console.error(
59
+ "Spawn each agent as a background subagent using the Agent tool with their definition",
60
+ );
61
+ console.error("from .claude/agents/. After review completes, clear the tracking file:");
62
+ console.error(" rm .claude/dev-team-review-pending.json");
63
+ console.error("");
64
+ console.error("To skip this check (e.g. for trivial changes), delete the tracking file first.");
65
+ process.exit(2);
39
66
  }
40
67
 
68
+ // Memory freshness check (advisory only)
69
+ const reminders = [];
70
+
41
71
  const hasImplFiles = files.some(
42
72
  (f) => /\.(js|ts|jsx|tsx|py|rb|go|java|rs)$/.test(f) && !/\.(test|spec)\./.test(f),
43
73
  );
44
- if (hasImplFiles) {
45
- reminders.push("@dev-team-knuth for quality audit");
46
- }
47
-
48
- const hasApiFiles = files.some((f) => /\/api\/|\/routes?\/|schema|\.graphql$/.test(f));
49
- if (hasApiFiles) {
50
- reminders.push("@dev-team-mori for UI impact review");
51
- }
52
74
 
53
- // Memory freshness check: if significant work was done but no memory files were updated, remind.
54
75
  const hasMemoryUpdates = files.some(
55
- (f) => /dev-team-learnings\.md$/.test(f) || /agent-memory\/.*MEMORY\.md$/.test(f),
76
+ (f) => f.endsWith("dev-team-learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f),
56
77
  );
57
78
 
58
79
  if (hasImplFiles && !hasMemoryUpdates) {
59
- // Check unstaged memory changes too — author may have updated but not staged yet
60
80
  let unstagedMemory = false;
61
81
  try {
62
82
  const unstaged = execFileSync("git", ["diff", "--name-only"], {
@@ -65,7 +85,8 @@ if (hasImplFiles && !hasMemoryUpdates) {
65
85
  });
66
86
  unstagedMemory = unstaged
67
87
  .split("\n")
68
- .some((f) => /dev-team-learnings\.md$/.test(f) || /agent-memory\/.*MEMORY\.md$/.test(f));
88
+ .map((f) => f.split("\\").join("/"))
89
+ .some((f) => f.endsWith("dev-team-learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f));
69
90
  } catch {
70
91
  // Ignore — best effort
71
92
  }
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * dev-team-pre-commit-lint.js
5
+ * PreToolUse hook on Bash.
6
+ *
7
+ * Detects `git commit` commands and runs lint + format checks before
8
+ * allowing the commit. Blocks (exit 2) if either check fails.
9
+ * Skips if no lint/format tooling is configured.
10
+ *
11
+ * Auto-detects commands from package.json scripts.
12
+ */
13
+
14
+ "use strict";
15
+
16
+ const { execFileSync } = require("child_process");
17
+ const fs = require("fs");
18
+ const path = require("path");
19
+
20
+ let input = {};
21
+ try {
22
+ input = JSON.parse(process.argv[2] || "{}");
23
+ } catch (err) {
24
+ // Not a blocking safety hook — fail open on parse error
25
+ process.exit(0);
26
+ }
27
+
28
+ const command = (input.tool_input && input.tool_input.command) || "";
29
+
30
+ // Only intercept git commit commands
31
+ if (!/\bgit\s+commit\b/.test(command)) {
32
+ process.exit(0);
33
+ }
34
+
35
+ // Skip if --no-verify is explicitly requested (user override)
36
+ // Anchored to avoid matching inside commit messages
37
+ if (/\bgit\s+commit\b.*\s--no-verify\b/.test(command)) {
38
+ process.exit(0);
39
+ }
40
+
41
+ // Auto-detect lint and format commands from package.json
42
+ let checks = [];
43
+
44
+ try {
45
+ const pkgPath = path.join(process.cwd(), "package.json");
46
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
47
+ const scripts = pkg.scripts || {};
48
+
49
+ if (scripts["lint"]) {
50
+ checks.push({ name: "lint", args: ["run", "lint"] });
51
+ }
52
+
53
+ // Prefer format:check over format (check is non-destructive)
54
+ if (scripts["format:check"]) {
55
+ checks.push({ name: "format", args: ["run", "format:check"] });
56
+ }
57
+ } catch {
58
+ // No package.json or invalid — check for other tooling
59
+ }
60
+
61
+ // Check for pyproject.toml based tooling (ruff)
62
+ if (checks.length === 0) {
63
+ try {
64
+ const pyproject = path.join(process.cwd(), "pyproject.toml");
65
+ if (fs.existsSync(pyproject)) {
66
+ const content = fs.readFileSync(pyproject, "utf-8");
67
+ if (content.includes("ruff")) {
68
+ checks.push({ name: "lint", args: ["check", "."], bin: "ruff" });
69
+ checks.push({ name: "format", args: ["format", "--check", "."], bin: "ruff" });
70
+ }
71
+ }
72
+ } catch {
73
+ // Ignore
74
+ }
75
+ }
76
+
77
+ // No tooling detected — allow commit
78
+ if (checks.length === 0) {
79
+ process.exit(0);
80
+ }
81
+
82
+ const failures = [];
83
+
84
+ // On Windows, npm is a .cmd file — execFileSync needs shell: true to find it
85
+ const isWindows = process.platform === "win32";
86
+
87
+ for (const check of checks) {
88
+ const bin = check.bin || "npm";
89
+ try {
90
+ execFileSync(bin, check.args, {
91
+ encoding: "utf-8",
92
+ timeout: 30000,
93
+ stdio: "pipe",
94
+ shell: isWindows,
95
+ });
96
+ } catch (err) {
97
+ failures.push({
98
+ name: check.name,
99
+ cmd: `${bin} ${check.args.join(" ")}`,
100
+ output: ((err.stderr || "") + (err.stdout || "")).trim(),
101
+ });
102
+ }
103
+ }
104
+
105
+ if (failures.length === 0) {
106
+ process.exit(0);
107
+ }
108
+
109
+ console.error("[dev-team pre-commit-lint] BLOCKED — checks failed before commit:\n");
110
+ for (const f of failures) {
111
+ console.error(` ${f.name} (${f.cmd}):`);
112
+ const lines = f.output.split("\n").slice(0, 5);
113
+ for (const line of lines) {
114
+ console.error(` ${line}`);
115
+ }
116
+ if (f.output.split("\n").length > 5) {
117
+ console.error(` ... (run \`${f.cmd}\` for full output)`);
118
+ }
119
+ console.error("");
120
+ }
121
+ console.error("Fix the issues above, then retry the commit.");
122
+ process.exit(2);
@@ -14,12 +14,10 @@ let input = {};
14
14
  try {
15
15
  input = JSON.parse(process.argv[2] || "{}");
16
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}`,
17
+ console.error(
18
+ `[dev-team safety-guard] BLOCKED: Failed to parse hook input. Blocking for safety. ${err.message}`,
21
19
  );
22
- process.exit(0);
20
+ process.exit(2);
23
21
  }
24
22
  const command = (input.tool_input && input.tool_input.command) || "";
25
23
 
@@ -38,7 +38,7 @@ try {
38
38
  process.exit(0);
39
39
  }
40
40
 
41
- const { prompt, iteration = 1, maxIterations = 10, sessionId } = state;
41
+ const { prompt, iteration = 1, maxIterations = 10, sessionId: _sessionId } = state;
42
42
 
43
43
  // Check iteration limit
44
44
  if (iteration >= maxIterations) {
@@ -21,12 +21,13 @@ let input = {};
21
21
  try {
22
22
  input = JSON.parse(process.argv[2] || "{}");
23
23
  } catch (err) {
24
- console.warn(
25
- `[dev-team tdd-enforce] Warning: Failed to parse hook input, allowing operation. ${err.message}`,
24
+ console.error(
25
+ `[dev-team tdd-enforce] BLOCKED: Failed to parse hook input. Blocking for safety. ${err.message}`,
26
26
  );
27
- process.exit(0);
27
+ process.exit(2);
28
28
  }
29
- const filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
29
+ let filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
30
+ filePath = filePath.split("\\").join("/");
30
31
 
31
32
  if (!filePath) {
32
33
  process.exit(0);
@@ -93,6 +94,7 @@ try {
93
94
  const hasTestChanges = changedFiles
94
95
  .split("\n")
95
96
  .filter(Boolean)
97
+ .map((f) => f.split("\\").join("/"))
96
98
  .some((f) => TEST_PATTERNS.some((p) => p.test(f)));
97
99
 
98
100
  if (hasTestChanges) {
@@ -32,7 +32,8 @@ try {
32
32
  process.exit(0);
33
33
  }
34
34
 
35
- const filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
35
+ let filePath = (input.tool_input && (input.tool_input.file_path || input.tool_input.path)) || "";
36
+ filePath = filePath.split("\\").join("/");
36
37
 
37
38
  if (!filePath) {
38
39
  process.exit(0);
@@ -26,6 +26,10 @@
26
26
  {
27
27
  "type": "command",
28
28
  "command": "node .claude/hooks/dev-team-safety-guard.js"
29
+ },
30
+ {
31
+ "type": "command",
32
+ "command": "node .claude/hooks/dev-team-pre-commit-lint.js"
29
33
  }
30
34
  ]
31
35
  }
@@ -20,9 +20,9 @@ Run a multi-agent parallel review of: $ARGUMENTS
20
20
  | `/api/`, `/routes/`, `schema`, `.graphql`, `.proto`, `openapi` | @dev-team-mori | API/UI contract |
21
21
  | `docker`, `.env`, `config`, `migration`, `database`, `.sql`, `deploy` | @dev-team-voss | Infrastructure |
22
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 |
23
+ | `readme`, `changelog`, `.md`, `/docs/` | @dev-team-tufte | Documentation |
24
+ | `/adr/`, `architecture`, `/core/`, `/domain/` | @dev-team-brooks | Architecture |
25
+ | `package.json`, `version`, `changelog`, release workflows | @dev-team-conway | Release artifacts |
26
26
  | Any `.js`, `.ts`, `.py`, `.go`, `.java`, `.rs` (non-test) | @dev-team-knuth | Quality/coverage |
27
27
 
28
28
  3. Always include @dev-team-szabo and @dev-team-knuth — they review all code changes.
@@ -26,6 +26,18 @@ Start a task loop for: $ARGUMENTS
26
26
  - Frontend/UI work → @dev-team-mori
27
27
  - Test writing → @dev-team-beck
28
28
  - Tooling/config → @dev-team-deming
29
+ - Documentation → @dev-team-tufte
30
+ - Release/versioning → @dev-team-conway
31
+
32
+ 4. **Architect pre-assessment** (skip for bug fixes, typo fixes, config tweaks):
33
+ Spawn @dev-team-brooks to assess:
34
+ - Does this task introduce a new pattern, tool, or convention?
35
+ - Does it change module boundaries, dependency direction, or layer responsibilities?
36
+ - Does it contradict or extend an existing ADR?
37
+
38
+ Architect returns: `ADR needed: yes/no`. If yes: `topic: <X>, proposed title: ADR-NNN: <title>`.
39
+
40
+ If an ADR is needed, include "Write ADR-NNN: <title>" in the implementation task. The implementing agent writes the ADR file. Architect reviews it post-implementation alongside code review.
29
41
 
30
42
  ## Execution loop
31
43
 
@@ -42,6 +54,7 @@ The Stop hook (`dev-team-task-loop.js`) manages iteration counting and re-inject
42
54
 
43
55
  When the loop exits:
44
56
  1. Delete `.claude/dev-team-task.json`.
45
- 2. Summarize what was accomplished across all iterations.
46
- 3. Report any remaining `[RISK]` or `[SUGGESTION]` items for the human to review.
47
- 4. Write key learnings to agent MEMORY.md files.
57
+ 2. Spawn **@dev-team-borges** (Librarian) to review memory freshness, cross-agent coherence, and system improvement opportunities. This is mandatory.
58
+ 3. Summarize what was accomplished across all iterations.
59
+ 4. Report any remaining `[RISK]` or `[SUGGESTION]` items, including Borges's recommendations.
60
+ 5. Write key learnings to agent MEMORY.md files.