@claudetools/tools 0.8.3 → 0.8.5
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/dist/cli.js +41 -0
- package/dist/context/deduplication.d.ts +72 -0
- package/dist/context/deduplication.js +77 -0
- package/dist/context/deduplication.test.d.ts +6 -0
- package/dist/context/deduplication.test.js +84 -0
- package/dist/context/emergency-eviction.d.ts +73 -0
- package/dist/context/emergency-eviction.example.d.ts +13 -0
- package/dist/context/emergency-eviction.example.js +94 -0
- package/dist/context/emergency-eviction.js +226 -0
- package/dist/context/eviction-engine.d.ts +76 -0
- package/dist/context/eviction-engine.example.d.ts +7 -0
- package/dist/context/eviction-engine.example.js +144 -0
- package/dist/context/eviction-engine.js +176 -0
- package/dist/context/example-usage.d.ts +1 -0
- package/dist/context/example-usage.js +128 -0
- package/dist/context/exchange-summariser.d.ts +80 -0
- package/dist/context/exchange-summariser.js +261 -0
- package/dist/context/health-monitor.d.ts +97 -0
- package/dist/context/health-monitor.example.d.ts +1 -0
- package/dist/context/health-monitor.example.js +164 -0
- package/dist/context/health-monitor.js +210 -0
- package/dist/context/importance-scorer.d.ts +94 -0
- package/dist/context/importance-scorer.example.d.ts +1 -0
- package/dist/context/importance-scorer.example.js +140 -0
- package/dist/context/importance-scorer.js +187 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.js +16 -0
- package/dist/context/session-helper.d.ts +10 -0
- package/dist/context/session-helper.js +51 -0
- package/dist/context/session-store.d.ts +94 -0
- package/dist/context/session-store.js +286 -0
- package/dist/context/usage-estimator.d.ts +131 -0
- package/dist/context/usage-estimator.js +260 -0
- package/dist/context/usage-estimator.test.d.ts +1 -0
- package/dist/context/usage-estimator.test.js +208 -0
- package/dist/context-cli.d.ts +16 -0
- package/dist/context-cli.js +309 -0
- package/dist/handlers/codedna-handlers.d.ts +1 -1
- package/dist/handlers/tool-handlers.js +215 -13
- package/dist/helpers/api-client.d.ts +5 -1
- package/dist/helpers/api-client.js +3 -1
- package/dist/helpers/circuit-breaker.d.ts +28 -0
- package/dist/helpers/circuit-breaker.js +97 -0
- package/dist/helpers/compact-formatter.d.ts +2 -0
- package/dist/helpers/compact-formatter.js +6 -0
- package/dist/helpers/error-tracking.js +1 -1
- package/dist/helpers/tasks-retry.d.ts +9 -0
- package/dist/helpers/tasks-retry.js +30 -0
- package/dist/helpers/tasks.d.ts +91 -5
- package/dist/helpers/tasks.js +261 -16
- package/dist/helpers/usage-analytics.js +1 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/post-tool-use-hook-cli.d.ts +2 -0
- package/dist/hooks/post-tool-use-hook-cli.js +34 -0
- package/dist/hooks/post-tool-use.d.ts +67 -0
- package/dist/hooks/post-tool-use.js +234 -0
- package/dist/hooks/stop-hook-cli.d.ts +2 -0
- package/dist/hooks/stop-hook-cli.js +34 -0
- package/dist/hooks/stop.d.ts +64 -0
- package/dist/hooks/stop.js +192 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +4 -0
- package/dist/setup.js +206 -2
- package/dist/tools.js +107 -2
- package/package.json +19 -18
- package/scripts/verify-prompt-compliance.sh +0 -0
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
|
-
|
|
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)
|
package/dist/tools.js
CHANGED
|
@@ -146,6 +146,10 @@ EXAMPLES:
|
|
|
146
146
|
type: 'string',
|
|
147
147
|
description: 'Project ID (optional, uses default if not provided)',
|
|
148
148
|
},
|
|
149
|
+
is_critical: {
|
|
150
|
+
type: 'boolean',
|
|
151
|
+
description: 'Mark as critical fact - always injected regardless of query relevance. Use sparingly for truly essential facts.',
|
|
152
|
+
},
|
|
149
153
|
},
|
|
150
154
|
required: ['entity1', 'relationship', 'entity2', 'context'],
|
|
151
155
|
},
|
|
@@ -461,6 +465,54 @@ High hit rate memories (frequently fetched after being indexed) are good candida
|
|
|
461
465
|
required: ['goal', 'epic_title', 'tasks'],
|
|
462
466
|
},
|
|
463
467
|
},
|
|
468
|
+
{
|
|
469
|
+
name: 'task_plan_revise',
|
|
470
|
+
description: 'Modify an existing epic by adding new tasks, removing tasks, or updating task details. Enables iterative planning without recreating the entire plan.',
|
|
471
|
+
inputSchema: {
|
|
472
|
+
type: 'object',
|
|
473
|
+
properties: {
|
|
474
|
+
epic_id: {
|
|
475
|
+
type: 'string',
|
|
476
|
+
description: 'The ID of the epic to revise',
|
|
477
|
+
},
|
|
478
|
+
add_tasks: {
|
|
479
|
+
type: 'array',
|
|
480
|
+
items: {
|
|
481
|
+
type: 'object',
|
|
482
|
+
properties: {
|
|
483
|
+
title: { type: 'string' },
|
|
484
|
+
description: { type: 'string' },
|
|
485
|
+
effort: { type: 'string', enum: ['xs', 's', 'm', 'l', 'xl'] },
|
|
486
|
+
domain: { type: 'string' },
|
|
487
|
+
blocked_by: { type: 'array', items: { type: 'string' } },
|
|
488
|
+
},
|
|
489
|
+
required: ['title'],
|
|
490
|
+
},
|
|
491
|
+
description: 'New tasks to add to the epic',
|
|
492
|
+
},
|
|
493
|
+
remove_task_ids: {
|
|
494
|
+
type: 'array',
|
|
495
|
+
items: { type: 'string' },
|
|
496
|
+
description: 'Task IDs to cancel (sets status to cancelled)',
|
|
497
|
+
},
|
|
498
|
+
update_tasks: {
|
|
499
|
+
type: 'array',
|
|
500
|
+
items: {
|
|
501
|
+
type: 'object',
|
|
502
|
+
properties: {
|
|
503
|
+
task_id: { type: 'string' },
|
|
504
|
+
title: { type: 'string' },
|
|
505
|
+
description: { type: 'string' },
|
|
506
|
+
effort: { type: 'string', enum: ['xs', 's', 'm', 'l', 'xl'] },
|
|
507
|
+
},
|
|
508
|
+
required: ['task_id'],
|
|
509
|
+
},
|
|
510
|
+
description: 'Tasks to update (adds context about changes)',
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
required: ['epic_id'],
|
|
514
|
+
},
|
|
515
|
+
},
|
|
464
516
|
{
|
|
465
517
|
name: 'task_start',
|
|
466
518
|
description: 'PROACTIVE: When starting work on a task, claim it and get all context. Use this before beginning any task work.',
|
|
@@ -604,7 +656,16 @@ High hit rate memories (frequently fetched after being indexed) are good candida
|
|
|
604
656
|
},
|
|
605
657
|
{
|
|
606
658
|
name: 'task_claim',
|
|
607
|
-
description:
|
|
659
|
+
description: `Claim a task for working on it. Creates a lock preventing other agents from working on it.
|
|
660
|
+
|
|
661
|
+
Lock duration is automatically scaled based on task effort:
|
|
662
|
+
- xs: 15 minutes
|
|
663
|
+
- s: 30 minutes (default if no effort specified)
|
|
664
|
+
- m: 60 minutes (1 hour)
|
|
665
|
+
- l: 120 minutes (2 hours)
|
|
666
|
+
- xl: 240 minutes (4 hours)
|
|
667
|
+
|
|
668
|
+
Explicit lock_duration_minutes parameter overrides the effort-based default.`,
|
|
608
669
|
inputSchema: {
|
|
609
670
|
type: 'object',
|
|
610
671
|
properties: {
|
|
@@ -618,7 +679,7 @@ High hit rate memories (frequently fetched after being indexed) are good candida
|
|
|
618
679
|
},
|
|
619
680
|
lock_duration_minutes: {
|
|
620
681
|
type: 'number',
|
|
621
|
-
description: '
|
|
682
|
+
description: 'Optional: Override effort-based lock duration (in minutes)',
|
|
622
683
|
},
|
|
623
684
|
},
|
|
624
685
|
required: ['task_id', 'agent_id'],
|
|
@@ -735,6 +796,32 @@ High hit rate memories (frequently fetched after being indexed) are good candida
|
|
|
735
796
|
required: ['task_id', 'agent_id'],
|
|
736
797
|
},
|
|
737
798
|
},
|
|
799
|
+
{
|
|
800
|
+
name: 'task_handoff',
|
|
801
|
+
description: 'Hand off a task to a different expert worker type during execution. Releases current lock, updates agent_type, and sets task back to ready status for re-dispatch.',
|
|
802
|
+
inputSchema: {
|
|
803
|
+
type: 'object',
|
|
804
|
+
properties: {
|
|
805
|
+
task_id: {
|
|
806
|
+
type: 'string',
|
|
807
|
+
description: 'The task ID to hand off',
|
|
808
|
+
},
|
|
809
|
+
new_worker_type: {
|
|
810
|
+
type: 'string',
|
|
811
|
+
description: 'Target worker type (e.g., "api-expert", "frontend-expert", "database-expert")',
|
|
812
|
+
},
|
|
813
|
+
reason: {
|
|
814
|
+
type: 'string',
|
|
815
|
+
description: 'Why the handoff is needed (e.g., "requires database expertise", "needs API integration")',
|
|
816
|
+
},
|
|
817
|
+
agent_id: {
|
|
818
|
+
type: 'string',
|
|
819
|
+
description: 'Your agent identifier (default: claude-code)',
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
required: ['task_id', 'new_worker_type', 'reason'],
|
|
823
|
+
},
|
|
824
|
+
},
|
|
738
825
|
// =========================================================================
|
|
739
826
|
// ORCHESTRATION TOOLS
|
|
740
827
|
// =========================================================================
|
|
@@ -917,6 +1004,24 @@ High hit rate memories (frequently fetched after being indexed) are good candida
|
|
|
917
1004
|
required: ['epic_id'],
|
|
918
1005
|
},
|
|
919
1006
|
},
|
|
1007
|
+
{
|
|
1008
|
+
name: 'task_aggregate',
|
|
1009
|
+
description: 'Aggregate work_log context from all sibling tasks under an epic for orchestrator synthesis. Returns structured summary of completed work across all tasks in the epic.',
|
|
1010
|
+
inputSchema: {
|
|
1011
|
+
type: 'object',
|
|
1012
|
+
properties: {
|
|
1013
|
+
epic_id: {
|
|
1014
|
+
type: 'string',
|
|
1015
|
+
description: 'Epic ID to aggregate from',
|
|
1016
|
+
},
|
|
1017
|
+
include_pending: {
|
|
1018
|
+
type: 'boolean',
|
|
1019
|
+
description: 'Include non-completed tasks (default: false)',
|
|
1020
|
+
},
|
|
1021
|
+
},
|
|
1022
|
+
required: ['epic_id'],
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
920
1025
|
// =========================================================================
|
|
921
1026
|
// CODEBASE MAPPING TOOLS
|
|
922
1027
|
// =========================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudetools/tools",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Persistent AI memory, task management, and codebase intelligence for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,22 +14,6 @@
|
|
|
14
14
|
"README.md",
|
|
15
15
|
"LICENSE"
|
|
16
16
|
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "tsc",
|
|
19
|
-
"start": "node dist/index.js",
|
|
20
|
-
"dev": "tsx src/index.ts",
|
|
21
|
-
"test": "vitest run",
|
|
22
|
-
"test:watch": "vitest",
|
|
23
|
-
"test:ui": "vitest --ui",
|
|
24
|
-
"prepublishOnly": "npm run build",
|
|
25
|
-
"codedna:monitor": "tsx -e \"import { runMonitoring } from './src/helpers/codedna-monitoring.js'; runMonitoring()\"",
|
|
26
|
-
"codedna:analytics": "tsx -e \"import { weeklyAnalyticsSummary } from './src/helpers/usage-analytics.js'; weeklyAnalyticsSummary()\"",
|
|
27
|
-
"codedna:analytics:24h": "tsx -e \"import { getLast24HoursAnalytics, printAnalytics } from './src/helpers/usage-analytics.js'; const r = await getLast24HoursAnalytics(); printAnalytics(r, 'Last 24 Hours')\"",
|
|
28
|
-
"codedna:analytics:30d": "tsx -e \"import { getLast30DaysAnalytics, printAnalytics } from './src/helpers/usage-analytics.js'; const r = await getLast30DaysAnalytics(); printAnalytics(r, 'Last 30 Days')\"",
|
|
29
|
-
"prompt:verify": "scripts/verify-prompt-compliance.sh",
|
|
30
|
-
"eval:build-dataset": "tsx src/evaluation/build-dataset.ts",
|
|
31
|
-
"eval:threshold": "tsx src/evaluation/threshold-eval.ts"
|
|
32
|
-
},
|
|
33
17
|
"repository": {
|
|
34
18
|
"type": "git",
|
|
35
19
|
"url": "git+https://github.com/claudetools/memory.git"
|
|
@@ -65,12 +49,29 @@
|
|
|
65
49
|
"typescript": "^5.3.0"
|
|
66
50
|
},
|
|
67
51
|
"devDependencies": {
|
|
52
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
68
53
|
"@types/node": "^20.10.0",
|
|
69
54
|
"@types/nunjucks": "^3.2.6",
|
|
70
55
|
"@types/prompts": "^2.4.9",
|
|
71
56
|
"@vitest/ui": "^4.0.15",
|
|
57
|
+
"better-sqlite3": "^12.5.0",
|
|
72
58
|
"tsx": "^4.7.0",
|
|
73
59
|
"typescript": "^5.3.0",
|
|
74
60
|
"vitest": "^4.0.15"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsc",
|
|
64
|
+
"start": "node dist/index.js",
|
|
65
|
+
"dev": "tsx src/index.ts",
|
|
66
|
+
"test": "vitest run",
|
|
67
|
+
"test:watch": "vitest",
|
|
68
|
+
"test:ui": "vitest --ui",
|
|
69
|
+
"codedna:monitor": "tsx -e \"import { runMonitoring } from './src/helpers/codedna-monitoring.js'; runMonitoring()\"",
|
|
70
|
+
"codedna:analytics": "tsx -e \"import { weeklyAnalyticsSummary } from './src/helpers/usage-analytics.js'; weeklyAnalyticsSummary()\"",
|
|
71
|
+
"codedna:analytics:24h": "tsx -e \"import { getLast24HoursAnalytics, printAnalytics } from './src/helpers/usage-analytics.js'; const r = await getLast24HoursAnalytics(); printAnalytics(r, 'Last 24 Hours')\"",
|
|
72
|
+
"codedna:analytics:30d": "tsx -e \"import { getLast30DaysAnalytics, printAnalytics } from './src/helpers/usage-analytics.js'; const r = await getLast30DaysAnalytics(); printAnalytics(r, 'Last 30 Days')\"",
|
|
73
|
+
"prompt:verify": "scripts/verify-prompt-compliance.sh",
|
|
74
|
+
"eval:build-dataset": "tsx src/evaluation/build-dataset.ts",
|
|
75
|
+
"eval:threshold": "tsx src/evaluation/threshold-eval.ts"
|
|
75
76
|
}
|
|
76
|
-
}
|
|
77
|
+
}
|
|
File without changes
|