@claudetools/tools 0.8.2 → 0.8.4

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 (74) hide show
  1. package/dist/cli.js +41 -0
  2. package/dist/context/deduplication.d.ts +72 -0
  3. package/dist/context/deduplication.js +77 -0
  4. package/dist/context/deduplication.test.d.ts +6 -0
  5. package/dist/context/deduplication.test.js +84 -0
  6. package/dist/context/emergency-eviction.d.ts +73 -0
  7. package/dist/context/emergency-eviction.example.d.ts +13 -0
  8. package/dist/context/emergency-eviction.example.js +94 -0
  9. package/dist/context/emergency-eviction.js +226 -0
  10. package/dist/context/eviction-engine.d.ts +76 -0
  11. package/dist/context/eviction-engine.example.d.ts +7 -0
  12. package/dist/context/eviction-engine.example.js +144 -0
  13. package/dist/context/eviction-engine.js +176 -0
  14. package/dist/context/example-usage.d.ts +1 -0
  15. package/dist/context/example-usage.js +128 -0
  16. package/dist/context/exchange-summariser.d.ts +80 -0
  17. package/dist/context/exchange-summariser.js +261 -0
  18. package/dist/context/health-monitor.d.ts +97 -0
  19. package/dist/context/health-monitor.example.d.ts +1 -0
  20. package/dist/context/health-monitor.example.js +164 -0
  21. package/dist/context/health-monitor.js +210 -0
  22. package/dist/context/importance-scorer.d.ts +94 -0
  23. package/dist/context/importance-scorer.example.d.ts +1 -0
  24. package/dist/context/importance-scorer.example.js +140 -0
  25. package/dist/context/importance-scorer.js +187 -0
  26. package/dist/context/index.d.ts +9 -0
  27. package/dist/context/index.js +16 -0
  28. package/dist/context/session-helper.d.ts +10 -0
  29. package/dist/context/session-helper.js +51 -0
  30. package/dist/context/session-store.d.ts +94 -0
  31. package/dist/context/session-store.js +286 -0
  32. package/dist/context/usage-estimator.d.ts +131 -0
  33. package/dist/context/usage-estimator.js +260 -0
  34. package/dist/context/usage-estimator.test.d.ts +1 -0
  35. package/dist/context/usage-estimator.test.js +208 -0
  36. package/dist/context-cli.d.ts +16 -0
  37. package/dist/context-cli.js +309 -0
  38. package/dist/evaluation/build-dataset.d.ts +1 -0
  39. package/dist/evaluation/build-dataset.js +135 -0
  40. package/dist/evaluation/threshold-eval.d.ts +63 -0
  41. package/dist/evaluation/threshold-eval.js +250 -0
  42. package/dist/handlers/codedna-handlers.d.ts +2 -2
  43. package/dist/handlers/tool-handlers.js +126 -165
  44. package/dist/helpers/api-client.d.ts +5 -1
  45. package/dist/helpers/api-client.js +3 -1
  46. package/dist/helpers/compact-formatter.d.ts +51 -0
  47. package/dist/helpers/compact-formatter.js +130 -0
  48. package/dist/helpers/engagement-tracker.d.ts +10 -0
  49. package/dist/helpers/engagement-tracker.js +61 -0
  50. package/dist/helpers/error-tracking.js +1 -1
  51. package/dist/helpers/session-validation.d.ts +76 -0
  52. package/dist/helpers/session-validation.js +221 -0
  53. package/dist/helpers/usage-analytics.js +1 -1
  54. package/dist/hooks/index.d.ts +4 -0
  55. package/dist/hooks/index.js +6 -0
  56. package/dist/hooks/post-tool-use-hook-cli.d.ts +2 -0
  57. package/dist/hooks/post-tool-use-hook-cli.js +34 -0
  58. package/dist/hooks/post-tool-use.d.ts +67 -0
  59. package/dist/hooks/post-tool-use.js +234 -0
  60. package/dist/hooks/stop-hook-cli.d.ts +2 -0
  61. package/dist/hooks/stop-hook-cli.js +34 -0
  62. package/dist/hooks/stop.d.ts +64 -0
  63. package/dist/hooks/stop.js +192 -0
  64. package/dist/index.d.ts +3 -0
  65. package/dist/index.js +2 -0
  66. package/dist/logger.d.ts +1 -1
  67. package/dist/logger.js +4 -0
  68. package/dist/resources.js +3 -0
  69. package/dist/setup.js +206 -2
  70. package/dist/templates/claude-md.d.ts +1 -1
  71. package/dist/templates/claude-md.js +23 -35
  72. package/dist/templates/worker-prompt.js +35 -202
  73. package/dist/tools.js +26 -20
  74. package/package.json +6 -2
package/dist/setup.js CHANGED
@@ -747,11 +747,22 @@ fi
747
747
  # Escape the query for JSON (handle quotes and newlines)
748
748
  ESCAPED_QUERY=$(echo "$USER_QUERY" | head -c 500 | jq -Rs '.')
749
749
 
