copilot-lens 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 +55 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +66 -0
- package/dist/cli.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +61 -0
- package/dist/server.js.map +1 -0
- package/dist/sessions.d.ts +40 -0
- package/dist/sessions.js +246 -0
- package/dist/sessions.js.map +1 -0
- package/package.json +35 -0
- package/public/app.js +398 -0
- package/public/index.html +79 -0
- package/public/style.css +364 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pavanvamsi3
|
|
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,55 @@
|
|
|
1
|
+
# Copilot Lens 👓
|
|
2
|
+
|
|
3
|
+
A local dashboard to visualize and analyze your GitHub Copilot CLI sessions.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g copilot-lens
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Start the dashboard
|
|
15
|
+
copilot-lens
|
|
16
|
+
|
|
17
|
+
# With options
|
|
18
|
+
copilot-lens --port 8080 --open
|
|
19
|
+
|
|
20
|
+
# Or use npx (no install needed)
|
|
21
|
+
npx copilot-lens
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Options
|
|
25
|
+
|
|
26
|
+
| Flag | Default | Description |
|
|
27
|
+
|------|---------|-------------|
|
|
28
|
+
| `--port` | `3000` | Port number |
|
|
29
|
+
| `--host` | `localhost` | Host address |
|
|
30
|
+
| `--open` | off | Auto-open browser |
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- **Session list** — Browse all your Copilot CLI sessions with search and filtering
|
|
35
|
+
- **Session details** — View full conversation history, tool calls, errors, and plans
|
|
36
|
+
- **Analytics dashboard** — Charts showing session activity, tool usage, top directories, and branch activity
|
|
37
|
+
- **Auto-refresh** — Dashboard updates every 5 seconds
|
|
38
|
+
- **Local only** — All data stays on your machine
|
|
39
|
+
|
|
40
|
+
## Data Source
|
|
41
|
+
|
|
42
|
+
Reads session data from `~/.copilot/session-state/` (the default GitHub Copilot CLI session directory).
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
MIT
|
|
47
|
+
|
|
48
|
+
## Optional: Custom Local Hostname
|
|
49
|
+
|
|
50
|
+
If you'd like a prettier URL like `http://copilot.lens:3000`, add this to your hosts file:
|
|
51
|
+
|
|
52
|
+
- **Windows** (run as Admin): `echo 127.0.0.1 copilot.lens >> C:\Windows\System32\drivers\etc\hosts`
|
|
53
|
+
- **macOS/Linux**: `echo "127.0.0.1 copilot.lens" | sudo tee -a /etc/hosts`
|
|
54
|
+
|
|
55
|
+
Then run: `copilot-lens --host copilot.lens`
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const server_1 = require("./server");
|
|
38
|
+
process.on("uncaughtException", (err) => {
|
|
39
|
+
console.error("Uncaught error:", err.message);
|
|
40
|
+
});
|
|
41
|
+
process.on("unhandledRejection", (err) => {
|
|
42
|
+
console.error("Unhandled rejection:", err?.message || err);
|
|
43
|
+
});
|
|
44
|
+
const args = process.argv.slice(2);
|
|
45
|
+
function getArg(name, fallback) {
|
|
46
|
+
const idx = args.indexOf(name);
|
|
47
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : fallback;
|
|
48
|
+
}
|
|
49
|
+
const port = parseInt(getArg("--port", "3000"), 10);
|
|
50
|
+
const host = getArg("--host", "localhost");
|
|
51
|
+
const shouldOpen = args.includes("--open");
|
|
52
|
+
const app = (0, server_1.createApp)();
|
|
53
|
+
app.listen(port, host, async () => {
|
|
54
|
+
const url = `http://${host}:${port}`;
|
|
55
|
+
console.log(`\n 👓 Copilot Lens is running at ${url}\n`);
|
|
56
|
+
if (shouldOpen) {
|
|
57
|
+
const { exec } = await Promise.resolve().then(() => __importStar(require("child_process")));
|
|
58
|
+
const cmd = process.platform === "win32"
|
|
59
|
+
? `start "" "${url}"`
|
|
60
|
+
: process.platform === "darwin"
|
|
61
|
+
? `open ${url}`
|
|
62
|
+
: `xdg-open ${url}`;
|
|
63
|
+
exec(cmd);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,qCAAqC;AAErC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,GAAQ,EAAE,EAAE;IAC5C,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,MAAM,CAAC,IAAY,EAAE,QAAgB;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChE,CAAC;AAED,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;AACpD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAE3C,MAAM,GAAG,GAAG,IAAA,kBAAS,GAAE,CAAC;AAExB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;IAChC,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,qCAAqC,GAAG,IAAI,CAAC,CAAC;IAE1D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,EAAE,IAAI,EAAE,GAAG,wDAAa,eAAe,GAAC,CAAC;QAC/C,MAAM,GAAG,GACP,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC1B,CAAC,CAAC,aAAa,GAAG,GAAG;YACrB,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;gBAC7B,CAAC,CAAC,QAAQ,GAAG,EAAE;gBACf,CAAC,CAAC,YAAY,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createApp(): import("express-serve-static-core").Express;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
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.createApp = createApp;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const cors_1 = __importDefault(require("cors"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const sessions_1 = require("./sessions");
|
|
11
|
+
function createApp() {
|
|
12
|
+
const app = (0, express_1.default)();
|
|
13
|
+
app.use((0, cors_1.default)());
|
|
14
|
+
// Serve static frontend files
|
|
15
|
+
app.use(express_1.default.static(path_1.default.join(__dirname, "..", "public")));
|
|
16
|
+
// API: List all sessions
|
|
17
|
+
app.get("/api/sessions", (_req, res) => {
|
|
18
|
+
try {
|
|
19
|
+
const sessions = (0, sessions_1.listSessions)();
|
|
20
|
+
res.json(sessions);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
res.status(500).json({ error: err.message });
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// API: Get session detail
|
|
27
|
+
app.get("/api/sessions/:id", (req, res) => {
|
|
28
|
+
try {
|
|
29
|
+
const session = (0, sessions_1.getSession)(req.params.id);
|
|
30
|
+
if (!session) {
|
|
31
|
+
res.status(404).json({ error: "Session not found" });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
res.json(session);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
res.status(500).json({ error: err.message });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// API: Analytics
|
|
41
|
+
app.get("/api/analytics", (_req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
const analytics = (0, sessions_1.getAnalytics)();
|
|
44
|
+
res.json(analytics);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
res.status(500).json({ error: err.message });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
// SPA fallback — only for non-API routes
|
|
51
|
+
app.use((_req, res) => {
|
|
52
|
+
res.sendFile(path_1.default.join(__dirname, "..", "public", "index.html"));
|
|
53
|
+
});
|
|
54
|
+
// Global error handler
|
|
55
|
+
app.use((err, _req, res, _next) => {
|
|
56
|
+
console.error("Server error:", err.message);
|
|
57
|
+
res.status(500).json({ error: err.message });
|
|
58
|
+
});
|
|
59
|
+
return app;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;AAKA,8BAqDC;AA1DD,sDAA8B;AAC9B,gDAAwB;AACxB,gDAAwB;AACxB,yCAAoE;AAEpE,SAAgB,SAAS;IACvB,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;IAEhB,8BAA8B;IAC9B,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9D,yBAAyB;IACzB,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAA,uBAAY,GAAE,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAA,qBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,iBAAiB;IACjB,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAA,uBAAY,GAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,yCAAyC;IACzC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpB,GAAG,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,uBAAuB;IACvB,GAAG,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,IAAS,EAAE,GAAQ,EAAE,KAAU,EAAE,EAAE;QACpD,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type SessionStatus = "running" | "completed" | "error";
|
|
2
|
+
export interface SessionMeta {
|
|
3
|
+
id: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
gitRoot?: string;
|
|
6
|
+
branch?: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
updatedAt: string;
|
|
9
|
+
summaryCount?: number;
|
|
10
|
+
status: SessionStatus;
|
|
11
|
+
}
|
|
12
|
+
export interface SessionEvent {
|
|
13
|
+
type: string;
|
|
14
|
+
id: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
data: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
export interface SessionDetail extends SessionMeta {
|
|
19
|
+
events: SessionEvent[];
|
|
20
|
+
planContent?: string;
|
|
21
|
+
hasSnapshots: boolean;
|
|
22
|
+
copilotVersion?: string;
|
|
23
|
+
eventCounts: Record<string, number>;
|
|
24
|
+
duration: number;
|
|
25
|
+
status: SessionStatus;
|
|
26
|
+
}
|
|
27
|
+
export interface AnalyticsData {
|
|
28
|
+
totalSessions: number;
|
|
29
|
+
sessionsPerDay: Record<string, number>;
|
|
30
|
+
avgDuration: number;
|
|
31
|
+
minDuration: number;
|
|
32
|
+
maxDuration: number;
|
|
33
|
+
totalDuration: number;
|
|
34
|
+
toolUsage: Record<string, number>;
|
|
35
|
+
topDirectories: Record<string, number>;
|
|
36
|
+
branchActivity: Record<string, number>;
|
|
37
|
+
}
|
|
38
|
+
export declare function listSessions(): SessionMeta[];
|
|
39
|
+
export declare function getSession(sessionId: string): SessionDetail | null;
|
|
40
|
+
export declare function getAnalytics(): AnalyticsData;
|
package/dist/sessions.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.listSessions = listSessions;
|
|
37
|
+
exports.getSession = getSession;
|
|
38
|
+
exports.getAnalytics = getAnalytics;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const yaml_1 = require("yaml");
|
|
43
|
+
function getSessionDir() {
|
|
44
|
+
return path.join(os.homedir(), ".copilot", "session-state");
|
|
45
|
+
}
|
|
46
|
+
function detectStatus(sessionDir, _updatedAt) {
|
|
47
|
+
try {
|
|
48
|
+
// session.db only exists for actively running sessions — strongest signal
|
|
49
|
+
if (fs.existsSync(path.join(sessionDir, "session.db")))
|
|
50
|
+
return "running";
|
|
51
|
+
const eventsPath = path.join(sessionDir, "events.jsonl");
|
|
52
|
+
if (!fs.existsSync(eventsPath))
|
|
53
|
+
return "completed";
|
|
54
|
+
// Only read the last 2KB to check for abort events (avoid reading huge files)
|
|
55
|
+
const stat = fs.statSync(eventsPath);
|
|
56
|
+
const readSize = Math.min(stat.size, 2048);
|
|
57
|
+
const buf = Buffer.alloc(readSize);
|
|
58
|
+
const fd = fs.openSync(eventsPath, "r");
|
|
59
|
+
fs.readSync(fd, buf, 0, readSize, Math.max(0, stat.size - readSize));
|
|
60
|
+
fs.closeSync(fd);
|
|
61
|
+
const tail = buf.toString("utf-8");
|
|
62
|
+
const lines = tail.trimEnd().split("\n").filter(Boolean);
|
|
63
|
+
// Check last few lines for abort signals
|
|
64
|
+
for (const line of lines.slice(-5)) {
|
|
65
|
+
try {
|
|
66
|
+
const event = JSON.parse(line);
|
|
67
|
+
if (event.type === "abort") {
|
|
68
|
+
return event.data?.reason === "user initiated" ? "completed" : "error";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
}
|
|
73
|
+
// No abort — check if recently modified
|
|
74
|
+
const age = Date.now() - stat.mtimeMs;
|
|
75
|
+
if (age < 300000)
|
|
76
|
+
return "running";
|
|
77
|
+
}
|
|
78
|
+
catch { }
|
|
79
|
+
return "completed";
|
|
80
|
+
}
|
|
81
|
+
function listSessions() {
|
|
82
|
+
const dir = getSessionDir();
|
|
83
|
+
if (!fs.existsSync(dir))
|
|
84
|
+
return [];
|
|
85
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
86
|
+
const sessions = [];
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (!entry.isDirectory())
|
|
89
|
+
continue;
|
|
90
|
+
const wsPath = path.join(dir, entry.name, "workspace.yaml");
|
|
91
|
+
if (!fs.existsSync(wsPath))
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
const raw = fs.readFileSync(wsPath, "utf-8");
|
|
95
|
+
const ws = (0, yaml_1.parse)(raw);
|
|
96
|
+
const sessionPath = path.join(dir, entry.name);
|
|
97
|
+
const updatedAt = ws.updated_at || "";
|
|
98
|
+
sessions.push({
|
|
99
|
+
id: ws.id || entry.name,
|
|
100
|
+
cwd: ws.cwd || "",
|
|
101
|
+
gitRoot: ws.git_root,
|
|
102
|
+
branch: ws.branch,
|
|
103
|
+
createdAt: ws.created_at || "",
|
|
104
|
+
updatedAt,
|
|
105
|
+
summaryCount: ws.summary_count,
|
|
106
|
+
status: detectStatus(sessionPath, updatedAt),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// skip corrupted files
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
sessions.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
114
|
+
return sessions;
|
|
115
|
+
}
|
|
116
|
+
function getSession(sessionId) {
|
|
117
|
+
const dir = path.join(getSessionDir(), sessionId);
|
|
118
|
+
if (!fs.existsSync(dir))
|
|
119
|
+
return null;
|
|
120
|
+
// Parse workspace.yaml
|
|
121
|
+
const wsPath = path.join(dir, "workspace.yaml");
|
|
122
|
+
if (!fs.existsSync(wsPath))
|
|
123
|
+
return null;
|
|
124
|
+
let ws;
|
|
125
|
+
try {
|
|
126
|
+
ws = (0, yaml_1.parse)(fs.readFileSync(wsPath, "utf-8"));
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
// Parse events.jsonl
|
|
132
|
+
const events = [];
|
|
133
|
+
const eventsPath = path.join(dir, "events.jsonl");
|
|
134
|
+
try {
|
|
135
|
+
if (fs.existsSync(eventsPath)) {
|
|
136
|
+
const lines = fs.readFileSync(eventsPath, "utf-8").split("\n");
|
|
137
|
+
for (const line of lines) {
|
|
138
|
+
if (!line.trim())
|
|
139
|
+
continue;
|
|
140
|
+
try {
|
|
141
|
+
events.push(JSON.parse(line));
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// skip malformed lines
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// file may be locked by active session
|
|
151
|
+
}
|
|
152
|
+
// Read plan.md
|
|
153
|
+
let planContent;
|
|
154
|
+
const planPath = path.join(dir, "plan.md");
|
|
155
|
+
if (fs.existsSync(planPath)) {
|
|
156
|
+
planContent = fs.readFileSync(planPath, "utf-8");
|
|
157
|
+
}
|
|
158
|
+
// Check snapshots
|
|
159
|
+
const hasSnapshots = fs.existsSync(path.join(dir, "rewind-snapshots", "index.json"));
|
|
160
|
+
// Extract copilot version from session.start event
|
|
161
|
+
const startEvent = events.find((e) => e.type === "session.start");
|
|
162
|
+
const copilotVersion = startEvent?.data?.copilotVersion;
|
|
163
|
+
// Count events by type
|
|
164
|
+
const eventCounts = {};
|
|
165
|
+
for (const e of events) {
|
|
166
|
+
eventCounts[e.type] = (eventCounts[e.type] || 0) + 1;
|
|
167
|
+
}
|
|
168
|
+
// Calculate duration
|
|
169
|
+
const created = new Date(ws.created_at).getTime();
|
|
170
|
+
const updated = new Date(ws.updated_at).getTime();
|
|
171
|
+
const duration = updated - created;
|
|
172
|
+
return {
|
|
173
|
+
id: ws.id || sessionId,
|
|
174
|
+
cwd: ws.cwd || "",
|
|
175
|
+
gitRoot: ws.git_root,
|
|
176
|
+
branch: ws.branch,
|
|
177
|
+
createdAt: ws.created_at || "",
|
|
178
|
+
updatedAt: ws.updated_at || "",
|
|
179
|
+
summaryCount: ws.summary_count,
|
|
180
|
+
events,
|
|
181
|
+
planContent,
|
|
182
|
+
hasSnapshots,
|
|
183
|
+
copilotVersion,
|
|
184
|
+
eventCounts,
|
|
185
|
+
duration,
|
|
186
|
+
status: detectStatus(dir, ws.updated_at || ""),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function getAnalytics() {
|
|
190
|
+
const sessions = listSessions();
|
|
191
|
+
const sessionsPerDay = {};
|
|
192
|
+
const toolUsage = {};
|
|
193
|
+
const topDirectories = {};
|
|
194
|
+
const branchActivity = {};
|
|
195
|
+
const durations = [];
|
|
196
|
+
const sessionDir = getSessionDir();
|
|
197
|
+
for (const s of sessions) {
|
|
198
|
+
// Sessions per day
|
|
199
|
+
const day = s.createdAt.slice(0, 10);
|
|
200
|
+
if (day)
|
|
201
|
+
sessionsPerDay[day] = (sessionsPerDay[day] || 0) + 1;
|
|
202
|
+
// Duration
|
|
203
|
+
const dur = new Date(s.updatedAt).getTime() - new Date(s.createdAt).getTime();
|
|
204
|
+
if (dur > 0)
|
|
205
|
+
durations.push(dur);
|
|
206
|
+
// Top directories
|
|
207
|
+
const dirName = s.cwd || "unknown";
|
|
208
|
+
topDirectories[dirName] = (topDirectories[dirName] || 0) + 1;
|
|
209
|
+
// Branch activity
|
|
210
|
+
const branch = s.branch || "unknown";
|
|
211
|
+
branchActivity[branch] = (branchActivity[branch] || 0) + 1;
|
|
212
|
+
// Tool usage — scan events.jsonl line by line without loading full detail
|
|
213
|
+
try {
|
|
214
|
+
const eventsPath = path.join(sessionDir, s.id, "events.jsonl");
|
|
215
|
+
if (fs.existsSync(eventsPath)) {
|
|
216
|
+
const content = fs.readFileSync(eventsPath, "utf-8");
|
|
217
|
+
for (const line of content.split("\n")) {
|
|
218
|
+
if (!line.includes("tool.execution_start"))
|
|
219
|
+
continue;
|
|
220
|
+
try {
|
|
221
|
+
const event = JSON.parse(line);
|
|
222
|
+
if (event.type === "tool.execution_start") {
|
|
223
|
+
const tool = event.data?.tool || event.data?.toolName || "unknown";
|
|
224
|
+
toolUsage[tool] = (toolUsage[tool] || 0) + 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch { }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch { }
|
|
232
|
+
}
|
|
233
|
+
const totalDuration = durations.reduce((a, b) => a + b, 0);
|
|
234
|
+
return {
|
|
235
|
+
totalSessions: sessions.length,
|
|
236
|
+
sessionsPerDay,
|
|
237
|
+
avgDuration: durations.length ? totalDuration / durations.length : 0,
|
|
238
|
+
minDuration: durations.length ? Math.min(...durations) : 0,
|
|
239
|
+
maxDuration: durations.length ? Math.max(...durations) : 0,
|
|
240
|
+
totalDuration,
|
|
241
|
+
toolUsage,
|
|
242
|
+
topDirectories,
|
|
243
|
+
branchActivity,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "copilot-lens",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A local dashboard to visualize and analyze your GitHub Copilot CLI sessions",
|
|
5
|
+
"main": "dist/server.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"copilot-lens": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsx src/cli.ts",
|
|
12
|
+
"start": "node dist/cli.js",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": ["copilot", "github", "cli", "dashboard", "sessions", "analytics"],
|
|
16
|
+
"author": "pavanvamsi3",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/pavanvamsi3/copilot-lens"
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist/", "public/", "README.md"],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"cors": "^2.8.6",
|
|
25
|
+
"express": "^5.2.1",
|
|
26
|
+
"yaml": "^2.8.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/cors": "^2.8.19",
|
|
30
|
+
"@types/express": "^5.0.6",
|
|
31
|
+
"@types/node": "^25.2.2",
|
|
32
|
+
"tsx": "^4.21.0",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
}
|
|
35
|
+
}
|