ai-hist 0.6.0 → 0.8.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.
Files changed (58) hide show
  1. package/README.md +34 -254
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +248 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/cloud-client.d.ts +0 -1
  7. package/dist/cloud-client.d.ts.map +1 -1
  8. package/dist/cloud-client.js +0 -2
  9. package/dist/cloud-client.js.map +1 -1
  10. package/dist/index.d.ts +138 -309
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +258 -1191
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp-server.d.ts +0 -9
  15. package/dist/mcp-server.d.ts.map +1 -1
  16. package/dist/mcp-server.js +52 -790
  17. package/dist/mcp-server.js.map +1 -1
  18. package/package.json +14 -8
  19. package/dist/cloud-push.d.ts +0 -51
  20. package/dist/cloud-push.d.ts.map +0 -1
  21. package/dist/cloud-push.js +0 -113
  22. package/dist/cloud-push.js.map +0 -1
  23. package/dist/cloud-push.test.d.ts +0 -2
  24. package/dist/cloud-push.test.d.ts.map +0 -1
  25. package/dist/cloud-push.test.js +0 -82
  26. package/dist/cloud-push.test.js.map +0 -1
  27. package/dist/jsonl-sources.d.ts +0 -33
  28. package/dist/jsonl-sources.d.ts.map +0 -1
  29. package/dist/jsonl-sources.js +0 -351
  30. package/dist/jsonl-sources.js.map +0 -1
  31. package/dist/mcp-smoke.test.d.ts +0 -2
  32. package/dist/mcp-smoke.test.d.ts.map +0 -1
  33. package/dist/mcp-smoke.test.js +0 -574
  34. package/dist/mcp-smoke.test.js.map +0 -1
  35. package/dist/pair-client.d.ts +0 -41
  36. package/dist/pair-client.d.ts.map +0 -1
  37. package/dist/pair-client.js +0 -60
  38. package/dist/pair-client.js.map +0 -1
  39. package/dist/pair-client.test.d.ts +0 -2
  40. package/dist/pair-client.test.d.ts.map +0 -1
  41. package/dist/pair-client.test.js +0 -118
  42. package/dist/pair-client.test.js.map +0 -1
  43. package/dist/session-catalog.d.ts +0 -257
  44. package/dist/session-catalog.d.ts.map +0 -1
  45. package/dist/session-catalog.js +0 -340
  46. package/dist/session-catalog.js.map +0 -1
  47. package/dist/session-catalog.test.d.ts +0 -2
  48. package/dist/session-catalog.test.d.ts.map +0 -1
  49. package/dist/session-catalog.test.js +0 -710
  50. package/dist/session-catalog.test.js.map +0 -1
  51. package/dist/session-events.test.d.ts +0 -2
  52. package/dist/session-events.test.d.ts.map +0 -1
  53. package/dist/session-events.test.js +0 -177
  54. package/dist/session-events.test.js.map +0 -1
  55. package/dist/trajectory-sources.d.ts +0 -36
  56. package/dist/trajectory-sources.d.ts.map +0 -1
  57. package/dist/trajectory-sources.js +0 -201
  58. package/dist/trajectory-sources.js.map +0 -1
package/README.md CHANGED
@@ -1,267 +1,47 @@
1
- # ai-hist (TypeScript SDK and MCP server)
1
+ # ai-hist
2
2
 
3
- TypeScript reader for the [ai-hist](../README.md) history database, plus an MCP server for searching local AI coding-agent history from Claude Code, Codex, Cursor, Grok, and Agent Relay.
4
-
5
- The SDK uses `sql.js`, so it has no native build step. It reads the same SQLite file that `ai-hist sync` writes, or falls back to scanning local Claude/Codex/Cursor/Grok JSONL files and compacted trajectory JSON when the database is missing.
6
-
7
- ## Install
3
+ The public TypeScript SDK, Node CLI, and MCP server for RelayHistory. Every
4
+ operation uses the mandatory `ai-hist-native` Node-API engine; there is no
5
+ JavaScript SQLite implementation or provider-file fallback.
8
6
 
9
7
  ```bash
10
8
  npm install ai-hist
11
9
  ```
12
10
 
