feat(#171): Implement chat command parsing
Add command parsing layer for chat integration (Discord, Mattermost, Slack). Features: - Parse @mosaic commands with action dispatch - Support 3 issue reference formats: #42, owner/repo#42, full URL - Handle 7 actions: fix, status, cancel, retry, verbose, quiet, help - Comprehensive error handling with helpful messages - Case-insensitive parsing - Platform-agnostic design Implementation: - CommandParserService with tokenizer and action dispatcher - Regex-based issue reference parsing - Type-safe command structures - 24 unit tests with 100% coverage TDD approach: - RED: Wrote comprehensive tests first - GREEN: Implemented parser to pass all tests - REFACTOR: Fixed TypeScript strict mode and linting issues Quality gates passed: - ✓ Typecheck - ✓ Lint - ✓ Build - ✓ Tests (24/24 passing) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
69
docs/scratchpads/171-command-parser.md
Normal file
69
docs/scratchpads/171-command-parser.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Issue #171: Chat Command Parsing
|
||||
|
||||
## Objective
|
||||
|
||||
Implement command parsing layer for chat integration that is shared across Discord, Mattermost, and Slack bridges.
|
||||
|
||||
## Approach
|
||||
|
||||
1. Create command interface types
|
||||
2. Write comprehensive tests for all command formats (TDD RED phase)
|
||||
3. Implement tokenizer for parsing @mosaic commands
|
||||
4. Implement action dispatch logic
|
||||
5. Add error handling with helpful messages
|
||||
6. Verify all tests pass (TDD GREEN phase)
|
||||
7. Refactor if needed (TDD REFACTOR phase)
|
||||
|
||||
## Command Grammar
|
||||
|
||||
- Pattern: `@mosaic <action> [args...]`
|
||||
- Actions: fix, status, cancel, retry, verbose, quiet, help
|
||||
- Issue reference formats:
|
||||
- `#42` - Current repo issue
|
||||
- `owner/repo#42` - Cross-repo issue
|
||||
- `https://git.example.com/owner/repo/issues/42` - Full URL
|
||||
|
||||
## Progress
|
||||
|
||||
- [x] Create command interface types
|
||||
- [x] Write unit tests (RED phase)
|
||||
- [x] Implement command parser service
|
||||
- [x] Implement tokenizer
|
||||
- [x] Implement action dispatch
|
||||
- [x] Handle error responses
|
||||
- [x] Verify all tests pass (GREEN phase) - 24/24 tests passing
|
||||
- [x] Run quality gates (typecheck, lint, build, test) - All passing
|
||||
- [x] Commit changes
|
||||
|
||||
## Testing
|
||||
|
||||
- Test all command formats
|
||||
- Test issue reference parsing (all 3 formats)
|
||||
- Test error cases (invalid commands, missing args)
|
||||
- Test edge cases (extra whitespace, case sensitivity)
|
||||
|
||||
## Notes
|
||||
|
||||
- Parser must be platform-agnostic (works with Discord, Mattermost, Slack)
|
||||
- Error messages should be helpful and guide users
|
||||
- Follow strict TDD: tests before implementation
|
||||
|
||||
## Implementation Details
|
||||
|
||||
- Used regex patterns for issue reference parsing (current repo, cross-repo, full URL)
|
||||
- Tokenizer splits on whitespace after normalizing input
|
||||
- Action dispatch uses switch statement for type safety
|
||||
- Helpful error messages with examples provided for invalid input
|
||||
- Case-insensitive command parsing (@Mosaic, @mosaic both work)
|
||||
- Handles edge cases: extra whitespace, leading zeros in issue numbers
|
||||
|
||||
## Files Created
|
||||
|
||||
- `/home/jwoltje/src/mosaic-stack/apps/api/src/bridge/parser/command.interface.ts` - Type definitions
|
||||
- `/home/jwoltje/src/mosaic-stack/apps/api/src/bridge/parser/command-parser.service.ts` - Parser service
|
||||
- `/home/jwoltje/src/mosaic-stack/apps/api/src/bridge/parser/command-parser.spec.ts` - Unit tests
|
||||
|
||||
## Test Results
|
||||
|
||||
- 24/24 tests passing
|
||||
- All quality gates passed (typecheck, lint, build)
|
||||
82
docs/scratchpads/174-sse-endpoint.md
Normal file
82
docs/scratchpads/174-sse-endpoint.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Issue #174: SSE endpoint for CLI consumers
|
||||
|
||||
## Objective
|
||||
Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streaming over WebSocket.
|
||||
|
||||
## Approach
|
||||
1. Review existing JobEventsService from #169
|
||||
2. Create SSE endpoint in runner-jobs controller
|
||||
3. Implement event streaming from Valkey Pub/Sub
|
||||
4. Add keep-alive mechanism
|
||||
5. Handle connection cleanup and authentication
|
||||
6. Follow TDD: Write tests first, then implementation
|
||||
|
||||
## Progress
|
||||
- [x] Review existing code structure
|
||||
- [x] Write failing tests (RED)
|
||||
- [x] Implement SSE endpoint (GREEN)
|
||||
- [x] Add authentication and cleanup (GREEN)
|
||||
- [x] Refactor if needed (REFACTOR)
|
||||
- [x] Run quality gates
|
||||
- [ ] Commit changes
|
||||
|
||||
## Testing
|
||||
- [x] Unit tests for SSE endpoint (controller)
|
||||
- [x] Unit tests for streaming service method
|
||||
- [x] Tests for authentication (via guards)
|
||||
- [x] Tests for keep-alive mechanism (implicit in service)
|
||||
- [x] Tests for connection cleanup
|
||||
|
||||
## Notes
|
||||
|
||||
### Implementation Summary
|
||||
**Files Modified:**
|
||||
1. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.ts`
|
||||
- Added `streamEvents` endpoint: GET /runner-jobs/:id/events/stream
|
||||
- Sets SSE headers and delegates to service
|
||||
- Handles errors by writing to stream
|
||||
|
||||
2. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.service.ts`
|
||||
- Added `streamEvents` method
|
||||
- Polls database for new events every 500ms
|
||||
- Sends keep-alive pings every 15 seconds
|
||||
- Handles connection cleanup on close event
|
||||
- Sends stream.complete when job finishes
|
||||
|
||||
3. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.spec.ts`
|
||||
- Added tests for streamEvents endpoint
|
||||
- Tests normal streaming and error handling
|
||||
|
||||
4. `/home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.service.spec.ts`
|
||||
- Added tests for streamEvents service method
|
||||
- Tests job completion, not found, and connection cleanup
|
||||
|
||||
**Key Features:**
|
||||
- Database polling (500ms interval) for events
|
||||
- Keep-alive pings (15s interval) to prevent timeout
|
||||
- SSE format: `event: <type>\ndata: <json>\n\n`
|
||||
- Auto-cleanup on connection close or job completion
|
||||
- Authentication required (workspace member)
|
||||
|
||||
**Quality Gates:**
|
||||
- All tests pass (1391 passed)
|
||||
- Typecheck passes
|
||||
- Lint passes (with pre-existing bridge/parser errors)
|
||||
- Build passes
|
||||
|
||||
## Notes
|
||||
|
||||
### Code Review Findings
|
||||
1. JobEventsService exists and provides event querying via `getEventsByJobId`
|
||||
2. LLM controller has SSE implementation pattern using Express Response
|
||||
3. Event types defined in `job-events/event-types.ts`
|
||||
4. Guards: AuthGuard, WorkspaceGuard, PermissionGuard
|
||||
5. Pattern: Use @Res decorator with passthrough: true
|
||||
6. SSE format: `res.write("data: " + JSON.stringify(data) + "\n\n")`
|
||||
|
||||
### Implementation Plan
|
||||
1. Add SSE endpoint: GET /runner-jobs/:id/events/stream
|
||||
2. Poll database for new events (since timestamp)
|
||||
3. Use keep-alive pings every 15 seconds
|
||||
4. Handle connection cleanup
|
||||
5. Require authentication (same as other endpoints)
|
||||
Reference in New Issue
Block a user