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.
Files changed (42) hide show
  1. package/dist/cli.js +9 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cloud/client.d.ts +28 -0
  4. package/dist/cloud/client.d.ts.map +1 -0
  5. package/dist/cloud/client.js +34 -0
  6. package/dist/cloud/client.js.map +1 -0
  7. package/dist/cloud/commands.d.ts +3 -0
  8. package/dist/cloud/commands.d.ts.map +1 -0
  9. package/dist/cloud/commands.js +77 -0
  10. package/dist/cloud/commands.js.map +1 -0
  11. package/dist/cloud/rework.d.ts +24 -0
  12. package/dist/cloud/rework.d.ts.map +1 -0
  13. package/dist/cloud/rework.js +87 -0
  14. package/dist/cloud/rework.js.map +1 -0
  15. package/dist/cloud/state.d.ts +15 -0
  16. package/dist/cloud/state.d.ts.map +1 -0
  17. package/dist/cloud/state.js +59 -0
  18. package/dist/cloud/state.js.map +1 -0
  19. package/dist/cloud/transcript.d.ts +19 -0
  20. package/dist/cloud/transcript.d.ts.map +1 -0
  21. package/dist/cloud/transcript.js +49 -0
  22. package/dist/cloud/transcript.js.map +1 -0
  23. package/dist/config.d.ts +62 -0
  24. package/dist/config.d.ts.map +1 -1
  25. package/dist/config.js +63 -0
  26. package/dist/config.js.map +1 -1
  27. package/dist/hook/score-prompt.d.ts +20 -0
  28. package/dist/hook/score-prompt.d.ts.map +1 -0
  29. package/dist/hook/score-prompt.js +281 -0
  30. package/dist/hook/score-prompt.js.map +1 -0
  31. package/dist/hook/stop.d.ts +11 -0
  32. package/dist/hook/stop.d.ts.map +1 -0
  33. package/dist/hook/stop.js +110 -0
  34. package/dist/hook/stop.js.map +1 -0
  35. package/dist/hook/user-prompt-submit.d.ts +10 -0
  36. package/dist/hook/user-prompt-submit.d.ts.map +1 -0
  37. package/dist/hook/user-prompt-submit.js +87 -0
  38. package/dist/hook/user-prompt-submit.js.map +1 -0
  39. package/dist/setup/install.d.ts.map +1 -1
  40. package/dist/setup/install.js +10 -0
  41. package/dist/setup/install.js.map +1 -1
  42. 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
@@ -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":"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"}
@@ -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"}