@tracemarketplace/cli 0.0.1

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 (72) hide show
  1. package/dist/api-client.d.ts +8 -0
  2. package/dist/api-client.d.ts.map +1 -0
  3. package/dist/api-client.js +34 -0
  4. package/dist/api-client.js.map +1 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +69 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/auto-submit.d.ts +9 -0
  10. package/dist/commands/auto-submit.d.ts.map +1 -0
  11. package/dist/commands/auto-submit.js +111 -0
  12. package/dist/commands/auto-submit.js.map +1 -0
  13. package/dist/commands/daemon.d.ts +2 -0
  14. package/dist/commands/daemon.d.ts.map +1 -0
  15. package/dist/commands/daemon.js +125 -0
  16. package/dist/commands/daemon.js.map +1 -0
  17. package/dist/commands/history.d.ts +2 -0
  18. package/dist/commands/history.d.ts.map +1 -0
  19. package/dist/commands/history.js +32 -0
  20. package/dist/commands/history.js.map +1 -0
  21. package/dist/commands/login.d.ts +2 -0
  22. package/dist/commands/login.d.ts.map +1 -0
  23. package/dist/commands/login.js +69 -0
  24. package/dist/commands/login.js.map +1 -0
  25. package/dist/commands/register.d.ts +4 -0
  26. package/dist/commands/register.d.ts.map +1 -0
  27. package/dist/commands/register.js +43 -0
  28. package/dist/commands/register.js.map +1 -0
  29. package/dist/commands/setup-hook.d.ts +6 -0
  30. package/dist/commands/setup-hook.d.ts.map +1 -0
  31. package/dist/commands/setup-hook.js +148 -0
  32. package/dist/commands/setup-hook.js.map +1 -0
  33. package/dist/commands/status.d.ts +2 -0
  34. package/dist/commands/status.d.ts.map +1 -0
  35. package/dist/commands/status.js +23 -0
  36. package/dist/commands/status.js.map +1 -0
  37. package/dist/commands/submit.d.ts +8 -0
  38. package/dist/commands/submit.d.ts.map +1 -0
  39. package/dist/commands/submit.js +149 -0
  40. package/dist/commands/submit.js.map +1 -0
  41. package/dist/commands/whoami.d.ts +2 -0
  42. package/dist/commands/whoami.d.ts.map +1 -0
  43. package/dist/commands/whoami.js +16 -0
  44. package/dist/commands/whoami.js.map +1 -0
  45. package/dist/config.d.ts +9 -0
  46. package/dist/config.d.ts.map +1 -0
  47. package/dist/config.js +23 -0
  48. package/dist/config.js.map +1 -0
  49. package/dist/sessions.d.ts +16 -0
  50. package/dist/sessions.d.ts.map +1 -0
  51. package/dist/sessions.js +107 -0
  52. package/dist/sessions.js.map +1 -0
  53. package/dist/submitter.d.ts +19 -0
  54. package/dist/submitter.d.ts.map +1 -0
  55. package/dist/submitter.js +65 -0
  56. package/dist/submitter.js.map +1 -0
  57. package/package.json +31 -0
  58. package/src/api-client.ts +33 -0
  59. package/src/cli.ts +82 -0
  60. package/src/commands/auto-submit.ts +95 -0
  61. package/src/commands/daemon.ts +128 -0
  62. package/src/commands/history.ts +50 -0
  63. package/src/commands/login.ts +75 -0
  64. package/src/commands/register.ts +52 -0
  65. package/src/commands/setup-hook.ts +175 -0
  66. package/src/commands/status.ts +26 -0
  67. package/src/commands/submit.ts +184 -0
  68. package/src/commands/whoami.ts +22 -0
  69. package/src/config.ts +29 -0
  70. package/src/sessions.ts +105 -0
  71. package/src/submitter.ts +89 -0
  72. package/tsconfig.json +8 -0