750
+ # Get session state for query-aware budget allocation (if SESSION_ID available)
751
+ SESSION_STATE_JSON='{}'
752
+ if [ -n "$SESSION_ID" ]; then
753
+ # Try to get session state from SessionStore
754
+ TOOLS_DIR="$HOME/.claudetools/node_modules/@claudetools/tools"
755
+ if [ -f "$TOOLS_DIR/dist/context/session-helper.js" ]; then
756
+ SESSION_STATE_JSON=$(node "$TOOLS_DIR/dist/context/session-helper.js" "$SESSION_ID" 2>/dev/null || echo '{}')
757
+ fi
758
+ fi
759
+
750
760
  # Inject context with semantic search based on the user's prompt
761
+ # Include session_state if available for dynamic budget calculation
751
762
  RESULT=$(curl -s --max-time 2 -X POST "$API_URL/api/v1/context/inject" \\
752
763
  -H "Authorization: Bearer $API_KEY" \\
753
764
  -H "Content-Type: application/json" \\
754
- -d "{\\"query\\": $ESCAPED_QUERY, \\"project_id\\": \\"$PROJECT_ID\\", \\"cwd\\": \\"$CWD\\"}" \\
765
+ -d "{\\"query\\": $ESCAPED_QUERY, \\"project_id\\": \\"$PROJECT_ID\\", \\"cwd\\": \\"$CWD\\", \\"session_state\\": $SESSION_STATE_JSON}" \\
755
766
  2>/dev/null)
756
767
 
757
768
  # Output context as additionalContext JSON for Claude Code
@@ -1330,6 +1341,170 @@ export async function runUninstall() {
1330
1341
  console.log('\n' + chalk.green('ClaudeTools removed from Claude Code.'));
1331
1342
  console.log(chalk.dim('Your ~/.claudetools/ config and data are preserved.\n'));
1332
1343
  }
1344
+ async function runOnboarding(apiUrl, apiKey, projectId, projectName) {
1345
+ header('Project Onboarding');
1346
+ info('Answer a few questions to help Claude understand your project better.');
1347
+ console.log(chalk.dim('This creates memory facts that provide context in future sessions.\n'));
1348
+ const spinner = ora('Starting onboarding session...').start();
1349
+ try {
1350
+ // Start onboarding session
1351
+ const startResponse = await fetch(`${apiUrl}/api/v1/onboarding/start`, {
1352
+ method: 'POST',
1353
+ headers: {
1354
+ 'Content-Type': 'application/json',
1355
+ 'Authorization': `Bearer ${apiKey}`,
1356
+ },
1357
+ body: JSON.stringify({ project_id: projectId }),
1358
+ });
1359
+ if (!startResponse.ok) {
1360
+ spinner.fail('Could not start onboarding');
1361
+ const errorData = await startResponse.json().catch(() => ({}));
1362
+ error(errorData.error || `HTTP ${startResponse.status}`);
1363
+ return;
1364
+ }
1365
+ const startData = await startResponse.json();
1366
+ if (!startData.success || !startData.data) {
1367
+ spinner.fail('Failed to start onboarding');
1368
+ return;
1369
+ }
1370
+ spinner.succeed('Onboarding session started');
1371
+ const sessionId = startData.data.session_id;
1372
+ let questions = startData.data.questions;
1373
+ let state = startData.data.state;
1374
+ let questionCount = 0;
1375
+ const maxQuestions = 8; // Limit to avoid fatigue
1376
+ // Interactive question loop
1377
+ while (questions.length > 0 && questionCount < maxQuestions) {
1378
+ const question = questions[0];
1379
+ questionCount++;
1380
+ console.log('');
1381
+ console.log(chalk.cyan(`Question ${questionCount}`) + (question.category ? chalk.dim(` [${question.category}]`) : ''));
1382
+ console.log(chalk.bold(question.question));
1383
+ let answer;
1384
+ if (question.options && question.options.length > 0) {
1385
+ // Multiple choice question
1386
+ const { selected } = await prompts({
1387
+ type: 'select',
1388
+ name: 'selected',
1389
+ message: 'Select an option:',
1390
+ choices: [
1391
+ ...question.options.map(opt => ({ title: opt, value: opt })),
1392
+ { title: 'Skip this question', value: '__skip__' },
1393
+ ],
1394
+ });
1395
+ if (selected === '__skip__' || !selected) {
1396
+ questions.shift();
1397
+ continue;
1398
+ }
1399
+ answer = selected;
1400
+ }
1401
+ else {
1402
+ // Free text question
1403
+ const { response } = await prompts({
1404
+ type: 'text',
1405
+ name: 'response',
1406
+ message: '>',
1407
+ validate: (v) => v.length > 0 || 'Please enter a response (or type "skip" to skip)',
1408
+ });
1409
+ if (!response || response.toLowerCase() === 'skip') {
1410
+ questions.shift();
1411
+ continue;
1412
+ }
1413
+ answer = response;
1414
+ }
1415
+ // Submit answer
1416
+ const answerSpinner = ora('Processing...').start();
1417
+ try {
1418
+ const answerResponse = await fetch(`${apiUrl}/api/v1/onboarding/answer`, {
1419
+ method: 'POST',
1420
+ headers: {
1421
+ 'Content-Type': 'application/json',
1422
+ 'Authorization': `Bearer ${apiKey}`,
1423
+ },
1424
+ body: JSON.stringify({
1425
+ session_id: sessionId,
1426
+ question_id: question.id,
1427
+ answer,
1428
+ }),
1429
+ });
1430
+ if (answerResponse.ok) {
1431
+ const answerData = await answerResponse.json();
1432
+ if (answerData.success && answerData.data) {
1433
+ const factsCount = answerData.data.facts_extracted || 0;
1434
+ if (factsCount > 0) {
1435
+ answerSpinner.succeed(`Recorded (${factsCount} fact${factsCount > 1 ? 's' : ''} extracted)`);
1436
+ }
1437
+ else {
1438
+ answerSpinner.succeed('Recorded');
1439
+ }
1440
+ // Update questions and state
1441
+ if (answerData.data.next_questions) {
1442
+ questions = answerData.data.next_questions;
1443
+ }
1444
+ else {
1445
+ questions.shift();
1446
+ }
1447
+ if (answerData.data.state) {
1448
+ state = answerData.data.state;
1449
+ }
1450
+ }
1451
+ else {
1452
+ answerSpinner.warn('Answer recorded (no facts extracted)');
1453
+ questions.shift();
1454
+ }
1455
+ }
1456
+ else {
1457
+ answerSpinner.fail('Could not submit answer');
1458
+ questions.shift();
1459
+ }
1460
+ }
1461
+ catch {
1462
+ answerSpinner.fail('Network error');
1463
+ questions.shift();
1464
+ }
1465
+ // Check if we should stop
1466
+ if (state.phase === 'confirmation' || state.phase === 'done') {
1467
+ break;
1468
+ }
1469
+ }
1470
+ // Complete onboarding
1471
+ console.log('');
1472
+ const completeSpinner = ora('Completing onboarding...').start();
1473
+ try {
1474
+ const completeResponse = await fetch(`${apiUrl}/api/v1/onboarding/complete`, {
1475
+ method: 'POST',
1476
+ headers: {
1477
+ 'Content-Type': 'application/json',
1478
+ 'Authorization': `Bearer ${apiKey}`,
1479
+ },
1480
+ body: JSON.stringify({
1481
+ session_id: sessionId,
1482
+ project_id: projectId,
1483
+ }),
1484
+ });
1485
+ if (completeResponse.ok) {
1486
+ const completeData = await completeResponse.json();
1487
+ if (completeData.success && completeData.data) {
1488
+ const totalFacts = completeData.data.facts_extracted || 0;
1489
+ completeSpinner.succeed(`Onboarding complete! ${totalFacts} facts stored in memory.`);
1490
+ }
1491
+ else {
1492
+ completeSpinner.succeed('Onboarding complete!');
1493
+ }
1494
+ }
1495
+ else {
1496
+ completeSpinner.warn('Onboarding session saved (completion had issues)');
1497
+ }
1498
+ }
1499
+ catch {
1500
+ completeSpinner.warn('Could not finalize onboarding');
1501
+ }
1502
+ }
1503
+ catch (err) {
1504
+ spinner.fail('Onboarding failed');
1505
+ error(err instanceof Error ? err.message : String(err));
1506
+ }
1507
+ }
1333
1508
  // -----------------------------------------------------------------------------
