mindlore 0.6.7 → 0.6.8
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 +259 -259
- package/SCHEMA.md +292 -292
- package/dist/scripts/cc-memory-bulk-sync.d.ts.map +1 -1
- package/dist/scripts/cc-memory-bulk-sync.js +47 -42
- package/dist/scripts/cc-memory-bulk-sync.js.map +1 -1
- package/dist/scripts/cc-session-sync.d.ts.map +1 -1
- package/dist/scripts/cc-session-sync.js +58 -48
- package/dist/scripts/cc-session-sync.js.map +1 -1
- package/dist/scripts/init.js +8 -8
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/all-migrations.d.ts.map +1 -1
- package/dist/scripts/lib/all-migrations.js +4 -1
- package/dist/scripts/lib/all-migrations.js.map +1 -1
- package/dist/scripts/lib/consolidation.d.ts +4 -3
- package/dist/scripts/lib/consolidation.d.ts.map +1 -1
- package/dist/scripts/lib/consolidation.js +10 -10
- package/dist/scripts/lib/consolidation.js.map +1 -1
- package/dist/scripts/lib/constants.d.ts +1 -7
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +2 -9
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/db-helpers.d.ts +0 -15
- package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
- package/dist/scripts/lib/db-helpers.js +1 -51
- package/dist/scripts/lib/db-helpers.js.map +1 -1
- package/dist/scripts/lib/decay.d.ts.map +1 -1
- package/dist/scripts/lib/decay.js +9 -9
- package/dist/scripts/lib/decay.js.map +1 -1
- package/dist/scripts/lib/episodes.js +23 -23
- package/dist/scripts/lib/migrations-v061.js +21 -21
- package/dist/scripts/lib/migrations-v062.js +11 -11
- package/dist/scripts/lib/migrations-v063.js +14 -14
- package/dist/scripts/lib/migrations-v067.js +11 -11
- package/dist/scripts/lib/migrations-v068.d.ts +3 -0
- package/dist/scripts/lib/migrations-v068.d.ts.map +1 -0
- package/dist/scripts/lib/migrations-v068.js +37 -0
- package/dist/scripts/lib/migrations-v068.js.map +1 -0
- package/dist/scripts/lib/migrations.d.ts.map +1 -1
- package/dist/scripts/lib/migrations.js +0 -15
- package/dist/scripts/lib/migrations.js.map +1 -1
- package/dist/scripts/lib/schema-version.js +6 -6
- package/dist/scripts/lib/search-cache.js +11 -11
- package/dist/scripts/lib/session-payload.d.ts.map +1 -1
- package/dist/scripts/lib/session-payload.js +7 -7
- package/dist/scripts/lib/session-payload.js.map +1 -1
- package/dist/scripts/lib/triage.js +3 -3
- package/dist/scripts/mindlore-backup.js +9 -9
- package/dist/scripts/mindlore-fts5-index.d.ts +1 -2
- package/dist/scripts/mindlore-fts5-index.d.ts.map +1 -1
- package/dist/scripts/mindlore-fts5-index.js +12 -64
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
- package/dist/scripts/mindlore-health-check.js +0 -11
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/tests/cc-memory-bulk-sync.test.js +23 -0
- package/dist/tests/cc-memory-bulk-sync.test.js.map +1 -1
- package/dist/tests/cc-session-sync.test.js +25 -0
- package/dist/tests/cc-session-sync.test.js.map +1 -1
- package/dist/tests/compaction-snapshot.test.js +2 -2
- package/dist/tests/consolidation.test.js +5 -5
- package/dist/tests/consolidation.test.js.map +1 -1
- package/dist/tests/decay.test.js +9 -9
- package/dist/tests/diary.test.js +4 -4
- package/dist/tests/episode-kind-constant.test.d.ts +2 -0
- package/dist/tests/episode-kind-constant.test.d.ts.map +1 -0
- package/dist/tests/episode-kind-constant.test.js +28 -0
- package/dist/tests/episode-kind-constant.test.js.map +1 -0
- package/dist/tests/episodes-inject.test.js +9 -9
- package/dist/tests/fts5.test.js +66 -125
- package/dist/tests/fts5.test.js.map +1 -1
- package/dist/tests/globalSetup.d.ts +2 -0
- package/dist/tests/globalSetup.d.ts.map +1 -0
- package/dist/tests/globalSetup.js +36 -0
- package/dist/tests/globalSetup.js.map +1 -0
- package/dist/tests/helpers/db.d.ts +13 -5
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js +60 -33
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/lesson-graduation.test.js +11 -11
- package/dist/tests/lesson-graduation.test.js.map +1 -1
- package/dist/tests/migrations-v053.test.js +16 -16
- package/dist/tests/migrations-v061.test.js +10 -10
- package/dist/tests/migrations-v063.test.js +2 -2
- package/dist/tests/migrations-v068.test.d.ts +2 -0
- package/dist/tests/migrations-v068.test.d.ts.map +1 -0
- package/dist/tests/migrations-v068.test.js +53 -0
- package/dist/tests/migrations-v068.test.js.map +1 -0
- package/dist/tests/nomination-counts.test.d.ts +2 -0
- package/dist/tests/nomination-counts.test.d.ts.map +1 -0
- package/dist/tests/nomination-counts.test.js +51 -0
- package/dist/tests/nomination-counts.test.js.map +1 -0
- package/dist/tests/recall-telemetry.test.js +8 -8
- package/dist/tests/schema-version.test.js +3 -7
- package/dist/tests/schema-version.test.js.map +1 -1
- package/dist/tests/search-hook.test.js +2 -2
- package/dist/tests/sec-regression.test.js +0 -50
- package/dist/tests/sec-regression.test.js.map +1 -1
- package/dist/tests/session-end-cleanup.test.js +3 -20
- package/dist/tests/session-end-cleanup.test.js.map +1 -1
- package/dist/tests/session-focus.test.js +7 -30
- package/dist/tests/session-focus.test.js.map +1 -1
- package/dist/tests/session-payload.test.js +1 -1
- package/dist/tests/session-summary.test.js +1 -1
- package/hooks/lib/constants.cjs +15 -0
- package/hooks/lib/mindlore-common.cjs +974 -1042
- package/hooks/mindlore-cwd-changed.cjs +57 -57
- package/hooks/mindlore-decision-detector.cjs +54 -54
- package/hooks/mindlore-dont-repeat.cjs +222 -222
- package/hooks/mindlore-fts5-sync.cjs +97 -88
- package/hooks/mindlore-index.cjs +229 -229
- package/hooks/mindlore-model-router.cjs +54 -54
- package/hooks/mindlore-post-compact.cjs +69 -69
- package/hooks/mindlore-post-read.cjs +106 -106
- package/hooks/mindlore-pre-compact.cjs +154 -154
- package/hooks/mindlore-read-guard.cjs +105 -105
- package/hooks/mindlore-research-guard.cjs +176 -176
- package/hooks/mindlore-search.cjs +200 -200
- package/hooks/mindlore-session-end.cjs +509 -526
- package/hooks/mindlore-session-focus.cjs +256 -259
- package/package.json +75 -78
- package/plugin.json +1 -1
- package/skills/mindlore-diary/SKILL.md +85 -85
- package/skills/mindlore-evolve/SKILL.md +126 -126
- package/skills/mindlore-explore/SKILL.md +109 -109
- package/skills/mindlore-ingest/SKILL.md +195 -195
- package/skills/mindlore-maintain/SKILL.md +125 -125
- package/skills/mindlore-query/SKILL.md +151 -151
- package/skills/mindlore-reflect/SKILL.md +141 -141
- package/skills/mindlore-stats/SKILL.md +106 -106
- package/templates/INDEX.md +14 -14
- package/templates/SCHEMA.md +292 -292
- package/templates/config.json +1 -1
- package/templates/extraction/article.md +15 -15
- package/templates/extraction/changelog.md +15 -15
- package/templates/extraction/default.md +15 -15
- package/templates/extraction/docs.md +15 -15
- package/templates/extraction/github-repo.md +17 -17
- package/dist/scripts/lib/daemon.d.ts +0 -16
- package/dist/scripts/lib/daemon.d.ts.map +0 -1
- package/dist/scripts/lib/daemon.js +0 -133
- package/dist/scripts/lib/daemon.js.map +0 -1
- package/dist/scripts/lib/embedding.d.ts +0 -5
- package/dist/scripts/lib/embedding.d.ts.map +0 -1
- package/dist/scripts/lib/embedding.js +0 -44
- package/dist/scripts/lib/embedding.js.map +0 -1
- package/dist/scripts/mindlore-daemon.d.ts +0 -2
- package/dist/scripts/mindlore-daemon.d.ts.map +0 -1
- package/dist/scripts/mindlore-daemon.js +0 -117
- package/dist/scripts/mindlore-daemon.js.map +0 -1
- package/dist/tests/daemon-integration.test.d.ts +0 -2
- package/dist/tests/daemon-integration.test.d.ts.map +0 -1
- package/dist/tests/daemon-integration.test.js +0 -37
- package/dist/tests/daemon-integration.test.js.map +0 -1
- package/dist/tests/daemon.test.d.ts +0 -2
- package/dist/tests/daemon.test.d.ts.map +0 -1
- package/dist/tests/daemon.test.js +0 -187
- package/dist/tests/daemon.test.js.map +0 -1
- package/dist/tests/embedding-hf-integration.test.d.ts +0 -2
- package/dist/tests/embedding-hf-integration.test.d.ts.map +0 -1
- package/dist/tests/embedding-hf-integration.test.js +0 -52
- package/dist/tests/embedding-hf-integration.test.js.map +0 -1
- package/dist/tests/embedding.test.d.ts +0 -6
- package/dist/tests/embedding.test.d.ts.map +0 -1
- package/dist/tests/embedding.test.js +0 -71
- package/dist/tests/embedding.test.js.map +0 -1
- package/dist/tests/sqlite-vec-v12.test.d.ts +0 -2
- package/dist/tests/sqlite-vec-v12.test.d.ts.map +0 -1
- package/dist/tests/sqlite-vec-v12.test.js +0 -72
- package/dist/tests/sqlite-vec-v12.test.js.map +0 -1
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* mindlore-model-router — PreToolUse (Agent) hook
|
|
5
|
-
* Overrides model for [mindlore:SKILL] marked Agent spawns.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const { findMindloreDir, readConfig, DEFAULT_MODELS, hookLog, withTelemetrySync } = require('./lib/mindlore-common.cjs');
|
|
10
|
-
|
|
11
|
-
const SKILL_KEYS = Object.keys(DEFAULT_MODELS).filter((k) => k !== 'default');
|
|
12
|
-
const MARKER_REGEX = new RegExp(`\\[mindlore:(${SKILL_KEYS.join('|')})\\]`);
|
|
13
|
-
|
|
14
|
-
function main() {
|
|
15
|
-
const mindloreDir = findMindloreDir();
|
|
16
|
-
if (!mindloreDir) return;
|
|
17
|
-
|
|
18
|
-
let input;
|
|
19
|
-
try {
|
|
20
|
-
const raw = fs.readFileSync(0, 'utf8').trim();
|
|
21
|
-
if (!raw) return;
|
|
22
|
-
input = JSON.parse(raw);
|
|
23
|
-
} catch (_err) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const toolName = input.tool_name || '';
|
|
28
|
-
if (toolName !== 'Agent') return;
|
|
29
|
-
|
|
30
|
-
const toolInput = input.tool_input || {};
|
|
31
|
-
const prompt = toolInput.prompt || '';
|
|
32
|
-
const match = prompt.match(MARKER_REGEX);
|
|
33
|
-
if (!match) return;
|
|
34
|
-
|
|
35
|
-
const skill = match[1];
|
|
36
|
-
|
|
37
|
-
// Resolve model: config.json → config default → hardcoded
|
|
38
|
-
const config = readConfig(mindloreDir);
|
|
39
|
-
const models = (config && config.models) || {};
|
|
40
|
-
const model = models[skill] || models.default || DEFAULT_MODELS[skill] || DEFAULT_MODELS.default;
|
|
41
|
-
|
|
42
|
-
const updatedInput = { ...toolInput, model: model };
|
|
43
|
-
|
|
44
|
-
const output = {
|
|
45
|
-
hookSpecificOutput: {
|
|
46
|
-
hookEventName: 'PreToolUse',
|
|
47
|
-
updatedInput: updatedInput,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
process.stdout.write(JSON.stringify(output));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
try { withTelemetrySync('mindlore-model-router', main); } catch (err) { hookLog('model-router', 'error', err?.message ?? String(err)); }
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* mindlore-model-router — PreToolUse (Agent) hook
|
|
5
|
+
* Overrides model for [mindlore:SKILL] marked Agent spawns.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const { findMindloreDir, readConfig, DEFAULT_MODELS, hookLog, withTelemetrySync } = require('./lib/mindlore-common.cjs');
|
|
10
|
+
|
|
11
|
+
const SKILL_KEYS = Object.keys(DEFAULT_MODELS).filter((k) => k !== 'default');
|
|
12
|
+
const MARKER_REGEX = new RegExp(`\\[mindlore:(${SKILL_KEYS.join('|')})\\]`);
|
|
13
|
+
|
|
14
|
+
function main() {
|
|
15
|
+
const mindloreDir = findMindloreDir();
|
|
16
|
+
if (!mindloreDir) return;
|
|
17
|
+
|
|
18
|
+
let input;
|
|
19
|
+
try {
|
|
20
|
+
const raw = fs.readFileSync(0, 'utf8').trim();
|
|
21
|
+
if (!raw) return;
|
|
22
|
+
input = JSON.parse(raw);
|
|
23
|
+
} catch (_err) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const toolName = input.tool_name || '';
|
|
28
|
+
if (toolName !== 'Agent') return;
|
|
29
|
+
|
|
30
|
+
const toolInput = input.tool_input || {};
|
|
31
|
+
const prompt = toolInput.prompt || '';
|
|
32
|
+
const match = prompt.match(MARKER_REGEX);
|
|
33
|
+
if (!match) return;
|
|
34
|
+
|
|
35
|
+
const skill = match[1];
|
|
36
|
+
|
|
37
|
+
// Resolve model: config.json → config default → hardcoded
|
|
38
|
+
const config = readConfig(mindloreDir);
|
|
39
|
+
const models = (config && config.models) || {};
|
|
40
|
+
const model = models[skill] || models.default || DEFAULT_MODELS[skill] || DEFAULT_MODELS.default;
|
|
41
|
+
|
|
42
|
+
const updatedInput = { ...toolInput, model: model };
|
|
43
|
+
|
|
44
|
+
const output = {
|
|
45
|
+
hookSpecificOutput: {
|
|
46
|
+
hookEventName: 'PreToolUse',
|
|
47
|
+
updatedInput: updatedInput,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
process.stdout.write(JSON.stringify(output));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try { withTelemetrySync('mindlore-model-router', main); } catch (err) { hookLog('model-router', 'error', err?.message ?? String(err)); }
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* mindlore-post-compact — PostCompact hook
|
|
6
|
-
*
|
|
7
|
-
* After context compaction, re-inject session context:
|
|
8
|
-
* 1. Read INDEX.md
|
|
9
|
-
* 2. Read latest delta
|
|
10
|
-
* 3. Inject via stdout (same as session-focus)
|
|
11
|
-
*
|
|
12
|
-
* This ensures the agent has knowledge context after compaction.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
const { findMindloreDir, getLatestDelta, readConfig, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
|
|
18
|
-
|
|
19
|
-
function main() {
|
|
20
|
-
const baseDir = findMindloreDir();
|
|
21
|
-
if (!baseDir) return;
|
|
22
|
-
|
|
23
|
-
const output = [];
|
|
24
|
-
|
|
25
|
-
// Re-inject INDEX.md
|
|
26
|
-
const indexPath = path.join(baseDir, 'INDEX.md');
|
|
27
|
-
if (fs.existsSync(indexPath)) {
|
|
28
|
-
const content = fs.readFileSync(indexPath, 'utf8').trim();
|
|
29
|
-
output.push(`[Mindlore INDEX (post-compact)]\n${content}`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const diaryDir = path.join(baseDir, 'diary');
|
|
33
|
-
|
|
34
|
-
const latestDelta = getLatestDelta(diaryDir);
|
|
35
|
-
if (latestDelta) {
|
|
36
|
-
const deltaContent = fs.readFileSync(latestDelta, 'utf8').trim();
|
|
37
|
-
const deltaName = path.basename(latestDelta);
|
|
38
|
-
output.push(`[Mindlore Delta (post-compact): ${deltaName}]\n${deltaContent}`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
const snapshots = fs.readdirSync(diaryDir)
|
|
43
|
-
.filter(f => f.startsWith('compaction-snapshot-'))
|
|
44
|
-
.sort();
|
|
45
|
-
if (snapshots.length > 0) {
|
|
46
|
-
const latestSnapshot = snapshots[snapshots.length - 1];
|
|
47
|
-
const snapshotContent = fs.readFileSync(
|
|
48
|
-
path.join(diaryDir, latestSnapshot), 'utf8'
|
|
49
|
-
).trim();
|
|
50
|
-
output.push(`[Mindlore Compaction Resume]\n${snapshotContent}`);
|
|
51
|
-
}
|
|
52
|
-
} catch (_err) { /* snapshot best-effort */ }
|
|
53
|
-
|
|
54
|
-
if (output.length > 0) {
|
|
55
|
-
const config = readConfig(baseDir);
|
|
56
|
-
const budgetConfig = config?.tokenBudget ?? {};
|
|
57
|
-
const maxInjectChars = (budgetConfig.sessionInject || 2000) * 4;
|
|
58
|
-
let joined = output.join('\n\n');
|
|
59
|
-
if (joined.length > maxInjectChars) {
|
|
60
|
-
joined = joined.slice(0, maxInjectChars) + '\n[...truncated by token budget]';
|
|
61
|
-
}
|
|
62
|
-
process.stdout.write(joined + '\n');
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
withTelemetry('mindlore-post-compact', main).catch(err => {
|
|
67
|
-
hookLog('mindlore-post-compact', 'error', err?.message ?? String(err));
|
|
68
|
-
process.exit(0);
|
|
69
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mindlore-post-compact — PostCompact hook
|
|
6
|
+
*
|
|
7
|
+
* After context compaction, re-inject session context:
|
|
8
|
+
* 1. Read INDEX.md
|
|
9
|
+
* 2. Read latest delta
|
|
10
|
+
* 3. Inject via stdout (same as session-focus)
|
|
11
|
+
*
|
|
12
|
+
* This ensures the agent has knowledge context after compaction.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { findMindloreDir, getLatestDelta, readConfig, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
|
|
18
|
+
|
|
19
|
+
function main() {
|
|
20
|
+
const baseDir = findMindloreDir();
|
|
21
|
+
if (!baseDir) return;
|
|
22
|
+
|
|
23
|
+
const output = [];
|
|
24
|
+
|
|
25
|
+
// Re-inject INDEX.md
|
|
26
|
+
const indexPath = path.join(baseDir, 'INDEX.md');
|
|
27
|
+
if (fs.existsSync(indexPath)) {
|
|
28
|
+
const content = fs.readFileSync(indexPath, 'utf8').trim();
|
|
29
|
+
output.push(`[Mindlore INDEX (post-compact)]\n${content}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const diaryDir = path.join(baseDir, 'diary');
|
|
33
|
+
|
|
34
|
+
const latestDelta = getLatestDelta(diaryDir);
|
|
35
|
+
if (latestDelta) {
|
|
36
|
+
const deltaContent = fs.readFileSync(latestDelta, 'utf8').trim();
|
|
37
|
+
const deltaName = path.basename(latestDelta);
|
|
38
|
+
output.push(`[Mindlore Delta (post-compact): ${deltaName}]\n${deltaContent}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const snapshots = fs.readdirSync(diaryDir)
|
|
43
|
+
.filter(f => f.startsWith('compaction-snapshot-'))
|
|
44
|
+
.sort();
|
|
45
|
+
if (snapshots.length > 0) {
|
|
46
|
+
const latestSnapshot = snapshots[snapshots.length - 1];
|
|
47
|
+
const snapshotContent = fs.readFileSync(
|
|
48
|
+
path.join(diaryDir, latestSnapshot), 'utf8'
|
|
49
|
+
).trim();
|
|
50
|
+
output.push(`[Mindlore Compaction Resume]\n${snapshotContent}`);
|
|
51
|
+
}
|
|
52
|
+
} catch (_err) { /* snapshot best-effort */ }
|
|
53
|
+
|
|
54
|
+
if (output.length > 0) {
|
|
55
|
+
const config = readConfig(baseDir);
|
|
56
|
+
const budgetConfig = config?.tokenBudget ?? {};
|
|
57
|
+
const maxInjectChars = (budgetConfig.sessionInject || 2000) * 4;
|
|
58
|
+
let joined = output.join('\n\n');
|
|
59
|
+
if (joined.length > maxInjectChars) {
|
|
60
|
+
joined = joined.slice(0, maxInjectChars) + '\n[...truncated by token budget]';
|
|
61
|
+
}
|
|
62
|
+
process.stdout.write(joined + '\n');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
withTelemetry('mindlore-post-compact', main).catch(err => {
|
|
67
|
+
hookLog('mindlore-post-compact', 'error', err?.message ?? String(err));
|
|
68
|
+
process.exit(0);
|
|
69
|
+
});
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* mindlore-post-read — PostToolUse hook (matcher: "Read")
|
|
6
|
-
*
|
|
7
|
-
* After a file is read, estimate its token count
|
|
8
|
-
* and store in _session-reads.json for the read-guard to reference.
|
|
9
|
-
*
|
|
10
|
-
* Outputs token estimate via additionalContext JSON.
|
|
11
|
-
* Also stores token info in _session-reads.json for read-guard.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const { findMindloreDir, getProjectName, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
|
|
17
|
-
|
|
18
|
-
const CODE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.rs', '.go', '.java', '.c', '.cpp', '.h', '.css', '.scss', '.sql', '.sh', '.yaml', '.yml', '.json', '.toml', '.xml', '.cjs', '.mjs']);
|
|
19
|
-
const PROSE_EXTS = new Set(['.md', '.txt', '.rst', '.adoc']);
|
|
20
|
-
|
|
21
|
-
function estimateTokens(charCount, ext) {
|
|
22
|
-
const ratio = CODE_EXTS.has(ext) ? 3.5 : PROSE_EXTS.has(ext) ? 4.0 : 3.75;
|
|
23
|
-
return Math.ceil(charCount / ratio);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function main() {
|
|
27
|
-
const baseDir = findMindloreDir();
|
|
28
|
-
if (!baseDir) return;
|
|
29
|
-
|
|
30
|
-
let input = '';
|
|
31
|
-
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
32
|
-
process.stdin.setEncoding('utf8');
|
|
33
|
-
process.stdin.on('error', () => process.exit(0));
|
|
34
|
-
process.stdin.on('data', chunk => input += chunk);
|
|
35
|
-
process.stdin.on('end', () => {
|
|
36
|
-
clearTimeout(stdinTimeout);
|
|
37
|
-
try {
|
|
38
|
-
const data = JSON.parse(input || '{}');
|
|
39
|
-
const toolInput = data.tool_input || {};
|
|
40
|
-
const toolOutput = data.tool_output || {};
|
|
41
|
-
|
|
42
|
-
const filePath = toolInput.file_path || toolInput.path || '';
|
|
43
|
-
if (!filePath) return process.exit(0);
|
|
44
|
-
|
|
45
|
-
// Skip .mindlore/ internals
|
|
46
|
-
const resolved = path.resolve(filePath);
|
|
47
|
-
if (resolved.startsWith(path.resolve(baseDir))) return process.exit(0);
|
|
48
|
-
|
|
49
|
-
// Get content length from tool output or read file
|
|
50
|
-
let charCount = 0;
|
|
51
|
-
if (toolOutput.content) {
|
|
52
|
-
charCount = typeof toolOutput.content === 'string'
|
|
53
|
-
? toolOutput.content.length
|
|
54
|
-
: JSON.stringify(toolOutput.content).length;
|
|
55
|
-
} else {
|
|
56
|
-
// Fallback: read file size
|
|
57
|
-
try {
|
|
58
|
-
const stat = fs.statSync(resolved);
|
|
59
|
-
charCount = stat.size;
|
|
60
|
-
} catch { return process.exit(0); }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (charCount === 0) return process.exit(0);
|
|
64
|
-
|
|
65
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
66
|
-
const tokens = estimateTokens(charCount, ext);
|
|
67
|
-
|
|
68
|
-
// Update _session-reads.json with token info
|
|
69
|
-
const diaryDir = path.join(baseDir, 'diary');
|
|
70
|
-
const readsPath = path.join(diaryDir, `_session-reads-${getProjectName()}.json`);
|
|
71
|
-
let reads = {};
|
|
72
|
-
if (fs.existsSync(readsPath)) {
|
|
73
|
-
try { reads = JSON.parse(fs.readFileSync(readsPath, 'utf8')); } catch { reads = {}; }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const normalizedPath = path.resolve(filePath);
|
|
77
|
-
const key = normalizedPath;
|
|
78
|
-
|
|
79
|
-
if (typeof reads[key] === 'number') {
|
|
80
|
-
// Upgrade from old format (just count) to new format (object)
|
|
81
|
-
reads[key] = { count: reads[key], tokens, chars: charCount };
|
|
82
|
-
} else if (reads[key] && typeof reads[key] === 'object') {
|
|
83
|
-
reads[key].tokens = tokens;
|
|
84
|
-
reads[key].chars = charCount;
|
|
85
|
-
} else {
|
|
86
|
-
reads[key] = { count: 1, tokens, chars: charCount };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
fs.writeFileSync(readsPath, JSON.stringify(reads, null, 2), 'utf8');
|
|
90
|
-
|
|
91
|
-
// Output token estimate to Claude via additionalContext
|
|
92
|
-
const basename = path.basename(filePath);
|
|
93
|
-
process.stdout.write(JSON.stringify({
|
|
94
|
-
hookSpecificOutput: {
|
|
95
|
-
hookEventName: 'PostToolUse',
|
|
96
|
-
additionalContext: `[Mindlore: ${basename} — ~${tokens} token (${charCount} char). Edit etmeyeceksen ctx_execute_file kullan.]`
|
|
97
|
-
}
|
|
98
|
-
}));
|
|
99
|
-
} catch {
|
|
100
|
-
// Silent fail
|
|
101
|
-
}
|
|
102
|
-
process.exit(0);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
withTelemetry('mindlore-post-read', main).catch(err => { hookLog('post-read', 'error', err?.message ?? String(err)); });
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mindlore-post-read — PostToolUse hook (matcher: "Read")
|
|
6
|
+
*
|
|
7
|
+
* After a file is read, estimate its token count
|
|
8
|
+
* and store in _session-reads.json for the read-guard to reference.
|
|
9
|
+
*
|
|
10
|
+
* Outputs token estimate via additionalContext JSON.
|
|
11
|
+
* Also stores token info in _session-reads.json for read-guard.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { findMindloreDir, getProjectName, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
|
|
17
|
+
|
|
18
|
+
const CODE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.rs', '.go', '.java', '.c', '.cpp', '.h', '.css', '.scss', '.sql', '.sh', '.yaml', '.yml', '.json', '.toml', '.xml', '.cjs', '.mjs']);
|
|
19
|
+
const PROSE_EXTS = new Set(['.md', '.txt', '.rst', '.adoc']);
|
|
20
|
+
|
|
21
|
+
function estimateTokens(charCount, ext) {
|
|
22
|
+
const ratio = CODE_EXTS.has(ext) ? 3.5 : PROSE_EXTS.has(ext) ? 4.0 : 3.75;
|
|
23
|
+
return Math.ceil(charCount / ratio);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function main() {
|
|
27
|
+
const baseDir = findMindloreDir();
|
|
28
|
+
if (!baseDir) return;
|
|
29
|
+
|
|
30
|
+
let input = '';
|
|
31
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
32
|
+
process.stdin.setEncoding('utf8');
|
|
33
|
+
process.stdin.on('error', () => process.exit(0));
|
|
34
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
35
|
+
process.stdin.on('end', () => {
|
|
36
|
+
clearTimeout(stdinTimeout);
|
|
37
|
+
try {
|
|
38
|
+
const data = JSON.parse(input || '{}');
|
|
39
|
+
const toolInput = data.tool_input || {};
|
|
40
|
+
const toolOutput = data.tool_output || {};
|
|
41
|
+
|
|
42
|
+
const filePath = toolInput.file_path || toolInput.path || '';
|
|
43
|
+
if (!filePath) return process.exit(0);
|
|
44
|
+
|
|
45
|
+
// Skip .mindlore/ internals
|
|
46
|
+
const resolved = path.resolve(filePath);
|
|
47
|
+
if (resolved.startsWith(path.resolve(baseDir))) return process.exit(0);
|
|
48
|
+
|
|
49
|
+
// Get content length from tool output or read file
|
|
50
|
+
let charCount = 0;
|
|
51
|
+
if (toolOutput.content) {
|
|
52
|
+
charCount = typeof toolOutput.content === 'string'
|
|
53
|
+
? toolOutput.content.length
|
|
54
|
+
: JSON.stringify(toolOutput.content).length;
|
|
55
|
+
} else {
|
|
56
|
+
// Fallback: read file size
|
|
57
|
+
try {
|
|
58
|
+
const stat = fs.statSync(resolved);
|
|
59
|
+
charCount = stat.size;
|
|
60
|
+
} catch { return process.exit(0); }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (charCount === 0) return process.exit(0);
|
|
64
|
+
|
|
65
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
66
|
+
const tokens = estimateTokens(charCount, ext);
|
|
67
|
+
|
|
68
|
+
// Update _session-reads.json with token info
|
|
69
|
+
const diaryDir = path.join(baseDir, 'diary');
|
|
70
|
+
const readsPath = path.join(diaryDir, `_session-reads-${getProjectName()}.json`);
|
|
71
|
+
let reads = {};
|
|
72
|
+
if (fs.existsSync(readsPath)) {
|
|
73
|
+
try { reads = JSON.parse(fs.readFileSync(readsPath, 'utf8')); } catch { reads = {}; }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const normalizedPath = path.resolve(filePath);
|
|
77
|
+
const key = normalizedPath;
|
|
78
|
+
|
|
79
|
+
if (typeof reads[key] === 'number') {
|
|
80
|
+
// Upgrade from old format (just count) to new format (object)
|
|
81
|
+
reads[key] = { count: reads[key], tokens, chars: charCount };
|
|
82
|
+
} else if (reads[key] && typeof reads[key] === 'object') {
|
|
83
|
+
reads[key].tokens = tokens;
|
|
84
|
+
reads[key].chars = charCount;
|
|
85
|
+
} else {
|
|
86
|
+
reads[key] = { count: 1, tokens, chars: charCount };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fs.writeFileSync(readsPath, JSON.stringify(reads, null, 2), 'utf8');
|
|
90
|
+
|
|
91
|
+
// Output token estimate to Claude via additionalContext
|
|
92
|
+
const basename = path.basename(filePath);
|
|
93
|
+
process.stdout.write(JSON.stringify({
|
|
94
|
+
hookSpecificOutput: {
|
|
95
|
+
hookEventName: 'PostToolUse',
|
|
96
|
+
additionalContext: `[Mindlore: ${basename} — ~${tokens} token (${charCount} char). Edit etmeyeceksen ctx_execute_file kullan.]`
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
} catch {
|
|
100
|
+
// Silent fail
|
|
101
|
+
}
|
|
102
|
+
process.exit(0);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
withTelemetry('mindlore-post-read', main).catch(err => { hookLog('post-read', 'error', err?.message ?? String(err)); });
|