Skip to content

Commit 7365231

Browse files
committed
Add linting, formatting, changelog, badges, and engines field
1 parent 5a5836e commit 7365231

14 files changed

Lines changed: 1444 additions & 70 deletions

‎.eslintrc.json‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"env": { "node": true, "es2022": true },
3+
"extends": "eslint:recommended",
4+
"rules": {
5+
"no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
6+
"no-undef": "error",
7+
"semi": ["error", "always"],
8+
"quotes": ["error", "single", { "avoidEscape": true }],
9+
"comma-dangle": ["error", "always-multiline"],
10+
"no-console": "off"
11+
},
12+
"overrides": [
13+
{
14+
"files": ["test.js"],
15+
"rules": {
16+
"no-empty": "off",
17+
"no-unused-vars": "off"
18+
}
19+
},
20+
{
21+
"files": ["scripts/**/*.mjs"],
22+
"parserOptions": { "sourceType": "module" }
23+
}
24+
]
25+
}

‎.prettierignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
.agent-observability/
3+
*.db
4+
*.db-wal
5+
*.db-shm
6+
.env
7+
.eslintcache

‎.prettierrc‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"printWidth": 100,
6+
"tabWidth": 2
7+
}

‎CHANGELOG.md‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Changelog
2+
3+
## v1.0.7 — 2026-07-24
4+
5+
- Add `mcpName` and `server.json` for MCP Registry publication
6+
7+
## v1.0.6 — 2026-07-23
8+
9+
- Expand npm keywords for better discoverability
10+
- Keyword-rich package description
11+
12+
## v1.0.5 — 2026-07-22
13+
14+
- Fix database path to `~/.agent-observability`
15+
- Add postinstall hook for zero-touch onboarding
16+
17+
## v1.0.4 — 2026-07-21
18+
19+
- Fix `demo --port` flag
20+
- Setup command creates config files for users without a detected agent
21+
22+
## v1.0.3 — 2026-07-20
23+
24+
- Pre-loaded demo session showing a real agent trace
25+
- Auto-open browser on dashboard start
26+
- Polished empty state for no sessions
27+
28+
## v1.0.2 — 2026-07-19
29+
30+
- Zero-friction onboarding with `agent-obs setup`
31+
- Auto-detects opencode, Claude Code, and Cursor
32+
- Configures MCP automatically — no manual editing needed
33+
34+
## v1.0.1 — 2026-07-18
35+
36+
- Automatic self-reporting via MCP server
37+
- Session cleanup for stale sessions (>1 hour idle)
38+
- Claude Code and Cursor integration docs
39+
- Proxy mode deprecated in favor of native MCP self-reporting
40+
41+
## v1.0.0 — 2026-07-17
42+
43+
- First major release
44+
- Self-reporting protocol: start_session, log_tool_call, end_session
45+
- Integration docs for opencode, Claude Code, Cursor
46+
- CLI: `check`, `stats`, `inspect` commands
47+
- 6 MCP tools: start_session, log_tool_call, end_session, get_last_session, check_session, get_session_stats
48+
- Local dashboard at localhost:9400
49+
- SQLite storage in `~/.agent-observability/`

‎README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# agent-observability
22

