codetree-claude 1.6.1 → 1.7.1
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 +9 -0
- package/dist/cli.js.map +1 -1
- package/dist/cloud/client.d.ts +28 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +34 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/commands.d.ts +3 -0
- package/dist/cloud/commands.d.ts.map +1 -0
- package/dist/cloud/commands.js +77 -0
- package/dist/cloud/commands.js.map +1 -0
- package/dist/cloud/rework.d.ts +24 -0
- package/dist/cloud/rework.d.ts.map +1 -0
- package/dist/cloud/rework.js +87 -0
- package/dist/cloud/rework.js.map +1 -0
- package/dist/cloud/state.d.ts +15 -0
- package/dist/cloud/state.d.ts.map +1 -0
- package/dist/cloud/state.js +59 -0
- package/dist/cloud/state.js.map +1 -0
- package/dist/cloud/transcript.d.ts +19 -0
- package/dist/cloud/transcript.d.ts.map +1 -0
- package/dist/cloud/transcript.js +49 -0
- package/dist/cloud/transcript.js.map +1 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -1
- package/dist/hook/score-prompt.d.ts +20 -0
- package/dist/hook/score-prompt.d.ts.map +1 -0
- package/dist/hook/score-prompt.js +281 -0
- package/dist/hook/score-prompt.js.map +1 -0
- package/dist/hook/stop.d.ts +11 -0
- package/dist/hook/stop.d.ts.map +1 -0
- package/dist/hook/stop.js +110 -0
- package/dist/hook/stop.js.map +1 -0
- package/dist/hook/user-prompt-submit.d.ts +10 -0
- package/dist/hook/user-prompt-submit.d.ts.map +1 -0
- package/dist/hook/user-prompt-submit.js +87 -0
- package/dist/hook/user-prompt-submit.js.map +1 -0
- package/dist/setup/install.d.ts.map +1 -1
- package/dist/setup/install.js +10 -0
- package/dist/setup/install.js.map +1 -1
- package/package.json +1 -1
package/dist/config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { resolve, join, dirname } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
const CacheConfigSchema = z.object({
|
|
5
6
|
memoryLimitMB: z.number().min(32).max(4096).default(256),
|
|
@@ -25,6 +26,26 @@ const TelemetryConfigSchema = z.object({
|
|
|
25
26
|
enabled: z.boolean().default(true),
|
|
26
27
|
statsFile: z.string().default(".codetree/stats.json"),
|
|
27
28
|
});
|
|
29
|
+
// CodeTree cloud telemetry (the team dashboard). OFF by default — when disabled,
|
|
30
|
+
// CodeTree opens zero sockets and behaves exactly as before. Secrets normally come
|
|
31
|
+
// from ~/.codetreerc.local.json (written by `codetree login`) or env, never committed.
|
|
32
|
+
const CloudConfigSchema = z.object({
|
|
33
|
+
enabled: z.boolean().default(false),
|
|
34
|
+
// Production cloud by default; overridden by ~/.codetreerc.local.json (written by
|
|
35
|
+
// `codetree login`), the CODETREE_CLOUD_URL env var, or a local dev base URL.
|
|
36
|
+
apiBaseUrl: z.string().default("https://codetree.electioncaffe.ai"),
|
|
37
|
+
apiKey: z.string().default(""), // machine key (tl_…); usually from the local secrets file
|
|
38
|
+
uploadIntervalMs: z.number().min(10_000).default(300_000), // 5 min flush cadence
|
|
39
|
+
batchSize: z.number().min(1).max(500).default(100),
|
|
40
|
+
capturePrompts: z.boolean().default(true), // write prompts/ locally + upload metadata
|
|
41
|
+
promptsDir: z.string().default("prompts"), // local prompt folder (req 8), gitignored
|
|
42
|
+
// Prompt scoring location. Default "local": score with THIS developer's own `claude` CLI and
|
|
43
|
+
// upload the result — ZERO server LLM cost (uses the dev's existing Claude subscription) and
|
|
44
|
+
// works out of the box with no org-side provider config. "server" = the cloud worker calls its
|
|
45
|
+
// configured LLM (costs the org API $) and requires a ProviderConfig; opt in via project config.
|
|
46
|
+
scoring: z.enum(["server", "local"]).default("local"),
|
|
47
|
+
scoringModel: z.string().default("haiku"), // model for local `claude -p` scoring (fast/cheap)
|
|
48
|
+
});
|
|
28
49
|
// Token-saving knobs for read / search / structure / session-start
|
|
29
50
|
const TokenSaveConfigSchema = z.object({
|
|
30
51
|
read: z.object({
|
|
@@ -59,8 +80,22 @@ const ConfigSchema = z.object({
|
|
|
59
80
|
watch: WatchConfigSchema.default({}),
|
|
60
81
|
symbols: SymbolsConfigSchema.default({}),
|
|
61
82
|
telemetry: TelemetryConfigSchema.default({}),
|
|
83
|
+
cloud: CloudConfigSchema.default({}),
|
|
62
84
|
tokenSave: TokenSaveConfigSchema,
|
|
63
85
|
});
|
|
86
|
+
// User-level secrets for the cloud connector (kept out of the repo).
|
|
87
|
+
export const CLOUD_LOCAL_FILE = join(homedir(), ".codetreerc.local.json");
|
|
88
|
+
export function readLocalCloud() {
|
|
89
|
+
if (!existsSync(CLOUD_LOCAL_FILE))
|
|
90
|
+
return {};
|
|
91
|
+
try {
|
|
92
|
+
const raw = JSON.parse(readFileSync(CLOUD_LOCAL_FILE, "utf-8"));
|
|
93
|
+
return raw.cloud ?? raw ?? {};
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
64
99
|
const CONFIG_FILENAMES = [".codetreerc.json", ".codetreerc", "codetree.config.json"];
|
|
65
100
|
/**
|
|
66
101
|
* Find the project root by walking up from startDir looking for config files or .git
|
|
@@ -111,6 +146,34 @@ export function loadConfig(projectRoot) {
|
|
|
111
146
|
config.projectRoot = resolve(root, config.projectRoot);
|
|
112
147
|
config.cache.dbPath = resolve(root, config.cache.dbPath);
|
|
113
148
|
config.telemetry.statsFile = resolve(root, config.telemetry.statsFile);
|
|
149
|
+
// Cloud secrets: ~/.codetreerc.local.json (from `codetree login`) and env override
|
|
150
|
+
// the project config. Precedence: env > local file > project config.
|
|
151
|
+
const local = readLocalCloud();
|
|
152
|
+
if (local.apiBaseUrl)
|
|
153
|
+
config.cloud.apiBaseUrl = local.apiBaseUrl;
|
|
154
|
+
if (local.apiKey)
|
|
155
|
+
config.cloud.apiKey = local.apiKey;
|
|
156
|
+
if (typeof local.enabled === "boolean")
|
|
157
|
+
config.cloud.enabled = local.enabled;
|
|
158
|
+
if (local.scoring)
|
|
159
|
+
config.cloud.scoring = local.scoring;
|
|
160
|
+
if (local.scoringModel)
|
|
161
|
+
config.cloud.scoringModel = local.scoringModel;
|
|
162
|
+
if (process.env.CODETREE_SCORING_MODE === "local" || process.env.CODETREE_SCORING_MODE === "server") {
|
|
163
|
+
config.cloud.scoring = process.env.CODETREE_SCORING_MODE;
|
|
164
|
+
}
|
|
165
|
+
if (process.env.CODETREE_CLOUD_URL)
|
|
166
|
+
config.cloud.apiBaseUrl = process.env.CODETREE_CLOUD_URL;
|
|
167
|
+
if (process.env.CODETREE_CLOUD_API_KEY)
|
|
168
|
+
config.cloud.apiKey = process.env.CODETREE_CLOUD_API_KEY;
|
|
169
|
+
if (process.env.CODETREE_CLOUD === "1")
|
|
170
|
+
config.cloud.enabled = true;
|
|
171
|
+
if (process.env.CODETREE_CLOUD === "0")
|
|
172
|
+
config.cloud.enabled = false;
|
|
173
|
+
// Hard fail-safe: never "enabled" without a key — guarantees cloud-off behaviour by default.
|
|
174
|
+
if (config.cloud.enabled && !config.cloud.apiKey)
|
|
175
|
+
config.cloud.enabled = false;
|
|
176
|
+
config.cloud.promptsDir = resolve(root, config.cloud.promptsDir);
|
|
114
177
|
return config;
|
|
115
178
|
}
|
|
116
179
|
// Normalize paths to forward slashes for cross-platform consistency
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeTree LOCAL prompt scorer (scoring="local") — runs DETACHED from the UserPromptSubmit
|
|
4
|
+
* hook so it never blocks the user. It scores the prompt with the developer's OWN `claude`
|
|
5
|
+
* CLI (their existing subscription → ZERO server-side LLM cost), then PATCHes the score onto
|
|
6
|
+
* the already-captured prompt (matched by sessionId + createdAt).
|
|
7
|
+
*
|
|
8
|
+
* R3 — CONTEXT-AWARE: Claude Code maintains the whole conversation in context, so a short
|
|
9
|
+
* follow-up like "option 2" is perfectly clear in the session. Scoring each prompt in
|
|
10
|
+
* isolation unfairly punished follow-ups. We now read the session transcript (passed by the
|
|
11
|
+
* hook as transcript_path), feed a trimmed window of recent turns to the scorer, and judge the
|
|
12
|
+
* latest prompt GIVEN that conversation. Bare acks/selections are flagged `trivial` (and skip
|
|
13
|
+
* the LLM entirely) so they're excluded from quality + coaching.
|
|
14
|
+
*
|
|
15
|
+
* Safety: `claude` is run in a NEUTRAL cwd (os.tmpdir → no project .claude hooks / .mcp.json
|
|
16
|
+
* loaded) AND with CODETREE_SCORING=1 so the scoring turn can never recurse into CodeTree's
|
|
17
|
+
* own hooks. Fail-open: any error → do nothing (the prompt is already captured, just unscored).
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=score-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score-prompt.d.ts","sourceRoot":"","sources":["../../src/hook/score-prompt.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeTree LOCAL prompt scorer (scoring="local") — runs DETACHED from the UserPromptSubmit
|
|
4
|
+
* hook so it never blocks the user. It scores the prompt with the developer's OWN `claude`
|
|
5
|
+
* CLI (their existing subscription → ZERO server-side LLM cost), then PATCHes the score onto
|
|
6
|
+
* the already-captured prompt (matched by sessionId + createdAt).
|
|
7
|
+
*
|
|
8
|
+
* R3 — CONTEXT-AWARE: Claude Code maintains the whole conversation in context, so a short
|
|
9
|
+
* follow-up like "option 2" is perfectly clear in the session. Scoring each prompt in
|
|
10
|
+
* isolation unfairly punished follow-ups. We now read the session transcript (passed by the
|
|
11
|
+
* hook as transcript_path), feed a trimmed window of recent turns to the scorer, and judge the
|
|
12
|
+
* latest prompt GIVEN that conversation. Bare acks/selections are flagged `trivial` (and skip
|
|
13
|
+
* the LLM entirely) so they're excluded from quality + coaching.
|
|
14
|
+
*
|
|
15
|
+
* Safety: `claude` is run in a NEUTRAL cwd (os.tmpdir → no project .claude hooks / .mcp.json
|
|
16
|
+
* loaded) AND with CODETREE_SCORING=1 so the scoring turn can never recurse into CodeTree's
|
|
17
|
+
* own hooks. Fail-open: any error → do nothing (the prompt is already captured, just unscored).
|
|
18
|
+
*/
|
|
19
|
+
import { readFileSync, unlinkSync, readdirSync, existsSync, appendFileSync } from "node:fs";
|
|
20
|
+
import { tmpdir, homedir } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { spawnSync } from "node:child_process";
|
|
23
|
+
// Lightweight debug log (set CODETREE_SCORE_DEBUG=0 to silence). Helps diagnose the
|
|
24
|
+
// detached scorer, whose stdout/stderr are otherwise discarded.
|
|
25
|
+
const LOG = join(homedir(), ".codetree-score.log");
|
|
26
|
+
const dbg = (m) => {
|
|
27
|
+
if (process.env.CODETREE_SCORE_DEBUG === "0")
|
|
28
|
+
return;
|
|
29
|
+
try {
|
|
30
|
+
appendFileSync(LOG, `[${new Date().toISOString()}] ${m}\n`);
|
|
31
|
+
}
|
|
32
|
+
catch { /* */ }
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Find an invokable `claude`. Many users have NO standalone CLI — Claude Code ships as the
|
|
36
|
+
* VS Code/Cursor extension which bundles a native binary. Order: explicit override → newest
|
|
37
|
+
* bundled extension binary → bare "claude" on PATH.
|
|
38
|
+
*/
|
|
39
|
+
function resolveClaude() {
|
|
40
|
+
if (process.env.CODETREE_CLAUDE_BIN)
|
|
41
|
+
return process.env.CODETREE_CLAUDE_BIN;
|
|
42
|
+
const exe = process.platform === "win32" ? "claude.exe" : "claude";
|
|
43
|
+
const roots = [".vscode/extensions", ".cursor/extensions", ".vscode-insiders/extensions", ".vscode-server/extensions"]
|
|
44
|
+
.map((r) => join(homedir(), ...r.split("/")));
|
|
45
|
+
const verOf = (d) => {
|
|
46
|
+
const m = d.match(/-(\d+)\.(\d+)\.(\d+)/);
|
|
47
|
+
return m ? Number(m[1]) * 1e6 + Number(m[2]) * 1e3 + Number(m[3]) : 0;
|
|
48
|
+
};
|
|
49
|
+
let best = "";
|
|
50
|
+
let bestVer = -1;
|
|
51
|
+
for (const root of roots) {
|
|
52
|
+
let dirs;
|
|
53
|
+
try {
|
|
54
|
+
dirs = readdirSync(root);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
for (const d of dirs) {
|
|
60
|
+
if (!d.startsWith("anthropic.claude-code-"))
|
|
61
|
+
continue;
|
|
62
|
+
const p = join(root, d, "resources", "native-binary", exe);
|
|
63
|
+
const v = verOf(d);
|
|
64
|
+
if (v > bestVer && existsSync(p)) {
|
|
65
|
+
bestVer = v;
|
|
66
|
+
best = p;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return best || "claude";
|
|
71
|
+
}
|
|
72
|
+
// ── Conversation context ────────────────────────────────────────────────────
|
|
73
|
+
const MAX_TURNS = 6; // recent turns fed to the scorer
|
|
74
|
+
const MAX_TURN_CHARS = 500; // per-turn cap
|
|
75
|
+
const MAX_CONTEXT_CHARS = 3000; // total context cap (keeps the scoring turn cheap/fast)
|
|
76
|
+
/** Pull readable text out of a transcript message's `content` (string OR content-block array). */
|
|
77
|
+
function msgText(content) {
|
|
78
|
+
if (typeof content === "string")
|
|
79
|
+
return content;
|
|
80
|
+
if (Array.isArray(content)) {
|
|
81
|
+
return content
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
.filter((b) => b && b.type === "text" && typeof b.text === "string")
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
.map((b) => b.text)
|
|
86
|
+
.join("\n");
|
|
87
|
+
}
|
|
88
|
+
return "";
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Read the last few user/assistant turns from the Claude Code transcript (JSONL), excluding the
|
|
92
|
+
* current prompt. Tool calls/results are skipped — only the actual dialogue is kept.
|
|
93
|
+
*/
|
|
94
|
+
function readContext(transcriptPath, currentText) {
|
|
95
|
+
if (!transcriptPath || !existsSync(transcriptPath))
|
|
96
|
+
return { context: "", priorTurns: 0 };
|
|
97
|
+
let raw;
|
|
98
|
+
try {
|
|
99
|
+
raw = readFileSync(transcriptPath, "utf-8");
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { context: "", priorTurns: 0 };
|
|
103
|
+
}
|
|
104
|
+
const turns = [];
|
|
105
|
+
for (const line of raw.split("\n")) {
|
|
106
|
+
const s = line.trim();
|
|
107
|
+
if (!s)
|
|
108
|
+
continue;
|
|
109
|
+
try {
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
const o = JSON.parse(s);
|
|
112
|
+
const role = o?.message?.role ?? o?.role;
|
|
113
|
+
if (role !== "user" && role !== "assistant")
|
|
114
|
+
continue;
|
|
115
|
+
const text = msgText(o?.message?.content ?? o?.content).trim();
|
|
116
|
+
if (!text)
|
|
117
|
+
continue; // pure tool_use / tool_result turns
|
|
118
|
+
turns.push({ role, text });
|
|
119
|
+
}
|
|
120
|
+
catch { /* skip malformed line */ }
|
|
121
|
+
}
|
|
122
|
+
// Drop the trailing entry if it's the current prompt (it lands in the transcript before we run).
|
|
123
|
+
while (turns.length && turns[turns.length - 1].role === "user" && turns[turns.length - 1].text === currentText.trim()) {
|
|
124
|
+
turns.pop();
|
|
125
|
+
}
|
|
126
|
+
if (turns.length === 0)
|
|
127
|
+
return { context: "", priorTurns: 0 };
|
|
128
|
+
const recent = turns.slice(-MAX_TURNS);
|
|
129
|
+
const lines = recent.map((t) => {
|
|
130
|
+
const who = t.role === "assistant" ? "Assistant" : "User";
|
|
131
|
+
const body = t.text.length > MAX_TURN_CHARS ? t.text.slice(0, MAX_TURN_CHARS) + "…" : t.text;
|
|
132
|
+
return `${who}: ${body}`;
|
|
133
|
+
});
|
|
134
|
+
let context = lines.join("\n");
|
|
135
|
+
if (context.length > MAX_CONTEXT_CHARS)
|
|
136
|
+
context = "…" + context.slice(context.length - MAX_CONTEXT_CHARS);
|
|
137
|
+
return { context, priorTurns: recent.length };
|
|
138
|
+
}
|
|
139
|
+
/** Bare acknowledgements / selections that carry nothing to coach (only treated as trivial in-thread). */
|
|
140
|
+
function isTrivialAck(text) {
|
|
141
|
+
const t = text.trim().toLowerCase().replace(/[.!?,]+$/, "");
|
|
142
|
+
if (!t)
|
|
143
|
+
return false;
|
|
144
|
+
if (t.length > 40)
|
|
145
|
+
return false;
|
|
146
|
+
if (/^#?\d+\)?$/.test(t))
|
|
147
|
+
return true; // "2", "#3", "1)"
|
|
148
|
+
if (/^option\s*\d+/.test(t) || /^number\s*\d+/.test(t) || /^the\s+\w+\s+one$/.test(t))
|
|
149
|
+
return true;
|
|
150
|
+
return /^(y|n|yes+|yep|yeah|ya|no+|nope|ok(ay)?|kk|sure|thanks?|thx|ty|thank you|go|go ahead|do it|continue|proceed|next|go on|please|pls|that one|this one|sounds good|lgtm|perfect|great|cool|fine|right|correct|exactly|agreed|approved)$/.test(t);
|
|
151
|
+
}
|
|
152
|
+
const RUBRIC = `You are a senior engineer coaching a developer on how they prompt AI coding tools.
|
|
153
|
+
You are given the recent CONVERSATION so far (reference only — do NOT score it) and then the LATEST
|
|
154
|
+
prompt. Score ONLY the latest prompt, judged as the next instruction GIVEN that conversation.
|
|
155
|
+
|
|
156
|
+
Rules:
|
|
157
|
+
- The AI already has the whole conversation in context. If the latest prompt is a clear continuation,
|
|
158
|
+
do NOT penalize it for omitting context already established above.
|
|
159
|
+
- "context" measures ONLY context the developer should have added that is NOT already in the
|
|
160
|
+
conversation and NOT inferable from it.
|
|
161
|
+
- followUp = true if the prompt depends on / continues the conversation above.
|
|
162
|
+
- trivial = true if it is a bare acknowledgement or selection with nothing to coach
|
|
163
|
+
("yes", "ok", "do it", "option 2", "go ahead"). If trivial: set all dims to 0, empty rewrite, no suggestions.
|
|
164
|
+
|
|
165
|
+
Return ONLY JSON, no prose, no markdown fences:
|
|
166
|
+
{"intent":"feature|bugfix|refactor|question|exploration|off_topic|continuation",
|
|
167
|
+
"followUp":true|false,"trivial":true|false,
|
|
168
|
+
"quality":{"score":0-100,"dims":{"clarity":0-25,"context":0-25,"specificity":0-25,"scope":0-25},"rationale":"one line on WHY this score, in context"},
|
|
169
|
+
"abusive":{"flag":true|false,"severity":"none|mild|severe"},
|
|
170
|
+
"rewrite":"a concrete improved version of THE LATEST prompt — keep their intent, add only what is genuinely missing given the conversation; one short paragraph (empty if trivial)",
|
|
171
|
+
"suggestions":["2-4 short actionable fixes specific to this prompt (omit if trivial)"]}
|
|
172
|
+
`;
|
|
173
|
+
function coerce(raw) {
|
|
174
|
+
const i = raw.indexOf("{");
|
|
175
|
+
const j = raw.lastIndexOf("}");
|
|
176
|
+
if (i < 0 || j <= i)
|
|
177
|
+
return null;
|
|
178
|
+
try {
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
180
|
+
const p = JSON.parse(raw.slice(i, j + 1));
|
|
181
|
+
const trivial = Boolean(p?.trivial);
|
|
182
|
+
return {
|
|
183
|
+
intent: String(p?.intent ?? "question"),
|
|
184
|
+
followUp: Boolean(p?.followUp),
|
|
185
|
+
trivial,
|
|
186
|
+
qualityScore: trivial ? null : Math.round(Number(p?.quality?.score ?? 0)) || 0,
|
|
187
|
+
qualityDims: trivial
|
|
188
|
+
? null
|
|
189
|
+
: {
|
|
190
|
+
clarity: Number(p?.quality?.dims?.clarity ?? 0),
|
|
191
|
+
context: Number(p?.quality?.dims?.context ?? 0),
|
|
192
|
+
specificity: Number(p?.quality?.dims?.specificity ?? 0),
|
|
193
|
+
scope: Number(p?.quality?.dims?.scope ?? 0),
|
|
194
|
+
},
|
|
195
|
+
rationale: String(p?.quality?.rationale ?? ""),
|
|
196
|
+
abusiveFlag: Boolean(p?.abusive?.flag),
|
|
197
|
+
abusiveSeverity: String(p?.abusive?.severity ?? "none"),
|
|
198
|
+
rewrite: trivial ? "" : String(p?.rewrite ?? ""),
|
|
199
|
+
suggestions: trivial ? [] : Array.isArray(p?.suggestions) ? p.suggestions.map((s) => String(s)).slice(0, 5) : [],
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async function postScore(q, payload) {
|
|
207
|
+
try {
|
|
208
|
+
const res = await fetch(`${q.apiBaseUrl.replace(/\/+$/, "")}/v1/prompts/score`, {
|
|
209
|
+
method: "POST",
|
|
210
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${q.apiKey}` },
|
|
211
|
+
body: JSON.stringify({ sessionId: q.sessionId, createdAt: q.createdAt, ...payload }),
|
|
212
|
+
});
|
|
213
|
+
dbg(`posted score (trivial=${payload.trivial} followUp=${payload.followUp}) → ${res.status}`);
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
dbg(`post failed: ${e.message}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async function main() {
|
|
220
|
+
const qfile = process.argv[2];
|
|
221
|
+
if (!qfile)
|
|
222
|
+
return;
|
|
223
|
+
let q;
|
|
224
|
+
try {
|
|
225
|
+
q = JSON.parse(readFileSync(qfile, "utf-8"));
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
unlinkSync(qfile);
|
|
232
|
+
}
|
|
233
|
+
catch { /* best-effort */ }
|
|
234
|
+
if (!q.text || !q.apiKey) {
|
|
235
|
+
dbg("no text/apiKey in queue");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Conversation context (so follow-ups are judged fairly).
|
|
239
|
+
const { context, priorTurns } = readContext(q.transcriptPath, q.text);
|
|
240
|
+
// Fast path: an obvious ack/selection inside an ongoing thread carries nothing to coach.
|
|
241
|
+
// Flag it trivial WITHOUT spending an LLM turn.
|
|
242
|
+
if (priorTurns > 0 && isTrivialAck(q.text)) {
|
|
243
|
+
dbg(`trivial ack (fast path) session=${q.sessionId}`);
|
|
244
|
+
await postScore(q, { intent: "continuation", followUp: true, trivial: true });
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
let score = null;
|
|
248
|
+
try {
|
|
249
|
+
const claude = resolveClaude();
|
|
250
|
+
const useShell = process.platform === "win32" && !/[\\/]/.test(claude); // only for a bare "claude"
|
|
251
|
+
const userMsg = context
|
|
252
|
+
? `${RUBRIC}\n=== CONVERSATION SO FAR (context only) ===\n${context}\n=== LATEST PROMPT (score this) ===\n${q.text}`
|
|
253
|
+
: `${RUBRIC}\n=== PROMPT (no prior context; score standalone) ===\n${q.text}`;
|
|
254
|
+
dbg(`scoring session=${q.sessionId} via ${claude} (model ${q.scoringModel}, ${priorTurns} ctx turns)`);
|
|
255
|
+
const r = spawnSync(claude, ["-p", "--model", q.scoringModel || "haiku", userMsg], {
|
|
256
|
+
cwd: tmpdir(), // neutral: no project .claude hooks / .mcp.json
|
|
257
|
+
env: { ...process.env, CODETREE_SCORING: "1" }, // guard against hook recursion
|
|
258
|
+
encoding: "utf-8",
|
|
259
|
+
timeout: 120_000,
|
|
260
|
+
shell: useShell,
|
|
261
|
+
windowsHide: true, // no flashing console window
|
|
262
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
263
|
+
});
|
|
264
|
+
dbg(`claude status=${r.status} err=${r.error?.message ?? ""} stdoutLen=${r.stdout?.length ?? 0}`);
|
|
265
|
+
if (r.status === 0 && r.stdout)
|
|
266
|
+
score = coerce(r.stdout);
|
|
267
|
+
if (!score)
|
|
268
|
+
dbg(`could not parse score; stdout head: ${(r.stdout ?? "").slice(0, 120)}`);
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
dbg(`claude spawn threw: ${e.message}`);
|
|
272
|
+
}
|
|
273
|
+
if (!score)
|
|
274
|
+
return; // prompt is already captured (unscored) by the hook; nothing to attach
|
|
275
|
+
// The model didn't see prior turns? Then it can't be a follow-up. Trust context presence.
|
|
276
|
+
if (priorTurns === 0)
|
|
277
|
+
score.followUp = false;
|
|
278
|
+
await postScore(q, score);
|
|
279
|
+
}
|
|
280
|
+
main().catch(() => undefined).finally(() => process.exit(0));
|
|
281
|
+
//# sourceMappingURL=score-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score-prompt.js","sourceRoot":"","sources":["../../src/hook/score-prompt.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5F,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,oFAAoF;AACpF,gEAAgE;AAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC;AACnD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO;IACrD,IAAI,CAAC;QAAC,cAAc,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF;;;;GAIG;AACH,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAC5E,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnE,MAAM,KAAK,GAAG,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,2BAA2B,CAAC;SACnH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC;IACF,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC;YAAC,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,SAAS;QAAC,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,wBAAwB,CAAC;gBAAE,SAAS;YACtD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,GAAG,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,OAAO,GAAG,CAAC,CAAC;gBAAC,IAAI,GAAG,CAAC,CAAC;YAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,IAAI,IAAI,QAAQ,CAAC;AAC1B,CAAC;AAYD,+EAA+E;AAC/E,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,iCAAiC;AACtD,MAAM,cAAc,GAAG,GAAG,CAAC,CAAC,eAAe;AAC3C,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAAC,wDAAwD;AAExF,kGAAkG;AAClG,SAAS,OAAO,CAAC,OAAgB;IAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO;YACZ,8DAA8D;aAC7D,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;YACzE,8DAA8D;aAC7D,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAc,CAAC;aACjC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,cAAkC,EAAE,WAAmB;IAC1E,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC1F,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QAAC,GAAG,GAAG,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAAC,CAAC;IAErG,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,CAAC;YACH,8DAA8D;YAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAQ,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC;YACzC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW;gBAAE,SAAS;YACtD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,CAAC,IAAI;gBAAE,SAAS,CAAC,oCAAoC;YACzD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;IACvC,CAAC;IAED,iGAAiG;IACjG,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACtH,KAAK,CAAC,GAAG,EAAE,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAE9D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1D,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7F,OAAO,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,MAAM,GAAG,iBAAiB;QAAE,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;IAC1G,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,0GAA0G;AAC1G,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;IACzD,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnG,OAAO,sOAAsO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxP,CAAC;AAeD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;CAoBd,CAAC;AAEF,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAQ,CAAC;QACjD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,UAAU,CAAC;YACvC,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC;YAC9B,OAAO;YACP,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9E,WAAW,EAAE,OAAO;gBAClB,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC;oBACE,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC;oBAC/C,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC;oBAC/C,WAAW,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC,CAAC;oBACvD,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;iBAC5C;YACL,SAAS,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;YAC9C,WAAW,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC;YACtC,eAAe,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM,CAAC;YACvD,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;YAChD,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;SAC1H,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,CAAQ,EAAE,OAAqB;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,EAAE;YAC9E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE;YACpF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC;SACrF,CAAC,CAAC;QACH,GAAG,CAAC,yBAAyB,OAAO,CAAC,OAAO,aAAa,OAAO,CAAC,QAAQ,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAChG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,gBAAiB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,IAAI,CAAQ,CAAC;IACb,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAU,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACtD,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAErE,0DAA0D;IAC1D,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAEtE,yFAAyF;IACzF,gDAAgD;IAChD,IAAI,UAAU,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,mCAAmC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QACtD,MAAM,SAAS,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IAED,IAAI,KAAK,GAAwB,IAAI,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,2BAA2B;QACnG,MAAM,OAAO,GAAG,OAAO;YACrB,CAAC,CAAC,GAAG,MAAM,iDAAiD,OAAO,yCAAyC,CAAC,CAAC,IAAI,EAAE;YACpH,CAAC,CAAC,GAAG,MAAM,0DAA0D,CAAC,CAAC,IAAI,EAAE,CAAC;QAChF,GAAG,CAAC,mBAAmB,CAAC,CAAC,SAAS,QAAQ,MAAM,WAAW,CAAC,CAAC,YAAY,KAAK,UAAU,aAAa,CAAC,CAAC;QACvG,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,YAAY,IAAI,OAAO,EAAE,OAAO,CAAC,EAAE;YACjF,GAAG,EAAE,MAAM,EAAE,EAAE,gDAAgD;YAC/D,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,EAAE,+BAA+B;YAC/E,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI,EAAE,6BAA6B;YAChD,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,iBAAiB,CAAC,CAAC,MAAM,QAAS,CAAC,CAAC,KAA2B,EAAE,OAAO,IAAI,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;QACzH,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK;YAAE,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,uBAAwB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,uEAAuE;IAE3F,0FAA0F;IAC1F,IAAI,UAAU,KAAK,CAAC;QAAE,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;IAC7C,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeTree Stop Hook — cloud telemetry (OFF unless `codetree login` enabled cloud).
|
|
4
|
+
*
|
|
5
|
+
* Fires when Claude finishes a response. Parses the transcript for REAL token usage
|
|
6
|
+
* (message.usage) → one event per assistant turn, merges CodeTree's own savings delta
|
|
7
|
+
* (baseline-anchored: full-read counterfactual) as a savings event, and uploads to the
|
|
8
|
+
* cloud. Offline-resilient (outbox) and fail-open: any error → exit 0, never blocks Claude.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=stop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/hook/stop.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeTree Stop Hook — cloud telemetry (OFF unless `codetree login` enabled cloud).
|
|
4
|
+
*
|
|
5
|
+
* Fires when Claude finishes a response. Parses the transcript for REAL token usage
|
|
6
|
+
* (message.usage) → one event per assistant turn, merges CodeTree's own savings delta
|
|
7
|
+
* (baseline-anchored: full-read counterfactual) as a savings event, and uploads to the
|
|
8
|
+
* cloud. Offline-resilient (outbox) and fail-open: any error → exit 0, never blocks Claude.
|
|
9
|
+
*/
|
|
10
|
+
import { basename } from "node:path";
|
|
11
|
+
import { loadConfig } from "../config.js";
|
|
12
|
+
import { findIpcPort } from "../utils.js";
|
|
13
|
+
import { queryIpc } from "./hook-client.js";
|
|
14
|
+
import { CloudClient } from "../cloud/client.js";
|
|
15
|
+
import { parseTranscript } from "../cloud/transcript.js";
|
|
16
|
+
import { detectRework } from "../cloud/rework.js";
|
|
17
|
+
import { readState, writeState, readOutbox, writeOutbox } from "../cloud/state.js";
|
|
18
|
+
const num = (v) => (typeof v === "number" && isFinite(v) ? v : 0);
|
|
19
|
+
async function main() {
|
|
20
|
+
let raw = "";
|
|
21
|
+
for await (const chunk of process.stdin)
|
|
22
|
+
raw += chunk;
|
|
23
|
+
let input;
|
|
24
|
+
try {
|
|
25
|
+
input = JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
const { session_id, transcript_path, cwd } = input;
|
|
31
|
+
if (!cwd || !session_id)
|
|
32
|
+
process.exit(0);
|
|
33
|
+
if (process.env.CODETREE_SCORING)
|
|
34
|
+
process.exit(0); // the local scorer's own claude turn → don't recurse
|
|
35
|
+
const config = loadConfig(cwd);
|
|
36
|
+
if (!config.cloud.enabled || !config.cloud.apiKey)
|
|
37
|
+
process.exit(0); // cloud off → zero work
|
|
38
|
+
const root = config.projectRoot;
|
|
39
|
+
const project = basename(root);
|
|
40
|
+
const state = readState(root);
|
|
41
|
+
const events = [];
|
|
42
|
+
// 1) Real consumption — one event per new assistant turn (idempotent on message id).
|
|
43
|
+
if (transcript_path) {
|
|
44
|
+
const sess = state.sessions[session_id] ?? { lines: 0 };
|
|
45
|
+
const { events: turns, totalLines } = parseTranscript(transcript_path, sess.lines);
|
|
46
|
+
const rework = detectRework(transcript_path); // heuristic: re-edit churn + error→fix loops
|
|
47
|
+
for (const t of turns) {
|
|
48
|
+
const rw = rework[t.eventId];
|
|
49
|
+
events.push({
|
|
50
|
+
eventId: t.eventId, time: t.time, sessionId: session_id, model: t.model, project,
|
|
51
|
+
tokensInput: t.tokensInput, tokensOutput: t.tokensOutput,
|
|
52
|
+
tokensCacheRead: t.tokensCacheRead, tokensCacheCreation: t.tokensCacheCreation,
|
|
53
|
+
tokensSaved: 0, reworkTurn: rw?.reworkTurn ?? false, reworkTokens: rw?.reworkTokens ?? 0,
|
|
54
|
+
tool: "claude-code",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
state.sessions[session_id] = { lines: totalLines };
|
|
58
|
+
}
|
|
59
|
+
// 2) Savings — delta of CodeTree's cumulative credit (baseline = full-read counterfactual)
|
|
60
|
+
// since last upload → one savings event (model carried so the cloud can price it).
|
|
61
|
+
const port = findIpcPort(cwd);
|
|
62
|
+
if (port) {
|
|
63
|
+
const stats = (await queryIpc(port, "/stats", 150));
|
|
64
|
+
const cumSaved = num(stats?.estimatedTokensSaved ?? stats?.tokensSaved);
|
|
65
|
+
const cumHits = num(stats?.cacheHits);
|
|
66
|
+
const cumMisses = num(stats?.cacheMisses);
|
|
67
|
+
// The IPC server holds these counters IN MEMORY and resets them to 0 every time it restarts
|
|
68
|
+
// (each new Claude session spawns a fresh server). Our cursors persist on disk, so after a
|
|
69
|
+
// restart cum* < cursor — a classic monotonic-counter reset. Detect it and rebase the cursor
|
|
70
|
+
// to 0, otherwise savedDelta stays 0 forever and savings never upload again post-restart.
|
|
71
|
+
if (cumSaved < (state.savingsCursor || 0))
|
|
72
|
+
state.savingsCursor = 0;
|
|
73
|
+
if (cumHits < (state.hitsCursor || 0))
|
|
74
|
+
state.hitsCursor = 0;
|
|
75
|
+
if (cumMisses < (state.missesCursor || 0))
|
|
76
|
+
state.missesCursor = 0;
|
|
77
|
+
const savedDelta = Math.max(0, cumSaved - (state.savingsCursor || 0));
|
|
78
|
+
const hitsDelta = Math.max(0, cumHits - (state.hitsCursor || 0));
|
|
79
|
+
const missesDelta = Math.max(0, cumMisses - (state.missesCursor || 0));
|
|
80
|
+
if (savedDelta > 0 || hitsDelta > 0 || missesDelta > 0) {
|
|
81
|
+
const lastModel = events.length ? events[events.length - 1].model : "";
|
|
82
|
+
events.push({
|
|
83
|
+
eventId: `${session_id}:sav:${cumSaved}:${cumHits}:${cumMisses}`, time: new Date().toISOString(),
|
|
84
|
+
sessionId: session_id, model: lastModel || null, project,
|
|
85
|
+
tokensInput: 0, tokensOutput: 0, tokensSaved: savedDelta,
|
|
86
|
+
cacheHits: hitsDelta, cacheMisses: missesDelta, saveMethod: "mixed", tool: "codetree",
|
|
87
|
+
});
|
|
88
|
+
state.savingsCursor = cumSaved;
|
|
89
|
+
state.hitsCursor = cumHits;
|
|
90
|
+
state.missesCursor = cumMisses;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 3) Upload (outbox-first so a prior offline batch flushes too). Cursors already advanced;
|
|
94
|
+
// failures persist in the outbox and retry next turn — idempotent event ids prevent dupes.
|
|
95
|
+
const batch = [...readOutbox(root, "events"), ...events];
|
|
96
|
+
if (batch.length) {
|
|
97
|
+
const client = new CloudClient(config.cloud.apiBaseUrl, config.cloud.apiKey);
|
|
98
|
+
try {
|
|
99
|
+
await client.uploadEvents(batch);
|
|
100
|
+
writeOutbox(root, "events", []);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
writeOutbox(root, "events", batch);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
writeState(root, state);
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
main().catch(() => process.exit(0));
|
|
110
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/hook/stop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeTree UserPromptSubmit Hook — cloud telemetry (OFF unless cloud enabled).
|
|
4
|
+
*
|
|
5
|
+
* Fires when the user submits a prompt. Writes the prompt to the local prompts/ folder
|
|
6
|
+
* (requirement 8; self-gitignored) and uploads metadata to the cloud (which redacts +
|
|
7
|
+
* scores it). Offline-resilient (outbox) and fail-open: any error → exit 0, never blocks.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=user-prompt-submit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-prompt-submit.d.ts","sourceRoot":"","sources":["../../src/hook/user-prompt-submit.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}
|