agenttop 1.1.0 → 1.2.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/README.md CHANGED
@@ -12,6 +12,7 @@ Currently supports [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
12
12
  - [Security rules](#security-rules)
13
13
  - [How it works](#how-it-works)
14
14
  - [Multi-user support](#multi-user-support)
15
+ - [Contributing](#contributing)
15
16
  - [Trademark notice](#trademark-notice)
16
17
  - [License](#license)
17
18
 
@@ -127,6 +128,10 @@ Two runtime dependencies: [ink](https://github.com/vadimdemedes/ink) (React-base
127
128
  - **Non-root** — monitors your own sessions only
128
129
  - **Root** — use `--all-users` to monitor all users' sessions on the machine
129
130
 
131
+ ## Contributing
132
+
133
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code standards, and PR guidelines.
134
+
130
135
  ## Trademark notice
131
136
 
132
137
  "Claude" is a trademark of Anthropic, PBC. This project is not affiliated with, endorsed by, or sponsored by Anthropic. It monitors Claude Code sessions by reading locally-stored session data.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import React3 from "react";
5
5
  import { render } from "ink";
6
6
 
7
7
  // src/discovery/sessions.ts
8
- import { readdirSync as readdirSync2, readFileSync, statSync, openSync, readSync, closeSync } from "fs";
8
+ import { readdirSync as readdirSync2, statSync, readlinkSync, openSync, readSync, closeSync } from "fs";
9
9
  import { join as join2, basename } from "path";
10
10
  import { execSync } from "child_process";
11
11
 
@@ -40,17 +40,25 @@ var getTaskDirs = (allUsers) => {
40
40
  var getClaudeProcesses = () => {
41
41
  try {
42
42
  const output = execSync("ps aux", { encoding: "utf-8", timeout: 5e3 });
43
- return output.split("\n").filter((line) => line.includes("claude") && !line.includes("grep") && !line.includes("agenttop")).map((line) => {
43
+ const procs = output.split("\n").filter((line) => line.includes("/claude") && !line.includes("grep") && !line.includes("agenttop")).map((line) => {
44
44
  const parts = line.trim().split(/\s+/);
45
+ const pid = parseInt(parts[1], 10);
46
+ let cwd = "";
47
+ try {
48
+ cwd = readlinkSync(`/proc/${pid}/cwd`);
49
+ } catch {
50
+ }
45
51
  return {
46
- pid: parseInt(parts[1], 10),
52
+ pid,
47
53
  cpu: parseFloat(parts[2]) || 0,
48
54
  mem: parseFloat(parts[3]) || 0,
49
55
  memKB: parseInt(parts[5], 10) || 0,
50
56
  startTime: parts[8] || "",
51
- command: parts.slice(10).join(" ")
57
+ command: parts.slice(10).join(" "),
58
+ cwd
52
59
  };
53
- }).filter((p) => !isNaN(p.pid));
60
+ }).filter((p) => !isNaN(p.pid)).filter((p) => !p.command.startsWith("sudo"));
61
+ return procs;
54
62
  } catch {
55
63
  return [];
56
64
  }
@@ -68,21 +76,31 @@ var readFirstEvent = (filePath) => {
68
76
  return null;
69
77
  }
70
78
  };
71
- var readLastLines = (filePath, count) => {
79
+ var findModel = (filePath) => {
72
80
  try {
73
- const content = readFileSync(filePath, "utf-8");
74
- const lines = content.trim().split("\n");
75
- const last = lines.slice(-count);
76
- return last.map((line) => {
81
+ const fd = openSync(filePath, "r");
82
+ const buf = Buffer.alloc(65536);
83
+ const bytesRead = readSync(fd, buf, 0, 65536, 0);
84
+ closeSync(fd);
85
+ const text = buf.subarray(0, bytesRead).toString("utf-8");
86
+ const lines = text.split("\n");
87
+ for (const line of lines) {
88
+ if (!line) continue;
77
89
  try {
78
- return JSON.parse(line);
90
+ const evt = JSON.parse(line);
91
+ if (evt.type === "assistant" && evt.message?.model) {
92
+ return String(evt.message.model);
93
+ }
79
94
  } catch {
80
- return null;
95
+ continue;
81
96
  }
82
- }).filter((e) => e !== null);
97
+ }
83
98
  } catch {
84
- return [];
85
99
  }
100
+ return "";
101
+ };
102
+ var normalisePath = (p) => {
103
+ return p.replace(/\/+$/, "");
86
104
  };
87
105
  var discoverSessions = (allUsers) => {
88
106
  const taskDirs = getTaskDirs(allUsers);
@@ -139,26 +157,18 @@ var discoverSessions = (allUsers) => {
139
157
  if (fstat.mtimeMs > lastActivity) lastActivity = fstat.mtimeMs;
140
158
  } catch {
141
159
  }
142
- const lastEvents = readLastLines(outputFile, 3);
143
- for (const evt of lastEvents) {
144
- if (!model && evt.type === "assistant") {
145
- const content = evt.message?.content;
146
- if (Array.isArray(content)) {
147
- for (const block of content) {
148
- if (typeof block === "object" && block !== null && "model" in block) {
149
- model = block.model;
150
- }
151
- }
152
- }
153
- }
160
+ if (!model) {
161
+ model = findModel(outputFile);
154
162
  }
155
163
  }
156
164
  if (!model) {
157
165
  model = "unknown";
158
166
  }
159
- const matchingProcess = processes.find(
160
- (p) => p.command.includes("claude") && p.command.includes(sessionId.slice(0, 8))
161
- );
167
+ const normCwd = normalisePath(cwd);
168
+ const matchingProcess = processes.find((p) => {
169
+ if (!p.cwd) return false;
170
+ return normalisePath(p.cwd) === normCwd;
171
+ });
162
172
  const session = {
163
173
  sessionId,
164
174
  slug: slug || sessionId.slice(0, 12),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/discovery/sessions.ts","../src/config.ts","../src/ingestion/watcher.ts","../src/ingestion/tail.ts","../src/ingestion/parser.ts","../src/discovery/types.ts","../src/analysis/rules/network.ts","../src/analysis/rules/exfiltration.ts","../src/analysis/rules/sensitive-files.ts","../src/analysis/rules/shell-escape.ts","../src/analysis/rules/injection.ts","../src/analysis/security.ts","../src/ui/App.tsx","../src/ui/components/StatusBar.tsx","../src/ui/theme.ts","../src/ui/components/SessionList.tsx","../src/ui/components/ActivityFeed.tsx","../src/ui/components/AlertBar.tsx","../src/ui/hooks/useSessions.ts","../src/ui/hooks/useActivityStream.ts","../src/ui/hooks/useAlerts.ts","../src/hooks/installer.ts"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\n\nimport type { AlertSeverity, CLIOptions, ToolCall, SecurityEvent } from './discovery/types.js';\nimport { discoverSessions } from './discovery/sessions.js';\nimport { Watcher } from './ingestion/watcher.js';\nimport { SecurityEngine } from './analysis/security.js';\nimport { App } from './ui/App.js';\nimport { installHooks, uninstallHooks } from './hooks/installer.js';\n\nconst VERSION = '1.0.0';\n\nconst HELP = `agenttop v${VERSION} -- Real-time dashboard for AI coding agent sessions\n\nUsage: agenttop [options]\n\nOptions:\n --all-users Monitor all users (root only)\n --no-security Disable security analysis\n --json Stream events as JSON (no TUI)\n --alert-level <l> Minimum: info|warn|high|critical (default: warn)\n --install-hooks Install Claude Code PostToolUse hook for active protection\n --uninstall-hooks Remove agenttop hooks from Claude Code\n --version Show version\n --help Show this help\n`;\n\nconst write = (msg: string): void => {\n process.stdout.write(msg + '\\n');\n};\n\nconst parseArgs = (argv: string[]): CLIOptions => {\n const args = argv.slice(2);\n const options: CLIOptions = {\n allUsers: false,\n noSecurity: false,\n json: false,\n alertLevel: 'warn',\n installHooks: false,\n uninstallHooks: false,\n help: false,\n version: false,\n };\n\n for (let i = 0; i < args.length; i++) {\n switch (args[i]) {\n case '--all-users':\n options.allUsers = true;\n break;\n case '--no-security':\n options.noSecurity = true;\n break;\n case '--json':\n options.json = true;\n break;\n case '--alert-level':\n i++;\n if (['info', 'warn', 'high', 'critical'].includes(args[i])) {\n options.alertLevel = args[i] as AlertSeverity;\n }\n break;\n case '--install-hooks':\n options.installHooks = true;\n break;\n case '--uninstall-hooks':\n options.uninstallHooks = true;\n break;\n case '--version':\n options.version = true;\n break;\n case '--help':\n options.help = true;\n break;\n }\n }\n\n return options;\n};\n\nconst runJsonMode = (options: CLIOptions): void => {\n const engine = options.noSecurity ? null : new SecurityEngine(options.alertLevel);\n\n const sessions = discoverSessions(options.allUsers);\n write(JSON.stringify({ type: 'sessions', data: sessions }));\n\n const handler = (calls: ToolCall[]) => {\n for (const call of calls) {\n write(JSON.stringify({ type: 'tool_call', data: call }));\n }\n };\n\n const securityHandler = engine\n ? (events: SecurityEvent[]) => {\n for (const event of events) {\n const alerts = engine.analyzeEvent(event);\n for (const alert of alerts) {\n write(JSON.stringify({ type: 'alert', data: alert }));\n }\n }\n }\n : undefined;\n\n const watcher = new Watcher(handler, options.allUsers, securityHandler);\n watcher.start();\n\n process.on('SIGINT', () => {\n watcher.stop();\n process.exit(0);\n });\n process.on('SIGTERM', () => {\n watcher.stop();\n process.exit(0);\n });\n};\n\nconst main = () => {\n const options = parseArgs(process.argv);\n\n if (options.version) {\n write(`agenttop v${VERSION}`);\n process.exit(0);\n }\n\n if (options.help) {\n write(HELP);\n process.exit(0);\n }\n\n if (options.installHooks) {\n installHooks();\n process.exit(0);\n }\n\n if (options.uninstallHooks) {\n uninstallHooks();\n process.exit(0);\n }\n\n if (options.json) {\n runJsonMode(options);\n return;\n }\n\n render(React.createElement(App, { options }));\n};\n\nmain();\n","import { readdirSync, readFileSync, statSync, readlinkSync, openSync, readSync, closeSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { execSync } from 'node:child_process';\n\nimport { getTaskDirs } from '../config.js';\nimport type { Session, RawEvent, ProcessInfo } from './types.js';\n\nexport const getClaudeProcesses = (): ProcessInfo[] => {\n try {\n const output = execSync('ps aux', { encoding: 'utf-8', timeout: 5000 });\n return output\n .split('\\n')\n .filter((line) => line.includes('claude') && !line.includes('grep') && !line.includes('agenttop'))\n .map((line) => {\n const parts = line.trim().split(/\\s+/);\n return {\n pid: parseInt(parts[1], 10),\n cpu: parseFloat(parts[2]) || 0,\n mem: parseFloat(parts[3]) || 0,\n memKB: parseInt(parts[5], 10) || 0,\n startTime: parts[8] || '',\n command: parts.slice(10).join(' '),\n };\n })\n .filter((p) => !isNaN(p.pid));\n } catch {\n return [];\n }\n};\n\nconst readFirstEvent = (filePath: string): Record<string, unknown> | null => {\n try {\n const fd = openSync(filePath, 'r');\n const buf = Buffer.alloc(16384);\n const bytesRead = readSync(fd, buf, 0, 16384, 0);\n closeSync(fd);\n const line = buf.subarray(0, bytesRead).toString('utf-8').split('\\n')[0];\n if (!line) return null;\n return JSON.parse(line) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\n\nconst readLastLines = (filePath: string, count: number): RawEvent[] => {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n const last = lines.slice(-count);\n return last\n .map((line) => {\n try {\n return JSON.parse(line) as RawEvent;\n } catch {\n return null;\n }\n })\n .filter((e): e is RawEvent => e !== null);\n } catch {\n return [];\n }\n};\n\nexport const discoverSessions = (allUsers: boolean): Session[] => {\n const taskDirs = getTaskDirs(allUsers);\n const processes = getClaudeProcesses();\n const sessionMap = new Map<string, Session>();\n\n for (const taskDir of taskDirs) {\n let projectDirs: string[];\n try {\n projectDirs = readdirSync(taskDir);\n } catch {\n continue;\n }\n\n for (const projectName of projectDirs) {\n const projectPath = join(taskDir, projectName);\n let stat;\n try {\n stat = statSync(projectPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n\n const tasksDir = join(projectPath, 'tasks');\n let outputFiles: string[];\n try {\n outputFiles = readdirSync(tasksDir)\n .filter((f) => f.endsWith('.output'))\n .map((f) => join(tasksDir, f));\n } catch {\n continue;\n }\n\n if (outputFiles.length === 0) continue;\n\n const agentIds: string[] = [];\n let sessionId = '';\n let slug = '';\n let cwd = '';\n let model = '';\n let version = '';\n let gitBranch = '';\n let startTime = Infinity;\n let lastActivity = 0;\n\n for (const outputFile of outputFiles) {\n const agentId = basename(outputFile, '.output');\n agentIds.push(agentId);\n\n const firstEvent = readFirstEvent(outputFile);\n if (firstEvent) {\n if (!sessionId) sessionId = String(firstEvent.sessionId || '');\n if (!slug) slug = String(firstEvent.slug || '');\n if (!cwd) cwd = String(firstEvent.cwd || '');\n if (!version) version = String(firstEvent.version || '');\n if (!gitBranch) gitBranch = String(firstEvent.gitBranch || '');\n }\n\n try {\n const fstat = statSync(outputFile);\n const created = fstat.birthtimeMs || fstat.ctimeMs;\n if (created < startTime) startTime = created;\n if (fstat.mtimeMs > lastActivity) lastActivity = fstat.mtimeMs;\n } catch {\n // ignore\n }\n\n const lastEvents = readLastLines(outputFile, 3);\n for (const evt of lastEvents) {\n if (!model && evt.type === 'assistant') {\n const content = evt.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (typeof block === 'object' && block !== null && 'model' in block) {\n model = (block as Record<string, string>).model;\n }\n }\n }\n }\n }\n }\n\n if (!model) {\n model = 'unknown';\n }\n\n const matchingProcess = processes.find(\n (p) => p.command.includes('claude') && p.command.includes(sessionId.slice(0, 8)),\n );\n\n const session: Session = {\n sessionId,\n slug: slug || sessionId.slice(0, 12),\n project: projectName.replace(/-/g, '/'),\n cwd,\n model,\n version,\n gitBranch,\n pid: matchingProcess?.pid ?? null,\n cpu: matchingProcess?.cpu ?? 0,\n mem: matchingProcess?.mem ?? 0,\n memMB: matchingProcess ? Math.round(matchingProcess.memKB / 1024) : 0,\n agentCount: agentIds.length,\n agentIds,\n outputFiles,\n startTime: startTime === Infinity ? Date.now() : startTime,\n lastActivity,\n };\n\n sessionMap.set(sessionId || projectName, session);\n }\n }\n\n return Array.from(sessionMap.values()).sort((a, b) => b.lastActivity - a.lastActivity);\n};\n","import { realpathSync, readdirSync } from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { join } from 'node:path';\n\nconst resolvePath = (p: string): string => {\n try {\n return realpathSync(p);\n } catch {\n return p;\n }\n};\n\nexport const getUid = (): number => process.getuid?.() ?? 0;\n\nexport const isRoot = (): boolean => getUid() === 0;\n\nexport const getTmpDir = (): string => resolvePath(platform() === 'darwin' ? '/private/tmp' : '/tmp');\n\nexport const getClaudeHome = (): string => join(homedir(), '.claude');\n\nexport const getHistoryPath = (): string => join(getClaudeHome(), 'history.jsonl');\n\nexport const getTaskDirs = (allUsers: boolean): string[] => {\n const tmp = getTmpDir();\n const uid = getUid();\n\n if (allUsers && isRoot()) {\n try {\n return readdirSync(tmp)\n .filter((d: string) => d.startsWith('claude-'))\n .filter((d: string) => !d.endsWith('-cwd'))\n .map((d: string) => join(tmp, d));\n } catch {\n return [join(tmp, `claude-${uid}`)];\n }\n }\n\n return [join(tmp, `claude-${uid}`)];\n};\n\nexport const getPlatform = (): 'linux' | 'darwin' | 'win32' => {\n const p = platform();\n if (p === 'darwin') return 'darwin';\n if (p === 'win32') return 'win32';\n return 'linux';\n};\n","import { watch } from 'chokidar';\nimport type { FSWatcher } from 'chokidar';\n\nimport { getTaskDirs } from '../config.js';\nimport type { ToolCall, SecurityEvent } from '../discovery/types.js';\nimport { FileTailer } from './tail.js';\nimport { parseLines, parseAllEvents } from './parser.js';\n\nexport type ToolCallHandler = (calls: ToolCall[]) => void;\nexport type SecurityEventHandler = (events: SecurityEvent[]) => void;\n\nexport class Watcher {\n private watcher: FSWatcher | null = null;\n private tailer = new FileTailer();\n private handler: ToolCallHandler;\n private securityHandler: SecurityEventHandler | null;\n private allUsers: boolean;\n private knownFiles = new Set<string>();\n\n constructor(handler: ToolCallHandler, allUsers: boolean, securityHandler?: SecurityEventHandler) {\n this.handler = handler;\n this.allUsers = allUsers;\n this.securityHandler = securityHandler ?? null;\n }\n\n start(): void {\n const taskDirs = getTaskDirs(this.allUsers);\n const globs = taskDirs.map((d) => `${d}/**/tasks/*.output`);\n\n this.watcher = watch(globs, {\n persistent: true,\n ignoreInitial: false,\n awaitWriteFinish: false,\n usePolling: false,\n });\n\n this.watcher.on('add', (filePath: string) => {\n if (this.knownFiles.has(filePath)) return;\n this.knownFiles.add(filePath);\n this.tailer.seekToEnd(filePath);\n });\n\n this.watcher.on('change', (filePath: string) => {\n const lines = this.tailer.readNewLines(filePath);\n if (lines.length === 0) return;\n\n const calls = parseLines(lines);\n if (calls.length > 0) {\n this.handler(calls);\n }\n\n if (this.securityHandler) {\n const allEvents = parseAllEvents(lines);\n if (allEvents.length > 0) {\n this.securityHandler(allEvents);\n }\n }\n });\n }\n\n stop(): void {\n this.watcher?.close();\n this.watcher = null;\n this.tailer.resetAll();\n this.knownFiles.clear();\n }\n\n readExisting(filePath: string): ToolCall[] {\n this.tailer.reset(filePath);\n const lines = this.tailer.readNewLines(filePath);\n return parseLines(lines);\n }\n}\n","import { openSync, readSync, closeSync, statSync } from 'node:fs';\n\nexport class FileTailer {\n private offsets = new Map<string, number>();\n\n readNewLines(filePath: string): string[] {\n let currentSize: number;\n try {\n currentSize = statSync(filePath).size;\n } catch {\n return [];\n }\n\n const lastOffset = this.offsets.get(filePath) ?? 0;\n if (currentSize <= lastOffset) return [];\n\n const bytesToRead = currentSize - lastOffset;\n const buf = Buffer.alloc(bytesToRead);\n\n let fd: number;\n try {\n fd = openSync(filePath, 'r');\n } catch {\n return [];\n }\n\n try {\n readSync(fd, buf, 0, bytesToRead, lastOffset);\n } finally {\n closeSync(fd);\n }\n\n this.offsets.set(filePath, currentSize);\n\n const text = buf.toString('utf-8');\n const lines = text.split('\\n').filter((l) => l.trim().length > 0);\n return lines;\n }\n\n seekToEnd(filePath: string): void {\n try {\n const size = statSync(filePath).size;\n this.offsets.set(filePath, size);\n } catch {\n // file doesn't exist yet\n }\n }\n\n reset(filePath: string): void {\n this.offsets.delete(filePath);\n }\n\n resetAll(): void {\n this.offsets.clear();\n }\n}\n","import type { RawEvent, ToolCall, ToolResult, SecurityEvent } from '../discovery/types.js';\n\nexport const parseLine = (line: string): RawEvent | null => {\n try {\n return JSON.parse(line) as RawEvent;\n } catch {\n return null;\n }\n};\n\nexport const extractToolCalls = (event: RawEvent): ToolCall[] => {\n if (event.type !== 'assistant') return [];\n\n const content = event.message?.content;\n if (!Array.isArray(content)) return [];\n\n const calls: ToolCall[] = [];\n\n for (const block of content) {\n if (\n typeof block === 'object' &&\n block !== null &&\n 'type' in block &&\n (block as Record<string, unknown>).type === 'tool_use'\n ) {\n const toolBlock = block as Record<string, unknown>;\n calls.push({\n sessionId: event.sessionId,\n agentId: event.agentId,\n slug: (event as Record<string, unknown>).slug as string || '',\n timestamp: Date.now(),\n toolName: (toolBlock.name as string) || 'unknown',\n toolInput: (toolBlock.input as Record<string, unknown>) || {},\n cwd: event.cwd,\n });\n }\n }\n\n return calls;\n};\n\nexport const extractToolResults = (event: RawEvent): ToolResult[] => {\n if (event.type !== 'user') return [];\n\n const content = event.message?.content;\n if (!Array.isArray(content)) return [];\n\n const results: ToolResult[] = [];\n\n for (const block of content) {\n if (\n typeof block === 'object' &&\n block !== null &&\n 'type' in block &&\n (block as Record<string, unknown>).type === 'tool_result'\n ) {\n const resultBlock = block as Record<string, unknown>;\n const resultContent = resultBlock.content;\n let text = '';\n if (typeof resultContent === 'string') {\n text = resultContent;\n } else if (Array.isArray(resultContent)) {\n text = resultContent\n .map((c) => (typeof c === 'object' && c !== null ? (c as Record<string, unknown>).text || '' : String(c)))\n .join('\\n');\n }\n\n results.push({\n sessionId: event.sessionId,\n agentId: event.agentId,\n slug: (event as Record<string, unknown>).slug as string || '',\n timestamp: Date.now(),\n toolUseId: String(resultBlock.tool_use_id || ''),\n content: text,\n isError: Boolean(resultBlock.is_error),\n cwd: event.cwd,\n });\n }\n }\n\n return results;\n};\n\nexport const parseLines = (lines: string[]): ToolCall[] => {\n const calls: ToolCall[] = [];\n for (const line of lines) {\n const event = parseLine(line);\n if (event) {\n calls.push(...extractToolCalls(event));\n }\n }\n return calls;\n};\n\nexport const parseAllEvents = (lines: string[]): SecurityEvent[] => {\n const events: SecurityEvent[] = [];\n for (const line of lines) {\n const event = parseLine(line);\n if (event) {\n events.push(...extractToolCalls(event));\n events.push(...extractToolResults(event));\n }\n }\n return events;\n};\n","export interface Session {\n sessionId: string;\n slug: string;\n project: string;\n cwd: string;\n model: string;\n version: string;\n gitBranch: string;\n pid: number | null;\n cpu: number;\n mem: number;\n memMB: number;\n agentCount: number;\n agentIds: string[];\n outputFiles: string[];\n startTime: number;\n lastActivity: number;\n}\n\nexport interface ToolCall {\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp: number;\n toolName: string;\n toolInput: Record<string, unknown>;\n cwd: string;\n}\n\nexport interface ToolResult {\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp: number;\n toolUseId: string;\n content: string;\n isError: boolean;\n cwd: string;\n}\n\nexport type SecurityEvent = ToolCall | ToolResult;\n\nexport const isToolResult = (event: SecurityEvent): event is ToolResult =>\n 'toolUseId' in event;\n\nexport const isToolCall = (event: SecurityEvent): event is ToolCall =>\n 'toolName' in event;\n\nexport interface RawEvent {\n type: 'user' | 'assistant' | 'tool_result';\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp?: number;\n cwd: string;\n version: string;\n gitBranch: string;\n message: {\n role: string;\n content: unknown;\n };\n}\n\nexport type AlertSeverity = 'info' | 'warn' | 'high' | 'critical';\n\nexport interface Alert {\n id: string;\n severity: AlertSeverity;\n rule: string;\n message: string;\n sessionSlug: string;\n sessionId: string;\n event: SecurityEvent;\n timestamp: number;\n}\n\nexport interface ProcessInfo {\n pid: number;\n cpu: number;\n mem: number;\n memKB: number;\n command: string;\n startTime: string;\n}\n\nexport interface CLIOptions {\n allUsers: boolean;\n noSecurity: boolean;\n json: boolean;\n alertLevel: AlertSeverity;\n installHooks: boolean;\n uninstallHooks: boolean;\n help: boolean;\n version: boolean;\n}\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst NETWORK_PATTERNS = [\n /\\bcurl\\b/,\n /\\bwget\\b/,\n /\\bfetch\\s*\\(/,\n /\\bnc\\b/,\n /\\bnetcat\\b/,\n /\\bpython3?\\s+-m\\s+http\\.server\\b/,\n /\\bncat\\b/,\n /\\bsocat\\b/,\n /\\btelnet\\b/,\n];\n\nconst LOCALHOST = /\\b(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|\\[::1\\])\\b/;\n\nexport const checkNetwork = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n const matched = NETWORK_PATTERNS.some((p) => p.test(command));\n if (!matched) return null;\n\n const isLocal = LOCALHOST.test(command);\n const severity = isLocal ? 'info' : 'warn';\n\n return {\n id: `net-${call.timestamp}-${call.agentId}`,\n severity,\n rule: 'network',\n message: isLocal\n ? `Network command to localhost: ${command.slice(0, 80)}`\n : `Network command to external target: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst EXFIL_PATTERNS = [\n /base64.*\\|\\s*(curl|wget|nc)/,\n /cat\\s+.*\\|\\s*(curl|wget|nc)/,\n /(tar|zip|gzip).*\\|\\s*(curl|wget|nc)/,\n /\\bcurl\\b.*-d\\s*@/,\n /\\bcurl\\b.*--data-binary/,\n /\\bscp\\b/,\n /\\brsync\\b.*[^/]@/,\n />\\s*\\/dev\\/tcp\\//,\n];\n\nexport const checkExfiltration = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n const matched = EXFIL_PATTERNS.some((p) => p.test(command));\n if (!matched) return null;\n\n return {\n id: `exfil-${call.timestamp}-${call.agentId}`,\n severity: 'high',\n rule: 'exfiltration',\n message: `Potential data exfiltration: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst SENSITIVE_PATTERNS = [\n /\\.env\\b/,\n /\\.env\\.\\w+/,\n /\\.ssh\\//,\n /id_rsa/,\n /id_ed25519/,\n /\\.pem$/,\n /\\.key$/,\n /credentials/i,\n /\\/etc\\/shadow/,\n /\\/etc\\/passwd/,\n /\\.aws\\/credentials/,\n /\\.kube\\/config/,\n /\\.docker\\/config\\.json/,\n /\\.npmrc/,\n /\\.pypirc/,\n /\\.netrc/,\n /secrets?\\.\\w+/i,\n /token\\.\\w+/i,\n];\n\nconst TOOLS_THAT_READ = ['Read', 'Bash', 'Grep', 'Glob'];\n\nexport const checkSensitiveFiles = (call: ToolCall): Alert | null => {\n if (!TOOLS_THAT_READ.includes(call.toolName)) return null;\n\n const inputs = JSON.stringify(call.toolInput);\n const matched = SENSITIVE_PATTERNS.some((p) => p.test(inputs));\n if (!matched) return null;\n\n const target =\n String(call.toolInput.file_path || call.toolInput.command || call.toolInput.pattern || '').slice(0, 60);\n\n return {\n id: `sens-${call.timestamp}-${call.agentId}`,\n severity: 'warn',\n rule: 'sensitive-files',\n message: `Accessing sensitive file: ${target}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst SHELL_PATTERNS: Array<{ pattern: RegExp; severity: 'high' | 'critical'; label: string }> = [\n { pattern: /\\beval\\s*[(\"']/, severity: 'high', label: 'eval execution' },\n { pattern: /\\bchmod\\s+777\\b/, severity: 'high', label: 'chmod 777' },\n { pattern: /\\bchmod\\s+\\+s\\b/, severity: 'critical', label: 'setuid chmod' },\n { pattern: /\\bsudo\\b/, severity: 'high', label: 'sudo usage' },\n { pattern: /\\bsu\\s+-?\\s*\\w/, severity: 'high', label: 'su usage' },\n { pattern: />\\s*\\/etc\\//, severity: 'critical', label: 'writing to /etc/' },\n { pattern: />\\s*\\/usr\\//, severity: 'critical', label: 'writing to /usr/' },\n { pattern: /--privileged/, severity: 'critical', label: 'privileged flag' },\n { pattern: /\\brm\\s+-rf\\s+\\/(?!\\w)/, severity: 'critical', label: 'rm -rf /' },\n { pattern: /\\bdd\\s+.*of=\\/dev\\//, severity: 'critical', label: 'dd to device' },\n { pattern: /\\bmkfs\\b/, severity: 'critical', label: 'filesystem format' },\n { pattern: /\\biptables\\b/, severity: 'high', label: 'firewall modification' },\n];\n\nexport const checkShellEscape = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n\n for (const rule of SHELL_PATTERNS) {\n if (rule.pattern.test(command)) {\n return {\n id: `shell-${call.timestamp}-${call.agentId}`,\n severity: rule.severity,\n rule: 'shell-escape',\n message: `${rule.label}: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n }\n }\n\n return null;\n};\n","import type { ToolCall, ToolResult, Alert, SecurityEvent } from '../../discovery/types.js';\nimport { isToolResult, isToolCall } from '../../discovery/types.js';\n\nconst INJECTION_PATTERNS = [\n /ignore\\s+(all\\s+)?previous\\s+instructions/i,\n /ignore\\s+(all\\s+)?prior\\s+instructions/i,\n /disregard\\s+(all\\s+)?previous/i,\n /you\\s+are\\s+now\\s+/i,\n /new\\s+instructions?\\s*:/i,\n /system\\s*:\\s*you/i,\n /\\bdo\\s+not\\s+follow\\s+(your|the)\\s+(original|previous)/i,\n /override\\s+(your\\s+)?(instructions|rules|guidelines)/i,\n /forget\\s+(your\\s+)?(instructions|rules|guidelines)/i,\n /act\\s+as\\s+(if\\s+)?(you\\s+are|a)\\s+/i,\n /pretend\\s+(you\\s+are|to\\s+be)\\s+/i,\n /\\bAI\\s+assistant\\b.*\\bmust\\b/i,\n /\\bhuman\\s*:\\s*/i,\n /\\bassistant\\s*:\\s*/i,\n /<\\s*system\\s*>/i,\n /\\[\\s*INST\\s*\\]/i,\n /BEGIN\\s+HIDDEN\\s+INSTRUCTIONS/i,\n];\n\nconst ENCODED_PATTERNS = [\n /aWdub3JlIHByZXZpb3Vz/, // base64 \"ignore previous\"\n /&#x[0-9a-f]+;/i, // html hex entities\n /&#\\d+;/, // html decimal entities\n /\\\\u[0-9a-f]{4}/i, // unicode escapes\n];\n\nexport const checkInjection = (event: SecurityEvent): Alert | null => {\n if (isToolCall(event)) {\n return checkToolCallInjection(event);\n }\n if (isToolResult(event)) {\n return checkToolResultInjection(event);\n }\n return null;\n};\n\nconst checkToolCallInjection = (call: ToolCall): Alert | null => {\n const inputs = JSON.stringify(call.toolInput);\n\n const matched = INJECTION_PATTERNS.some((p) => p.test(inputs));\n if (!matched) return null;\n\n return {\n id: `inject-call-${call.timestamp}-${call.agentId}`,\n severity: 'critical',\n rule: 'injection',\n message: `Prompt injection in ${call.toolName} input`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n\nconst checkToolResultInjection = (result: ToolResult): Alert | null => {\n const content = result.content;\n if (!content || content.length < 10) return null;\n\n const textPatternMatch = INJECTION_PATTERNS.some((p) => p.test(content));\n const encodedMatch = ENCODED_PATTERNS.some((p) => p.test(content));\n\n if (!textPatternMatch && !encodedMatch) return null;\n\n const matchedPattern = INJECTION_PATTERNS.find((p) => p.test(content));\n const snippet = matchedPattern\n ? content.match(matchedPattern)?.[0]?.slice(0, 50) || ''\n : 'encoded pattern';\n\n return {\n id: `inject-result-${result.timestamp}-${result.agentId}`,\n severity: 'critical',\n rule: 'injection-in-result',\n message: `Prompt injection in tool result: \"${snippet}\"`,\n sessionSlug: result.slug,\n sessionId: result.sessionId,\n event: result,\n timestamp: result.timestamp,\n };\n};\n","import type { ToolCall, ToolResult, SecurityEvent, Alert, AlertSeverity } from '../discovery/types.js';\nimport { isToolCall } from '../discovery/types.js';\n\nimport { checkNetwork } from './rules/network.js';\nimport { checkExfiltration } from './rules/exfiltration.js';\nimport { checkSensitiveFiles } from './rules/sensitive-files.js';\nimport { checkShellEscape } from './rules/shell-escape.js';\nimport { checkInjection } from './rules/injection.js';\n\ntype ToolCallRule = (call: ToolCall) => Alert | null;\ntype SecurityEventRule = (event: SecurityEvent) => Alert | null;\n\nconst toolCallRules: ToolCallRule[] = [\n checkNetwork,\n checkExfiltration,\n checkSensitiveFiles,\n checkShellEscape,\n];\n\nconst allEventRules: SecurityEventRule[] = [\n checkInjection,\n];\n\nconst SEVERITY_ORDER: Record<AlertSeverity, number> = {\n info: 0,\n warn: 1,\n high: 2,\n critical: 3,\n};\n\nconst DEDUP_WINDOW_MS = 30_000;\n\nexport class SecurityEngine {\n private recentAlerts = new Map<string, number>();\n private minLevel: AlertSeverity;\n\n constructor(minLevel: AlertSeverity = 'warn') {\n this.minLevel = minLevel;\n }\n\n analyze(call: ToolCall): Alert[] {\n return this.analyzeEvent(call);\n }\n\n analyzeResult(result: ToolResult): Alert[] {\n return this.analyzeEvent(result);\n }\n\n analyzeEvent(event: SecurityEvent): Alert[] {\n const alerts: Alert[] = [];\n\n if (isToolCall(event)) {\n for (const rule of toolCallRules) {\n const alert = rule(event);\n if (alert) alerts.push(alert);\n }\n }\n\n for (const rule of allEventRules) {\n const alert = rule(event);\n if (alert) alerts.push(alert);\n }\n\n return alerts.filter((alert) => {\n if (SEVERITY_ORDER[alert.severity] < SEVERITY_ORDER[this.minLevel]) return false;\n\n const dedupKey = `${alert.rule}-${alert.sessionId}-${alert.message.slice(0, 40)}`;\n const lastSeen = this.recentAlerts.get(dedupKey);\n if (lastSeen && alert.timestamp - lastSeen < DEDUP_WINDOW_MS) return false;\n\n this.recentAlerts.set(dedupKey, alert.timestamp);\n return true;\n });\n }\n\n pruneOldAlerts(): void {\n const cutoff = Date.now() - DEDUP_WINDOW_MS * 2;\n for (const [key, ts] of this.recentAlerts) {\n if (ts < cutoff) this.recentAlerts.delete(key);\n }\n }\n}\n","import React, { useState, useCallback, useEffect } from 'react';\nimport { Box, Text, useApp, useInput, useStdout } from 'ink';\n\nimport type { CLIOptions } from '../discovery/types.js';\nimport { StatusBar } from './components/StatusBar.js';\nimport { SessionList } from './components/SessionList.js';\nimport { ActivityFeed } from './components/ActivityFeed.js';\nimport { AlertBar } from './components/AlertBar.js';\nimport { useSessions } from './hooks/useSessions.js';\nimport { useActivityStream } from './hooks/useActivityStream.js';\nimport { useAlerts } from './hooks/useAlerts.js';\n\ntype Panel = 'sessions' | 'activity';\n\ninterface AppProps {\n options: CLIOptions;\n}\n\nexport const App: React.FC<AppProps> = ({ options }) => {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const termHeight = stdout?.rows ?? 40;\n const [activePanel, setActivePanel] = useState<Panel>('sessions');\n const [activityScroll, setActivityScroll] = useState(0);\n\n const { sessions, selectedSession, selectedIndex, selectNext, selectPrev } = useSessions(options.allUsers);\n const events = useActivityStream(selectedSession, options.allUsers);\n const { alerts } = useAlerts(!options.noSecurity, options.alertLevel, options.allUsers);\n\n const alertHeight = options.noSecurity ? 0 : 6;\n const statusHeight = 3;\n const footerHeight = 1;\n const mainHeight = termHeight - statusHeight - alertHeight - footerHeight;\n const viewportRows = mainHeight - 2;\n const maxScroll = Math.max(0, events.length - viewportRows);\n\n useEffect(() => {\n setActivityScroll(0);\n }, [selectedSession?.sessionId]);\n\n useInput((input, key) => {\n if (input === 'q') {\n exit();\n return;\n }\n\n if (key.tab) {\n setActivePanel((p) => (p === 'sessions' ? 'activity' : 'sessions'));\n return;\n }\n\n if (activePanel === 'sessions') {\n if (input === 'j' || key.downArrow) selectNext();\n if (input === 'k' || key.upArrow) selectPrev();\n }\n\n if (activePanel === 'activity') {\n if (input === 'k' || key.upArrow) {\n setActivityScroll((s) => Math.min(s + 1, maxScroll));\n }\n if (input === 'j' || key.downArrow) {\n setActivityScroll((s) => Math.max(s - 1, 0));\n }\n if (input === 'G' || key.end) {\n setActivityScroll(0);\n }\n if (input === 'g' || key.home) {\n setActivityScroll(maxScroll);\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" height={termHeight}>\n <StatusBar sessionCount={sessions.length} alertCount={alerts.length} />\n\n <Box flexGrow={1} height={mainHeight}>\n <SessionList\n sessions={sessions}\n selectedIndex={selectedIndex}\n focused={activePanel === 'sessions'}\n />\n <ActivityFeed\n events={events}\n sessionSlug={selectedSession?.slug ?? null}\n focused={activePanel === 'activity'}\n height={mainHeight}\n scrollOffset={activityScroll}\n />\n </Box>\n\n {!options.noSecurity && <AlertBar alerts={alerts} />}\n\n <Box paddingX={1}>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">q:quit</Text>\n </Box>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">j/k:nav</Text>\n </Box>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">tab:panel</Text>\n </Box>\n {activePanel === 'activity' && (\n <Box marginRight={2}>\n <Text color=\"#5C6370\">g/G:top/bottom</Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\n\nimport { colors } from '../theme.js';\n\ninterface StatusBarProps {\n sessionCount: number;\n alertCount: number;\n}\n\nexport const StatusBar: React.FC<StatusBarProps> = ({ sessionCount, alertCount }) => {\n const [time, setTime] = useState(new Date());\n\n useEffect(() => {\n const interval = setInterval(() => setTime(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n const timeStr = time.toLocaleTimeString('en-GB', { hour12: false });\n\n return (\n <Box borderStyle=\"single\" borderColor={colors.border} paddingX={1} justifyContent=\"space-between\">\n <Text color={colors.header} bold>\n agenttop v1.0.0\n </Text>\n <Text color={colors.text}>\n {sessionCount} session{sessionCount !== 1 ? 's' : ''}\n </Text>\n {alertCount > 0 && (\n <Text color={colors.error} bold>\n {alertCount} alert{alertCount !== 1 ? 's' : ''}\n </Text>\n )}\n <Text color={colors.muted}>{timeStr}</Text>\n </Box>\n );\n};\n","export const colors = {\n primary: '#61AFEF',\n secondary: '#98C379',\n accent: '#C678DD',\n warning: '#E5C07B',\n error: '#E06C75',\n critical: '#FF0000',\n muted: '#5C6370',\n text: '#ABB2BF',\n bright: '#FFFFFF',\n border: '#3E4451',\n selected: '#2C313A',\n header: '#61AFEF',\n};\n\nexport const severityColors: Record<string, string> = {\n info: colors.muted,\n warn: colors.warning,\n high: colors.error,\n critical: colors.critical,\n};\n\nexport const toolColors: Record<string, string> = {\n Bash: colors.error,\n Read: colors.secondary,\n Write: colors.accent,\n Edit: colors.accent,\n Grep: colors.primary,\n Glob: colors.primary,\n Task: colors.warning,\n WebFetch: colors.warning,\n WebSearch: colors.warning,\n};\n\nexport const getToolColor = (toolName: string): string =>\n toolColors[toolName] || colors.text;\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { Session } from '../../discovery/types.js';\nimport { colors } from '../theme.js';\n\ninterface SessionListProps {\n sessions: Session[];\n selectedIndex: number;\n focused: boolean;\n}\n\nconst formatModel = (model: string): string => {\n if (model.includes('opus')) return 'opus';\n if (model.includes('sonnet')) return 'sonnet';\n if (model.includes('haiku')) return 'haiku';\n return model.slice(0, 8);\n};\n\nconst formatProject = (project: string): string => {\n const parts = project.split('/');\n const last = parts[parts.length - 1] || project;\n return last.length > 18 ? last.slice(0, 17) + '\\u2026' : last;\n};\n\nexport const SessionList: React.FC<SessionListProps> = ({ sessions, selectedIndex, focused }) => {\n return (\n <Box flexDirection=\"column\" width={28} borderStyle=\"single\" borderColor={focused ? colors.primary : colors.border}>\n <Box paddingX={1}>\n <Text color={colors.header} bold>\n SESSIONS\n </Text>\n </Box>\n\n {sessions.length === 0 && (\n <Box paddingX={1} paddingY={1}>\n <Text color={colors.muted} italic>\n No active sessions\n </Text>\n </Box>\n )}\n\n {sessions.map((session, i) => {\n const isSelected = i === selectedIndex;\n const indicator = isSelected ? '>' : ' ';\n\n return (\n <Box key={session.sessionId} flexDirection=\"column\" paddingX={1} paddingY={0}>\n <Text\n color={isSelected ? colors.bright : colors.text}\n bold={isSelected}\n backgroundColor={isSelected ? colors.selected : undefined}\n >\n {indicator} {session.slug}\n </Text>\n <Text color={colors.muted}>\n {' '}{formatProject(session.project)} | {formatModel(session.model)}\n </Text>\n <Text color={colors.muted}>\n {' '}CPU {session.cpu}% | {session.memMB}MB | {session.agentCount} ag\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n};\n","import React, { useState, useEffect, useRef } from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { ToolCall } from '../../discovery/types.js';\nimport { colors, getToolColor } from '../theme.js';\n\ninterface ActivityFeedProps {\n events: ToolCall[];\n sessionSlug: string | null;\n focused: boolean;\n height: number;\n scrollOffset: number;\n}\n\nconst formatTime = (ts: number): string => {\n const d = new Date(ts);\n return d.toLocaleTimeString('en-GB', { hour12: false });\n};\n\nconst summarizeInput = (call: ToolCall): string => {\n const input = call.toolInput;\n\n switch (call.toolName) {\n case 'Bash':\n return String(input.command || '').slice(0, 50);\n case 'Read':\n case 'Write':\n case 'Edit':\n return String(input.file_path || '').split('/').slice(-2).join('/');\n case 'Grep':\n return `pattern=\"${String(input.pattern || '').slice(0, 30)}\"`;\n case 'Glob':\n return String(input.pattern || '').slice(0, 40);\n case 'Task':\n return String(input.description || '').slice(0, 40);\n case 'WebFetch':\n case 'WebSearch':\n return String(input.url || input.query || '').slice(0, 40);\n default:\n return JSON.stringify(input).slice(0, 40);\n }\n};\n\nexport const ActivityFeed: React.FC<ActivityFeedProps> = ({ events, sessionSlug, focused, height, scrollOffset }) => {\n const viewportRows = height - 2;\n const totalEvents = events.length;\n const start = Math.max(0, totalEvents - viewportRows - scrollOffset);\n const end = start + viewportRows;\n const visible = events.slice(start, end);\n\n const isAtBottom = scrollOffset === 0;\n const isAtTop = start === 0;\n const canScroll = totalEvents > viewportRows;\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={focused ? colors.primary : colors.border}\n >\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box>\n <Text color={colors.header} bold>\n ACTIVITY\n </Text>\n {sessionSlug && (\n <Text color={colors.muted}> ({sessionSlug})</Text>\n )}\n </Box>\n {focused && canScroll && !isAtBottom && (\n <Text color={colors.muted}>\n [{totalEvents - end + viewportRows}/{totalEvents}]\n </Text>\n )}\n </Box>\n\n {visible.length === 0 && (\n <Box paddingX={1} paddingY={1}>\n <Text color={colors.muted} italic>\n {sessionSlug ? 'Waiting for activity...' : 'Select a session'}\n </Text>\n </Box>\n )}\n\n {visible.map((event, i) => (\n <Box key={`${event.timestamp}-${i}`} paddingX={1}>\n <Text color={colors.muted}>{formatTime(event.timestamp)} </Text>\n <Text color={getToolColor(event.toolName)} bold>\n {event.toolName.padEnd(8)}\n </Text>\n <Text color={colors.text}> {summarizeInput(event)}</Text>\n </Box>\n ))}\n\n {focused && canScroll && !isAtTop && visible.length > 0 && (\n <Box paddingX={1} justifyContent=\"flex-end\">\n <Text color={colors.muted}>\n {isAtBottom ? '' : 'G:bottom '}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { Alert } from '../../discovery/types.js';\nimport { colors, severityColors } from '../theme.js';\n\ninterface AlertBarProps {\n alerts: Alert[];\n maxVisible?: number;\n}\n\nconst formatTime = (ts: number): string => {\n const d = new Date(ts);\n return d.toLocaleTimeString('en-GB', { hour12: false });\n};\n\nconst severityIcon: Record<string, string> = {\n info: 'i',\n warn: '!',\n high: '!!',\n critical: '!!!',\n};\n\nexport const AlertBar: React.FC<AlertBarProps> = ({ alerts, maxVisible = 4 }) => {\n const visible = alerts.slice(-maxVisible);\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={alerts.length > 0 ? colors.error : colors.border}\n >\n <Box paddingX={1}>\n <Text color={colors.error} bold>\n ALERTS\n </Text>\n {alerts.length === 0 && (\n <Text color={colors.muted}> (none)</Text>\n )}\n </Box>\n\n {visible.map((alert, i) => (\n <Box key={alert.id || i} paddingX={1}>\n <Text color={severityColors[alert.severity] || colors.text}>\n [{severityIcon[alert.severity] || '?'}]\n </Text>\n <Text color={colors.muted}> {formatTime(alert.timestamp)} </Text>\n <Text color={colors.warning}>{alert.sessionSlug}: </Text>\n <Text color={colors.text}>{alert.message.slice(0, 60)}</Text>\n </Box>\n ))}\n </Box>\n );\n};\n","import { useState, useEffect, useCallback } from 'react';\n\nimport { discoverSessions } from '../../discovery/sessions.js';\nimport type { Session } from '../../discovery/types.js';\n\nexport const useSessions = (allUsers: boolean, pollMs = 5000) => {\n const [sessions, setSessions] = useState<Session[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const refresh = useCallback(() => {\n const found = discoverSessions(allUsers);\n setSessions(found);\n }, [allUsers]);\n\n useEffect(() => {\n refresh();\n const interval = setInterval(refresh, pollMs);\n return () => clearInterval(interval);\n }, [refresh, pollMs]);\n\n const selectedSession = sessions[selectedIndex] ?? null;\n\n const selectNext = useCallback(() => {\n setSelectedIndex((i) => Math.min(i + 1, sessions.length - 1));\n }, [sessions.length]);\n\n const selectPrev = useCallback(() => {\n setSelectedIndex((i) => Math.max(i - 1, 0));\n }, []);\n\n const selectIndex = useCallback((i: number) => {\n setSelectedIndex(i);\n }, []);\n\n return { sessions, selectedSession, selectedIndex, selectNext, selectPrev, selectIndex, refresh };\n};\n","import { useState, useEffect, useRef } from 'react';\n\nimport type { Session, ToolCall } from '../../discovery/types.js';\nimport { Watcher } from '../../ingestion/watcher.js';\n\nconst MAX_EVENTS = 200;\n\nexport const useActivityStream = (session: Session | null, allUsers: boolean) => {\n const [events, setEvents] = useState<ToolCall[]>([]);\n const watcherRef = useRef<Watcher | null>(null);\n\n useEffect(() => {\n setEvents([]);\n\n if (!session) return;\n\n const existingCalls: ToolCall[] = [];\n const tempWatcher = new Watcher(() => {}, allUsers);\n for (const file of session.outputFiles) {\n existingCalls.push(...tempWatcher.readExisting(file));\n }\n setEvents(existingCalls.slice(-MAX_EVENTS));\n\n const handler = (calls: ToolCall[]) => {\n const sessionCalls = calls.filter((c) => c.sessionId === session.sessionId);\n if (sessionCalls.length === 0) return;\n setEvents((prev) => [...prev, ...sessionCalls].slice(-MAX_EVENTS));\n };\n\n const watcher = new Watcher(handler, allUsers);\n watcherRef.current = watcher;\n watcher.start();\n\n return () => {\n watcher.stop();\n watcherRef.current = null;\n };\n }, [session?.sessionId, allUsers]);\n\n return events;\n};\n","import { useState, useEffect, useRef } from 'react';\n\nimport type { Alert, AlertSeverity, SecurityEvent } from '../../discovery/types.js';\nimport { SecurityEngine } from '../../analysis/security.js';\nimport { Watcher } from '../../ingestion/watcher.js';\n\nconst MAX_ALERTS = 100;\n\nexport const useAlerts = (enabled: boolean, alertLevel: AlertSeverity, allUsers: boolean) => {\n const [alerts, setAlerts] = useState<Alert[]>([]);\n const engineRef = useRef(new SecurityEngine(alertLevel));\n const watcherRef = useRef<Watcher | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n\n engineRef.current = new SecurityEngine(alertLevel);\n\n const securityHandler = (events: SecurityEvent[]) => {\n const newAlerts: Alert[] = [];\n for (const event of events) {\n newAlerts.push(...engineRef.current.analyzeEvent(event));\n }\n if (newAlerts.length > 0) {\n setAlerts((prev) => [...prev, ...newAlerts].slice(-MAX_ALERTS));\n }\n };\n\n const watcher = new Watcher(() => {}, allUsers, securityHandler);\n watcherRef.current = watcher;\n watcher.start();\n\n return () => {\n watcher.stop();\n watcherRef.current = null;\n };\n }, [enabled, alertLevel, allUsers]);\n\n const clearAlerts = () => setAlerts([]);\n\n return { alerts, clearAlerts };\n};\n","import { existsSync, readFileSync, writeFileSync, copyFileSync, mkdirSync, chmodSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { fileURLToPath } from 'node:url';\n\nconst HOOK_FILENAME = 'agenttop-guard.py';\nconst SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');\n\nconst getHookSource = (): string => {\n const thisFile = fileURLToPath(import.meta.url);\n const srcHooksDir = join(dirname(thisFile), '..', 'src', 'hooks');\n const distHooksDir = join(dirname(thisFile), 'hooks');\n\n for (const dir of [distHooksDir, srcHooksDir]) {\n const path = join(dir, HOOK_FILENAME);\n if (existsSync(path)) return path;\n }\n\n const npmGlobalPath = join(dirname(thisFile), '..', 'hooks', HOOK_FILENAME);\n if (existsSync(npmGlobalPath)) return npmGlobalPath;\n\n throw new Error(`cannot find ${HOOK_FILENAME} — is agenttop installed correctly?`);\n};\n\nconst getHookTarget = (): string => {\n const claudeHooksDir = join(homedir(), '.claude', 'hooks');\n mkdirSync(claudeHooksDir, { recursive: true });\n return join(claudeHooksDir, HOOK_FILENAME);\n};\n\ninterface HookEntry {\n type: string;\n command: string;\n}\n\ninterface MatcherEntry {\n matcher: string;\n hooks: HookEntry[];\n}\n\nconst readSettings = (): Record<string, unknown> => {\n if (!existsSync(SETTINGS_PATH)) {\n return {};\n }\n try {\n return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));\n } catch {\n return {};\n }\n};\n\nconst writeSettings = (settings: Record<string, unknown>): void => {\n mkdirSync(dirname(SETTINGS_PATH), { recursive: true });\n writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\\n');\n};\n\nexport const installHooks = (): void => {\n const source = getHookSource();\n const target = getHookTarget();\n\n copyFileSync(source, target);\n chmodSync(target, 0o755);\n\n const settings = readSettings();\n const hooks = (settings.hooks ?? {}) as Record<string, MatcherEntry[]>;\n\n const postToolUse = hooks.PostToolUse ?? [];\n const hookCommand = target;\n\n const allToolsMatcher = postToolUse.find(\n (entry: MatcherEntry) => entry.matcher === 'Bash|Read|Grep|Glob|WebFetch|WebSearch',\n );\n\n if (allToolsMatcher) {\n const alreadyInstalled = allToolsMatcher.hooks.some(\n (h: HookEntry) => h.command.includes('agenttop-guard'),\n );\n if (alreadyInstalled) {\n process.stdout.write('agenttop hooks already installed\\n');\n return;\n }\n allToolsMatcher.hooks.push({ type: 'command', command: hookCommand });\n } else {\n postToolUse.push({\n matcher: 'Bash|Read|Grep|Glob|WebFetch|WebSearch',\n hooks: [{ type: 'command', command: hookCommand }],\n });\n }\n\n hooks.PostToolUse = postToolUse;\n settings.hooks = hooks;\n writeSettings(settings);\n\n process.stdout.write(`agenttop hooks installed:\\n`);\n process.stdout.write(` hook: ${target}\\n`);\n process.stdout.write(` settings: ${SETTINGS_PATH}\\n`);\n process.stdout.write(` matcher: PostToolUse (Bash|Read|Grep|Glob|WebFetch|WebSearch)\\n`);\n};\n\nexport const uninstallHooks = (): void => {\n const settings = readSettings();\n const hooks = (settings.hooks ?? {}) as Record<string, MatcherEntry[]>;\n const postToolUse = hooks.PostToolUse ?? [];\n\n let removed = false;\n for (const entry of postToolUse) {\n const before = entry.hooks.length;\n entry.hooks = entry.hooks.filter((h: HookEntry) => !h.command.includes('agenttop-guard'));\n if (entry.hooks.length < before) removed = true;\n }\n\n hooks.PostToolUse = postToolUse.filter((e: MatcherEntry) => e.hooks.length > 0);\n settings.hooks = hooks;\n writeSettings(settings);\n\n if (removed) {\n process.stdout.write('agenttop hooks removed from Claude Code settings\\n');\n } else {\n process.stdout.write('agenttop hooks were not installed\\n');\n }\n};\n"],"mappings":"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","names":["React","readdirSync","join","readdirSync","join","openSync","readSync","closeSync","statSync","useState","useEffect","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","formatTime","Box","Text","useState","useEffect","useState","useEffect","useState","useEffect","useState","useEffect","useState","useEffect","useRef","useState","useRef","useEffect","jsx","jsxs","useState","useEffect","Box","Text","readFileSync","join","homedir","React"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/discovery/sessions.ts","../src/config.ts","../src/ingestion/watcher.ts","../src/ingestion/tail.ts","../src/ingestion/parser.ts","../src/discovery/types.ts","../src/analysis/rules/network.ts","../src/analysis/rules/exfiltration.ts","../src/analysis/rules/sensitive-files.ts","../src/analysis/rules/shell-escape.ts","../src/analysis/rules/injection.ts","../src/analysis/security.ts","../src/ui/App.tsx","../src/ui/components/StatusBar.tsx","../src/ui/theme.ts","../src/ui/components/SessionList.tsx","../src/ui/components/ActivityFeed.tsx","../src/ui/components/AlertBar.tsx","../src/ui/hooks/useSessions.ts","../src/ui/hooks/useActivityStream.ts","../src/ui/hooks/useAlerts.ts","../src/hooks/installer.ts"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\n\nimport type { AlertSeverity, CLIOptions, ToolCall, SecurityEvent } from './discovery/types.js';\nimport { discoverSessions } from './discovery/sessions.js';\nimport { Watcher } from './ingestion/watcher.js';\nimport { SecurityEngine } from './analysis/security.js';\nimport { App } from './ui/App.js';\nimport { installHooks, uninstallHooks } from './hooks/installer.js';\n\nconst VERSION = '1.0.0';\n\nconst HELP = `agenttop v${VERSION} -- Real-time dashboard for AI coding agent sessions\n\nUsage: agenttop [options]\n\nOptions:\n --all-users Monitor all users (root only)\n --no-security Disable security analysis\n --json Stream events as JSON (no TUI)\n --alert-level <l> Minimum: info|warn|high|critical (default: warn)\n --install-hooks Install Claude Code PostToolUse hook for active protection\n --uninstall-hooks Remove agenttop hooks from Claude Code\n --version Show version\n --help Show this help\n`;\n\nconst write = (msg: string): void => {\n process.stdout.write(msg + '\\n');\n};\n\nconst parseArgs = (argv: string[]): CLIOptions => {\n const args = argv.slice(2);\n const options: CLIOptions = {\n allUsers: false,\n noSecurity: false,\n json: false,\n alertLevel: 'warn',\n installHooks: false,\n uninstallHooks: false,\n help: false,\n version: false,\n };\n\n for (let i = 0; i < args.length; i++) {\n switch (args[i]) {\n case '--all-users':\n options.allUsers = true;\n break;\n case '--no-security':\n options.noSecurity = true;\n break;\n case '--json':\n options.json = true;\n break;\n case '--alert-level':\n i++;\n if (['info', 'warn', 'high', 'critical'].includes(args[i])) {\n options.alertLevel = args[i] as AlertSeverity;\n }\n break;\n case '--install-hooks':\n options.installHooks = true;\n break;\n case '--uninstall-hooks':\n options.uninstallHooks = true;\n break;\n case '--version':\n options.version = true;\n break;\n case '--help':\n options.help = true;\n break;\n }\n }\n\n return options;\n};\n\nconst runJsonMode = (options: CLIOptions): void => {\n const engine = options.noSecurity ? null : new SecurityEngine(options.alertLevel);\n\n const sessions = discoverSessions(options.allUsers);\n write(JSON.stringify({ type: 'sessions', data: sessions }));\n\n const handler = (calls: ToolCall[]) => {\n for (const call of calls) {\n write(JSON.stringify({ type: 'tool_call', data: call }));\n }\n };\n\n const securityHandler = engine\n ? (events: SecurityEvent[]) => {\n for (const event of events) {\n const alerts = engine.analyzeEvent(event);\n for (const alert of alerts) {\n write(JSON.stringify({ type: 'alert', data: alert }));\n }\n }\n }\n : undefined;\n\n const watcher = new Watcher(handler, options.allUsers, securityHandler);\n watcher.start();\n\n process.on('SIGINT', () => {\n watcher.stop();\n process.exit(0);\n });\n process.on('SIGTERM', () => {\n watcher.stop();\n process.exit(0);\n });\n};\n\nconst main = () => {\n const options = parseArgs(process.argv);\n\n if (options.version) {\n write(`agenttop v${VERSION}`);\n process.exit(0);\n }\n\n if (options.help) {\n write(HELP);\n process.exit(0);\n }\n\n if (options.installHooks) {\n installHooks();\n process.exit(0);\n }\n\n if (options.uninstallHooks) {\n uninstallHooks();\n process.exit(0);\n }\n\n if (options.json) {\n runJsonMode(options);\n return;\n }\n\n render(React.createElement(App, { options }));\n};\n\nmain();\n","import { readdirSync, readFileSync, statSync, readlinkSync, openSync, readSync, closeSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { execSync } from 'node:child_process';\n\nimport { getTaskDirs } from '../config.js';\nimport type { Session, RawEvent, ProcessInfo } from './types.js';\n\nexport const getClaudeProcesses = (): ProcessInfo[] => {\n try {\n const output = execSync('ps aux', { encoding: 'utf-8', timeout: 5000 });\n const procs = output\n .split('\\n')\n .filter((line) => line.includes('/claude') && !line.includes('grep') && !line.includes('agenttop'))\n .map((line) => {\n const parts = line.trim().split(/\\s+/);\n const pid = parseInt(parts[1], 10);\n let cwd = '';\n try {\n cwd = readlinkSync(`/proc/${pid}/cwd`);\n } catch {\n // no access or process gone\n }\n return {\n pid,\n cpu: parseFloat(parts[2]) || 0,\n mem: parseFloat(parts[3]) || 0,\n memKB: parseInt(parts[5], 10) || 0,\n startTime: parts[8] || '',\n command: parts.slice(10).join(' '),\n cwd,\n };\n })\n .filter((p) => !isNaN(p.pid))\n .filter((p) => !p.command.startsWith('sudo'));\n return procs;\n } catch {\n return [];\n }\n};\n\nconst readFirstEvent = (filePath: string): Record<string, unknown> | null => {\n try {\n const fd = openSync(filePath, 'r');\n const buf = Buffer.alloc(16384);\n const bytesRead = readSync(fd, buf, 0, 16384, 0);\n closeSync(fd);\n const line = buf.subarray(0, bytesRead).toString('utf-8').split('\\n')[0];\n if (!line) return null;\n return JSON.parse(line) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\n\nconst findModel = (filePath: string): string => {\n try {\n const fd = openSync(filePath, 'r');\n const buf = Buffer.alloc(65536);\n const bytesRead = readSync(fd, buf, 0, 65536, 0);\n closeSync(fd);\n const text = buf.subarray(0, bytesRead).toString('utf-8');\n const lines = text.split('\\n');\n for (const line of lines) {\n if (!line) continue;\n try {\n const evt = JSON.parse(line);\n if (evt.type === 'assistant' && evt.message?.model) {\n return String(evt.message.model);\n }\n } catch {\n continue;\n }\n }\n } catch {\n // ignore\n }\n return '';\n};\n\nconst normalisePath = (p: string): string => {\n return p.replace(/\\/+$/, '');\n};\n\nexport const discoverSessions = (allUsers: boolean): Session[] => {\n const taskDirs = getTaskDirs(allUsers);\n const processes = getClaudeProcesses();\n const sessionMap = new Map<string, Session>();\n\n for (const taskDir of taskDirs) {\n let projectDirs: string[];\n try {\n projectDirs = readdirSync(taskDir);\n } catch {\n continue;\n }\n\n for (const projectName of projectDirs) {\n const projectPath = join(taskDir, projectName);\n let stat;\n try {\n stat = statSync(projectPath);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n\n const tasksDir = join(projectPath, 'tasks');\n let outputFiles: string[];\n try {\n outputFiles = readdirSync(tasksDir)\n .filter((f) => f.endsWith('.output'))\n .map((f) => join(tasksDir, f));\n } catch {\n continue;\n }\n\n if (outputFiles.length === 0) continue;\n\n const agentIds: string[] = [];\n let sessionId = '';\n let slug = '';\n let cwd = '';\n let model = '';\n let version = '';\n let gitBranch = '';\n let startTime = Infinity;\n let lastActivity = 0;\n\n for (const outputFile of outputFiles) {\n const agentId = basename(outputFile, '.output');\n agentIds.push(agentId);\n\n const firstEvent = readFirstEvent(outputFile);\n if (firstEvent) {\n if (!sessionId) sessionId = String(firstEvent.sessionId || '');\n if (!slug) slug = String(firstEvent.slug || '');\n if (!cwd) cwd = String(firstEvent.cwd || '');\n if (!version) version = String(firstEvent.version || '');\n if (!gitBranch) gitBranch = String(firstEvent.gitBranch || '');\n }\n\n try {\n const fstat = statSync(outputFile);\n const created = fstat.birthtimeMs || fstat.ctimeMs;\n if (created < startTime) startTime = created;\n if (fstat.mtimeMs > lastActivity) lastActivity = fstat.mtimeMs;\n } catch {\n // ignore\n }\n\n if (!model) {\n model = findModel(outputFile);\n }\n }\n\n if (!model) {\n model = 'unknown';\n }\n\n const normCwd = normalisePath(cwd);\n const matchingProcess = processes.find((p) => {\n if (!p.cwd) return false;\n return normalisePath(p.cwd) === normCwd;\n });\n\n const session: Session = {\n sessionId,\n slug: slug || sessionId.slice(0, 12),\n project: projectName.replace(/-/g, '/'),\n cwd,\n model,\n version,\n gitBranch,\n pid: matchingProcess?.pid ?? null,\n cpu: matchingProcess?.cpu ?? 0,\n mem: matchingProcess?.mem ?? 0,\n memMB: matchingProcess ? Math.round(matchingProcess.memKB / 1024) : 0,\n agentCount: agentIds.length,\n agentIds,\n outputFiles,\n startTime: startTime === Infinity ? Date.now() : startTime,\n lastActivity,\n };\n\n sessionMap.set(sessionId || projectName, session);\n }\n }\n\n return Array.from(sessionMap.values()).sort((a, b) => b.lastActivity - a.lastActivity);\n};\n","import { realpathSync, readdirSync } from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { join } from 'node:path';\n\nconst resolvePath = (p: string): string => {\n try {\n return realpathSync(p);\n } catch {\n return p;\n }\n};\n\nexport const getUid = (): number => process.getuid?.() ?? 0;\n\nexport const isRoot = (): boolean => getUid() === 0;\n\nexport const getTmpDir = (): string => resolvePath(platform() === 'darwin' ? '/private/tmp' : '/tmp');\n\nexport const getClaudeHome = (): string => join(homedir(), '.claude');\n\nexport const getHistoryPath = (): string => join(getClaudeHome(), 'history.jsonl');\n\nexport const getTaskDirs = (allUsers: boolean): string[] => {\n const tmp = getTmpDir();\n const uid = getUid();\n\n if (allUsers && isRoot()) {\n try {\n return readdirSync(tmp)\n .filter((d: string) => d.startsWith('claude-'))\n .filter((d: string) => !d.endsWith('-cwd'))\n .map((d: string) => join(tmp, d));\n } catch {\n return [join(tmp, `claude-${uid}`)];\n }\n }\n\n return [join(tmp, `claude-${uid}`)];\n};\n\nexport const getPlatform = (): 'linux' | 'darwin' | 'win32' => {\n const p = platform();\n if (p === 'darwin') return 'darwin';\n if (p === 'win32') return 'win32';\n return 'linux';\n};\n","import { watch } from 'chokidar';\nimport type { FSWatcher } from 'chokidar';\n\nimport { getTaskDirs } from '../config.js';\nimport type { ToolCall, SecurityEvent } from '../discovery/types.js';\nimport { FileTailer } from './tail.js';\nimport { parseLines, parseAllEvents } from './parser.js';\n\nexport type ToolCallHandler = (calls: ToolCall[]) => void;\nexport type SecurityEventHandler = (events: SecurityEvent[]) => void;\n\nexport class Watcher {\n private watcher: FSWatcher | null = null;\n private tailer = new FileTailer();\n private handler: ToolCallHandler;\n private securityHandler: SecurityEventHandler | null;\n private allUsers: boolean;\n private knownFiles = new Set<string>();\n\n constructor(handler: ToolCallHandler, allUsers: boolean, securityHandler?: SecurityEventHandler) {\n this.handler = handler;\n this.allUsers = allUsers;\n this.securityHandler = securityHandler ?? null;\n }\n\n start(): void {\n const taskDirs = getTaskDirs(this.allUsers);\n const globs = taskDirs.map((d) => `${d}/**/tasks/*.output`);\n\n this.watcher = watch(globs, {\n persistent: true,\n ignoreInitial: false,\n awaitWriteFinish: false,\n usePolling: false,\n });\n\n this.watcher.on('add', (filePath: string) => {\n if (this.knownFiles.has(filePath)) return;\n this.knownFiles.add(filePath);\n this.tailer.seekToEnd(filePath);\n });\n\n this.watcher.on('change', (filePath: string) => {\n const lines = this.tailer.readNewLines(filePath);\n if (lines.length === 0) return;\n\n const calls = parseLines(lines);\n if (calls.length > 0) {\n this.handler(calls);\n }\n\n if (this.securityHandler) {\n const allEvents = parseAllEvents(lines);\n if (allEvents.length > 0) {\n this.securityHandler(allEvents);\n }\n }\n });\n }\n\n stop(): void {\n this.watcher?.close();\n this.watcher = null;\n this.tailer.resetAll();\n this.knownFiles.clear();\n }\n\n readExisting(filePath: string): ToolCall[] {\n this.tailer.reset(filePath);\n const lines = this.tailer.readNewLines(filePath);\n return parseLines(lines);\n }\n}\n","import { openSync, readSync, closeSync, statSync } from 'node:fs';\n\nexport class FileTailer {\n private offsets = new Map<string, number>();\n\n readNewLines(filePath: string): string[] {\n let currentSize: number;\n try {\n currentSize = statSync(filePath).size;\n } catch {\n return [];\n }\n\n const lastOffset = this.offsets.get(filePath) ?? 0;\n if (currentSize <= lastOffset) return [];\n\n const bytesToRead = currentSize - lastOffset;\n const buf = Buffer.alloc(bytesToRead);\n\n let fd: number;\n try {\n fd = openSync(filePath, 'r');\n } catch {\n return [];\n }\n\n try {\n readSync(fd, buf, 0, bytesToRead, lastOffset);\n } finally {\n closeSync(fd);\n }\n\n this.offsets.set(filePath, currentSize);\n\n const text = buf.toString('utf-8');\n const lines = text.split('\\n').filter((l) => l.trim().length > 0);\n return lines;\n }\n\n seekToEnd(filePath: string): void {\n try {\n const size = statSync(filePath).size;\n this.offsets.set(filePath, size);\n } catch {\n // file doesn't exist yet\n }\n }\n\n reset(filePath: string): void {\n this.offsets.delete(filePath);\n }\n\n resetAll(): void {\n this.offsets.clear();\n }\n}\n","import type { RawEvent, ToolCall, ToolResult, SecurityEvent } from '../discovery/types.js';\n\nexport const parseLine = (line: string): RawEvent | null => {\n try {\n return JSON.parse(line) as RawEvent;\n } catch {\n return null;\n }\n};\n\nexport const extractToolCalls = (event: RawEvent): ToolCall[] => {\n if (event.type !== 'assistant') return [];\n\n const content = event.message?.content;\n if (!Array.isArray(content)) return [];\n\n const calls: ToolCall[] = [];\n\n for (const block of content) {\n if (\n typeof block === 'object' &&\n block !== null &&\n 'type' in block &&\n (block as Record<string, unknown>).type === 'tool_use'\n ) {\n const toolBlock = block as Record<string, unknown>;\n calls.push({\n sessionId: event.sessionId,\n agentId: event.agentId,\n slug: (event as Record<string, unknown>).slug as string || '',\n timestamp: Date.now(),\n toolName: (toolBlock.name as string) || 'unknown',\n toolInput: (toolBlock.input as Record<string, unknown>) || {},\n cwd: event.cwd,\n });\n }\n }\n\n return calls;\n};\n\nexport const extractToolResults = (event: RawEvent): ToolResult[] => {\n if (event.type !== 'user') return [];\n\n const content = event.message?.content;\n if (!Array.isArray(content)) return [];\n\n const results: ToolResult[] = [];\n\n for (const block of content) {\n if (\n typeof block === 'object' &&\n block !== null &&\n 'type' in block &&\n (block as Record<string, unknown>).type === 'tool_result'\n ) {\n const resultBlock = block as Record<string, unknown>;\n const resultContent = resultBlock.content;\n let text = '';\n if (typeof resultContent === 'string') {\n text = resultContent;\n } else if (Array.isArray(resultContent)) {\n text = resultContent\n .map((c) => (typeof c === 'object' && c !== null ? (c as Record<string, unknown>).text || '' : String(c)))\n .join('\\n');\n }\n\n results.push({\n sessionId: event.sessionId,\n agentId: event.agentId,\n slug: (event as Record<string, unknown>).slug as string || '',\n timestamp: Date.now(),\n toolUseId: String(resultBlock.tool_use_id || ''),\n content: text,\n isError: Boolean(resultBlock.is_error),\n cwd: event.cwd,\n });\n }\n }\n\n return results;\n};\n\nexport const parseLines = (lines: string[]): ToolCall[] => {\n const calls: ToolCall[] = [];\n for (const line of lines) {\n const event = parseLine(line);\n if (event) {\n calls.push(...extractToolCalls(event));\n }\n }\n return calls;\n};\n\nexport const parseAllEvents = (lines: string[]): SecurityEvent[] => {\n const events: SecurityEvent[] = [];\n for (const line of lines) {\n const event = parseLine(line);\n if (event) {\n events.push(...extractToolCalls(event));\n events.push(...extractToolResults(event));\n }\n }\n return events;\n};\n","export interface Session {\n sessionId: string;\n slug: string;\n project: string;\n cwd: string;\n model: string;\n version: string;\n gitBranch: string;\n pid: number | null;\n cpu: number;\n mem: number;\n memMB: number;\n agentCount: number;\n agentIds: string[];\n outputFiles: string[];\n startTime: number;\n lastActivity: number;\n}\n\nexport interface ToolCall {\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp: number;\n toolName: string;\n toolInput: Record<string, unknown>;\n cwd: string;\n}\n\nexport interface ToolResult {\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp: number;\n toolUseId: string;\n content: string;\n isError: boolean;\n cwd: string;\n}\n\nexport type SecurityEvent = ToolCall | ToolResult;\n\nexport const isToolResult = (event: SecurityEvent): event is ToolResult =>\n 'toolUseId' in event;\n\nexport const isToolCall = (event: SecurityEvent): event is ToolCall =>\n 'toolName' in event;\n\nexport interface RawEvent {\n type: 'user' | 'assistant' | 'tool_result';\n sessionId: string;\n agentId: string;\n slug: string;\n timestamp?: number;\n cwd: string;\n version: string;\n gitBranch: string;\n message: {\n role: string;\n content: unknown;\n };\n}\n\nexport type AlertSeverity = 'info' | 'warn' | 'high' | 'critical';\n\nexport interface Alert {\n id: string;\n severity: AlertSeverity;\n rule: string;\n message: string;\n sessionSlug: string;\n sessionId: string;\n event: SecurityEvent;\n timestamp: number;\n}\n\nexport interface ProcessInfo {\n pid: number;\n cpu: number;\n mem: number;\n memKB: number;\n command: string;\n startTime: string;\n cwd: string;\n}\n\nexport interface CLIOptions {\n allUsers: boolean;\n noSecurity: boolean;\n json: boolean;\n alertLevel: AlertSeverity;\n installHooks: boolean;\n uninstallHooks: boolean;\n help: boolean;\n version: boolean;\n}\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst NETWORK_PATTERNS = [\n /\\bcurl\\b/,\n /\\bwget\\b/,\n /\\bfetch\\s*\\(/,\n /\\bnc\\b/,\n /\\bnetcat\\b/,\n /\\bpython3?\\s+-m\\s+http\\.server\\b/,\n /\\bncat\\b/,\n /\\bsocat\\b/,\n /\\btelnet\\b/,\n];\n\nconst LOCALHOST = /\\b(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|\\[::1\\])\\b/;\n\nexport const checkNetwork = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n const matched = NETWORK_PATTERNS.some((p) => p.test(command));\n if (!matched) return null;\n\n const isLocal = LOCALHOST.test(command);\n const severity = isLocal ? 'info' : 'warn';\n\n return {\n id: `net-${call.timestamp}-${call.agentId}`,\n severity,\n rule: 'network',\n message: isLocal\n ? `Network command to localhost: ${command.slice(0, 80)}`\n : `Network command to external target: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst EXFIL_PATTERNS = [\n /base64.*\\|\\s*(curl|wget|nc)/,\n /cat\\s+.*\\|\\s*(curl|wget|nc)/,\n /(tar|zip|gzip).*\\|\\s*(curl|wget|nc)/,\n /\\bcurl\\b.*-d\\s*@/,\n /\\bcurl\\b.*--data-binary/,\n /\\bscp\\b/,\n /\\brsync\\b.*[^/]@/,\n />\\s*\\/dev\\/tcp\\//,\n];\n\nexport const checkExfiltration = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n const matched = EXFIL_PATTERNS.some((p) => p.test(command));\n if (!matched) return null;\n\n return {\n id: `exfil-${call.timestamp}-${call.agentId}`,\n severity: 'high',\n rule: 'exfiltration',\n message: `Potential data exfiltration: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst SENSITIVE_PATTERNS = [\n /\\.env\\b/,\n /\\.env\\.\\w+/,\n /\\.ssh\\//,\n /id_rsa/,\n /id_ed25519/,\n /\\.pem$/,\n /\\.key$/,\n /credentials/i,\n /\\/etc\\/shadow/,\n /\\/etc\\/passwd/,\n /\\.aws\\/credentials/,\n /\\.kube\\/config/,\n /\\.docker\\/config\\.json/,\n /\\.npmrc/,\n /\\.pypirc/,\n /\\.netrc/,\n /secrets?\\.\\w+/i,\n /token\\.\\w+/i,\n];\n\nconst TOOLS_THAT_READ = ['Read', 'Bash', 'Grep', 'Glob'];\n\nexport const checkSensitiveFiles = (call: ToolCall): Alert | null => {\n if (!TOOLS_THAT_READ.includes(call.toolName)) return null;\n\n const inputs = JSON.stringify(call.toolInput);\n const matched = SENSITIVE_PATTERNS.some((p) => p.test(inputs));\n if (!matched) return null;\n\n const target =\n String(call.toolInput.file_path || call.toolInput.command || call.toolInput.pattern || '').slice(0, 60);\n\n return {\n id: `sens-${call.timestamp}-${call.agentId}`,\n severity: 'warn',\n rule: 'sensitive-files',\n message: `Accessing sensitive file: ${target}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n","import type { ToolCall, Alert } from '../../discovery/types.js';\n\nconst SHELL_PATTERNS: Array<{ pattern: RegExp; severity: 'high' | 'critical'; label: string }> = [\n { pattern: /\\beval\\s*[(\"']/, severity: 'high', label: 'eval execution' },\n { pattern: /\\bchmod\\s+777\\b/, severity: 'high', label: 'chmod 777' },\n { pattern: /\\bchmod\\s+\\+s\\b/, severity: 'critical', label: 'setuid chmod' },\n { pattern: /\\bsudo\\b/, severity: 'high', label: 'sudo usage' },\n { pattern: /\\bsu\\s+-?\\s*\\w/, severity: 'high', label: 'su usage' },\n { pattern: />\\s*\\/etc\\//, severity: 'critical', label: 'writing to /etc/' },\n { pattern: />\\s*\\/usr\\//, severity: 'critical', label: 'writing to /usr/' },\n { pattern: /--privileged/, severity: 'critical', label: 'privileged flag' },\n { pattern: /\\brm\\s+-rf\\s+\\/(?!\\w)/, severity: 'critical', label: 'rm -rf /' },\n { pattern: /\\bdd\\s+.*of=\\/dev\\//, severity: 'critical', label: 'dd to device' },\n { pattern: /\\bmkfs\\b/, severity: 'critical', label: 'filesystem format' },\n { pattern: /\\biptables\\b/, severity: 'high', label: 'firewall modification' },\n];\n\nexport const checkShellEscape = (call: ToolCall): Alert | null => {\n if (call.toolName !== 'Bash') return null;\n\n const command = String(call.toolInput.command || '');\n\n for (const rule of SHELL_PATTERNS) {\n if (rule.pattern.test(command)) {\n return {\n id: `shell-${call.timestamp}-${call.agentId}`,\n severity: rule.severity,\n rule: 'shell-escape',\n message: `${rule.label}: ${command.slice(0, 80)}`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n }\n }\n\n return null;\n};\n","import type { ToolCall, ToolResult, Alert, SecurityEvent } from '../../discovery/types.js';\nimport { isToolResult, isToolCall } from '../../discovery/types.js';\n\nconst INJECTION_PATTERNS = [\n /ignore\\s+(all\\s+)?previous\\s+instructions/i,\n /ignore\\s+(all\\s+)?prior\\s+instructions/i,\n /disregard\\s+(all\\s+)?previous/i,\n /you\\s+are\\s+now\\s+/i,\n /new\\s+instructions?\\s*:/i,\n /system\\s*:\\s*you/i,\n /\\bdo\\s+not\\s+follow\\s+(your|the)\\s+(original|previous)/i,\n /override\\s+(your\\s+)?(instructions|rules|guidelines)/i,\n /forget\\s+(your\\s+)?(instructions|rules|guidelines)/i,\n /act\\s+as\\s+(if\\s+)?(you\\s+are|a)\\s+/i,\n /pretend\\s+(you\\s+are|to\\s+be)\\s+/i,\n /\\bAI\\s+assistant\\b.*\\bmust\\b/i,\n /\\bhuman\\s*:\\s*/i,\n /\\bassistant\\s*:\\s*/i,\n /<\\s*system\\s*>/i,\n /\\[\\s*INST\\s*\\]/i,\n /BEGIN\\s+HIDDEN\\s+INSTRUCTIONS/i,\n];\n\nconst ENCODED_PATTERNS = [\n /aWdub3JlIHByZXZpb3Vz/, // base64 \"ignore previous\"\n /&#x[0-9a-f]+;/i, // html hex entities\n /&#\\d+;/, // html decimal entities\n /\\\\u[0-9a-f]{4}/i, // unicode escapes\n];\n\nexport const checkInjection = (event: SecurityEvent): Alert | null => {\n if (isToolCall(event)) {\n return checkToolCallInjection(event);\n }\n if (isToolResult(event)) {\n return checkToolResultInjection(event);\n }\n return null;\n};\n\nconst checkToolCallInjection = (call: ToolCall): Alert | null => {\n const inputs = JSON.stringify(call.toolInput);\n\n const matched = INJECTION_PATTERNS.some((p) => p.test(inputs));\n if (!matched) return null;\n\n return {\n id: `inject-call-${call.timestamp}-${call.agentId}`,\n severity: 'critical',\n rule: 'injection',\n message: `Prompt injection in ${call.toolName} input`,\n sessionSlug: call.slug,\n sessionId: call.sessionId,\n event: call,\n timestamp: call.timestamp,\n };\n};\n\nconst checkToolResultInjection = (result: ToolResult): Alert | null => {\n const content = result.content;\n if (!content || content.length < 10) return null;\n\n const textPatternMatch = INJECTION_PATTERNS.some((p) => p.test(content));\n const encodedMatch = ENCODED_PATTERNS.some((p) => p.test(content));\n\n if (!textPatternMatch && !encodedMatch) return null;\n\n const matchedPattern = INJECTION_PATTERNS.find((p) => p.test(content));\n const snippet = matchedPattern\n ? content.match(matchedPattern)?.[0]?.slice(0, 50) || ''\n : 'encoded pattern';\n\n return {\n id: `inject-result-${result.timestamp}-${result.agentId}`,\n severity: 'critical',\n rule: 'injection-in-result',\n message: `Prompt injection in tool result: \"${snippet}\"`,\n sessionSlug: result.slug,\n sessionId: result.sessionId,\n event: result,\n timestamp: result.timestamp,\n };\n};\n","import type { ToolCall, ToolResult, SecurityEvent, Alert, AlertSeverity } from '../discovery/types.js';\nimport { isToolCall } from '../discovery/types.js';\n\nimport { checkNetwork } from './rules/network.js';\nimport { checkExfiltration } from './rules/exfiltration.js';\nimport { checkSensitiveFiles } from './rules/sensitive-files.js';\nimport { checkShellEscape } from './rules/shell-escape.js';\nimport { checkInjection } from './rules/injection.js';\n\ntype ToolCallRule = (call: ToolCall) => Alert | null;\ntype SecurityEventRule = (event: SecurityEvent) => Alert | null;\n\nconst toolCallRules: ToolCallRule[] = [\n checkNetwork,\n checkExfiltration,\n checkSensitiveFiles,\n checkShellEscape,\n];\n\nconst allEventRules: SecurityEventRule[] = [\n checkInjection,\n];\n\nconst SEVERITY_ORDER: Record<AlertSeverity, number> = {\n info: 0,\n warn: 1,\n high: 2,\n critical: 3,\n};\n\nconst DEDUP_WINDOW_MS = 30_000;\n\nexport class SecurityEngine {\n private recentAlerts = new Map<string, number>();\n private minLevel: AlertSeverity;\n\n constructor(minLevel: AlertSeverity = 'warn') {\n this.minLevel = minLevel;\n }\n\n analyze(call: ToolCall): Alert[] {\n return this.analyzeEvent(call);\n }\n\n analyzeResult(result: ToolResult): Alert[] {\n return this.analyzeEvent(result);\n }\n\n analyzeEvent(event: SecurityEvent): Alert[] {\n const alerts: Alert[] = [];\n\n if (isToolCall(event)) {\n for (const rule of toolCallRules) {\n const alert = rule(event);\n if (alert) alerts.push(alert);\n }\n }\n\n for (const rule of allEventRules) {\n const alert = rule(event);\n if (alert) alerts.push(alert);\n }\n\n return alerts.filter((alert) => {\n if (SEVERITY_ORDER[alert.severity] < SEVERITY_ORDER[this.minLevel]) return false;\n\n const dedupKey = `${alert.rule}-${alert.sessionId}-${alert.message.slice(0, 40)}`;\n const lastSeen = this.recentAlerts.get(dedupKey);\n if (lastSeen && alert.timestamp - lastSeen < DEDUP_WINDOW_MS) return false;\n\n this.recentAlerts.set(dedupKey, alert.timestamp);\n return true;\n });\n }\n\n pruneOldAlerts(): void {\n const cutoff = Date.now() - DEDUP_WINDOW_MS * 2;\n for (const [key, ts] of this.recentAlerts) {\n if (ts < cutoff) this.recentAlerts.delete(key);\n }\n }\n}\n","import React, { useState, useCallback, useEffect } from 'react';\nimport { Box, Text, useApp, useInput, useStdout } from 'ink';\n\nimport type { CLIOptions } from '../discovery/types.js';\nimport { StatusBar } from './components/StatusBar.js';\nimport { SessionList } from './components/SessionList.js';\nimport { ActivityFeed } from './components/ActivityFeed.js';\nimport { AlertBar } from './components/AlertBar.js';\nimport { useSessions } from './hooks/useSessions.js';\nimport { useActivityStream } from './hooks/useActivityStream.js';\nimport { useAlerts } from './hooks/useAlerts.js';\n\ntype Panel = 'sessions' | 'activity';\n\ninterface AppProps {\n options: CLIOptions;\n}\n\nexport const App: React.FC<AppProps> = ({ options }) => {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const termHeight = stdout?.rows ?? 40;\n const [activePanel, setActivePanel] = useState<Panel>('sessions');\n const [activityScroll, setActivityScroll] = useState(0);\n\n const { sessions, selectedSession, selectedIndex, selectNext, selectPrev } = useSessions(options.allUsers);\n const events = useActivityStream(selectedSession, options.allUsers);\n const { alerts } = useAlerts(!options.noSecurity, options.alertLevel, options.allUsers);\n\n const alertHeight = options.noSecurity ? 0 : 6;\n const statusHeight = 3;\n const footerHeight = 1;\n const mainHeight = termHeight - statusHeight - alertHeight - footerHeight;\n const viewportRows = mainHeight - 2;\n const maxScroll = Math.max(0, events.length - viewportRows);\n\n useEffect(() => {\n setActivityScroll(0);\n }, [selectedSession?.sessionId]);\n\n useInput((input, key) => {\n if (input === 'q') {\n exit();\n return;\n }\n\n if (key.tab) {\n setActivePanel((p) => (p === 'sessions' ? 'activity' : 'sessions'));\n return;\n }\n\n if (activePanel === 'sessions') {\n if (input === 'j' || key.downArrow) selectNext();\n if (input === 'k' || key.upArrow) selectPrev();\n }\n\n if (activePanel === 'activity') {\n if (input === 'k' || key.upArrow) {\n setActivityScroll((s) => Math.min(s + 1, maxScroll));\n }\n if (input === 'j' || key.downArrow) {\n setActivityScroll((s) => Math.max(s - 1, 0));\n }\n if (input === 'G' || key.end) {\n setActivityScroll(0);\n }\n if (input === 'g' || key.home) {\n setActivityScroll(maxScroll);\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" height={termHeight}>\n <StatusBar sessionCount={sessions.length} alertCount={alerts.length} />\n\n <Box flexGrow={1} height={mainHeight}>\n <SessionList\n sessions={sessions}\n selectedIndex={selectedIndex}\n focused={activePanel === 'sessions'}\n />\n <ActivityFeed\n events={events}\n sessionSlug={selectedSession?.slug ?? null}\n focused={activePanel === 'activity'}\n height={mainHeight}\n scrollOffset={activityScroll}\n />\n </Box>\n\n {!options.noSecurity && <AlertBar alerts={alerts} />}\n\n <Box paddingX={1}>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">q:quit</Text>\n </Box>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">j/k:nav</Text>\n </Box>\n <Box marginRight={2}>\n <Text color=\"#5C6370\">tab:panel</Text>\n </Box>\n {activePanel === 'activity' && (\n <Box marginRight={2}>\n <Text color=\"#5C6370\">g/G:top/bottom</Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\n\nimport { colors } from '../theme.js';\n\ninterface StatusBarProps {\n sessionCount: number;\n alertCount: number;\n}\n\nexport const StatusBar: React.FC<StatusBarProps> = ({ sessionCount, alertCount }) => {\n const [time, setTime] = useState(new Date());\n\n useEffect(() => {\n const interval = setInterval(() => setTime(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n const timeStr = time.toLocaleTimeString('en-GB', { hour12: false });\n\n return (\n <Box borderStyle=\"single\" borderColor={colors.border} paddingX={1} justifyContent=\"space-between\">\n <Text color={colors.header} bold>\n agenttop v1.0.0\n </Text>\n <Text color={colors.text}>\n {sessionCount} session{sessionCount !== 1 ? 's' : ''}\n </Text>\n {alertCount > 0 && (\n <Text color={colors.error} bold>\n {alertCount} alert{alertCount !== 1 ? 's' : ''}\n </Text>\n )}\n <Text color={colors.muted}>{timeStr}</Text>\n </Box>\n );\n};\n","export const colors = {\n primary: '#61AFEF',\n secondary: '#98C379',\n accent: '#C678DD',\n warning: '#E5C07B',\n error: '#E06C75',\n critical: '#FF0000',\n muted: '#5C6370',\n text: '#ABB2BF',\n bright: '#FFFFFF',\n border: '#3E4451',\n selected: '#2C313A',\n header: '#61AFEF',\n};\n\nexport const severityColors: Record<string, string> = {\n info: colors.muted,\n warn: colors.warning,\n high: colors.error,\n critical: colors.critical,\n};\n\nexport const toolColors: Record<string, string> = {\n Bash: colors.error,\n Read: colors.secondary,\n Write: colors.accent,\n Edit: colors.accent,\n Grep: colors.primary,\n Glob: colors.primary,\n Task: colors.warning,\n WebFetch: colors.warning,\n WebSearch: colors.warning,\n};\n\nexport const getToolColor = (toolName: string): string =>\n toolColors[toolName] || colors.text;\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { Session } from '../../discovery/types.js';\nimport { colors } from '../theme.js';\n\ninterface SessionListProps {\n sessions: Session[];\n selectedIndex: number;\n focused: boolean;\n}\n\nconst formatModel = (model: string): string => {\n if (model.includes('opus')) return 'opus';\n if (model.includes('sonnet')) return 'sonnet';\n if (model.includes('haiku')) return 'haiku';\n return model.slice(0, 8);\n};\n\nconst formatProject = (project: string): string => {\n const parts = project.split('/');\n const last = parts[parts.length - 1] || project;\n return last.length > 18 ? last.slice(0, 17) + '\\u2026' : last;\n};\n\nexport const SessionList: React.FC<SessionListProps> = ({ sessions, selectedIndex, focused }) => {\n return (\n <Box flexDirection=\"column\" width={28} borderStyle=\"single\" borderColor={focused ? colors.primary : colors.border}>\n <Box paddingX={1}>\n <Text color={colors.header} bold>\n SESSIONS\n </Text>\n </Box>\n\n {sessions.length === 0 && (\n <Box paddingX={1} paddingY={1}>\n <Text color={colors.muted} italic>\n No active sessions\n </Text>\n </Box>\n )}\n\n {sessions.map((session, i) => {\n const isSelected = i === selectedIndex;\n const indicator = isSelected ? '>' : ' ';\n\n return (\n <Box key={session.sessionId} flexDirection=\"column\" paddingX={1} paddingY={0}>\n <Text\n color={isSelected ? colors.bright : colors.text}\n bold={isSelected}\n backgroundColor={isSelected ? colors.selected : undefined}\n >\n {indicator} {session.slug}\n </Text>\n <Text color={colors.muted}>\n {' '}{formatProject(session.project)} | {formatModel(session.model)}\n </Text>\n <Text color={colors.muted}>\n {' '}CPU {session.cpu}% | {session.memMB}MB | {session.agentCount} ag\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n};\n","import React, { useState, useEffect, useRef } from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { ToolCall } from '../../discovery/types.js';\nimport { colors, getToolColor } from '../theme.js';\n\ninterface ActivityFeedProps {\n events: ToolCall[];\n sessionSlug: string | null;\n focused: boolean;\n height: number;\n scrollOffset: number;\n}\n\nconst formatTime = (ts: number): string => {\n const d = new Date(ts);\n return d.toLocaleTimeString('en-GB', { hour12: false });\n};\n\nconst summarizeInput = (call: ToolCall): string => {\n const input = call.toolInput;\n\n switch (call.toolName) {\n case 'Bash':\n return String(input.command || '').slice(0, 50);\n case 'Read':\n case 'Write':\n case 'Edit':\n return String(input.file_path || '').split('/').slice(-2).join('/');\n case 'Grep':\n return `pattern=\"${String(input.pattern || '').slice(0, 30)}\"`;\n case 'Glob':\n return String(input.pattern || '').slice(0, 40);\n case 'Task':\n return String(input.description || '').slice(0, 40);\n case 'WebFetch':\n case 'WebSearch':\n return String(input.url || input.query || '').slice(0, 40);\n default:\n return JSON.stringify(input).slice(0, 40);\n }\n};\n\nexport const ActivityFeed: React.FC<ActivityFeedProps> = ({ events, sessionSlug, focused, height, scrollOffset }) => {\n const viewportRows = height - 2;\n const totalEvents = events.length;\n const start = Math.max(0, totalEvents - viewportRows - scrollOffset);\n const end = start + viewportRows;\n const visible = events.slice(start, end);\n\n const isAtBottom = scrollOffset === 0;\n const isAtTop = start === 0;\n const canScroll = totalEvents > viewportRows;\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={focused ? colors.primary : colors.border}\n >\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box>\n <Text color={colors.header} bold>\n ACTIVITY\n </Text>\n {sessionSlug && (\n <Text color={colors.muted}> ({sessionSlug})</Text>\n )}\n </Box>\n {focused && canScroll && !isAtBottom && (\n <Text color={colors.muted}>\n [{totalEvents - end + viewportRows}/{totalEvents}]\n </Text>\n )}\n </Box>\n\n {visible.length === 0 && (\n <Box paddingX={1} paddingY={1}>\n <Text color={colors.muted} italic>\n {sessionSlug ? 'Waiting for activity...' : 'Select a session'}\n </Text>\n </Box>\n )}\n\n {visible.map((event, i) => (\n <Box key={`${event.timestamp}-${i}`} paddingX={1}>\n <Text color={colors.muted}>{formatTime(event.timestamp)} </Text>\n <Text color={getToolColor(event.toolName)} bold>\n {event.toolName.padEnd(8)}\n </Text>\n <Text color={colors.text}> {summarizeInput(event)}</Text>\n </Box>\n ))}\n\n {focused && canScroll && !isAtTop && visible.length > 0 && (\n <Box paddingX={1} justifyContent=\"flex-end\">\n <Text color={colors.muted}>\n {isAtBottom ? '' : 'G:bottom '}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nimport type { Alert } from '../../discovery/types.js';\nimport { colors, severityColors } from '../theme.js';\n\ninterface AlertBarProps {\n alerts: Alert[];\n maxVisible?: number;\n}\n\nconst formatTime = (ts: number): string => {\n const d = new Date(ts);\n return d.toLocaleTimeString('en-GB', { hour12: false });\n};\n\nconst severityIcon: Record<string, string> = {\n info: 'i',\n warn: '!',\n high: '!!',\n critical: '!!!',\n};\n\nexport const AlertBar: React.FC<AlertBarProps> = ({ alerts, maxVisible = 4 }) => {\n const visible = alerts.slice(-maxVisible);\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={alerts.length > 0 ? colors.error : colors.border}\n >\n <Box paddingX={1}>\n <Text color={colors.error} bold>\n ALERTS\n </Text>\n {alerts.length === 0 && (\n <Text color={colors.muted}> (none)</Text>\n )}\n </Box>\n\n {visible.map((alert, i) => (\n <Box key={alert.id || i} paddingX={1}>\n <Text color={severityColors[alert.severity] || colors.text}>\n [{severityIcon[alert.severity] || '?'}]\n </Text>\n <Text color={colors.muted}> {formatTime(alert.timestamp)} </Text>\n <Text color={colors.warning}>{alert.sessionSlug}: </Text>\n <Text color={colors.text}>{alert.message.slice(0, 60)}</Text>\n </Box>\n ))}\n </Box>\n );\n};\n","import { useState, useEffect, useCallback } from 'react';\n\nimport { discoverSessions } from '../../discovery/sessions.js';\nimport type { Session } from '../../discovery/types.js';\n\nexport const useSessions = (allUsers: boolean, pollMs = 5000) => {\n const [sessions, setSessions] = useState<Session[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const refresh = useCallback(() => {\n const found = discoverSessions(allUsers);\n setSessions(found);\n }, [allUsers]);\n\n useEffect(() => {\n refresh();\n const interval = setInterval(refresh, pollMs);\n return () => clearInterval(interval);\n }, [refresh, pollMs]);\n\n const selectedSession = sessions[selectedIndex] ?? null;\n\n const selectNext = useCallback(() => {\n setSelectedIndex((i) => Math.min(i + 1, sessions.length - 1));\n }, [sessions.length]);\n\n const selectPrev = useCallback(() => {\n setSelectedIndex((i) => Math.max(i - 1, 0));\n }, []);\n\n const selectIndex = useCallback((i: number) => {\n setSelectedIndex(i);\n }, []);\n\n return { sessions, selectedSession, selectedIndex, selectNext, selectPrev, selectIndex, refresh };\n};\n","import { useState, useEffect, useRef } from 'react';\n\nimport type { Session, ToolCall } from '../../discovery/types.js';\nimport { Watcher } from '../../ingestion/watcher.js';\n\nconst MAX_EVENTS = 200;\n\nexport const useActivityStream = (session: Session | null, allUsers: boolean) => {\n const [events, setEvents] = useState<ToolCall[]>([]);\n const watcherRef = useRef<Watcher | null>(null);\n\n useEffect(() => {\n setEvents([]);\n\n if (!session) return;\n\n const existingCalls: ToolCall[] = [];\n const tempWatcher = new Watcher(() => {}, allUsers);\n for (const file of session.outputFiles) {\n existingCalls.push(...tempWatcher.readExisting(file));\n }\n setEvents(existingCalls.slice(-MAX_EVENTS));\n\n const handler = (calls: ToolCall[]) => {\n const sessionCalls = calls.filter((c) => c.sessionId === session.sessionId);\n if (sessionCalls.length === 0) return;\n setEvents((prev) => [...prev, ...sessionCalls].slice(-MAX_EVENTS));\n };\n\n const watcher = new Watcher(handler, allUsers);\n watcherRef.current = watcher;\n watcher.start();\n\n return () => {\n watcher.stop();\n watcherRef.current = null;\n };\n }, [session?.sessionId, allUsers]);\n\n return events;\n};\n","import { useState, useEffect, useRef } from 'react';\n\nimport type { Alert, AlertSeverity, SecurityEvent } from '../../discovery/types.js';\nimport { SecurityEngine } from '../../analysis/security.js';\nimport { Watcher } from '../../ingestion/watcher.js';\n\nconst MAX_ALERTS = 100;\n\nexport const useAlerts = (enabled: boolean, alertLevel: AlertSeverity, allUsers: boolean) => {\n const [alerts, setAlerts] = useState<Alert[]>([]);\n const engineRef = useRef(new SecurityEngine(alertLevel));\n const watcherRef = useRef<Watcher | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n\n engineRef.current = new SecurityEngine(alertLevel);\n\n const securityHandler = (events: SecurityEvent[]) => {\n const newAlerts: Alert[] = [];\n for (const event of events) {\n newAlerts.push(...engineRef.current.analyzeEvent(event));\n }\n if (newAlerts.length > 0) {\n setAlerts((prev) => [...prev, ...newAlerts].slice(-MAX_ALERTS));\n }\n };\n\n const watcher = new Watcher(() => {}, allUsers, securityHandler);\n watcherRef.current = watcher;\n watcher.start();\n\n return () => {\n watcher.stop();\n watcherRef.current = null;\n };\n }, [enabled, alertLevel, allUsers]);\n\n const clearAlerts = () => setAlerts([]);\n\n return { alerts, clearAlerts };\n};\n","import { existsSync, readFileSync, writeFileSync, copyFileSync, mkdirSync, chmodSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { fileURLToPath } from 'node:url';\n\nconst HOOK_FILENAME = 'agenttop-guard.py';\nconst SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');\n\nconst getHookSource = (): string => {\n const thisFile = fileURLToPath(import.meta.url);\n const srcHooksDir = join(dirname(thisFile), '..', 'src', 'hooks');\n const distHooksDir = join(dirname(thisFile), 'hooks');\n\n for (const dir of [distHooksDir, srcHooksDir]) {\n const path = join(dir, HOOK_FILENAME);\n if (existsSync(path)) return path;\n }\n\n const npmGlobalPath = join(dirname(thisFile), '..', 'hooks', HOOK_FILENAME);\n if (existsSync(npmGlobalPath)) return npmGlobalPath;\n\n throw new Error(`cannot find ${HOOK_FILENAME} — is agenttop installed correctly?`);\n};\n\nconst getHookTarget = (): string => {\n const claudeHooksDir = join(homedir(), '.claude', 'hooks');\n mkdirSync(claudeHooksDir, { recursive: true });\n return join(claudeHooksDir, HOOK_FILENAME);\n};\n\ninterface HookEntry {\n type: string;\n command: string;\n}\n\ninterface MatcherEntry {\n matcher: string;\n hooks: HookEntry[];\n}\n\nconst readSettings = (): Record<string, unknown> => {\n if (!existsSync(SETTINGS_PATH)) {\n return {};\n }\n try {\n return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));\n } catch {\n return {};\n }\n};\n\nconst writeSettings = (settings: Record<string, unknown>): void => {\n mkdirSync(dirname(SETTINGS_PATH), { recursive: true });\n writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\\n');\n};\n\nexport const installHooks = (): void => {\n const source = getHookSource();\n const target = getHookTarget();\n\n copyFileSync(source, target);\n chmodSync(target, 0o755);\n\n const settings = readSettings();\n const hooks = (settings.hooks ?? {}) as Record<string, MatcherEntry[]>;\n\n const postToolUse = hooks.PostToolUse ?? [];\n const hookCommand = target;\n\n const allToolsMatcher = postToolUse.find(\n (entry: MatcherEntry) => entry.matcher === 'Bash|Read|Grep|Glob|WebFetch|WebSearch',\n );\n\n if (allToolsMatcher) {\n const alreadyInstalled = allToolsMatcher.hooks.some(\n (h: HookEntry) => h.command.includes('agenttop-guard'),\n );\n if (alreadyInstalled) {\n process.stdout.write('agenttop hooks already installed\\n');\n return;\n }\n allToolsMatcher.hooks.push({ type: 'command', command: hookCommand });\n } else {\n postToolUse.push({\n matcher: 'Bash|Read|Grep|Glob|WebFetch|WebSearch',\n hooks: [{ type: 'command', command: hookCommand }],\n });\n }\n\n hooks.PostToolUse = postToolUse;\n settings.hooks = hooks;\n writeSettings(settings);\n\n process.stdout.write(`agenttop hooks installed:\\n`);\n process.stdout.write(` hook: ${target}\\n`);\n process.stdout.write(` settings: ${SETTINGS_PATH}\\n`);\n process.stdout.write(` matcher: PostToolUse (Bash|Read|Grep|Glob|WebFetch|WebSearch)\\n`);\n};\n\nexport const uninstallHooks = (): void => {\n const settings = readSettings();\n const hooks = (settings.hooks ?? {}) as Record<string, MatcherEntry[]>;\n const postToolUse = hooks.PostToolUse ?? [];\n\n let removed = false;\n for (const entry of postToolUse) {\n const before = entry.hooks.length;\n entry.hooks = entry.hooks.filter((h: HookEntry) => !h.command.includes('agenttop-guard'));\n if (entry.hooks.length < before) removed = true;\n }\n\n hooks.PostToolUse = postToolUse.filter((e: MatcherEntry) => e.hooks.length > 0);\n settings.hooks = hooks;\n writeSettings(settings);\n\n if (removed) {\n process.stdout.write('agenttop hooks removed from Claude Code settings\\n');\n } else {\n process.stdout.write('agenttop hooks were not installed\\n');\n }\n};\n"],"mappings":"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","names":["React","readdirSync","join","readdirSync","join","openSync","readSync","closeSync","statSync","useState","useEffect","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","formatTime","Box","Text","useState","useEffect","useState","useEffect","useState","useEffect","useState","useEffect","useState","useEffect","useRef","useState","useRef","useEffect","jsx","jsxs","useState","useEffect","Box","Text","readFileSync","join","homedir","React"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenttop",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Real-time terminal dashboard for monitoring AI coding agent sessions — like htop for agents",
5
5
  "type": "module",
6
6
  "bin": {