3+
[![CI](https://github.com/KryptosAI/agent-observability/actions/workflows/ci.yml/badge.svg)](https://github.com/KryptosAI/agent-observability/actions/workflows/ci.yml)
4+
[![npm](https://img.shields.io/npm/v/agent-obs)](https://www.npmjs.com/package/agent-obs)
5+
[![license](https://img.shields.io/npm/l/agent-obs)](./LICENSE)
6+
37
> Open source agent observability — see what your agents did, why they failed, and what it cost. Runs locally. No cloud required.
48
59
## Quick Start

‎cli.js‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ async function main() {
176176
config.mcp['agent-obs'] = {
177177
type: 'local',
178178
command: ['npx', '-y', 'agent-obs@latest', 'server'],
179-
enabled: true
179+
enabled: true,
180180
};
181181
fs.writeFileSync(opencodeJson, JSON.stringify(config, null, 2) + '\n');
182182
actions.push('opencode.json updated (agent-obs MCP server added)');
@@ -211,13 +211,13 @@ async function main() {
211211
const target = mcpJson;
212212
let mcpConfig = {};
213213
if (fs.existsSync(target)) {
214-
try { mcpConfig = JSON.parse(fs.readFileSync(target, 'utf8')); } catch(e) {}
214+
try { mcpConfig = JSON.parse(fs.readFileSync(target, 'utf8')); } catch (_) { /* use empty default */ }
215215
}
216216
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
217217
if (!mcpConfig.mcpServers['agent-obs']) {
218218
mcpConfig.mcpServers['agent-obs'] = {
219219
command: 'npx',
220-
args: ['-y', 'agent-obs@latest', 'server']
220+
args: ['-y', 'agent-obs@latest', 'server'],
221221
};
222222
fs.writeFileSync(target, JSON.stringify(mcpConfig, null, 2) + '\n');
223223
actions.push('.mcp.json created (agent-obs MCP server configured)');
@@ -366,7 +366,7 @@ Never skip log_tool_call — every tool call must be logged.\n`);
366366
if (command === 'demo') {
367367
const portIdx = args.indexOf('--port');
368368
const port = portIdx >= 0 ? parseInt(args[portIdx + 1]) : 9400;
369-
const { seedDemoSession, getSessions } = require('./database');
369+
const { seedDemoSession } = require('./database');
370370
seedDemoSession();
371371
printSummary();
372372
console.log('Demo session loaded — showing a real agent trace');
@@ -383,15 +383,14 @@ Never skip log_tool_call — every tool call must be logged.\n`);
383383
process.exit(1);
384384
}
385385

386-
const { getSession, getToolCalls, getDecisions } = require('./database');
386+
const { getSession, getToolCalls } = require('./database');
387387
const session = getSession(sessionId);
388388
if (!session) {
389389
console.error('Session not found');
390390
process.exit(1);
391391
}
392392

393393
const calls = getToolCalls(session.id);
394-
const decisions = getDecisions(session.id);
395394

396395
console.log(`\n Session: ${session.id}`);
397396
console.log(` Agent: ${session.agent_type}`);

‎database.js‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function initSchema() {
123123
function createSession({ agentType, model, taskDescription }) {
124124
const db = getDb();
125125
const id = uuidv4();
126-
db.prepare(`INSERT INTO sessions (id, agent_type, model, task_description) VALUES (?, ?, ?, ?)`)
126+
db.prepare('INSERT INTO sessions (id, agent_type, model, task_description) VALUES (?, ?, ?, ?)')
127127
.run(id, agentType || 'unknown', model || null, taskDescription || null);
128128
return { id, agentType, model };
129129
}
@@ -243,7 +243,7 @@ function getLatestHealthChecks() {
243243

244244
function getHealthHistory(toolServer, limit = 20) {
245245
return getDb().prepare(
246-
'SELECT * FROM tool_health_checks WHERE tool_server = ? ORDER BY checked_at DESC LIMIT ?'
246+
'SELECT * FROM tool_health_checks WHERE tool_server = ? ORDER BY checked_at DESC LIMIT ?',
247247
).all(toolServer, limit);
248248
}
249249

@@ -256,7 +256,7 @@ function getDashboardStats() {
256256
const failedSessions = db.prepare("SELECT COUNT(*) as c FROM sessions WHERE status IN ('error', 'failed')").get().c;
257257
const totalToolCalls = db.prepare('SELECT COUNT(*) as c FROM tool_calls').get().c;
258258
const avgDuration = db.prepare(
259-
"SELECT AVG((julianday(ended_at) - julianday(started_at)) * 86400) as avg FROM sessions WHERE ended_at IS NOT NULL"
259+
'SELECT AVG((julianday(ended_at) - julianday(started_at)) * 86400) as avg FROM sessions WHERE ended_at IS NOT NULL',
260260
).get().avg || 0;
261261
const totalCost = db.prepare('SELECT SUM(estimated_cost_usd) as c FROM sessions').get().c || 0;
262262
const totalTokens = db.prepare('SELECT SUM(total_tokens) as c FROM sessions').get().c || 0;
@@ -275,7 +275,7 @@ function estimateCost(totalTokens) {
275275
return Math.round((totalTokens / 1000000) * 3 * 10000) / 10000;
276276
}
277277

278-
function computeGrade({ errorCount, totalCalls, durationMs }) {
278+
function computeGrade({ errorCount, totalCalls }) {
279279
if (totalCalls === 0) return { grade: 'N/A', score: 0 };
280280
const errorRate = errorCount / totalCalls;
281281
if (errorRate === 0) return { grade: 'A', score: 95 };
@@ -301,7 +301,7 @@ function closeStaleSessions() {
301301
endSession(s.id, {
302302
status: 'timeout',
303303
errorMessage: 'Auto-closed: no activity for over 1 hour',
304-
grade: grade.grade
304+
grade: grade.grade,
305305
});
306306
}
307307
return stale.length;
@@ -337,9 +337,9 @@ function seedDemoSession() {
337337
{ name: 'Edit', server: 'filesystem', step: 12, status: 'success', duration: 22, input: '{"filePath":"/src/auth.ts","oldString":"console.log(expiry)","newString":""}', output: '{"applied":true}', summary: 'Removed debug console.log from auth.ts' },
338338
];
339339

340-
const insertCall = db.prepare(`INSERT INTO tool_calls (id, session_id, tool_name, tool_server, step_number, input_json, output_json, output_summary, duration_ms, status, error_message, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
341-
const insertDecision = db.prepare(`INSERT INTO decision_points (id, session_id, step_number, chosen_action, rationale, timestamp) VALUES (?, ?, ?, ?, ?, ?)`);
342-
const insertAudit = db.prepare(`INSERT INTO audit_entries (id, session_id, event_type, actor, resource_accessed, outcome, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)`);
340+
const insertCall = db.prepare('INSERT INTO tool_calls (id, session_id, tool_name, tool_server, step_number, input_json, output_json, output_summary, duration_ms, status, error_message, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
341+
const insertDecision = db.prepare('INSERT INTO decision_points (id, session_id, step_number, chosen_action, rationale, timestamp) VALUES (?, ?, ?, ?, ?, ?)');
342+
const insertAudit = db.prepare('INSERT INTO audit_entries (id, session_id, event_type, actor, resource_accessed, outcome, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)');
343343

344344
const tx = db.transaction(() => {
345345
for (const t of tools) {

‎mcp-server.js‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,20 @@ function sendToolResult(id, data) {
120120
});
121121
}
122122

123-
function handleInitialize(id, params) {
123+
function handleInitialize(id, _params) {
124124
log('Received initialize request');
125125
sendResponse(id, {
126126
protocolVersion: '2024-11-05',
127127
serverInfo: SERVER_INFO,
128128
capabilities: CAPABILITIES,
129-
instructions: "After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves.",
129+
instructions: 'After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves.',
130130
});
131131
}
132132

133133
function handleToolsList(id) {
134134
sendResponse(id, {
135135
tools: TOOLS,
136-
instructions: "After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves."
136+
instructions: 'After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves.',
137137
});
138138
}
139139

@@ -282,7 +282,7 @@ function handleToolsCall(id, params) {
282282
const stats = database.getDashboardStats();
283283
const sessions = database.getSessions({ limit: 1000 });
284284
const grades = { A: 0, B: 0, C: 0, D: 0, F: 0 };
285-
sessions.forEach(s => { if (s.grade && grades.hasOwnProperty(s.grade)) grades[s.grade]++; });
285+
sessions.forEach(s => { if (s.grade && Object.hasOwn(grades, s.grade)) grades[s.grade]++; });
286286

287287
sendToolResult(id, {
288288
...stats,

0 commit comments

Comments
 (0)