13
- ## Quick start
14
-
15
11
  ```ts
16
- import { openAiHist, resumeCommand } from 'ai-hist';
17
-
18
- const hist = await openAiHist(); // uses $AI_HIST_DB or ~/.local/share/ai-hist/ai-history.db
19
- try {
20
- const sessions = hist.listSessions({ limit: 20 });
21
- for (const s of sessions) {
22
- console.log(`[${s.source}] ${s.firstPrompt.slice(0, 60)} (${s.promptCount} prompts)`);
23
- console.log(' resume:', resumeCommand(s));
24
- }
25
- } finally {
26
- hist.close();
12
+ import {
13
+ discoverSessions,
14
+ listSessionCatalogPage,
15
+ getSession,
16
+ getSessionEventsPage,
17
+ sessionEvents,
18
+ search,
19
+ recent,
20
+ stats,
21
+ sync,
22
+ } from 'ai-hist';
23
+
24
+ await discoverSessions({ limit: 100 });
25
+ const page = await listSessionCatalogPage({ limit: 20 });
26
+ const first = page.sessions[0];
27
+ if (first) {
28
+ const prompts = await getSession(first.sessionId);
29
+ const events = await getSessionEventsPage(first.sessionId, { limit: 200 });
30
+ for await (const event of sessionEvents(first.sessionId)) consume(event);
27
31
  }
28
32
  ```
29
33
 
