hool-cli 0.6.2 → 0.7.1

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 (54) hide show
  1. package/agents/claude/be-dev.md +9 -1
  2. package/agents/claude/be-tech-lead.md +8 -0
  3. package/agents/claude/fe-dev.md +9 -1
  4. package/agents/claude/fe-tech-lead.md +8 -0
  5. package/agents/claude/forensic.md +8 -0
  6. package/agents/claude/governor.md +8 -0
  7. package/agents/claude/qa.md +8 -0
  8. package/dist/adapters/adapters.test.d.ts +1 -0
  9. package/dist/adapters/adapters.test.js +189 -0
  10. package/dist/adapters/adapters.test.js.map +1 -0
  11. package/dist/adapters/claude-code.js +22 -13
  12. package/dist/adapters/claude-code.js.map +1 -1
  13. package/dist/core/scaffold.d.ts +3 -0
  14. package/dist/core/scaffold.js +88 -10
  15. package/dist/core/scaffold.js.map +1 -1
  16. package/dist/core/scaffold.test.d.ts +1 -0
  17. package/dist/core/scaffold.test.js +329 -0
  18. package/dist/core/scaffold.test.js.map +1 -0
  19. package/dist/core/templates.js +2 -2
  20. package/dist/core/templates.js.map +1 -1
  21. package/dist/core/templates.test.d.ts +1 -0
  22. package/dist/core/templates.test.js +146 -0
  23. package/dist/core/templates.test.js.map +1 -0
  24. package/dist/e2e.test.d.ts +1 -0
  25. package/dist/e2e.test.js +161 -0
  26. package/dist/e2e.test.js.map +1 -0
  27. package/dist/index.js +5 -23
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcps/mcps.test.d.ts +1 -0
  30. package/dist/mcps/mcps.test.js +110 -0
  31. package/dist/mcps/mcps.test.js.map +1 -0
  32. package/hooks/inject-pl-context.sh +22 -3
  33. package/hooks/suggest-compact.sh +8 -12
  34. package/hooks/track-prompt-count.sh +24 -22
  35. package/package.json +13 -3
  36. package/prompts/agents/05-fe-tech-lead.md +5 -2
  37. package/prompts/agents/06-be-tech-lead.md +5 -2
  38. package/prompts/agents/08-be-dev.md +4 -1
  39. package/prompts/agents/08-fe-dev.md +4 -1
  40. package/prompts/agents/10-qa.md +1 -0
  41. package/prompts/agents/11-forensic.md +1 -0
  42. package/prompts/agents/governor.md +3 -2
  43. package/prompts/orchestrator.md +130 -38
  44. package/prompts/skills/01-brainstorm.md +5 -0
  45. package/prompts/skills/02-spec.md +5 -0
  46. package/prompts/skills/03-design.md +5 -0
  47. package/prompts/skills/04-architecture.md +5 -0
  48. package/settings/be-dev.json +17 -0
  49. package/settings/be-tech-lead.json +17 -0
  50. package/settings/fe-dev.json +17 -0
  51. package/settings/fe-tech-lead.json +17 -0
  52. package/settings/forensic.json +17 -0
  53. package/settings/governor.json +17 -0
  54. package/settings/qa.json +17 -0
