codesession-cli 1.0.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.
- package/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/db.d.ts +15 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +229 -0
- package/dist/db.js.map +1 -0
- package/dist/formatters.d.ts +9 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +121 -0
- package/dist/formatters.js.map +1 -0
- package/dist/git.d.ts +7 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +47 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +168 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher.d.ts +3 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +48 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +46 -0
- package/src/db.ts +239 -0
- package/src/formatters.ts +152 -0
- package/src/git.ts +44 -0
- package/src/index.ts +206 -0
- package/src/types.ts +49 -0
- package/src/watcher.ts +52 -0
- package/test.ts +4 -0
- package/tsconfig.json +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Brian Munene Mwirigi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# codesession
|
|
2
|
+
|
|
3
|
+
Track your AI coding sessions: time, files, commits, and AI costs.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Session Tracking** - Start/stop coding sessions with one command
|
|
8
|
+
- **File Monitoring** - Automatically track file changes
|
|
9
|
+
- **Git Integration** - Log commits during sessions
|
|
10
|
+
- **AI Cost Tracking** - Record AI API usage per session
|
|
11
|
+
- **Statistics** - View productivity metrics
|
|
12
|
+
- **Local Storage** - All data stored locally in SQLite
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Install
|
|
18
|
+
npm install -g codesession
|
|
19
|
+
|
|
20
|
+
# Start a session
|
|
21
|
+
cs start "Build user auth"
|
|
22
|
+
|
|
23
|
+
# Code away... (files, commits tracked automatically)
|
|
24
|
+
|
|
25
|
+
# End session
|
|
26
|
+
cs end -n "Completed basic auth flow"
|
|
27
|
+
|
|
28
|
+
# View session
|
|
29
|
+
cs show
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g codesession
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Start a Session
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Start tracking
|
|
44
|
+
cs start "Feature name"
|
|
45
|
+
|
|
46
|
+
# Automatically tracks:
|
|
47
|
+
# - File changes in real-time
|
|
48
|
+
# - Git commits
|
|
49
|
+
# - Time spent
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### End a Session
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# End with notes
|
|
56
|
+
cs end -n "Completed feature X"
|
|
57
|
+
|
|
58
|
+
# View summary automatically
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### View Sessions
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Show last session
|
|
65
|
+
cs show
|
|
66
|
+
|
|
67
|
+
# Show specific session
|
|
68
|
+
cs show 5
|
|
69
|
+
|
|
70
|
+
# Show with details
|
|
71
|
+
cs show --files --commits
|
|
72
|
+
|
|
73
|
+
# List recent sessions
|
|
74
|
+
cs list
|
|
75
|
+
|
|
76
|
+
# List more
|
|
77
|
+
cs list -l 20
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Statistics
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Overall stats
|
|
84
|
+
cs stats
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Log AI Usage
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Manually log AI usage (or integrate with APIs)
|
|
91
|
+
cs log-ai -p anthropic -m claude-3.5-sonnet -t 15000 -c 0.105
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Check Status
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# See active session
|
|
98
|
+
cs status
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Example Output
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
$ cs show
|
|
105
|
+
|
|
106
|
+
Session: Build user auth
|
|
107
|
+
|
|
108
|
+
┌──────────────┬────────────────────────────┐
|
|
109
|
+
│ Metric │ Value │
|
|
110
|
+
├──────────────┼────────────────────────────┤
|
|
111
|
+
│ Status │ Completed │
|
|
112
|
+
│ Started │ Feb 01, 2026 14:30 │
|
|
113
|
+
│ Ended │ Feb 01, 2026 16:45 │
|
|
114
|
+
│ Duration │ 2h 15m │
|
|
115
|
+
│ Files Changed│ 12 │
|
|
116
|
+
│ Commits │ 5 │
|
|
117
|
+
│ AI Tokens │ 45,000 │
|
|
118
|
+
│ AI Cost │ $2.34 │
|
|
119
|
+
│ Notes │ Completed basic auth flow │
|
|
120
|
+
└──────────────┴────────────────────────────┘
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Use Cases
|
|
124
|
+
|
|
125
|
+
### Freelancers
|
|
126
|
+
Track exact time and costs per feature for client billing.
|
|
127
|
+
|
|
128
|
+
### Indie Hackers
|
|
129
|
+
Monitor build speed and AI spending per feature.
|
|
130
|
+
|
|
131
|
+
### Learning
|
|
132
|
+
See how long features take you to build.
|
|
133
|
+
|
|
134
|
+
### Content Creation
|
|
135
|
+
Auto-generate "I built X in Y hours" blog posts.
|
|
136
|
+
|
|
137
|
+
### Portfolio
|
|
138
|
+
Show concrete evidence of shipping speed.
|
|
139
|
+
|
|
140
|
+
## Integrations
|
|
141
|
+
|
|
142
|
+
### With TokenCost
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Track tokens with tokencost
|
|
146
|
+
tc list --json | jq -r '.[] | "cs log-ai -p \(.provider) -m \(.model) -t \(.totalTokens) -c \(.cost)"'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### With Git Hooks
|
|
150
|
+
|
|
151
|
+
Create `.git/hooks/post-commit`:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
#!/bin/sh
|
|
155
|
+
# Auto-log commits to active session
|
|
156
|
+
cs status > /dev/null 2>&1
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Data Storage
|
|
160
|
+
|
|
161
|
+
All data stored locally in `~/.codesession/sessions.db` (SQLite).
|
|
162
|
+
|
|
163
|
+
No data sent anywhere. 100% privacy.
|
|
164
|
+
|
|
165
|
+
## Development
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Clone
|
|
169
|
+
git clone https://github.com/brian-mwirigi/codesession.git
|
|
170
|
+
cd codesession
|
|
171
|
+
|
|
172
|
+
# Install
|
|
173
|
+
npm install
|
|
174
|
+
|
|
175
|
+
# Dev mode
|
|
176
|
+
npm run dev -- start "Test session"
|
|
177
|
+
|
|
178
|
+
# Build
|
|
179
|
+
npm run build
|
|
180
|
+
|
|
181
|
+
# Test
|
|
182
|
+
npm link
|
|
183
|
+
cs start "My session"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT
|
|
189
|
+
|
|
190
|
+
## Author
|
|
191
|
+
|
|
192
|
+
Built by [Brian Mwirigi](https://github.com/brian-mwirigi)
|
|
193
|
+
|
|
194
|
+
## Testing
|
|
195
|
+
|
|
196
|
+
This is a test modification to trigger file watcher.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
**Track your velocity. Ship faster.**
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Session, FileChange, Commit, AIUsage, SessionStats } from './types';
|
|
2
|
+
export declare function createSession(session: Omit<Session, 'id'>): number;
|
|
3
|
+
export declare function getActiveSession(): Session | null;
|
|
4
|
+
export declare function endSession(sessionId: number, endTime: string, notes?: string): void;
|
|
5
|
+
export declare function getSession(sessionId: number): Session | null;
|
|
6
|
+
export declare function getSessions(limit?: number): Session[];
|
|
7
|
+
export declare function addFileChange(change: Omit<FileChange, 'id'>): void;
|
|
8
|
+
export declare function addCommit(commit: Omit<Commit, 'id'>): void;
|
|
9
|
+
export declare function addAIUsage(usage: Omit<AIUsage, 'id'>): void;
|
|
10
|
+
export declare function getFileChanges(sessionId: number): FileChange[];
|
|
11
|
+
export declare function getCommits(sessionId: number): Commit[];
|
|
12
|
+
export declare function getAIUsage(sessionId: number): AIUsage[];
|
|
13
|
+
export declare function getStats(): SessionStats;
|
|
14
|
+
export declare function closeDb(): void;
|
|
15
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAgE7E,wBAAgB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,MAAM,CAOlE;AAED,wBAAgB,gBAAgB,IAAI,OAAO,GAAG,IAAI,CAKjD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAYnF;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAI5D;AAED,wBAAgB,WAAW,CAAC,KAAK,SAAK,GAAG,OAAO,EAAE,CAIjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,IAAI,CAalE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAa1D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAgB3D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAU9D;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAUtD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAYvD;AAED,wBAAgB,QAAQ,IAAI,YAAY,CAqBvC;AAmBD,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSession = createSession;
|
|
7
|
+
exports.getActiveSession = getActiveSession;
|
|
8
|
+
exports.endSession = endSession;
|
|
9
|
+
exports.getSession = getSession;
|
|
10
|
+
exports.getSessions = getSessions;
|
|
11
|
+
exports.addFileChange = addFileChange;
|
|
12
|
+
exports.addCommit = addCommit;
|
|
13
|
+
exports.addAIUsage = addAIUsage;
|
|
14
|
+
exports.getFileChanges = getFileChanges;
|
|
15
|
+
exports.getCommits = getCommits;
|
|
16
|
+
exports.getAIUsage = getAIUsage;
|
|
17
|
+
exports.getStats = getStats;
|
|
18
|
+
exports.closeDb = closeDb;
|
|
19
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
20
|
+
const path_1 = require("path");
|
|
21
|
+
const os_1 = require("os");
|
|
22
|
+
const fs_1 = require("fs");
|
|
23
|
+
const DB_DIR = (0, path_1.join)((0, os_1.homedir)(), '.devsession');
|
|
24
|
+
const DB_PATH = (0, path_1.join)(DB_DIR, 'sessions.db');
|
|
25
|
+
if (!(0, fs_1.existsSync)(DB_DIR)) {
|
|
26
|
+
(0, fs_1.mkdirSync)(DB_DIR, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
const db = new better_sqlite3_1.default(DB_PATH);
|
|
29
|
+
// Initialize database
|
|
30
|
+
db.exec(`
|
|
31
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
32
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
33
|
+
name TEXT NOT NULL,
|
|
34
|
+
start_time TEXT NOT NULL,
|
|
35
|
+
end_time TEXT,
|
|
36
|
+
duration INTEGER,
|
|
37
|
+
working_directory TEXT NOT NULL,
|
|
38
|
+
files_changed INTEGER DEFAULT 0,
|
|
39
|
+
commits INTEGER DEFAULT 0,
|
|
40
|
+
ai_cost REAL DEFAULT 0,
|
|
41
|
+
ai_tokens INTEGER DEFAULT 0,
|
|
42
|
+
notes TEXT,
|
|
43
|
+
status TEXT DEFAULT 'active'
|
|
44
|
+
)
|
|
45
|
+
`);
|
|
46
|
+
db.exec(`
|
|
47
|
+
CREATE TABLE IF NOT EXISTS file_changes (
|
|
48
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
49
|
+
session_id INTEGER NOT NULL,
|
|
50
|
+
file_path TEXT NOT NULL,
|
|
51
|
+
change_type TEXT NOT NULL,
|
|
52
|
+
timestamp TEXT NOT NULL,
|
|
53
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
54
|
+
)
|
|
55
|
+
`);
|
|
56
|
+
db.exec(`
|
|
57
|
+
CREATE TABLE IF NOT EXISTS commits (
|
|
58
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
59
|
+
session_id INTEGER NOT NULL,
|
|
60
|
+
hash TEXT NOT NULL,
|
|
61
|
+
message TEXT NOT NULL,
|
|
62
|
+
timestamp TEXT NOT NULL,
|
|
63
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
64
|
+
)
|
|
65
|
+
`);
|
|
66
|
+
db.exec(`
|
|
67
|
+
CREATE TABLE IF NOT EXISTS ai_usage (
|
|
68
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
69
|
+
session_id INTEGER NOT NULL,
|
|
70
|
+
provider TEXT NOT NULL,
|
|
71
|
+
model TEXT NOT NULL,
|
|
72
|
+
tokens INTEGER NOT NULL,
|
|
73
|
+
cost REAL NOT NULL,
|
|
74
|
+
timestamp TEXT NOT NULL,
|
|
75
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
76
|
+
)
|
|
77
|
+
`);
|
|
78
|
+
function createSession(session) {
|
|
79
|
+
const stmt = db.prepare(`
|
|
80
|
+
INSERT INTO sessions (name, start_time, working_directory, status)
|
|
81
|
+
VALUES (?, ?, ?, ?)
|
|
82
|
+
`);
|
|
83
|
+
const result = stmt.run(session.name, session.startTime, session.workingDirectory, 'active');
|
|
84
|
+
return result.lastInsertRowid;
|
|
85
|
+
}
|
|
86
|
+
function getActiveSession() {
|
|
87
|
+
const stmt = db.prepare('SELECT * FROM sessions WHERE status = ? ORDER BY id DESC LIMIT 1');
|
|
88
|
+
const row = stmt.get('active');
|
|
89
|
+
if (!row)
|
|
90
|
+
return null;
|
|
91
|
+
return mapSession(row);
|
|
92
|
+
}
|
|
93
|
+
function endSession(sessionId, endTime, notes) {
|
|
94
|
+
const session = getSession(sessionId);
|
|
95
|
+
if (!session)
|
|
96
|
+
return;
|
|
97
|
+
const duration = Math.floor((new Date(endTime).getTime() - new Date(session.startTime).getTime()) / 1000);
|
|
98
|
+
const stmt = db.prepare(`
|
|
99
|
+
UPDATE sessions
|
|
100
|
+
SET end_time = ?, duration = ?, status = ?, notes = ?
|
|
101
|
+
WHERE id = ?
|
|
102
|
+
`);
|
|
103
|
+
stmt.run(endTime, duration, 'completed', notes || null, sessionId);
|
|
104
|
+
}
|
|
105
|
+
function getSession(sessionId) {
|
|
106
|
+
const stmt = db.prepare('SELECT * FROM sessions WHERE id = ?');
|
|
107
|
+
const row = stmt.get(sessionId);
|
|
108
|
+
return row ? mapSession(row) : null;
|
|
109
|
+
}
|
|
110
|
+
function getSessions(limit = 10) {
|
|
111
|
+
const stmt = db.prepare('SELECT * FROM sessions ORDER BY start_time DESC LIMIT ?');
|
|
112
|
+
const rows = stmt.all(limit);
|
|
113
|
+
return rows.map(mapSession);
|
|
114
|
+
}
|
|
115
|
+
function addFileChange(change) {
|
|
116
|
+
const stmt = db.prepare(`
|
|
117
|
+
INSERT INTO file_changes (session_id, file_path, change_type, timestamp)
|
|
118
|
+
VALUES (?, ?, ?, ?)
|
|
119
|
+
`);
|
|
120
|
+
stmt.run(change.sessionId, change.filePath, change.changeType, change.timestamp);
|
|
121
|
+
// Update session files count
|
|
122
|
+
const countStmt = db.prepare('SELECT COUNT(DISTINCT file_path) as count FROM file_changes WHERE session_id = ?');
|
|
123
|
+
const result = countStmt.get(change.sessionId);
|
|
124
|
+
const updateStmt = db.prepare('UPDATE sessions SET files_changed = ? WHERE id = ?');
|
|
125
|
+
updateStmt.run(result.count, change.sessionId);
|
|
126
|
+
}
|
|
127
|
+
function addCommit(commit) {
|
|
128
|
+
const stmt = db.prepare(`
|
|
129
|
+
INSERT INTO commits (session_id, hash, message, timestamp)
|
|
130
|
+
VALUES (?, ?, ?, ?)
|
|
131
|
+
`);
|
|
132
|
+
stmt.run(commit.sessionId, commit.hash, commit.message, commit.timestamp);
|
|
133
|
+
// Update session commits count
|
|
134
|
+
const countStmt = db.prepare('SELECT COUNT(*) as count FROM commits WHERE session_id = ?');
|
|
135
|
+
const result = countStmt.get(commit.sessionId);
|
|
136
|
+
const updateStmt = db.prepare('UPDATE sessions SET commits = ? WHERE id = ?');
|
|
137
|
+
updateStmt.run(result.count, commit.sessionId);
|
|
138
|
+
}
|
|
139
|
+
function addAIUsage(usage) {
|
|
140
|
+
const stmt = db.prepare(`
|
|
141
|
+
INSERT INTO ai_usage (session_id, provider, model, tokens, cost, timestamp)
|
|
142
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
143
|
+
`);
|
|
144
|
+
stmt.run(usage.sessionId, usage.provider, usage.model, usage.tokens, usage.cost, usage.timestamp);
|
|
145
|
+
// Update session AI totals
|
|
146
|
+
const sumStmt = db.prepare(`
|
|
147
|
+
SELECT SUM(cost) as total_cost, SUM(tokens) as total_tokens
|
|
148
|
+
FROM ai_usage WHERE session_id = ?
|
|
149
|
+
`);
|
|
150
|
+
const result = sumStmt.get(usage.sessionId);
|
|
151
|
+
const updateStmt = db.prepare('UPDATE sessions SET ai_cost = ?, ai_tokens = ? WHERE id = ?');
|
|
152
|
+
updateStmt.run(result.total_cost || 0, result.total_tokens || 0, usage.sessionId);
|
|
153
|
+
}
|
|
154
|
+
function getFileChanges(sessionId) {
|
|
155
|
+
const stmt = db.prepare('SELECT * FROM file_changes WHERE session_id = ? ORDER BY timestamp');
|
|
156
|
+
const rows = stmt.all(sessionId);
|
|
157
|
+
return rows.map((row) => ({
|
|
158
|
+
id: row.id,
|
|
159
|
+
sessionId: row.session_id,
|
|
160
|
+
filePath: row.file_path,
|
|
161
|
+
changeType: row.change_type,
|
|
162
|
+
timestamp: row.timestamp,
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
function getCommits(sessionId) {
|
|
166
|
+
const stmt = db.prepare('SELECT * FROM commits WHERE session_id = ? ORDER BY timestamp');
|
|
167
|
+
const rows = stmt.all(sessionId);
|
|
168
|
+
return rows.map((row) => ({
|
|
169
|
+
id: row.id,
|
|
170
|
+
sessionId: row.session_id,
|
|
171
|
+
hash: row.hash,
|
|
172
|
+
message: row.message,
|
|
173
|
+
timestamp: row.timestamp,
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
function getAIUsage(sessionId) {
|
|
177
|
+
const stmt = db.prepare('SELECT * FROM ai_usage WHERE session_id = ? ORDER BY timestamp');
|
|
178
|
+
const rows = stmt.all(sessionId);
|
|
179
|
+
return rows.map((row) => ({
|
|
180
|
+
id: row.id,
|
|
181
|
+
sessionId: row.session_id,
|
|
182
|
+
provider: row.provider,
|
|
183
|
+
model: row.model,
|
|
184
|
+
tokens: row.tokens,
|
|
185
|
+
cost: row.cost,
|
|
186
|
+
timestamp: row.timestamp,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
function getStats() {
|
|
190
|
+
const stmt = db.prepare(`
|
|
191
|
+
SELECT
|
|
192
|
+
COUNT(*) as total,
|
|
193
|
+
SUM(duration) as total_time,
|
|
194
|
+
SUM(files_changed) as total_files,
|
|
195
|
+
SUM(commits) as total_commits,
|
|
196
|
+
SUM(ai_cost) as total_cost,
|
|
197
|
+
AVG(duration) as avg_time
|
|
198
|
+
FROM sessions WHERE status = 'completed'
|
|
199
|
+
`);
|
|
200
|
+
const result = stmt.get();
|
|
201
|
+
return {
|
|
202
|
+
totalSessions: result.total || 0,
|
|
203
|
+
totalTime: result.total_time || 0,
|
|
204
|
+
totalFiles: result.total_files || 0,
|
|
205
|
+
totalCommits: result.total_commits || 0,
|
|
206
|
+
totalAICost: result.total_cost || 0,
|
|
207
|
+
avgSessionTime: result.avg_time || 0,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function mapSession(row) {
|
|
211
|
+
return {
|
|
212
|
+
id: row.id,
|
|
213
|
+
name: row.name,
|
|
214
|
+
startTime: row.start_time,
|
|
215
|
+
endTime: row.end_time,
|
|
216
|
+
duration: row.duration,
|
|
217
|
+
workingDirectory: row.working_directory,
|
|
218
|
+
filesChanged: row.files_changed,
|
|
219
|
+
commits: row.commits,
|
|
220
|
+
aiCost: row.ai_cost,
|
|
221
|
+
aiTokens: row.ai_tokens,
|
|
222
|
+
notes: row.notes,
|
|
223
|
+
status: row.status,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function closeDb() {
|
|
227
|
+
db.close();
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":";;;;;AAoEA,sCAOC;AAED,4CAKC;AAED,gCAYC;AAED,gCAIC;AAED,kCAIC;AAED,sCAaC;AAED,8BAaC;AAED,gCAgBC;AAED,wCAUC;AAED,gCAUC;AAED,gCAYC;AAED,4BAqBC;AAmBD,0BAEC;AA9OD,oEAAsC;AACtC,+BAA4B;AAC5B,2BAA6B;AAC7B,2BAA2C;AAG3C,MAAM,MAAM,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,aAAa,CAAC,CAAC;AAC9C,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE5C,IAAI,CAAC,IAAA,eAAU,EAAC,MAAM,CAAC,EAAE,CAAC;IACxB,IAAA,cAAS,EAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,OAAO,CAAC,CAAC;AAEjC,sBAAsB;AACtB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;CAeP,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC;;;;;;;;;CASP,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC;;;;;;;;;CASP,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;CAWP,CAAC,CAAC;AAEH,SAAgB,aAAa,CAAC,OAA4B;IACxD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGvB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC,eAAyB,CAAC;AAC1C,CAAC;AAED,SAAgB,gBAAgB;IAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC;IAC5F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAQ,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,UAAU,CAAC,SAAiB,EAAE,OAAe,EAAE,KAAc;IAC3E,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAE1G,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;GAIvB,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,IAAI,EAAE,SAAS,CAAC,CAAC;AACrE,CAAC;AAED,SAAgB,UAAU,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAQ,CAAC;IACvC,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC;AAED,SAAgB,WAAW,CAAC,KAAK,GAAG,EAAE;IACpC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAU,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED,SAAgB,aAAa,CAAC,MAA8B;IAC1D,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGvB,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAEjF,6BAA6B;IAC7B,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,kFAAkF,CAAC,CAAC;IACjH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAQ,CAAC;IAEtD,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC;IACpF,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,SAAgB,SAAS,CAAC,MAA0B;IAClD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGvB,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAE1E,+BAA+B;IAC/B,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,4DAA4D,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAQ,CAAC;IAEtD,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;IAC9E,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,SAAgB,UAAU,CAAC,KAA0B;IACnD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGvB,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAElG,2BAA2B;IAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAG1B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAQ,CAAC;IAEnD,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,6DAA6D,CAAC,CAAC;IAC7F,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;AACpF,CAAC;AAED,SAAgB,cAAc,CAAC,SAAiB;IAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,oEAAoE,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAU,CAAC;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,UAAU,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,+DAA+D,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAU,CAAC;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,UAAU,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAU,CAAC;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,QAAQ;IACtB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;GASvB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAS,CAAC;IAEjC,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;QAChC,SAAS,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC;QACjC,UAAU,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC;QACnC,YAAY,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC;QACvC,WAAW,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,GAAQ;IAC1B,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,gBAAgB,EAAE,GAAG,CAAC,iBAAiB;QACvC,YAAY,EAAE,GAAG,CAAC,aAAa;QAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB,CAAC;AACJ,CAAC;AAED,SAAgB,OAAO;IACrB,EAAE,CAAC,KAAK,EAAE,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Session, SessionStats, FileChange, Commit } from './types';
|
|
2
|
+
export declare function formatDuration(seconds: number): string;
|
|
3
|
+
export declare function formatCost(cost: number): string;
|
|
4
|
+
export declare function displaySession(session: Session): void;
|
|
5
|
+
export declare function displaySessions(sessions: Session[]): void;
|
|
6
|
+
export declare function displayStats(stats: SessionStats): void;
|
|
7
|
+
export declare function displayFileChanges(changes: FileChange[]): void;
|
|
8
|
+
export declare function displayCommits(commits: Commit[]): void;
|
|
9
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGpE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiCrD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAgCzD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAkBtD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAsB9D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAmBtD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.formatDuration = formatDuration;
|
|
7
|
+
exports.formatCost = formatCost;
|
|
8
|
+
exports.displaySession = displaySession;
|
|
9
|
+
exports.displaySessions = displaySessions;
|
|
10
|
+
exports.displayStats = displayStats;
|
|
11
|
+
exports.displayFileChanges = displayFileChanges;
|
|
12
|
+
exports.displayCommits = displayCommits;
|
|
13
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
15
|
+
const date_fns_1 = require("date-fns");
|
|
16
|
+
function formatDuration(seconds) {
|
|
17
|
+
const hours = Math.floor(seconds / 3600);
|
|
18
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
19
|
+
if (hours > 0) {
|
|
20
|
+
return `${hours}h ${minutes}m`;
|
|
21
|
+
}
|
|
22
|
+
return `${minutes}m`;
|
|
23
|
+
}
|
|
24
|
+
function formatCost(cost) {
|
|
25
|
+
return `$${cost.toFixed(2)}`;
|
|
26
|
+
}
|
|
27
|
+
function displaySession(session) {
|
|
28
|
+
console.log(chalk_1.default.bold.cyan(`\nSession: ${session.name}\n`));
|
|
29
|
+
const table = new cli_table3_1.default({
|
|
30
|
+
head: [chalk_1.default.cyan.bold('Metric'), chalk_1.default.cyan.bold('Value')],
|
|
31
|
+
style: { head: [], border: [] },
|
|
32
|
+
});
|
|
33
|
+
table.push(['Status', session.status === 'active' ? chalk_1.default.green('Active') : chalk_1.default.gray('Completed')], ['Started', (0, date_fns_1.format)(new Date(session.startTime), 'MMM dd, yyyy HH:mm')]);
|
|
34
|
+
if (session.endTime) {
|
|
35
|
+
table.push(['Ended', (0, date_fns_1.format)(new Date(session.endTime), 'MMM dd, yyyy HH:mm')]);
|
|
36
|
+
}
|
|
37
|
+
if (session.duration) {
|
|
38
|
+
table.push(['Duration', chalk_1.default.white(formatDuration(session.duration))]);
|
|
39
|
+
}
|
|
40
|
+
table.push(['Files Changed', chalk_1.default.white(session.filesChanged.toString())], ['Commits', chalk_1.default.white(session.commits.toString())], ['AI Tokens', chalk_1.default.white(session.aiTokens.toLocaleString())], ['AI Cost', chalk_1.default.yellow(formatCost(session.aiCost))]);
|
|
41
|
+
if (session.notes) {
|
|
42
|
+
table.push(['Notes', chalk_1.default.gray(session.notes)]);
|
|
43
|
+
}
|
|
44
|
+
console.log(table.toString());
|
|
45
|
+
}
|
|
46
|
+
function displaySessions(sessions) {
|
|
47
|
+
if (sessions.length === 0) {
|
|
48
|
+
console.log(chalk_1.default.yellow('\nNo sessions found.\n'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const table = new cli_table3_1.default({
|
|
52
|
+
head: [
|
|
53
|
+
chalk_1.default.cyan.bold('ID'),
|
|
54
|
+
chalk_1.default.cyan.bold('Name'),
|
|
55
|
+
chalk_1.default.cyan.bold('Started'),
|
|
56
|
+
chalk_1.default.cyan.bold('Duration'),
|
|
57
|
+
chalk_1.default.cyan.bold('Files'),
|
|
58
|
+
chalk_1.default.cyan.bold('Commits'),
|
|
59
|
+
chalk_1.default.cyan.bold('AI Cost'),
|
|
60
|
+
],
|
|
61
|
+
style: { head: [], border: [] },
|
|
62
|
+
});
|
|
63
|
+
for (const session of sessions) {
|
|
64
|
+
table.push([
|
|
65
|
+
chalk_1.default.gray(`#${session.id}`),
|
|
66
|
+
session.status === 'active' ? chalk_1.default.green(session.name) : chalk_1.default.white(session.name),
|
|
67
|
+
(0, date_fns_1.formatDistanceToNow)(new Date(session.startTime), { addSuffix: true }),
|
|
68
|
+
session.duration ? formatDuration(session.duration) : chalk_1.default.gray('ongoing'),
|
|
69
|
+
session.filesChanged.toString(),
|
|
70
|
+
session.commits.toString(),
|
|
71
|
+
chalk_1.default.yellow(formatCost(session.aiCost)),
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
74
|
+
console.log('\n' + table.toString() + '\n');
|
|
75
|
+
}
|
|
76
|
+
function displayStats(stats) {
|
|
77
|
+
console.log(chalk_1.default.bold.cyan('\nOverall Stats\n'));
|
|
78
|
+
const table = new cli_table3_1.default({
|
|
79
|
+
head: [chalk_1.default.cyan.bold('Metric'), chalk_1.default.cyan.bold('Value')],
|
|
80
|
+
style: { head: [], border: [] },
|
|
81
|
+
});
|
|
82
|
+
table.push(['Total Sessions', chalk_1.default.white(stats.totalSessions.toLocaleString())], ['Total Time', chalk_1.default.white(formatDuration(stats.totalTime))], ['Average Session', chalk_1.default.white(formatDuration(stats.avgSessionTime))], ['Files Changed', chalk_1.default.white(stats.totalFiles.toLocaleString())], ['Commits', chalk_1.default.white(stats.totalCommits.toLocaleString())], ['Total AI Cost', chalk_1.default.yellow(formatCost(stats.totalAICost))]);
|
|
83
|
+
console.log(table.toString() + '\n');
|
|
84
|
+
}
|
|
85
|
+
function displayFileChanges(changes) {
|
|
86
|
+
if (changes.length === 0)
|
|
87
|
+
return;
|
|
88
|
+
console.log(chalk_1.default.bold.cyan('\nFile Changes\n'));
|
|
89
|
+
const table = new cli_table3_1.default({
|
|
90
|
+
head: [chalk_1.default.cyan.bold('Type'), chalk_1.default.cyan.bold('File'), chalk_1.default.cyan.bold('Time')],
|
|
91
|
+
style: { head: [], border: [] },
|
|
92
|
+
});
|
|
93
|
+
for (const change of changes) {
|
|
94
|
+
const typeColor = change.changeType === 'created' ? chalk_1.default.green :
|
|
95
|
+
change.changeType === 'modified' ? chalk_1.default.yellow : chalk_1.default.red;
|
|
96
|
+
table.push([
|
|
97
|
+
typeColor(change.changeType),
|
|
98
|
+
change.filePath,
|
|
99
|
+
(0, date_fns_1.formatDistanceToNow)(new Date(change.timestamp), { addSuffix: true }),
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
console.log(table.toString() + '\n');
|
|
103
|
+
}
|
|
104
|
+
function displayCommits(commits) {
|
|
105
|
+
if (commits.length === 0)
|
|
106
|
+
return;
|
|
107
|
+
console.log(chalk_1.default.bold.cyan('\nCommits\n'));
|
|
108
|
+
const table = new cli_table3_1.default({
|
|
109
|
+
head: [chalk_1.default.cyan.bold('Hash'), chalk_1.default.cyan.bold('Message'), chalk_1.default.cyan.bold('Time')],
|
|
110
|
+
style: { head: [], border: [] },
|
|
111
|
+
});
|
|
112
|
+
for (const commit of commits) {
|
|
113
|
+
table.push([
|
|
114
|
+
chalk_1.default.gray(commit.hash),
|
|
115
|
+
commit.message,
|
|
116
|
+
(0, date_fns_1.formatDistanceToNow)(new Date(commit.timestamp), { addSuffix: true }),
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
119
|
+
console.log(table.toString() + '\n');
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function initGit(cwd: string): void;
|
|
2
|
+
export declare function checkForNewCommits(sessionId: number): Promise<void>;
|
|
3
|
+
export declare function getGitInfo(): Promise<{
|
|
4
|
+
branch: string;
|
|
5
|
+
hasChanges: boolean;
|
|
6
|
+
} | null>;
|
|
7
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAMA,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzE;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CAa1F"}
|