braintracker 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/braintracker.js
CHANGED
|
@@ -10,6 +10,8 @@ const PRE_CMD = `node ${path.join(DEST_HOOKS, 'pre_skill.js')}`;
|
|
|
10
10
|
const POST_CMD = `node ${path.join(DEST_HOOKS, 'post_skill.js')}`;
|
|
11
11
|
const PRE_PROMPT_CMD = `node ${path.join(DEST_HOOKS, 'pre_prompt.js')}`;
|
|
12
12
|
const POST_PROMPT_CMD = `node ${path.join(DEST_HOOKS, 'post_prompt.js')}`;
|
|
13
|
+
const PRE_TURN_CMD = `node ${path.join(DEST_HOOKS, 'pre_turn.js')}`;
|
|
14
|
+
const POST_TURN_CMD = `node ${path.join(DEST_HOOKS, 'post_turn.js')}`;
|
|
13
15
|
|
|
14
16
|
function readSettings() {
|
|
15
17
|
try { return JSON.parse(fs.readFileSync(SETTINGS, 'utf8')); } catch { return {}; }
|
|
@@ -44,7 +46,7 @@ function removeHook(arr, command) {
|
|
|
44
46
|
function install() {
|
|
45
47
|
const SRC_HOOKS = path.join(__dirname, '..', 'braintracker', 'hooks');
|
|
46
48
|
fs.mkdirSync(DEST_HOOKS, { recursive: true });
|
|
47
|
-
for (const file of ['pre_skill.js', 'post_skill.js', 'pre_prompt.js', 'post_prompt.js']) {
|
|
49
|
+
for (const file of ['pre_skill.js', 'post_skill.js', 'pre_prompt.js', 'post_prompt.js', 'pre_turn.js', 'post_turn.js']) {
|
|
48
50
|
fs.copyFileSync(path.join(SRC_HOOKS, file), path.join(DEST_HOOKS, file));
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -57,7 +59,9 @@ function install() {
|
|
|
57
59
|
addHook(settings.hooks.PreToolUse, 'Skill', PRE_CMD);
|
|
58
60
|
addHook(settings.hooks.PostToolUse, 'Skill', POST_CMD);
|
|
59
61
|
addHook(settings.hooks.UserPromptSubmit, null, PRE_PROMPT_CMD);
|
|
62
|
+
addHook(settings.hooks.UserPromptSubmit, null, PRE_TURN_CMD);
|
|
60
63
|
addHook(settings.hooks.Stop, null, POST_PROMPT_CMD);
|
|
64
|
+
addHook(settings.hooks.Stop, null, POST_TURN_CMD);
|
|
61
65
|
writeSettings(settings);
|
|
62
66
|
|
|
63
67
|
console.log('braintracker installed.');
|
|
@@ -72,7 +76,9 @@ function uninstall() {
|
|
|
72
76
|
settings.hooks.PreToolUse = removeHook(settings.hooks.PreToolUse, PRE_CMD);
|
|
73
77
|
settings.hooks.PostToolUse = removeHook(settings.hooks.PostToolUse, POST_CMD);
|
|
74
78
|
settings.hooks.UserPromptSubmit = removeHook(settings.hooks.UserPromptSubmit, PRE_PROMPT_CMD);
|
|
79
|
+
settings.hooks.UserPromptSubmit = removeHook(settings.hooks.UserPromptSubmit, PRE_TURN_CMD);
|
|
75
80
|
settings.hooks.Stop = removeHook(settings.hooks.Stop, POST_PROMPT_CMD);
|
|
81
|
+
settings.hooks.Stop = removeHook(settings.hooks.Stop, POST_TURN_CMD);
|
|
76
82
|
}
|
|
77
83
|
writeSettings(settings);
|
|
78
84
|
|
|
@@ -85,7 +91,9 @@ function disable() {
|
|
|
85
91
|
settings.hooks.PreToolUse = removeHook(settings.hooks.PreToolUse, PRE_CMD);
|
|
86
92
|
settings.hooks.PostToolUse = removeHook(settings.hooks.PostToolUse, POST_CMD);
|
|
87
93
|
settings.hooks.UserPromptSubmit = removeHook(settings.hooks.UserPromptSubmit, PRE_PROMPT_CMD);
|
|
94
|
+
settings.hooks.UserPromptSubmit = removeHook(settings.hooks.UserPromptSubmit, PRE_TURN_CMD);
|
|
88
95
|
settings.hooks.Stop = removeHook(settings.hooks.Stop, POST_PROMPT_CMD);
|
|
96
|
+
settings.hooks.Stop = removeHook(settings.hooks.Stop, POST_TURN_CMD);
|
|
89
97
|
}
|
|
90
98
|
writeSettings(settings);
|
|
91
99
|
console.log('braintracker disabled. Hook files kept. Run "npx braintracker enable" to re-enable.');
|
|
@@ -106,7 +114,9 @@ function enable() {
|
|
|
106
114
|
addHook(settings.hooks.PreToolUse, 'Skill', PRE_CMD);
|
|
107
115
|
addHook(settings.hooks.PostToolUse, 'Skill', POST_CMD);
|
|
108
116
|
addHook(settings.hooks.UserPromptSubmit, null, PRE_PROMPT_CMD);
|
|
117
|
+
addHook(settings.hooks.UserPromptSubmit, null, PRE_TURN_CMD);
|
|
109
118
|
addHook(settings.hooks.Stop, null, POST_PROMPT_CMD);
|
|
119
|
+
addHook(settings.hooks.Stop, null, POST_TURN_CMD);
|
|
110
120
|
writeSettings(settings);
|
|
111
121
|
|
|
112
122
|
console.log('braintracker enabled.');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
let raw = '';
|
|
7
|
+
process.stdin.on('data', chunk => (raw += chunk));
|
|
8
|
+
process.stdin.on('end', () => {
|
|
9
|
+
let payload;
|
|
10
|
+
try { payload = JSON.parse(raw); } catch { process.exit(0); }
|
|
11
|
+
|
|
12
|
+
const sessionId = payload.session_id;
|
|
13
|
+
const prj = path.basename(process.cwd());
|
|
14
|
+
const cacheDir = path.join(os.homedir(), '.claude', 'plugin', 'cache', 'braintracker', prj);
|
|
15
|
+
const preFile = path.join(cacheDir, `${sessionId}.turn.pre.json`);
|
|
16
|
+
|
|
17
|
+
let preData;
|
|
18
|
+
try { preData = JSON.parse(fs.readFileSync(preFile, 'utf8')); } catch { process.exit(0); }
|
|
19
|
+
|
|
20
|
+
const transcript = payload.transcript || [];
|
|
21
|
+
const lastAssistant = [...transcript].reverse().find(m => m.role === 'assistant');
|
|
22
|
+
let assistantResponse = '';
|
|
23
|
+
if (lastAssistant) {
|
|
24
|
+
const c = lastAssistant.content;
|
|
25
|
+
if (typeof c === 'string') {
|
|
26
|
+
assistantResponse = c;
|
|
27
|
+
} else if (Array.isArray(c)) {
|
|
28
|
+
assistantResponse = c.filter(b => b.type === 'text').map(b => b.text).join('');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const entry = {
|
|
33
|
+
type: 'conversation_turn',
|
|
34
|
+
session_id: sessionId,
|
|
35
|
+
user_prompt: preData.prompt,
|
|
36
|
+
assistant_response: assistantResponse,
|
|
37
|
+
started_at: new Date(preData.start_time).toISOString(),
|
|
38
|
+
duration_seconds: (Date.now() - preData.start_time) / 1000,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const logFile = path.join(cacheDir, `${sessionId}.jsonl`);
|
|
42
|
+
fs.appendFileSync(logFile, JSON.stringify(entry) + '\n');
|
|
43
|
+
fs.unlinkSync(preFile);
|
|
44
|
+
|
|
45
|
+
process.exit(0);
|
|
46
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
let raw = '';
|
|
7
|
+
process.stdin.on('data', chunk => (raw += chunk));
|
|
8
|
+
process.stdin.on('end', () => {
|
|
9
|
+
let payload;
|
|
10
|
+
try { payload = JSON.parse(raw); } catch { process.exit(0); }
|
|
11
|
+
|
|
12
|
+
const sessionId = payload.session_id;
|
|
13
|
+
const prompt = (payload.prompt || '').trim();
|
|
14
|
+
const prj = path.basename(process.cwd());
|
|
15
|
+
const cacheDir = path.join(os.homedir(), '.claude', 'plugin', 'cache', 'braintracker', prj);
|
|
16
|
+
|
|
17
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
18
|
+
|
|
19
|
+
const preFile = path.join(cacheDir, `${sessionId}.turn.pre.json`);
|
|
20
|
+
fs.writeFileSync(preFile, JSON.stringify({
|
|
21
|
+
session_id: sessionId,
|
|
22
|
+
prompt,
|
|
23
|
+
start_time: Date.now(),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
process.exit(0);
|
|
27
|
+
});
|