@opencode-trace/cli 0.0.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 (54) hide show
  1. package/README.md +126 -0
  2. package/dist/formatter.d.ts +13 -0
  3. package/dist/formatter.d.ts.map +1 -0
  4. package/dist/formatter.js +74 -0
  5. package/dist/formatter.js.map +1 -0
  6. package/dist/handlers/disable.d.ts +2 -0
  7. package/dist/handlers/disable.d.ts.map +1 -0
  8. package/dist/handlers/disable.js +5 -0
  9. package/dist/handlers/disable.js.map +1 -0
  10. package/dist/handlers/enable.d.ts +3 -0
  11. package/dist/handlers/enable.d.ts.map +1 -0
  12. package/dist/handlers/enable.js +24 -0
  13. package/dist/handlers/enable.js.map +1 -0
  14. package/dist/handlers/export.d.ts +2 -0
  15. package/dist/handlers/export.d.ts.map +1 -0
  16. package/dist/handlers/export.js +150 -0
  17. package/dist/handlers/export.js.map +1 -0
  18. package/dist/handlers/list.d.ts +2 -0
  19. package/dist/handlers/list.d.ts.map +1 -0
  20. package/dist/handlers/list.js +18 -0
  21. package/dist/handlers/list.js.map +1 -0
  22. package/dist/handlers/show.d.ts +2 -0
  23. package/dist/handlers/show.d.ts.map +1 -0
  24. package/dist/handlers/show.js +74 -0
  25. package/dist/handlers/show.js.map +1 -0
  26. package/dist/handlers/status.d.ts +2 -0
  27. package/dist/handlers/status.d.ts.map +1 -0
  28. package/dist/handlers/status.js +23 -0
  29. package/dist/handlers/status.js.map +1 -0
  30. package/dist/handlers/sync.d.ts +2 -0
  31. package/dist/handlers/sync.d.ts.map +1 -0
  32. package/dist/handlers/sync.js +19 -0
  33. package/dist/handlers/sync.js.map +1 -0
  34. package/dist/handlers/viewer.d.ts +2 -0
  35. package/dist/handlers/viewer.d.ts.map +1 -0
  36. package/dist/handlers/viewer.js +16 -0
  37. package/dist/handlers/viewer.js.map +1 -0
  38. package/dist/handlers/viewer.test.d.ts +2 -0
  39. package/dist/handlers/viewer.test.d.ts.map +1 -0
  40. package/dist/handlers/viewer.test.js +75 -0
  41. package/dist/handlers/viewer.test.js.map +1 -0
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +115 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/index.test.d.ts +2 -0
  47. package/dist/index.test.d.ts.map +1 -0
  48. package/dist/index.test.js +51 -0
  49. package/dist/index.test.js.map +1 -0
  50. package/dist/utils.d.ts +15 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +106 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @opencode-trace/cli