@@ -0,0 +1,110 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { MCP_REGISTRY, getRequiredMcps, getRequiredMcpNames } from './registry.js';
3
+ import { checkAndInstallMcps } from './installer.js';
4
+ describe('MCP_REGISTRY', () => {
5
+ it('contains context7, playwright, deepwiki', () => {
6
+ expect(MCP_REGISTRY).toHaveProperty('context7');
7
+ expect(MCP_REGISTRY).toHaveProperty('playwright');
8
+ expect(MCP_REGISTRY).toHaveProperty('deepwiki');
9
+ });
10
+ it('each entry has name, installCommand, configEntry', () => {
11
+ for (const [key, mcp] of Object.entries(MCP_REGISTRY)) {
12
+ expect(mcp.name).toBe(key);
13
+ expect(mcp.installCommand).toBeTruthy();
14
+ expect(mcp.configEntry).toHaveProperty('command');
15
+ expect(mcp.configEntry).toHaveProperty('args');
16
+ }
17
+ });
18
+ });
19
+ describe('getRequiredMcps', () => {
20
+ it('returns context7 + deepwiki + playwright for web-app', () => {
21
+ const mcps = getRequiredMcps('web-app');
22
+ const names = mcps.map(m => m.name);
23
+ expect(names).toContain('context7');
24
+ expect(names).toContain('deepwiki');
25
+ expect(names).toContain('playwright');
26
+ });
27
+ it('returns context7 + deepwiki for cli-tool (no playwright)', () => {
28
+ const mcps = getRequiredMcps('cli-tool');
29
+ const names = mcps.map(m => m.name);
30
+ expect(names).toContain('context7');
31
+ expect(names).toContain('deepwiki');
32
+ expect(names).not.toContain('playwright');
33
+ });
34
+ it('returns context7 + deepwiki + playwright for browser-game', () => {
35
+ const mcps = getRequiredMcps('browser-game');
36
+ const names = mcps.map(m => m.name);
37
+ expect(names).toContain('playwright');
38
+ });
39
+ it('returns context7 + deepwiki for api-only', () => {
40
+ const mcps = getRequiredMcps('api-only');
41
+ const names = mcps.map(m => m.name);
42
+ expect(names).toEqual(['context7', 'deepwiki']);
43
+ });
44
+ it('returns McpDefinition objects with full config', () => {
45
+ const mcps = getRequiredMcps('web-app');
46
+ for (const mcp of mcps) {
47
+ expect(mcp).toHaveProperty('name');
48
+ expect(mcp).toHaveProperty('installCommand');
49
+ expect(mcp).toHaveProperty('configEntry');
50
+ }
51
+ });
52
+ });
53
+ describe('getRequiredMcpNames', () => {
54
+ it('returns string array of MCP names', () => {
55
+ const names = getRequiredMcpNames('web-app');
56
+ expect(names).toEqual(['context7', 'deepwiki', 'playwright']);
57
+ });
58
+ it('returns context7 + deepwiki for desktop', () => {
59
+ expect(getRequiredMcpNames('desktop')).toEqual(['context7', 'deepwiki']);
60
+ });
61
+ });
62
+ describe('checkAndInstallMcps', () => {
63
+ function createMockAdapter(installed = new Set()) {
64
+ return {
65
+ platform: 'claude-code',
66
+ injectInstructions: vi.fn(),
67
+ installMcp: vi.fn(),
68
+ isMcpInstalled: vi.fn(async (name) => installed.has(name)),
69
+ getCompletionMessage: vi.fn(() => ''),
70
+ };
71
+ }
72
+ const config = {
73
+ platform: 'claude-code',
74
+ projectType: 'cli-tool',
75
+ projectDir: '/tmp/test',
76
+ promptsDir: '/tmp/test/prompts',
77
+ mode: 'interactive',
78
+ };
79
+ it('returns already-installed for pre-installed MCPs', async () => {
80
+ const adapter = createMockAdapter(new Set(['context7', 'deepwiki']));
81
+ const results = await checkAndInstallMcps(adapter, config);
82
+ expect(results).toHaveLength(2);
83
+ expect(results.every(r => r.status === 'already-installed')).toBe(true);
84
+ expect(adapter.installMcp).not.toHaveBeenCalled();
85
+ });
86
+ it('installs missing MCPs', async () => {
87
+ const adapter = createMockAdapter(new Set(['context7'])); // deepwiki missing
88
+ const results = await checkAndInstallMcps(adapter, config);
89
+ const deepwikiResult = results.find(r => r.name === 'deepwiki');
90
+ expect(deepwikiResult?.status).toBe('installed');
91
+ expect(adapter.installMcp).toHaveBeenCalledOnce();
92
+ });
93
+ it('handles install failure gracefully', async () => {
94
+ const adapter = createMockAdapter();
95
+ adapter.installMcp.mockRejectedValue(new Error('Network error'));
96
+ const results = await checkAndInstallMcps(adapter, config);
97
+ expect(results.every(r => r.status === 'failed')).toBe(true);
98
+ expect(results[0].error).toBe('Network error');
99
+ });
100
+ it('processes all required MCPs for project type', async () => {
101
+ const webConfig = { ...config, projectType: 'web-app' };
102
+ const adapter = createMockAdapter();
103
+ const results = await checkAndInstallMcps(adapter, webConfig);
104
+ const names = results.map(r => r.name);
105
+ expect(names).toContain('context7');
106
+ expect(names).toContain('deepwiki');
107
+ expect(names).toContain('playwright');
108
+ });
109
+ });
110
+ //# sourceMappingURL=mcps.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcps.test.js","sourceRoot":"","sources":["../../src/mcps/mcps.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAc,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAClD,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,IAAI,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,SAAS,iBAAiB,CAAC,YAAyB,IAAI,GAAG,EAAE;QAC3D,OAAO;YACL,QAAQ,EAAE,aAAa;YACvB,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE;YAC3B,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClE,oBAAoB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,QAAQ,EAAE,aAAa;QACvB,WAAW,EAAE,UAAU;QACvB,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,mBAAmB;QAC/B,IAAI,EAAE,aAAa;KACpB,CAAC;IAEF,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB;QAC7E,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAChE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,oBAAoB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;QACnC,OAAO,CAAC,UAAuC,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,SAAkB,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -4,6 +4,24 @@
4
4
  # Outputs JSON with additionalContext to remind the PL of its identity and state
