@hustle-together/api-dev-tools 1.2.1 → 1.6.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 CHANGED
@@ -26,16 +26,18 @@ Five powerful slash commands for Claude Code:
26
26
  - **`/api-status [endpoint]`** - Track implementation progress and phase completion
27
27
 
28
28
  ### Enforcement Hooks
29
- Three Python hooks that provide **real programmatic guarantees**:
29
+ Five Python hooks that provide **real programmatic guarantees**:
30
30
 
31
31
  - **`enforce-research.py`** - Blocks API code writing until research is complete
32
- - **`track-tool-use.py`** - Logs all research activity (Context7, WebSearch, WebFetch)
33
- - **`api-workflow-check.py`** - Prevents stopping until required phases are complete
32
+ - **`enforce-interview.py`** - Verifies user questions were actually asked (prevents self-answering)
33
+ - **`verify-implementation.py`** - Checks implementation matches interview requirements
34
+ - **`track-tool-use.py`** - Logs all research activity (Context7, WebSearch, WebFetch, AskUserQuestion)
35
+ - **`api-workflow-check.py`** - Prevents stopping until required phases are complete + git diff verification
34
36
 
35
37
  ### State Tracking
36
38
  - **`.claude/api-dev-state.json`** - Persistent state file tracking all workflow progress
37
39
 
38
- ### MCP Servers (Auto-configured in `.mcp.json`)
40
+ ### MCP Servers (Auto-installed via `claude mcp add`)
39
41
  - **Context7** - Fetches LIVE documentation from library source code (not training data)
40
42
  - **GitHub** - Read/create issues, pull requests, and access repository data (requires `GITHUB_PERSONAL_ACCESS_TOKEN`)
41
43
 
@@ -402,6 +404,47 @@ The `.claude/api-dev-state.json` file tracks:
402
404
  - All research activity is **logged** - auditable trail
403
405
  - Workflow completion is **verified** - can't stop early
404
406
 
407
+ ## šŸ” Gap Detection & Verification (v1.6.0+)
408
+
409
+ The workflow now includes automatic detection of common implementation gaps:
410
+
411
+ ### Gap 1: Exact Term Matching
412
+ **Problem:** AI paraphrases user terminology instead of using exact terms for research.
413
+
414
+ **Example:**
415
+ - User says: "Use Vercel AI Gateway"
416
+ - AI searches for: "Vercel AI SDK" (wrong!)
417
+
418
+ **Fix:** `verify-implementation.py` extracts key terms from interview answers and warns if those exact terms weren't used in research queries.
419
+
420
+ ### Gap 2: File Change Tracking
421
+ **Problem:** AI claims "all files updated" but doesn't verify which files actually changed.
422
+
423
+ **Fix:** `api-workflow-check.py` runs `git diff --name-only` and compares against tracked `files_created`/`files_modified` in state. Warns about untracked changes.
424
+
425
+ ### Gap 3: Skipped Test Investigation
426
+ **Problem:** AI accepts "9 tests skipped" without investigating why.
427
+
428
+ **Fix:** `verification_warnings` in state file tracks issues that need review. Stop hook shows unaddressed warnings.
429
+
430
+ ### Gap 4: Implementation Verification
431
+ **Problem:** AI marks task complete without verifying implementation matches interview.
432
+
433
+ **Fix:** Stop hook checks that:
434
+ - Route files exist if endpoints mentioned
435
+ - Test files are tracked
436
+ - Key terms from interview appear in implementation
437
+
438
+ ### Gap 5: Test/Production Alignment
439
+ **Problem:** Test files check different environment variables than production code.
440
+
441
+ **Example:**
442
+ - Interview: "single gateway key"
443
+ - Production: uses `AI_GATEWAY_API_KEY`
444
+ - Test: still checks `OPENAI_API_KEY` (wrong!)
445
+
446
+ **Fix:** `verify-implementation.py` warns when test files check env vars that don't match interview requirements.
447
+
405
448
  ## šŸ”§ Requirements
406
449
 
407
450
  - **Node.js** 14.0.0 or higher
@@ -432,7 +475,7 @@ Required for `/pr` and `/issue` commands to work with GitHub MCP tools.
432
475
  export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_your_token_here