2
+
3
+ opencode-trace command-line tool, providing trace data management, query, and export functionality.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@opencode-trace/cli)](https://www.npmjs.com/package/@opencode-trace/cli)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Global install
11
+ npm install -g @opencode-trace/cli
12
+
13
+ # Or use npx (no installation required)
14
+ npx @opencode-trace/cli <command>
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ opencode-trace <command> [options]
21
+ ```
22
+
23
+ ### Commands
24
+
25
+ #### Trace Control
26
+
27
+ ```bash
28
+ opencode-trace enable # Enable global tracing
29
+ opencode-trace enable -s <id> # Enable tracing for specific session
30
+ opencode-trace disable # Disable global tracing
31
+ opencode-trace disable -s <id> # Disable tracing for specific session
32
+ opencode-trace status # View global tracing status
33
+ opencode-trace status -s <id> # View status for specific session
34
+ ```
35
+
36
+ #### Session Management
37
+
38
+ ```bash
39
+ opencode-trace list # List all sessions
40
+ opencode-trace sync # Sync SQLite with filesystem
41
+ opencode-trace sync --repair # Rebuild corrupted state.db
42
+ ```
43
+
44
+ #### Data Viewing
45
+
46
+ ```bash
47
+ # Show session metadata (Token statistics, latency metrics)
48
+ opencode-trace show <id> metadata
49
+
50
+ # Show conversation content
51
+ opencode-trace show <id> conversation # Last conversation
52
+ opencode-trace show <id> conversation -r 1:3 # Conversation for requests 1-3
53
+ opencode-trace show <id> conversation -r 1 # Conversation from request 1 to last
54
+ opencode-trace show <id> conversation --format xml # XML format
55
+ opencode-trace show <id> conversation --compact # Compact output
56
+
57
+ # Show request changes (added/deleted messages and Blocks)
58
+ opencode-trace show <id> changes # All request changes
59
+ opencode-trace show <id> changes -r 1:5 # Changes for requests 1-5
60
+ opencode-trace show <id> changes --format xml # XML format
61
+ ```
62
+
63
+ #### Data Export
64
+
65
+ ```bash
66
+ # Export raw data (ZIP format)
67
+ opencode-trace export <id> -t raw -o ./output
68
+
69
+ # Export conversation content
70
+ opencode-trace export <id> -t conversation -o ./output
71
+ opencode-trace export <id> -t conversation --format xml -o ./output
72
+
73
+ # Export change analysis
74
+ opencode-trace export <id> -t changes -o ./output
75
+
76
+ # Export metadata
77
+ opencode-trace export <id> -t metadata -o ./output
78
+
79
+ # Collapse options (simplified output)
80
+ opencode-trace export <id> -t conversation --collapse sys,tool,msgs -o ./output
81
+ opencode-trace export <id> -t conversation --collapse-blocks text,thinking -o ./output
82
+ ```
83
+
84
+ #### Start Viewer
85
+
86
+ ```bash
87
+ opencode-trace viewer # Start Web Viewer (default port 3000)
88
+ opencode-trace viewer --port 8080 # Specify port
89
+ opencode-trace viewer --no-open # Don't auto-open browser
90
+ ```
91
+
92
+ ### Options
93
+
94
+ | Option | Description |
95
+ |--------|-------------|
96
+ | `-s, --session <id>` | Specify session ID |
97
+ | `-r, --range <range>` | Request range (e.g., `1:3` or `1`) |
98
+ | `--format <json|xml>` | Output format |
99
+ | `--compact` | Compact JSON output |
100
+ | `-t, --type <type>` | Export type (raw/conversation/changes/metadata) |
101
+ | `-o, --output <path>` | Output directory |
102
+ | `--collapse <items>` | Collapse items (sys,tool,msgs) |
103
+ | `--collapse-blocks <types>` | Collapse Block types (text,thinking,td,tc,tr,image,other) |
104
+ | `--port <num>` | Viewer port |
105
+ | `--no-open` | Don't auto-open browser |
106
+ | `--repair` | Rebuild corrupted database |
107
+
108
+ ## Examples
109
+
110
+ ```bash
111
+ # Quickly view recent sessions
112
+ opencode-trace list
113
+
114
+ # View session details
115
+ opencode-trace show session-abc123 metadata
116
+
117
+ # Export session as ZIP
118
+ opencode-trace export session-abc123 -t raw -o ./export
119
+
120
+ # Start Viewer to view
121
+ opencode-trace viewer
122
+ ```
123
+
124
+ ## License
125
+
126
+ MIT
@@ -0,0 +1,13 @@
1
+ import type { BlockType } from "@opencode-trace/core";
2
+ export declare function outputData(data: unknown, formatType: string, compact: boolean): void;
3
+ export declare function isConversationsMap(data: unknown): boolean;
4
+ export declare function isDeltasMap(data: unknown): boolean;
5
+ export declare function isConversation(data: unknown): boolean;
6
+ export declare function isTimeline(data: unknown): boolean;
7
+ export declare function parseCollapse(value: string | undefined): ("sys" | "tool" | "msgs")[] | undefined;
8
+ export declare function parseCollapseBlocks(value: string | undefined): BlockType[] | undefined;
9
+ export declare function writeCollapsedExport(outputPath: string, result: {
10
+ main: string;
11
+ blocks: Map<string, string>;
12
+ }, formatType: string): void;
13
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAgBpF;AAUD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAElD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAErD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEjD;AAcD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,SAAS,CAEhG;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,EAAE,GAAG,SAAS,CAEtF;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAgBxI"}
@@ -0,0 +1,74 @@
1
+ import { writeFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { format } from "@opencode-trace/core";
4
+ export function outputData(data, formatType, compact) {
5
+ let output;
6
+ if (formatType === "xml") {
7
+ if (isConversationsMap(data)) {
8
+ output = format.conversationsMapToXML(data);
9
+ }
10
+ else if (isDeltasMap(data)) {
11
+ output = format.deltasMapToXML(data);
12
+ }
13
+ else {
14
+ output = JSON.stringify(data, null, compact ? 0 : 2);
15
+ }
16
+ }
17
+ else {
18
+ output = JSON.stringify(data, null, compact ? 0 : 2);
19
+ }
20
+ console.log(output);
21
+ }
22
+ function isMapWithProperty(data, property) {
23
+ if (typeof data !== "object" || data === null)
24
+ return false;
25
+ const keys = Object.keys(data);
26
+ if (keys.length === 0)
27
+ return false;
28
+ const firstVal = data[keys[0]];
29
+ return typeof firstVal === "object" && firstVal !== null && property in firstVal;
30
+ }
31
+ export function isConversationsMap(data) {
32
+ return isMapWithProperty(data, "provider") && isMapWithProperty(data, "msgs");
33
+ }
34
+ export function isDeltasMap(data) {
35
+ return isMapWithProperty(data, "msgs") && !isMapWithProperty(data, "provider");
36
+ }
37
+ export function isConversation(data) {
38
+ return typeof data === "object" && data !== null && "provider" in data && "msgs" in data;
39
+ }
40
+ export function isTimeline(data) {
41
+ return typeof data === "object" && data !== null && "sessionId" in data && "changes" in data;
42
+ }
43
+ function parseList(value, valid, errorPrefix) {
44
+ if (!value)
45
+ return undefined;
46
+ const items = value.split(",").map(s => s.trim());
47
+ for (const item of items) {
48
+ if (!valid.includes(item)) {
49
+ console.error(`Error: ${errorPrefix}: ${item}. Valid: ${valid.join(", ")}`);
50
+ process.exit(1);
51
+ }
52
+ }
53
+ return items;
54
+ }
55
+ export function parseCollapse(value) {
56
+ return parseList(value, ["sys", "tool", "msgs"], "Invalid collapse item");
57
+ }
58
+ export function parseCollapseBlocks(value) {
59
+ return parseList(value, ["text", "thinking", "td", "tc", "tr", "image", "other"], "Invalid block type");
60
+ }
61
+ export function writeCollapsedExport(outputPath, result, formatType) {
62
+ mkdirSync(outputPath, { recursive: true });
63
+ const mainFile = join(outputPath, `main.${formatType}`);
64
+ writeFileSync(mainFile, result.main, "utf-8");
65
+ if (result.blocks.size > 0) {
66
+ const blocksDir = join(outputPath, "blocks");
67
+ mkdirSync(blocksDir, { recursive: true });
68
+ for (const [path, content] of result.blocks) {
69
+ writeFileSync(join(outputPath, path), content, "utf-8");
70
+ }
71
+ }
72
+ console.log(JSON.stringify({ success: true, path: outputPath, files: result.blocks.size + 1 }));
73
+ }
74
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,UAAkB,EAAE,OAAgB;IAC5E,IAAI,MAAc,CAAC;IAEnB,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAA2B,CAAC,CAAC;QACrE,CAAC;aAAM,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAA2B,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAa,EAAE,QAAgB;IACxD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAsB,CAAC,CAAC;IACpD,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,IAAI,QAAQ,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAa;IAC9C,OAAO,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,OAAO,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,UAAU,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,CAAC;AAC/F,CAAC;AAED,SAAS,SAAS,CAAmB,KAAyB,EAAE,KAAU,EAAE,WAAmB;IAC7F,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAQ,CAAC;IACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,UAAU,WAAW,KAAK,IAAI,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,uBAAuB,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,MAAqD,EAAE,UAAkB;IAChI,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,UAAU,EAAE,CAAC,CAAC;IACxD,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC7C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5C,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAClG,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdDisable(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=disable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.d.ts","sourceRoot":"","sources":["../../src/handlers/disable.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D"}
@@ -0,0 +1,5 @@
1
+ import { cmdSetEnabled } from "./enable.js";
2
+ export async function cmdDisable(args) {
3
+ await cmdSetEnabled(args, false);
4
+ }
5
+ //# sourceMappingURL=disable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.js","sourceRoot":"","sources":["../../src/handlers/disable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAc;IAC7C,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function cmdEnable(args: string[]): Promise<void>;
2
+ export declare function cmdSetEnabled(args: string[], enable: boolean): Promise<void>;
3
+ //# sourceMappingURL=enable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.d.ts","sourceRoot":"","sources":["../../src/handlers/enable.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBlF"}
@@ -0,0 +1,24 @@
1
+ import { record } from "@opencode-trace/core";
2
+ import { parseFlags, GLOBAL_TRACE_DIR, LOCAL_TRACE_DIR } from "../utils.js";
3
+ export async function cmdEnable(args) {
4
+ await cmdSetEnabled(args, true);
5
+ }
6
+ export async function cmdSetEnabled(args, enable) {
7
+ const { positional, flags } = parseFlags(args);
8
+ const traceDir = flags.session ? LOCAL_TRACE_DIR : GLOBAL_TRACE_DIR;
9
+ await record.initStateManager(traceDir);
10
+ if (flags.session) {
11
+ const sessionId = positional[0];
12
+ if (!sessionId) {
13
+ console.error(`Error: session-id is required when using -s`);
14
+ process.exit(1);
15
+ }
16
+ record.setSessionEnabled(sessionId, enable, traceDir);
17
+ console.log(`Session ${sessionId} ${enable ? 'enabled' : 'disabled'}.`);
18
+ }
19
+ else {
20
+ record.setGlobalTraceEnabled(enable, traceDir);
21
+ console.log(`Global trace ${enable ? 'enabled' : 'disabled'}.`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=enable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../src/handlers/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IAC5C,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,MAAe;IACjE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEpE,MAAM,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,WAAW,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdExport(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/handlers/export.ts"],"names":[],"mappings":"AAMA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyK7D"}
@@ -0,0 +1,150 @@
1
+ import { writeFileSync, createWriteStream } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { store, parse, query, record, format } from "@opencode-trace/core";
4
+ import { parseFlags, parseRange, inRange, findSessionTraceDir } from "../utils.js";
5
+ import { parseCollapse, parseCollapseBlocks, writeCollapsedExport, isConversationsMap, isDeltasMap } from "../formatter.js";
6
+ export async function cmdExport(args) {
7
+ const { positional, flags } = parseFlags(args);
8
+ const sessionId = positional[0];
9
+ if (!sessionId) {
10
+ console.error("Error: session-id is required");
11
+ process.exit(1);
12
+ }
13
+ if (!flags.type || !flags.output) {
14
+ console.error("Error: -t <type> and -o <path> are required");
15
+ process.exit(1);
16
+ }
17
+ const traceDir = findSessionTraceDir(sessionId);
18
+ if (!traceDir) {
19
+ console.error(`Session not found: ${sessionId}`);
20
+ process.exit(1);
21
+ }
22
+ await record.initStateManager(traceDir);
23
+ const formatType = flags.format || "json";
24
+ const compact = flags.compact === true;
25
+ const exportType = flags.type;
26
+ const records = store.getSessionRecords(sessionId, { traceDir });
27
+ if (records.length === 0) {
28
+ console.error("No records found");
29
+ process.exit(1);
30
+ }
31
+ const lastReqId = records[records.length - 1].id;
32
+ const range = flags.req ? parseRange(flags.req, lastReqId) : null;
33
+ if (exportType === "raw" && flags.req) {
34
+ console.error("Warning: -r parameter is not applicable for raw export type");
35
+ }
36
+ let data;
37
+ switch (exportType) {
38
+ case "metadata": {
39
+ const parsedRecords = records.map((rec) => ({
40
+ id: rec.id,
41
+ parsed: parse.detectAndParse(rec),
42
+ }));
43
+ data = query.buildSessionMetadata(sessionId, parsedRecords);
44
+ const sessionMeta = store.readSessionMetadata(sessionId, traceDir);
45
+ if (sessionMeta) {
46
+ data.createdAt = sessionMeta.createdAt ?? data.createdAt;
47
+ data.updatedAt = sessionMeta.updatedAt ?? data.updatedAt;
48
+ data.enabled = sessionMeta.enabled ?? false;
49
+ }
50
+ break;
51
+ }
52
+ case "conversation": {
53
+ const outputPath = resolve(flags.output);
54
+ if (outputPath.endsWith(".json") || outputPath.endsWith(".xml")) {
55
+ console.error("Error: Output path must be a folder for export");
56
+ process.exit(1);
57
+ }
58
+ const effectiveRange = range ?? { start: lastReqId, end: null };
59
+ const conversations = {};
60
+ for (const rec of records) {
61
+ if (inRange(rec.id, effectiveRange)) {
62
+ conversations[rec.id] = parse.detectAndParse(rec);
63
+ }
64
+ }
65
+ const collapseItems = parseCollapse(flags.collapse);
66
+ const collapseBlockTypes = parseCollapseBlocks(flags.collapseBlocks);
67
+ const result = format.collapseConversations(conversations, {
68
+ collapse: collapseItems,
69
+ collapseBlocks: collapseBlockTypes,
70
+ format: formatType
71
+ });
72
+ writeCollapsedExport(outputPath, result, formatType);
73
+ return;
74
+ }
75
+ case "changes": {
76
+ const outputPath = resolve(flags.output);
77
+ if (outputPath.endsWith(".json") || outputPath.endsWith(".xml")) {
78
+ console.error("Error: Output path must be a folder for export");
79
+ process.exit(1);
80
+ }
81
+ const parsedRecords = records.map((rec) => ({
82
+ id: rec.id,
83
+ parsed: parse.detectAndParse(rec),
84
+ }));
85
+ const timeline = query.buildSessionTimeline(sessionId, parsedRecords);
86
+ const deltas = {};
87
+ for (const change of timeline.changes) {
88
+ if (inRange(change.requestId, range)) {
89
+ deltas[change.requestId] = change.delta;
90
+ }
91
+ }
92
+ const collapseItems = parseCollapse(flags.collapse);
93
+ const collapseBlockTypes = parseCollapseBlocks(flags.collapseBlocks);
94
+ const result = format.collapseDeltas(deltas, {
95
+ collapse: collapseItems,
96
+ collapseBlocks: collapseBlockTypes,
97
+ format: formatType
98
+ });
99
+ writeCollapsedExport(outputPath, result, formatType);
100
+ return;
101
+ }
102
+ case "raw": {
103
+ try {
104
+ const stream = await store.exportSessionZip(sessionId, { traceDir });
105
+ const outputPath = resolve(flags.output);
106
+ const writeStream = createWriteStream(outputPath);
107
+ stream.pipe(writeStream);
108
+ await new Promise((resolve, reject) => {
109
+ writeStream.on("finish", () => resolve());
110
+ writeStream.on("error", (err) => reject(err));
111
+ stream.on("error", (err) => reject(err));
112
+ });
113
+ console.log(JSON.stringify({ success: true, path: outputPath }));
114
+ return;
115
+ }
116
+ catch (e) {
117
+ console.error(`Failed to export: ${e.message}`);
118
+ process.exit(1);
119
+ }
120
+ }
121
+ default:
122
+ console.error(`Unknown export type: ${exportType}`);
123
+ process.exit(1);
124
+ }
125
+ let output;
126
+ if (formatType === "xml") {
127
+ if (isConversationsMap(data)) {
128
+ output = format.conversationsMapToXML(data);
129
+ }
130
+ else if (isDeltasMap(data)) {
131
+ output = format.deltasMapToXML(data);
132
+ }
133
+ else {
134
+ output = JSON.stringify(data, null, compact ? 0 : 2);
135
+ }
136
+ }
137
+ else {
138
+ output = JSON.stringify(data, null, compact ? 0 : 2);
139
+ }
140
+ const outputPath = resolve(flags.output);
141
+ try {
142
+ writeFileSync(outputPath, output, "utf-8");
143
+ console.log(JSON.stringify({ success: true, path: outputPath }));
144
+ }
145
+ catch (e) {
146
+ console.error(`Failed to export: ${e.message}`);
147
+ process.exit(1);
148
+ }
149
+ }
150
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/handlers/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdList(args: string[]): void;
2
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/handlers/list.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmB5C"}
@@ -0,0 +1,18 @@
1
+ import { store } from "@opencode-trace/core";
2
+ import { GLOBAL_TRACE_DIR, LOCAL_TRACE_DIR } from "../utils.js";
3
+ export function cmdList(args) {
4
+ const localSessions = store.listSessions({ traceDir: LOCAL_TRACE_DIR });
5
+ const globalSessions = store.listSessions({ traceDir: GLOBAL_TRACE_DIR });
6
+ const all = [
7
+ ...localSessions.map((s) => ({ ...s, scope: "local" })),
8
+ ...globalSessions.map((s) => ({ ...s, scope: "global" })),
9
+ ];
10
+ if (all.length === 0) {
11
+ console.log("No sessions found.");
12
+ return;
13
+ }
14
+ for (const s of all) {
15
+ console.log(`${s.id} title:${s.title ?? "?"} created:${s.createdAt ?? "?"} updated:${s.updatedAt ?? "?"}`);
16
+ }
17
+ }
18
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/handlers/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,UAAU,OAAO,CAAC,IAAc;IACpC,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAE1E,MAAM,GAAG,GAAG;QACV,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACvD,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;KAC1D,CAAC;IAEF,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,SAAS,IAAI,GAAG,EAAE,CACjG,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdShow(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/handlers/show.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF3D"}
@@ -0,0 +1,74 @@
1
+ import { store, parse, query, record } from "@opencode-trace/core";
2
+ import { parseFlags, parseRange, inRange, findSessionTraceDir } from "../utils.js";
3
+ import { outputData } from "../formatter.js";
4
+ export async function cmdShow(args) {
5
+ const { positional, flags } = parseFlags(args);
6
+ const sessionId = positional[0];
7
+ const subCommand = positional[1];
8
+ if (!sessionId || !subCommand) {
9
+ console.error("Error: session-id and subcommand are required");
10
+ process.exit(1);
11
+ }
12
+ const traceDir = findSessionTraceDir(sessionId);
13
+ if (!traceDir) {
14
+ console.error(`Session not found: ${sessionId}`);
15
+ process.exit(1);
16
+ }
17
+ await record.initStateManager(traceDir);
18
+ const formatType = flags.format || "json";
19
+ const compact = flags.compact === true;
20
+ const records = store.getSessionRecords(sessionId, { traceDir });
21
+ if (records.length === 0) {
22
+ console.error("No records found");
23
+ process.exit(1);
24
+ }
25
+ const lastReqId = records[records.length - 1].id;
26
+ const range = flags.req ? parseRange(flags.req, lastReqId) : null;
27
+ switch (subCommand) {
28
+ case "metadata": {
29
+ const parsedRecords = records.map((rec) => ({
30
+ id: rec.id,
31
+ parsed: parse.detectAndParse(rec),
32
+ }));
33
+ const metadata = query.buildSessionMetadata(sessionId, parsedRecords);
34
+ const sessionMeta = store.readSessionMetadata(sessionId, traceDir);
35
+ if (sessionMeta) {
36
+ metadata.createdAt = sessionMeta.createdAt ?? metadata.createdAt;
37
+ metadata.updatedAt = sessionMeta.updatedAt ?? metadata.updatedAt;
38
+ metadata.enabled = sessionMeta.enabled ?? false;
39
+ }
40
+ outputData(metadata, formatType, compact);
41
+ break;
42
+ }
43
+ case "conversation": {
44
+ const effectiveRange = range ?? { start: lastReqId, end: null };
45
+ const result = {};
46
+ for (const rec of records) {
47
+ if (inRange(rec.id, effectiveRange)) {
48
+ result[rec.id] = parse.detectAndParse(rec);
49
+ }
50
+ }
51
+ outputData(result, formatType, compact);
52
+ break;
53
+ }
54
+ case "changes": {
55
+ const parsedRecords = records.map((rec) => ({
56
+ id: rec.id,
57
+ parsed: parse.detectAndParse(rec),
58
+ }));
59
+ const timeline = query.buildSessionTimeline(sessionId, parsedRecords);
60
+ const result = {};
61
+ for (const change of timeline.changes) {
62
+ if (inRange(change.requestId, range)) {
63
+ result[change.requestId] = change.delta;
64
+ }
65
+ }
66
+ outputData(result, formatType, compact);
67
+ break;
68
+ }
69
+ default:
70
+ console.error(`Unknown subcommand: ${subCommand}`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../src/handlers/show.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdStatus(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/handlers/status.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B7D"}
@@ -0,0 +1,23 @@
1
+ import { record } from "@opencode-trace/core";
2
+ import { parseFlags, GLOBAL_TRACE_DIR, LOCAL_TRACE_DIR } from "../utils.js";
3
+ export async function cmdStatus(args) {
4
+ const { positional, flags } = parseFlags(args);
5
+ const traceDir = flags.session ? LOCAL_TRACE_DIR : GLOBAL_TRACE_DIR;
6
+ await record.initStateManager(traceDir);
7
+ const status = {};
8
+ if (flags.session) {
9
+ const sessionId = positional[0];
10
+ if (!sessionId) {
11
+ console.error("Error: session-id is required when using -s");
12
+ process.exit(1);
13
+ }
14
+ status.globalEnabled = record.getGlobalTraceEnabled(traceDir);
15
+ status.sessionEnabled = record.getSessionEnabled(sessionId, traceDir);
16
+ status.sessionId = sessionId;
17
+ }
18
+ else {
19
+ status.globalEnabled = record.getGlobalTraceEnabled(traceDir);
20
+ }
21
+ console.log(JSON.stringify(status, null, 2));
22
+ }
23
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/handlers/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IAC5C,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEpE,MAAM,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,MAAM,GAIR,EAAE,CAAC;IAEP,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdSync(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/handlers/sync.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB3D"}
@@ -0,0 +1,19 @@
1
+ import { resolve } from "node:path";
2
+ import { record, logger } from "@opencode-trace/core";
3
+ import { parseFlags, GLOBAL_TRACE_DIR } from "../utils.js";
4
+ export async function cmdSync(args) {
5
+ const { flags } = parseFlags(args);
6
+ const traceDir = GLOBAL_TRACE_DIR;
7
+ if (flags.repair) {
8
+ const { existsSync, rmSync } = await import("node:fs");
9
+ const dbPath = resolve(traceDir, "state.db");
10
+ if (existsSync(dbPath)) {
11
+ rmSync(dbPath, { force: true });
12
+ logger.info("Removed corrupted state.db");
13
+ }
14
+ }
15
+ await record.initStateManager(traceDir);
16
+ record.syncState(traceDir);
17
+ logger.info("Sync completed");
18
+ }
19
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/handlers/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;IAElC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC7C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdViewer(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/handlers/viewer.ts"],"names":[],"mappings":"AAMA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7D"}
@@ -0,0 +1,16 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ export async function cmdViewer(args) {
6
+ const viewerPath = resolve(__dirname, '..', '..', 'viewer', 'cli.js');
7
+ const child = spawn('node', [viewerPath, ...args], { stdio: 'inherit' });
8
+ child.on('error', (err) => {
9
+ console.error(`Failed to spawn viewer: ${err.message}`);
10
+ process.exit(1);
11
+ });
12
+ child.on('exit', (code) => {
13
+ process.exit(code ?? 0);
14
+ });
15
+ }
16
+ //# sourceMappingURL=viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/handlers/viewer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAErE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAExE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=viewer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.test.d.ts","sourceRoot":"","sources":["../../src/handlers/viewer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @vitest-environment node
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import * as childProcess from 'node:child_process';
6
+ vi.mock('node:child_process', async (importOriginal) => {
7
+ const actual = await importOriginal();
8
+ return {
9
+ ...actual,
10
+ default: actual,
11
+ spawn: vi.fn()
12
+ };
13
+ });
14
+ describe('cmdViewer', () => {
15
+ let mockSpawn;
16
+ let exitSpy;
17
+ beforeEach(async () => {
18
+ vi.resetModules();
19
+ mockSpawn = vi.mocked(childProcess.spawn);
20
+ exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined);
21
+ vi.clearAllMocks();
22
+ });
23
+ afterEach(() => {
24
+ exitSpy.mockRestore();
25
+ vi.restoreAllMocks();
26
+ });
27
+ it('should spawn viewer CLI with args', async () => {
28
+ const mockChild = {
29
+ on: vi.fn((event, callback) => {
30
+ if (event === 'exit') {
31
+ callback(0);
32
+ }
33
+ return mockChild;
34
+ })
35
+ };
36
+ mockSpawn.mockReturnValue(mockChild);
37
+ const { cmdViewer } = await import('./viewer.js');
38
+ await cmdViewer(['--port', '3000']);
39
+ expect(mockSpawn).toHaveBeenCalledWith('node', [expect.stringContaining('viewer/cli.js'), '--port', '3000'], { stdio: 'inherit' });
40
+ expect(exitSpy).toHaveBeenCalledWith(0);
41
+ });
42
+ it('should pass through exit code', async () => {
43
+ const mockChild = {
44
+ on: vi.fn((event, callback) => {
45
+ if (event === 'exit') {
46
+ callback(1);
47
+ }
48
+ return mockChild;
49
+ })
50
+ };
51
+ mockSpawn.mockReturnValue(mockChild);
52
+ const { cmdViewer } = await import('./viewer.js');
53
+ await cmdViewer([]);
54
+ expect(exitSpy).toHaveBeenCalledWith(1);
55
+ });
56
+ it('should handle spawn errors', async () => {
57
+ const mockError = new Error('spawn error');
58
+ const mockChild = {
59
+ on: vi.fn((event, callback) => {
60
+ if (event === 'error') {
61
+ callback(mockError);
62
+ }
63
+ return mockChild;
64
+ })
65
+ };
66
+ mockSpawn.mockReturnValue(mockChild);
67
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
68
+ const { cmdViewer } = await import('./viewer.js');
69
+ await cmdViewer([]);
70
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to spawn viewer: spawn error');
71
+ expect(exitSpy).toHaveBeenCalledWith(1);
72
+ consoleErrorSpy.mockRestore();
73
+ });
74
+ });
75
+ //# sourceMappingURL=viewer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.test.js","sourceRoot":"","sources":["../../src/handlers/viewer.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAA;AAElD,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IACrD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAuC,CAAA;IAC1E,OAAO;QACL,GAAG,MAAM;QACT,OAAO,EAAE,MAAM;QACf,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACf,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAI,SAAmC,CAAA;IACvC,IAAI,OAAoC,CAAA;IAExC,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,YAAY,EAAE,CAAA;QACjB,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QACzC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,SAAkB,CAAC,CAAA;QAChF,EAAE,CAAC,aAAa,EAAE,CAAA;IACpB,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,WAAW,EAAE,CAAA;QACrB,EAAE,CAAC,eAAe,EAAE,CAAA;IACtB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,SAAS,GAAG;YAChB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAC5B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACrB,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACb,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC,CAAC;SACH,CAAA;QACD,SAAS,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAA;QAE3C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QACjD,MAAM,SAAS,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;QAEnC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,MAAM,EACN,CAAC,MAAM,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAC5D,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAA;QACD,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,SAAS,GAAG;YAChB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAC5B,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBACrB,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACb,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC,CAAC;SACH,CAAA;QACD,SAAS,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAA;QAE3C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QACjD,MAAM,SAAS,CAAC,EAAE,CAAC,CAAA;QAEnB,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC,CAAA;QAC1C,MAAM,SAAS,GAAG;YAChB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAC5B,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBACtB,QAAQ,CAAC,SAAS,CAAC,CAAA;gBACrB,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC,CAAC;SACH,CAAA;QACD,SAAS,CAAC,eAAe,CAAC,SAAgB,CAAC,CAAA;QAE3C,MAAM,eAAe,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAE/E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QACjD,MAAM,SAAS,CAAC,EAAE,CAAC,CAAA;QAEnB,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAAC,qCAAqC,CAAC,CAAA;QACnF,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAA;QAEvC,eAAe,CAAC,WAAW,EAAE,CAAA;IAC/B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env node
2
+ import { cmdEnable } from "./handlers/enable.js";
3
+ import { cmdDisable } from "./handlers/disable.js";
4
+ import { cmdStatus } from "./handlers/status.js";
5
+ import { cmdList } from "./handlers/list.js";
6
+ import { cmdSync } from "./handlers/sync.js";
7
+ import { cmdShow } from "./handlers/show.js";
8
+ import { cmdExport } from "./handlers/export.js";
9
+ import { cmdViewer } from "./handlers/viewer.js";
10
+ function help() {
11
+ console.log(`opencode-trace - CLI for managing opencode trace data
12
+
13
+ Usage:
14
+ opencode-trace <command> [options]
15
+
16
+ Commands:
17
+ enable [-s] [session-id] Enable trace (global by default)
18
+ -s: enable specific session
19
+ disable [-s] [session-id] Disable trace (global by default)
20
+ -s: disable specific session
21
+ status [-s] [session-id] Show trace status (global by default)
22
+ -s: show specific session status
23
+ list List all sessions
24
+ Shows: session-id, title, created, updated
25
+ show <session-id> metadata Show session metadata
26
+ show <session-id> conversation [-r <range>] [--format json/xml] [--compact]
27
+ Show conversation (last request by default)
28
+ -r: request range, e.g., "1:3" means [1,3)
29
+ if single number like "1", means [1,last]
30
+ returns {req_id: conversation, ...}
31
+ show <session-id> changes [-r <range>] [--format json/xml] [--compact]
32
+ Show changes (all requests by default)
33
+ -r: request range, e.g., "1:3" means [1,3)
34
+ returns {req_id: delta, ...}
35
+ export <session-id> -t <type> -o <folder> [-r <range>] [--format json/xml]
36
+ [--collapse sys,tool,msgs]
37
+ [--collapse-blocks <types>]
38
+ Export session data to folder
39
+ -t: metadata/conversation/changes/raw
40
+ raw: export original data as ZIP
41
+ -o: output folder path (required)
42
+ -r: request range (not for raw)
43
+ --collapse: top-level collapse (sys,tool,msgs)
44
+ --collapse-blocks: block types (text,thinking,td,tc,tr,image,other)
45
+ sync [--repair] Sync SQLite with filesystem
46
+ --repair: rebuild corrupted state.db
47
+ viewer [options] Start web viewer
48
+ Options: --port <num>, --no-open
49
+ help Show this help message
50
+ `);
51
+ }
52
+ async function main() {
53
+ const args = process.argv.slice(2);
54
+ const command = args[0];
55
+ if (!command) {
56
+ console.error("Usage: opencode-trace <command> [options]");
57
+ console.error("Commands: enable, disable, status, list, sync, show, export");
58
+ process.exit(1);
59
+ }
60
+ if (command === "--version" || command === "-v") {
61
+ console.error("opencode-trace version 0.0.1");
62
+ process.exit(0);
63
+ }
64
+ if (command === "--help" || command === "-h") {
65
+ console.error("Usage: opencode-trace <command> [options]");
66
+ console.error("Commands:");
67
+ console.error(" enable [--session <id>] - Enable trace recording");
68
+ console.error(" disable [--session <id>] - Disable trace recording");
69
+ console.error(" status [--session <id>] - Show trace status");
70
+ console.error(" list - List all sessions");
71
+ console.error(" sync [--repair] - Sync trace data");
72
+ console.error(" viewer [options] - Start web viewer");
73
+ console.error(" show <type> <session> - Show trace data");
74
+ console.error(" export <type> <session> - Export trace data");
75
+ process.exit(0);
76
+ }
77
+ const handlerArgs = args.slice(1);
78
+ switch (command) {
79
+ case "enable":
80
+ await cmdEnable(handlerArgs);
81
+ break;
82
+ case "disable":
83
+ await cmdDisable(handlerArgs);
84
+ break;
85
+ case "status":
86
+ await cmdStatus(handlerArgs);
87
+ break;
88
+ case "list":
89
+ cmdList(handlerArgs);
90
+ break;
91
+ case "sync":
92
+ await cmdSync(handlerArgs);
93
+ break;
94
+ case "show":
95
+ await cmdShow(handlerArgs);
96
+ break;
97
+ case "export":
98
+ await cmdExport(handlerArgs);
99
+ break;
100
+ case "viewer":
101
+ await cmdViewer(handlerArgs);
102
+ break;
103
+ case "help":
104
+ help();
105
+ break;
106
+ default:
107
+ console.error(`Unknown command: ${command}`);
108
+ process.exit(1);
109
+ }
110
+ }
111
+ main().catch((err) => {
112
+ console.error(err);
113
+ process.exit(1);
114
+ });
115
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { execSync } from "node:child_process";
3
+ import { resolve } from "node:path";
4
+ const CLI_PATH = resolve(__dirname, "..", "dist", "index.js");
5
+ function runCLI(args) {
6
+ try {
7
+ const stdout = execSync(`node ${CLI_PATH} ${args}`, {
8
+ encoding: "utf-8",
9
+ cwd: resolve(__dirname, ".."),
10
+ });
11
+ return { stdout, stderr: "", exitCode: 0 };
12
+ }
13
+ catch (error) {
14
+ return {
15
+ stdout: error.stdout ?? "",
16
+ stderr: error.stderr ?? "",
17
+ exitCode: error.status ?? 1,
18
+ };
19
+ }
20
+ }
21
+ describe("parseCollapse", () => {
22
+ it("should accept valid collapse options in flags", () => {
23
+ const result = runCLI("help --collapse sys,tool,msgs");
24
+ expect(result.exitCode).toBe(0);
25
+ });
26
+ });
27
+ describe("parseCollapseBlocks", () => {
28
+ it("should accept valid block types in flags", () => {
29
+ const result = runCLI("help --collapse-blocks text,thinking");
30
+ expect(result.exitCode).toBe(0);
31
+ });
32
+ });
33
+ describe("export validation", () => {
34
+ it("help shows output folder requirement for conversation export", () => {
35
+ const result = runCLI("help");
36
+ expect(result.stdout).toContain("-o: output folder path");
37
+ });
38
+ });
39
+ describe("help text", () => {
40
+ it("should show --collapse option in help", () => {
41
+ const result = runCLI("help");
42
+ expect(result.stdout).toContain("--collapse");
43
+ expect(result.stdout).toContain("sys,tool,msgs");
44
+ });
45
+ it("should show --collapse-blocks option in help", () => {
46
+ const result = runCLI("help");
47
+ expect(result.stdout).toContain("--collapse-blocks");
48
+ expect(result.stdout).toContain("text,thinking,td,tc,tr,image,other");
49
+ });
50
+ });
51
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AAE9D,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,QAAQ,IAAI,IAAI,EAAE,EAAE;YAClD,QAAQ,EAAE,OAAO;YACjB,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC;SAC9B,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;SAC5B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,+BAA+B,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,sCAAsC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const GLOBAL_TRACE_DIR: string;
2
+ export declare const LOCAL_TRACE_DIR: string;
3
+ export interface ParsedFlags {
4
+ positional: string[];
5
+ flags: Record<string, string | boolean>;
6
+ }
7
+ export interface RequestRange {
8
+ start: number;
9
+ end: number | null;
10
+ }
11
+ export declare function parseRange(rangeStr: string, lastReqId: number): RequestRange;
12
+ export declare function inRange(reqId: number, range: RequestRange | null): boolean;
13
+ export declare function parseFlags(argv: string[]): ParsedFlags;
14
+ export declare function findSessionTraceDir(sessionId: string): string | null;
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,QAAwC,CAAC;AACtE,eAAO,MAAM,eAAe,QAA4C,CAAC;AAEzE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CA4B5E;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,OAAO,CAK1E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CA0CtD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcpE"}
package/dist/utils.js ADDED
@@ -0,0 +1,106 @@
1
+ import { resolve } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { store } from "@opencode-trace/core";
4
+ export const GLOBAL_TRACE_DIR = resolve(homedir(), ".opencode-trace");
5
+ export const LOCAL_TRACE_DIR = resolve(process.cwd(), ".opencode-trace");
6
+ export function parseRange(rangeStr, lastReqId) {
7
+ if (!/^\d+(:\d*)?$/.test(rangeStr)) {
8
+ console.error(`Error: Invalid range format: ${rangeStr}. Expected format: "N" or "N:M"`);
9
+ process.exit(1);
10
+ }
11
+ if (rangeStr.includes(":")) {
12
+ const parts = rangeStr.split(":");
13
+ const start = parseInt(parts[0], 10);
14
+ const end = parts[1] ? parseInt(parts[1], 10) : null;
15
+ if (start < 1) {
16
+ console.error(`Error: Range start must be >= 1, got: ${start}`);
17
+ process.exit(1);
18
+ }
19
+ if (end !== null && end <= start) {
20
+ console.error(`Error: Range end must be > start, got: ${start}:${end}`);
21
+ process.exit(1);
22
+ }
23
+ return { start, end };
24
+ }
25
+ const start = parseInt(rangeStr, 10);
26
+ if (start < 1) {
27
+ console.error(`Error: Request ID must be >= 1, got: ${start}`);
28
+ process.exit(1);
29
+ }
30
+ return { start, end: lastReqId };
31
+ }
32
+ export function inRange(reqId, range) {
33
+ if (!range)
34
+ return true;
35
+ if (reqId < range.start)
36
+ return false;
37
+ if (range.end !== null && reqId >= range.end)
38
+ return false;
39
+ return true;
40
+ }
41
+ export function parseFlags(argv) {
42
+ const positional = [];
43
+ const flags = {};
44
+ let i = 0;
45
+ while (i < argv.length) {
46
+ const arg = argv[i];
47
+ if (arg === "-s" || arg === "--session") {
48
+ flags.session = true;
49
+ }
50
+ else if (arg === "-r" && i + 1 < argv.length) {
51
+ flags.req = argv[++i];
52
+ }
53
+ else if (arg === "-o" && i + 1 < argv.length) {
54
+ flags.output = argv[++i];
55
+ }
56
+ else if (arg === "-t" && i + 1 < argv.length) {
57
+ const t = argv[++i];
58
+ if (!["metadata", "conversation", "changes", "raw"].includes(t)) {
59
+ console.error(`Error: Invalid export type: ${t}. Valid: metadata, conversation, changes, raw`);
60
+ process.exit(1);
61
+ }
62
+ flags.type = t;
63
+ }
64
+ else if (arg === "--format" && i + 1 < argv.length) {
65
+ const fmt = argv[++i];
66
+ if (fmt !== "json" && fmt !== "xml") {
67
+ console.error(`Error: Invalid format: ${fmt}. Valid: json, xml`);
68
+ process.exit(1);
69
+ }
70
+ flags.format = fmt;
71
+ }
72
+ else if (arg === "--compact") {
73
+ flags.compact = true;
74
+ }
75
+ else if (arg === "--collapse" && i + 1 < argv.length) {
76
+ flags.collapse = argv[++i];
77
+ }
78
+ else if (arg === "--collapse-blocks" && i + 1 < argv.length) {
79
+ flags.collapseBlocks = argv[++i];
80
+ }
81
+ else if (arg === "--repair") {
82
+ flags.repair = true;
83
+ }
84
+ else if (!arg.startsWith("-")) {
85
+ positional.push(arg);
86
+ }
87
+ i++;
88
+ }
89
+ return { positional, flags };
90
+ }
91
+ export function findSessionTraceDir(sessionId) {
92
+ const localMeta = store.readSessionMetadata(sessionId, LOCAL_TRACE_DIR);
93
+ if (localMeta)
94
+ return LOCAL_TRACE_DIR;
95
+ const globalMeta = store.readSessionMetadata(sessionId, GLOBAL_TRACE_DIR);
96
+ if (globalMeta)
97
+ return GLOBAL_TRACE_DIR;
98
+ const localRecords = store.getSessionRecords(sessionId, { traceDir: LOCAL_TRACE_DIR });
99
+ if (localRecords.length > 0)
100
+ return LOCAL_TRACE_DIR;
101
+ const globalRecords = store.getSessionRecords(sessionId, { traceDir: GLOBAL_TRACE_DIR });
102
+ if (globalRecords.length > 0)
103
+ return GLOBAL_TRACE_DIR;
104
+ return null;
105
+ }
106
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@opencode-trace/cli",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "description": "CLI tool for opencode-trace",
6
+ "bin": {
7
+ "opencode-trace": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist/",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest watch",
17
+ "clean": "rm -rf dist *.tsbuildinfo"
18
+ },
19
+ "dependencies": {
20
+ "@opencode-trace/core": "0.0.2",
21
+ "adm-zip": "^0.5.17",
22
+ "archiver": "^7.0.0",
23
+ "marked": "^18.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/adm-zip": "^0.5.8",
27
+ "@types/archiver": "^6.0.0",
28
+ "typescript": "^5.3.0",
29
+ "vitest": "^4.1.5"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public",
33
+ "registry": "https://registry.npmjs.org/"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/aixmoyu/opencode-trace.git",
38
+ "directory": "packages/cli"
39
+ },
40
+ "keywords": [
41
+ "opencode",
42
+ "trace",
43
+ "cli"
44
+ ],
45
+ "license": "MIT"
46
+ }