Jason Woltje
8961f5b18c
chore: upgrade Node.js runtime to v24 across codebase
...
ci/woodpecker/push/orchestrator Pipeline was successful
ci/woodpecker/push/api Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
- Update .woodpecker/codex-review.yml: node:22-slim → node:24-slim
- Update packages/cli-tools engines: >=18 → >=24.0.0
- Update README.md, CONTRIBUTING.md, prerequisites docs to reference Node 24+
- Rename eslint.config.js → eslint.config.mjs to eliminate Node 24
MODULE_TYPELESS_PACKAGE_JSON warnings (ESM detection overhead)
- Add .nvmrc targeting Node 24
- Fix pre-existing no-unsafe-return lint error in matrix-room.service.ts
- Add Campsite Rule to CLAUDE.md
- Regenerate Prisma client for Node 24 compatibility
All Dockerfiles and main CI pipelines already used node:24. This commit
aligns the remaining stragglers (codex-review CI, cli-tools engines,
documentation) and resolves Node 24 ESM module detection warnings.
Quality gates: lint ✅ typecheck ✅ tests ✅ (6 pre-existing API failures)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-16 17:33:26 -06:00
8d19ac1f4b
fix( #377 ): remediate code review and security findings
...
ci/woodpecker/push/infra Pipeline was successful
ci/woodpecker/push/api Pipeline failed
- Fix sendThreadMessage room mismatch: use channelId from options instead of hardcoded controlRoomId
- Add .catch() to fire-and-forget handleRoomMessage to prevent silent error swallowing
- Wrap dispatchJob in try-catch for user-visible error reporting in handleFixCommand
- Add MATRIX_BOT_USER_ID validation in connect() to prevent infinite message loops
- Fix streamResponse error masking: wrap finally/catch side-effects in try-catch
- Replace unsafe type assertion with public getClient() in MatrixRoomService
- Add orphaned room warning in provisionRoom on DB failure
- Add provider identity to Herald error logs
- Add channelId to ThreadMessageOptions interface and all callers
- Add missing env var warnings in BridgeModule factory
- Fix JSON injection in setup-bot.sh: use jq for safe JSON construction
Fixes #377
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-15 03:00:53 -06:00
9cc70dbe31
test( #385 ): Matrix bridge integration tests
...
- BridgeModule DI verification (conditional loading)
- Command flow: message -> parser -> dispatch
- Herald multi-provider broadcast
- Room-workspace mapping integration
- Streaming flow verification
- Multi-provider coexistence
Refs #385
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-15 02:39:59 -06:00
93cd31435b
feat( #383 ): Streaming AI responses via Matrix message edits
...
ci/woodpecker/push/api Pipeline failed
- Add MatrixStreamingService with editMessage, setTypingIndicator, streamResponse
- Rate-limited edits (500ms) for incremental streaming output
- Typing indicator management during generation
- Graceful error handling and fallback for non-streaming scenarios
- Add optional editMessage to IChatProvider interface
- Add getClient() accessor to MatrixService for streaming service
- Register MatrixStreamingService in BridgeModule
- Tests: 20 tests pass
Refs #383
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-15 02:34:36 -06:00
ad24720616
feat( #382 ): Herald Service: broadcast to all active chat providers
...
ci/woodpecker/push/api Pipeline failed
- Replace direct DiscordService injection with CHAT_PROVIDERS array
- Herald broadcasts to ALL active chat providers (Discord, Matrix, future)
- Graceful error handling — one provider failure doesn't block others
- Skips disconnected providers automatically
- Tests verify multi-provider broadcasting behavior
- Fix lint: remove unnecessary conditional in matrix.service.ts
Refs #382
2026-02-15 02:25:55 -06:00
771ed484e4
feat( #379 ): Register MatrixService in BridgeModule with conditional loading
...
ci/woodpecker/push/api Pipeline failed
- Add CHAT_PROVIDERS injection token for bridge-agnostic access
- Conditional loading based on env vars (DISCORD_BOT_TOKEN, MATRIX_ACCESS_TOKEN)
- Both bridges can run simultaneously
- No crash if neither bridge is configured
- Tests verify all configuration combinations
Refs #379
2026-02-15 02:18:55 -06:00
7d22c2490a
feat( #380 ): Workspace-to-Matrix-Room mapping and provisioning
...
ci/woodpecker/push/api Pipeline failed
- Add matrix_room_id column to workspace table (migration)
- Create MatrixRoomService for room provisioning and mapping
- Auto-create Matrix room on workspace provisioning (when configured)
- Support manual room linking for existing workspaces
- Unit tests for all mapping operations
Refs #380
2026-02-15 02:16:29 -06:00
5b5d3811d6
feat( #378 ): Install matrix-bot-sdk and create MatrixService skeleton
...
ci/woodpecker/push/api Pipeline failed
ci/woodpecker/push/orchestrator Pipeline failed
ci/woodpecker/push/web Pipeline failed
- Add matrix-bot-sdk dependency to @mosaic/api
- Create MatrixService implementing IChatProvider interface
- Support connect/disconnect, message sending, thread management
- Parse @mosaic and !mosaic command prefixes
- Delegate commands to StitcherService (same flow as Discord)
- Add comprehensive unit tests with mocked MatrixClient (31 tests)
- Add Matrix env vars to .env.example
Refs #378
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-15 02:04:39 -06:00
4552c2c460
fix(test): Add ENCRYPTION_KEY to bridge.module.spec.ts and fix API lint errors
ci/woodpecker/push/woodpecker Pipeline failed
2026-02-07 17:33:32 -06:00
Jason Woltje
12abdfe81d
feat( #93 ): implement agent spawn via federation
...
Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.
Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)
Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification
Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts
Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)
Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed
Refs #93
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2026-02-03 14:37:06 -06:00
Jason Woltje
e3479aeffd
fix( #188 ): sanitize Discord error logs to prevent secret exposure
...
P1 SECURITY FIX - Prevents credential leakage through error logs
Changes:
1. Created comprehensive log sanitization utility (log-sanitizer.ts)
- Detects and redacts API keys, tokens, passwords, emails
- Deep object traversal with circular reference detection
- Preserves Error objects and non-sensitive data
- Performance optimized (<100ms for 1000+ keys)
2. Integrated sanitizer into Discord service error logging
- All error logs automatically sanitized before Discord broadcast
- Prevents bot tokens, API keys, passwords from being exposed
3. Comprehensive test suite (32 tests, 100% passing)
- Tests all sensitive pattern detection
- Verifies deep object sanitization
- Validates performance requirements
Security Patterns Redacted:
- API keys (sk_live_*, pk_test_*)
- Bearer tokens and JWT tokens
- Discord bot tokens
- Authorization headers
- Database credentials
- Email addresses
- Environment secrets
- Generic password patterns
Test Coverage: 97.43% (exceeds 85% requirement)
Fixes #188
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2026-02-02 12:24:29 -06:00
Jason Woltje
cc6a5edfdf
fix( #183 ): remove hardcoded workspace ID from Discord service
...
Remove critical security vulnerability where Discord service used hardcoded
"default-workspace" ID, bypassing Row-Level Security policies and creating
potential for cross-tenant data leakage.
Changes:
- Add DISCORD_WORKSPACE_ID environment variable requirement
- Add validation in connect() to require workspace configuration
- Replace hardcoded workspace ID with configured value
- Add 3 new tests for workspace configuration
- Update .env.example with security documentation
Security Impact:
- Multi-tenant isolation now properly enforced
- Each Discord bot instance must be configured for specific workspace
- Service fails fast if workspace ID not configured
Breaking Change:
- Existing deployments must set DISCORD_WORKSPACE_ID environment variable
Tests: All 21 Discord service tests passing (100%)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2026-02-02 11:41:38 -06:00
e689a1379c
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 >
2026-02-01 21:32:53 -06:00
4ac21d1a3a
feat( #170 ): Implement mosaic-bridge module for Discord
...
Created the mosaic-bridge module to enable Discord integration for
chat-based control of Mosaic Stack. This module provides the foundation
for receiving commands via Discord and forwarding them to the stitcher
for job orchestration.
Key Features:
- Discord bot connection and authentication
- Command parsing (@mosaic fix, status, cancel, verbose, quiet, help)
- Thread management for job updates
- Chat provider interface for future platform extensibility
- Noise management (low/medium/high verbosity levels)
Implementation Details:
- Created IChatProvider interface for platform abstraction
- Implemented DiscordService with Discord.js
- Basic command parsing (detailed parsing in #171 )
- Thread creation for job-specific updates
- Configuration via environment variables
Commands Supported:
- @mosaic fix <issue> - Start job for issue
- @mosaic status <job> - Get job status (placeholder)
- @mosaic cancel <job> - Cancel running job (placeholder)
- @mosaic verbose <job> - Stream full logs (placeholder)
- @mosaic quiet - Reduce notifications (placeholder)
- @mosaic help - Show available commands
Testing:
- 23/23 tests passing (TDD approach)
- Unit tests for Discord service
- Module integration tests
- 100% coverage of critical paths
Quality Gates:
- Typecheck: PASSED
- Lint: PASSED
- Build: PASSED
- Tests: PASSED (23/23)
Environment Variables:
- DISCORD_BOT_TOKEN - Bot authentication token
- DISCORD_GUILD_ID - Server/Guild ID (optional)
- DISCORD_CONTROL_CHANNEL_ID - Channel for commands
Files Created:
- apps/api/src/bridge/bridge.module.ts
- apps/api/src/bridge/discord/discord.service.ts
- apps/api/src/bridge/interfaces/chat-provider.interface.ts
- apps/api/src/bridge/index.ts
- Full test coverage
Dependencies Added:
- discord.js@latest
Next Steps:
- Issue #171 : Implement detailed command parsing
- Issue #172 : Add Herald integration for job updates
- Future: Add Slack, Matrix support via IChatProvider
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-01 21:26:40 -06:00