@clauderecallhq/cli 0.12.5 → 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 +110 -22
- package/dist/cli.js +1641 -353
- 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 +56 -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/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/threads.js
DELETED
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { getDb } from '../db/client.js';
|
|
5
|
-
import { RECALL_HOME, ensureRecallHome } from './paths.js';
|
|
6
|
-
const THREADS_DIR = join(RECALL_HOME, 'threads');
|
|
7
|
-
const THREADS_INDEX = join(THREADS_DIR, 'index.json');
|
|
8
|
-
function ensureThreadsDir() {
|
|
9
|
-
ensureRecallHome();
|
|
10
|
-
if (!existsSync(THREADS_DIR))
|
|
11
|
-
mkdirSync(THREADS_DIR, { recursive: true });
|
|
12
|
-
}
|
|
13
|
-
function rowToSummary(r, counts) {
|
|
14
|
-
return {
|
|
15
|
-
id: r.id,
|
|
16
|
-
name: r.name,
|
|
17
|
-
summary: r.summary,
|
|
18
|
-
created_at: r.created_at,
|
|
19
|
-
closed_at: r.closed_at,
|
|
20
|
-
archived: r.archived === 1,
|
|
21
|
-
session_count: counts.session_count,
|
|
22
|
-
origin_count: counts.origin_count,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function rowToEdge(r) {
|
|
26
|
-
const ats = r.auto_title_source;
|
|
27
|
-
return {
|
|
28
|
-
thread_id: r.thread_id,
|
|
29
|
-
session_id: r.session_id,
|
|
30
|
-
parent_session_id: r.parent_session_id,
|
|
31
|
-
role: r.role,
|
|
32
|
-
confidence: r.confidence,
|
|
33
|
-
source: r.source,
|
|
34
|
-
added_at: r.added_at,
|
|
35
|
-
alias: r.alias,
|
|
36
|
-
auto_title: r.auto_title,
|
|
37
|
-
auto_title_source: ats === 'agent' || ats === 'heuristic' ? ats : null,
|
|
38
|
-
// alias_source is derived at request time from the terminal registry.
|
|
39
|
-
// Default to 'manual' so anything bypassing the route enricher (CLI,
|
|
40
|
-
// tests) still applies a sensible precedence.
|
|
41
|
-
alias_source: r.alias ? 'manual' : null,
|
|
42
|
-
first_user_message: r.first_user_message,
|
|
43
|
-
project: r.project,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function labelFieldsFor(sessionId) {
|
|
47
|
-
const db = getDb();
|
|
48
|
-
const row = db
|
|
49
|
-
.prepare(`SELECT NULLIF(sa.alias, '') AS alias,
|
|
50
|
-
s.auto_title AS auto_title,
|
|
51
|
-
s.auto_title_source AS auto_title_source,
|
|
52
|
-
s.first_user_message AS first_user_message,
|
|
53
|
-
p.name AS project
|
|
54
|
-
FROM (SELECT ? AS sid) q
|
|
55
|
-
LEFT JOIN sessions s ON s.id = q.sid
|
|
56
|
-
LEFT JOIN session_aliases sa ON sa.session_id = q.sid
|
|
57
|
-
LEFT JOIN projects p ON p.id = s.project_id`)
|
|
58
|
-
.get(sessionId);
|
|
59
|
-
const ats = row?.auto_title_source ?? null;
|
|
60
|
-
return {
|
|
61
|
-
alias: row?.alias ?? null,
|
|
62
|
-
auto_title: row?.auto_title ?? null,
|
|
63
|
-
auto_title_source: ats === 'agent' || ats === 'heuristic' ? ats : null,
|
|
64
|
-
first_user_message: row?.first_user_message ?? null,
|
|
65
|
-
project: row?.project ?? null,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function countsFor(threadId) {
|
|
69
|
-
const db = getDb();
|
|
70
|
-
const r = db
|
|
71
|
-
.prepare(`SELECT
|
|
72
|
-
COUNT(*) AS session_count,
|
|
73
|
-
SUM(CASE WHEN role = 'origin' THEN 1 ELSE 0 END) AS origin_count
|
|
74
|
-
FROM thread_edges WHERE thread_id = ?`)
|
|
75
|
-
.get(threadId);
|
|
76
|
-
return {
|
|
77
|
-
session_count: r?.session_count ?? 0,
|
|
78
|
-
origin_count: r?.origin_count ?? 0,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function backupThread(threadId) {
|
|
82
|
-
const detail = getThread(threadId);
|
|
83
|
-
if (!detail)
|
|
84
|
-
return;
|
|
85
|
-
ensureThreadsDir();
|
|
86
|
-
writeFileSync(join(THREADS_DIR, `${threadId}.json`), JSON.stringify(detail, null, 2));
|
|
87
|
-
rewriteIndex();
|
|
88
|
-
}
|
|
89
|
-
function rewriteIndex() {
|
|
90
|
-
ensureThreadsDir();
|
|
91
|
-
const list = listThreads({ includeArchived: true });
|
|
92
|
-
writeFileSync(THREADS_INDEX, JSON.stringify({ threads: list }, null, 2));
|
|
93
|
-
}
|
|
94
|
-
export function createThread(input) {
|
|
95
|
-
const name = input.name.trim();
|
|
96
|
-
if (!name)
|
|
97
|
-
throw new Error('thread name cannot be empty');
|
|
98
|
-
const db = getDb();
|
|
99
|
-
const id = randomUUID();
|
|
100
|
-
const now = new Date().toISOString();
|
|
101
|
-
db.prepare(`INSERT INTO threads (id, name, summary, created_at) VALUES (?, ?, ?, ?)`).run(id, name, input.summary?.trim() || null, now);
|
|
102
|
-
if (input.originSessionId) {
|
|
103
|
-
db.prepare(`INSERT INTO thread_edges (thread_id, session_id, parent_session_id, role, confidence, source, added_at)
|
|
104
|
-
VALUES (?, ?, NULL, 'origin', 1.0, 'manual', ?)`).run(id, input.originSessionId, now);
|
|
105
|
-
}
|
|
106
|
-
backupThread(id);
|
|
107
|
-
const detail = getThread(id);
|
|
108
|
-
if (!detail)
|
|
109
|
-
throw new Error('thread creation succeeded but read-back failed');
|
|
110
|
-
return detail;
|
|
111
|
-
}
|
|
112
|
-
export function listThreads(opts = {}) {
|
|
113
|
-
const db = getDb();
|
|
114
|
-
const where = opts.includeArchived ? '' : 'WHERE archived = 0';
|
|
115
|
-
const threads = db
|
|
116
|
-
.prepare(`SELECT * FROM threads ${where} ORDER BY created_at DESC`)
|
|
117
|
-
.all();
|
|
118
|
-
return threads.map((t) => rowToSummary(t, countsFor(t.id)));
|
|
119
|
-
}
|
|
120
|
-
export function getThread(threadId) {
|
|
121
|
-
const db = getDb();
|
|
122
|
-
const t = db.prepare(`SELECT * FROM threads WHERE id = ?`).get(threadId);
|
|
123
|
-
if (!t)
|
|
124
|
-
return null;
|
|
125
|
-
// Surface alias/auto_title/first_user_message inline so the graph can render
|
|
126
|
-
// human-readable labels without a per-node round-trip. Uses LEFT JOINs so
|
|
127
|
-
// edges for sessions not yet indexed (or whose alias was cleared) still show
|
|
128
|
-
// up; the consumer falls back to id.slice(0,8) per the standard chain.
|
|
129
|
-
const edges = db
|
|
130
|
-
.prepare(`SELECT e.*,
|
|
131
|
-
NULLIF(sa.alias, '') AS alias,
|
|
132
|
-
s.auto_title AS auto_title,
|
|
133
|
-
s.auto_title_source AS auto_title_source,
|
|
134
|
-
s.first_user_message AS first_user_message,
|
|
135
|
-
p.name AS project
|
|
136
|
-
FROM thread_edges e
|
|
137
|
-
LEFT JOIN sessions s ON s.id = e.session_id
|
|
138
|
-
LEFT JOIN session_aliases sa ON sa.session_id = e.session_id
|
|
139
|
-
LEFT JOIN projects p ON p.id = s.project_id
|
|
140
|
-
WHERE e.thread_id = ?
|
|
141
|
-
ORDER BY e.added_at ASC`)
|
|
142
|
-
.all(threadId).map(rowToEdge);
|
|
143
|
-
return { ...rowToSummary(t, countsFor(t.id)), edges };
|
|
144
|
-
}
|
|
145
|
-
export function threadsForSession(sessionId) {
|
|
146
|
-
const db = getDb();
|
|
147
|
-
const rows = db
|
|
148
|
-
.prepare(`SELECT t.* FROM threads t
|
|
149
|
-
JOIN thread_edges e ON e.thread_id = t.id
|
|
150
|
-
WHERE e.session_id = ? AND t.archived = 0
|
|
151
|
-
ORDER BY t.created_at DESC`)
|
|
152
|
-
.all(sessionId);
|
|
153
|
-
return rows.map((t) => rowToSummary(t, countsFor(t.id)));
|
|
154
|
-
}
|
|
155
|
-
export function addSessionToThread(input) {
|
|
156
|
-
const db = getDb();
|
|
157
|
-
const existing = db
|
|
158
|
-
.prepare(`SELECT * FROM threads WHERE id = ?`)
|
|
159
|
-
.get(input.threadId);
|
|
160
|
-
if (!existing)
|
|
161
|
-
throw new Error(`thread ${input.threadId} not found`);
|
|
162
|
-
const now = new Date().toISOString();
|
|
163
|
-
const parent = input.parentSessionId ?? null;
|
|
164
|
-
const role = input.role ?? (parent ? 'child' : 'origin');
|
|
165
|
-
const confidence = input.confidence ?? 1.0;
|
|
166
|
-
const source = input.source ?? 'manual';
|
|
167
|
-
if (confidence < 0 || confidence > 1)
|
|
168
|
-
throw new Error('confidence must be 0..1');
|
|
169
|
-
db.prepare(`INSERT INTO thread_edges
|
|
170
|
-
(thread_id, session_id, parent_session_id, role, confidence, source, added_at)
|
|
171
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
172
|
-
ON CONFLICT(thread_id, session_id) DO UPDATE SET
|
|
173
|
-
parent_session_id = excluded.parent_session_id,
|
|
174
|
-
role = excluded.role,
|
|
175
|
-
confidence = excluded.confidence,
|
|
176
|
-
source = excluded.source,
|
|
177
|
-
added_at = excluded.added_at`).run(input.threadId, input.sessionId, parent, role, confidence, source, now);
|
|
178
|
-
backupThread(input.threadId);
|
|
179
|
-
const labels = labelFieldsFor(input.sessionId);
|
|
180
|
-
return {
|
|
181
|
-
thread_id: input.threadId,
|
|
182
|
-
session_id: input.sessionId,
|
|
183
|
-
parent_session_id: parent,
|
|
184
|
-
role,
|
|
185
|
-
confidence,
|
|
186
|
-
source,
|
|
187
|
-
added_at: now,
|
|
188
|
-
alias: labels.alias,
|
|
189
|
-
auto_title: labels.auto_title,
|
|
190
|
-
auto_title_source: labels.auto_title_source,
|
|
191
|
-
alias_source: labels.alias ? 'manual' : null,
|
|
192
|
-
first_user_message: labels.first_user_message,
|
|
193
|
-
project: labels.project,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
export function removeSessionFromThread(threadId, sessionId) {
|
|
197
|
-
const db = getDb();
|
|
198
|
-
const result = db
|
|
199
|
-
.prepare(`DELETE FROM thread_edges WHERE thread_id = ? AND session_id = ?`)
|
|
200
|
-
.run(threadId, sessionId);
|
|
201
|
-
if (result.changes > 0)
|
|
202
|
-
backupThread(threadId);
|
|
203
|
-
return { removed: result.changes };
|
|
204
|
-
}
|
|
205
|
-
export function setParent(threadId, sessionId, parentSessionId) {
|
|
206
|
-
const db = getDb();
|
|
207
|
-
const existing = db
|
|
208
|
-
.prepare(`SELECT * FROM thread_edges WHERE thread_id = ? AND session_id = ?`)
|
|
209
|
-
.get(threadId, sessionId);
|
|
210
|
-
if (!existing)
|
|
211
|
-
throw new Error('edge not found; add the session first');
|
|
212
|
-
// DAG invariant: walking parent chain from the new parent must not reach
|
|
213
|
-
// sessionId (that would create a cycle). Also rejects self-parent.
|
|
214
|
-
if (parentSessionId !== null) {
|
|
215
|
-
if (parentSessionId === sessionId) {
|
|
216
|
-
throw new Error('cycle detected: session cannot be its own parent');
|
|
217
|
-
}
|
|
218
|
-
const stmt = db.prepare(`SELECT parent_session_id FROM thread_edges WHERE thread_id = ? AND session_id = ?`);
|
|
219
|
-
let cursor = parentSessionId;
|
|
220
|
-
const seen = new Set();
|
|
221
|
-
while (cursor !== null) {
|
|
222
|
-
if (cursor === sessionId) {
|
|
223
|
-
throw new Error(`cycle detected: setting parent of ${sessionId} to ${parentSessionId} would create a loop`);
|
|
224
|
-
}
|
|
225
|
-
if (seen.has(cursor))
|
|
226
|
-
break;
|
|
227
|
-
seen.add(cursor);
|
|
228
|
-
const row = stmt.get(threadId, cursor);
|
|
229
|
-
cursor = row?.parent_session_id ?? null;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
const role = parentSessionId ? 'child' : 'origin';
|
|
233
|
-
db.prepare(`UPDATE thread_edges
|
|
234
|
-
SET parent_session_id = ?, role = ?, added_at = ?
|
|
235
|
-
WHERE thread_id = ? AND session_id = ?`).run(parentSessionId, role, new Date().toISOString(), threadId, sessionId);
|
|
236
|
-
backupThread(threadId);
|
|
237
|
-
const labels = labelFieldsFor(sessionId);
|
|
238
|
-
return rowToEdge({
|
|
239
|
-
...existing,
|
|
240
|
-
parent_session_id: parentSessionId,
|
|
241
|
-
role,
|
|
242
|
-
added_at: new Date().toISOString(),
|
|
243
|
-
alias: labels.alias,
|
|
244
|
-
auto_title: labels.auto_title,
|
|
245
|
-
auto_title_source: labels.auto_title_source,
|
|
246
|
-
first_user_message: labels.first_user_message,
|
|
247
|
-
project: labels.project,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
export function renameThread(threadId, name) {
|
|
251
|
-
const trimmed = name.trim();
|
|
252
|
-
if (!trimmed)
|
|
253
|
-
throw new Error('name cannot be empty');
|
|
254
|
-
const db = getDb();
|
|
255
|
-
db.prepare(`UPDATE threads SET name = ? WHERE id = ?`).run(trimmed, threadId);
|
|
256
|
-
backupThread(threadId);
|
|
257
|
-
const detail = getThread(threadId);
|
|
258
|
-
if (!detail)
|
|
259
|
-
throw new Error(`thread ${threadId} not found`);
|
|
260
|
-
return detail;
|
|
261
|
-
}
|
|
262
|
-
export function closeThread(threadId) {
|
|
263
|
-
const db = getDb();
|
|
264
|
-
db.prepare(`UPDATE threads SET closed_at = ? WHERE id = ?`).run(new Date().toISOString(), threadId);
|
|
265
|
-
backupThread(threadId);
|
|
266
|
-
const detail = getThread(threadId);
|
|
267
|
-
if (!detail)
|
|
268
|
-
throw new Error(`thread ${threadId} not found`);
|
|
269
|
-
return detail;
|
|
270
|
-
}
|
|
271
|
-
export function reopenThread(threadId) {
|
|
272
|
-
const db = getDb();
|
|
273
|
-
db.prepare(`UPDATE threads SET closed_at = NULL WHERE id = ?`).run(threadId);
|
|
274
|
-
backupThread(threadId);
|
|
275
|
-
const detail = getThread(threadId);
|
|
276
|
-
if (!detail)
|
|
277
|
-
throw new Error(`thread ${threadId} not found`);
|
|
278
|
-
return detail;
|
|
279
|
-
}
|
|
280
|
-
export function archiveThread(threadId) {
|
|
281
|
-
const db = getDb();
|
|
282
|
-
db.prepare(`UPDATE threads SET archived = 1 WHERE id = ?`).run(threadId);
|
|
283
|
-
backupThread(threadId);
|
|
284
|
-
const detail = getThread(threadId);
|
|
285
|
-
if (!detail)
|
|
286
|
-
throw new Error(`thread ${threadId} not found`);
|
|
287
|
-
return detail;
|
|
288
|
-
}
|
|
289
|
-
export function mergeThreads(sourceId, destId) {
|
|
290
|
-
if (sourceId === destId)
|
|
291
|
-
throw new Error('cannot merge a thread into itself');
|
|
292
|
-
const db = getDb();
|
|
293
|
-
const now = new Date().toISOString();
|
|
294
|
-
db.transaction(() => {
|
|
295
|
-
const edges = db
|
|
296
|
-
.prepare(`SELECT * FROM thread_edges WHERE thread_id = ?`)
|
|
297
|
-
.all(sourceId);
|
|
298
|
-
for (const e of edges) {
|
|
299
|
-
db.prepare(`INSERT INTO thread_edges
|
|
300
|
-
(thread_id, session_id, parent_session_id, role, confidence, source, added_at)
|
|
301
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
302
|
-
ON CONFLICT(thread_id, session_id) DO UPDATE SET
|
|
303
|
-
parent_session_id = COALESCE(thread_edges.parent_session_id, excluded.parent_session_id),
|
|
304
|
-
role = CASE WHEN thread_edges.role = 'origin' OR excluded.role = 'origin' THEN 'origin' ELSE 'child' END,
|
|
305
|
-
confidence = MAX(thread_edges.confidence, excluded.confidence),
|
|
306
|
-
source = thread_edges.source`).run(destId, e.session_id, e.parent_session_id, e.role, e.confidence, e.source, now);
|
|
307
|
-
}
|
|
308
|
-
db.prepare(`DELETE FROM threads WHERE id = ?`).run(sourceId);
|
|
309
|
-
})();
|
|
310
|
-
backupThread(destId);
|
|
311
|
-
rewriteIndex();
|
|
312
|
-
const detail = getThread(destId);
|
|
313
|
-
if (!detail)
|
|
314
|
-
throw new Error('merge destination disappeared');
|
|
315
|
-
return detail;
|
|
316
|
-
}
|
|
317
|
-
export function splitThread(input) {
|
|
318
|
-
if (input.sessionIds.length === 0)
|
|
319
|
-
throw new Error('no sessions to split off');
|
|
320
|
-
const db = getDb();
|
|
321
|
-
const now = new Date().toISOString();
|
|
322
|
-
const newId = randomUUID();
|
|
323
|
-
db.transaction(() => {
|
|
324
|
-
db.prepare(`INSERT INTO threads (id, name, summary, created_at) VALUES (?, ?, NULL, ?)`).run(newId, input.newThreadName.trim(), now);
|
|
325
|
-
for (const sid of input.sessionIds) {
|
|
326
|
-
const existing = db
|
|
327
|
-
.prepare(`SELECT * FROM thread_edges WHERE thread_id = ? AND session_id = ?`)
|
|
328
|
-
.get(input.threadId, sid);
|
|
329
|
-
if (!existing)
|
|
330
|
-
continue;
|
|
331
|
-
db.prepare(`INSERT INTO thread_edges
|
|
332
|
-
(thread_id, session_id, parent_session_id, role, confidence, source, added_at)
|
|
333
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(newId, sid, existing.parent_session_id, existing.role, existing.confidence, existing.source, now);
|
|
334
|
-
db.prepare(`DELETE FROM thread_edges WHERE thread_id = ? AND session_id = ?`).run(input.threadId, sid);
|
|
335
|
-
}
|
|
336
|
-
})();
|
|
337
|
-
backupThread(input.threadId);
|
|
338
|
-
backupThread(newId);
|
|
339
|
-
const detail = getThread(newId);
|
|
340
|
-
if (!detail)
|
|
341
|
-
throw new Error('split destination disappeared');
|
|
342
|
-
return detail;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Collect every session id for a thread, origin-first then children in
|
|
346
|
-
* add order. Used by `recall context <thread-id>` to expand the whole
|
|
347
|
-
* thread into context for re-injection.
|
|
348
|
-
*/
|
|
349
|
-
export function sessionIdsForThread(threadId) {
|
|
350
|
-
const detail = getThread(threadId);
|
|
351
|
-
if (!detail)
|
|
352
|
-
return [];
|
|
353
|
-
const origins = detail.edges.filter((e) => e.role === 'origin').map((e) => e.session_id);
|
|
354
|
-
const children = detail.edges.filter((e) => e.role === 'child').map((e) => e.session_id);
|
|
355
|
-
return [...origins, ...children];
|
|
356
|
-
}
|
|
357
|
-
export function restoreFromMirror() {
|
|
358
|
-
ensureThreadsDir();
|
|
359
|
-
if (!existsSync(THREADS_INDEX))
|
|
360
|
-
return { threads: 0, edges: 0 };
|
|
361
|
-
const raw = readFileSync(THREADS_INDEX, 'utf8');
|
|
362
|
-
const parsed = JSON.parse(raw);
|
|
363
|
-
const db = getDb();
|
|
364
|
-
let threads = 0;
|
|
365
|
-
let edges = 0;
|
|
366
|
-
for (const t of parsed.threads) {
|
|
367
|
-
const detailPath = join(THREADS_DIR, `${t.id}.json`);
|
|
368
|
-
if (!existsSync(detailPath))
|
|
369
|
-
continue;
|
|
370
|
-
const detail = JSON.parse(readFileSync(detailPath, 'utf8'));
|
|
371
|
-
db.prepare(`INSERT OR IGNORE INTO threads (id, name, summary, created_at, closed_at, archived)
|
|
372
|
-
VALUES (?, ?, ?, ?, ?, ?)`).run(detail.id, detail.name, detail.summary, detail.created_at, detail.closed_at, detail.archived ? 1 : 0);
|
|
373
|
-
threads += 1;
|
|
374
|
-
for (const e of detail.edges) {
|
|
375
|
-
db.prepare(`INSERT OR IGNORE INTO thread_edges
|
|
376
|
-
(thread_id, session_id, parent_session_id, role, confidence, source, added_at)
|
|
377
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(e.thread_id, e.session_id, e.parent_session_id, e.role, e.confidence, e.source, e.added_at);
|
|
378
|
-
edges += 1;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return { threads, edges };
|
|
382
|
-
}
|
|
383
|
-
//# sourceMappingURL=threads.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/utils/threads.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/usage.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
export function writeMessageUsageRows(db, sessionId, entries) {
|
|
2
|
-
// Rebuild usage rows for this session from scratch — cheap and keeps
|
|
3
|
-
// the table consistent with whatever is currently in `messages`.
|
|
4
|
-
db.prepare('DELETE FROM message_usage WHERE session_id = ?').run(sessionId);
|
|
5
|
-
const insert = db.prepare(`
|
|
6
|
-
INSERT INTO message_usage (
|
|
7
|
-
message_uuid, session_id, model,
|
|
8
|
-
input_tokens, output_tokens, cache_create_tokens, cache_read_tokens,
|
|
9
|
-
timestamp
|
|
10
|
-
) VALUES (
|
|
11
|
-
@uuid, @session_id, @model,
|
|
12
|
-
@input, @output, @cc, @cr,
|
|
13
|
-
@ts
|
|
14
|
-
)
|
|
15
|
-
ON CONFLICT(message_uuid) DO UPDATE SET
|
|
16
|
-
model = excluded.model,
|
|
17
|
-
input_tokens = excluded.input_tokens,
|
|
18
|
-
output_tokens = excluded.output_tokens,
|
|
19
|
-
cache_create_tokens = excluded.cache_create_tokens,
|
|
20
|
-
cache_read_tokens = excluded.cache_read_tokens,
|
|
21
|
-
timestamp = excluded.timestamp
|
|
22
|
-
`);
|
|
23
|
-
for (const e of entries) {
|
|
24
|
-
if (!e.usage)
|
|
25
|
-
continue;
|
|
26
|
-
if (e.role !== 'assistant')
|
|
27
|
-
continue;
|
|
28
|
-
insert.run({
|
|
29
|
-
uuid: e.uuid,
|
|
30
|
-
session_id: sessionId,
|
|
31
|
-
model: e.model,
|
|
32
|
-
input: e.usage.inputTokens,
|
|
33
|
-
output: e.usage.outputTokens,
|
|
34
|
-
cc: e.usage.cacheCreateTokens,
|
|
35
|
-
cr: e.usage.cacheReadTokens,
|
|
36
|
-
ts: e.timestamp,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Recompute the five rollup columns on `sessions` from `message_usage`.
|
|
42
|
-
* `primary_model` is the model that produced the most *output* tokens
|
|
43
|
-
* (where the real money goes).
|
|
44
|
-
*/
|
|
45
|
-
export function recomputeSessionRollup(db, sessionId) {
|
|
46
|
-
const totals = db
|
|
47
|
-
.prepare(`SELECT
|
|
48
|
-
COALESCE(SUM(input_tokens), 0) AS input_tokens,
|
|
49
|
-
COALESCE(SUM(output_tokens), 0) AS output_tokens,
|
|
50
|
-
COALESCE(SUM(cache_create_tokens), 0) AS cache_create_tokens,
|
|
51
|
-
COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens
|
|
52
|
-
FROM message_usage WHERE session_id = ?`)
|
|
53
|
-
.get(sessionId);
|
|
54
|
-
const primary = db
|
|
55
|
-
.prepare(`SELECT model, SUM(output_tokens) AS out
|
|
56
|
-
FROM message_usage
|
|
57
|
-
WHERE session_id = ? AND model IS NOT NULL
|
|
58
|
-
GROUP BY model
|
|
59
|
-
ORDER BY out DESC LIMIT 1`)
|
|
60
|
-
.get(sessionId);
|
|
61
|
-
db.prepare(`UPDATE sessions SET
|
|
62
|
-
total_input_tokens = @input,
|
|
63
|
-
total_output_tokens = @output,
|
|
64
|
-
total_cache_create_tokens = @cc,
|
|
65
|
-
total_cache_read_tokens = @cr,
|
|
66
|
-
primary_model = @model
|
|
67
|
-
WHERE id = @id`).run({
|
|
68
|
-
id: sessionId,
|
|
69
|
-
input: totals.input_tokens,
|
|
70
|
-
output: totals.output_tokens,
|
|
71
|
-
cc: totals.cache_create_tokens,
|
|
72
|
-
cr: totals.cache_read_tokens,
|
|
73
|
-
model: primary?.model ?? null,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=usage.js.map
|
package/dist/utils/usage.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/utils/usage.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,qBAAqB,CACnC,EAAgB,EAChB,SAAiB,EACjB,OAAsB;IAEtB,qEAAqE;IACrE,iEAAiE;IACjE,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;GAiBzB,CAAC,CAAC;IACH,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,SAAS;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACrC,MAAM,CAAC,GAAG,CAAC;YACT,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW;YAC1B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY;YAC5B,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB;YAC7B,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe;YAC3B,EAAE,EAAE,CAAC,CAAC,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAgB,EAAE,SAAiB;IACxE,MAAM,MAAM,GAAG,EAAE;SACd,OAAO,CACN;;;;;+CAKyC,CAC1C;SACA,GAAG,CAAC,SAAS,CAKf,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE;SACf,OAAO,CACN;;;;iCAI2B,CAC5B;SACA,GAAG,CAAC,SAAS,CAAsD,CAAC;IAEvE,EAAE,CAAC,OAAO,CACR;;;;;;oBAMgB,CACjB,CAAC,GAAG,CAAC;QACJ,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,MAAM,CAAC,YAAY;QAC1B,MAAM,EAAE,MAAM,CAAC,aAAa;QAC5B,EAAE,EAAE,MAAM,CAAC,mBAAmB;QAC9B,EAAE,EAAE,MAAM,CAAC,iBAAiB;QAC5B,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI;KAC9B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { getDb } from '../db/client.js';
|
|
2
|
-
const CLAIM_PATTERNS = [
|
|
3
|
-
/\btask\s+complete/i,
|
|
4
|
-
/\bdone\b/i,
|
|
5
|
-
/\bfinished\b/i,
|
|
6
|
-
/\bimplemented\b/i,
|
|
7
|
-
/\bcompleted\b/i,
|
|
8
|
-
/\bshipped\b/i,
|
|
9
|
-
/\ball\s+(?:tests?\s+)?pass/i,
|
|
10
|
-
/\bsuccessfully\b/i,
|
|
11
|
-
];
|
|
12
|
-
const TTL_MS = 24 * 60 * 60 * 1000;
|
|
13
|
-
export function computeVerificationStatus(sessionId) {
|
|
14
|
-
const db = getDb();
|
|
15
|
-
const assistantMsgs = db
|
|
16
|
-
.prepare(`SELECT content_text, tool_names FROM messages
|
|
17
|
-
WHERE session_id = ? AND role = 'assistant'
|
|
18
|
-
ORDER BY timestamp DESC LIMIT 5`)
|
|
19
|
-
.all(sessionId);
|
|
20
|
-
let claimFound = false;
|
|
21
|
-
for (const msg of assistantMsgs) {
|
|
22
|
-
if (!msg.content_text)
|
|
23
|
-
continue;
|
|
24
|
-
if (CLAIM_PATTERNS.some((p) => p.test(msg.content_text))) {
|
|
25
|
-
claimFound = true;
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const allMsgs = db
|
|
30
|
-
.prepare(`SELECT content_text, tool_names FROM messages
|
|
31
|
-
WHERE session_id = ?`)
|
|
32
|
-
.all(sessionId);
|
|
33
|
-
const evidence = {
|
|
34
|
-
fileWrites: false,
|
|
35
|
-
testRuns: false,
|
|
36
|
-
commits: false,
|
|
37
|
-
buildSuccess: false,
|
|
38
|
-
};
|
|
39
|
-
for (const msg of allMsgs) {
|
|
40
|
-
const tools = msg.tool_names ?? '';
|
|
41
|
-
const text = msg.content_text ?? '';
|
|
42
|
-
if (/\bWrite\b|\bEdit\b/.test(tools))
|
|
43
|
-
evidence.fileWrites = true;
|
|
44
|
-
if (/\b(?:jest|pytest|vitest|mocha|test|spec)\b/i.test(text) && /pass|ok|✓/i.test(text)) {
|
|
45
|
-
evidence.testRuns = true;
|
|
46
|
-
}
|
|
47
|
-
if (/\bgit\s+commit\b/i.test(text))
|
|
48
|
-
evidence.commits = true;
|
|
49
|
-
if (/\bbuild\s+(?:succeeded|success|passed)\b/i.test(text) || /tsc.*(?:0 errors|no errors)/i.test(text)) {
|
|
50
|
-
evidence.buildSuccess = true;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (!claimFound) {
|
|
54
|
-
return { status: 'neutral', evidence, claimFound };
|
|
55
|
-
}
|
|
56
|
-
const evidenceCount = [
|
|
57
|
-
evidence.fileWrites,
|
|
58
|
-
evidence.testRuns,
|
|
59
|
-
evidence.commits,
|
|
60
|
-
evidence.buildSuccess,
|
|
61
|
-
].filter(Boolean).length;
|
|
62
|
-
const status = evidenceCount >= 2 ? 'verified' : 'unverified';
|
|
63
|
-
return { status, evidence, claimFound };
|
|
64
|
-
}
|
|
65
|
-
export function computeAndCache(sessionId) {
|
|
66
|
-
const result = computeVerificationStatus(sessionId);
|
|
67
|
-
const db = getDb();
|
|
68
|
-
db.prepare(`UPDATE sessions SET verification_status = ?, verification_computed_at = ? WHERE id = ?`).run(result.status, Date.now(), sessionId);
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
export function getOrCompute(sessionId) {
|
|
72
|
-
const db = getDb();
|
|
73
|
-
const row = db
|
|
74
|
-
.prepare(`SELECT verification_status, verification_computed_at FROM sessions WHERE id = ?`)
|
|
75
|
-
.get(sessionId);
|
|
76
|
-
if (row?.verification_status &&
|
|
77
|
-
row.verification_computed_at &&
|
|
78
|
-
Date.now() - row.verification_computed_at < TTL_MS) {
|
|
79
|
-
const evidence = { fileWrites: false, testRuns: false, commits: false, buildSuccess: false };
|
|
80
|
-
return {
|
|
81
|
-
status: row.verification_status,
|
|
82
|
-
evidence,
|
|
83
|
-
claimFound: row.verification_status !== 'neutral',
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
return computeAndCache(sessionId);
|
|
87
|
-
}
|
|
88
|
-
//# sourceMappingURL=compute.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compute.js","sourceRoot":"","sources":["../../src/verification/compute.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, mkdirSync, chmodSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
function configPath() {
|
|
5
|
-
return join(homedir(), '.recall', 'config.json');
|
|
6
|
-
}
|
|
7
|
-
function readConfig() {
|
|
8
|
-
try {
|
|
9
|
-
return JSON.parse(readFileSync(configPath(), 'utf-8'));
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return {};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function writeConfig(config) {
|
|
16
|
-
const p = configPath();
|
|
17
|
-
mkdirSync(join(homedir(), '.recall'), { recursive: true });
|
|
18
|
-
writeFileSync(p, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
19
|
-
chmodSync(p, 0o600);
|
|
20
|
-
}
|
|
21
|
-
export function isVerificationEnabled() {
|
|
22
|
-
const cfg = readConfig();
|
|
23
|
-
const v = cfg.verification;
|
|
24
|
-
if (typeof v === 'object' && v !== null && 'enabled' in v) {
|
|
25
|
-
return Boolean(v.enabled);
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
export function setVerificationEnabled(enabled) {
|
|
30
|
-
const cfg = readConfig();
|
|
31
|
-
cfg.verification = { ...(typeof cfg.verification === 'object' && cfg.verification !== null ? cfg.verification : {}), enabled };
|
|
32
|
-
writeConfig(cfg);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/verification/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B;IAClD,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAClE,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;IAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAC1D,OAAO,OAAO,CAAE,CAA0B,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,GAAG,CAAC,YAAY,GAAG,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/H,WAAW,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
|