agent-scope 0.1.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +312 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +134 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/logParser.d.ts +11 -0
  8. package/dist/core/logParser.d.ts.map +1 -0
  9. package/dist/core/logParser.js +103 -0
  10. package/dist/core/logParser.js.map +1 -0
  11. package/dist/core/queueParser.d.ts +11 -0
  12. package/dist/core/queueParser.d.ts.map +1 -0
  13. package/dist/core/queueParser.js +181 -0
  14. package/dist/core/queueParser.js.map +1 -0
  15. package/dist/core/stateEngine.d.ts +6 -0
  16. package/dist/core/stateEngine.d.ts.map +1 -0
  17. package/dist/core/stateEngine.js +150 -0
  18. package/dist/core/stateEngine.js.map +1 -0
  19. package/dist/core/types.d.ts +40 -0
  20. package/dist/core/types.d.ts.map +1 -0
  21. package/dist/core/types.js +2 -0
  22. package/dist/core/types.js.map +1 -0
  23. package/dist/public/404/index.html +1 -0
  24. package/dist/public/404.html +1 -0
  25. package/dist/public/_next/static/chunks/117-373243894bd7fac6.js +2 -0
  26. package/dist/public/_next/static/chunks/app/_not-found/page-4b9eb8aab41bf6df.js +1 -0
  27. package/dist/public/_next/static/chunks/app/layout-c337d9910c024cee.js +1 -0
  28. package/dist/public/_next/static/chunks/app/page-72fc8cefe60ad1d7.js +1 -0
  29. package/dist/public/_next/static/chunks/fd9d1056-9f91b5e418130764.js +1 -0
  30. package/dist/public/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
  31. package/dist/public/_next/static/chunks/main-7be9b0d6fba5e000.js +1 -0
  32. package/dist/public/_next/static/chunks/main-app-feb0e3b0cc6fb4c7.js +1 -0
  33. package/dist/public/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
  34. package/dist/public/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
  35. package/dist/public/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  36. package/dist/public/_next/static/chunks/webpack-8658fdbc42bfbbae.js +1 -0
  37. package/dist/public/_next/static/css/14aedabfb1f06bdb.css +3 -0
  38. package/dist/public/_next/static/uP1Ux3UC4o-JCDXNPB44Y/_buildManifest.js +1 -0
  39. package/dist/public/_next/static/uP1Ux3UC4o-JCDXNPB44Y/_ssgManifest.js +1 -0
  40. package/dist/public/index.html +1 -0
  41. package/dist/public/index.txt +7 -0
  42. package/dist/server/server.d.ts +2 -0
  43. package/dist/server/server.d.ts.map +1 -0
  44. package/dist/server/server.js +104 -0
  45. package/dist/server/server.js.map +1 -0
  46. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-scope contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,312 @@
