agent-scope 0.4.0 → 0.5.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 +49 -2
- package/dist/cli.js +1 -1
- package/dist/core/contextHealth.d.ts +14 -0
- package/dist/core/contextHealth.d.ts.map +1 -0
- package/dist/core/contextHealth.js +46 -0
- package/dist/core/contextHealth.js.map +1 -0
- package/dist/core/insightsEngine.d.ts +4 -0
- package/dist/core/insightsEngine.d.ts.map +1 -0
- package/dist/core/insightsEngine.js +223 -0
- package/dist/core/insightsEngine.js.map +1 -0
- package/dist/core/logParser.js +17 -0
- package/dist/core/logParser.js.map +1 -1
- package/dist/core/qualityTimeline.d.ts +8 -0
- package/dist/core/qualityTimeline.d.ts.map +1 -0
- package/dist/core/qualityTimeline.js +40 -0
- package/dist/core/qualityTimeline.js.map +1 -0
- package/dist/core/queueParser.d.ts +7 -0
- package/dist/core/queueParser.d.ts.map +1 -1
- package/dist/core/queueParser.js +77 -36
- package/dist/core/queueParser.js.map +1 -1
- package/dist/core/todoReader.d.ts.map +1 -1
- package/dist/core/todoReader.js +48 -18
- package/dist/core/todoReader.js.map +1 -1
- package/dist/core/types.d.ts +108 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/worktreeDetector.d.ts +18 -0
- package/dist/core/worktreeDetector.d.ts.map +1 -0
- package/dist/core/worktreeDetector.js +99 -0
- package/dist/core/worktreeDetector.js.map +1 -0
- package/dist/core/worktreeMapper.d.ts +10 -0
- package/dist/core/worktreeMapper.d.ts.map +1 -0
- package/dist/core/worktreeMapper.js +38 -0
- package/dist/core/worktreeMapper.js.map +1 -0
- package/dist/public/404/index.html +1 -1
- package/dist/public/404.html +1 -1
- package/dist/public/__next.__PAGE__.txt +9 -0
- package/dist/public/__next._full.txt +17 -0
- package/dist/public/__next._head.txt +5 -0
- package/dist/public/__next._index.txt +5 -0
- package/dist/public/__next._tree.txt +2 -0
- package/dist/public/_next/static/chunks/4611ba49fa18f0e2.js +1 -0
- package/dist/public/_next/static/chunks/64ee9622541d967c.js +1 -0
- package/dist/public/_next/static/chunks/66f59f4487e89157.js +1 -0
- package/dist/public/_next/static/chunks/9d942f371db80ae5.css +2 -0
- package/dist/public/_next/static/chunks/a6dad97d9634a72d.js.map +1 -0
- package/dist/public/_next/static/chunks/ac8ad6bf034ff528.js +2 -0
- package/dist/public/_next/static/chunks/d1f8ac52f80f9493.js +5 -0
- package/dist/public/_next/static/chunks/turbopack-87039ecabc6befeb.js +4 -0
- package/dist/public/_next/static/u4-iykRCgYzYIvXiFEi6J/_buildManifest.js +42 -0
- package/dist/public/_next/static/u4-iykRCgYzYIvXiFEi6J/_clientMiddlewareManifest.json +1 -0
- package/dist/public/_not-found/__next._full.txt +13 -0
- package/dist/public/_not-found/__next._head.txt +5 -0
- package/dist/public/_not-found/__next._index.txt +5 -0
- package/dist/public/_not-found/__next._not-found.__PAGE__.txt +5 -0
- package/dist/public/_not-found/__next._not-found.txt +4 -0
- package/dist/public/_not-found/__next._tree.txt +2 -0
- package/dist/public/_not-found/index.html +1 -0
- package/dist/public/_not-found/index.txt +13 -0
- package/dist/public/index.html +1 -1
- package/dist/public/index.txt +17 -7
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +117 -4
- package/dist/server/server.js.map +1 -1
- package/dist/server/watcher.d.ts +2 -1
- package/dist/server/watcher.d.ts.map +1 -1
- package/dist/server/watcher.js +33 -17
- package/dist/server/watcher.js.map +1 -1
- package/package.json +1 -1
- package/dist/public/_next/static/chunks/117-c710cb30aa7ed4f8.js +0 -2
- package/dist/public/_next/static/chunks/46-3b308c2fb194eb7d.js +0 -1
- package/dist/public/_next/static/chunks/app/_not-found/page-c8219ab21dbb5ed7.js +0 -1
- package/dist/public/_next/static/chunks/app/layout-c337d9910c024cee.js +0 -1
- package/dist/public/_next/static/chunks/app/page-a23aeddad1c9219d.js +0 -1
- package/dist/public/_next/static/chunks/fd9d1056-9e191f0896c1d560.js +0 -1
- package/dist/public/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/dist/public/_next/static/chunks/main-app-feb0e3b0cc6fb4c7.js +0 -1
- package/dist/public/_next/static/chunks/main-bfc57b0f3d63ff2c.js +0 -1
- package/dist/public/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/dist/public/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/dist/public/_next/static/chunks/webpack-8658fdbc42bfbbae.js +0 -1
- package/dist/public/_next/static/css/e8cdacecda7e3044.css +0 -5
- package/dist/public/_next/static/efnniGzlp_oXwEMyLjbwF/_buildManifest.js +0 -1
- /package/dist/public/_next/static/chunks/{polyfills-42372ed130431b0a.js → a6dad97d9634a72d.js} +0 -0
- /package/dist/public/_next/static/{efnniGzlp_oXwEMyLjbwF → u4-iykRCgYzYIvXiFEi6J}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@ See what your AI agent is actually doing.
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/agent-scope)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](CHANGELOG.md)
|
|
7
8
|
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -124,15 +125,61 @@ Append-only JSONL:
|
|
|
124
125
|
{"task_id":"S1-T3","status":"BLOCKED","reason":"API key missing","timestamp":"2026-02-16T14:35:00Z","agent":"claude"}
|
|
125
126
|
```
|
|
126
127
|
|
|
128
|
+
## New in v0.5.0 — Observability Features
|
|
129
|
+
|
|
130
|
+
### Quality Gates
|
|
131
|
+
|
|
132
|
+
Track lint, typecheck, and test results per task and view them as a timeline in the Plan mode dashboard.
|
|
133
|
+
|
|
134
|
+
Log quality results in `execution.log`:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"task_id": "F1-2",
|
|
139
|
+
"status": "DONE",
|
|
140
|
+
"timestamp": "2026-02-18T12:05:00Z",
|
|
141
|
+
"agent": "claude",
|
|
142
|
+
"meta": {
|
|
143
|
+
"file": "src/core/logParser.ts",
|
|
144
|
+
"quality": { "lint": true, "typecheck": true, "test": false }
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Select any task in Plan mode to see its quality check history with pass/fail badges. → [Quality Gates docs](docs/quality-gates.md)
|
|
150
|
+
|
|
151
|
+
### Context Health
|
|
152
|
+
|
|
153
|
+
See how much of Claude's context window each session is using, with color-coded warnings at 65% (warn) and 75% (critical).
|
|
154
|
+
|
|
155
|
+
- Session cards show a compact `72%` indicator
|
|
156
|
+
- Selected session shows a full progress bar in the token header
|
|
157
|
+
- A header banner appears when any session crosses warn/critical level
|
|
158
|
+
|
|
159
|
+
→ [Context Health docs](docs/context-health.md) | [Estimation methodology](docs/context-estimation.md)
|
|
160
|
+
|
|
161
|
+
### Worktree Observability
|
|
162
|
+
|
|
163
|
+
When running agents across multiple git worktrees in parallel, the new **Worktrees** tab shows:
|
|
164
|
+
|
|
165
|
+
- Branch name and HEAD commit per worktree
|
|
166
|
+
- Dirty/clean status (uncommitted changes)
|
|
167
|
+
- Ahead/behind commits relative to upstream
|
|
168
|
+
- Which agent tasks are running in each worktree
|
|
169
|
+
|
|
170
|
+
→ [Worktree docs](docs/worktrees.md)
|
|
171
|
+
|
|
127
172
|
## API
|
|
128
173
|
|
|
129
174
|
| Endpoint | Description |
|
|
130
175
|
|---|---|
|
|
131
176
|
| `GET /health` | Status + available modes |
|
|
132
|
-
| `GET /sessions` | All Claude Code sessions |
|
|
177
|
+
| `GET /sessions` | All Claude Code sessions (includes `contextHealth`) |
|
|
133
178
|
| `GET /sessions/:id` | Tasks for a session |
|
|
134
179
|
| `GET /events` | SSE stream |
|
|
135
180
|
| `GET /snapshot` | Plan mode state |
|
|
181
|
+
| `GET /quality-timeline` | Quality check events (filter with `?taskId=`) |
|
|
182
|
+
| `GET /worktrees` | Git worktrees with task associations |
|
|
136
183
|
|
|
137
184
|
## Development
|
|
138
185
|
|
|
@@ -142,7 +189,7 @@ cd agent-scope && npm install
|
|
|
142
189
|
cd dashboard && npm install && cd ..
|
|
143
190
|
|
|
144
191
|
npm run build # Build core + dashboard
|
|
145
|
-
npm test #
|
|
192
|
+
npm test # 163 tests
|
|
146
193
|
npm run dev # Dev server with watch
|
|
147
194
|
```
|
|
148
195
|
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ const program = new Command();
|
|
|
8
8
|
program
|
|
9
9
|
.name('agent-scope')
|
|
10
10
|
.description('Deterministic, local, passive execution observer for AI agent workflows')
|
|
11
|
-
.version('0.
|
|
11
|
+
.version('0.5.0');
|
|
12
12
|
program
|
|
13
13
|
.command('init')
|
|
14
14
|
.description('Initialize agent-scope in current directory')
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ClaudeSession, ContextHealth } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Estimates context window usage percentage for a Claude session.
|
|
4
|
+
*
|
|
5
|
+
* Uses inputTokens as the primary proxy for context occupancy (see docs/context-estimation.md).
|
|
6
|
+
* Returns null when token data is unavailable or empty.
|
|
7
|
+
*/
|
|
8
|
+
export declare function estimateContextPercentage(session: ClaudeSession): number | null;
|
|
9
|
+
/**
|
|
10
|
+
* Builds a full ContextHealth object for a session.
|
|
11
|
+
* Returns null when estimation is impossible.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildContextHealth(session: ClaudeSession): ContextHealth | null;
|
|
14
|
+
//# sourceMappingURL=contextHealth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextHealth.d.ts","sourceRoot":"","sources":["../../src/core/contextHealth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAuB,MAAM,YAAY,CAAC;AAgBpF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAQ/E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAa/E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const DEFAULT_MAX_TOKENS = 200_000;
|
|
2
|
+
const WARN_THRESHOLD = 65;
|
|
3
|
+
const CRITICAL_THRESHOLD = 75;
|
|
4
|
+
/**
|
|
5
|
+
* Derives warning level from a 0-100 percentage.
|
|
6
|
+
*/
|
|
7
|
+
function deriveWarningLevel(percentage) {
|
|
8
|
+
if (percentage >= CRITICAL_THRESHOLD)
|
|
9
|
+
return 'critical';
|
|
10
|
+
if (percentage >= WARN_THRESHOLD)
|
|
11
|
+
return 'warn';
|
|
12
|
+
return 'safe';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Estimates context window usage percentage for a Claude session.
|
|
16
|
+
*
|
|
17
|
+
* Uses inputTokens as the primary proxy for context occupancy (see docs/context-estimation.md).
|
|
18
|
+
* Returns null when token data is unavailable or empty.
|
|
19
|
+
*/
|
|
20
|
+
export function estimateContextPercentage(session) {
|
|
21
|
+
if (!session.tokenUsage)
|
|
22
|
+
return null;
|
|
23
|
+
const { inputTokens } = session.tokenUsage;
|
|
24
|
+
if (inputTokens <= 0)
|
|
25
|
+
return null;
|
|
26
|
+
const percentage = Math.min(100, (inputTokens / DEFAULT_MAX_TOKENS) * 100);
|
|
27
|
+
return Math.round(percentage * 10) / 10; // 1 decimal place
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Builds a full ContextHealth object for a session.
|
|
31
|
+
* Returns null when estimation is impossible.
|
|
32
|
+
*/
|
|
33
|
+
export function buildContextHealth(session) {
|
|
34
|
+
const percentage = estimateContextPercentage(session);
|
|
35
|
+
if (percentage === null)
|
|
36
|
+
return null;
|
|
37
|
+
const tokensUsed = session.tokenUsage.inputTokens;
|
|
38
|
+
return {
|
|
39
|
+
percentage,
|
|
40
|
+
warningLevel: deriveWarningLevel(percentage),
|
|
41
|
+
tokensUsed,
|
|
42
|
+
maxTokens: DEFAULT_MAX_TOKENS,
|
|
43
|
+
estimationMethod: 'token-based',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=contextHealth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextHealth.js","sourceRoot":"","sources":["../../src/core/contextHealth.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEnC,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;GAEG;AACH,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,IAAI,UAAU,IAAI,kBAAkB;QAAE,OAAO,UAAU,CAAC;IACxD,IAAI,UAAU,IAAI,cAAc;QAAE,OAAO,MAAM,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAsB;IAC9D,IAAI,CAAC,OAAO,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,GAAG,kBAAkB,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,kBAAkB;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB;IACvD,MAAM,UAAU,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAW,CAAC,WAAW,CAAC;IAEnD,OAAO;QACL,UAAU;QACV,YAAY,EAAE,kBAAkB,CAAC,UAAU,CAAC;QAC5C,UAAU;QACV,SAAS,EAAE,kBAAkB;QAC7B,gBAAgB,EAAE,aAAa;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ComputedTask, LogEvent, ClaudeSession, PlanInsights, LiveInsights } from './types.js';
|
|
2
|
+
export declare function computePlanInsights(tasks: ComputedTask[], events: LogEvent[]): PlanInsights;
|
|
3
|
+
export declare function computeLiveInsights(sessions: ClaudeSession[]): LiveInsights;
|
|
4
|
+
//# sourceMappingURL=insightsEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insightsEngine.d.ts","sourceRoot":"","sources":["../../src/core/insightsEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,MAAM,EAAE,QAAQ,EAAE,GACjB,YAAY,CA8Dd;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,YAAY,CAgE3E"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
export function computePlanInsights(tasks, events) {
|
|
2
|
+
const completedTasks = tasks.filter((t) => t.status === 'DONE').length;
|
|
3
|
+
const failedTasks = tasks.filter((t) => t.status === 'FAILED').length;
|
|
4
|
+
const blockedTasks = tasks.filter((t) => t.status === 'BLOCKED').length;
|
|
5
|
+
const totalTasks = tasks.length;
|
|
6
|
+
const successRate = completedTasks + failedTasks > 0
|
|
7
|
+
? completedTasks / (completedTasks + failedTasks)
|
|
8
|
+
: 0;
|
|
9
|
+
const completionRate = totalTasks > 0 ? completedTasks / totalTasks : 0;
|
|
10
|
+
// Compute timeline
|
|
11
|
+
const timeline = computeTimeline(events);
|
|
12
|
+
// Slice statistics
|
|
13
|
+
const sliceStats = {};
|
|
14
|
+
const sliceMap = new Map();
|
|
15
|
+
for (const task of tasks) {
|
|
16
|
+
if (!sliceMap.has(task.slice)) {
|
|
17
|
+
sliceMap.set(task.slice, []);
|
|
18
|
+
}
|
|
19
|
+
sliceMap.get(task.slice).push(task);
|
|
20
|
+
}
|
|
21
|
+
for (const [sliceName, sliceTasks] of sliceMap) {
|
|
22
|
+
const total = sliceTasks.length;
|
|
23
|
+
const completed = sliceTasks.filter((t) => t.status === 'DONE').length;
|
|
24
|
+
const failed = sliceTasks.filter((t) => t.status === 'FAILED').length;
|
|
25
|
+
const blocked = sliceTasks.filter((t) => t.status === 'BLOCKED').length;
|
|
26
|
+
sliceStats[sliceName] = {
|
|
27
|
+
name: sliceName,
|
|
28
|
+
total,
|
|
29
|
+
completed,
|
|
30
|
+
failed,
|
|
31
|
+
blocked,
|
|
32
|
+
progress: total > 0 ? (completed / total) * 100 : 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Velocity calculation
|
|
36
|
+
const velocity = computeVelocity(events);
|
|
37
|
+
// Bottlenecks: tasks that block the most other tasks
|
|
38
|
+
const bottlenecks = computeBottlenecks(tasks);
|
|
39
|
+
return {
|
|
40
|
+
summary: {
|
|
41
|
+
totalTasks,
|
|
42
|
+
completedTasks,
|
|
43
|
+
failedTasks,
|
|
44
|
+
blockedTasks,
|
|
45
|
+
successRate,
|
|
46
|
+
completionRate,
|
|
47
|
+
},
|
|
48
|
+
timeline,
|
|
49
|
+
sliceStats,
|
|
50
|
+
velocity,
|
|
51
|
+
bottlenecks,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function computeLiveInsights(sessions) {
|
|
55
|
+
const totalSessions = sessions.length;
|
|
56
|
+
const activeSessions = sessions.filter((s) => s.tasks.some((t) => t.status === 'in_progress')).length;
|
|
57
|
+
let totalTasks = 0;
|
|
58
|
+
let completedTasks = 0;
|
|
59
|
+
let inProgressTasks = 0;
|
|
60
|
+
let pendingTasks = 0;
|
|
61
|
+
let totalInputTokens = 0;
|
|
62
|
+
let totalOutputTokens = 0;
|
|
63
|
+
let totalCacheCreation = 0;
|
|
64
|
+
let totalCacheRead = 0;
|
|
65
|
+
for (const session of sessions) {
|
|
66
|
+
totalTasks += session.tasks.length;
|
|
67
|
+
completedTasks += session.tasks.filter((t) => t.status === 'completed').length;
|
|
68
|
+
inProgressTasks += session.tasks.filter((t) => t.status === 'in_progress').length;
|
|
69
|
+
pendingTasks += session.tasks.filter((t) => t.status === 'pending').length;
|
|
70
|
+
if (session.tokenUsage) {
|
|
71
|
+
totalInputTokens += session.tokenUsage.inputTokens;
|
|
72
|
+
totalOutputTokens += session.tokenUsage.outputTokens;
|
|
73
|
+
totalCacheCreation += session.tokenUsage.cacheCreationTokens;
|
|
74
|
+
totalCacheRead += session.tokenUsage.cacheReadTokens;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Timeline for live mode - group by hour
|
|
78
|
+
const timeline = computeLiveTimeline(sessions);
|
|
79
|
+
// Top sessions by task count
|
|
80
|
+
const topSessions = sessions
|
|
81
|
+
.map((s) => ({
|
|
82
|
+
id: s.id,
|
|
83
|
+
taskCount: s.tasks.length,
|
|
84
|
+
completedCount: s.tasks.filter((t) => t.status === 'completed').length,
|
|
85
|
+
projectName: s.projectName,
|
|
86
|
+
lastActivity: s.updatedAt,
|
|
87
|
+
}))
|
|
88
|
+
.sort((a, b) => b.taskCount - a.taskCount)
|
|
89
|
+
.slice(0, 5);
|
|
90
|
+
return {
|
|
91
|
+
summary: {
|
|
92
|
+
totalSessions,
|
|
93
|
+
activeSessions,
|
|
94
|
+
totalTasks,
|
|
95
|
+
completedTasks,
|
|
96
|
+
inProgressTasks,
|
|
97
|
+
pendingTasks,
|
|
98
|
+
},
|
|
99
|
+
timeline,
|
|
100
|
+
tokenUsage: {
|
|
101
|
+
total: totalInputTokens + totalOutputTokens + totalCacheCreation + totalCacheRead,
|
|
102
|
+
input: totalInputTokens,
|
|
103
|
+
output: totalOutputTokens,
|
|
104
|
+
cacheCreation: totalCacheCreation,
|
|
105
|
+
cacheRead: totalCacheRead,
|
|
106
|
+
},
|
|
107
|
+
topSessions,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function computeTimeline(events) {
|
|
111
|
+
if (events.length === 0)
|
|
112
|
+
return [];
|
|
113
|
+
// Group events by day
|
|
114
|
+
const dayMap = new Map();
|
|
115
|
+
for (const event of events) {
|
|
116
|
+
const date = new Date(event.timestamp).toISOString().split('T')[0];
|
|
117
|
+
if (!dayMap.has(date)) {
|
|
118
|
+
dayMap.set(date, { completed: 0, failed: 0 });
|
|
119
|
+
}
|
|
120
|
+
const day = dayMap.get(date);
|
|
121
|
+
if (event.status === 'DONE')
|
|
122
|
+
day.completed++;
|
|
123
|
+
if (event.status === 'FAILED')
|
|
124
|
+
day.failed++;
|
|
125
|
+
}
|
|
126
|
+
// Convert to array and compute cumulative totals
|
|
127
|
+
const sorted = Array.from(dayMap.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
128
|
+
let cumulativeCompleted = 0;
|
|
129
|
+
let cumulativeFailed = 0;
|
|
130
|
+
return sorted.map(([date, counts]) => {
|
|
131
|
+
cumulativeCompleted += counts.completed;
|
|
132
|
+
cumulativeFailed += counts.failed;
|
|
133
|
+
return {
|
|
134
|
+
timestamp: date,
|
|
135
|
+
completed: cumulativeCompleted,
|
|
136
|
+
failed: cumulativeFailed,
|
|
137
|
+
total: cumulativeCompleted + cumulativeFailed,
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function computeLiveTimeline(sessions) {
|
|
142
|
+
if (sessions.length === 0)
|
|
143
|
+
return [];
|
|
144
|
+
// Group by day based on session updatedAt
|
|
145
|
+
const dayMap = new Map();
|
|
146
|
+
for (const session of sessions) {
|
|
147
|
+
const date = new Date(session.updatedAt).toISOString().split('T')[0];
|
|
148
|
+
const completedCount = session.tasks.filter((t) => t.status === 'completed').length;
|
|
149
|
+
if (!dayMap.has(date)) {
|
|
150
|
+
dayMap.set(date, { completed: 0 });
|
|
151
|
+
}
|
|
152
|
+
dayMap.get(date).completed += completedCount;
|
|
153
|
+
}
|
|
154
|
+
const sorted = Array.from(dayMap.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
155
|
+
let cumulative = 0;
|
|
156
|
+
return sorted.map(([date, counts]) => {
|
|
157
|
+
cumulative += counts.completed;
|
|
158
|
+
return {
|
|
159
|
+
timestamp: date,
|
|
160
|
+
completed: cumulative,
|
|
161
|
+
failed: 0,
|
|
162
|
+
total: cumulative,
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function computeVelocity(events) {
|
|
167
|
+
if (events.length === 0) {
|
|
168
|
+
return { tasksPerHour: 0, tasksPerDay: 0, avgTaskDuration: 0 };
|
|
169
|
+
}
|
|
170
|
+
const completedEvents = events.filter((e) => e.status === 'DONE');
|
|
171
|
+
if (completedEvents.length === 0) {
|
|
172
|
+
return { tasksPerHour: 0, tasksPerDay: 0, avgTaskDuration: 0 };
|
|
173
|
+
}
|
|
174
|
+
// Find time range
|
|
175
|
+
const timestamps = completedEvents.map((e) => new Date(e.timestamp).getTime());
|
|
176
|
+
const minTime = Math.min(...timestamps);
|
|
177
|
+
const maxTime = Math.max(...timestamps);
|
|
178
|
+
const totalHours = (maxTime - minTime) / (1000 * 60 * 60);
|
|
179
|
+
const tasksPerHour = totalHours > 0 ? completedEvents.length / totalHours : 0;
|
|
180
|
+
const tasksPerDay = tasksPerHour * 24;
|
|
181
|
+
// Average duration between consecutive tasks
|
|
182
|
+
const sortedTimes = timestamps.sort((a, b) => a - b);
|
|
183
|
+
let totalDuration = 0;
|
|
184
|
+
for (let i = 1; i < sortedTimes.length; i++) {
|
|
185
|
+
totalDuration += sortedTimes[i] - sortedTimes[i - 1];
|
|
186
|
+
}
|
|
187
|
+
const avgTaskDuration = sortedTimes.length > 1
|
|
188
|
+
? totalDuration / (sortedTimes.length - 1) / (1000 * 60)
|
|
189
|
+
: 0;
|
|
190
|
+
return {
|
|
191
|
+
tasksPerHour: Math.round(tasksPerHour * 100) / 100,
|
|
192
|
+
tasksPerDay: Math.round(tasksPerDay * 100) / 100,
|
|
193
|
+
avgTaskDuration: Math.round(avgTaskDuration),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function computeBottlenecks(tasks) {
|
|
197
|
+
// Count how many tasks each task blocks
|
|
198
|
+
const blockCount = new Map();
|
|
199
|
+
for (const task of tasks) {
|
|
200
|
+
if (!blockCount.has(task.id)) {
|
|
201
|
+
blockCount.set(task.id, 0);
|
|
202
|
+
}
|
|
203
|
+
// For each dependency, increment the count
|
|
204
|
+
for (const dep of task.dependsOn) {
|
|
205
|
+
blockCount.set(dep, (blockCount.get(dep) || 0) + 1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Find tasks that block the most
|
|
209
|
+
const bottlenecks = Array.from(blockCount.entries())
|
|
210
|
+
.filter(([_, count]) => count > 0)
|
|
211
|
+
.sort((a, b) => b[1] - a[1])
|
|
212
|
+
.slice(0, 5)
|
|
213
|
+
.map(([taskId, count]) => {
|
|
214
|
+
const task = tasks.find((t) => t.id === taskId);
|
|
215
|
+
return {
|
|
216
|
+
taskId,
|
|
217
|
+
blocksCount: count,
|
|
218
|
+
description: task?.description || 'Unknown task',
|
|
219
|
+
};
|
|
220
|
+
});
|
|
221
|
+
return bottlenecks;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=insightsEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insightsEngine.js","sourceRoot":"","sources":["../../src/core/insightsEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/core/logParser.js
CHANGED
|
@@ -77,6 +77,23 @@ function validateLogEvent(obj, lineNumber) {
|
|
|
77
77
|
if (typeof event.meta !== 'object' || event.meta === null || Array.isArray(event.meta)) {
|
|
78
78
|
errors.push(`Line ${lineNumber}: meta must be an object if provided`);
|
|
79
79
|
}
|
|
80
|
+
else {
|
|
81
|
+
const meta = event.meta;
|
|
82
|
+
// Validate meta.quality if present
|
|
83
|
+
if (meta.quality !== undefined) {
|
|
84
|
+
if (typeof meta.quality !== 'object' || meta.quality === null || Array.isArray(meta.quality)) {
|
|
85
|
+
errors.push(`Line ${lineNumber}: meta.quality must be an object if provided`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const quality = meta.quality;
|
|
89
|
+
for (const key of ['lint', 'typecheck', 'test']) {
|
|
90
|
+
if (quality[key] !== undefined && typeof quality[key] !== 'boolean') {
|
|
91
|
+
errors.push(`Line ${lineNumber}: meta.quality.${key} must be a boolean`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
80
97
|
}
|
|
81
98
|
if (errors.length > 0) {
|
|
82
99
|
return { event: null, errors };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logParser.js","sourceRoot":"","sources":["../../src/core/logParser.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logParser.js","sourceRoot":"","sources":["../../src/core/logParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QualityEvent } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a quality event timeline from JSONL execution log content.
|
|
4
|
+
* Only includes log entries that have a valid meta.quality object.
|
|
5
|
+
* Returns events in chronological order.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseQualityTimeline(logContent: string): QualityEvent[];
|
|
8
|
+
//# sourceMappingURL=qualityTimeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qualityTimeline.d.ts","sourceRoot":"","sources":["../../src/core/qualityTimeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,YAAY,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,EAAE,CAqCvE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { parseLog } from './logParser.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a quality event timeline from JSONL execution log content.
|
|
4
|
+
* Only includes log entries that have a valid meta.quality object.
|
|
5
|
+
* Returns events in chronological order.
|
|
6
|
+
*/
|
|
7
|
+
export function parseQualityTimeline(logContent) {
|
|
8
|
+
const { events } = parseLog(logContent);
|
|
9
|
+
const qualityEvents = [];
|
|
10
|
+
for (const event of events) {
|
|
11
|
+
if (!event.meta || typeof event.meta.quality !== 'object' || event.meta.quality === null || Array.isArray(event.meta.quality)) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const raw = event.meta.quality;
|
|
15
|
+
const checks = {};
|
|
16
|
+
if (typeof raw.lint === 'boolean')
|
|
17
|
+
checks.lint = raw.lint;
|
|
18
|
+
if (typeof raw.typecheck === 'boolean')
|
|
19
|
+
checks.typecheck = raw.typecheck;
|
|
20
|
+
if (typeof raw.test === 'boolean')
|
|
21
|
+
checks.test = raw.test;
|
|
22
|
+
// Only include entries that have at least one quality check result
|
|
23
|
+
if (Object.keys(checks).length === 0) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const file = typeof event.meta.file === 'string' && event.meta.file
|
|
27
|
+
? event.meta.file
|
|
28
|
+
: event.task_id;
|
|
29
|
+
qualityEvents.push({
|
|
30
|
+
timestamp: event.timestamp,
|
|
31
|
+
file,
|
|
32
|
+
checks,
|
|
33
|
+
taskId: event.task_id,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Sort chronologically
|
|
37
|
+
qualityEvents.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
38
|
+
return qualityEvents;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=qualityTimeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qualityTimeline.js","sourceRoot":"","sources":["../../src/core/qualityTimeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,aAAa,GAAmB,EAAE,CAAC;IAEzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9H,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,OAAkC,CAAC;QAC1D,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS;YAAE,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAC1D,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QACzE,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS;YAAE,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAE1D,mEAAmE;QACnE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI;YACjE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI;YACjB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAElB,aAAa,CAAC,IAAI,CAAC;YACjB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,KAAK,CAAC,OAAO;SACtB,CAAC,CAAC;IACL,CAAC;IAED,uBAAuB;IACvB,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAErE,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { Task } from './types.js';
|
|
2
|
+
export interface FieldDefinition {
|
|
3
|
+
name: string;
|
|
4
|
+
type: 'text' | 'enum' | 'refs';
|
|
5
|
+
required: boolean;
|
|
6
|
+
values?: string[];
|
|
7
|
+
}
|
|
2
8
|
export interface QueueParseConfig {
|
|
3
9
|
id?: string;
|
|
4
10
|
headings?: {
|
|
5
11
|
slice?: string;
|
|
6
12
|
task?: string;
|
|
7
13
|
};
|
|
14
|
+
fields?: FieldDefinition[];
|
|
8
15
|
}
|
|
9
16
|
export interface QueueParseResult {
|
|
10
17
|
tasks: Task[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queueParser.d.ts","sourceRoot":"","sources":["../../src/core/queueParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;
|
|
1
|
+
{"version":3,"file":"queueParser.d.ts","sourceRoot":"","sources":["../../src/core/queueParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AA0FD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CA2HvF"}
|