@clauderecallhq/cli 0.12.1 → 0.61.2
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/LICENSE +37 -17
- package/README.md +316 -106
- package/dist/cli.js +1641 -361
- package/dist/daemon/entrypoint.js +1872 -54
- package/dist/mcp-server.js +930 -0
- package/dist/share/fonts/Inter-Bold.woff +0 -0
- package/dist/share/fonts/Inter-Regular.woff +0 -0
- package/dist/share/fonts/JetBrainsMono-Regular.woff +0 -0
- package/dist/web/assets/_brand-Bw9uSB4O.js +1 -0
- package/dist/web/assets/captureNode-9CVj9vYC.js +2 -0
- package/dist/web/assets/card-a-minimal-ujNERzX7.js +1 -0
- package/dist/web/assets/card-b-terminal-DpJ_tVpg.js +1 -0
- package/dist/web/assets/card-c-gradient-CZXVGuNd.js +1 -0
- package/dist/web/assets/card-d-dashboard-CHKD-PnB.js +1 -0
- package/dist/web/assets/dist-CWaokT35.js +56 -0
- package/dist/web/assets/index-B-HrjaDy.css +1 -0
- package/dist/web/assets/index-BZYcD76T.js +633 -0
- package/dist/web/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
- package/dist/web/assets/patterns-BPeZb9N0.js +1 -0
- package/dist/web/assets/stats-BSwqSiFU.js +1 -0
- package/dist/web/assets/thread-D2AXyhOx.js +1 -0
- package/dist/web/index.html +8 -2
- package/package.json +57 -16
- package/scripts/postinstall.mjs +38 -0
- package/dist/cli.js.map +0 -1
- package/dist/commands/activate.js +0 -69
- package/dist/commands/activate.js.map +0 -1
- package/dist/commands/audit-secrets.js +0 -103
- package/dist/commands/audit-secrets.js.map +0 -1
- package/dist/commands/blame.js +0 -35
- package/dist/commands/blame.js.map +0 -1
- package/dist/commands/config-verification.js +0 -18
- package/dist/commands/config-verification.js.map +0 -1
- package/dist/commands/context.js +0 -144
- package/dist/commands/context.js.map +0 -1
- package/dist/commands/correlate.js +0 -70
- package/dist/commands/correlate.js.map +0 -1
- package/dist/commands/digest.js +0 -78
- package/dist/commands/digest.js.map +0 -1
- package/dist/commands/health.js +0 -62
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/index.js +0 -247
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/install-extension.js +0 -138
- package/dist/commands/install-extension.js.map +0 -1
- package/dist/commands/installs.js +0 -128
- package/dist/commands/installs.js.map +0 -1
- package/dist/commands/license.js +0 -39
- package/dist/commands/license.js.map +0 -1
- package/dist/commands/list.js +0 -47
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/mcp.js +0 -29
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/open.js +0 -28
- package/dist/commands/open.js.map +0 -1
- package/dist/commands/paste.js +0 -154
- package/dist/commands/paste.js.map +0 -1
- package/dist/commands/projects.js +0 -36
- package/dist/commands/projects.js.map +0 -1
- package/dist/commands/search.js +0 -67
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/semantic.js +0 -173
- package/dist/commands/semantic.js.map +0 -1
- package/dist/commands/show.js +0 -121
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/start.js +0 -47
- package/dist/commands/start.js.map +0 -1
- package/dist/commands/stats.js +0 -133
- package/dist/commands/stats.js.map +0 -1
- package/dist/commands/status.js +0 -45
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/stop.js +0 -29
- package/dist/commands/stop.js.map +0 -1
- package/dist/commands/thread.js +0 -396
- package/dist/commands/thread.js.map +0 -1
- package/dist/context/formatter.js +0 -103
- package/dist/context/formatter.js.map +0 -1
- package/dist/daemon/auto-tag-config.js +0 -103
- package/dist/daemon/auto-tag-config.js.map +0 -1
- package/dist/daemon/auto-tag-config.test.js +0 -72
- package/dist/daemon/auto-tag-config.test.js.map +0 -1
- package/dist/daemon/auto-title-config.js +0 -70
- package/dist/daemon/auto-title-config.js.map +0 -1
- package/dist/daemon/bulk-title-jobs.js +0 -170
- package/dist/daemon/bulk-title-jobs.js.map +0 -1
- package/dist/daemon/correlator.js +0 -320
- package/dist/daemon/correlator.js.map +0 -1
- package/dist/daemon/discover.js +0 -316
- package/dist/daemon/discover.js.map +0 -1
- package/dist/daemon/editor-detection.js +0 -186
- package/dist/daemon/editor-detection.js.map +0 -1
- package/dist/daemon/entrypoint.js.map +0 -1
- package/dist/daemon/git-correlator.js +0 -256
- package/dist/daemon/git-correlator.js.map +0 -1
- package/dist/daemon/mcp-installer.js +0 -108
- package/dist/daemon/mcp-installer.js.map +0 -1
- package/dist/daemon/onboarding-state.js +0 -140
- package/dist/daemon/onboarding-state.js.map +0 -1
- package/dist/daemon/pidfile.js +0 -57
- package/dist/daemon/pidfile.js.map +0 -1
- package/dist/daemon/ports.js +0 -48
- package/dist/daemon/ports.js.map +0 -1
- package/dist/daemon/scanProgressRegistry.js +0 -62
- package/dist/daemon/scanProgressRegistry.js.map +0 -1
- package/dist/daemon/server.js +0 -2010
- package/dist/daemon/server.js.map +0 -1
- package/dist/daemon/tag-scanner/anthropic-client.js +0 -40
- package/dist/daemon/tag-scanner/anthropic-client.js.map +0 -1
- package/dist/daemon/tag-scanner/autopilot.js +0 -131
- package/dist/daemon/tag-scanner/autopilot.js.map +0 -1
- package/dist/daemon/tag-scanner/claude-cli-driver.js +0 -250
- package/dist/daemon/tag-scanner/claude-cli-driver.js.map +0 -1
- package/dist/daemon/tag-scanner/orchestrator.js +0 -88
- package/dist/daemon/tag-scanner/orchestrator.js.map +0 -1
- package/dist/daemon/tag-scanner/prompt.js +0 -46
- package/dist/daemon/tag-scanner/prompt.js.map +0 -1
- package/dist/daemon/tag-scanner/prompt.test.js +0 -48
- package/dist/daemon/tag-scanner/prompt.test.js.map +0 -1
- package/dist/daemon/tag-scanner/scan-state.js +0 -49
- package/dist/daemon/tag-scanner/scan-state.js.map +0 -1
- package/dist/daemon/tag-scanner/session-fetcher.js +0 -82
- package/dist/daemon/tag-scanner/session-fetcher.js.map +0 -1
- package/dist/daemon/tag-scanner/session-fetcher.test.js +0 -34
- package/dist/daemon/tag-scanner/session-fetcher.test.js.map +0 -1
- package/dist/daemon/tag-scanner/validator.js +0 -50
- package/dist/daemon/tag-scanner/validator.js.map +0 -1
- package/dist/daemon/tag-scanner/validator.test.js +0 -41
- package/dist/daemon/tag-scanner/validator.test.js.map +0 -1
- package/dist/daemon/terminal-registry.js +0 -443
- package/dist/daemon/terminal-registry.js.map +0 -1
- package/dist/daemon/ui.js +0 -64
- package/dist/daemon/ui.js.map +0 -1
- package/dist/daemon/watcher.js +0 -256
- package/dist/daemon/watcher.js.map +0 -1
- package/dist/db/client.js +0 -22
- package/dist/db/client.js.map +0 -1
- package/dist/db/schema.js +0 -496
- package/dist/db/schema.js.map +0 -1
- package/dist/license/api-base.js +0 -13
- package/dist/license/api-base.js.map +0 -1
- package/dist/license/manager.js +0 -43
- package/dist/license/manager.js.map +0 -1
- package/dist/license/public-key.js +0 -19
- package/dist/license/public-key.js.map +0 -1
- package/dist/license/storage.js +0 -27
- package/dist/license/storage.js.map +0 -1
- package/dist/license/verify.js +0 -23
- package/dist/license/verify.js.map +0 -1
- package/dist/mcp/audit.js +0 -126
- package/dist/mcp/audit.js.map +0 -1
- package/dist/mcp/prompts.js +0 -180
- package/dist/mcp/prompts.js.map +0 -1
- package/dist/mcp/server.js +0 -502
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/thread-tools.js +0 -363
- package/dist/mcp/thread-tools.js.map +0 -1
- package/dist/mcp/write-tools.js +0 -239
- package/dist/mcp/write-tools.js.map +0 -1
- package/dist/parser/jsonl.js +0 -150
- package/dist/parser/jsonl.js.map +0 -1
- package/dist/semantic/chunker.js +0 -47
- package/dist/semantic/chunker.js.map +0 -1
- package/dist/semantic/config.js +0 -74
- package/dist/semantic/config.js.map +0 -1
- package/dist/semantic/embedder.js +0 -54
- package/dist/semantic/embedder.js.map +0 -1
- package/dist/semantic/fusion.js +0 -38
- package/dist/semantic/fusion.js.map +0 -1
- package/dist/semantic/model-download.js +0 -69
- package/dist/semantic/model-download.js.map +0 -1
- package/dist/semantic/pipeline.js +0 -375
- package/dist/semantic/pipeline.js.map +0 -1
- package/dist/semantic/query.js +0 -42
- package/dist/semantic/query.js.map +0 -1
- package/dist/semantic/worker.js +0 -78
- package/dist/semantic/worker.js.map +0 -1
- package/dist/stats/backfill.js +0 -151
- package/dist/stats/backfill.js.map +0 -1
- package/dist/stats/health.js +0 -102
- package/dist/stats/health.js.map +0 -1
- package/dist/stats/query.js +0 -385
- package/dist/stats/query.js.map +0 -1
- package/dist/utils/aliases.js +0 -107
- package/dist/utils/aliases.js.map +0 -1
- package/dist/utils/autoCollections.js +0 -635
- package/dist/utils/autoCollections.js.map +0 -1
- package/dist/utils/autoTitle.js +0 -348
- package/dist/utils/autoTitle.js.map +0 -1
- package/dist/utils/collections.js +0 -446
- package/dist/utils/collections.js.map +0 -1
- package/dist/utils/format.js +0 -46
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/notes.js +0 -270
- package/dist/utils/notes.js.map +0 -1
- package/dist/utils/paths.js +0 -50
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/pricing.js +0 -257
- package/dist/utils/pricing.js.map +0 -1
- package/dist/utils/secret-scanner.js +0 -166
- package/dist/utils/secret-scanner.js.map +0 -1
- package/dist/utils/sessionLabel.js +0 -64
- package/dist/utils/sessionLabel.js.map +0 -1
- package/dist/utils/tags.js +0 -97
- package/dist/utils/tags.js.map +0 -1
- package/dist/utils/thread-context.js +0 -129
- package/dist/utils/thread-context.js.map +0 -1
- package/dist/utils/threadFilter.js +0 -18
- package/dist/utils/threadFilter.js.map +0 -1
- package/dist/utils/threads-titler.js +0 -298
- package/dist/utils/threads-titler.js.map +0 -1
- package/dist/utils/threads.js +0 -383
- package/dist/utils/threads.js.map +0 -1
- package/dist/utils/usage.js +0 -76
- package/dist/utils/usage.js.map +0 -1
- package/dist/verification/compute.js +0 -88
- package/dist/verification/compute.js.map +0 -1
- package/dist/verification/config.js +0 -34
- package/dist/verification/config.js.map +0 -1
- package/dist/web/assets/index-CIr6J4Fw.js +0 -1201
- package/dist/web/assets/index-Ctc8g9Jw.css +0 -1
package/dist/utils/notes.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { getDb } from '../db/client.js';
|
|
4
|
-
import { RECALL_HOME, ensureRecallHome } from './paths.js';
|
|
5
|
-
/**
|
|
6
|
-
* Per-session markdown notes with the same "never lose data" guarantees as aliases:
|
|
7
|
-
*
|
|
8
|
-
* 1. Every save to a non-empty content value archives the *current* content
|
|
9
|
-
* onto previous_versions (JSON array of {content, replaced_at}).
|
|
10
|
-
* 2. On every mutation we mirror the note to ~/.recall/notes/<session_id>.md
|
|
11
|
-
* as plain markdown. Users can grep / edit / commit these files freely.
|
|
12
|
-
* 3. "Clearing" a note stores an empty string — the row (and history) remain.
|
|
13
|
-
*
|
|
14
|
-
* The plain-markdown file on disk is the source of truth for user sanity:
|
|
15
|
-
* even if the SQLite database is lost, every note is recoverable from text files.
|
|
16
|
-
*
|
|
17
|
-
* In addition to the user-typed `content`, the row carries an `auto_synopsis`
|
|
18
|
-
* column populated by `deriveAgentNote()` — agent-generated markdown
|
|
19
|
-
* synopsis. The user-typed note is NEVER overwritten; the synopsis lives
|
|
20
|
-
* alongside it and the UI renders both.
|
|
21
|
-
*/
|
|
22
|
-
export const NOTES_DIR = join(RECALL_HOME, 'notes');
|
|
23
|
-
// ✨ Generate Note — sample budget. We read messages newest-first until we
|
|
24
|
-
// hit MAX_MESSAGES OR the cumulative char count exceeds CHAR_BUDGET, then
|
|
25
|
-
// flip to chronological order before sending to the model. ~12k chars
|
|
26
|
-
// roughly fits in a 4k token claude -p budget with prompt overhead.
|
|
27
|
-
const NOTE_MAX_MESSAGES = 200;
|
|
28
|
-
const NOTE_CHAR_BUDGET = 12_000;
|
|
29
|
-
const NOTE_PER_MESSAGE_CHAR_LIMIT = 800;
|
|
30
|
-
const NOTE_SYNOPSIS_MAX = 8_000;
|
|
31
|
-
function parsePrevious(raw) {
|
|
32
|
-
try {
|
|
33
|
-
const parsed = JSON.parse(raw);
|
|
34
|
-
if (Array.isArray(parsed))
|
|
35
|
-
return parsed;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
/* fall through */
|
|
39
|
-
}
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
function parseSynopsisHistory(raw) {
|
|
43
|
-
if (!raw)
|
|
44
|
-
return [];
|
|
45
|
-
try {
|
|
46
|
-
const parsed = JSON.parse(raw);
|
|
47
|
-
if (!Array.isArray(parsed))
|
|
48
|
-
return [];
|
|
49
|
-
return parsed.filter((e) => !!e &&
|
|
50
|
-
typeof e === 'object' &&
|
|
51
|
-
typeof e.synopsis === 'string' &&
|
|
52
|
-
typeof e.replaced_at === 'string');
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return [];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function ensureNotesDir() {
|
|
59
|
-
ensureRecallHome();
|
|
60
|
-
if (!existsSync(NOTES_DIR))
|
|
61
|
-
mkdirSync(NOTES_DIR, { recursive: true });
|
|
62
|
-
}
|
|
63
|
-
function rowToNote(row) {
|
|
64
|
-
return {
|
|
65
|
-
session_id: row.session_id,
|
|
66
|
-
content: row.content,
|
|
67
|
-
updated_at: row.updated_at,
|
|
68
|
-
previous_versions: parsePrevious(row.previous_versions),
|
|
69
|
-
auto_synopsis: row.auto_synopsis ?? null,
|
|
70
|
-
auto_synopsis_generated_at: row.auto_synopsis_generated_at ?? null,
|
|
71
|
-
auto_synopsis_history: parseSynopsisHistory(row.auto_synopsis_history),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
const NOTE_SELECT_COLS = 'session_id, content, updated_at, previous_versions, auto_synopsis, auto_synopsis_generated_at, auto_synopsis_history';
|
|
75
|
-
export function getNote(sessionId) {
|
|
76
|
-
const row = getDb()
|
|
77
|
-
.prepare(`SELECT ${NOTE_SELECT_COLS} FROM session_notes WHERE session_id = ?`)
|
|
78
|
-
.get(sessionId);
|
|
79
|
-
if (!row)
|
|
80
|
-
return null;
|
|
81
|
-
return rowToNote(row);
|
|
82
|
-
}
|
|
83
|
-
export function setNote(sessionId, content) {
|
|
84
|
-
const db = getDb();
|
|
85
|
-
const now = new Date().toISOString();
|
|
86
|
-
const existing = db
|
|
87
|
-
.prepare('SELECT content, previous_versions FROM session_notes WHERE session_id = ?')
|
|
88
|
-
.get(sessionId);
|
|
89
|
-
let previous = [];
|
|
90
|
-
if (existing) {
|
|
91
|
-
previous = parsePrevious(existing.previous_versions);
|
|
92
|
-
if (existing.content !== content && existing.content.length > 0) {
|
|
93
|
-
previous.push({ content: existing.content, replaced_at: now });
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
db.prepare(`INSERT INTO session_notes (session_id, content, updated_at, previous_versions)
|
|
97
|
-
VALUES (?, ?, ?, ?)
|
|
98
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
99
|
-
content = excluded.content,
|
|
100
|
-
updated_at = excluded.updated_at,
|
|
101
|
-
previous_versions = excluded.previous_versions`).run(sessionId, content, now, JSON.stringify(previous));
|
|
102
|
-
writeNoteFile(sessionId, content, now);
|
|
103
|
-
// Re-read so we return any auto_synopsis written by a parallel ✨ click.
|
|
104
|
-
return getNote(sessionId) ?? {
|
|
105
|
-
session_id: sessionId,
|
|
106
|
-
content,
|
|
107
|
-
updated_at: now,
|
|
108
|
-
previous_versions: previous,
|
|
109
|
-
auto_synopsis: null,
|
|
110
|
-
auto_synopsis_generated_at: null,
|
|
111
|
-
auto_synopsis_history: [],
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* ✨ Generate Note — runs the user's local `claude` CLI over a sampled
|
|
116
|
-
* conversation, returns a markdown synopsis. Pure read; the caller is
|
|
117
|
-
* responsible for persisting via `setAutoSynopsis`.
|
|
118
|
-
*
|
|
119
|
-
* Sampling strategy: walk newest-first until we either hit
|
|
120
|
-
* `NOTE_MAX_MESSAGES` rows or the cumulative content_text length passes
|
|
121
|
-
* `NOTE_CHAR_BUDGET`. Then flip to chronological order before sending. This
|
|
122
|
-
* gives the model an unbiased recent slice without blowing the context
|
|
123
|
-
* window on multi-thousand-message sessions. Both user AND assistant
|
|
124
|
-
* messages are included — the synopsis reflects what was discussed and
|
|
125
|
-
* what was done.
|
|
126
|
-
*/
|
|
127
|
-
export async function deriveAgentNote(sessionId) {
|
|
128
|
-
const db = getDb();
|
|
129
|
-
const rows = db
|
|
130
|
-
.prepare(`SELECT rowid AS rid, role, content_text
|
|
131
|
-
FROM messages
|
|
132
|
-
WHERE session_id = ? AND is_sidechain = 0
|
|
133
|
-
AND content_text IS NOT NULL AND content_text != ''
|
|
134
|
-
AND role IN ('user', 'assistant')
|
|
135
|
-
ORDER BY COALESCE(timestamp, '') DESC, rowid DESC
|
|
136
|
-
LIMIT ?`)
|
|
137
|
-
.all(sessionId, NOTE_MAX_MESSAGES);
|
|
138
|
-
if (rows.length === 0) {
|
|
139
|
-
throw new Error('no messages available to summarise');
|
|
140
|
-
}
|
|
141
|
-
// Walk the newest-first list, collect until char budget hits, then flip
|
|
142
|
-
// chronological. Cap each message's contribution so a single huge message
|
|
143
|
-
// can't crowd everything else out.
|
|
144
|
-
let charBudget = NOTE_CHAR_BUDGET;
|
|
145
|
-
const sample = [];
|
|
146
|
-
for (const r of rows) {
|
|
147
|
-
if (charBudget <= 0)
|
|
148
|
-
break;
|
|
149
|
-
const slice = (r.content_text ?? '').slice(0, NOTE_PER_MESSAGE_CHAR_LIMIT);
|
|
150
|
-
sample.push({ rid: r.rid, role: r.role, content: slice });
|
|
151
|
-
charBudget -= slice.length;
|
|
152
|
-
}
|
|
153
|
-
sample.reverse(); // chronological
|
|
154
|
-
const dropped = rows.length === NOTE_MAX_MESSAGES || charBudget <= 0;
|
|
155
|
-
const body = sample
|
|
156
|
-
.map((r) => `**${r.role}**: ${r.content}`)
|
|
157
|
-
.join('\n\n');
|
|
158
|
-
const prompt = [
|
|
159
|
-
'You will receive a sampled chronological transcript from a Claude Code session.',
|
|
160
|
-
dropped
|
|
161
|
-
? 'The sample is the most recent slice that fits in the context budget; older messages were dropped.'
|
|
162
|
-
: 'The full session is included.',
|
|
163
|
-
'',
|
|
164
|
-
'Write a clean markdown synopsis of the session. Use these sections — omit any that genuinely have nothing to say:',
|
|
165
|
-
'',
|
|
166
|
-
'## Goal',
|
|
167
|
-
'One sentence — what the user was trying to accomplish.',
|
|
168
|
-
'',
|
|
169
|
-
'## What was done',
|
|
170
|
-
'Bullet list — concrete actions, code changes, decisions. Skip pleasantries.',
|
|
171
|
-
'',
|
|
172
|
-
'## Key decisions',
|
|
173
|
-
'Bullet list — non-obvious choices and the reason behind them.',
|
|
174
|
-
'',
|
|
175
|
-
'## Files touched',
|
|
176
|
-
'Bullet list — file paths mentioned in the conversation. Omit the section if none.',
|
|
177
|
-
'',
|
|
178
|
-
'## Open follow-ups',
|
|
179
|
-
'Bullet list — anything left undone or flagged for later. Omit the section if none.',
|
|
180
|
-
'',
|
|
181
|
-
'Output ONLY the markdown — no surrounding prose, no code fences around the whole thing, no closing summary.',
|
|
182
|
-
'',
|
|
183
|
-
'---',
|
|
184
|
-
'',
|
|
185
|
-
body,
|
|
186
|
-
].join('\n');
|
|
187
|
-
const { spawnClaudePrompt, isClaudeCliAvailable } = await import('../daemon/tag-scanner/claude-cli-driver.js');
|
|
188
|
-
if (!isClaudeCliAvailable()) {
|
|
189
|
-
throw new Error('claude CLI not found on PATH');
|
|
190
|
-
}
|
|
191
|
-
const result = await spawnClaudePrompt(prompt, [], {});
|
|
192
|
-
if (!result.success) {
|
|
193
|
-
throw new Error(`claude CLI exited ${result.exitCode}: ${result.stderr.slice(-500)}`);
|
|
194
|
-
}
|
|
195
|
-
const synopsis = extractSynopsisFromCliResult(result.stdout);
|
|
196
|
-
if (!synopsis)
|
|
197
|
-
throw new Error('claude CLI returned an empty synopsis');
|
|
198
|
-
return synopsis.slice(0, NOTE_SYNOPSIS_MAX);
|
|
199
|
-
}
|
|
200
|
-
function extractSynopsisFromCliResult(stdout) {
|
|
201
|
-
const trimmed = stdout.trim();
|
|
202
|
-
if (!trimmed)
|
|
203
|
-
return '';
|
|
204
|
-
// claude -p --output-format json returns { result: "..." }; raw text is
|
|
205
|
-
// also accepted.
|
|
206
|
-
try {
|
|
207
|
-
const parsed = JSON.parse(trimmed);
|
|
208
|
-
if (parsed && typeof parsed === 'object') {
|
|
209
|
-
const result = parsed.result;
|
|
210
|
-
if (typeof result === 'string')
|
|
211
|
-
return result.trim();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
catch {
|
|
215
|
-
/* not JSON — fall through */
|
|
216
|
-
}
|
|
217
|
-
return trimmed;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Persist a freshly-generated synopsis. Pushes the prior synopsis (if any)
|
|
221
|
-
* onto auto_synopsis_history so regeneration never loses content. Idempotent
|
|
222
|
-
* if the synopsis text is identical to the current value.
|
|
223
|
-
*/
|
|
224
|
-
export function setAutoSynopsis(sessionId, synopsis) {
|
|
225
|
-
const db = getDb();
|
|
226
|
-
const now = new Date().toISOString();
|
|
227
|
-
const nowMs = Date.now();
|
|
228
|
-
const existing = db
|
|
229
|
-
.prepare('SELECT auto_synopsis, auto_synopsis_history, content, updated_at FROM session_notes WHERE session_id = ?')
|
|
230
|
-
.get(sessionId);
|
|
231
|
-
const history = parseSynopsisHistory(existing?.auto_synopsis_history ?? null);
|
|
232
|
-
if (existing?.auto_synopsis &&
|
|
233
|
-
existing.auto_synopsis !== synopsis &&
|
|
234
|
-
existing.auto_synopsis.length > 0) {
|
|
235
|
-
history.push({ synopsis: existing.auto_synopsis, replaced_at: now });
|
|
236
|
-
}
|
|
237
|
-
if (existing) {
|
|
238
|
-
db.prepare(`UPDATE session_notes
|
|
239
|
-
SET auto_synopsis = ?,
|
|
240
|
-
auto_synopsis_generated_at = ?,
|
|
241
|
-
auto_synopsis_history = ?
|
|
242
|
-
WHERE session_id = ?`).run(synopsis, nowMs, JSON.stringify(history), sessionId);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
// No row at all — create with empty content and the synopsis.
|
|
246
|
-
db.prepare(`INSERT INTO session_notes
|
|
247
|
-
(session_id, content, updated_at, previous_versions, auto_synopsis,
|
|
248
|
-
auto_synopsis_generated_at, auto_synopsis_history)
|
|
249
|
-
VALUES (?, '', ?, '[]', ?, ?, ?)`).run(sessionId, now, synopsis, nowMs, JSON.stringify(history));
|
|
250
|
-
}
|
|
251
|
-
return getNote(sessionId);
|
|
252
|
-
}
|
|
253
|
-
function writeNoteFile(sessionId, content, updatedAt) {
|
|
254
|
-
try {
|
|
255
|
-
ensureNotesDir();
|
|
256
|
-
const filePath = join(NOTES_DIR, `${sessionId}.md`);
|
|
257
|
-
const header = `<!-- Claude Recall note · session ${sessionId} · updated ${updatedAt} -->\n`;
|
|
258
|
-
writeFileSync(filePath, header + content);
|
|
259
|
-
}
|
|
260
|
-
catch (err) {
|
|
261
|
-
console.error('[notes] mirror write failed:', err);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
export function hasNote(sessionId) {
|
|
265
|
-
const row = getDb()
|
|
266
|
-
.prepare("SELECT 1 FROM session_notes WHERE session_id = ? AND content != '' LIMIT 1")
|
|
267
|
-
.get(sessionId);
|
|
268
|
-
return !!row;
|
|
269
|
-
}
|
|
270
|
-
//# sourceMappingURL=notes.js.map
|
package/dist/utils/notes.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notes.js","sourceRoot":"","sources":["../../src/utils/notes.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/paths.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { homedir } from 'node:os';
|
|
2
|
-
import { join, basename } from 'node:path';
|
|
3
|
-
import { existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
|
|
4
|
-
export const CLAUDE_PROJECTS_DIR = join(homedir(), '.claude', 'projects');
|
|
5
|
-
// $RECALL_HOME lets tests and isolated profiles redirect the data root.
|
|
6
|
-
// Default stays ~/.recall so nothing changes for normal users.
|
|
7
|
-
export const RECALL_HOME = process.env.RECALL_HOME
|
|
8
|
-
? process.env.RECALL_HOME
|
|
9
|
-
: join(homedir(), '.recall');
|
|
10
|
-
export const RECALL_DB_PATH = join(RECALL_HOME, 'db.sqlite');
|
|
11
|
-
export function ensureRecallHome() {
|
|
12
|
-
if (!existsSync(RECALL_HOME)) {
|
|
13
|
-
mkdirSync(RECALL_HOME, { recursive: true });
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export function decodeProjectPath(encoded) {
|
|
17
|
-
return encoded.replace(/^-/, '/').replace(/-/g, '/');
|
|
18
|
-
}
|
|
19
|
-
export function projectDisplayName(encoded) {
|
|
20
|
-
const decoded = decodeProjectPath(encoded);
|
|
21
|
-
return basename(decoded) || decoded;
|
|
22
|
-
}
|
|
23
|
-
export function discoverSessionFiles() {
|
|
24
|
-
if (!existsSync(CLAUDE_PROJECTS_DIR))
|
|
25
|
-
return [];
|
|
26
|
-
const results = [];
|
|
27
|
-
const projectDirs = readdirSync(CLAUDE_PROJECTS_DIR, { withFileTypes: true })
|
|
28
|
-
.filter((e) => e.isDirectory())
|
|
29
|
-
.map((e) => e.name);
|
|
30
|
-
for (const projectDir of projectDirs) {
|
|
31
|
-
const projectRoot = join(CLAUDE_PROJECTS_DIR, projectDir);
|
|
32
|
-
const entries = readdirSync(projectRoot, { withFileTypes: true });
|
|
33
|
-
for (const entry of entries) {
|
|
34
|
-
if (!entry.isFile())
|
|
35
|
-
continue;
|
|
36
|
-
if (!entry.name.endsWith('.jsonl'))
|
|
37
|
-
continue;
|
|
38
|
-
const fullPath = join(projectRoot, entry.name);
|
|
39
|
-
const stat = statSync(fullPath);
|
|
40
|
-
results.push({
|
|
41
|
-
sessionFile: fullPath,
|
|
42
|
-
encodedProject: projectDir,
|
|
43
|
-
mtime: stat.mtimeMs,
|
|
44
|
-
size: stat.size,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return results;
|
|
49
|
-
}
|
|
50
|
-
//# sourceMappingURL=paths.js.map
|
package/dist/utils/paths.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAE1E,wEAAwE;AACxE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW;IAChD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW;IACzB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAE7D,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;AACtC,CAAC;AASD,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,MAAM,WAAW,GAAG,WAAW,CAAC,mBAAmB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC1E,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEtB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC;gBACX,WAAW,EAAE,QAAQ;gBACrB,cAAc,EAAE,UAAU;gBAC1B,KAAK,EAAE,IAAI,CAAC,OAAO;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/utils/pricing.js
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v0.10a — Claude model pricing, hardcoded.
|
|
3
|
-
*
|
|
4
|
-
* Prices change; token counts don't. Recall persists only raw token counts
|
|
5
|
-
* in `message_usage` and derives dollar amounts here at render time. If
|
|
6
|
-
* Anthropic re-prices tomorrow, we ship a patch to this file and every
|
|
7
|
-
* historical session re-computes with the new rate — no data migration.
|
|
8
|
-
*
|
|
9
|
-
* Units: cents per million tokens (¢/Mtok). To get dollars:
|
|
10
|
-
* dollars = (tokens / 1_000_000) * (centsPerMtok / 100)
|
|
11
|
-
*
|
|
12
|
-
* Rates sourced from https://www.anthropic.com/pricing (current as of
|
|
13
|
-
* 2026-04-21). Cache-read tokens bill at ~10% of input; cache-write
|
|
14
|
-
* (5m ephemeral) bills at ~125% of input. Historic retired model rates
|
|
15
|
-
* are kept so old sessions still price meaningfully; if a model is
|
|
16
|
-
* entirely unknown we fall back to Sonnet pricing and flag it.
|
|
17
|
-
*/
|
|
18
|
-
/**
|
|
19
|
-
* Keys are substrings we match against `message.model` (case-insensitive).
|
|
20
|
-
* Order matters — most specific first, generic family names last, so a
|
|
21
|
-
* `claude-opus-4-7-20260115` id is recognized as opus-4.7, not plain opus.
|
|
22
|
-
*/
|
|
23
|
-
const PRICING_TABLE = [
|
|
24
|
-
// ── Current lineup (Claude 4.x) ──────────────────────────────────────
|
|
25
|
-
[
|
|
26
|
-
/opus[-_ ]?4[-_. ]?7/i,
|
|
27
|
-
{
|
|
28
|
-
label: 'Opus 4.7',
|
|
29
|
-
inputCentsPerMtok: 1500,
|
|
30
|
-
outputCentsPerMtok: 7500,
|
|
31
|
-
cacheCreateCentsPerMtok: 1875,
|
|
32
|
-
cacheReadCentsPerMtok: 150,
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
[
|
|
36
|
-
/opus[-_ ]?4[-_. ]?6/i,
|
|
37
|
-
{
|
|
38
|
-
label: 'Opus 4.6',
|
|
39
|
-
inputCentsPerMtok: 1500,
|
|
40
|
-
outputCentsPerMtok: 7500,
|
|
41
|
-
cacheCreateCentsPerMtok: 1875,
|
|
42
|
-
cacheReadCentsPerMtok: 150,
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
[
|
|
46
|
-
/sonnet[-_ ]?4[-_. ]?6/i,
|
|
47
|
-
{
|
|
48
|
-
label: 'Sonnet 4.6',
|
|
49
|
-
inputCentsPerMtok: 300,
|
|
50
|
-
outputCentsPerMtok: 1500,
|
|
51
|
-
cacheCreateCentsPerMtok: 375,
|
|
52
|
-
cacheReadCentsPerMtok: 30,
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
[
|
|
56
|
-
/sonnet[-_ ]?4[-_. ]?5/i,
|
|
57
|
-
{
|
|
58
|
-
label: 'Sonnet 4.5',
|
|
59
|
-
inputCentsPerMtok: 300,
|
|
60
|
-
outputCentsPerMtok: 1500,
|
|
61
|
-
cacheCreateCentsPerMtok: 375,
|
|
62
|
-
cacheReadCentsPerMtok: 30,
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
[
|
|
66
|
-
/haiku[-_ ]?4[-_. ]?5/i,
|
|
67
|
-
{
|
|
68
|
-
label: 'Haiku 4.5',
|
|
69
|
-
inputCentsPerMtok: 100,
|
|
70
|
-
outputCentsPerMtok: 500,
|
|
71
|
-
cacheCreateCentsPerMtok: 125,
|
|
72
|
-
cacheReadCentsPerMtok: 10,
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
// ── Historic (retired but still show up in JSONLs) ──────────────────
|
|
76
|
-
[
|
|
77
|
-
/opus[-_ ]?4(?!.*[5-9])/i,
|
|
78
|
-
{
|
|
79
|
-
label: 'Opus 4',
|
|
80
|
-
inputCentsPerMtok: 1500,
|
|
81
|
-
outputCentsPerMtok: 7500,
|
|
82
|
-
cacheCreateCentsPerMtok: 1875,
|
|
83
|
-
cacheReadCentsPerMtok: 150,
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
[
|
|
87
|
-
/sonnet[-_ ]?4(?!.*[5-9])/i,
|
|
88
|
-
{
|
|
89
|
-
label: 'Sonnet 4',
|
|
90
|
-
inputCentsPerMtok: 300,
|
|
91
|
-
outputCentsPerMtok: 1500,
|
|
92
|
-
cacheCreateCentsPerMtok: 375,
|
|
93
|
-
cacheReadCentsPerMtok: 30,
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
[
|
|
97
|
-
/3[-_. ]?7[-_ ]?sonnet|sonnet[-_ ]?3[-_. ]?7/i,
|
|
98
|
-
{
|
|
99
|
-
label: 'Sonnet 3.7',
|
|
100
|
-
inputCentsPerMtok: 300,
|
|
101
|
-
outputCentsPerMtok: 1500,
|
|
102
|
-
cacheCreateCentsPerMtok: 375,
|
|
103
|
-
cacheReadCentsPerMtok: 30,
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
[
|
|
107
|
-
/3[-_. ]?5[-_ ]?sonnet|sonnet[-_ ]?3[-_. ]?5/i,
|
|
108
|
-
{
|
|
109
|
-
label: 'Sonnet 3.5',
|
|
110
|
-
inputCentsPerMtok: 300,
|
|
111
|
-
outputCentsPerMtok: 1500,
|
|
112
|
-
cacheCreateCentsPerMtok: 375,
|
|
113
|
-
cacheReadCentsPerMtok: 30,
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
[
|
|
117
|
-
/3[-_. ]?5[-_ ]?haiku|haiku[-_ ]?3[-_. ]?5/i,
|
|
118
|
-
{
|
|
119
|
-
label: 'Haiku 3.5',
|
|
120
|
-
inputCentsPerMtok: 80,
|
|
121
|
-
outputCentsPerMtok: 400,
|
|
122
|
-
cacheCreateCentsPerMtok: 100,
|
|
123
|
-
cacheReadCentsPerMtok: 8,
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
[
|
|
127
|
-
/3[-_ ]?opus|opus[-_ ]?3/i,
|
|
128
|
-
{
|
|
129
|
-
label: 'Opus 3',
|
|
130
|
-
inputCentsPerMtok: 1500,
|
|
131
|
-
outputCentsPerMtok: 7500,
|
|
132
|
-
cacheCreateCentsPerMtok: 1875,
|
|
133
|
-
cacheReadCentsPerMtok: 150,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
[
|
|
137
|
-
/3[-_ ]?haiku|haiku(?!.*3[-_. ]?5)/i,
|
|
138
|
-
{
|
|
139
|
-
label: 'Haiku 3',
|
|
140
|
-
inputCentsPerMtok: 25,
|
|
141
|
-
outputCentsPerMtok: 125,
|
|
142
|
-
cacheCreateCentsPerMtok: 30,
|
|
143
|
-
cacheReadCentsPerMtok: 3,
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
// ── Family-level fallbacks ──────────────────────────────────────────
|
|
147
|
-
[
|
|
148
|
-
/opus/i,
|
|
149
|
-
{
|
|
150
|
-
label: 'Opus',
|
|
151
|
-
inputCentsPerMtok: 1500,
|
|
152
|
-
outputCentsPerMtok: 7500,
|
|
153
|
-
cacheCreateCentsPerMtok: 1875,
|
|
154
|
-
cacheReadCentsPerMtok: 150,
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
[
|
|
158
|
-
/sonnet/i,
|
|
159
|
-
{
|
|
160
|
-
label: 'Sonnet',
|
|
161
|
-
inputCentsPerMtok: 300,
|
|
162
|
-
outputCentsPerMtok: 1500,
|
|
163
|
-
cacheCreateCentsPerMtok: 375,
|
|
164
|
-
cacheReadCentsPerMtok: 30,
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
[
|
|
168
|
-
/haiku/i,
|
|
169
|
-
{
|
|
170
|
-
label: 'Haiku',
|
|
171
|
-
inputCentsPerMtok: 100,
|
|
172
|
-
outputCentsPerMtok: 500,
|
|
173
|
-
cacheCreateCentsPerMtok: 125,
|
|
174
|
-
cacheReadCentsPerMtok: 10,
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
];
|
|
178
|
-
/** Sonnet-ish fallback for fully unknown ids so cost isn't zero. */
|
|
179
|
-
const FALLBACK = {
|
|
180
|
-
label: 'unknown',
|
|
181
|
-
inputCentsPerMtok: 300,
|
|
182
|
-
outputCentsPerMtok: 1500,
|
|
183
|
-
cacheCreateCentsPerMtok: 375,
|
|
184
|
-
cacheReadCentsPerMtok: 30,
|
|
185
|
-
};
|
|
186
|
-
export function priceFor(model) {
|
|
187
|
-
if (!model)
|
|
188
|
-
return FALLBACK;
|
|
189
|
-
for (const [re, price] of PRICING_TABLE) {
|
|
190
|
-
if (re.test(model))
|
|
191
|
-
return price;
|
|
192
|
-
}
|
|
193
|
-
return FALLBACK;
|
|
194
|
-
}
|
|
195
|
-
export function estimateCost(totals, fallbackModel) {
|
|
196
|
-
// If we have a by-model breakdown, price each bucket separately and sum.
|
|
197
|
-
if (totals.byModel && Object.keys(totals.byModel).length > 0) {
|
|
198
|
-
const parts = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 };
|
|
199
|
-
let totalTokens = 0;
|
|
200
|
-
for (const [model, m] of Object.entries(totals.byModel)) {
|
|
201
|
-
const p = priceFor(model);
|
|
202
|
-
parts.input += (m.inputTokens / 1_000_000) * p.inputCentsPerMtok;
|
|
203
|
-
parts.output += (m.outputTokens / 1_000_000) * p.outputCentsPerMtok;
|
|
204
|
-
parts.cacheCreate +=
|
|
205
|
-
(m.cacheCreateTokens / 1_000_000) * p.cacheCreateCentsPerMtok;
|
|
206
|
-
parts.cacheRead +=
|
|
207
|
-
(m.cacheReadTokens / 1_000_000) * p.cacheReadCentsPerMtok;
|
|
208
|
-
totalTokens +=
|
|
209
|
-
m.inputTokens + m.outputTokens + m.cacheCreateTokens + m.cacheReadTokens;
|
|
210
|
-
}
|
|
211
|
-
const cents = parts.input + parts.output + parts.cacheCreate + parts.cacheRead;
|
|
212
|
-
return { cents, dollars: cents / 100, totalTokens, parts };
|
|
213
|
-
}
|
|
214
|
-
const p = priceFor(fallbackModel);
|
|
215
|
-
const parts = {
|
|
216
|
-
input: (totals.inputTokens / 1_000_000) * p.inputCentsPerMtok,
|
|
217
|
-
output: (totals.outputTokens / 1_000_000) * p.outputCentsPerMtok,
|
|
218
|
-
cacheCreate: (totals.cacheCreateTokens / 1_000_000) * p.cacheCreateCentsPerMtok,
|
|
219
|
-
cacheRead: (totals.cacheReadTokens / 1_000_000) * p.cacheReadCentsPerMtok,
|
|
220
|
-
};
|
|
221
|
-
const cents = parts.input + parts.output + parts.cacheCreate + parts.cacheRead;
|
|
222
|
-
const totalTokens = totals.inputTokens +
|
|
223
|
-
totals.outputTokens +
|
|
224
|
-
totals.cacheCreateTokens +
|
|
225
|
-
totals.cacheReadTokens;
|
|
226
|
-
return { cents, dollars: cents / 100, totalTokens, parts };
|
|
227
|
-
}
|
|
228
|
-
/** Format cents as a short dollar string: $12.34, $0.04, <$0.01. */
|
|
229
|
-
export function formatDollars(cents) {
|
|
230
|
-
const dollars = cents / 100;
|
|
231
|
-
if (dollars === 0)
|
|
232
|
-
return '$0.00';
|
|
233
|
-
if (dollars < 0.01)
|
|
234
|
-
return '<$0.01';
|
|
235
|
-
if (dollars < 1)
|
|
236
|
-
return `$${dollars.toFixed(2)}`;
|
|
237
|
-
if (dollars < 100)
|
|
238
|
-
return `$${dollars.toFixed(2)}`;
|
|
239
|
-
if (dollars < 10000)
|
|
240
|
-
return `$${dollars.toFixed(0)}`;
|
|
241
|
-
return `$${(dollars / 1000).toFixed(1)}k`;
|
|
242
|
-
}
|
|
243
|
-
/** Format a token count as "1.2k", "3.4M", "12.42B", etc. */
|
|
244
|
-
export function formatTokens(n) {
|
|
245
|
-
if (!Number.isFinite(n) || n < 0)
|
|
246
|
-
return '0';
|
|
247
|
-
if (n < 1_000)
|
|
248
|
-
return String(Math.round(n));
|
|
249
|
-
if (n < 1_000_000)
|
|
250
|
-
return `${(n / 1_000).toFixed(1)}k`;
|
|
251
|
-
if (n < 1_000_000_000)
|
|
252
|
-
return `${(n / 1_000_000).toFixed(2)}M`;
|
|
253
|
-
if (n < 1_000_000_000_000)
|
|
254
|
-
return `${(n / 1_000_000_000).toFixed(2)}B`;
|
|
255
|
-
return `${(n / 1_000_000_000_000).toFixed(2)}T`;
|
|
256
|
-
}
|
|
257
|
-
//# sourceMappingURL=pricing.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/utils/pricing.ts"],"names":[],"mappings":"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"}
|