@code-insights/cli 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +146 -156
- package/dashboard-dist/assets/index-BMhL7wL8.css +1 -0
- package/dashboard-dist/assets/index-CuCBzQyQ.js +548 -0
- package/dashboard-dist/dist/assets/index-BMhL7wL8.css +1 -0
- package/dashboard-dist/dist/assets/index-CuCBzQyQ.js +548 -0
- package/dashboard-dist/dist/favicon.svg +4 -0
- package/dashboard-dist/dist/index.html +33 -0
- package/dashboard-dist/favicon.svg +4 -0
- package/dashboard-dist/index.html +33 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +188 -69
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +16 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +82 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/init.d.ts +3 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +24 -201
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install-hook.d.ts.map +1 -1
- package/dist/commands/install-hook.js +4 -21
- package/dist/commands/install-hook.js.map +1 -1
- package/dist/commands/open.d.ts +2 -1
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +10 -21
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/reset.d.ts.map +1 -1
- package/dist/commands/reset.js +38 -69
- package/dist/commands/reset.js.map +1 -1
- package/dist/commands/stats/actions/error-handler.d.ts.map +1 -1
- package/dist/commands/stats/actions/error-handler.js +1 -11
- package/dist/commands/stats/actions/error-handler.js.map +1 -1
- package/dist/commands/stats/actions/overview.js +2 -2
- package/dist/commands/stats/actions/overview.js.map +1 -1
- package/dist/commands/stats/actions/today.js +1 -1
- package/dist/commands/stats/actions/today.js.map +1 -1
- package/dist/commands/stats/data/firestore.d.ts +1 -1
- package/dist/commands/stats/data/firestore.d.ts.map +1 -1
- package/dist/commands/stats/data/firestore.js +24 -9
- package/dist/commands/stats/data/firestore.js.map +1 -1
- package/dist/commands/stats/data/local.d.ts +1 -3
- package/dist/commands/stats/data/local.d.ts.map +1 -1
- package/dist/commands/stats/data/local.js +45 -41
- package/dist/commands/stats/data/local.js.map +1 -1
- package/dist/commands/stats/data/source.d.ts +3 -9
- package/dist/commands/stats/data/source.d.ts.map +1 -1
- package/dist/commands/stats/data/source.js +3 -35
- package/dist/commands/stats/data/source.js.map +1 -1
- package/dist/commands/stats/data/types.d.ts +2 -13
- package/dist/commands/stats/data/types.d.ts.map +1 -1
- package/dist/commands/stats/data/types.js +0 -16
- package/dist/commands/stats/data/types.js.map +1 -1
- package/dist/commands/stats/shared.d.ts.map +1 -1
- package/dist/commands/stats/shared.js +1 -5
- package/dist/commands/stats/shared.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +53 -92
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts +5 -5
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +56 -40
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/telemetry.d.ts.map +1 -1
- package/dist/commands/telemetry.js +0 -1
- package/dist/commands/telemetry.js.map +1 -1
- package/dist/constants/llm-providers.d.ts +5 -0
- package/dist/constants/llm-providers.d.ts.map +1 -0
- package/dist/constants/llm-providers.js +56 -0
- package/dist/constants/llm-providers.js.map +1 -0
- package/dist/db/client.d.ts +17 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +53 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +31 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/read.d.ts +42 -0
- package/dist/db/read.d.ts.map +1 -0
- package/dist/db/read.js +194 -0
- package/dist/db/read.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +129 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/write.d.ts +24 -0
- package/dist/db/write.d.ts.map +1 -0
- package/dist/db/write.js +287 -0
- package/dist/db/write.js.map +1 -0
- package/dist/firebase/client.d.ts +5 -0
- package/dist/firebase/client.d.ts.map +1 -1
- package/dist/firebase/client.js +23 -0
- package/dist/firebase/client.js.map +1 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/providers/context.d.ts +3 -0
- package/dist/providers/context.d.ts.map +1 -0
- package/dist/providers/context.js +13 -0
- package/dist/providers/context.js.map +1 -0
- package/dist/providers/copilot.d.ts +18 -0
- package/dist/providers/copilot.d.ts.map +1 -0
- package/dist/providers/copilot.js +289 -0
- package/dist/providers/copilot.js.map +1 -0
- package/dist/providers/cursor.d.ts.map +1 -1
- package/dist/providers/cursor.js +99 -4
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +3 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/types.d.ts +38 -47
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/browser.d.ts +6 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +23 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/config.d.ts +9 -21
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +23 -50
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/telemetry.js +2 -7
- package/dist/utils/telemetry.js.map +1 -1
- package/dist/utils/tips.js +1 -1
- package/dist/utils/tips.js.map +1 -1
- package/dist/utils/welcome.d.ts +1 -1
- package/dist/utils/welcome.d.ts.map +1 -1
- package/dist/utils/welcome.js +20 -49
- package/dist/utils/welcome.js.map +1 -1
- package/package.json +19 -5
- package/server-dist/dist/index.d.ts +12 -0
- package/server-dist/dist/index.d.ts.map +1 -0
- package/server-dist/dist/index.js +92 -0
- package/server-dist/dist/index.js.map +1 -0
- package/server-dist/dist/llm/analysis.d.ts +80 -0
- package/server-dist/dist/llm/analysis.d.ts.map +1 -0
- package/server-dist/dist/llm/analysis.js +509 -0
- package/server-dist/dist/llm/analysis.js.map +1 -0
- package/server-dist/dist/llm/client.d.ts +27 -0
- package/server-dist/dist/llm/client.d.ts.map +1 -0
- package/server-dist/dist/llm/client.js +71 -0
- package/server-dist/dist/llm/client.js.map +1 -0
- package/server-dist/dist/llm/index.d.ts +7 -0
- package/server-dist/dist/llm/index.d.ts.map +1 -0
- package/server-dist/dist/llm/index.js +5 -0
- package/server-dist/dist/llm/index.js.map +1 -0
- package/server-dist/dist/llm/prompts.d.ts +73 -0
- package/server-dist/dist/llm/prompts.d.ts.map +1 -0
- package/server-dist/dist/llm/prompts.js +242 -0
- package/server-dist/dist/llm/prompts.js.map +1 -0
- package/server-dist/dist/llm/providers/anthropic.d.ts +3 -0
- package/server-dist/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/server-dist/dist/llm/providers/anthropic.js +45 -0
- package/server-dist/dist/llm/providers/anthropic.js.map +1 -0
- package/server-dist/dist/llm/providers/gemini.d.ts +3 -0
- package/server-dist/dist/llm/providers/gemini.d.ts.map +1 -0
- package/server-dist/dist/llm/providers/gemini.js +51 -0
- package/server-dist/dist/llm/providers/gemini.js.map +1 -0
- package/server-dist/dist/llm/providers/ollama.d.ts +12 -0
- package/server-dist/dist/llm/providers/ollama.d.ts.map +1 -0
- package/server-dist/dist/llm/providers/ollama.js +61 -0
- package/server-dist/dist/llm/providers/ollama.js.map +1 -0
- package/server-dist/dist/llm/providers/openai.d.ts +3 -0
- package/server-dist/dist/llm/providers/openai.d.ts.map +1 -0
- package/server-dist/dist/llm/providers/openai.js +39 -0
- package/server-dist/dist/llm/providers/openai.js.map +1 -0
- package/server-dist/dist/llm/types.d.ts +22 -0
- package/server-dist/dist/llm/types.d.ts.map +1 -0
- package/server-dist/dist/llm/types.js +5 -0
- package/server-dist/dist/llm/types.js.map +1 -0
- package/server-dist/dist/routes/analysis.d.ts +4 -0
- package/server-dist/dist/routes/analysis.d.ts.map +1 -0
- package/server-dist/dist/routes/analysis.js +103 -0
- package/server-dist/dist/routes/analysis.js.map +1 -0
- package/server-dist/dist/routes/analytics.d.ts +4 -0
- package/server-dist/dist/routes/analytics.d.ts.map +1 -0
- package/server-dist/dist/routes/analytics.js +47 -0
- package/server-dist/dist/routes/analytics.js.map +1 -0
- package/server-dist/dist/routes/config.d.ts +4 -0
- package/server-dist/dist/routes/config.d.ts.map +1 -0
- package/server-dist/dist/routes/config.js +108 -0
- package/server-dist/dist/routes/config.js.map +1 -0
- package/server-dist/dist/routes/export.d.ts +4 -0
- package/server-dist/dist/routes/export.d.ts.map +1 -0
- package/server-dist/dist/routes/export.js +52 -0
- package/server-dist/dist/routes/export.js.map +1 -0
- package/server-dist/dist/routes/insights.d.ts +4 -0
- package/server-dist/dist/routes/insights.d.ts.map +1 -0
- package/server-dist/dist/routes/insights.js +80 -0
- package/server-dist/dist/routes/insights.js.map +1 -0
- package/server-dist/dist/routes/messages.d.ts +4 -0
- package/server-dist/dist/routes/messages.d.ts.map +1 -0
- package/server-dist/dist/routes/messages.js +19 -0
- package/server-dist/dist/routes/messages.js.map +1 -0
- package/server-dist/dist/routes/projects.d.ts +4 -0
- package/server-dist/dist/routes/projects.d.ts.map +1 -0
- package/server-dist/dist/routes/projects.js +32 -0
- package/server-dist/dist/routes/projects.js.map +1 -0
- package/server-dist/dist/routes/sessions.d.ts +4 -0
- package/server-dist/dist/routes/sessions.d.ts.map +1 -0
- package/server-dist/dist/routes/sessions.js +65 -0
- package/server-dist/dist/routes/sessions.js.map +1 -0
- package/server-dist/dist/utils.d.ts +6 -0
- package/server-dist/dist/utils.d.ts.map +1 -0
- package/server-dist/dist/utils.js +9 -0
- package/server-dist/dist/utils.js.map +1 -0
- package/server-dist/index.d.ts +12 -0
- package/server-dist/index.d.ts.map +1 -0
- package/server-dist/index.js +92 -0
- package/server-dist/index.js.map +1 -0
- package/server-dist/llm/analysis.d.ts +80 -0
- package/server-dist/llm/analysis.d.ts.map +1 -0
- package/server-dist/llm/analysis.js +509 -0
- package/server-dist/llm/analysis.js.map +1 -0
- package/server-dist/llm/client.d.ts +27 -0
- package/server-dist/llm/client.d.ts.map +1 -0
- package/server-dist/llm/client.js +71 -0
- package/server-dist/llm/client.js.map +1 -0
- package/server-dist/llm/index.d.ts +7 -0
- package/server-dist/llm/index.d.ts.map +1 -0
- package/server-dist/llm/index.js +5 -0
- package/server-dist/llm/index.js.map +1 -0
- package/server-dist/llm/prompts.d.ts +73 -0
- package/server-dist/llm/prompts.d.ts.map +1 -0
- package/server-dist/llm/prompts.js +242 -0
- package/server-dist/llm/prompts.js.map +1 -0
- package/server-dist/llm/providers/anthropic.d.ts +3 -0
- package/server-dist/llm/providers/anthropic.d.ts.map +1 -0
- package/server-dist/llm/providers/anthropic.js +45 -0
- package/server-dist/llm/providers/anthropic.js.map +1 -0
- package/server-dist/llm/providers/gemini.d.ts +3 -0
- package/server-dist/llm/providers/gemini.d.ts.map +1 -0
- package/server-dist/llm/providers/gemini.js +51 -0
- package/server-dist/llm/providers/gemini.js.map +1 -0
- package/server-dist/llm/providers/ollama.d.ts +12 -0
- package/server-dist/llm/providers/ollama.d.ts.map +1 -0
- package/server-dist/llm/providers/ollama.js +61 -0
- package/server-dist/llm/providers/ollama.js.map +1 -0
- package/server-dist/llm/providers/openai.d.ts +3 -0
- package/server-dist/llm/providers/openai.d.ts.map +1 -0
- package/server-dist/llm/providers/openai.js +39 -0
- package/server-dist/llm/providers/openai.js.map +1 -0
- package/server-dist/llm/types.d.ts +22 -0
- package/server-dist/llm/types.d.ts.map +1 -0
- package/server-dist/llm/types.js +5 -0
- package/server-dist/llm/types.js.map +1 -0
- package/server-dist/routes/analysis.d.ts +4 -0
- package/server-dist/routes/analysis.d.ts.map +1 -0
- package/server-dist/routes/analysis.js +103 -0
- package/server-dist/routes/analysis.js.map +1 -0
- package/server-dist/routes/analytics.d.ts +4 -0
- package/server-dist/routes/analytics.d.ts.map +1 -0
- package/server-dist/routes/analytics.js +47 -0
- package/server-dist/routes/analytics.js.map +1 -0
- package/server-dist/routes/config.d.ts +4 -0
- package/server-dist/routes/config.d.ts.map +1 -0
- package/server-dist/routes/config.js +108 -0
- package/server-dist/routes/config.js.map +1 -0
- package/server-dist/routes/export.d.ts +4 -0
- package/server-dist/routes/export.d.ts.map +1 -0
- package/server-dist/routes/export.js +52 -0
- package/server-dist/routes/export.js.map +1 -0
- package/server-dist/routes/insights.d.ts +4 -0
- package/server-dist/routes/insights.d.ts.map +1 -0
- package/server-dist/routes/insights.js +80 -0
- package/server-dist/routes/insights.js.map +1 -0
- package/server-dist/routes/messages.d.ts +4 -0
- package/server-dist/routes/messages.d.ts.map +1 -0
- package/server-dist/routes/messages.js +19 -0
- package/server-dist/routes/messages.js.map +1 -0
- package/server-dist/routes/projects.d.ts +4 -0
- package/server-dist/routes/projects.d.ts.map +1 -0
- package/server-dist/routes/projects.js +32 -0
- package/server-dist/routes/projects.js.map +1 -0
- package/server-dist/routes/sessions.d.ts +4 -0
- package/server-dist/routes/sessions.d.ts.map +1 -0
- package/server-dist/routes/sessions.js +65 -0
- package/server-dist/routes/sessions.js.map +1 -0
- package/server-dist/utils.d.ts +6 -0
- package/server-dist/utils.d.ts.map +1 -0
- package/server-dist/utils.js +9 -0
- package/server-dist/utils.js.map +1 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
5
|
+
import { runMigrations } from './migrate.js';
|
|
6
|
+
const DB_DIR = join(homedir(), '.code-insights');
|
|
7
|
+
const DB_PATH = join(DB_DIR, 'data.db');
|
|
8
|
+
let _db = null;
|
|
9
|
+
/**
|
|
10
|
+
* Get (or initialize) the singleton SQLite database instance.
|
|
11
|
+
* WAL mode is enabled for concurrent reads during CLI sync.
|
|
12
|
+
* Migrations run automatically on first call.
|
|
13
|
+
*/
|
|
14
|
+
export function getDb() {
|
|
15
|
+
if (_db)
|
|
16
|
+
return _db;
|
|
17
|
+
if (!existsSync(DB_DIR)) {
|
|
18
|
+
mkdirSync(DB_DIR, { recursive: true, mode: 0o700 });
|
|
19
|
+
}
|
|
20
|
+
const db = new Database(DB_PATH);
|
|
21
|
+
// WAL mode: allows concurrent reads while CLI writes
|
|
22
|
+
db.pragma('journal_mode = WAL');
|
|
23
|
+
// Wait up to 5s if another writer holds the lock (e.g., dashboard writing insights)
|
|
24
|
+
db.pragma('busy_timeout = 5000');
|
|
25
|
+
// Foreign key enforcement
|
|
26
|
+
db.pragma('foreign_keys = ON');
|
|
27
|
+
runMigrations(db);
|
|
28
|
+
_db = db;
|
|
29
|
+
// Ensure WAL checkpoint runs on process exit so no data is left in the WAL file.
|
|
30
|
+
// Registered here (on first open) so it fires whether process exits normally or
|
|
31
|
+
// via an unhandled exception that reaches the exit handler.
|
|
32
|
+
process.on('exit', () => {
|
|
33
|
+
closeDb();
|
|
34
|
+
});
|
|
35
|
+
return _db;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Close the database connection. Used in tests and graceful shutdown.
|
|
39
|
+
* Also called by the process 'exit' handler to ensure WAL checkpointing.
|
|
40
|
+
*/
|
|
41
|
+
export function closeDb() {
|
|
42
|
+
if (_db) {
|
|
43
|
+
_db.close();
|
|
44
|
+
_db = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the database file path.
|
|
49
|
+
*/
|
|
50
|
+
export function getDbPath() {
|
|
51
|
+
return DB_PATH;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACjD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAExC,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,KAAK;IACnB,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAEpB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,qDAAqD;IACrD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,oFAAoF;IACpF,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,0BAA0B;IAC1B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAE/B,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB,GAAG,GAAG,EAAE,CAAC;IAET,iFAAiF;IACjF,gFAAgF;IAChF,4DAA4D;IAC5D,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO;IACrB,IAAI,GAAG,EAAE,CAAC;QACR,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
/**
|
|
3
|
+
* Apply schema migrations to the database.
|
|
4
|
+
* Called once on startup before any reads or writes.
|
|
5
|
+
*
|
|
6
|
+
* Version 1: Initial schema (projects, sessions, messages, insights, usage_stats)
|
|
7
|
+
*/
|
|
8
|
+
export declare function runMigrations(db: Database.Database): void;
|
|
9
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAiBzD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SCHEMA_SQL, CURRENT_SCHEMA_VERSION } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Apply schema migrations to the database.
|
|
4
|
+
* Called once on startup before any reads or writes.
|
|
5
|
+
*
|
|
6
|
+
* Version 1: Initial schema (projects, sessions, messages, insights, usage_stats)
|
|
7
|
+
*/
|
|
8
|
+
export function runMigrations(db) {
|
|
9
|
+
// Create schema_version table first if it doesn't exist.
|
|
10
|
+
// This table is created inline (not via SCHEMA_SQL) so migrations can check it.
|
|
11
|
+
db.exec(`
|
|
12
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
13
|
+
version INTEGER PRIMARY KEY,
|
|
14
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
15
|
+
);
|
|
16
|
+
`);
|
|
17
|
+
const currentVersion = getCurrentVersion(db);
|
|
18
|
+
if (currentVersion < 1) {
|
|
19
|
+
applyV1(db);
|
|
20
|
+
}
|
|
21
|
+
// Future migrations: if (currentVersion < 2) { applyV2(db); }
|
|
22
|
+
}
|
|
23
|
+
function getCurrentVersion(db) {
|
|
24
|
+
const row = db.prepare('SELECT MAX(version) as v FROM schema_version').get();
|
|
25
|
+
return row.v ?? 0;
|
|
26
|
+
}
|
|
27
|
+
function applyV1(db) {
|
|
28
|
+
db.exec(SCHEMA_SQL);
|
|
29
|
+
db.prepare('INSERT OR IGNORE INTO schema_version (version) VALUES (?)').run(CURRENT_SCHEMA_VERSION);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,yDAAyD;IACzD,gFAAgF;IAChF,EAAE,CAAC,IAAI,CAAC;;;;;GAKP,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAE7C,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,8DAA8D;AAChE,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC,GAAG,EAA0B,CAAC;IACrG,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,OAAO,CAAC,EAAqB;IACpC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpB,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtG,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SessionRow } from '../commands/stats/data/types.js';
|
|
2
|
+
export declare function sessionExists(sessionId: string): boolean;
|
|
3
|
+
export interface ProjectRow {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
path: string;
|
|
7
|
+
session_count: number;
|
|
8
|
+
last_activity: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getProjects(): ProjectRow[];
|
|
11
|
+
export interface SessionQueryOptions {
|
|
12
|
+
periodStart?: Date;
|
|
13
|
+
projectId?: string;
|
|
14
|
+
sourceTool?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Query sessions from SQLite, mapping snake_case columns to SessionRow shape.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getSessions(opts?: SessionQueryOptions): SessionRow[];
|
|
20
|
+
/**
|
|
21
|
+
* Get the most recent session matching optional filters.
|
|
22
|
+
* Uses LIMIT 1 to avoid scanning all rows.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getLastSession(opts?: {
|
|
25
|
+
sourceTool?: string;
|
|
26
|
+
projectId?: string;
|
|
27
|
+
}): SessionRow | null;
|
|
28
|
+
/**
|
|
29
|
+
* Count sessions matching optional filters without loading row data.
|
|
30
|
+
* Use this instead of getSessions({}).length to avoid full-table scans
|
|
31
|
+
* when only a count is needed.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSessionCount(opts?: SessionQueryOptions): number;
|
|
34
|
+
/**
|
|
35
|
+
* Get distinct project names and IDs from sessions table.
|
|
36
|
+
* Used for project resolution in stats commands.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getProjectList(): Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
}>;
|
|
42
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/db/read.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAwBlE,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIxD;AAMD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,WAAW,IAAI,UAAU,EAAE,CAO1C;AAMD,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,mBAAwB,GAAG,UAAU,EAAE,CAoFxE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,GAAG,IAAI,CAmFpG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,mBAAwB,GAAG,MAAM,CAwBtE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAOpE"}
|
package/dist/db/read.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { getDb } from './client.js';
|
|
2
|
+
// ──────────────────────────────────────────────────────
|
|
3
|
+
// Helpers
|
|
4
|
+
// ──────────────────────────────────────────────────────
|
|
5
|
+
/**
|
|
6
|
+
* Safely parse the models_used JSON column.
|
|
7
|
+
* Returns undefined on any parse failure rather than throwing — a corrupt
|
|
8
|
+
* value in one row should not break the entire query.
|
|
9
|
+
*/
|
|
10
|
+
function parseModelsUsed(raw) {
|
|
11
|
+
if (!raw)
|
|
12
|
+
return undefined;
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(raw);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// ──────────────────────────────────────────────────────
|
|
21
|
+
// Session existence check (used by sync)
|
|
22
|
+
// ──────────────────────────────────────────────────────
|
|
23
|
+
export function sessionExists(sessionId) {
|
|
24
|
+
const db = getDb();
|
|
25
|
+
const row = db.prepare('SELECT 1 FROM sessions WHERE id = ?').get(sessionId);
|
|
26
|
+
return row !== undefined;
|
|
27
|
+
}
|
|
28
|
+
export function getProjects() {
|
|
29
|
+
const db = getDb();
|
|
30
|
+
return db.prepare(`
|
|
31
|
+
SELECT id, name, path, session_count, last_activity
|
|
32
|
+
FROM projects
|
|
33
|
+
ORDER BY last_activity DESC
|
|
34
|
+
`).all();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Query sessions from SQLite, mapping snake_case columns to SessionRow shape.
|
|
38
|
+
*/
|
|
39
|
+
export function getSessions(opts = {}) {
|
|
40
|
+
const db = getDb();
|
|
41
|
+
const conditions = [];
|
|
42
|
+
const params = [];
|
|
43
|
+
if (opts.periodStart) {
|
|
44
|
+
conditions.push('started_at >= ?');
|
|
45
|
+
params.push(opts.periodStart.toISOString());
|
|
46
|
+
}
|
|
47
|
+
if (opts.projectId) {
|
|
48
|
+
conditions.push('project_id = ?');
|
|
49
|
+
params.push(opts.projectId);
|
|
50
|
+
}
|
|
51
|
+
if (opts.sourceTool) {
|
|
52
|
+
conditions.push('source_tool = ?');
|
|
53
|
+
params.push(opts.sourceTool);
|
|
54
|
+
}
|
|
55
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
56
|
+
const sql = `
|
|
57
|
+
SELECT
|
|
58
|
+
id, project_id, project_name,
|
|
59
|
+
started_at, ended_at,
|
|
60
|
+
message_count, user_message_count, assistant_message_count, tool_call_count,
|
|
61
|
+
estimated_cost_usd, total_input_tokens, total_output_tokens,
|
|
62
|
+
cache_creation_tokens, cache_read_tokens,
|
|
63
|
+
primary_model, models_used,
|
|
64
|
+
generated_title, custom_title, summary, session_character,
|
|
65
|
+
source_tool, usage_source
|
|
66
|
+
FROM sessions
|
|
67
|
+
${where}
|
|
68
|
+
ORDER BY started_at DESC
|
|
69
|
+
`;
|
|
70
|
+
const rows = db.prepare(sql).all(...params);
|
|
71
|
+
return rows.map((r) => ({
|
|
72
|
+
id: r.id,
|
|
73
|
+
projectId: r.project_id,
|
|
74
|
+
projectName: r.project_name,
|
|
75
|
+
startedAt: new Date(r.started_at),
|
|
76
|
+
endedAt: new Date(r.ended_at),
|
|
77
|
+
messageCount: r.message_count,
|
|
78
|
+
userMessageCount: r.user_message_count,
|
|
79
|
+
assistantMessageCount: r.assistant_message_count,
|
|
80
|
+
toolCallCount: r.tool_call_count,
|
|
81
|
+
estimatedCostUsd: r.estimated_cost_usd ?? undefined,
|
|
82
|
+
totalInputTokens: r.total_input_tokens ?? undefined,
|
|
83
|
+
totalOutputTokens: r.total_output_tokens ?? undefined,
|
|
84
|
+
cacheCreationTokens: r.cache_creation_tokens ?? undefined,
|
|
85
|
+
cacheReadTokens: r.cache_read_tokens ?? undefined,
|
|
86
|
+
primaryModel: r.primary_model ?? undefined,
|
|
87
|
+
modelsUsed: parseModelsUsed(r.models_used),
|
|
88
|
+
generatedTitle: r.generated_title ?? undefined,
|
|
89
|
+
customTitle: r.custom_title ?? undefined,
|
|
90
|
+
summary: r.summary ?? undefined,
|
|
91
|
+
sessionCharacter: r.session_character ?? undefined,
|
|
92
|
+
sourceTool: r.source_tool,
|
|
93
|
+
usageSource: r.usage_source ?? undefined,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the most recent session matching optional filters.
|
|
98
|
+
* Uses LIMIT 1 to avoid scanning all rows.
|
|
99
|
+
*/
|
|
100
|
+
export function getLastSession(opts) {
|
|
101
|
+
const db = getDb();
|
|
102
|
+
const conditions = [];
|
|
103
|
+
const params = [];
|
|
104
|
+
if (opts?.sourceTool) {
|
|
105
|
+
conditions.push('source_tool = ?');
|
|
106
|
+
params.push(opts.sourceTool);
|
|
107
|
+
}
|
|
108
|
+
if (opts?.projectId) {
|
|
109
|
+
conditions.push('project_id = ?');
|
|
110
|
+
params.push(opts.projectId);
|
|
111
|
+
}
|
|
112
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
113
|
+
const sql = `
|
|
114
|
+
SELECT
|
|
115
|
+
id, project_id, project_name,
|
|
116
|
+
started_at, ended_at,
|
|
117
|
+
message_count, user_message_count, assistant_message_count, tool_call_count,
|
|
118
|
+
estimated_cost_usd, total_input_tokens, total_output_tokens,
|
|
119
|
+
cache_creation_tokens, cache_read_tokens,
|
|
120
|
+
primary_model, models_used,
|
|
121
|
+
generated_title, custom_title, summary, session_character,
|
|
122
|
+
source_tool, usage_source
|
|
123
|
+
FROM sessions
|
|
124
|
+
${where}
|
|
125
|
+
ORDER BY started_at DESC
|
|
126
|
+
LIMIT 1
|
|
127
|
+
`;
|
|
128
|
+
const row = db.prepare(sql).get(...params);
|
|
129
|
+
if (!row)
|
|
130
|
+
return null;
|
|
131
|
+
return {
|
|
132
|
+
id: row.id,
|
|
133
|
+
projectId: row.project_id,
|
|
134
|
+
projectName: row.project_name,
|
|
135
|
+
startedAt: new Date(row.started_at),
|
|
136
|
+
endedAt: new Date(row.ended_at),
|
|
137
|
+
messageCount: row.message_count,
|
|
138
|
+
userMessageCount: row.user_message_count,
|
|
139
|
+
assistantMessageCount: row.assistant_message_count,
|
|
140
|
+
toolCallCount: row.tool_call_count,
|
|
141
|
+
estimatedCostUsd: row.estimated_cost_usd ?? undefined,
|
|
142
|
+
totalInputTokens: row.total_input_tokens ?? undefined,
|
|
143
|
+
totalOutputTokens: row.total_output_tokens ?? undefined,
|
|
144
|
+
cacheCreationTokens: row.cache_creation_tokens ?? undefined,
|
|
145
|
+
cacheReadTokens: row.cache_read_tokens ?? undefined,
|
|
146
|
+
primaryModel: row.primary_model ?? undefined,
|
|
147
|
+
modelsUsed: parseModelsUsed(row.models_used),
|
|
148
|
+
generatedTitle: row.generated_title ?? undefined,
|
|
149
|
+
customTitle: row.custom_title ?? undefined,
|
|
150
|
+
summary: row.summary ?? undefined,
|
|
151
|
+
sessionCharacter: row.session_character ?? undefined,
|
|
152
|
+
sourceTool: row.source_tool,
|
|
153
|
+
usageSource: row.usage_source ?? undefined,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Count sessions matching optional filters without loading row data.
|
|
158
|
+
* Use this instead of getSessions({}).length to avoid full-table scans
|
|
159
|
+
* when only a count is needed.
|
|
160
|
+
*/
|
|
161
|
+
export function getSessionCount(opts = {}) {
|
|
162
|
+
const db = getDb();
|
|
163
|
+
const conditions = [];
|
|
164
|
+
const params = [];
|
|
165
|
+
if (opts.periodStart) {
|
|
166
|
+
conditions.push('started_at >= ?');
|
|
167
|
+
params.push(opts.periodStart.toISOString());
|
|
168
|
+
}
|
|
169
|
+
if (opts.projectId) {
|
|
170
|
+
conditions.push('project_id = ?');
|
|
171
|
+
params.push(opts.projectId);
|
|
172
|
+
}
|
|
173
|
+
if (opts.sourceTool) {
|
|
174
|
+
conditions.push('source_tool = ?');
|
|
175
|
+
params.push(opts.sourceTool);
|
|
176
|
+
}
|
|
177
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
178
|
+
const sql = `SELECT COUNT(*) AS cnt FROM sessions ${where}`;
|
|
179
|
+
const row = db.prepare(sql).get(...params);
|
|
180
|
+
return row.cnt;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get distinct project names and IDs from sessions table.
|
|
184
|
+
* Used for project resolution in stats commands.
|
|
185
|
+
*/
|
|
186
|
+
export function getProjectList() {
|
|
187
|
+
const db = getDb();
|
|
188
|
+
return db.prepare(`
|
|
189
|
+
SELECT DISTINCT project_id AS id, project_name AS name
|
|
190
|
+
FROM sessions
|
|
191
|
+
ORDER BY project_name
|
|
192
|
+
`).all();
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/db/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const SCHEMA_SQL = "\n-- ============================================================\n-- Projects\n-- ============================================================\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n path TEXT NOT NULL,\n git_remote_url TEXT,\n project_id_source TEXT NOT NULL DEFAULT 'path-hash',\n session_count INTEGER NOT NULL DEFAULT 0,\n last_activity TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n total_input_tokens INTEGER DEFAULT 0,\n total_output_tokens INTEGER DEFAULT 0,\n cache_creation_tokens INTEGER DEFAULT 0,\n cache_read_tokens INTEGER DEFAULT 0,\n estimated_cost_usd REAL DEFAULT 0\n);\n\n-- ============================================================\n-- Sessions\n-- ============================================================\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id),\n project_name TEXT NOT NULL,\n project_path TEXT NOT NULL,\n git_remote_url TEXT,\n summary TEXT,\n custom_title TEXT,\n generated_title TEXT,\n title_source TEXT,\n session_character TEXT,\n started_at TEXT NOT NULL,\n ended_at TEXT NOT NULL,\n message_count INTEGER NOT NULL DEFAULT 0,\n user_message_count INTEGER NOT NULL DEFAULT 0,\n assistant_message_count INTEGER NOT NULL DEFAULT 0,\n tool_call_count INTEGER NOT NULL DEFAULT 0,\n git_branch TEXT,\n claude_version TEXT,\n source_tool TEXT NOT NULL DEFAULT 'claude-code',\n device_id TEXT,\n device_hostname TEXT,\n device_platform TEXT,\n synced_at TEXT NOT NULL DEFAULT (datetime('now')),\n total_input_tokens INTEGER,\n total_output_tokens INTEGER,\n cache_creation_tokens INTEGER,\n cache_read_tokens INTEGER,\n estimated_cost_usd REAL,\n models_used TEXT,\n primary_model TEXT,\n usage_source TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_sessions_project_id ON sessions(project_id);\nCREATE INDEX IF NOT EXISTS idx_sessions_started_at ON sessions(started_at DESC);\nCREATE INDEX IF NOT EXISTS idx_sessions_source_tool ON sessions(source_tool);\n\n-- ============================================================\n-- Messages\n-- ============================================================\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n type TEXT NOT NULL,\n content TEXT NOT NULL DEFAULT '',\n thinking TEXT,\n tool_calls TEXT,\n tool_results TEXT,\n usage TEXT,\n timestamp TEXT NOT NULL,\n parent_id TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id);\nCREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(session_id, timestamp ASC);\n\n-- ============================================================\n-- Insights (written by dashboard server, not CLI)\n-- ============================================================\nCREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n project_id TEXT NOT NULL REFERENCES projects(id),\n project_name TEXT NOT NULL,\n type TEXT NOT NULL,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n summary TEXT NOT NULL,\n bullets TEXT,\n confidence REAL NOT NULL,\n source TEXT NOT NULL DEFAULT 'llm',\n metadata TEXT,\n timestamp TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n scope TEXT NOT NULL DEFAULT 'session',\n analysis_version TEXT NOT NULL DEFAULT '1.0.0',\n linked_insight_ids TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_insights_session_id ON insights(session_id);\nCREATE INDEX IF NOT EXISTS idx_insights_project_id ON insights(project_id);\nCREATE INDEX IF NOT EXISTS idx_insights_type ON insights(type);\nCREATE INDEX IF NOT EXISTS idx_insights_timestamp ON insights(timestamp DESC);\n\n-- ============================================================\n-- Global usage stats (singleton row, updated by CLI sync)\n-- ============================================================\nCREATE TABLE IF NOT EXISTS usage_stats (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n total_input_tokens INTEGER DEFAULT 0,\n total_output_tokens INTEGER DEFAULT 0,\n cache_creation_tokens INTEGER DEFAULT 0,\n cache_read_tokens INTEGER DEFAULT 0,\n estimated_cost_usd REAL DEFAULT 0,\n sessions_with_usage INTEGER DEFAULT 0,\n last_updated_at TEXT DEFAULT (datetime('now'))\n);\n";
|
|
2
|
+
export declare const CURRENT_SCHEMA_VERSION = 1;
|
|
3
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,m9JA0HtB,CAAC;AAEF,eAAO,MAAM,sBAAsB,IAAI,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// SQL schema for local SQLite database at ~/.code-insights/data.db
|
|
2
|
+
// Mirrors Firestore collections but normalized into relational tables.
|
|
3
|
+
// All timestamps are ISO 8601 strings (SQLite has no native datetime).
|
|
4
|
+
// Arrays and nested objects are stored as JSON strings.
|
|
5
|
+
export const SCHEMA_SQL = `
|
|
6
|
+
-- ============================================================
|
|
7
|
+
-- Projects
|
|
8
|
+
-- ============================================================
|
|
9
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
10
|
+
id TEXT PRIMARY KEY,
|
|
11
|
+
name TEXT NOT NULL,
|
|
12
|
+
path TEXT NOT NULL,
|
|
13
|
+
git_remote_url TEXT,
|
|
14
|
+
project_id_source TEXT NOT NULL DEFAULT 'path-hash',
|
|
15
|
+
session_count INTEGER NOT NULL DEFAULT 0,
|
|
16
|
+
last_activity TEXT NOT NULL,
|
|
17
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
18
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
19
|
+
total_input_tokens INTEGER DEFAULT 0,
|
|
20
|
+
total_output_tokens INTEGER DEFAULT 0,
|
|
21
|
+
cache_creation_tokens INTEGER DEFAULT 0,
|
|
22
|
+
cache_read_tokens INTEGER DEFAULT 0,
|
|
23
|
+
estimated_cost_usd REAL DEFAULT 0
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
-- ============================================================
|
|
27
|
+
-- Sessions
|
|
28
|
+
-- ============================================================
|
|
29
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
32
|
+
project_name TEXT NOT NULL,
|
|
33
|
+
project_path TEXT NOT NULL,
|
|
34
|
+
git_remote_url TEXT,
|
|
35
|
+
summary TEXT,
|
|
36
|
+
custom_title TEXT,
|
|
37
|
+
generated_title TEXT,
|
|
38
|
+
title_source TEXT,
|
|
39
|
+
session_character TEXT,
|
|
40
|
+
started_at TEXT NOT NULL,
|
|
41
|
+
ended_at TEXT NOT NULL,
|
|
42
|
+
message_count INTEGER NOT NULL DEFAULT 0,
|
|
43
|
+
user_message_count INTEGER NOT NULL DEFAULT 0,
|
|
44
|
+
assistant_message_count INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
tool_call_count INTEGER NOT NULL DEFAULT 0,
|
|
46
|
+
git_branch TEXT,
|
|
47
|
+
claude_version TEXT,
|
|
48
|
+
source_tool TEXT NOT NULL DEFAULT 'claude-code',
|
|
49
|
+
device_id TEXT,
|
|
50
|
+
device_hostname TEXT,
|
|
51
|
+
device_platform TEXT,
|
|
52
|
+
synced_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
53
|
+
total_input_tokens INTEGER,
|
|
54
|
+
total_output_tokens INTEGER,
|
|
55
|
+
cache_creation_tokens INTEGER,
|
|
56
|
+
cache_read_tokens INTEGER,
|
|
57
|
+
estimated_cost_usd REAL,
|
|
58
|
+
models_used TEXT,
|
|
59
|
+
primary_model TEXT,
|
|
60
|
+
usage_source TEXT
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project_id ON sessions(project_id);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_started_at ON sessions(started_at DESC);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_source_tool ON sessions(source_tool);
|
|
66
|
+
|
|
67
|
+
-- ============================================================
|
|
68
|
+
-- Messages
|
|
69
|
+
-- ============================================================
|
|
70
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
71
|
+
id TEXT PRIMARY KEY,
|
|
72
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
73
|
+
type TEXT NOT NULL,
|
|
74
|
+
content TEXT NOT NULL DEFAULT '',
|
|
75
|
+
thinking TEXT,
|
|
76
|
+
tool_calls TEXT,
|
|
77
|
+
tool_results TEXT,
|
|
78
|
+
usage TEXT,
|
|
79
|
+
timestamp TEXT NOT NULL,
|
|
80
|
+
parent_id TEXT
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(session_id, timestamp ASC);
|
|
85
|
+
|
|
86
|
+
-- ============================================================
|
|
87
|
+
-- Insights (written by dashboard server, not CLI)
|
|
88
|
+
-- ============================================================
|
|
89
|
+
CREATE TABLE IF NOT EXISTS insights (
|
|
90
|
+
id TEXT PRIMARY KEY,
|
|
91
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
92
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
93
|
+
project_name TEXT NOT NULL,
|
|
94
|
+
type TEXT NOT NULL,
|
|
95
|
+
title TEXT NOT NULL,
|
|
96
|
+
content TEXT NOT NULL,
|
|
97
|
+
summary TEXT NOT NULL,
|
|
98
|
+
bullets TEXT,
|
|
99
|
+
confidence REAL NOT NULL,
|
|
100
|
+
source TEXT NOT NULL DEFAULT 'llm',
|
|
101
|
+
metadata TEXT,
|
|
102
|
+
timestamp TEXT NOT NULL,
|
|
103
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
104
|
+
scope TEXT NOT NULL DEFAULT 'session',
|
|
105
|
+
analysis_version TEXT NOT NULL DEFAULT '1.0.0',
|
|
106
|
+
linked_insight_ids TEXT
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
CREATE INDEX IF NOT EXISTS idx_insights_session_id ON insights(session_id);
|
|
110
|
+
CREATE INDEX IF NOT EXISTS idx_insights_project_id ON insights(project_id);
|
|
111
|
+
CREATE INDEX IF NOT EXISTS idx_insights_type ON insights(type);
|
|
112
|
+
CREATE INDEX IF NOT EXISTS idx_insights_timestamp ON insights(timestamp DESC);
|
|
113
|
+
|
|
114
|
+
-- ============================================================
|
|
115
|
+
-- Global usage stats (singleton row, updated by CLI sync)
|
|
116
|
+
-- ============================================================
|
|
117
|
+
CREATE TABLE IF NOT EXISTS usage_stats (
|
|
118
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
119
|
+
total_input_tokens INTEGER DEFAULT 0,
|
|
120
|
+
total_output_tokens INTEGER DEFAULT 0,
|
|
121
|
+
cache_creation_tokens INTEGER DEFAULT 0,
|
|
122
|
+
cache_read_tokens INTEGER DEFAULT 0,
|
|
123
|
+
estimated_cost_usd REAL DEFAULT 0,
|
|
124
|
+
sessions_with_usage INTEGER DEFAULT 0,
|
|
125
|
+
last_updated_at TEXT DEFAULT (datetime('now'))
|
|
126
|
+
);
|
|
127
|
+
`;
|
|
128
|
+
export const CURRENT_SCHEMA_VERSION = 1;
|
|
129
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,uEAAuE;AACvE,uEAAuE;AACvE,wDAAwD;AAExD,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0HzB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ParsedSession } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Upsert project record and insert session + messages.
|
|
4
|
+
* Replaces firebase/client.ts uploadSession() + uploadMessages().
|
|
5
|
+
*
|
|
6
|
+
* isForce: when true (--force sync), usage stats on the project are NOT
|
|
7
|
+
* incrementally added — they'll be recalculated via recalculateUsageStats().
|
|
8
|
+
*/
|
|
9
|
+
export declare function insertSessionWithProject(session: ParsedSession, isForce?: boolean): void;
|
|
10
|
+
/**
|
|
11
|
+
* Insert messages for a session.
|
|
12
|
+
* Replaces firebase/client.ts uploadMessages().
|
|
13
|
+
*/
|
|
14
|
+
export declare function insertMessages(session: ParsedSession): void;
|
|
15
|
+
/**
|
|
16
|
+
* After a --force sync, recalculate usage_stats singleton from all sessions.
|
|
17
|
+
* Also recalculates per-project usage totals.
|
|
18
|
+
*/
|
|
19
|
+
export declare function recalculateUsageStats(): {
|
|
20
|
+
sessionsWithUsage: number;
|
|
21
|
+
totalTokens: number;
|
|
22
|
+
estimatedCostUsd: number;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/db/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AA4JhE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,UAAQ,GAAG,IAAI,CAgBtF;AA8ED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAmC3D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAmHpH"}
|