1334
1509
  // Project Init
1335
1510
  // -----------------------------------------------------------------------------
@@ -1491,12 +1666,41 @@ export async function runInit() {
1491
1666
  const newContent = existingContent.trimEnd() + '\n' + projectContent;
1492
1667
  writeFileSync(projectClaudeMd, newContent);
1493
1668
  success('Created .claude/CLAUDE.md');
1669
+ // Ensure hooks are installed and configured
1670
+ // (User might have run init without setup, or hooks might have been deleted)
1671
+ header('Hook Configuration');
1672
+ try {
1673
+ await installHooks();
1674
+ await configureSettings();
1675
+ info('Hooks configured successfully');
1676
+ }
1677
+ catch (err) {
1678
+ // Non-fatal - just warn
1679
+ console.log(chalk.yellow('⚠ Warning: Could not configure hooks. Run "claudetools --setup" to fix.'));
1680
+ }
1494
1681
  // Summary
1495
1682
  console.log('\n' + chalk.green(' Project initialized!\n'));
1496
1683
  console.log(' ' + chalk.bold('Project:') + ` ${projectName}`);
1497
1684
  console.log(' ' + chalk.bold('ID:') + ` ${projectId}`);
1498
1685
  console.log(' ' + chalk.bold('Config:') + ` ${projectClaudeMd}\n`);
1499
- console.log(chalk.dim(' Memory tools are now configured for this project.\n'));
1686
+ // Offer onboarding
1687
+ if (config.apiKey) {
1688
+ const { runOnboard } = await prompts({
1689
+ type: 'confirm',
1690
+ name: 'runOnboard',
1691
+ message: 'Run project onboarding? (Helps Claude understand your project)',
1692
+ initial: true,
1693
+ });
1694
+ if (runOnboard) {
1695
+ await runOnboarding(config.apiUrl || DEFAULT_CONFIG.apiUrl, config.apiKey, projectId, projectName);
1696
+ }
1697
+ else {
1698
+ console.log(chalk.dim('\n You can run onboarding later with: claudetools onboard\n'));
1699
+ }
1700
+ }
1701
+ else {
1702
+ console.log(chalk.dim(' Memory tools are now configured for this project.\n'));
1703
+ }
1500
1704
  }
1501
1705
  // -----------------------------------------------------------------------------
1502
1706
  // Cleanup Command (standalone)