433
476
  ```
434
477
 
435
- The MCP configuration is written to `.mcp.json` in your project root and will be picked up by Claude Code on restart. First use will prompt for security approval.
478
+ The installer runs `claude mcp add` commands directly, which registers the servers in your Claude Code config (`~/.claude.json`). Restart Claude Code after installation for MCP tools to be available.
436
479
 
437
480
  ## šŸ“– Documentation
438
481
 
package/bin/cli.js CHANGED
@@ -234,40 +234,40 @@ function main() {
234
234
  }
235
235
 
236
236
  // ========================================
237
- // 5. Install/Merge MCP Servers (Context7, GitHub)
237
+ // 5. Install MCP Servers via CLI (Context7, GitHub)
238
238
  // ========================================
239
- // NOTE: Claude Code uses .mcp.json in project root, NOT .claude/mcp-servers.json
240
- const mcpSource = path.join(sourceTemplatesDir, 'mcp-servers.json');
241
- const mcpDest = path.join(targetDir, '.mcp.json');
239
+ // NOTE: We use `claude mcp add` directly because .mcp.json requires manual approval
240
+ // and doesn't auto-load. Using the CLI ensures servers are immediately available.
241
+ log('\nšŸ”Œ Configuring MCP servers:', 'cyan');
242
242
 
243
- if (fs.existsSync(mcpSource)) {
244
- log('\nšŸ”Œ Configuring MCP servers:', 'cyan');
243
+ const { execSync } = require('child_process');
245
244
 
245
+ const mcpServers = [
246
+ { name: 'context7', command: 'npx -y @upstash/context7-mcp', description: 'Live documentation from library source code' },
247
+ { name: 'github', command: 'npx -y @modelcontextprotocol/server-github', description: 'GitHub issues, PRs, and repository access' }
248
+ ];
249
+
250
+ for (const server of mcpServers) {
246
251
  try {
247
- const newMcp = JSON.parse(fs.readFileSync(mcpSource, 'utf8'));
248
-
249
- if (fs.existsSync(mcpDest)) {
250
- // Merge with existing MCP config
251
- const existingMcp = JSON.parse(fs.readFileSync(mcpDest, 'utf8'));
252
- const mergedMcp = mergeMcpServers(existingMcp, newMcp);
253
- fs.writeFileSync(mcpDest, JSON.stringify(mergedMcp, null, 2));
254
- log(' āœ… Merged into existing .mcp.json', 'green');
255
- } else {
256
- // Create new MCP config file
257
- fs.writeFileSync(mcpDest, JSON.stringify(newMcp, null, 2));
258
- log(' āœ… Created .mcp.json in project root', 'green');
252
+ // Check if server already exists
253
+ const checkResult = execSync(`claude mcp get ${server.name} 2>&1`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
254
+ if (checkResult.includes('Connected') || checkResult.includes('Scope:')) {
255
+ log(` āœ“ ${server.name} - already configured`, 'blue');
256
+ }
257
+ } catch (checkError) {
258
+ // Server doesn't exist, add it
259
+ try {
260
+ execSync(`claude mcp add ${server.name} -- ${server.command}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
261
+ log(` āœ… ${server.name} - ${server.description}`, 'green');
262
+ } catch (addError) {
263
+ log(` āš ļø ${server.name} - Could not add (run manually: claude mcp add ${server.name} -- ${server.command})`, 'yellow');
259
264
  }
260
-
261
- log('\n MCP servers configured:', 'blue');
262
- log(' • context7 - Live documentation from library source code', 'blue');
263
- log(' • github - GitHub issues, PRs, and repository access', 'blue');
264
- log('\n āš ļø GitHub MCP requires GITHUB_PERSONAL_ACCESS_TOKEN in env', 'yellow');
265
- log(' āš ļø First use will prompt for security approval', 'yellow');
266
- } catch (error) {
267
- log(` āŒ Failed to configure MCP servers: ${error.message}`, 'red');
268
265
  }
269
266
  }
270
267
 
268
+ log('\n āš ļø GitHub MCP requires GITHUB_PERSONAL_ACCESS_TOKEN in env', 'yellow');
269
+ log(' šŸ’” Restart Claude Code for MCP tools to be available', 'yellow');
270
+
271
271
  // ========================================
272
272
  // Success Summary
273
273
  // ========================================
@@ -280,7 +280,7 @@ function main() {
280
280
  log(' Hooks: .claude/hooks/*.py', 'blue');
281
281
  log(' Settings: .claude/settings.json', 'blue');
282
282
  log(' State: .claude/api-dev-state.json', 'blue');
283
- log(' MCP: .mcp.json (Context7, GitHub)', 'blue');
283
+ log(' MCP: context7, github (via claude mcp add)', 'blue');
284
284
 
285
285
  log('\nšŸ”’ Enforcement Features:', 'bright');
286
286
  log(' • Research MUST happen before code writing', 'cyan');