Sign In

session-intelligence-cli

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

session-intelligence-cli - npm Package Compare versions

Comparing version
0.2.2
to
0.3.0
+1
dist/stdin.d.ts
export declare function readStdin(): Promise<Record<string, unknown>>;
export function readStdin() {
return new Promise((resolve) => {
const chunks = [];
process.stdin.on("data", (chunk) => chunks.push(chunk));
process.stdin.on("end", () => {
try {
const raw = Buffer.concat(chunks).toString("utf-8").trim();
resolve(raw ? JSON.parse(raw) : {});
}
catch {
resolve({});
}
});
process.stdin.on("error", () => resolve({}));
});
}
+13
-4

@@ -5,3 +5,3 @@ #!/usr/bin/env node

import { sendEvent } from "./api.js";
// Called as: node report-bg.js <json-payload>
// Called as: node report-bg.js <json-payload> [source]
// Runs detached from the parent process to avoid being killed on session teardown.

@@ -11,5 +11,10 @@ const raw = process.argv[2];

process.exit(0);
const source = (process.argv[3] ?? "claude-code");
const stdinData = JSON.parse(raw);
const sessionId = stdinData.session_id ?? "";
const cwd = stdinData.cwd ?? process.cwd();
const sessionId = source === "cursor"
? stdinData.conversation_id ?? ""
: stdinData.session_id ?? "";
const cwd = source === "cursor"
? (stdinData.workspace_roots?.[0] ?? process.cwd())
: (stdinData.cwd ?? process.cwd());
const payload = {

@@ -19,5 +24,9 @@ session_id: sessionId,

hook_event_name: "SessionEnd",
source: "claude-code",
source,
model: stdinData.model,
};
if (source === "cursor") {
payload.duration_ms = stdinData.duration_ms;
payload.reason = stdinData.reason;
}
const transcriptPath = stdinData.transcript_path;