@@ -5,7 +5,7 @@ export declare const PROJECT_SECTION_END = "<!-- CLAUDETOOLS:PROJECT:END -->";
5
5
  /**
6
6
  * Global CLAUDE.md content - added to ~/.claude/CLAUDE.md
7
7
  */
8
- export declare const GLOBAL_TEMPLATE = "\n<!-- CLAUDETOOLS:START -->\n# ClaudeTools Memory System\n\nYou have access to a persistent memory system via the `claudetools_memory` MCP server. Use it to remember context across sessions.\n\n## Memory Tools\n\n### Searching Memory\n```\nmemory_search(query: \"authentication patterns\")\n```\nSearch for relevant facts, entities, and past context. Use this when:\n- Starting work on a feature to recall past decisions\n- Looking for patterns or conventions used before\n- Finding related code or architectural context\n\n### Storing Facts\n```\nmemory_store_fact(\n entity1: \"UserService\",\n relationship: \"USES\",\n entity2: \"bcrypt\",\n context: \"Password hashing uses bcrypt with 12 rounds\"\n)\n```\nStore important facts as relationships between entities. Use for:\n- Architectural decisions\n- Code patterns and conventions\n- Dependencies and relationships\n- User preferences learned during conversation\n\n### Context Injection\nContext is automatically injected at the start of each session based on the current project. Check `~/.claudetools/session-context.md` for project-specific context.\n\n## Task Management\n\n### Creating Work Plans with Auto-Dispatch\n```\ntask_plan(\n goal: \"Add user authentication\",\n epic_title: \"User Auth System\",\n tasks: [...]\n)\n```\nBreak down complex work into tracked tasks. **Tasks are automatically set to `ready` status.**\n\nAfter `task_plan` completes, you will receive Task tool invocations to spawn parallel agents.\n**Execute ALL Task tool calls in a SINGLE message** to enable parallel execution.\n\n### Parallel Agent Workflow\n1. User describes work needed\n2. Call `task_plan_draft` to present the plan\n3. User says \"go\" to approve\n4. Call `task_plan` - tasks created in `ready` status\n5. Execute the provided Task tool calls in ONE message\n6. Agents work in parallel, each calling `task_complete` when done\n\n### Manual Task Start (Sequential)\n```\ntask_start(task_id: \"task_xxx\")\n```\nClaim a task before working on it. Use for sequential execution.\n\n### Completing Tasks\n```\ntask_complete(task_id: \"task_xxx\", summary: \"Implemented JWT auth with refresh tokens\")\n```\nMark tasks done with a summary of work completed. **Always call this when a task is finished.**\n\n## Codebase Intelligence\n\n### Start with codebase_map() - ALWAYS\n```\ncodebase_map() # FIRST TOOL when exploring unfamiliar code\n```\n**When to use:** Starting a new task, exploring unfamiliar code, understanding project structure, finding entry points.\n\nThe map shows:\n- Project structure and key directories\n- Entry points and their exports\n- Framework detection (React, Express, etc.)\n- Key symbols and their locations\n\n**Use codebase_map BEFORE using Grep/Glob** - it gives you the lay of the land so you know where to look.\n\n### Then use targeted tools\n```\ncodebase_find(\"UserService\") # Find specific symbols/files\ncodebase_context(\"src/auth.ts\") # Get file dependencies\nanalyze_impact(\"validateToken\") # See what changing a function affects\n```\n\n## CodeDNA: Generate Code, Save 99% Tokens\n\n**When creating APIs/CRUD operations:** Call `codedna_generate_api` instead of writing code manually.\n\n```\ncodedna_generate_api({\n spec: \"User(email:string:unique, password:string:hashed, age:integer:min(18))\",\n framework: \"express\",\n options: { auth: true, validation: true, tests: true }\n})\n```\n\n**Generates 6 production files** (models, controllers, routes, validators, auth, tests) in ~5 seconds.\n**Saves:** 30,000 tokens \u2192 200 tokens (99% reduction)\n\n## Best Practices\n\n1. **Search before implementing** - Check memory for existing patterns\n2. **Store decisions** - Save architectural choices as facts\n3. **Use task tracking** - Break complex work into tasks\n4. **Use CodeDNA for APIs** - Generate instead of write (99% token savings)\n<!-- CLAUDETOOLS:END -->\n";
8
+ export declare const GLOBAL_TEMPLATE = "\n<!-- CLAUDETOOLS:START -->\n# ClaudeTools Memory System\n\nYou have access to a persistent memory system. **Context is AUTO-INJECTED via hooks** - you rarely need to call memory tools explicitly.\n\n## \u26A0\uFE0F IMPORTANT: Hooks vs MCP Tools\n\n**AUTOMATIC (via hooks - zero context cost):**\n- Context injection \u2192 `user-prompt-submit` hook runs on every message\n- Fact extraction \u2192 `post-tool-use` hook extracts from your work\n- Session context \u2192 `session-start` hook provides initial context\n\n**EXPLICIT (MCP tools - costs context):**\n- `memory_store_fact` \u2192 Store a specific fact you learned\n- `task_plan` / `task_start` / `task_complete` \u2192 Task management\n\n**DO NOT CALL these tools routinely (context already injected):**\n- `memory_search` - only if you need DIFFERENT search params\n- `memory_inject` - only if you need to refresh for a different query\n- `memory_get_context` - only for debugging\n- `memory_index` - only for debugging\n\n## Storing Facts (DO use this)\n```\nmemory_store_fact(\n entity1: \"UserService\",\n relationship: \"USES\",\n entity2: \"bcrypt\",\n context: \"Password hashing uses bcrypt with 12 rounds\"\n)\n```\nStore important facts when you learn something concrete. The `post-tool-use` hook also extracts facts automatically.\n\n## Task Management\n\n### Creating Work Plans with Auto-Dispatch\n```\ntask_plan(\n goal: \"Add user authentication\",\n epic_title: \"User Auth System\",\n tasks: [...]\n)\n```\nBreak down complex work into tracked tasks. **Tasks are automatically set to `ready` status.**\n\nAfter `task_plan` completes, you will receive Task tool invocations to spawn parallel agents.\n**Execute ALL Task tool calls in a SINGLE message** to enable parallel execution.\n\n### Parallel Agent Workflow\n1. User describes work needed\n2. Call `task_plan_draft` to present the plan\n3. User says \"go\" to approve\n4. Call `task_plan` - tasks created in `ready` status\n5. Execute the provided Task tool calls in ONE message\n6. Agents work in parallel, each calling `task_complete` when done\n\n### Manual Task Start (Sequential)\n```\ntask_start(task_id: \"task_xxx\")\n```\nClaim a task before working on it. Use for sequential execution.\n\n### Completing Tasks\n```\ntask_complete(task_id: \"task_xxx\", summary: \"Implemented JWT auth with refresh tokens\")\n```\nMark tasks done with a summary of work completed. **Always call this when a task is finished.**\n\n## Codebase Intelligence\n\n### Start with codebase_map() - ALWAYS\n```\ncodebase_map() # FIRST TOOL when exploring unfamiliar code\n```\n**When to use:** Starting a new task, exploring unfamiliar code, understanding project structure, finding entry points.\n\nThe map shows:\n- Project structure and key directories\n- Entry points and their exports\n- Framework detection (React, Express, etc.)\n- Key symbols and their locations\n\n**Use codebase_map BEFORE using Grep/Glob** - it gives you the lay of the land so you know where to look.\n\n### Then use targeted tools\n```\ncodebase_find(\"UserService\") # Find specific symbols/files\ncodebase_context(\"src/auth.ts\") # Get file dependencies\nanalyze_impact(\"validateToken\") # See what changing a function affects\n```\n\n## CodeDNA: Generate Code, Save 99% Tokens\n\n**When creating APIs/CRUD operations:** Call `codedna_generate_api` instead of writing code manually.\n\n```\ncodedna_generate_api({\n spec: \"User(email:string:unique, password:string:hashed, age:integer:min(18))\",\n framework: \"express\",\n options: { auth: true, validation: true, tests: true }\n})\n```\n\n**Generates 6 production files** (models, controllers, routes, validators, auth, tests) in ~5 seconds.\n**Saves:** 30,000 tokens \u2192 200 tokens (99% reduction)\n\n## Best Practices\n\n1. **Trust auto-injection** - Context is injected automatically, don't call memory_search\n2. **Store decisions** - Use `memory_store_fact` for architectural choices\n3. **Use task tracking** - Break complex work into tasks\n4. **Use CodeDNA for APIs** - Generate instead of write (99% token savings)\n5. **Minimize tool calls** - Every MCP call costs context tokens\n<!-- CLAUDETOOLS:END -->\n";
9
9
  /**
10
10
  * Project-level CLAUDE.md content - added to .claude/CLAUDE.md
11
11
  */