30
- To require the ai-hist SQLite database instead of JSONL fallback:
31
-
32
- ```ts
33
- const hist = await openAiHist({ fallback: 'error' });
34
- ```
35
-
36
- ## MCP server
37
-
38
- After the package is published, run the local stdio MCP server with:
39
-
40
- ```bash
41
- npx -y ai-hist-mcp
42
- ```
43
-
44
- From a local checkout:
45
-
46
- ```bash
47
- npm install
48
- npm run build
49
- node dist/mcp-server.js
50
- ```
51
-
52
- The MCP server exposes tools for search, recent history, the session catalog, session lookup, temporal context, evidence packing, stats, trajectory search, and task WHY lookup over stdio. It runs on the user's machine and uses the same data-opening behavior as the SDK: SQLite first, then local fallback scanning.
53
-
54
- To expose only one project through MCP, pass a project scope when launching the server. Exact project matches and child paths are included.
55
-
56
- ```bash
57
- npx -y ai-hist-mcp --project .
58
- npx -y ai-hist-mcp --project /path/to/project
59
- ```
60
-
61
- Contract tools:
62
-
63
- - `search_history(query, limit?)`
64
- - `recent_entries(limit?, project?)`
65
- - `get_session(session_id)`
66
- - `get_context(id)`
67
- - `stats()`
68
- - `search_trajectories(query, limit?)`
69
- - `why_for_task(query)`
70
- - `list_sessions(sources?, limit?, before_ms?, after?)`
71
-
72
- ## Session catalog
73
-
74
- `sessions` is a materialized catalog of every coding-agent session ai-hist knows about — one row per `(source, session_id)`, with cwd, git branch, first/last activity, the first prompt, observed models, originator, agent version, and repo identity. It is populated by shallow discovery (cheap, metadata only) and upgraded in place by a full `ai-hist sync`. `discoveryState` says which you are looking at: `'shallow'` for a catalog row whose transcript has not been ingested, `'full'` once it has (rows written before the catalog existed store `NULL` and read as `'full'`).
75
-
76
- Reading it is one indexed query over a single table — no provider transcript is opened and no prompt history is scanned — so it is the fast path for "which sessions exist?" on first paint:
77
-
78
- ```ts
79
- import { openAiHist, discoverSessions, SESSION_CATALOG_CONTRACT_VERSION } from 'ai-hist';
80
-
81
- const hist = await openAiHist();
82
- for (const s of hist.listSessionCatalog({ limit: 20 })) {
83
- console.log(s.lastActivityMs, s.source, s.sessionId, s.cwd, s.firstPrompt);
84
- }
85
- ```
86
-
87
- The catalog's total order is `(lastActivityMs DESC, source ASC, sessionId ASC)`, with rows of unknown recency last. Recency alone is not a key: one discovery pass can stamp many sessions with the same mtime-derived millisecond, so paginate with `listSessionCatalogPage` and follow its cursor, which carries all three columns:
88
-
89
- ```ts
90
- let after;
91
- for (;;) {
92
- const page = hist.listSessionCatalogPage({ limit: 20, after });
93
- render(page.sessions);
94
- if (!page.nextCursor) break; // null once the catalog is exhausted
95
- after = page.nextCursor; // { lastActivityMs, source, sessionId }
96
- }
97
- ```
98
-
99
- `nextCursor` is non-null only when the page filled its limit, so the loop terminates on an empty catalog and on a null-timestamp tail alike — both cases where a `beforeMs`-only walk either spins forever or silently drops the rows tied with a page boundary. `beforeMs` survives as a *coarse* cutoff ("anything before last Tuesday") and is ignored when `after` is set. The same contract is available from the CLI as the `next_cursor` field of `sessions list --json`, fed back as `--after-source` + `--after-session-id` (both required together, and `--after-ms` alone is refused — a timestamp is not a cursor). Omit `--after-ms` to continue through the undated tail.
100
-
101
- `trajectory` rows are excluded — trajectories are derived records, not sessions. A configured `projectScope` constrains rows by `cwd`, so sources with no working directory (relay) drop out of a scoped listing. A negative `limit` throws (SQLite would read it as "unlimited"). In JSONL fallback mode (no SQLite database) the catalog is empty and the methods return no rows; only the native discovery engine writes it.
102
-
103
- To populate or refresh the catalog, run shallow discovery. It scans the known provider locations with bounded reads, orders candidates globally by recency before applying the limit, and skips sources whose bytes have not changed since the last run:
104
-
105
- ```ts
106
- const { sessions, diagnostics, summary } = await discoverSessions({
107
- sources: ['claude', 'codex'], // omit for every discoverable source
108
- limit: 50, // global across providers, by recency
109
- onSession: (s) => render(s), // streams as rows arrive
110
- });
111
-
112
- console.log(summary.discovered, summary.skippedUnchanged, summary.counters.bytesRead);
113
- for (const d of diagnostics) console.warn(`[${d.source}] ${d.locator ?? ''}: ${d.error}`);
114
- ```
115
-
116
- `discoverSessions` is a top-level function, not an `AiHist` method: it drives `ai-hist sessions discover --json` (binary discovery is `$AI_HIST_RUST_BIN` → the install.sh location → `ai-hist` on `PATH`, the same as `pushToCloud`), and that writes the on-disk database. An `AiHist` instance is an in-memory snapshot taken at open time, so re-open it before listing to see freshly discovered rows.
117
-
118
- Failure behavior matches the CLI's: one provider blowing up yields a diagnostic and the run still resolves. The promise rejects with a `DiscoveryError` when the binary cannot be run at all (the message names `AI_HIST_RUST_BIN`), when the run exits non-zero because every selected provider failed, or when the closing summary is missing or announces a contract version this SDK does not implement — the version is checked for you against `SESSION_CATALOG_CONTRACT_VERSION` rather than left as a field to remember. The native command writes its diagnostics and summary trailer even on an all-provider failure, so a `DiscoveryError` carries `diagnostics`, `summary`, `stderr`, and `exitCode`. Unparseable or unrecognized JSONL lines are skipped rather than failing the run.
119
-
120
- An exception thrown by `onSession` or `onDiagnostic` aborts the run: the child process is killed and the promise rejects with your error, instead of escaping the stream handler as an uncaught exception in the host.
121
-
122
- ## API
123
-
124
- ```ts
125
- openAiHist(opts?: {
126
- dbPath?: string;
127
- projectScope?: string;
128
- fallback?: 'jsonl' | 'error';
129
- }): Promise<AiHist>
130
-
131
- hist.close(): void
132
- hist.dbPath: string
133
- hist.sourceKind: 'sqlite' | 'jsonl'
134
- hist.projectScope: string | undefined
135
-
136
- hist.recent(opts?): HistoryEntry[] // newest prompts first
137
- hist.listSessions(opts?): SessionSummary[] // grouped from history by session_id, last activity DESC
138
- hist.listSessionCatalog(opts?): CatalogSession[] // the sessions catalog: cache-only, one indexed query
139
- hist.listSessionCatalogPage(opts?): SessionCatalogPage // the same page plus its nextCursor
140
- hist.getSession(sessionId): HistoryEntry[] // all prompts in a session, oldest first
141
- hist.getSessionEvents(sessionId): SessionEvent[] // full transcript: text, thinking, tool calls/results, token usage
142
- hist.getToolCalls(sessionId): SessionToolCall[] // the session's tool invocations
143
- hist.getEntry(id): HistoryEntry | null
144
- hist.getInTimeWindow(timestampMs, windowMs): HistoryEntry[]
145
- hist.search(query, opts?): HistoryEntry[] // literal substring search, recent matches first
146
- hist.searchTrajectories(query, opts?): TrajectoryEntry[]
147
- hist.whyForTask(query): TrajectoryEntry | null
148
- hist.stats(): Stats // counts + date range
149
- ```
150
-
151
- All list-style methods accept `{ source?, project?, limit?, beforeMs? }`. `beforeMs` is the cursor for paginating older results.
152
-
153
- The catalog methods take `{ sources?, limit?, beforeMs?, after? }` instead — they filter on the catalog's own `source` column, not on project, and `after` is the cursor for paging.
154
-
155
- ```ts
156
- resumeCommand(entry): string | null // shell command per source; null for relay
157
- defaultDbPath(): string // resolve env / OS default
158
- discoverSessions(opts?): Promise<DiscoverResult> // drives `ai-hist sessions discover --json`
159
- SESSION_CATALOG_CONTRACT_VERSION: number // native session-catalog output contract (1)
160
- DiscoveryError // thrown by discoverSessions; carries diagnostics + summary
161
- ```
162
-
163
- ## Trajectories
164
-
165
- ai-hist indexes compacted per-run trajectory JSON files as the decision WHY. Set `TRAJECTORY_ROOT` to an explicit root; the scanner reads:
166
-
167
- ```text
168
- $TRAJECTORY_ROOT/**/compacted/*.json
169
- ```
170
-
171
- Without `TRAJECTORY_ROOT`, default discovery scans:
172
-
173
- ```text
174
- ~/Projects/**/.trajectories/**/compacted/*.json
175
- ```
176
-
177
- The runtime contract is one JSON file per completed run:
178
-
179
- ```json
180
- {
181
- "id": "run-id",
182
- "version": 1,
183
- "personaId": "planner",
184
- "projectId": "agent-workforce",
185
- "task": { "title": "Task title", "description": "Task description" },
186
- "status": "completed",
187
- "startedAt": "2026-06-06T10:00:00.000Z",
188
- "completedAt": "2026-06-06T10:05:00.000Z",
189
- "decisions": [
190
- {
191
- "question": "What should we do?",
192
- "chosen": "Chosen option",
193
- "reasoning": "Why this option won",
194
- "alternatives": ["Other option"]
195
- }
196
- ],
197
- "retrospective": {
198
- "summary": "What happened",
199
- "approach": "How the work was done",
200
- "learnings": ["What to carry forward"],
201
- "confidence": 0.8
202
- }
203
- }
204
- ```
205
-
206
- ## Schema
207
-
208
- The canonical ai-hist SQLite schema is:
209
-
210
- ```sql
211
- CREATE TABLE history (
212
- id INTEGER PRIMARY KEY AUTOINCREMENT,
213
- source TEXT NOT NULL,
214
- session_id TEXT,
215
- project TEXT,
216
- prompt TEXT NOT NULL,
217
- prompt_hash TEXT,
218
- timestamp_ms INTEGER NOT NULL,
219
- UNIQUE(source, timestamp_ms, prompt)
220
- );
221
-
222
- CREATE VIRTUAL TABLE history_fts USING fts5(prompt, project, content='history', content_rowid='id');
223
-
224
- CREATE TABLE sessions (
225
- session_id TEXT NOT NULL,
226
- source TEXT NOT NULL,
227
- cwd TEXT,
228
- git_branch TEXT,
229
- first_activity_ms INTEGER,
230
- last_activity_ms INTEGER,
231
- last_assistant_text TEXT,
232
- raw_path TEXT,
233
- parser_version INTEGER NOT NULL DEFAULT 1,
234
- first_prompt TEXT,
235
- models_json TEXT,
236
- originator TEXT,
237
- agent_version TEXT,
238
- repo_url TEXT,
239
- initial_commit TEXT,
240
- workspace_roots_json TEXT,
241
- source_stamp TEXT,
242
- discovery_state TEXT,
243
- PRIMARY KEY (session_id, source)
244
- );
245
-
246
- CREATE INDEX idx_sessions_recency ON sessions(last_activity_ms DESC, source, session_id);
247
- CREATE INDEX idx_sessions_source_recency ON sessions(source, last_activity_ms DESC, session_id);
248
- CREATE INDEX idx_sessions_source_last ON sessions(source, last_activity_ms DESC);
249
- CREATE INDEX idx_sessions_raw_path ON sessions(source, raw_path);
250
-
251
- CREATE TABLE discovery_skips (
252
- source TEXT NOT NULL,
253
- locator TEXT NOT NULL,
254
- stamp TEXT NOT NULL,
255
- reason TEXT,
256
- updated_ms INTEGER,
257
- PRIMARY KEY (source, locator)
258
- );
259
- ```
260
-
261
- `models_json` and `workspace_roots_json` hold JSON string arrays or `NULL` (never `[]`); the SDK parses both into arrays. The catalog columns were added after 0.5.0, so when the SDK opens an older database file it backfills the missing columns on its in-memory copy with `ALTER TABLE` — the file on disk is not touched, and the absent values read as `NULL`.
34
+ All APIs are async. `listSessionCatalog` and `listSessionCatalogPage` are
35
+ cache-only. `discoverSessions` is shallow discovery. `sync` is full ingestion.
36
+ Missing databases return empty read results; they do not trigger provider I/O.
262
37
 