5
5
 
6
6
  PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
7
+ METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
8
+
9
+ # Ensure metrics file exists with default counters
10
+ if [ ! -f "$METRICS_FILE" ]; then
11
+ mkdir -p "$(dirname "$METRICS_FILE")"
12
+ cat > "$METRICS_FILE" <<'EOF'
13
+ # HOOL Metrics
14
+ - Agent dispatches: 0
15
+ - Tool calls: 0
16
+ - User prompts: 0
17
+ EOF
18
+ fi
19
+
20
+ # Increment user prompts counter
21
+ CURRENT_PROMPTS=$(grep -o 'User prompts: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
22
+ CURRENT_PROMPTS=${CURRENT_PROMPTS:-0}
23
+ NEXT_PROMPTS=$((CURRENT_PROMPTS + 1))
24
+ sed -i '' "s/User prompts: ${CURRENT_PROMPTS}/User prompts: ${NEXT_PROMPTS}/" "$METRICS_FILE"
7
25
 
8
26
  # Read current phase
9
27
  PHASE="unknown"
@@ -80,10 +98,11 @@ if [ -f "$PROJECT_ROOT/.hool/operations/inconsistencies.md" ]; then
80
98
  INCONSISTENCIES=$(grep -c '^- ' "$PROJECT_ROOT/.hool/operations/inconsistencies.md" 2>/dev/null | tr -d '\n' || echo "0")
81
99
  fi
82
100
 
83
- # Check governor dispatch count
101
+ # Check governor dispatch count from metrics.md
84
102
  DISPATCH_COUNT=0
85
- if [ -f "$PROJECT_ROOT/.hool/metrics/dispatch-count.txt" ]; then
86
- DISPATCH_COUNT=$(cat "$PROJECT_ROOT/.hool/metrics/dispatch-count.txt" 2>/dev/null | tr -d '\n' || echo "0")
103
+ if [ -f "$METRICS_FILE" ]; then
104
+ DISPATCH_COUNT=$(grep -o 'Agent dispatches: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*' || echo "0")
105
+ DISPATCH_COUNT=${DISPATCH_COUNT:-0}
87
106
  fi
88
107
  GOVERNOR_DUE=""
89
108
  if [ "$DISPATCH_COUNT" -gt 0 ] && [ $(( DISPATCH_COUNT % 3 )) -ge 2 ]; then
@@ -5,27 +5,23 @@
5
5
  # Strategic compaction between phases preserves better context.
6
6
 
7
7
  PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
8
- METRICS_DIR="$PROJECT_ROOT/.hool/metrics"
9
- mkdir -p "$METRICS_DIR"
10
-
11
- COUNTER_FILE="$METRICS_DIR/tool-call-count.txt"
8
+ METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
12
9
  THRESHOLD="${HOOL_COMPACT_THRESHOLD:-50}"
13
10
 
14
- # Read and increment counter
15
- CURRENT=$(cat "$COUNTER_FILE" 2>/dev/null || echo "0")
16
- NEXT=$((CURRENT + 1))
17
- echo "$NEXT" > "$COUNTER_FILE"
11
+ # Read tool call count from metrics.md (format: "- Tool calls: N")
12
+ COUNT=$(grep -o 'Tool calls: [0-9]*' "$METRICS_FILE" 2>/dev/null | grep -o '[0-9]*')
13
+ COUNT="${COUNT:-0}"
18
14
 
19
15
  # Suggest at threshold
20
- if [ "$NEXT" -eq "$THRESHOLD" ]; then
16
+ if [ "$COUNT" -eq "$THRESHOLD" ]; then
21
17
  echo "HOOL: ${THRESHOLD} tool calls reached. Consider running /compact if you're between phases or tasks." >&2
22
18
  fi
23
19
 
24
20
  # Suggest every 25 calls after threshold
25
- if [ "$NEXT" -gt "$THRESHOLD" ]; then
26
- OVER=$((NEXT - THRESHOLD))
21
+ if [ "$COUNT" -gt "$THRESHOLD" ]; then
22
+ OVER=$((COUNT - THRESHOLD))
27
23
  if [ $((OVER % 25)) -eq 0 ]; then
28
- echo "HOOL: ${NEXT} tool calls. Good checkpoint for /compact if context feels stale." >&2
24
+ echo "HOOL: ${COUNT} tool calls. Good checkpoint for /compact if context feels stale." >&2
29
25
  fi
30
26
  fi
31
27
 
@@ -1,39 +1,41 @@
1
1
  #!/bin/bash
2
- # Hook: Track prompt/tool count and trigger governor every 3 dispatches
2
+ # Hook: Track tool calls + agent dispatches in metrics.md, trigger governor every 3 dispatches
3
3
  # Type: PostToolUse
4
4
  # Outputs JSON with additionalContext when governor should run
5
5
 
6
6
  PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
7
- METRICS_DIR="$PROJECT_ROOT/.hool/metrics"
8
- mkdir -p "$METRICS_DIR"
9
-
10
- COUNTER_FILE="$METRICS_DIR/prompt-count.log"
11
- SESSION_FILE="$METRICS_DIR/current-session.txt"
12
- DISPATCH_FILE="$METRICS_DIR/dispatch-count.txt"
13
-
14
- # Get or create session ID
15
- if [ ! -f "$SESSION_FILE" ]; then
16
- echo "session-$(date +%Y%m%d-%H%M%S)" > "$SESSION_FILE"
7
+ METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
8
+
9
+ # Ensure metrics file exists with default counters
10
+ if [ ! -f "$METRICS_FILE" ]; then
11
+ mkdir -p "$(dirname "$METRICS_FILE")"
12
+ cat > "$METRICS_FILE" <<'EOF'
13
+ # HOOL Metrics
14
+ - Agent dispatches: 0
15
+ - Tool calls: 0
16
+ - User prompts: 0
17
+ EOF
17
18
  fi
18
19
 
19
- TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
20
-
21
- # Append to log
22
- echo "$TIMESTAMP | tool-call" >> "$COUNTER_FILE"
20
+ # Increment tool calls counter
21
+ CURRENT_TOOLS=$(grep -o 'Tool calls: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
22
+ CURRENT_TOOLS=${CURRENT_TOOLS:-0}
23
+ NEXT_TOOLS=$((CURRENT_TOOLS + 1))
24
+ sed -i '' "s/Tool calls: ${CURRENT_TOOLS}/Tool calls: ${NEXT_TOOLS}/" "$METRICS_FILE"
23
25
 
24
- # Track dispatch count (Agent tool calls specifically)
25
- # Read from stdin to check tool name
26
+ # Read stdin to check tool name
26
27
  INPUT=$(cat)
27
28
  TOOL_NAME=$(echo "$INPUT" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_name"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
28
29
 
29
30
  if [ "$TOOL_NAME" = "Agent" ]; then
30
- # Increment dispatch counter
31
- CURRENT=$(cat "$DISPATCH_FILE" 2>/dev/null || echo "0")
32
- NEXT=$((CURRENT + 1))
33
- echo "$NEXT" > "$DISPATCH_FILE"
31
+ # Increment agent dispatches counter
32
+ CURRENT_DISPATCHES=$(grep -o 'Agent dispatches: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
33
+ CURRENT_DISPATCHES=${CURRENT_DISPATCHES:-0}
34
+ NEXT_DISPATCHES=$((CURRENT_DISPATCHES + 1))
35
+ sed -i '' "s/Agent dispatches: ${CURRENT_DISPATCHES}/Agent dispatches: ${NEXT_DISPATCHES}/" "$METRICS_FILE"
34
36
 
35
37
  # Check if divisible by 3
36
- if [ $((NEXT % 3)) -eq 0 ]; then
38
+ if [ $((NEXT_DISPATCHES % 3)) -eq 0 ]; then
37
39
  # Output JSON to inject governor reminder into conversation
38
40
  cat <<'JSONEOF'
39
41
  {
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "hool-cli",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "Agent-Driven SDLC — scaffold and configure HOOL for any project",
5
5
  "bin": {
6
6
  "hool": "./dist/index.js"
7
7
  },
8
8
  "scripts": {
9
9
  "build": "tsc",
10
+ "test": "vitest run",
11
+ "test:watch": "vitest",
10
12
  "dev": "tsx src/index.ts",
11
13
  "prepublishOnly": "npm run build && rm -rf ./prompts ./agents ./rules ./hooks ./settings && cp -R ../hool-mini/prompts ./prompts && cp -R ../hool-mini/agents ./agents && cp -R ../hool-mini/rules ./rules && cp -R ../hool-mini/hooks ./hooks && cp -R ../hool-mini/settings ./settings"
12
14
  },
@@ -27,7 +29,8 @@
27
29
  "devDependencies": {
28
30
  "@types/node": "^20.11.0",
29
31
  "tsx": "^4.7.0",
30
- "typescript": "^5.4.0"
32
+ "typescript": "^5.4.0",
33
+ "vitest": "^4.0.18"
31
34
  },
32
35
  "type": "module",
33
36
  "license": "MIT",
@@ -35,7 +38,14 @@
35
38
  "type": "git",
36
39
  "url": "git+https://github.com/the-wise-agents/hool.git"
37
40
  },
38
- "keywords": ["agent", "sdlc", "ai", "cli", "scaffold", "autonomous"],
41
+ "keywords": [
42
+ "agent",
43
+ "sdlc",
44
+ "ai",
45
+ "cli",
46
+ "scaffold",
47
+ "autonomous"
48
+ ],
39
49
  "engines": {
40
50
  "node": ">=18"
41
51
  }
@@ -136,13 +136,13 @@ How logging works. Where logs go. How to read them.
136
136
  - .hool/phases/05-fe-scaffold/fe-lld.md — LLD compliance check
137
137
  - .hool/phases/07-test-plan/test-plan.md — test coverage check
138
138
  - .hool/memory/fe-dev/hot.md — what FE Dev has been doing
139
- - .hool/prompts/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
139
+ - .hool/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
140
140
  - .hool/memory/fe-tech-lead/best-practices.md — project-specific patterns (organic checklist items)
141
141
  ### Writes
142
142
  - .hool/operations/inconsistencies.md — INC-XXX entries for any issues found
143
143
  ### Process
144
144
  1. Read the code FE Dev produced for the task
145
- 2. Load and run the baseline checklist from `.hool/prompts/checklists/code-review.md` (skip BE-only items)
145
+ 2. Load and run the baseline checklist from `.hool/checklists/code-review.md` (skip BE-only items)
146
146
  3. Also check project-specific patterns from your `best-practices.md`
147
147
  4. Run the 6-point review checklist:
148
148
  - **Contract compliance** — API calls match .hool/phases/04-architecture/contracts/ (endpoints, methods, request/response shapes, status codes handled)
@@ -156,6 +156,9 @@ How logging works. Where logs go. How to read them.
156
156
  - Code inconsistency found -> write to .hool/operations/inconsistencies.md with INC-XXX format
157
157
  - Doc inconsistency found (spec says X, contract says Y) -> escalate to Product Lead via .hool/operations/inconsistencies.md
158
158
 
159
+ ## Forbidden Actions
160
+ - NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
161
+
159
162
  ## Work Log
160
163
  ### Tags
161
164
  - [ARCH-FE] — FE architectural decision -> best-practices.md
@@ -157,13 +157,13 @@ Order matters. List in execution order:
157
157
  - .hool/phases/02-spec/spec.md (and features/ if split) — acceptance criteria check
158
158
  - .hool/phases/07-test-plan/test-plan.md — test coverage check
159
159
  - .hool/memory/be-dev/hot.md — what BE Dev has been doing
160
- - .hool/prompts/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
160
+ - .hool/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
161
161
  - .hool/memory/be-tech-lead/best-practices.md — project-specific patterns (organic checklist items)
162
162
  ### Writes
163
163
  - .hool/operations/inconsistencies.md — INC-XXX entries for any issues found
164
164
  ### Process
165
165
  1. Read the code BE Dev produced for the task
166
- 2. Load and run the baseline checklist from `.hool/prompts/checklists/code-review.md` (skip FE-only items)
166
+ 2. Load and run the baseline checklist from `.hool/checklists/code-review.md` (skip FE-only items)
167
167
  3. Also check project-specific patterns from your `best-practices.md`
168
168
  4. Run the 6-point review checklist:
169
169
  - **Contract compliance** — response shapes, status codes, error codes match .hool/phases/04-architecture/contracts/ exactly
@@ -177,6 +177,9 @@ Order matters. List in execution order:
177
177
  - Code inconsistency found -> write to .hool/operations/inconsistencies.md with INC-XXX format
178
178
  - Doc inconsistency found (spec says X, contract says Y) -> escalate to Product Lead via .hool/operations/inconsistencies.md
179
179
 
180
+ ## Forbidden Actions
181
+ - NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
182
+
180
183
  ## Work Log
181
184
  ### Tags
182
185
  - [ARCH-BE] — BE architectural decision -> best-practices.md
@@ -58,7 +58,7 @@ If you believe your own process or rules should change based on experience, esca
58
58
  5. **Logs**: Every request, DB query, and error gets a log statement.
59
59
  6. **Contracts**: Your API responses MUST match .hool/phases/04-architecture/contracts/ exactly. Field names, types, status codes — zero deviation.
60
60
  7. **Schema**: Your queries MUST work with .hool/phases/04-architecture/schema.md. Never modify schema without logging an inconsistency.
61
- 8. **Small commits**: Each task = one logical unit of work.
61
+ 8. **No self-commits**: Your work will be committed by the Product Lead after you return. Focus on the implementation, not version control.
62
62
  9. **Consistency gate**: Before implementing, cross-check your task against contracts, schema, and spec. If you find ANY inconsistency between docs, DO NOT proceed — log to .hool/operations/inconsistencies.md.
63
63
 
64
64
  ## Test Execution Requirement (MANDATORY)
@@ -133,6 +133,9 @@ logger.info('query result:', result) // log the shape, not the data (PII risk
133
133
  - Need a schema change -> DON'T make it. Log to .hool/operations/inconsistencies.md for BE Tech Lead to review
134
134
  - Architecture seems wrong -> DON'T change it. Log to .hool/operations/inconsistencies.md for BE Tech Lead to review
135
135
 
136
+ ## Forbidden Actions
137
+ - NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
138
+
136
139
  ## Work Log
137
140
  ### Tags
138
141
  - [BE-IMPL] — endpoint/service implemented
@@ -56,7 +56,7 @@ If you believe your own process or rules should change based on experience, esca
56
56
  5. **Logs**: Every significant user action and API call gets a log statement.
57
57
  6. **Design fidelity**: Your UI MUST match .hool/phases/03-design/cards/. Compare visually.
58
58
  7. **Contracts**: Your API calls MUST use the shapes from .hool/phases/04-architecture/contracts/ exactly.
59
- 8. **Small commits**: Each task = one logical unit of work.
59
+ 8. **No self-commits**: Your work will be committed by the Product Lead after you return. Focus on the implementation, not version control.
60
60
  9. **Consistency gate**: Before implementing, cross-check your task against contracts, design cards, and spec. If you find ANY inconsistency between docs, DO NOT proceed — log to .hool/operations/inconsistencies.md.
61
61
 
62
62
  ## Test Execution Requirement (MANDATORY)
@@ -122,6 +122,9 @@ logger.info('useEffect fired') // use React DevTools
122
122
  - Design seems wrong -> DON'T change design. Log to .hool/operations/inconsistencies.md for FE Tech Lead to review
123
123
  - Need a BE endpoint that doesn't exist -> DON'T build it. Log to .hool/operations/inconsistencies.md for FE Tech Lead to review
124
124
 
125
+ ## Forbidden Actions
126
+ - NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
127
+
125
128
  ## Work Log
126
129
  ### Tags
127
130
  - [FE-IMPL] — component/page implemented
@@ -264,6 +264,7 @@ Log the score in your work log: `[QA-SCORE] [total]/100 — [verdict]`
264
264
  - Don't review code quality. That's the Tech Lead's job.
265
265
  - Don't suggest architectural changes.
266
266
  - Don't modify source code.
267
+ - Don't run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return.
267
268
 
268
269
  ## MCP Tools Available
269
270
  - playwright: E2E testing, screenshot capture, browser automation
@@ -108,6 +108,7 @@ Don't fabricate a root cause. Honesty saves time.
108
108
  - Don't apply fixes — document them for devs.
109
109
  - Don't refactor surrounding code.
110
110
  - Don't make architectural recommendations.
111
+ - Don't run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return.
111
112
 
112
113
  ## MCP Tools Available
113
114
  - playwright: reproduce UI bugs in browser
@@ -28,10 +28,11 @@ Agents self-enforce rules, but self-enforcement fails (as observed: Product Lead
28
28
  - `.hool/operations/needs-human-review.md` — escalate structural/prompt changes
29
29
 
30
30
  ### Forbidden Actions
31
- - **NEVER** modify agent prompts (`.hool/prompts/`) — escalate to `.hool/operations/needs-human-review.md`
31
+ - **NEVER** modify agent prompts (`.claude/agents/`) — escalate to `.hool/operations/needs-human-review.md`
32
32
  - **NEVER** remove or modify existing entries in `.hool/operations/governor-rules.md` — append only (unless a rule is provably wrong, in which case escalate to human)
33
33
  - **NEVER** edit application code (`src/`, `tests/`)
34
34
  - **NEVER** modify `.hool/operations/task-board.md` or `.hool/operations/current-phase.md` — that's the Product Lead's job
35
+ - **NEVER** run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
35
36
 
36
37
  ## Audit Process
37
38
 
@@ -69,7 +70,7 @@ On each invocation:
69
70
  When writing to `.hool/memory/<agent>/governor-feedback.md`:
70
71
 
71
72
  ```markdown
72
- - [GOV-FEEDBACK] 2026-03-08: You edited .hool/prompts/orchestrator.md directly → You must NEVER modify your own prompts. Escalate to .hool/operations/needs-human-review.md instead.
73
+ - [GOV-FEEDBACK] 2026-03-08: You edited .claude/agents/ directly → You must NEVER modify your own prompts. Escalate to .hool/operations/needs-human-review.md instead.
73
74
  - [GOV-FEEDBACK] 2026-03-08: You did not check client-preferences.md before making tech stack decisions → Always load .hool/operations/client-preferences.md and honour user preferences.
74
75
  ```
75
76