@@ -14,20 +14,26 @@ export const GLOBAL_TEMPLATE = `
14
14
  ${SECTION_START}
15
15
  # ClaudeTools Memory System
16
16
 
17
- You have access to a persistent memory system via the \`claudetools_memory\` MCP server. Use it to remember context across sessions.
17
+ You have access to a persistent memory system. **Context is AUTO-INJECTED via hooks** - you rarely need to call memory tools explicitly.
18
18
 
19
- ## Memory Tools
19
+ ## ⚠️ IMPORTANT: Hooks vs MCP Tools
20
20
 
21
- ### Searching Memory
22
- \`\`\`
23
- memory_search(query: "authentication patterns")
24
- \`\`\`
25
- Search for relevant facts, entities, and past context. Use this when:
26
- - Starting work on a feature to recall past decisions
27
- - Looking for patterns or conventions used before
28
- - Finding related code or architectural context
21
+ **AUTOMATIC (via hooks - zero context cost):**
22
+ - Context injection → \`user-prompt-submit\` hook runs on every message
23
+ - Fact extraction → \`post-tool-use\` hook extracts from your work
24
+ - Session context → \`session-start\` hook provides initial context
25
+
26
+ **EXPLICIT (MCP tools - costs context):**
27
+ - \`memory_store_fact\` Store a specific fact you learned
28
+ - \`task_plan\` / \`task_start\` / \`task_complete\` → Task management
29
29
 
30
- ### Storing Facts
30
+ **DO NOT CALL these tools routinely (context already injected):**
31
+ - \`memory_search\` - only if you need DIFFERENT search params
32
+ - \`memory_inject\` - only if you need to refresh for a different query
33
+ - \`memory_get_context\` - only for debugging
34
+ - \`memory_index\` - only for debugging
35
+
36
+ ## Storing Facts (DO use this)
31
37
  \`\`\`
32
38
  memory_store_fact(
33
39
  entity1: "UserService",
@@ -36,14 +42,7 @@ memory_store_fact(
36
42
  context: "Password hashing uses bcrypt with 12 rounds"
37
43
  )
38
44
  \`\`\`
39
- Store important facts as relationships between entities. Use for:
40
- - Architectural decisions
41
- - Code patterns and conventions
42
- - Dependencies and relationships
43
- - User preferences learned during conversation
44
-
45
- ### Context Injection
46
- Context is automatically injected at the start of each session based on the current project. Check \`~/.claudetools/session-context.md\` for project-specific context.
45
+ Store important facts when you learn something concrete. The \`post-tool-use\` hook also extracts facts automatically.
47
46
 
48
47
  ## Task Management
49
48
 
@@ -120,10 +119,11 @@ codedna_generate_api({
120
119
 
121
120
  ## Best Practices
122
121
 
123
- 1. **Search before implementing** - Check memory for existing patterns
124
- 2. **Store decisions** - Save architectural choices as facts
122
+ 1. **Trust auto-injection** - Context is injected automatically, don't call memory_search
123
+ 2. **Store decisions** - Use \`memory_store_fact\` for architectural choices
125
124
  3. **Use task tracking** - Break complex work into tasks
126
125
  4. **Use CodeDNA for APIs** - Generate instead of write (99% token savings)
126
+ 5. **Minimize tool calls** - Every MCP call costs context tokens
127
127
  ${SECTION_END}
128
128
  `;