263
- Trajectory sync also creates a structured `trajectories` table and inserts each per-run compact file into `history` with `source='trajectory'`, so general history search and WHY-specific lookup both work.
38
+ The event primitive is page-based and uses `{ tsMs, id }` as a deterministic
39
+ cursor. The `sessionEvents` async iterator walks pages without accumulating a
40
+ large transcript. `getSessionEvents` is an explicit collecting convenience.
264
41
 
265
- ## License
42
+ Native loading failures distinguish unsupported platforms, missing optional
43
+ platform packages, addon load failures, SDK/native contract mismatches, and
44
+ database open failures through stable `RelayHistoryError` subclasses.
266
45
 
267
- MIT
46
+ The old synchronous `AiHist` class and `openAiHist()` API were removed in 1.0.
47
+ See [the migration guide](https://github.com/AgentWorkforce/relayhistory/blob/main/docs/native-sdk-migration.md).
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from 'node:fs/promises';
3
+ import { discoverSessions, getSession, getSessionEventsPage, listSessionCatalogPage, recent, search, stats, sync, } from './index.js';
4
+ function versionTriple(value) {
5
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(value);
6
+ return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
7
+ }
8
+ function newerVersion(current, latest) {
9
+ const left = versionTriple(current);
10
+ const right = versionTriple(latest);
11
+ if (!left || !right)
12
+ return false;
13
+ for (let index = 0; index < left.length; index++) {
14
+ if (right[index] !== left[index])
15
+ return right[index] > left[index];
16
+ }
17
+ return false;
18
+ }
19
+ async function packageVersion() {
20
+ const contents = await readFile(new URL('../package.json', import.meta.url), 'utf8');
21
+ return JSON.parse(contents).version ?? 'unknown';
22
+ }
23
+ async function maybePrintUpdateNotice(current, args) {
24
+ const optOut = process.env.RELAYHISTORY_NO_UPDATE_CHECK;
25
+ if (!process.stderr.isTTY || args.includes('--no-warning') || (optOut && optOut !== '0'))
26
+ return;
27
+ try {
28
+ const response = await fetch('https://registry.npmjs.org/ai-hist/latest', {
29
+ signal: AbortSignal.timeout(3_000),
30
+ headers: { accept: 'application/json' },
31
+ });
32
+ if (!response.ok)
33
+ return;
34
+ const latest = (await response.json());
35
+ if (!latest.version || !newerVersion(current, latest.version))
36
+ return;
37
+ process.stderr.write(`\nA new version of ai-hist is available: ${current} -> ${latest.version}\n` +
38
+ 'Update with:\n npm install --global ai-hist@latest\n' +
39
+ '(pass --no-warning or set RELAYHISTORY_NO_UPDATE_CHECK=1 to hide this notice)\n');
40
+ }
41
+ catch {
42
+ // Version checks are best-effort; --version stays useful while offline.
43
+ }
44
+ }
45
+ function parse(argv) {
46
+ const positional = [];
47
+ const flags = new Map();
48
+ for (let i = 0; i < argv.length; i++) {
49
+ const arg = argv[i];
50
+ if (!arg.startsWith('--')) {
51
+ positional.push(arg);
52
+ continue;
53
+ }
54
+ const [name, inline] = arg.slice(2).split('=', 2);
55
+ if (inline !== undefined) {
56
+ flags.set(name, [...(flags.get(name) ?? []), inline]);
57
+ continue;
58
+ }
59
+ const next = argv[i + 1];
60
+ if (next && !next.startsWith('-')) {
61
+ flags.set(name, [...(flags.get(name) ?? []), next]);
62
+ i++;
63
+ }
64
+ else
65
+ flags.set(name, [...(flags.get(name) ?? []), true]);
66
+ }
67
+ return { positional, flags };
68
+ }
69
+ function textFlag(args, name) {
70
+ const value = args.flags.get(name)?.at(-1);
71
+ return typeof value === 'string' ? value : undefined;
72
+ }
73
+ function textFlags(args, name) {
74
+ return (args.flags.get(name) ?? []).filter((value) => typeof value === 'string');
75
+ }
76
+ function numberFlag(args, name) {
77
+ const value = textFlag(args, name);
78
+ if (value === undefined)
79
+ return undefined;
80
+ const parsed = Number(value);
81
+ if (!Number.isFinite(parsed))
82
+ throw new Error(`--${name} must be a number`);
83
+ return parsed;
84
+ }
85
+ function common(args) {
86
+ return {
87
+ dbPath: textFlag(args, 'db'),
88
+ source: textFlag(args, 'source'),
89
+ project: textFlag(args, 'project'),
90
+ tag: textFlag(args, 'tag'),
91
+ limit: numberFlag(args, 'limit'),
92
+ beforeMs: numberFlag(args, 'before-ms'),
93
+ };
94
+ }
95
+ function snakeCase(key) {
96
+ return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
97
+ }
98
+ function wireValue(value) {
99
+ if (Array.isArray(value))
100
+ return value.map(wireValue);
101
+ if (!value || typeof value !== 'object')
102
+ return value;
103
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [snakeCase(key), wireValue(item)]));
104
+ }
105
+ function humanLine(value) {
106
+ if (!value || typeof value !== 'object')
107
+ return String(value);
108
+ const row = value;
109
+ return [row.timestampMs ?? row.lastActivityMs ?? '', row.source ?? '', row.sessionId ?? '', row.project ?? row.cwd ?? '', row.prompt ?? row.firstPrompt ?? '']
110
+ .filter((item) => item !== '' && item != null)
111
+ .join(' ');
112
+ }
113
+ function output(value, json) {
114
+ if (json) {
115
+ process.stdout.write(`${JSON.stringify(wireValue(value))}\n`);
116
+ }
117
+ else if (Array.isArray(value)) {
118
+ process.stdout.write(value.length ? `${value.map(humanLine).join('\n')}\n` : 'No results.\n');
119
+ }
120
+ else if (typeof value === 'object' && value !== null) {
121
+ const record = value;
122
+ if (Array.isArray(record.sessions)) {
123
+ process.stdout.write(record.sessions.length ? `${record.sessions.map(humanLine).join('\n')}\n` : 'No sessions in the catalog.\n');
124
+ if (record.nextCursor)
125
+ process.stdout.write(`more available: --after '${JSON.stringify(record.nextCursor)}'\n`);
126
+ }
127
+ else {
128
+ process.stdout.write(`${Object.entries(record).map(([key, item]) => `${key}: ${typeof item === 'object' ? JSON.stringify(item) : String(item)}`).join('\n')}\n`);
129
+ }
130
+ }
131
+ else {
132
+ process.stdout.write(`${String(value)}\n`);
133
+ }
134
+ }
135
+ function usage() {
136
+ process.stderr.write(`Usage:
137
+ ai-hist sessions list [--source SOURCE]... [--limit N] [--before-ms MS] [--after JSON | --after-source SOURCE --after-session-id ID [--after-ms MS]] [--json]
138
+ ai-hist sessions discover [--source SOURCE] [--limit N] [--json]
139
+ ai-hist search QUERY... [--source SOURCE] [--project PATH] [--limit N] [--json]
140
+ ai-hist recent [N] [--source SOURCE] [--project PATH] [--json]
141
+ ai-hist session SESSION_ID [--source SOURCE] [--json]
142
+ ai-hist events SESSION_ID [--source SOURCE] [--limit N] [--after JSON] [--json]
143
+ ai-hist stats [--json]
144
+ ai-hist sync [--db PATH] [--json]
145
+ `);
146
+ process.exit(2);
147
+ }
148
+ function cursorFlag(args) {
149
+ const raw = textFlag(args, 'after');
150
+ return raw ? JSON.parse(raw) : undefined;
151
+ }
152
+ function catalogCursorFlag(args) {
153
+ const encoded = cursorFlag(args);
154
+ if (encoded)
155
+ return encoded;
156
+ const source = textFlag(args, 'after-source');
157
+ const sessionId = textFlag(args, 'after-session-id');
158
+ if (!source && !sessionId)
159
+ return undefined;
160
+ if (!source || !sessionId)
161
+ throw new Error('--after-source and --after-session-id must be used together');
162
+ return { lastActivityMs: numberFlag(args, 'after-ms') ?? null, source, sessionId };
163
+ }
164
+ function outputDiscovery(value, json) {
165
+ if (!json) {
166
+ for (const session of value.sessions)
167
+ process.stdout.write(`${humanLine(session)}\n`);
168
+ process.stdout.write(`${value.sessions.length} session(s): ${value.discovered} discovered, ${value.skippedUnchanged} unchanged\n`);
169
+ return;
170
+ }
171
+ for (const session of value.sessions)
172
+ output({ type: 'session', ...session }, true);
173
+ for (const diagnostic of value.diagnostics)
174
+ output({ type: 'diagnostic', ...diagnostic }, true);
175
+ const { sessions: _sessions, diagnostics: _diagnostics, ...summary } = value;
176
+ const providers = Object.fromEntries(summary.providers.map(({ source, ...provider }) => [source, provider]));
177
+ output({ type: 'summary', ...summary, providers }, true);
178
+ }
179
+ async function main() {
180
+ const rawArgs = process.argv.slice(2);
181
+ if (rawArgs.includes('--version') || rawArgs.includes('-V')) {
182
+ const version = await packageVersion();
183
+ process.stdout.write(`ai-hist ${version}\n`);
184
+ await maybePrintUpdateNotice(version, rawArgs);
185
+ return;
186
+ }
187
+ const args = parse(rawArgs);
188
+ const [command, subcommand, ...rest] = args.positional;
189
+ const json = args.flags.has('json');
190
+ if (command === 'sessions' && subcommand === 'list') {
191
+ const sources = textFlags(args, 'source');
192
+ output(await listSessionCatalogPage({
193
+ dbPath: textFlag(args, 'db'), sources: sources.length ? sources : undefined,
194
+ limit: numberFlag(args, 'limit'), beforeMs: numberFlag(args, 'before-ms'),
195
+ after: catalogCursorFlag(args),
196
+ }), json);
197
+ return;
198
+ }
199
+ if (command === 'sessions' && subcommand === 'discover') {
200
+ const sources = textFlags(args, 'source');
201
+ outputDiscovery(await discoverSessions({
202
+ dbPath: textFlag(args, 'db'), sources: sources.length ? sources : undefined,
203
+ limit: numberFlag(args, 'limit'),
204
+ }), json);
205
+ return;
206
+ }
207
+ if (command === 'search') {
208
+ if (!subcommand)
209
+ usage();
210
+ output(await search([subcommand, ...rest].join(' '), { ...common(args), rawFts: args.flags.has('fts') }), json);
211
+ return;
212
+ }
213
+ if (command === 'recent') {
214
+ const fallback = subcommand ? Number(subcommand) : undefined;
215
+ output(await recent({ ...common(args), limit: numberFlag(args, 'limit') ?? fallback }), json);
216
+ return;
217
+ }
218
+ if (command === 'session') {
219
+ if (!subcommand)
220
+ usage();
221
+ output(await getSession(subcommand, { dbPath: textFlag(args, 'db'), source: textFlag(args, 'source'), tag: textFlag(args, 'tag') }), json);
222
+ return;
223
+ }
224
+ if (command === 'events') {
225
+ if (!subcommand)
226
+ usage();
227
+ output(await getSessionEventsPage(subcommand, {
228
+ dbPath: textFlag(args, 'db'), source: textFlag(args, 'source'),
229
+ limit: numberFlag(args, 'limit'), after: cursorFlag(args),
230
+ }), json);
231
+ return;
232
+ }
233
+ if (command === 'stats') {
234
+ output(await stats({ dbPath: textFlag(args, 'db'), tag: textFlag(args, 'tag') }), json);
235
+ return;
236
+ }
237
+ if (command === 'sync') {
238
+ output(await sync({ dbPath: textFlag(args, 'db') }), json);
239
+ return;
240
+ }
241
+ usage();
242
+ }
243
+ main().catch((error) => {
244
+ const value = error;
245
+ process.stderr.write(`ai-hist: ${value.code ? `${value.code}: ` : ''}${value.message ?? String(error)}\n`);
246
+ process.exitCode = 1;
247
+ });
248
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EACL,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAE,sBAAsB,EAC1E,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAC5B,MAAM,YAAY,CAAC;AAMpB,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/E,CAAC;AAED,SAAS,YAAY,CAAC,OAAe,EAAE,MAAc;IACnD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAClC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IACrF,OAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAqB,CAAC,OAAO,IAAI,SAAS,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,OAAe,EAAE,IAAc;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IACxD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,GAAG,CAAC;QAAE,OAAO;IACjG,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,2CAA2C,EAAE;YACxE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;YAClC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO;QACzB,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAoB,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;YAAE,OAAO;QACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4CAA4C,OAAO,OAAO,MAAM,CAAC,OAAO,IAAI;YAC5E,uDAAuD;YACvD,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;IAC1E,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,IAAc;IAC3B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgC,CAAC;IACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9D,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9F,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;;YAC3F,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAY;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,IAAY;IAC3C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,IAAY;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,mBAAmB,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;QAC5B,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAU;QACzC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QAClC,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAC1B,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;QAChC,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;SAC3J,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC;SAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,IAAa;IAC3C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAChG,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,KAAgC,CAAC;QAChD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC;YAClI,IAAI,MAAM,CAAC,UAAU;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAClH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnK,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,KAAK;IACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;CAStB,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CAAI,IAAY;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,UAAU,CAAgB,IAAI,CAAC,CAAC;IAChD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC1G,OAAO,EAAE,cAAc,EAAE,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,eAAe,CAAC,KAAmD,EAAE,IAAa;IACzF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,gBAAgB,KAAK,CAAC,UAAU,gBAAgB,KAAK,CAAC,gBAAgB,cAAc,CAAC,CAAC;QACnI,OAAO;IACT,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACpF,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,WAAW;QAAE,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;IAChG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC;IAC7E,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7G,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,IAAI,CAAC,CAAC;QAC7C,MAAM,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEpC,IAAI,OAAO,KAAK,UAAU,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,sBAAsB,CAAC;YAClC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC,SAAS;YACpF,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC;YACzE,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC;SAC/B,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,UAAU,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,eAAe,CAAC,MAAM,gBAAgB,CAAC;YACrC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC,SAAS;YACpF,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;SACjC,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU;YAAE,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAChH,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7D,MAAM,CAAC,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9F,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU;YAAE,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,MAAM,UAAU,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACpJ,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU;YAAE,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,MAAM,oBAAoB,CAAC,UAAU,EAAE;YAC5C,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAU;YACvE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC;SAC1D,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAC7H,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAC/F,KAAK,EAAE,CAAC;AACV,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,KAAK,GAAG,KAA4C,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3G,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -1,4 +1,3 @@
1
- export { pushToCloud, resolveAiHistBinary, type PushReport, type PushOptions } from './cloud-push.js';
2
1
  export interface RelayhistoryAuth {
3
2
  baseUrl: string;
4
3
  accessToken: string;
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-client.d.ts","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEtG,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAajC,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CASnF;AAED,wBAAsB,UAAU,CAC9B,gBAAgB,EAAE,MAAM,EACxB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAkD3B"}
1
+ {"version":3,"file":"cloud-client.d.ts","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAajC,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CASnF;AAED,wBAAsB,UAAU,CAC9B,gBAAgB,EAAE,MAAM,EACxB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAkD3B"}
@@ -1,8 +1,6 @@
1
1
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
2
  import { homedir } from 'node:os';
3
3
  import { join, dirname } from 'node:path';
4
- // Re-export the in-process cloud push so `ai-hist/cloud` exposes auth + push.
5
- export { pushToCloud, resolveAiHistBinary } from './cloud-push.js';
6
4
  function authPath() {
7
5
  const configDir = process.env.AI_HIST_CONFIG_DIR ?? join(homedir(), '.config', 'ai-hist');
8
6
  return join(configDir, 'auth.json');
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"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"}