@@ -0,0 +1,8 @@
1
+ export declare class ApiClient {
2
+ private baseUrl;
3
+ private apiKey;
4
+ constructor(baseUrl: string, apiKey: string);
5
+ get(path: string): Promise<unknown>;
6
+ post(path: string, body: unknown): Promise<unknown>;
7
+ }
8
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IAElB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;gBADN,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAGlB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWnC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAe1D"}
@@ -0,0 +1,34 @@
1
+ export class ApiClient {
2
+ baseUrl;
3
+ apiKey;
4
+ constructor(baseUrl, apiKey) {
5
+ this.baseUrl = baseUrl;
6
+ this.apiKey = apiKey;
7
+ }
8
+ async get(path) {
9
+ const res = await fetch(`${this.baseUrl}${path}`, {
10
+ headers: { "X-Api-Key": this.apiKey },
11
+ });
12
+ if (!res.ok) {
13
+ const text = await res.text();
14
+ throw new Error(`API error ${res.status}: ${text}`);
15
+ }
16
+ return res.json();
17
+ }
18
+ async post(path, body) {
19
+ const res = await fetch(`${this.baseUrl}${path}`, {
20
+ method: "POST",
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ "X-Api-Key": this.apiKey,
24
+ },
25
+ body: JSON.stringify(body),
26
+ });
27
+ if (!res.ok) {
28
+ const text = await res.text();
29
+ throw new Error(`API error ${res.status}: ${text}`);
30
+ }
31
+ return res.json();
32
+ }
33
+ }
34
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;IAEV;IACA;IAFV,YACU,OAAe,EACf,MAAc;QADd,YAAO,GAAP,OAAO,CAAQ;QACf,WAAM,GAAN,MAAM,CAAQ;IACrB,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YAChD,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE;SACtC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAa;QACpC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YAChD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,MAAM;aACzB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACF"}
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,69 @@
1
+ #!/usr/bin/env node
2
+ import { program } from "commander";
3
+ import { loginCommand } from "./commands/login.js";
4
+ import { registerCommand } from "./commands/register.js";
5
+ import { whoamiCommand } from "./commands/whoami.js";
6
+ import { submitCommand } from "./commands/submit.js";
7
+ import { statusCommand } from "./commands/status.js";
8
+ import { historyCommand } from "./commands/history.js";
9
+ import { autoSubmitCommand } from "./commands/auto-submit.js";
10
+ import { setupHookCommand } from "./commands/setup-hook.js";
11
+ import { daemonCommand } from "./commands/daemon.js";
12
+ program
13
+ .name("trace")
14
+ .description("Trace Marketplace CLI — submit AI coding sessions, get paid")
15
+ .version("0.0.1");
16
+ program
17
+ .command("login")
18
+ .description("Sign in via browser — opens tracemarketplace.dev, no key needed")
19
+ .action(() => loginCommand().catch(handleError));
20
+ program
21
+ .command("register")
22
+ .description("Register your email and get an API key")
23
+ .option("--server-url <url>", "Server URL (default: https://api.tracemarketplace.dev)")
24
+ .action((opts) => registerCommand({ serverUrl: opts.serverUrl }).catch(handleError));
25
+ program
26
+ .command("whoami")
27
+ .description("Show your account info and balance")
28
+ .action(() => whoamiCommand().catch(handleError));
29
+ program
30
+ .command("submit")
31
+ .description("Auto-detect and submit traces from Claude Code, Codex CLI, and Cursor")
32
+ .option("--tool <tool>", "Only submit from specific tool (claude-code|codex|cursor)")
33
+ .option("--dry-run", "Preview without submitting")
34
+ .option("--since <duration>", "Only include sessions from last N days (e.g. 30d)", "30d")
35
+ .action((opts) => submitCommand({
36
+ tool: opts.tool,
37
+ dryRun: opts.dryRun,
38
+ since: opts.since,
39
+ }).catch(handleError));
40
+ program
41
+ .command("status")
42
+ .description("Show pending submissions and balance")
43
+ .action(() => statusCommand().catch(handleError));
44
+ program
45
+ .command("history")
46
+ .description("Show submission history")
47
+ .action(() => historyCommand().catch(handleError));
48
+ program
49
+ .command("auto-submit")
50
+ .description("Submit the current session (called by tool hooks — do not run manually)")
51
+ .option("--tool <tool>", "Tool that triggered the hook (claude-code|cursor|codex)")
52
+ .option("--session <id>", "Session ID (for cursor/codex hooks)")
53
+ .option("--file <path>", "Direct path to session file (for claude-code)")
54
+ .action((opts) => autoSubmitCommand({ tool: opts.tool, session: opts.session, file: opts.file }));
55
+ program
56
+ .command("daemon")
57
+ .description("Watch session directories and auto-submit new sessions as they appear")
58
+ .action(() => daemonCommand().catch(handleError));
59
+ program
60
+ .command("setup-hook")
61
+ .description("Install session-end hooks for Claude Code, Cursor, and Codex CLI")
62
+ .option("--tool <tool>", "Only set up hook for specific tool (claude-code|cursor|codex)")
63
+ .action((opts) => setupHookCommand({ tool: opts.tool }).catch(handleError));
64
+ function handleError(e) {
65
+ console.error(e.message ?? String(e));
66
+ process.exit(1);
67
+ }
68
+ program.parse();
69
+ //# 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,9 @@
1
+ interface AutoSubmitOptions {
2
+ tool?: string;
3
+ session?: string;
4
+ file?: string;
5
+ }
6
+ export declare function log(msg: string): void;
7
+ export declare function autoSubmitCommand(opts: AutoSubmitOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=auto-submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-submit.d.ts","sourceRoot":"","sources":["../../src/commands/auto-submit.ts"],"names":[],"mappings":"AAYA,UAAU,iBAAiB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,QAM9B;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9E"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * auto-submit — called by tool hooks (Claude Code Stop, Cursor sessionEnd).
3
+ * Non-interactive: never prompts, always exits 0 so it never blocks the user's tool.
4
+ * Logs results to ~/.config/tracemarketplace/auto-submit.log
5
+ */
6
+ import { readFileSync, appendFileSync, mkdirSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ import { loadConfig } from "../config.js";
10
+ import { findLatestFile, findCodexFileById } from "../sessions.js";
11
+ import { submitFile, submitCursorSession } from "../submitter.js";
12
+ export function log(msg) {
13
+ const dir = join(homedir(), ".config", "tracemarketplace");
14
+ mkdirSync(dir, { recursive: true });
15
+ try {
16
+ appendFileSync(join(dir, "auto-submit.log"), `[${new Date().toISOString()}] ${msg}\n`);
17
+ }
18
+ catch { }
19
+ }
20
+ export async function autoSubmitCommand(opts) {
21
+ try {
22
+ await run(opts);
23
+ }
24
+ catch (err) {
25
+ log(`ERROR: ${String(err)}`);
26
+ }
27
+ }
28
+ async function run(opts) {
29
+ const config = loadConfig();
30
+ if (!config) {
31
+ log("Not registered — run: trace register");
32
+ return;
33
+ }
34
+ // Read hook payload from stdin
35
+ let hookPayload = {};
36
+ try {
37
+ const raw = readFileSync("/dev/stdin", "utf-8").trim();
38
+ if (raw)
39
+ hookPayload = JSON.parse(raw);
40
+ }
41
+ catch { }
42
+ const tool = opts.tool ?? inferTool(hookPayload);
43
+ if (!tool) {
44
+ log("Could not determine tool");
45
+ return;
46
+ }
47
+ log(`auto-submit triggered for tool=${tool}`);
48
+ if (tool === "claude-code" || tool === "claude_code") {
49
+ // Claude Code Stop hook sends { session_id, transcript_path }
50
+ const filePath = opts.file
51
+ ?? hookPayload["transcript_path"]
52
+ ?? findLatestFile("claude_code");
53
+ if (!filePath) {
54
+ log("Claude Code: no session file found");
55
+ return;
56
+ }
57
+ const result = await submitFile("claude_code", filePath, config);
58
+ logResult(result, filePath);
59
+ }
60
+ else if (tool === "cursor") {
61
+ const sessionId = opts.session ?? hookPayload["sessionId"];
62
+ if (!sessionId) {
63
+ log("Cursor: no sessionId");
64
+ return;
65
+ }
66
+ const result = await submitCursorSession(sessionId, config);
67
+ logResult(result, sessionId);
68
+ }
69
+ else if (tool === "codex" || tool === "codex_cli") {
70
+ // after_agent payload: { "thread-id": "...", "turn-id": "...", "cwd": "...", "last-assistant-message": "..." }
71
+ // Legacy / manual: session_path or session_id
72
+ const threadId = hookPayload["thread-id"] ?? "";
73
+ const filePath = opts.file
74
+ ?? hookPayload["session_path"]
75
+ ?? findCodexFileById(opts.session ?? hookPayload["session_id"] ?? threadId ?? "");
76
+ if (!filePath) {
77
+ log("Codex: no session file found");
78
+ return;
79
+ }
80
+ const result = await submitFile("codex_cli", filePath, config);
81
+ logResult(result, filePath);
82
+ }
83
+ else {
84
+ log(`Unknown tool: ${tool}`);
85
+ }
86
+ }
87
+ function logResult(result, label) {
88
+ if (result.error) {
89
+ log(`${label}: ${result.error}`);
90
+ return;
91
+ }
92
+ if (result.duplicate) {
93
+ log(`${label}: already captured — skipped`);
94
+ return;
95
+ }
96
+ if (result.superseded) {
97
+ log(`${label}: updated (${result.turnCount} turns) — $${(result.payoutCents / 100).toFixed(2)}`);
98
+ return;
99
+ }
100
+ log(`${label}: accepted (${result.turnCount} turns) — $${(result.payoutCents / 100).toFixed(2)}`);
101
+ }
102
+ function inferTool(payload) {
103
+ if (payload["transcript_path"])
104
+ return "claude-code";
105
+ if (payload["terminationReason"] || payload["sessionId"])
106
+ return "cursor";
107
+ if (payload["session_path"] || payload["thread-id"])
108
+ return "codex";
109
+ return null;
110
+ }
111
+ //# sourceMappingURL=auto-submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-submit.js","sourceRoot":"","sources":["../../src/commands/auto-submit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function daemonCommand(): Promise<void>;
2
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AA2EA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAoDnD"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * trace daemon — watches ~/.claude and ~/.codex session dirs and auto-submits on change.
3
+ * Keeps a state file so already-submitted unchanged files are skipped on restart.
4
+ *
5
+ * State: ~/.config/tracemarketplace/daemon-state.json
6
+ * { [filePath]: { mtime: number, size: number } }
7
+ *
8
+ * On startup: backfills any files newer than last run.
9
+ * While running: submits files 5s after they stop changing (debounce in watchDirs).
10
+ * Server handles dedup/supersession — daemon just fires on change.
11
+ */
12
+ import { readFileSync, writeFileSync, mkdirSync, statSync, existsSync } from "fs";
13
+ import { homedir } from "os";
14
+ import { join } from "path";
15
+ import chalk from "chalk";
16
+ import { loadConfig } from "../config.js";
17
+ import { findFiles, watchDirs } from "../sessions.js";
18
+ import { submitFile } from "../submitter.js";
19
+ import { log } from "./auto-submit.js";
20
+ const STATE_PATH = join(homedir(), ".config", "tracemarketplace", "daemon-state.json");
21
+ function loadState() {
22
+ try {
23
+ return JSON.parse(readFileSync(STATE_PATH, "utf-8"));
24
+ }
25
+ catch {
26
+ return {};
27
+ }
28
+ }
29
+ function saveState(state) {
30
+ mkdirSync(join(homedir(), ".config", "tracemarketplace"), { recursive: true });
31
+ writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
32
+ }
33
+ function hasChanged(filePath, state) {
34
+ try {
35
+ const { mtimeMs, size } = statSync(filePath);
36
+ const recorded = state[filePath];
37
+ if (!recorded)
38
+ return true;
39
+ return mtimeMs !== recorded.mtime || size !== recorded.size;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ function recordFile(filePath, state) {
46
+ try {
47
+ const { mtimeMs, size } = statSync(filePath);
48
+ return { ...state, [filePath]: { mtime: mtimeMs, size } };
49
+ }
50
+ catch {
51
+ return state;
52
+ }
53
+ }
54
+ async function processFile(tool, filePath, state) {
55
+ const config = loadConfig();
56
+ if (!config)
57
+ return state;
58
+ const result = await submitFile(tool, filePath, config);
59
+ const updated = recordFile(filePath, state);
60
+ if (result.error && result.error !== "Empty session") {
61
+ log(`daemon: ${filePath}: ${result.error}`);
62
+ }
63
+ else if (result.duplicate) {
64
+ // Already current — no log noise
65
+ }
66
+ else if (result.superseded) {
67
+ log(`daemon: updated ${filePath} (${result.turnCount} turns) +$${(result.payoutCents / 100).toFixed(2)}`);
68
+ console.log(chalk.cyan(` ↑ updated`), chalk.gray(filePath.split("/").slice(-2).join("/")), chalk.green(`+$${(result.payoutCents / 100).toFixed(2)}`));
69
+ }
70
+ else if (result.accepted) {
71
+ log(`daemon: accepted ${filePath} (${result.turnCount} turns) +$${(result.payoutCents / 100).toFixed(2)}`);
72
+ console.log(chalk.green(` āœ“ new`), chalk.gray(filePath.split("/").slice(-2).join("/")), chalk.green(`+$${(result.payoutCents / 100).toFixed(2)}`));
73
+ }
74
+ return updated;
75
+ }
76
+ export async function daemonCommand() {
77
+ const config = loadConfig();
78
+ if (!config) {
79
+ console.error(chalk.red("Not registered. Run: trace register"));
80
+ process.exit(1);
81
+ }
82
+ const tools = [];
83
+ if (existsSync(join(homedir(), ".claude")))
84
+ tools.push("claude_code");
85
+ if (existsSync(join(homedir(), ".codex", "sessions")))
86
+ tools.push("codex_cli");
87
+ if (tools.length === 0) {
88
+ console.log(chalk.yellow("No supported tools detected (Claude Code, Codex)."));
89
+ return;
90
+ }
91
+ console.log(chalk.bold("Trace daemon starting"));
92
+ console.log(chalk.gray(`Watching: ${tools.join(", ")}`));
93
+ console.log(chalk.gray("Press Ctrl+C to stop\n"));
94
+ let state = loadState();
95
+ // Backfill: submit any files from the last 7 days that have changed since last run
96
+ console.log(chalk.gray("Backfilling new/changed sessions..."));
97
+ let backfilled = 0;
98
+ for (const tool of tools) {
99
+ for (const filePath of findFiles(tool, 7)) {
100
+ if (hasChanged(filePath, state)) {
101
+ state = await processFile(tool, filePath, state);
102
+ backfilled++;
103
+ }
104
+ }
105
+ }
106
+ saveState(state);
107
+ if (backfilled === 0)
108
+ console.log(chalk.gray(" Nothing new.\n"));
109
+ else
110
+ console.log();
111
+ // Watch for ongoing changes
112
+ const stop = watchDirs(tools, async (tool, filePath) => {
113
+ if (!hasChanged(filePath, state))
114
+ return;
115
+ state = await processFile(tool, filePath, state);
116
+ saveState(state);
117
+ });
118
+ console.log(chalk.gray("Watching for new sessions...\n"));
119
+ // Graceful shutdown
120
+ process.on("SIGINT", () => { stop(); console.log(chalk.gray("\nDaemon stopped.")); process.exit(0); });
121
+ process.on("SIGTERM", () => { stop(); process.exit(0); });
122
+ // Keep alive
123
+ await new Promise(() => { });
124
+ }
125
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function historyCommand(): Promise<void>;
2
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CpD"}
@@ -0,0 +1,32 @@
1
+ import chalk from "chalk";
2
+ import { loadConfig } from "../config.js";
3
+ import { ApiClient } from "../api-client.js";
4
+ export async function historyCommand() {
5
+ const config = loadConfig();
6
+ if (!config) {
7
+ console.error(chalk.red("Not registered. Run: trace register"));
8
+ process.exit(1);
9
+ }
10
+ const client = new ApiClient(config.serverUrl, config.apiKey);
11
+ const subs = (await client.get("/api/v1/submissions"));
12
+ if (subs.length === 0) {
13
+ console.log(chalk.gray("No submissions yet."));
14
+ return;
15
+ }
16
+ console.log(chalk.gray("Date".padEnd(14) +
17
+ "Tool".padEnd(16) +
18
+ "Accepted".padEnd(12) +
19
+ "Payout"));
20
+ console.log(chalk.gray("─".repeat(50)));
21
+ for (const s of subs) {
22
+ const date = new Date(s.submittedAt).toLocaleDateString();
23
+ const payout = s.totalPayoutCents !== null
24
+ ? "$" + (s.totalPayoutCents / 100).toFixed(2)
25
+ : "pending";
26
+ console.log(date.padEnd(14) +
27
+ s.sourceTool.padEnd(16) +
28
+ `${s.acceptedCount ?? "—"}/${s.sessionCount}`.padEnd(12) +
29
+ chalk.green(payout));
30
+ }
31
+ }
32
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAOnD,CAAC;IAEH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACf,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACjB,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,QAAQ,CACX,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAC1D,MAAM,MAAM,GACV,CAAC,CAAC,gBAAgB,KAAK,IAAI;YACzB,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC,SAAS,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACb,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,CAAC,aAAa,IAAI,GAAG,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CACtB,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function loginCommand(): Promise<void>;
2
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AASA,wBAAsB,YAAY,kBA6DjC"}
@@ -0,0 +1,69 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import open from "open";
4
+ import { loadConfig, saveConfig } from "../config.js";
5
+ import { ApiClient } from "../api-client.js";
6
+ const POLL_INTERVAL = 2000;
7
+ const POLL_TIMEOUT = 10 * 60 * 1000; // 10 min
8
+ export async function loginCommand() {
9
+ const config = loadConfig();
10
+ const serverUrl = config?.serverUrl ?? "https://api.tracemarketplace.dev";
11
+ const client = new ApiClient(serverUrl, config?.apiKey ?? "");
12
+ // Step 1: init CLI session
13
+ const spinner = ora("Initializing...").start();
14
+ let token;
15
+ let loginUrl;
16
+ try {
17
+ const res = await client.post("/api/v1/auth/cli-init", {});
18
+ token = res.token;
19
+ loginUrl = res.loginUrl;
20
+ spinner.stop();
21
+ }
22
+ catch (e) {
23
+ spinner.fail("Failed to connect to server");
24
+ throw e;
25
+ }
26
+ // Step 2: open browser
27
+ console.log(chalk.dim("\nOpening browser to sign in...\n"));
28
+ console.log(chalk.dim(` ${loginUrl}\n`));
29
+ console.log(chalk.dim("If the browser didn't open, copy the URL above.\n"));
30
+ try {
31
+ await open(loginUrl);
32
+ }
33
+ catch {
34
+ // Browser open failed — user can copy the URL
35
+ }
36
+ // Step 3: poll for completion
37
+ const pollSpinner = ora("Waiting for authentication...").start();
38
+ const deadline = Date.now() + POLL_TIMEOUT;
39
+ while (Date.now() < deadline) {
40
+ await sleep(POLL_INTERVAL);
41
+ try {
42
+ const res = await client.get(`/api/v1/auth/cli-poll?token=${token}`);
43
+ if (res.pending)
44
+ continue;
45
+ if (res.apiKey) {
46
+ pollSpinner.succeed("Authenticated");
47
+ // Get user info to confirm
48
+ const infoClient = new ApiClient(serverUrl, res.apiKey);
49
+ const me = await infoClient.get("/api/v1/me");
50
+ saveConfig({ apiKey: res.apiKey, serverUrl, email: me.email });
51
+ console.log(chalk.green(`\nāœ“ Logged in as ${me.email}\n`));
52
+ return;
53
+ }
54
+ }
55
+ catch (e) {
56
+ if (e.message?.includes("Expired")) {
57
+ pollSpinner.fail("Login timed out. Run trace login again.");
58
+ process.exit(1);
59
+ }
60
+ // Transient error — keep polling
61
+ }
62
+ }
63
+ pollSpinner.fail("Timed out. Run trace login again.");
64
+ process.exit(1);
65
+ }
66
+ function sleep(ms) {
67
+ return new Promise((r) => setTimeout(r, ms));
68
+ }
69
+ //# 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,4 @@
1
+ export declare function registerCommand(opts: {
2
+ serverUrl?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAIA,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CjF"}
@@ -0,0 +1,43 @@
1
+ import inquirer from "inquirer";
2
+ import chalk from "chalk";
3
+ import { saveConfig } from "../config.js";
4
+ export async function registerCommand(opts) {
5
+ const { email } = await inquirer.prompt([
6
+ {
7
+ type: "input",
8
+ name: "email",
9
+ message: "Your email address:",
10
+ validate: (v) => v.includes("@") || "Enter a valid email",
11
+ },
12
+ ]);
13
+ const serverUrl = opts.serverUrl ??
14
+ (await inquirer.prompt([
15
+ {
16
+ type: "input",
17
+ name: "url",
18
+ message: "Server URL:",
19
+ default: "https://api.tracemarketplace.dev",
20
+ },
21
+ ])).url;
22
+ const res = await fetch(`${serverUrl}/api/v1/register`, {
23
+ method: "POST",
24
+ headers: { "Content-Type": "application/json" },
25
+ body: JSON.stringify({ email }),
26
+ });
27
+ const data = (await res.json());
28
+ if (!res.ok) {
29
+ if (res.status === 409 && data.api_key) {
30
+ console.log(chalk.yellow("Email already registered."));
31
+ console.log(chalk.cyan("Your API key:"), chalk.bold(data.api_key));
32
+ saveConfig({ apiKey: data.api_key, serverUrl, email });
33
+ return;
34
+ }
35
+ throw new Error(data.error ?? `HTTP ${res.status}`);
36
+ }
37
+ const apiKey = data.api_key;
38
+ saveConfig({ apiKey, serverUrl, email });
39
+ console.log(chalk.green("Registered successfully!"));
40
+ console.log(chalk.cyan("Your API key:"), chalk.bold(apiKey));
41
+ console.log(chalk.gray("Config saved to ~/.config/tracemarketplace/config.json"));
42
+ }
43
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAA4B;IAChE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACtC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,qBAAqB;YAC9B,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,qBAAqB;SAClE;KACF,CAAC,CAAC;IAEH,MAAM,SAAS,GACb,IAAI,CAAC,SAAS;QACd,CACE,MAAM,QAAQ,CAAC,MAAM,CAAC;YACpB;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,aAAa;gBACtB,OAAO,EAAE,kCAAkC;aAC5C;SACF,CAAC,CACH,CAAC,GAAG,CAAC;IAER,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,kBAAkB,EAAE;QACtD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;KAChC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyC,CAAC;IAExE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACnE,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAQ,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC,CAAC;AACpF,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface SetupHookOptions {
2
+ tool?: string;
3
+ }
4
+ export declare function setupHookCommand(opts: SetupHookOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=setup-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-hook.d.ts","sourceRoot":"","sources":["../../src/commands/setup-hook.ts"],"names":[],"mappings":"AAeA,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC5E"}