@oh-my-pi/omp-stats 12.0.0 → 12.1.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 (3) hide show
  1. package/package.json +66 -65
  2. package/src/db.ts +3 -4
  3. package/src/parser.ts +13 -17
package/package.json CHANGED
@@ -1,66 +1,67 @@
1
1
  {
2
- "name": "@oh-my-pi/omp-stats",
3
- "version": "12.0.0",
4
- "description": "Local observability dashboard for pi AI usage statistics",
5
- "type": "module",
6
- "main": "./src/index.ts",
7
- "types": "./src/index.ts",
8
- "bin": {
9
- "omp-stats": "./src/index.ts"
10
- },
11
- "exports": {
12
- ".": {
13
- "types": "./src/index.ts",
14
- "import": "./src/index.ts"
15
- },
16
- "./src/server": {
17
- "types": "./src/server.ts",
18
- "import": "./src/server.ts"
19
- },
20
- "./src/db": {
21
- "types": "./src/db.ts",
22
- "import": "./src/db.ts"
23
- }
24
- },
25
- "files": [
26
- "src",
27
- "public",
28
- "README.md"
29
- ],
30
- "keywords": [
31
- "ai",
32
- "observability",
33
- "metrics",
34
- "dashboard",
35
- "llm",
36
- "statistics"
37
- ],
38
- "scripts": {
39
- "dev": "bun run src/index.ts",
40
- "check": "tsgo -p tsconfig.json && tsgo -p tsconfig.client.json",
41
- "build": "bun run build.ts"
42
- },
43
- "author": "Can Bölük",
44
- "license": "MIT",
45
- "repository": {
46
- "type": "git",
47
- "url": "git+https://github.com/can1357/oh-my-pi.git",
48
- "directory": "packages/stats"
49
- },
50
- "dependencies": {
51
- "@oh-my-pi/pi-ai": "12.0.0",
52
- "date-fns": "^4.1.0",
53
- "lucide-react": "^0.563.0",
54
- "react": "^19.2.4",
55
- "react-dom": "^19.2.4",
56
- "recharts": "^3.7.0"
57
- },
58
- "devDependencies": {
59
- "@types/bun": "^1.3.9",
60
- "@types/react": "^19.2.10",
61
- "@types/react-dom": "^19.2.3"
62
- },
63
- "engines": {
64
- "bun": ">=1.3.7"
65
- }
66
- }
2
+ "name": "@oh-my-pi/omp-stats",
3
+ "version": "12.1.0",
4
+ "description": "Local observability dashboard for pi AI usage statistics",
5
+ "type": "module",
6
+ "main": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
+ "bin": {
9
+ "omp-stats": "./src/index.ts"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./src/index.ts",
14
+ "import": "./src/index.ts"
15
+ },
16
+ "./src/server": {
17
+ "types": "./src/server.ts",
18
+ "import": "./src/server.ts"
19
+ },
20
+ "./src/db": {
21
+ "types": "./src/db.ts",
22
+ "import": "./src/db.ts"
23
+ }
24
+ },
25
+ "files": [
26
+ "src",
27
+ "public",
28
+ "README.md"
29
+ ],
30
+ "keywords": [
31
+ "ai",
32
+ "observability",
33
+ "metrics",
34
+ "dashboard",
35
+ "llm",
36
+ "statistics"
37
+ ],
38
+ "scripts": {
39
+ "dev": "bun run src/index.ts",
40
+ "check": "tsgo -p tsconfig.json && tsgo -p tsconfig.client.json",
41
+ "build": "bun run build.ts"
42
+ },
43
+ "author": "Can Bölük",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/can1357/oh-my-pi.git",
48
+ "directory": "packages/stats"
49
+ },
50
+ "dependencies": {
51
+ "@oh-my-pi/pi-ai": "12.1.0",
52
+ "date-fns": "^4.1.0",
53
+ "lucide-react": "^0.563.0",
54
+ "react": "^19.2.4",
55
+ "react-dom": "^19.2.4",
56
+ "recharts": "^3.7.0",
57
+ "@oh-my-pi/pi-utils": "12.1.0"
58
+ },
59
+ "devDependencies": {
60
+ "@types/bun": "^1.3.9",
61
+ "@types/react": "^19.2.10",
62
+ "@types/react-dom": "^19.2.3"
63
+ },
64
+ "engines": {
65
+ "bun": ">=1.3.7"
66
+ }
67
+ }
package/src/db.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import * as fs from "node:fs/promises";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
3
+ import { getConfigRootDir, getStatsDbPath } from "@oh-my-pi/pi-utils/dirs";
5
4
  import type {
6
5
  AggregatedStats,
7
6
  FolderStats,
@@ -12,7 +11,7 @@ import type {
12
11
  TimeSeriesPoint,
13
12
  } from "./types";
14
13
 
15
- const DB_PATH = path.join(os.homedir(), ".omp", "stats.db");
14
+ const DB_PATH = getStatsDbPath();
16
15
 
17
16
  let db: Database | null = null;
18
17
 
@@ -23,7 +22,7 @@ export async function initDb(): Promise<Database> {
23
22
  if (db) return db;
24
23
 
25
24
  // Ensure directory exists
26
- await fs.mkdir(path.join(os.homedir(), ".omp"), { recursive: true });
25
+ await fs.mkdir(getConfigRootDir(), { recursive: true });
27
26
 
28
27
  db = new Database(DB_PATH);
29
28
  db.exec("PRAGMA journal_mode = WAL");
package/src/parser.ts CHANGED
@@ -1,11 +1,9 @@
1
1
  import * as fs from "node:fs/promises";
2
- import * as os from "node:os";
3
2
  import * as path from "node:path";
4
3
  import type { AssistantMessage } from "@oh-my-pi/pi-ai";
4
+ import { getSessionsDir } from "@oh-my-pi/pi-utils/dirs";
5
5
  import type { MessageStats, SessionEntry, SessionMessageEntry } from "./types";
6
6
 
7
- const SESSIONS_DIR = path.join(os.homedir(), ".omp", "agent", "sessions");
8
-
9
7
  /**
10
8
  * Extract folder name from session filename.
11
9
  * Session files are named like: --work--pi--/timestamp_uuid.jsonl
@@ -72,12 +70,16 @@ export async function parseSessionFile(
72
70
  for (const line of lines) {
73
71
  const lineLength = line.length + 1; // +1 for newline
74
72
  if (line.trim()) {
75
- const entry = JSON.parse(line) as SessionEntry;
76
- if (currentOffset >= fromOffset && entry && isAssistantMessage(entry)) {
77
- const msgStats = extractStats(sessionPath, folder, entry);
78
- if (msgStats) {
79
- stats.push(msgStats);
73
+ try {
74
+ const entry = JSON.parse(line) as SessionEntry;
75
+ if (currentOffset >= fromOffset && entry && isAssistantMessage(entry)) {
76
+ const msgStats = extractStats(sessionPath, folder, entry);
77
+ if (msgStats) {
78
+ stats.push(msgStats);
79
+ }
80
80
  }
81
+ } catch {
82
+ // Skip malformed JSONL lines
81
83
  }
82
84
  }
83
85
  currentOffset += lineLength;
@@ -91,8 +93,9 @@ export async function parseSessionFile(
91
93
  */
92
94
  export async function listSessionFolders(): Promise<string[]> {
93
95
  try {
94
- const entries = await fs.readdir(SESSIONS_DIR, { withFileTypes: true });
95
- return entries.filter(e => e.isDirectory()).map(e => path.join(SESSIONS_DIR, e.name));
96
+ const sessionsDir = getSessionsDir();
97
+ const entries = await fs.readdir(sessionsDir, { withFileTypes: true });
98
+ return entries.filter(e => e.isDirectory()).map(e => path.join(sessionsDir, e.name));
96
99
  } catch {
97
100
  return [];
98
101
  }
@@ -125,13 +128,6 @@ export async function listAllSessionFiles(): Promise<string[]> {
125
128
  return allFiles;
126
129
  }
127
130
 
128
- /**
129
- * Get session directory path.
130
- */
131
- export function getSessionsDir(): string {
132
- return SESSIONS_DIR;
133
- }
134
-
135
131
  /**
136
132
  * Find a specific entry in a session file.
137
133
  */