mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-06 17:23:28 +08:00
feat: inject active instincts into session start context
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const crypto = require('crypto');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
@@ -179,6 +180,26 @@ function cleanupTestDir(testDir) {
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
function writeInstinctFile(filePath, entries) {
|
||||
const body = entries.map(entry => `---
|
||||
id: ${entry.id}
|
||||
trigger: "${entry.trigger}"
|
||||
confidence: ${entry.confidence}
|
||||
domain: ${entry.domain || 'general'}
|
||||
scope: ${entry.scope}
|
||||
---
|
||||
|
||||
## Action
|
||||
${entry.action}
|
||||
|
||||
## Evidence
|
||||
${entry.evidence || 'Learned from repeated observations.'}
|
||||
`).join('\n');
|
||||
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, body);
|
||||
}
|
||||
|
||||
function getHookCommandByDescription(hooks, lifecycle, descriptionText) {
|
||||
const hookGroup = hooks.hooks[lifecycle]?.find(
|
||||
entry => entry.description && entry.description.includes(descriptionText)
|
||||
@@ -333,6 +354,66 @@ async function runTests() {
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (await asyncTest('session-start injects high-confidence instincts into additionalContext', async () => {
|
||||
const testDir = createTestDir();
|
||||
const projectDir = path.join(testDir, 'project');
|
||||
fs.mkdirSync(projectDir, { recursive: true });
|
||||
|
||||
try {
|
||||
const projectId = crypto.createHash('sha256').update(projectDir).digest('hex').slice(0, 12);
|
||||
const homunculusDir = path.join(testDir, '.claude', 'homunculus');
|
||||
const projectInstinctDir = path.join(homunculusDir, 'projects', projectId, 'instincts', 'personal');
|
||||
const globalInstinctDir = path.join(homunculusDir, 'instincts', 'inherited');
|
||||
|
||||
writeInstinctFile(path.join(projectInstinctDir, 'project-instincts.yaml'), [
|
||||
{
|
||||
id: 'project-tests-first',
|
||||
trigger: 'when changing tests',
|
||||
confidence: 0.9,
|
||||
scope: 'project',
|
||||
action: 'Run the targeted *.test.js file first, then widen to node tests/run-all.js.',
|
||||
},
|
||||
{
|
||||
id: 'project-low-confidence',
|
||||
trigger: 'when guessing',
|
||||
confidence: 0.4,
|
||||
scope: 'project',
|
||||
action: 'This should never be injected.',
|
||||
},
|
||||
]);
|
||||
|
||||
writeInstinctFile(path.join(globalInstinctDir, 'global-instincts.yaml'), [
|
||||
{
|
||||
id: 'global-validation',
|
||||
trigger: 'when editing hooks',
|
||||
confidence: 0.82,
|
||||
scope: 'global',
|
||||
action: 'Keep hook scripts, tests, and docs aligned in the same change set.',
|
||||
},
|
||||
]);
|
||||
|
||||
const result = await runHookWithInput(
|
||||
path.join(scriptsDir, 'session-start.js'),
|
||||
{},
|
||||
{
|
||||
HOME: testDir,
|
||||
CLAUDE_PROJECT_DIR: projectDir,
|
||||
}
|
||||
);
|
||||
|
||||
assert.strictEqual(result.code, 0, 'SessionStart should exit 0');
|
||||
const payload = getSessionStartPayload(result.stdout);
|
||||
const additionalContext = payload.hookSpecificOutput.additionalContext;
|
||||
|
||||
assert.ok(additionalContext.includes('Active instincts:'), 'Should inject instinct summary into additionalContext');
|
||||
assert.ok(additionalContext.includes('[project 90%] Run the targeted *.test.js file first, then widen to node tests/run-all.js.'), 'Should include project-scoped instinct');
|
||||
assert.ok(additionalContext.includes('[global 82%] Keep hook scripts, tests, and docs aligned in the same change set.'), 'Should include global instinct');
|
||||
assert.ok(!additionalContext.includes('This should never be injected.'), 'Should exclude low-confidence instincts');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (await asyncTest('session-end-marker removes the last lease and stops the observer process', async () => {
|
||||
const testDir = createTestDir();
|
||||
const projectDir = path.join(testDir, 'project');
|
||||
|
||||
Reference in New Issue
Block a user