1
+ # agent-scope
2
+
3
+ > **Deterministic, local, passive execution observer for AI agent workflows**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
7
+ [![Test Coverage](https://img.shields.io/badge/coverage-98.33%25-brightgreen)](https://vitest.dev/)
8
+
9
+ agent-scope is a lightweight, file-based execution observer for AI agent workflows. It provides real-time visibility into task progress, dependencies, and completion status without requiring databases, authentication, or cloud infrastructure.
10
+
11
+ ## Features
12
+
13
+ - 🎯 **Deterministic** - Pure function state computation from files
14
+ - 📁 **File-based** - No database, just markdown + JSONL
15
+ - 👀 **Observer-only** - Passive monitoring, not an agent wrapper
16
+ - 🤖 **Model-agnostic** - Works with any AI agent or framework
17
+ - 📊 **Real-time dashboard** - Track progress, blockers, and failures
18
+ - 🔒 **Local-first** - All data stays on your machine
19
+ - ✅ **Type-safe** - Built with TypeScript in strict mode
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install -g agent-scope
25
+ ```
26
+
27
+ Or use directly with npx:
28
+
29
+ ```bash
30
+ npx agent-scope init
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ### 1. Initialize in your project
36
+
37
+ ```bash
38
+ npx agent-scope init
39
+ ```
40
+
41
+ This creates a `.agent-scope/` directory with:
42
+ - `queue.md` - Task definitions in markdown
43
+ - `execution.log` - JSONL event log
44
+ - `config.json` - Configuration
45
+
46
+ ### 2. Define your task queue
47
+
48
+ Edit `.agent-scope/queue.md`:
49
+
50
+ ```markdown
51
+ # Slice S1
52
+
53
+ ## S1-T1
54
+ Area: Backend
55
+ Depends: -
56
+ Description: Setup database schema
57
+ AC: Tables created and migrations run
58
+
59
+ ## S1-T2
60
+ Area: Backend
61
+ Depends: S1-T1
62
+ Description: Implement user authentication
63
+ AC: Login and registration endpoints working
64
+ ```
65
+
66
+ ### 3. Log task completion
67
+
68
+ Your agent writes to `.agent-scope/execution.log`:
69
+
70
+ ```json
71
+ {"task_id":"S1-T1","status":"DONE","timestamp":"2026-02-16T14:31:22Z","agent":"claude"}
72
+ {"task_id":"S1-T2","status":"FAILED","timestamp":"2026-02-16T14:33:10Z","agent":"claude","meta":{"reason":"timeout"}}
73
+ ```
74
+
75
+ ### 4. Start the dashboard
76
+
77
+ ```bash
78
+ npx agent-scope start
79
+ ```
80
+
81
+ Opens `http://localhost:4317` with live progress visualization.
82
+
83
+ ## Dashboard Features
84
+
85
+ ### Executive Summary
86
+ - Total tasks, done, failed, blocked, ready counts
87
+ - Overall success rate calculation
88
+ - Last updated timestamp
89
+
90
+ ### Slice Progress
91
+ - Visual progress bars per slice
92
+ - Percentage completion tracking
93
+ - Task distribution breakdown
94
+
95
+ ### Task Table
96
+ - Filter by status (READY, BLOCKED, DONE, FAILED)
97
+ - View dependencies and blockers
98
+ - Click any task for full details
99
+
100
+ ### Task Details
101
+ - Acceptance criteria
102
+ - Dependency graph
103
+ - Reverse dependencies (who depends on this)
104
+ - Last event information
105
+
106
+ ## Task Queue Format
107
+
108
+ ### Markdown DSL
109
+
110
+ ```markdown
111
+ # Slice S1
112
+
113
+ ## S1-T1
114
+ Area: <category>
115
+ Depends: - # No dependencies, or comma-separated IDs
116
+ Description: <what to do>
117
+ AC: <acceptance criteria>
118
+ ```
119
+
120
+ ### Validation
121
+
122
+ agent-scope validates:
123
+ - ✅ All required fields present
124
+ - ✅ No duplicate task IDs
125
+ - ✅ No unknown dependencies
126
+ - ✅ No circular dependencies (DFS detection)
127
+
128
+ ## Execution Log Format
129
+
130
+ ### JSONL Schema
131
+
132
+ ```typescript
133
+ {
134
+ "task_id": "S1-T1", // Required: matches task in queue
135
+ "status": "DONE" | "FAILED", // Required: outcome
136
+ "timestamp": "ISO-8601", // Required: when it happened
137
+ "agent": "string", // Required: agent name
138
+ "meta": {...} // Optional: additional context
139
+ }
140
+ ```
141
+
142
+ ### Behavior
143
+
144
+ - Latest event per task wins (by timestamp)
145
+ - Invalid lines collected as warnings
146
+ - Malformed JSON doesn't crash the system
147
+
148
+ ## Architecture
149
+
150
+ ### Core Principles
151
+
152
+ 1. **Deterministic** - Same inputs always produce same output
153
+ 2. **Stateless** - Server recomputes on every request (no cache in v0.1)
154
+ 3. **Error-tolerant** - Collects errors instead of crashing
155
+ 4. **Type-safe** - Strict TypeScript throughout
156
+
157
+ ### Status Computation
158
+
159
+ ```
160
+ For each task:
161
+ if lastEvent.status === FAILED → FAILED
162
+ else if lastEvent.status === DONE → DONE
163
+ else if any dependency.status !== DONE → BLOCKED
164
+ else → READY
165
+ ```
166
+
167
+ Priority: `FAILED > DONE > BLOCKED > READY`
168
+
169
+ ### Tech Stack
170
+
171
+ - **Language**: TypeScript (strict mode)
172
+ - **CLI**: Commander
173
+ - **Server**: Fastify
174
+ - **UI**: Next.js App Router + Tailwind CSS
175
+ - **Testing**: Vitest (98.33% coverage)
176
+
177
+ ## Development
178
+
179
+ ### Setup
180
+
181
+ ```bash
182
+ git clone https://github.com/yourusername/agent-scope.git
183
+ cd agent-scope
184
+ npm install
185
+ cd dashboard && npm install && cd ..
186
+ ```
187
+
188
+ ### Build
189
+
190
+ ```bash
191
+ npm run build # Builds core + dashboard
192
+ npm run build:core # Only TypeScript
193
+ npm run build:dashboard # Only Next.js UI
194
+ ```
195
+
196
+ ### Test
197
+
198
+ ```bash
199
+ npm test # Run tests in watch mode
200
+ npm run test:coverage # Generate coverage report
201
+ ```
202
+
203
+ ### Project Structure
204
+
205
+ ```
206
+ agent-scope/
207
+ ├─ src/
208
+ │ ├─ core/
209
+ │ │ ├─ types.ts # Domain model
210
+ │ │ ├─ queueParser.ts # Markdown parser
211
+ │ │ ├─ logParser.ts # JSONL parser
212
+ │ │ └─ stateEngine.ts # Snapshot computation
213
+ │ ├─ server/
214
+ │ │ └─ server.ts # Fastify API
215
+ │ └─ cli.ts # Commander CLI
216
+ ├─ tests/core/ # Unit tests (62 tests)
217
+ ├─ dashboard/ # Next.js UI
218
+ │ └─ src/
219
+ │ ├─ app/ # App Router pages
220
+ │ └─ components/ # React components
221
+ ├─ dist/ # Build output
222
+ └─ .agent-scope/ # Created by init (gitignored)
223
+ ```
224
+
225
+ ## API Reference
226
+
227
+ ### `GET /snapshot`
228
+
229
+ Returns current system state:
230
+
231
+ ```typescript
232
+ {
233
+ snapshot: Snapshot | null,
234
+ queueErrors: string[], // Fatal queue parse errors
235
+ logErrors: string[], // Non-fatal log warnings
236
+ meta: {
237
+ generatedAt: string, // ISO-8601
238
+ totalTasks: number
239
+ }
240
+ }
241
+ ```
242
+
243
+ ### `GET /health`
244
+
245
+ Health check endpoint:
246
+
247
+ ```json
248
+ {"status": "ok"}
249
+ ```
250
+
251
+ ## Use Cases
252
+
253
+ - **AI Agent Development** - Monitor multi-step agent workflows
254
+ - **Task Automation** - Track long-running automation pipelines
255
+ - **Project Management** - Visualize task dependencies and progress
256
+ - **Testing** - Observe test execution flows
257
+ - **CI/CD Monitoring** - Track deployment task completion
258
+
259
+ ## Non-Goals (v0.1)
260
+
261
+ - ❌ Real-time streaming (manual refresh only)
262
+ - ❌ Agent execution wrapper
263
+ - ❌ Git integration
264
+ - ❌ SaaS/cloud mode
265
+ - ❌ Authentication
266
+ - ❌ Task editing UI
267
+ - ❌ WebSocket updates
268
+
269
+ agent-scope is an **observer**, not an orchestrator. It watches your workflow, it doesn't run it.
270
+
271
+ ## Roadmap
272
+
273
+ ### v0.2 (Planned)
274
+ - Incremental state updates
275
+ - File watching for auto-refresh
276
+ - Export reports (JSON, CSV)
277
+ - Performance optimizations
278
+
279
+ ### v0.3 (Planned)
280
+ - Historical snapshots
281
+ - Time-series progress tracking
282
+ - Multiple project support
283
+ - Search and filters
284
+
285
+ ## Contributing
286
+
287
+ Contributions welcome! Please:
288
+
289
+ 1. Fork the repository
290
+ 2. Create a feature branch (`git checkout -b feature/amazing`)
291
+ 3. Write tests for new functionality
292
+ 4. Ensure `npm test` passes with 95%+ coverage
293
+ 5. Submit a pull request
294
+
295
+ ## License
296
+
297
+ MIT License - see [LICENSE](LICENSE) file for details
298
+
299
+ ## Credits
300
+
301
+ Built with ❤️ by the agent-scope team
302
+
303
+ Powered by:
304
+ - [TypeScript](https://www.typescriptlang.org/)
305
+ - [Fastify](https://www.fastify.io/)
306
+ - [Next.js](https://nextjs.org/)
307
+ - [Commander](https://github.com/tj/commander.js)
308
+ - [Vitest](https://vitest.dev/)
309
+
310
+ ---
311
+
312
+ **Note**: This is v0.1 - a minimal viable product focused on core functionality. Features are intentionally limited to ensure stability and simplicity.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { mkdirSync, writeFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { exec } from 'child_process';
6
+ import { startServer } from './server/server.js';
7
+ const program = new Command();
8
+ program
9
+ .name('agent-scope')
10
+ .description('Deterministic, local, passive execution observer for AI agent workflows')
11
+ .version('0.1.0');
12
+ program
13
+ .command('init')
14
+ .description('Initialize agent-scope in current directory')
15
+ .action(() => {
16
+ const agentScopeDir = join(process.cwd(), '.agent-scope');
17
+ // Create .agent-scope/ directory
18
+ if (existsSync(agentScopeDir)) {
19
+ console.log('⚠️ .agent-scope/ already exists');
20
+ process.exit(1);
21
+ }
22
+ try {
23
+ mkdirSync(agentScopeDir);
24
+ console.log('✓ Created .agent-scope/ folder');
25
+ // Create queue.md template
26
+ const queueTemplate = `# Slice S1
27
+
28
+ ## S1-T1
29
+ Area: Core
30
+ Depends: -
31
+ Description: First task
32
+ AC: Task completed successfully
33
+ `;
34
+ writeFileSync(join(agentScopeDir, 'queue.md'), queueTemplate);
35
+ console.log('✓ Created queue.md template');
36
+ // Create empty execution.log
37
+ writeFileSync(join(agentScopeDir, 'execution.log'), '');
38
+ console.log('✓ Created execution.log');
39
+ // Create config.json
40
+ const config = {
41
+ queueFile: 'queue.md',
42
+ logFile: 'execution.log',
43
+ port: 4317
44
+ };
45
+ writeFileSync(join(agentScopeDir, 'config.json'), JSON.stringify(config, null, 2));
46
+ console.log('✓ Created config.json');
47
+ // Generate Claude.md snippet
48
+ const claudeMdSnippet = `
49
+ # Agent Scope Integration
50
+
51
+ When working on tasks, log your progress to \`.agent-scope/execution.log\`:
52
+
53
+ ## Log Format (JSONL)
54
+
55
+ Each completed task should be logged as a single line:
56
+
57
+ \`\`\`json
58
+ {"task_id":"S1-T1","status":"DONE","timestamp":"2026-02-16T14:31:22Z","agent":"claude"}
59
+ \`\`\`
60
+
61
+ Or for failures:
62
+
63
+ \`\`\`json
64
+ {"task_id":"S1-T2","status":"FAILED","timestamp":"2026-02-16T14:33:10Z","agent":"claude","meta":{"reason":"timeout"}}
65
+ \`\`\`
66
+
67
+ ## Required Fields
68
+
69
+ - \`task_id\`: Task identifier from queue.md (e.g., "S1-T1")
70
+ - \`status\`: Either "DONE" or "FAILED"
71
+ - \`timestamp\`: ISO-8601 timestamp (use \`new Date().toISOString()\`)
72
+ - \`agent\`: Your agent name (e.g., "claude")
73
+ - \`meta\`: (Optional) Additional context
74
+
75
+ Run \`npx agent-scope start\` to view the dashboard.
76
+ `;
77
+ console.log('✓ Ready to use! Add this to your Claude.md:\n');
78
+ console.log(claudeMdSnippet);
79
+ }
80
+ catch (error) {
81
+ console.error('❌ Failed to initialize:', error);
82
+ process.exit(1);
83
+ }
84
+ });
85
+ program
86
+ .command('start')
87
+ .description('Start the agent-scope server and dashboard')
88
+ .action(async () => {
89
+ const agentScopeDir = join(process.cwd(), '.agent-scope');
90
+ // Verify .agent-scope/ exists
91
+ if (!existsSync(agentScopeDir)) {
92
+ console.error('❌ .agent-scope/ not found. Run "agent-scope init" first.');
93
+ process.exit(1);
94
+ }
95
+ // Read config
96
+ const configPath = join(agentScopeDir, 'config.json');
97
+ if (!existsSync(configPath)) {
98
+ console.error('❌ config.json not found in .agent-scope/');
99
+ process.exit(1);
100
+ }
101
+ let config;
102
+ try {
103
+ const configContent = await import('fs').then(fs => fs.promises.readFile(configPath, 'utf-8'));
104
+ config = JSON.parse(configContent);
105
+ }
106
+ catch (error) {
107
+ console.error('❌ Failed to read config.json:', error);
108
+ process.exit(1);
109
+ }
110
+ const port = config.port || 4317;
111
+ const url = `http://localhost:${port}`;
112
+ try {
113
+ // Start server
114
+ await startServer(agentScopeDir, port);
115
+ console.log(`✓ Server running on ${url}`);
116
+ console.log('✓ Opening browser...');
117
+ // Auto-open browser
118
+ const platform = process.platform;
119
+ const openCommand = platform === 'darwin' ? 'open' :
120
+ platform === 'win32' ? 'start' :
121
+ 'xdg-open';
122
+ exec(`${openCommand} ${url}`, (error) => {
123
+ if (error) {
124
+ console.log('Could not auto-open browser. Please visit:', url);
125
+ }
126
+ });
127
+ }
128
+ catch (error) {
129
+ console.error('❌ Failed to start server:', error);
130
+ process.exit(1);
131
+ }
132
+ });
133
+ program.parse();
134
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { LogEvent } from './types.js';
2
+ export interface LogParseResult {
3
+ events: LogEvent[];
4
+ errors: string[];
5
+ }
6
+ /**
7
+ * Parses a JSONL execution log file.
8
+ * Keeps only the latest event per task based on ISO-8601 timestamp comparison.
9
+ */
10
+ export declare function parseLog(content: string): LogParseResult;
11
+ //# sourceMappingURL=logParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logParser.d.ts","sourceRoot":"","sources":["../../src/core/logParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CA4CxD"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Parses a JSONL execution log file.
3
+ * Keeps only the latest event per task based on ISO-8601 timestamp comparison.
4
+ */
5
+ export function parseLog(content) {
6
+ const errors = [];
7
+ const eventsByTask = new Map();
8
+ const lines = content.split('\n');
9
+ for (let i = 0; i < lines.length; i++) {
10
+ const line = lines[i].trim();
11
+ const lineNumber = i + 1;
12
+ // Skip empty lines
13
+ if (!line) {
14
+ continue;
15
+ }
16
+ // Try to parse JSON
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(line);
20
+ }
21
+ catch (error) {
22
+ errors.push(`Line ${lineNumber}: Invalid JSON`);
23
+ continue;
24
+ }
25
+ // Validate schema
26
+ const validation = validateLogEvent(parsed, lineNumber);
27
+ if (validation.errors.length > 0) {
28
+ errors.push(...validation.errors);
29
+ continue;
30
+ }
31
+ const event = validation.event;
32
+ // Keep only latest event per task
33
+ const existing = eventsByTask.get(event.task_id);
34
+ if (!existing || event.timestamp > existing.timestamp) {
35
+ eventsByTask.set(event.task_id, event);
36
+ }
37
+ }
38
+ return {
39
+ events: Array.from(eventsByTask.values()),
40
+ errors
41
+ };
42
+ }
43
+ /**
44
+ * Validates that an object conforms to the LogEvent schema.
45
+ */
46
+ function validateLogEvent(obj, lineNumber) {
47
+ const errors = [];
48
+ if (typeof obj !== 'object' || obj === null) {
49
+ errors.push(`Line ${lineNumber}: Event must be an object`);
50
+ return { event: null, errors };
51
+ }
52
+ const event = obj;
53
+ // Validate task_id
54
+ if (typeof event.task_id !== 'string' || !event.task_id) {
55
+ errors.push(`Line ${lineNumber}: Missing or invalid task_id`);
56
+ }
57
+ // Validate status
58
+ if (event.status !== 'DONE' && event.status !== 'FAILED') {
59
+ errors.push(`Line ${lineNumber}: Invalid status (must be DONE or FAILED)`);
60
+ }
61
+ // Validate timestamp
62
+ if (typeof event.timestamp !== 'string' || !isValidISO8601(event.timestamp)) {
63
+ errors.push(`Line ${lineNumber}: Missing or invalid timestamp (must be ISO-8601)`);
64
+ }
65
+ // Validate agent
66
+ if (typeof event.agent !== 'string' || !event.agent) {
67
+ errors.push(`Line ${lineNumber}: Missing or invalid agent`);
68
+ }
69
+ // Validate meta (optional)
70
+ if (event.meta !== undefined) {
71
+ if (typeof event.meta !== 'object' || event.meta === null || Array.isArray(event.meta)) {
72
+ errors.push(`Line ${lineNumber}: meta must be an object if provided`);
73
+ }
74
+ }
75
+ if (errors.length > 0) {
76
+ return { event: null, errors };
77
+ }
78
+ // At this point, all validations passed, so we can safely construct a LogEvent
79
+ const validEvent = {
80
+ task_id: event.task_id,
81
+ status: event.status,
82
+ timestamp: event.timestamp,
83
+ agent: event.agent,
84
+ ...(event.meta !== undefined && { meta: event.meta })
85
+ };
86
+ return {
87
+ event: validEvent,
88
+ errors: []
89
+ };
90
+ }
91
+ /**
92
+ * Basic ISO-8601 timestamp validation.
93
+ */
94
+ function isValidISO8601(timestamp) {
95
+ // Check basic format and that it can be parsed as a date
96
+ const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z?$/;
97
+ if (!iso8601Regex.test(timestamp)) {
98
+ return false;
99
+ }
100
+ const date = new Date(timestamp);
101
+ return !isNaN(date.getTime());
102
+ }
103
+ //# sourceMappingURL=logParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logParser.js","sourceRoot":"","sources":["../../src/core/logParser.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,mBAAmB;QACnB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,oBAAoB;QACpB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,gBAAgB,CAAC,CAAC;YAChD,SAAS;QACX,CAAC;QAED,kBAAkB;QAClB,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAM,CAAC;QAEhC,kCAAkC;QAClC,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;YACtD,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzC,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAY,EAAE,UAAkB;IACxD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,2BAA2B,CAAC,CAAC;QAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,KAAK,GAAG,GAA8B,CAAC;IAE7C,mBAAmB;IACnB,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,8BAA8B,CAAC,CAAC;IAChE,CAAC;IAED,kBAAkB;IAClB,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,2CAA2C,CAAC,CAAC;IAC7E,CAAC;IAED,qBAAqB;IACrB,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,mDAAmD,CAAC,CAAC;IACrF,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,4BAA4B,CAAC,CAAC;IAC9D,CAAC;IAED,2BAA2B;IAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvF,MAAM,CAAC,IAAI,CAAC,QAAQ,UAAU,sCAAsC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjC,CAAC;IAED,+EAA+E;IAC/E,MAAM,UAAU,GAAa;QAC3B,OAAO,EAAE,KAAK,CAAC,OAAiB;QAChC,MAAM,EAAE,KAAK,CAAC,MAA2B;QACzC,SAAS,EAAE,KAAK,CAAC,SAAmB;QACpC,KAAK,EAAE,KAAK,CAAC,KAAe;QAC5B,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAA+B,EAAE,CAAC;KACjF,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,SAAiB;IACvC,yDAAyD;IACzD,MAAM,YAAY,GAAG,iDAAiD,CAAC;IACvE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Task } from './types.js';
2
+ export interface QueueParseResult {
3
+ tasks: Task[];
4
+ errors: string[];
5
+ }
6
+ /**
7
+ * Parses a markdown queue file into structured tasks.
8
+ * Returns both tasks and any validation errors encountered.
9
+ */
10
+ export declare function parseQueue(content: string): QueueParseResult;
11
+ //# sourceMappingURL=queueParser.d.ts.map
@@ -0,0 +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,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAmH5D"}