129
129
  /**
@@ -134,31 +134,19 @@ export function getProjectTemplate(projectId, projectName) {
134
134
  ${SECTION_START}
135
135
  # Project: ${projectName}
136
136
 
137
- This project is registered with ClaudeTools Memory.
138
-
139
137
  **Project ID:** \`${projectId}\`
140
138
 
141
- ## Project Memory
142
-
143
- Use memory tools to search and store project-specific context:
139
+ Context is **auto-injected** via hooks. Only use \`memory_store_fact\` to store new facts:
144
140
 
145
141
  \`\`\`
146
- # Search this project's memory
147
- memory_search(query: "your search", project_id: "${projectId}")
148
-
149
- # Store a project fact
150
142
  memory_store_fact(
151
143
  entity1: "ComponentName",
152
144
  relationship: "IMPLEMENTS",
153
145
  entity2: "PatternName",
154
- context: "Description of the relationship",
146
+ context: "Why this decision was made",
155
147
  project_id: "${projectId}"
156
148
  )
157
149
  \`\`\`
158
-
159
- ## Session Context
160
-
161
- Project-specific context is injected automatically. Check \`~/.claudetools/session-context.md\` for current context.
162
150
  ${SECTION_END}
163
151
  `;
164
152
  }
@@ -67,136 +67,42 @@ function buildIdentitySection(worker) {
67
67
  function buildBehavioralSection(taskId) {
68
68
  return `<!-- Layer 2: Behavioral Guidelines -->
69
69
  <behavioral_guidelines>
70
- <core_behaviors>
71
- <behavior id="codedna_first" priority="MANDATORY">
72
- BEFORE writing code manually, check if CodeDNA can generate it:
73
-
74
- DISCOVERY WORKFLOW:
75
- 1. Call codedna_list_generators() to see available generators
76
- 2. Check if task includes Entity DSL format
77
- Example: "User(email:string:unique, password:string:hashed)"
78
- 3. Detect framework from project (package.json, existing code)
79
- 4. Match detected framework to generator capabilities
80
- 5. Call appropriate generator with detected settings
81
-
82
- BENEFITS:
83
- → Saves 95-99% tokens vs manual coding
84
- → Generates production-ready code with validation, auth, tests
85
-
86
- ONLY write code manually when:
87
- - Logic is too complex for generation
88
- - Modifying existing code (not creating new)
89
- - Custom business rules that can't be templated
90
- </behavior>
91
-
92
- <behavior id="tool_first" priority="MANDATORY">
93
- BEFORE writing code, use available tools:
94
-
95
- 1. codebase_map: START HERE - Get project overview
96
- → Understand project structure and key entry points
97
- → Identify frameworks and patterns in use
98
- → Find relevant directories before diving in
99
- → Use BEFORE Grep/Glob for unfamiliar code
100
-
101
- 2. memory_search: Check for existing patterns and decisions
102
- → "How was authentication implemented?"
103
- → "What patterns are used for X?"
104
-
105
- 3. codebase_find: Find specific symbols/files
106
- → Search for existing code to extend/adapt
107
-
108
- 4. codebase_context: Understand file dependencies
109
- → See what a file imports/exports
110
-
111
- 5. docs_get: Retrieve cached documentation
112
- → Get up-to-date API references
113
- </behavior>
114
-
115
- <behavior id="minimal_changes" priority="IMPORTANT">
116
- Make ONLY the changes required for this task.
117
- NEVER:
118
- - Refactor unrelated code
119
- - Add features not requested
120
- - Over-engineer solutions
121
- - Add unnecessary abstractions
122
- </behavior>
123
- </core_behaviors>
70
+ <behavior id="codedna_first" priority="MANDATORY">
71
+ BEFORE writing code: codedna_list_generators() → check if task matches generator
72
+ Entity DSL: "User(email:string:unique, password:string:hashed)"
73
+ Only write manually for: complex logic, modifications, custom business rules
74
+ </behavior>
75
+
76
+ <behavior id="tool_first" priority="MANDATORY">
77
+ Tool precedence: codebase_map → memory_search → codebase_find → docs_get
78
+ </behavior>
79
+
80
+ <behavior id="minimal_changes" priority="IMPORTANT">
81
+ Make ONLY task-required changes. No refactoring, features, or abstractions.
82
+ </behavior>
124
83
  </behavioral_guidelines>`;
125
84
  }
126
85
  function buildStandardsSection() {
127
86
  return `<!-- Layer 3: Standards & Best Practices -->
128
87
  <standards>
129
88
  <code_quality>
130
- - Write code that others can understand
131
- - Prefer explicit over implicit
132
- - Validate inputs at system boundaries
133
- - Handle errors with clear messages
89
+ Australian English. Explicit over implicit. Validate boundaries. Clear errors.
134
90
  </code_quality>
135
91
 
136
- <formatting>
137
- - Use Australian English in comments and messages
138
- - Follow existing code style in the project
139
- - Include file paths with line numbers in references
140
- </formatting>
141
-
142
92
  <memory_usage priority="CRITICAL">
143
- When storing facts with memory_store_fact(), follow these rules:
144
-
145
- STORE (learned contextual knowledge):
146
- - Project discoveries: Anti-patterns found, bugs fixed, patterns discovered
147
- - User preferences: Workflows, communication styles learned through interaction
148
- - Architectural decisions WHY: Reasoning behind choices, rejected alternatives
149
- - Solutions that worked: Specific implementations with context
150
-
151
- ❌ DON'T STORE (generic documentation):
152
- - Tool behavior: How the tool system works (already in API docs)
153
- - Universal knowledge: Programming concepts, language features
154
- - Temporary state: Current task status, session-specific data
155
-
156
- Rule of thumb: "Would I need to rediscover this in 3 months?"
157
- → YES = store it (learned pattern, specific to this context)
158
- → NO = don't store it (universal knowledge, temporary state)
93
+ Store: project discoveries, user preferences, decision rationale, working solutions
94
+ Don't store: tool behavior, universal knowledge, temporary state
95
+ Rule: "Would I rediscover this in 3 months?" → YES = store
159
96
  </memory_usage>
160
97
 
161
98
  <documentation_files priority="MANDATORY">
162
- NEVER create .md files in random locations. Follow these rules:
163
-
164
- DIRECTORY STRUCTURE:
165
- - docs/ → Project documentation, guides, specs
166
- - docs/research/ → Research notes, analysis, investigations
167
- - docs/decisions/ → Architecture Decision Records (ADRs)
168
- - CHANGELOG.md → Only in project root
169
- - README.md → Only in project root or package roots
170
-
171
- NAMING CONVENTIONS:
172
- - Use lowercase with hyphens: user-authentication-guide.md
173
- - NEVER use spaces or underscores in filenames
174
- - Include date prefix for time-sensitive docs: YYYY-MM-DD-topic.md
175
- Example: 2025-12-05-api-migration-plan.md
176
- - Research docs: YYYY-MM-DD-research-topic.md
177
- - Decision records: NNNN-decision-title.md (e.g., 0001-use-jwt-auth.md)
178
-
179
- ANTI-PATTERNS (NEVER DO):
180
- - Creating PLAN.md, NOTES.md, TODO.md in project root
181
- - Random capitalised filenames like IMPLEMENTATION_GUIDE.md
182
- - Nested docs in src/ or lib/ directories
183
- - Multiple README files outside package roots
184
- - Temporary docs without dates (impossible to clean up later)
185
-
186
- BEFORE CREATING ANY .md FILE:
187
- 1. Check if docs/ directory exists - create if needed
188
- 2. Determine correct subdirectory (research/, decisions/, etc.)
189
- 3. Use proper naming convention with date if temporal
190
- 4. Ask user if uncertain about placement
99
+ Structure: docs/research/, docs/decisions/, README.md/CHANGELOG.md in root only
100
+ Naming: lowercase-with-hyphens.md, YYYY-MM-DD-topic.md for temporal docs
101
+ Never: PLAN.md/NOTES.md in root, random caps, nested in src/, undated temp files
191
102
  </documentation_files>
192
103
 
193
104
  <completion_summary>
194
- When calling task_complete, include:
195
- - Implementation: What you built/changed
196
- - Files: List of modified files with paths
197
- - Decisions: Any architectural choices made
198
- - Testing: How changes were verified
199
- - Notes: Caveats, limitations, follow-up needed
105
+ Include: implementation, files modified, decisions, testing, notes
200
106
  </completion_summary>
201
107
  </standards>`;
202
108
  }
@@ -204,31 +110,10 @@ function buildDomainSection(worker) {
204
110
  return `<!-- Layer 4: Domain Knowledge -->
205
111
  <domain_knowledge>
206
112
  <codedna_capabilities>
207
- CODEDNA DISCOVERY PATTERN:
208
- 1. Call codedna_list_generators() to see available generators
209
- 2. Each generator lists supported frameworks and options
210
- 3. Detect project framework from package.json/pyproject.toml
211
- 4. Match detected framework to generator capabilities
212
- 5. If no match, ASK the user which framework to use
213
-
214
- ENTITY DSL FORMAT:
215
- EntityName(field:type:constraint, field:type:constraint, ...)
216
-
217
- TYPES:
218
- - string, integer, decimal, boolean, datetime
219
- - ref(EntityName) - foreign key reference
220
- - enum(val1|val2|val3) - enumeration
221
-
222
- CONSTRAINTS:
223
- - unique, required, min(n), max(n), hashed, default(value)
224
- - UI hints: textarea, switch, radio (for form rendering)
225
-
226
- WORKFLOW:
227
- 1. codedna_list_generators() → discover capabilities
228
- 2. codedna_validate_spec(spec) → validate DSL syntax
229
- 3. codedna_generate_*(spec, framework, options) → generate code
230
-
231
- DO NOT assume frameworks exist - always discover via codedna_list_generators
113
+ Discovery: codedna_list_generators() → detect framework → validate spec → generate
114
+ DSL: EntityName(field:type:constraint, ...)
115
+ Types: string, integer, decimal, boolean, datetime, ref(Entity), enum(a|b)
116
+ Constraints: unique, required, min(n), max(n), hashed, default(v), textarea, switch
232
117
  </codedna_capabilities>
233
118
 
234
119
  <worker_expertise>
@@ -239,26 +124,9 @@ function buildDomainSection(worker) {
239
124
  function buildCrossCuttingSection() {
240
125
  return `<!-- Layer 5: Cross-Cutting Concerns -->
241
126
  <cross_cutting_concerns>
242
- <error_handling>
243
- - Validate inputs at boundaries (API, CLI, file I/O)
244
- - Fail fast with clear error messages
245
- - Log errors with sufficient context for debugging
246
- - Provide actionable guidance to users
247
- </error_handling>
248
-
249
- <security>
250
- CRITICAL: Follow OWASP Top 10 guidelines
251
- - Never expose sensitive data (API keys, passwords, tokens)
252
- - Sanitize all user inputs
253
- - Use parameterized queries (never string concat for SQL)
254
- - Apply principle of least privilege
255
- </security>
256
-
257
- <performance>
258
- - Don't optimise prematurely
259
- - Consider token efficiency in prompts
260
- - Use CodeDNA for boilerplate (saves 95%+ tokens)
261
- </performance>
127
+ <error_handling>Validate boundaries. Fail fast. Clear messages. Actionable guidance.</error_handling>
128
+ <security>OWASP Top 10. No exposed secrets. Sanitize inputs. Parameterized queries. Least privilege.</security>
129
+ <performance>No premature optimization. Token efficiency. CodeDNA for boilerplate.</performance>
262
130
  </cross_cutting_concerns>`;
263
131
  }
264
132
  function buildTaskSection(task, epicContext) {
@@ -309,54 +177,19 @@ function buildSiblingSection(siblingTasks) {
309
177
  function buildProtocolSection(taskId) {
310
178
  return `<!-- Protocol -->
311
179
  <protocol>
312
- <step number="1" action="START">
313
- Call: task_start(task_id="${taskId}", agent_id="your-agent-id")
314
- This claims the task and prevents conflicts.
315
- </step>
316
-
317
- <step number="2" action="CHECK_CODEDNA">
318
- IF task involves creating entities/APIs:
319
- → Look for Entity DSL in task description
320
- → Call codedna_generate_api with the spec
321
- → Review generated code, make adjustments if needed
322
-
323
- IF task is modification/complex logic:
324
- → Use memory_search and codebase_find first
325
- → Write code manually only when necessary
326
- </step>
327
-
328
- <step number="3" action="IMPLEMENT">
329
- Complete the requirements described in the task.
330
- Make minimal changes. Don't over-engineer.
331
- </step>
332
-
333
- <step number="4" action="COMPLETE">
334
- Call: task_complete(task_id="${taskId}", summary="detailed summary")
335
-
336
- Include in summary:
337
- - What you implemented
338
- - Files created/modified
339
- - Decisions made
340
- - How you verified it works
341
- </step>
180
+ <step number="1">task_start(task_id="${taskId}")</step>
181
+ <step number="2">Check CodeDNA for entities/APIs, else use tools (memory_search, codebase_find)</step>
182
+ <step number="3">Implement requirements. Minimal changes.</step>
183
+ <step number="4">task_complete(task_id="${taskId}", summary="impl, files, decisions, testing")</step>
342
184
 
343
185
  <error_handling>
344
- IF you encounter blocking issues:
345
-
346
- 1. Log error:
347
- task_add_context(task_id="${taskId}", context_type="work_log",
348
- content="ERROR: description", added_by="your-agent-id")
349
-
350
- 2. Release task:
351
- task_release(task_id="${taskId}", agent_id="your-agent-id",
352
- new_status="blocked", work_log="summary of issue")
353
-
354
- Do NOT mark incomplete work as complete.
186
+ Blocking issues: task_add_context + task_release(status="blocked")
187
+ Never mark incomplete work as complete.
355
188
  </error_handling>
356
189
  </protocol>
357
190
 
358
191
  ---
359
- **Begin work now. Remember to call task_start first!**`;
192
+ **Begin work now. Call task_start first!**`;
360
193
  }
361
194
  /**
362
195
  * Build a minimal prompt for simple tasks