@@ -24,0 +33,0 @@ if (transcriptPath) {

@@ -0,3 +1,7 @@

import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import { readGitState, readGitDiffStats } from "./git.js";
import { sendEvent } from "./api.js";
import { readStdin } from "./stdin.js";
export const CURSOR_EVENT_MAP = {

@@ -13,18 +17,2 @@ "session-start": "SessionStart",

};
function readStdin() {
return new Promise((resolve) => {
const chunks = [];
process.stdin.on("data", (chunk) => chunks.push(chunk));
process.stdin.on("end", () => {
try {
const raw = Buffer.concat(chunks).toString("utf-8").trim();
resolve(raw ? JSON.parse(raw) : {});
}
catch {
resolve({});
}
});
process.stdin.on("error", () => resolve({}));
});
}
export function buildCursorPayload(eventType, stdinData, cwd) {

@@ -37,5 +25,6 @@ const sessionId = stdinData.conversation_id ?? "";

source: "cursor",
model: stdinData.model,
};
if (eventType === "prompt") {
payload.prompt = stdinData.input ?? stdinData.prompt;
payload.prompt = stdinData.prompt ?? stdinData.input;
}

@@ -61,4 +50,8 @@ else if (eventType === "tool-use") {

else if (eventType === "subagent-stop") {
payload.agent_type = stdinData.agent_type;
payload.subagent_type = stdinData.subagent_type;
}
else if (eventType === "session-end") {
payload.duration_ms = stdinData.duration_ms;
payload.reason = stdinData.reason;
}
return payload;

@@ -68,6 +61,17 @@ }

const stdinData = await readStdin();
// For session-end, spawn a detached background process so the hook
// can exit immediately and avoid being killed during session teardown.
if (eventType === "session-end") {
const scriptDir = dirname(fileURLToPath(import.meta.url));
const bgScript = join(scriptDir, "report-bg.js");
const child = spawn(process.execPath, [bgScript, JSON.stringify(stdinData), "cursor"], {
detached: true,
stdio: "ignore",
});
child.unref();
return;
}
const workspaceRoots = stdinData.workspace_roots;
const cwd = workspaceRoots?.[0] ?? process.cwd();
const payload = buildCursorPayload(eventType, stdinData, cwd);
// Cursor hooks don't include git data — collect it ourselves
const git = readGitState(cwd);

@@ -74,0 +78,0 @@ if (git) {

@@ -6,2 +6,3 @@ import { spawn } from "node:child_process";

import { sendEvent } from "./api.js";
import { readStdin } from "./stdin.js";
export const CLAUDE_EVENT_MAP = {

@@ -15,18 +16,2 @@ "session-start": "SessionStart",

};
function readStdin() {
return new Promise((resolve) => {
const chunks = [];
process.stdin.on("data", (chunk) => chunks.push(chunk));
process.stdin.on("end", () => {
try {
const raw = Buffer.concat(chunks).toString("utf-8").trim();
resolve(raw ? JSON.parse(raw) : {});
}
catch {
resolve({});
}
});
process.stdin.on("error", () => resolve({}));
});
}
export function buildClaudePayload(eventType, stdinData, cwd) {

@@ -33,0 +18,0 @@ return {

@@ -35,10 +35,10 @@ import { createInterface } from "node:readline";

const CURSOR_HOOKS = {
sessionStart: [{ command: "session-intelligence report-cursor session-start", timeout: 5 }],
sessionEnd: [{ command: "session-intelligence report-cursor session-end", timeout: 5 }],
beforeSubmitPrompt: [{ command: "session-intelligence report-cursor prompt", timeout: 5 }],
postToolUse: [{ command: "session-intelligence report-cursor tool-use", timeout: 3 }],
afterFileEdit: [{ command: "session-intelligence report-cursor file-edit", timeout: 3 }],
afterShellExecution: [{ command: "session-intelligence report-cursor shell", timeout: 3 }],
stop: [{ command: "session-intelligence report-cursor stop", timeout: 5 }],
subagentStop: [{ command: "session-intelligence report-cursor subagent-stop", timeout: 3 }],
sessionStart: [{ command: "session-intelligence report-cursor session-start", timeout: 10 }],
sessionEnd: [{ command: "session-intelligence report-cursor session-end", timeout: 10 }],
beforeSubmitPrompt: [{ command: "session-intelligence report-cursor prompt", timeout: 10 }],
postToolUse: [{ command: "session-intelligence report-cursor tool-use", timeout: 10 }],
afterFileEdit: [{ command: "session-intelligence report-cursor file-edit", timeout: 10 }],
afterShellExecution: [{ command: "session-intelligence report-cursor shell", timeout: 10 }],
stop: [{ command: "session-intelligence report-cursor stop", timeout: 10 }],
subagentStop: [{ command: "session-intelligence report-cursor subagent-stop", timeout: 10 }],
};

@@ -45,0 +45,0 @@ export async function setup(args) {

{
"name": "session-intelligence-cli",
"version": "0.2.2",
"version": "0.3.0",
"description": "Real-time dashboard for AI coding sessions — track activity, git changes, token usage, and session history across Claude Code and Cursor",

@@ -5,0 +5,0 @@ "type": "module",

+45
-16
# Session Intelligence CLI
A [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin that gives you a real-time dashboard for all your coding sessions.
A plugin for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and [Cursor](https://cursor.com) that gives you a real-time dashboard for all your AI coding sessions.

@@ -18,4 +18,6 @@ See what every session is doing, track token usage and git changes, and get a full activity history across all your projects.

### Claude Code
```bash
npx session-intelligence-cli setup
npx session-intelligence-cli setup --tool claude-code
```

@@ -31,17 +33,42 @@

### Cursor
```bash
npx session-intelligence-cli setup --tool cursor
```
This will:
1. Ask for your **server URL** and **API key**
2. Save config to `~/.session-intelligence/config.json`
3. Register hooks in `~/.cursor/hooks.json`
Your next Cursor session will start reporting automatically.
## How it works
The CLI registers lightweight [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) that fire on session lifecycle events:
The CLI registers lightweight hooks that fire on session lifecycle events:
| Event | What it reports |
|---|---|
| `SessionStart` | New session created |
| `PostToolUse` | Tool activity (Read, Edit, Bash, etc.) |
| `Notification` | Permission requests / input needed |
| `SubagentStop` | Subagent task completion |
| `Stop` | Task turn completed |
| `SessionEnd` | Session archived with token usage summary |
| Event | Claude Code | Cursor | What it reports |
|---|---|---|---|
| `SessionStart` | ✓ | ✓ | New session created |
| `PostToolUse` | ✓ | ✓ | Tool activity (Read, Edit, Bash, etc.) |
| `UserPromptSubmit` | — | ✓ | User prompt submitted |
| `Notification` | ✓ | — | Permission requests / input needed |
| `SubagentStop` | ✓ | ✓ | Subagent task completion |
| `Stop` | ✓ | ✓ | Task turn completed |
| `SessionEnd` | ✓ | ✓ | Session archived with token usage summary |
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.
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 editor performance.
## Importing existing sessions
Backfill your dashboard with past Claude Code sessions:
```bash
npx session-intelligence-cli import
```
Options: `--project <name>`, `--since <date>`, `--dry-run`, `--dir <path>`.
## Updating

@@ -52,3 +79,4 @@

```bash
npx session-intelligence-cli@latest setup
npx session-intelligence-cli@latest setup --tool claude-code
npx session-intelligence-cli@latest setup --tool cursor
```

@@ -59,4 +87,5 @@

```bash
session-intelligence setup # configure and install hooks
session-intelligence status # check connection and config
session-intelligence setup --tool <claude-code|cursor> # configure and install hooks
session-intelligence status # check connection and active sessions
session-intelligence import # backfill from Claude Code transcripts
```

@@ -67,3 +96,3 @@

- Node.js >= 18
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) or [Cursor](https://cursor.com)

@@ -70,0 +99,0 @@ ## License