@nocoo/pew 0.2.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.
Files changed (69) hide show
  1. package/dist/bin.d.ts +3 -0
  2. package/dist/bin.d.ts.map +1 -0
  3. package/dist/bin.js +5 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +221 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/login.d.ts +34 -0
  10. package/dist/commands/login.d.ts.map +1 -0
  11. package/dist/commands/login.js +108 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/status.d.ts +19 -0
  14. package/dist/commands/status.d.ts.map +1 -0
  15. package/dist/commands/status.js +35 -0
  16. package/dist/commands/status.js.map +1 -0
  17. package/dist/commands/sync.d.ts +49 -0
  18. package/dist/commands/sync.d.ts.map +1 -0
  19. package/dist/commands/sync.js +267 -0
  20. package/dist/commands/sync.js.map +1 -0
  21. package/dist/commands/upload.d.ts +53 -0
  22. package/dist/commands/upload.d.ts.map +1 -0
  23. package/dist/commands/upload.js +185 -0
  24. package/dist/commands/upload.js.map +1 -0
  25. package/dist/config/manager.d.ts +14 -0
  26. package/dist/config/manager.d.ts.map +1 -0
  27. package/dist/config/manager.js +32 -0
  28. package/dist/config/manager.js.map +1 -0
  29. package/dist/discovery/sources.d.ts +37 -0
  30. package/dist/discovery/sources.d.ts.map +1 -0
  31. package/dist/discovery/sources.js +110 -0
  32. package/dist/discovery/sources.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/parsers/claude.d.ts +34 -0
  38. package/dist/parsers/claude.d.ts.map +1 -0
  39. package/dist/parsers/claude.js +101 -0
  40. package/dist/parsers/claude.js.map +1 -0
  41. package/dist/parsers/gemini.d.ts +38 -0
  42. package/dist/parsers/gemini.d.ts.map +1 -0
  43. package/dist/parsers/gemini.js +142 -0
  44. package/dist/parsers/gemini.js.map +1 -0
  45. package/dist/parsers/openclaw.d.ts +23 -0
  46. package/dist/parsers/openclaw.d.ts.map +1 -0
  47. package/dist/parsers/openclaw.js +85 -0
  48. package/dist/parsers/openclaw.js.map +1 -0
  49. package/dist/parsers/opencode.d.ts +35 -0
  50. package/dist/parsers/opencode.d.ts.map +1 -0
  51. package/dist/parsers/opencode.js +118 -0
  52. package/dist/parsers/opencode.js.map +1 -0
  53. package/dist/storage/cursor-store.d.ts +14 -0
  54. package/dist/storage/cursor-store.d.ts.map +1 -0
  55. package/dist/storage/cursor-store.js +34 -0
  56. package/dist/storage/cursor-store.js.map +1 -0
  57. package/dist/storage/local-queue.d.ts +30 -0
  58. package/dist/storage/local-queue.d.ts.map +1 -0
  59. package/dist/storage/local-queue.js +70 -0
  60. package/dist/storage/local-queue.js.map +1 -0
  61. package/dist/utils/buckets.d.ts +17 -0
  62. package/dist/utils/buckets.d.ts.map +1 -0
  63. package/dist/utils/buckets.js +38 -0
  64. package/dist/utils/buckets.js.map +1 -0
  65. package/dist/utils/paths.d.ts +17 -0
  66. package/dist/utils/paths.d.ts.map +1 -0
  67. package/dist/utils/paths.js +21 -0
  68. package/dist/utils/paths.js.map +1 -0
  69. package/package.json +44 -0
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { runMain } from "citty";
3
+ import { main } from "./cli.js";
4
+ runMain(main);
5
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const main: import("citty").CommandDef<import("citty").ArgsDef>;
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAmPA,eAAO,MAAM,IAAI,qDAWf,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,221 @@
1
+ import { defineCommand } from "citty";
2
+ import { consola } from "consola";
3
+ import pc from "picocolors";
4
+ import { resolveDefaultPaths } from "./utils/paths.js";
5
+ import { executeSync } from "./commands/sync.js";
6
+ import { executeStatus } from "./commands/status.js";
7
+ import { executeLogin, resolveHost } from "./commands/login.js";
8
+ import { executeUpload } from "./commands/upload.js";
9
+ // ---------------------------------------------------------------------------
10
+ // Dev mode detection (otter pattern)
11
+ // ---------------------------------------------------------------------------
12
+ function isDevMode() {
13
+ return process.argv.includes("--dev");
14
+ }
15
+ // Allow self-signed certs (mkcert) in dev mode
16
+ if (isDevMode()) {
17
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
18
+ }
19
+ const syncCommand = defineCommand({
20
+ meta: {
21
+ name: "sync",
22
+ description: "Parse local AI tool usage and upload to dashboard",
23
+ },
24
+ args: {
25
+ upload: {
26
+ type: "boolean",
27
+ description: "Upload to dashboard after syncing (default: true if logged in)",
28
+ default: true,
29
+ },
30
+ dev: {
31
+ type: "boolean",
32
+ description: "Use the dev host (pew.dev.hexly.ai)",
33
+ default: false,
34
+ },
35
+ },
36
+ async run({ args }) {
37
+ const paths = resolveDefaultPaths();
38
+ consola.start("Syncing token usage from AI coding tools...\n");
39
+ const result = await executeSync({
40
+ stateDir: paths.stateDir,
41
+ claudeDir: paths.claudeDir,
42
+ geminiDir: paths.geminiDir,
43
+ openCodeMessageDir: paths.openCodeMessageDir,
44
+ openclawDir: paths.openclawDir,
45
+ onProgress(event) {
46
+ if (event.phase === "parse" && event.current && event.total) {
47
+ // Only log at 25% intervals or small counts
48
+ if (event.total <= 10 ||
49
+ event.current === event.total ||
50
+ event.current % Math.ceil(event.total / 4) === 0) {
51
+ consola.info(` ${pc.cyan(event.source)} ${event.current}/${event.total} files`);
52
+ }
53
+ }
54
+ },
55
+ });
56
+ // Summary
57
+ consola.log("");
58
+ if (result.totalDeltas === 0) {
59
+ consola.info("No new token usage found.");
60
+ }
61
+ else {
62
+ consola.success(`Synced ${pc.bold(String(result.totalDeltas))} new events → ${pc.bold(String(result.totalRecords))} queue records`);
63
+ const deltaParts = [];
64
+ if (result.sources.claude > 0)
65
+ deltaParts.push(`Claude: ${result.sources.claude}`);
66
+ if (result.sources.gemini > 0)
67
+ deltaParts.push(`Gemini: ${result.sources.gemini}`);
68
+ if (result.sources.opencode > 0)
69
+ deltaParts.push(`OpenCode: ${result.sources.opencode}`);
70
+ if (result.sources.openclaw > 0)
71
+ deltaParts.push(`OpenClaw: ${result.sources.openclaw}`);
72
+ if (deltaParts.length > 0) {
73
+ consola.info(` ${pc.dim(deltaParts.join(" | "))}`);
74
+ }
75
+ }
76
+ // Always show files scanned
77
+ const fs = result.filesScanned;
78
+ const scanParts = [];
79
+ if (fs.claude > 0)
80
+ scanParts.push(`Claude: ${fs.claude}`);
81
+ if (fs.gemini > 0)
82
+ scanParts.push(`Gemini: ${fs.gemini}`);
83
+ if (fs.opencode > 0)
84
+ scanParts.push(`OpenCode: ${fs.opencode}`);
85
+ if (fs.openclaw > 0)
86
+ scanParts.push(`OpenClaw: ${fs.openclaw}`);
87
+ if (scanParts.length > 0) {
88
+ consola.info(` Files scanned: ${pc.dim(scanParts.join(" | "))}`);
89
+ }
90
+ // Auto-upload if logged in
91
+ if (args.upload) {
92
+ const dev = isDevMode();
93
+ await runUpload(paths.stateDir, resolveHost(dev), dev);
94
+ }
95
+ },
96
+ });
97
+ const statusCommand = defineCommand({
98
+ meta: {
99
+ name: "status",
100
+ description: "Show current sync status and token usage summary",
101
+ },
102
+ async run() {
103
+ const paths = resolveDefaultPaths();
104
+ const result = await executeStatus({ stateDir: paths.stateDir });
105
+ consola.log("");
106
+ consola.log(pc.bold("Pew Status"));
107
+ consola.log(pc.dim("─".repeat(40)));
108
+ consola.log(` Tracked files: ${pc.cyan(String(result.trackedFiles))}`);
109
+ consola.log(` Last sync: ${result.lastSync ? pc.green(result.lastSync) : pc.dim("never")}`);
110
+ consola.log(` Pending upload: ${result.pendingRecords > 0 ? pc.yellow(String(result.pendingRecords)) : pc.dim("0")} records`);
111
+ if (Object.keys(result.sources).length > 0) {
112
+ consola.log("");
113
+ consola.log(pc.bold(" Files by source:"));
114
+ for (const [source, count] of Object.entries(result.sources)) {
115
+ consola.log(` ${pc.cyan(source.padEnd(14))} ${count}`);
116
+ }
117
+ }
118
+ consola.log("");
119
+ },
120
+ });
121
+ const loginCommand = defineCommand({
122
+ meta: {
123
+ name: "login",
124
+ description: "Connect your CLI to the Pew dashboard via browser OAuth",
125
+ },
126
+ args: {
127
+ force: {
128
+ type: "boolean",
129
+ description: "Force re-login even if already authenticated",
130
+ default: false,
131
+ },
132
+ dev: {
133
+ type: "boolean",
134
+ description: "Use the dev host (pew.dev.hexly.ai)",
135
+ default: false,
136
+ },
137
+ },
138
+ async run({ args }) {
139
+ const paths = resolveDefaultPaths();
140
+ const dev = isDevMode();
141
+ const host = resolveHost(dev);
142
+ const { exec } = await import("node:child_process");
143
+ consola.start("Opening browser for authentication...\n");
144
+ const result = await executeLogin({
145
+ configDir: paths.stateDir,
146
+ apiUrl: host,
147
+ dev,
148
+ force: args.force,
149
+ openBrowser: async (url) => {
150
+ const cmd = process.platform === "darwin"
151
+ ? "open"
152
+ : process.platform === "win32"
153
+ ? "start"
154
+ : "xdg-open";
155
+ exec(`${cmd} "${url}"`);
156
+ },
157
+ });
158
+ if (result.alreadyLoggedIn) {
159
+ consola.info(`Already logged in. Use ${pc.cyan("pew login --force")} to re-authenticate.`);
160
+ return;
161
+ }
162
+ if (result.success) {
163
+ consola.success(`Logged in as ${pc.bold(result.email ?? "unknown")}`);
164
+ consola.info(`Token saved to ${pc.dim(paths.stateDir + (dev ? "/config.dev.json" : "/config.json"))}`);
165
+ }
166
+ else {
167
+ consola.error(`Login failed: ${result.error}`);
168
+ process.exitCode = 1;
169
+ }
170
+ },
171
+ });
172
+ // ---------------------------------------------------------------------------
173
+ // Upload helper (used by `sync --upload`)
174
+ // ---------------------------------------------------------------------------
175
+ async function runUpload(stateDir, apiUrl, dev) {
176
+ consola.log("");
177
+ consola.start("Uploading to dashboard...");
178
+ const uploadResult = await executeUpload({
179
+ stateDir,
180
+ apiUrl,
181
+ dev,
182
+ fetch: globalThis.fetch,
183
+ onProgress(event) {
184
+ if (event.phase === "uploading") {
185
+ consola.info(` ${pc.dim(`Batch ${event.batch}/${event.totalBatches}`)} (${event.message})`);
186
+ }
187
+ },
188
+ });
189
+ if (!uploadResult.success && uploadResult.error?.match(/not logged in/i)) {
190
+ consola.info(`Not logged in — skipping upload. Run ${pc.cyan("pew login")} to enable.`);
191
+ return;
192
+ }
193
+ if (uploadResult.success) {
194
+ if (uploadResult.uploaded === 0) {
195
+ consola.info("No pending records to upload.");
196
+ }
197
+ else {
198
+ consola.success(`Uploaded ${pc.bold(String(uploadResult.uploaded))} records in ${uploadResult.batches} batch(es).`);
199
+ }
200
+ }
201
+ else {
202
+ consola.error(`Upload failed: ${uploadResult.error}`);
203
+ if (uploadResult.uploaded > 0) {
204
+ consola.info(` ${pc.yellow(String(uploadResult.uploaded))} records uploaded before failure.`);
205
+ }
206
+ process.exitCode = 1;
207
+ }
208
+ }
209
+ export const main = defineCommand({
210
+ meta: {
211
+ name: "pew",
212
+ version: "0.2.0",
213
+ description: "Track token usage from your local AI coding tools",
214
+ },
215
+ subCommands: {
216
+ sync: syncCommand,
217
+ status: statusCommand,
218
+ login: loginCommand,
219
+ },
220
+ });
221
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * CLI login command — browser-based OAuth flow.
3
+ *
4
+ * Flow:
5
+ * 1. Start local HTTP server on random port
6
+ * 2. Open browser to SaaS auth endpoint with callback URL
7
+ * 3. SaaS authenticates user (Google OAuth) and redirects back with api_key
8
+ * 4. Save api_key to ~/.config/pew/config.json
9
+ */
10
+ export declare const DEFAULT_HOST = "https://pew.md";
11
+ export declare const DEV_HOST = "https://pew.dev.hexly.ai";
12
+ export declare function resolveHost(dev: boolean): string;
13
+ export interface LoginOptions {
14
+ /** Directory for config file */
15
+ configDir: string;
16
+ /** Base URL of the Pew SaaS */
17
+ apiUrl: string;
18
+ /** Whether dev mode is active (uses config.dev.json) */
19
+ dev?: boolean;
20
+ /** Timeout in milliseconds (default: 120000) */
21
+ timeoutMs?: number;
22
+ /** Force re-login even if already authenticated */
23
+ force?: boolean;
24
+ /** Injected browser opener (for testing) */
25
+ openBrowser: (url: string) => Promise<void>;
26
+ }
27
+ export interface LoginResult {
28
+ success: boolean;
29
+ email?: string;
30
+ alreadyLoggedIn?: boolean;
31
+ error?: string;
32
+ }
33
+ export declare function executeLogin(options: LoginOptions): Promise<LoginResult>;
34
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,QAAQ,6BAA6B,CAAC;AAEnD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEhD;AAMD,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA6F9E"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * CLI login command — browser-based OAuth flow.
3
+ *
4
+ * Flow:
5
+ * 1. Start local HTTP server on random port
6
+ * 2. Open browser to SaaS auth endpoint with callback URL
7
+ * 3. SaaS authenticates user (Google OAuth) and redirects back with api_key
8
+ * 4. Save api_key to ~/.config/pew/config.json
9
+ */
10
+ import { createServer } from "node:http";
11
+ import { ConfigManager } from "../config/manager.js";
12
+ // ---------------------------------------------------------------------------
13
+ // Host constants
14
+ // ---------------------------------------------------------------------------
15
+ export const DEFAULT_HOST = "https://pew.md";
16
+ export const DEV_HOST = "https://pew.dev.hexly.ai";
17
+ export function resolveHost(dev) {
18
+ return dev ? DEV_HOST : DEFAULT_HOST;
19
+ }
20
+ // ---------------------------------------------------------------------------
21
+ // Implementation
22
+ // ---------------------------------------------------------------------------
23
+ export async function executeLogin(options) {
24
+ const { configDir, apiUrl, dev = false, timeoutMs = 120_000, force = false, openBrowser, } = options;
25
+ const configManager = new ConfigManager(configDir, dev);
26
+ // 1. Check existing login
27
+ if (!force) {
28
+ const existing = await configManager.load();
29
+ if (existing.token) {
30
+ return { success: true, alreadyLoggedIn: true };
31
+ }
32
+ }
33
+ // 2. Start local callback server using Node http
34
+ return new Promise((resolve) => {
35
+ let settled = false;
36
+ let timeoutHandle;
37
+ const server = createServer(async (req, res) => {
38
+ const url = new URL(req.url ?? "/", `http://localhost`);
39
+ if (url.pathname === "/callback") {
40
+ const apiKey = url.searchParams.get("api_key");
41
+ const email = url.searchParams.get("email") ?? undefined;
42
+ if (!apiKey) {
43
+ res.writeHead(200, { "Content-Type": "text/html" });
44
+ res.end(htmlPage("Login Failed", "No API key was received. Please try again."));
45
+ settle({
46
+ success: false,
47
+ error: "No api_key received in callback",
48
+ });
49
+ return;
50
+ }
51
+ // Save to config
52
+ await configManager.save({ token: apiKey });
53
+ res.writeHead(200, { "Content-Type": "text/html" });
54
+ res.end(htmlPage("Login Successful!", `Logged in as ${email ?? "unknown"}. You can close this tab.`));
55
+ settle({ success: true, email });
56
+ return;
57
+ }
58
+ res.writeHead(404);
59
+ res.end("Not Found");
60
+ });
61
+ function settle(result) {
62
+ if (settled)
63
+ return;
64
+ settled = true;
65
+ clearTimeout(timeoutHandle);
66
+ server.close();
67
+ resolve(result);
68
+ }
69
+ // Listen on port 0 for random available port
70
+ server.listen(0, () => {
71
+ const addr = server.address();
72
+ const port = typeof addr === "object" && addr ? addr.port : 0;
73
+ const callbackUrl = `http://localhost:${port}/callback`;
74
+ const loginUrl = `${apiUrl}/api/auth/cli?callback=${encodeURIComponent(callbackUrl)}`;
75
+ // 3. Set timeout
76
+ timeoutHandle = setTimeout(() => {
77
+ settle({
78
+ success: false,
79
+ error: `Login timeout after ${timeoutMs / 1000}s — no callback received`,
80
+ });
81
+ }, timeoutMs);
82
+ // 4. Open browser
83
+ openBrowser(loginUrl).catch((err) => {
84
+ settle({
85
+ success: false,
86
+ error: `Failed to open browser: ${String(err)}`,
87
+ });
88
+ });
89
+ });
90
+ });
91
+ }
92
+ function htmlPage(title, message) {
93
+ return `<!DOCTYPE html>
94
+ <html>
95
+ <head><title>Pew — ${title}</title>
96
+ <style>
97
+ body { font-family: -apple-system, sans-serif; text-align: center; padding: 60px 20px; background: #0a0a0a; color: #fafafa; }
98
+ h1 { font-size: 2rem; margin-bottom: 1rem; }
99
+ p { color: #888; font-size: 1.1rem; }
100
+ </style>
101
+ </head>
102
+ <body>
103
+ <h1>${title}</h1>
104
+ <p>${message}</p>
105
+ </body>
106
+ </html>`;
107
+ }
108
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** Status summary for display */
2
+ export interface StatusResult {
3
+ /** Number of tracked files */
4
+ trackedFiles: number;
5
+ /** Last sync timestamp (ISO) or null */
6
+ lastSync: string | null;
7
+ /** Number of unuploaded records in queue */
8
+ pendingRecords: number;
9
+ /** Breakdown by source */
10
+ sources: Record<string, number>;
11
+ }
12
+ /**
13
+ * Compute the current sync status.
14
+ * Pure logic — no CLI I/O.
15
+ */
16
+ export declare function executeStatus(opts: {
17
+ stateDir: string;
18
+ }): Promise<StatusResult>;
19
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4BxB"}
@@ -0,0 +1,35 @@
1
+ import { CursorStore } from "../storage/cursor-store.js";
2
+ import { LocalQueue } from "../storage/local-queue.js";
3
+ /**
4
+ * Compute the current sync status.
5
+ * Pure logic — no CLI I/O.
6
+ */
7
+ export async function executeStatus(opts) {
8
+ const { stateDir } = opts;
9
+ const cursorStore = new CursorStore(stateDir);
10
+ const queue = new LocalQueue(stateDir);
11
+ const cursors = await cursorStore.load();
12
+ const offset = await queue.loadOffset();
13
+ const { records } = await queue.readFromOffset(offset);
14
+ // Count files by source based on path patterns
15
+ const sources = {};
16
+ for (const filePath of Object.keys(cursors.files)) {
17
+ let source = "unknown";
18
+ if (filePath.includes(".claude"))
19
+ source = "claude-code";
20
+ else if (filePath.includes(".gemini"))
21
+ source = "gemini-cli";
22
+ else if (filePath.includes("opencode"))
23
+ source = "opencode";
24
+ else if (filePath.includes(".openclaw"))
25
+ source = "openclaw";
26
+ sources[source] = (sources[source] || 0) + 1;
27
+ }
28
+ return {
29
+ trackedFiles: Object.keys(cursors.files).length,
30
+ lastSync: cursors.updatedAt,
31
+ pendingRecords: records.length,
32
+ sources,
33
+ };
34
+ }
35
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAevD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAEnC;IACC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1B,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;IACxC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvD,+CAA+C;IAC/C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,MAAM,GAAG,aAAa,CAAC;aACpD,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,MAAM,GAAG,YAAY,CAAC;aACxD,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,MAAM,GAAG,UAAU,CAAC;aACvD,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,MAAM,GAAG,UAAU,CAAC;QAE7D,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM;QAC/C,QAAQ,EAAE,OAAO,CAAC,SAAS;QAC3B,cAAc,EAAE,OAAO,CAAC,MAAM;QAC9B,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,49 @@
1
+ /** Sync execution options */
2
+ export interface SyncOptions {
3
+ /** Directory for persisting state (cursors, queue) */
4
+ stateDir: string;
5
+ /** Override: Claude data directory (~/.claude) */
6
+ claudeDir?: string;
7
+ /** Override: Gemini data directory (~/.gemini) */
8
+ geminiDir?: string;
9
+ /** Override: OpenCode message directory (~/.local/share/opencode/storage/message) */
10
+ openCodeMessageDir?: string;
11
+ /** Override: OpenClaw data directory (~/.openclaw) */
12
+ openclawDir?: string;
13
+ /** Progress callback */
14
+ onProgress?: (event: ProgressEvent) => void;
15
+ }
16
+ /** Progress event for UI display */
17
+ export interface ProgressEvent {
18
+ source: string;
19
+ phase: "discover" | "parse" | "aggregate" | "done";
20
+ current?: number;
21
+ total?: number;
22
+ message?: string;
23
+ }
24
+ /** Result of a sync execution */
25
+ export interface SyncResult {
26
+ totalDeltas: number;
27
+ totalRecords: number;
28
+ sources: {
29
+ claude: number;
30
+ gemini: number;
31
+ opencode: number;
32
+ openclaw: number;
33
+ };
34
+ /** Total files scanned per source */
35
+ filesScanned: {
36
+ claude: number;
37
+ gemini: number;
38
+ opencode: number;
39
+ openclaw: number;
40
+ };
41
+ }
42
+ /**
43
+ * Execute the sync operation: discover files, parse incrementally,
44
+ * aggregate into half-hour buckets, and write to local queue.
45
+ *
46
+ * Pure logic — no CLI I/O. Receives all dependencies via options.
47
+ */
48
+ export declare function executeSync(opts: SyncOptions): Promise<SyncResult>;
49
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA0BA,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC7C;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,qCAAqC;IACrC,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAUD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA2SxE"}