session-intelligence-cli 0.1.2 → 0.1.4

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/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Session Intelligence CLI
2
+
3
+ A [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin that gives you a real-time dashboard for all your coding sessions.
4
+
5
+ See what every session is doing, track token usage and git changes, and get a full activity history across all your projects.
6
+
7
+ **[session-intelligence.com](https://www.session-intelligence.com)**
8
+
9
+ ## What it does
10
+
11
+ - **Live session tracking** — see every session as it thinks, runs tools, or waits for input
12
+ - **Activity heatmap & stats** — tokens, lines changed, model usage, and streaks over time
13
+ - **GitHub integration** — auto-links sessions to PRs, tracks open issues and review requests
14
+ - **Multi-project** — one dashboard for all your repos and branches
15
+
16
+ ## Quick start
17
+
18
+ ```bash
19
+ npx session-intelligence-cli setup
20
+ ```
21
+
22
+ This will:
23
+
24
+ 1. Ask for your **server URL** and **API key** (get one at [session-intelligence.com](https://www.session-intelligence.com))
25
+ 2. Save config to `~/.session-intelligence/config.json`
26
+ 3. Register hooks in `~/.claude/settings.json`
27
+
28
+ Your next Claude Code session will start reporting automatically.
29
+
30
+ ## How it works
31
+
32
+ The CLI registers lightweight [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) that fire on session lifecycle events:
33
+
34
+ | Event | What it reports |
35
+ |---|---|
36
+ | `SessionStart` | New session created |
37
+ | `PostToolUse` | Tool activity (Read, Edit, Bash, etc.) |
38
+ | `Notification` | Permission requests / input needed |
39
+ | `SubagentStop` | Subagent task completion |
40
+ | `Stop` | Task turn completed |
41
+ | `SessionEnd` | Session archived with token usage summary |
42
+
43
+ Each hook reads the current git state (branch, last commit, uncommitted changes) and sends a small payload to your dashboard. All calls are fire-and-forget with no impact on Claude Code performance.
44
+
45
+ ## Updating
46
+
47
+ If you installed a previous version, re-run setup to register any new hooks:
48
+
49
+ ```bash
50
+ npx session-intelligence-cli@latest setup
51
+ ```
52
+
53
+ ## Commands
54
+
55
+ ```bash
56
+ session-intelligence setup # configure and install hooks
57
+ session-intelligence status # check connection and config
58
+ ```
59
+
60
+ ## Requirements
61
+
62
+ - Node.js >= 18
63
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed
64
+
65
+ ## License
66
+
67
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { readGitState, readGitDiffStats } from "./git.js";
4
+ import { sendEvent } from "./api.js";
5
+ // Called as: node report-bg.js <json-payload>
6
+ // Runs detached from the parent process to avoid being killed on session teardown.
7
+ const raw = process.argv[2];
8
+ if (!raw)
9
+ process.exit(0);
10
+ const stdinData = JSON.parse(raw);
11
+ const sessionId = stdinData.session_id ?? "";
12
+ const cwd = stdinData.cwd ?? process.cwd();
13
+ const payload = {
14
+ session_id: sessionId,
15
+ cwd,
16
+ hook_event_name: "SessionEnd",
17
+ model: stdinData.model,
18
+ };
19
+ const transcriptPath = stdinData.transcript_path;
20
+ if (transcriptPath) {
21
+ try {
22
+ const content = readFileSync(transcriptPath, "utf-8");
23
+ const usage = { input_tokens: 0, output_tokens: 0, cache_read_tokens: 0, cache_creation_tokens: 0 };
24
+ for (const line of content.split("\n")) {
25
+ const trimmed = line.trim();
26
+ if (!trimmed)
27
+ continue;
28
+ try {
29
+ const entry = JSON.parse(trimmed);
30
+ if (entry.type !== "assistant" || !entry.message?.usage)
31
+ continue;
32
+ const u = entry.message.usage;
33
+ usage.input_tokens += u.input_tokens ?? 0;
34
+ usage.output_tokens += u.output_tokens ?? 0;
35
+ usage.cache_read_tokens += u.cache_read_input_tokens ?? 0;
36
+ usage.cache_creation_tokens += u.cache_creation_input_tokens ?? 0;
37
+ }
38
+ catch {
39
+ // skip malformed lines
40
+ }
41
+ }
42
+ payload.usage = usage;
43
+ }
44
+ catch {
45
+ // transcript unreadable
46
+ }
47
+ }
48
+ const git = readGitState(cwd);
49
+ if (git) {
50
+ const stats = readGitDiffStats(cwd);
51
+ payload.git = {
52
+ branch: git.branch,
53
+ lastCommitSha: git.lastCommitSha,
54
+ lastCommitMessage: git.lastCommitMessage,
55
+ hasUncommittedChanges: git.hasUncommittedChanges,
56
+ filesChanged: stats.filesChanged,
57
+ insertions: stats.insertions,
58
+ deletions: stats.deletions,
59
+ };
60
+ }
61
+ await sendEvent(payload);
package/dist/report.js CHANGED
@@ -1,4 +1,6 @@
1
- import { readFileSync } from "node:fs";
1
+ import { spawn } from "node:child_process";
2
+ import { fileURLToPath } from "node:url";
3
+ import { dirname, join } from "node:path";
2
4
  import { readGitState, readGitDiffStats } from "./git.js";
3
5
  import { sendEvent } from "./api.js";
4
6
  const EVENT_MAP = {
@@ -9,47 +11,35 @@ const EVENT_MAP = {
9
11
  "notification": "Notification",
10
12
  "subagent-stop": "SubagentStop",
11
13
  };
12
- function parseTranscriptTokens(transcriptPath) {
13
- const zero = { input_tokens: 0, output_tokens: 0, cache_read_tokens: 0, cache_creation_tokens: 0 };
14
- try {
15
- const content = readFileSync(transcriptPath, "utf-8");
16
- for (const line of content.split("\n")) {
17
- const trimmed = line.trim();
18
- if (!trimmed)
19
- continue;
14
+ function readStdin() {
15
+ return new Promise((resolve) => {
16
+ const chunks = [];
17
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
18
+ process.stdin.on("end", () => {
20
19
  try {
21
- const entry = JSON.parse(trimmed);
22
- if (entry.type !== "assistant" || !entry.message?.usage)
23
- continue;
24
- const u = entry.message.usage;
25
- zero.input_tokens += u.input_tokens ?? 0;
26
- zero.output_tokens += u.output_tokens ?? 0;
27
- zero.cache_read_tokens += u.cache_read_input_tokens ?? 0;
28
- zero.cache_creation_tokens += u.cache_creation_input_tokens ?? 0;
20
+ const raw = Buffer.concat(chunks).toString("utf-8").trim();
21
+ resolve(raw ? JSON.parse(raw) : {});
29
22
  }
30
23
  catch {
31
- // skip malformed lines
24
+ resolve({});
32
25
  }
33
- }
34
- }
35
- catch {
36
- // file not found or unreadable
37
- }
38
- return zero;
26
+ });
27
+ process.stdin.on("error", () => resolve({}));
28
+ });
39
29
  }
40
30
  export async function report(eventType) {
41
- let stdinData = {};
42
- try {
43
- const chunks = [];
44
- for await (const chunk of process.stdin) {
45
- chunks.push(chunk);
46
- }
47
- const raw = Buffer.concat(chunks).toString("utf-8").trim();
48
- if (raw)
49
- stdinData = JSON.parse(raw);
50
- }
51
- catch {
52
- // No stdin or invalid JSON
31
+ const stdinData = await readStdin();
32
+ // For session-end, spawn a detached background process so the hook
33
+ // can exit immediately and avoid being killed during session teardown.
34
+ if (eventType === "session-end") {
35
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
36
+ const bgScript = join(scriptDir, "report-bg.js");
37
+ const child = spawn(process.execPath, [bgScript, JSON.stringify(stdinData)], {
38
+ detached: true,
39
+ stdio: "ignore",
40
+ });
41
+ child.unref();
42
+ return;
53
43
  }
54
44
  const sessionId = stdinData.session_id ?? "";
55
45
  const cwd = stdinData.cwd ?? process.cwd();
@@ -60,12 +50,6 @@ export async function report(eventType) {
60
50
  model: stdinData.model,
61
51
  tool_name: stdinData.tool_name,
62
52
  };
63
- if (eventType === "session-end") {
64
- const transcriptPath = stdinData.transcript_path;
65
- if (transcriptPath) {
66
- payload.usage = parseTranscriptTokens(transcriptPath);
67
- }
68
- }
69
53
  const git = readGitState(cwd);
70
54
  if (git) {
71
55
  const gitPayload = {
@@ -74,7 +58,7 @@ export async function report(eventType) {
74
58
  lastCommitMessage: git.lastCommitMessage,
75
59
  hasUncommittedChanges: git.hasUncommittedChanges,
76
60
  };
77
- if (eventType === "stop" || eventType === "session-end") {
61
+ if (eventType === "stop") {
78
62
  const stats = readGitDiffStats(cwd);
79
63
  gitPayload.filesChanged = stats.filesChanged;
80
64
  gitPayload.insertions = stats.insertions;
package/dist/setup.js CHANGED
@@ -15,6 +15,7 @@ function prompt(question) {
15
15
  const HOOKS_CONFIG = {
16
16
  SessionStart: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report session-start" }] }],
17
17
  Stop: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report stop" }] }],
18
+ SessionEnd: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report session-end" }] }],
18
19
  PostToolUse: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report tool-use", timeout: 3000 }] }],
19
20
  Notification: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report notification" }] }],
20
21
  SubagentStop: [{ hooks: [{ type: "command", command: "npx session-intelligence-cli report subagent-stop", timeout: 3000 }] }],
package/package.json CHANGED
@@ -1,9 +1,22 @@
1
1
  {
2
2
  "name": "session-intelligence-cli",
3
- "version": "0.1.2",
4
- "description": "CLI plugin for Session Intelligencehooks into Claude Code to track sessions",
3
+ "version": "0.1.4",
4
+ "description": "Real-time dashboard for Claude Code sessions track activity, git changes, token usage, and session history across all your projects",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "keywords": [
8
+ "claude",
9
+ "claude-code",
10
+ "anthropic",
11
+ "ai",
12
+ "session",
13
+ "dashboard",
14
+ "cli",
15
+ "hooks",
16
+ "developer-tools",
17
+ "productivity"
18
+ ],
19
+ "homepage": "https://www.session-intelligence.com",
7
20
  "repository": {
8
21
  "type": "git",
9
22
  "url": "https://github.com/0xleal/personal-dashboard.git",
@@ -13,7 +26,8 @@
13
26
  "session-intelligence": "./dist/index.js"
14
27
  },
15
28
  "files": [
16
- "dist"
29
+ "dist",
30
+ "README.md"
17
31
  ],
18
32
  "scripts": {
19
33
  "build": "tsc",