Commit graph

729 commits

Author SHA1 Message Date
Nexus Dev
a01c28dff2 feat: Phase 40 — Job Infrastructure (content jobs, SSE events, namespaced storage) 2026-04-05 09:55:08 +00:00
Nexus Dev
f85cab192a [nexus] fix: resolve rebase artifacts — duplicate function, missing import, stale SDK types 2026-04-04 03:58:39 +00:00
Nexus Dev
25e3eda0b9 feat(39-02): voice capability probe in hardware service
- Add VoiceCapability interface with whisperAvailable, piperAvailable, voiceTierSufficient
- Extend HardwareInfo with voiceCapability field
- Add detectVoiceCapability() probing whisper-cpp/whisper and piper with 2s timeout each
- voiceTierSufficient: true for apple_silicon/gpu, or cpu_only with >= 4GB free RAM
- Wrap voice probe in 3s timeout to avoid slowing hardware detection
- Route automatically includes voiceCapability via existing HardwareInfo return
2026-04-04 03:55:50 +00:00
Nexus Dev
0f46d9b3bd test(39-02): add failing tests for voice capability detection 2026-04-04 03:55:50 +00:00
Nexus Dev
22beb245f2 feat(39-01): sentence-buffered TTS streaming + multi-language synthesis
- Export splitSentences() with title-abbreviation protection (Dr., Mr. etc.)
- Add synthesizeSentenceStream() AsyncGenerator yielding per-sentence audio chunks
- Add synthesizeMultiLang() synthesizing same text in N voices via Promise.all
- Add POST /api/synthesize/stream SSE endpoint with base64 audio per sentence
- Add POST /api/synthesize/multi-lang returning array of voiceId+audio pairs
- Existing POST /api/synthesize unchanged (backward compatible)
2026-04-04 03:55:50 +00:00
Nexus Dev
6be251a9fb test(39-01): add failing tests for sentence streaming and multi-lang synthesis 2026-04-04 03:55:50 +00:00
Nexus Dev
6435ccb1c4 feat(38-02): add voice message handling + TTS reply to Telegram bridge
- Refactor text relay into shared relayToAgent() used by both text/voice handlers
- Add bot.on('message:voice') handler: send 'Transcribing...' immediately, process async
- Download OGG from Telegram CDN via ctx.getFile() + fetch, transcribe via voicePipelineService
- Synthesize agent responses to OGG Opus via transcodeToOggOpus() and ctx.replyWithVoice()
- TTS failure degrades gracefully (text reply already sent, voice is bonus)
- telegram.ts stays at 322 lines (under 500-line TGRAM-06 constraint)
2026-04-04 03:55:50 +00:00
Nexus Dev
34bfbe06e1 feat(38-01): wire telegramService + telegramRoutes into app.ts
- Import telegramService, telegramRoutes, nexusSettingsService
- Mount /telegram routes under /api prefix
- Conditionally start Telegram bot on boot if telegramToken is configured
- Token route restarts bot after saving new token
2026-04-04 03:55:50 +00:00
Nexus Dev
69269fea14 feat(38-01): install grammY, create telegramService + telegramRoutes
- Install grammy v2 for long polling Telegram bot
- telegramService: text relay handler, agent prefix, session map, deleteWebhook lifecycle
- telegramRoutes: POST /telegram/token (getMe validation), GET /telegram/status
- telegram.ts under 500 lines (187 lines)
2026-04-04 03:55:50 +00:00
Nexus Dev
c42a64b7a2 feat(37-01): add COOP/COEP headers to Express server for SharedArrayBuffer support
- Add Cross-Origin-Opener-Policy: same-origin middleware before all routes
- Add Cross-Origin-Embedder-Policy: require-corp middleware before all routes
- Required for @ricky0123/vad-react (VAD uses SharedArrayBuffer internally)
2026-04-04 03:55:50 +00:00
Nexus Dev
b204d6318e fix(36): resolve TypeScript errors in voice-pipeline.ts (ffmpegPath cast, callback types) 2026-04-04 03:55:50 +00:00
Nexus Dev
f23c4218aa feat(36-03): wire voiceMode through chat stream, mount voice routes, remove old transcribe
- server/src/routes/chat.ts: destructure voiceMode from req.body in stream endpoint
- server/src/routes/chat.ts: inject dual-output system prompt when voiceMode=full_voice (VPIPE-06)
- server/src/routes/chat.ts: persist voiceMode to messageType column (voice_full/voice_input)
- server/src/routes/chat-files.ts: remove old inline /transcribe endpoint (lines 297-386)
- server/src/app.ts: import and mount voiceRoutes() after nexusSettingsRoutes()
2026-04-04 03:55:50 +00:00
Nexus Dev
bf757509ef feat(36-03): add voice HTTP routes with POST /transcribe and POST /synthesize
- Create server/src/routes/voice.ts with voiceRoutes() factory
- POST /transcribe: multer audio upload → VoicePipelineService.transcribe → JSON response
- POST /synthesize: text body → VoicePipelineService.synthesize → audio/wav response
- Both routes protected by assertBoard(req) auth check
- Create server/src/__tests__/36-voice-routes.test.ts with 5 passing tests
2026-04-04 03:55:50 +00:00
Nexus Dev
9fcf27fed9 feat(36-02): extend nexus-settings schema with voiceMode, telegramToken, and binary paths
- Export VOICE_MODES constant and VoiceMode type from nexus-settings
- Export nexusSettingsSchema for testing
- Add voiceMode field with default 'text' to nexusSettingsSchema
- Add telegramToken optional field to nexusSettingsSchema
- Add piperBinaryPath and whisperBinaryPath optional fields
- Update fallback in get() to use nexusSettingsSchema.parse({}) for consistent defaults
- Add 5 passing tests for nexus-settings schema in 36-voice-schema.test.ts
2026-04-04 03:55:50 +00:00
Nexus Dev
8e564e8125 feat(36-02): add voiceMode field to createMessageSchema and ChatMessage interface
- Add VOICE_MODES constant and VoiceMode type to shared validators/chat.ts
- Extend createMessageSchema with optional voiceMode enum field
- Add voiceMode optional field to ChatMessage interface in types/chat.ts
- Add 36-voice-schema.test.ts with 6 passing tests for voiceMode validation
2026-04-04 03:55:50 +00:00
Nexus Dev
346b42dd73 feat(36-01): VoicePipelineService with transcribe, synthesize, formatForVoice, transcodeToWav16k
- Install ffmpeg-static and @types/ffmpeg-static
- Create voice-pipeline.ts with voicePipelineService factory function
- transcodeToWav16k: pipes audio through ffmpeg at 16kHz mono WAV
- transcribe: whisper-cpp cascade with --language auto, falls back to openai-whisper
- synthesize: piper TTS with sentence chunking and 8s timeout via Promise.race
- formatForVoice: extracts SPOKEN marker or strips markdown as fallback
- Unit tests with mocked child_process (12 tests all passing)
2026-04-04 03:55:50 +00:00
Nexus Dev
5ad8e2bee8 feat(36-02): extend nexus-settings schema with voiceMode, telegramToken, and binary paths
- Export VOICE_MODES constant and VoiceMode type from nexus-settings
- Export nexusSettingsSchema for testing
- Add voiceMode field with default 'text' to nexusSettingsSchema
- Add telegramToken optional field to nexusSettingsSchema
- Add piperBinaryPath and whisperBinaryPath optional fields
- Update fallback in get() to use nexusSettingsSchema.parse({}) for consistent defaults
- Add 5 passing tests for nexus-settings schema in 36-voice-schema.test.ts
2026-04-04 03:55:50 +00:00
Nexus Dev
14e059862b feat(36-02): add voiceMode field to createMessageSchema and ChatMessage interface
- Add VOICE_MODES constant and VoiceMode type to shared validators/chat.ts
- Extend createMessageSchema with optional voiceMode enum field
- Add voiceMode optional field to ChatMessage interface in types/chat.ts
- Add 36-voice-schema.test.ts with 6 passing tests for voiceMode validation
2026-04-04 03:55:49 +00:00
Nexus Dev
36746ed17b feat(34-01): register chatFileRoutes + nexusSettingsRoutes in app.ts, add voiceEnabled to nexus-settings
- Add chatFileRoutes(db, storageService) after assistantHandoffRoutes (inside boardMutationGuard)
- Add nexusSettingsRoutes() after chatFileRoutes
- Extend nexusSettingsSchema with voiceEnabled: z.boolean().default(false)
- Update default return values in nexusSettingsService.get() to include voiceEnabled: false
- Add voiceEnabled?: boolean to NexusSettings client interface in hardware.ts
2026-04-04 03:55:49 +00:00
Nexus Dev
222d00c57f feat(33-03): real AI streaming with memory injection + assistant handoff
Replace streamEcho with Puter proxy AI call, inject memory facts as
system message, append memory after each turn. Assistant-to-PM handoff
creates new conversation with context summary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
7bb72a5a2f feat(33-01,33-02): memory service + sanitizer, personal assistant page
33-01: memory-sanitizer, assistant-memory service, REST routes, 17 tests
33-02: useNexusMode hook, PersonalAssistantPage, sidebar nav, route wiring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
d1bb30517f feat(31-01): mount puterProxyRoutes in app.ts
- Add import for puterProxyRoutes from routes/puter-proxy.js
- Mount api.use(puterProxyRoutes(db)) after costRoutes inside api Router
- Route is protected by boardMutationGuard as required
2026-04-04 03:55:49 +00:00
Nexus Dev
dbba43cb3c test(31-02): add 11 unit tests for Google OAuth service and routes
- Test 1-2: PKCE generation (verifier/challenge format, auth URL params)
- Test 3: token exchange posts correct body to Google token endpoint
- Test 4-5: storeTokens create and rotate paths
- Test 6: authorize returns {url, stateId} with no companyId in pendingPkce
- Test 7: callback exchanges code and redirects with google_oauth=success
- Test 8: callback with invalid state returns 400
- Test 9: full authorize->callback->claim flow stores tokens by companyId
- Test 10: claim with missing stateId returns 404
- Test 11: api-keys/store upserts via secretService
2026-04-04 03:55:49 +00:00
Nexus Dev
526acbe8aa feat(31-01): implement puterProxyService, puterProxyRoutes, and unit tests
- puterProxyService with storeToken (create/rotate idempotent), resolveToken, chatStream
- chatStream relays to Puter OpenAI-compat endpoint with SSE streaming
- Cost recording with provider=puter, billingType=subscription_included, costCents=0
- Cost recording skipped when agentId is null/undefined (no FK violation)
- puterProxyRoutes with POST /puter-proxy/token and POST /puter-proxy/chat
- Board auth (assertBoard + assertCompanyAccess) on all routes
- All 10 TDD tests passing
2026-04-04 03:55:49 +00:00
Nexus Dev
895b3004be feat(31-02): add googleOAuthRoutes with pendingTokens pattern and mount in app.ts
- POST /oauth/google/authorize: returns {url, stateId}, stores PKCE verifier only (no companyId)
- GET /oauth/google/callback: exchanges code, parks tokens in pendingTokens by stateId
- POST /oauth/google/claim: moves tokens from pendingTokens to secretService with real companyId
- POST /api-keys/store: upserts provider API keys (openai/anthropic/groq) via secretService
- Cleanup of entries older than 10 minutes on each request
- Mounted in app.ts via api.use(googleOAuthRoutes(db))
2026-04-04 03:55:49 +00:00
Nexus Dev
14784d47c2 feat(31-02): add googleOAuthService with PKCE generation and token management
- generatePkce() using crypto.randomBytes base64url verifier and SHA256 challenge
- generateAuthUrl() builds Google OAuth URL with PKCE params for Gemini scopes
- exchangeCode() POSTs to Google token endpoint with code_verifier
- storeTokens() upserts google_gemini_oauth_token via secretService
- resolveTokens() retrieves and parses stored tokens by companyId
2026-04-04 03:55:49 +00:00
Nexus Dev
59bf5dd8ba feat(30-01): hardware and nexus-settings routes, app.ts mounting
- Add hardwareRoutes with unauthenticated GET /system/providers
- Add hardwareRoutes with GET /system/providers/recommendation
- Add nexusSettingsRoutes with board-auth GET/PATCH /nexus/settings
- Mount hardwareRoutes on app before boardMutationGuard (unauthenticated)
- Mount nexusSettingsRoutes on api router (board-auth gated)
2026-04-04 03:55:49 +00:00
Nexus Dev
a9817a9659 feat(30-01): hardware detection, nexus-settings, extended model catalog
- Add hardwareService with Apple Silicon / GPU / cpu_only tier detection
- Add 3s Promise.race timeout for si.graphics() with cpu_only fallback
- Add nexusSettingsService with Zod validation and file-backed persistence
- Extend ollama-model-catalog.json with tier arrays on every variant
- Add qwen3:8b family to catalog
- Update getRecommendedModel to accept optional hardwareTier parameter
- All 13 unit tests pass (TDD green)
2026-04-04 03:55:49 +00:00
Nexus Dev
0fc748d2d4 feat(29-02): Hermes skill injection + default provider integration tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
1ff3953c97 feat(29-01): adapter probe route, Hermes onboarding fallback, neutral templates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
1cf1c1f038 feat(28-02,28-03): Ollama UI surface + Hermes runtime dashboard
28-02: ollamaApi client, model dropdown in config, skill badge
28-03: stateJson merge after heartbeat, HermesRuntimeCard in AgentOverview

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
39327b7660 feat(28-03): merge Hermes runtime data into stateJson and add HermesRuntimeCard
- Add OllamaPsResponse interface and getOllamaMemoryUsage() to ollama.ts
- Import getOllamaMemoryUsage in heartbeat.ts
- Add hermes_local block in updateRuntimeState: COALESCE jsonb merge of hermesModel + hermesMemoryBytes
- Add HermesRuntimeCard component in AgentDetail.tsx
- Render HermesRuntimeCard in AgentOverview gated by adapterType === hermes_local
- Native skill count derived from agentsApi.skills entries with originLabel === Hermes skill
2026-04-04 03:55:49 +00:00
Nexus Dev
5345b67f92 feat(28-01): Ollama service, routes, model catalog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
9ef04fd1de feat(27-01): close Hermes adapter integration gaps
- Add hermes_local to SESSIONED_LOCAL_ADAPTERS (HERM-03)
- Fix create-mode toolsets field guard (HERM-02)
- Add hermes session codec round-trip tests (HERM-04)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
4b9d267f46 fix(v1.3): close 3 integration gaps from milestone audit
1. Push notifications: call sendPushToAll after streaming completes
2. Mobile offline: add useOfflineQueue + banners to MobileChatView
3. New conversation streaming: call startStream in Path 1 handleSend

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
66bbfbf766 feat(26-04): create push_subscriptions schema, migration, pushService, and push routes
- Add push_subscriptions pgTable with endpoint, p256dh, auth, userId, companyId, deviceLabel
- Add 0055_create_push_subscriptions.sql migration with CREATE TABLE and endpoint index
- Export pushSubscriptions from schema/index.ts
- Create pushService with initVapid, getVapidPublicKey, saveSubscription, removeSubscription, sendPushToAll
- sendPushToAll auto-deletes stale subscriptions on 410/404 response
- Create pushRoutes: GET /vapid-public-key, POST /subscribe, DELETE /subscribe
- Mount /api/push routes and call initVapid() in app.ts with graceful skip
- Install web-push and @types/web-push
2026-04-04 03:55:48 +00:00
Nexus Dev
dae0e3a3be feat(25-06): merge git file service and history endpoint from worktree
Adds gitFileService with commitFile/getLog, wires git commits into
upload flow, adds GET /files/:fileId/history endpoint, and exports
ChatFileHistoryEntry type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
7ab49d9824 feat(25-07): add placeholder and agent-generated file routes
- Import placeholderService and resolveDefaultStorageDir in chat-files routes
- Track agent_generated project-scoped uploads in PLACEHOLDERS.md manifest
- Add POST /files/:fileId/replace endpoint for placeholder replacement
- Replace endpoint updates manifest and creates cross-reference chain
- Mark FILE-08 and FILE-11 Complete in REQUIREMENTS.md
2026-04-04 03:55:48 +00:00
Nexus Dev
859ba1707b feat(25-07): create placeholderService and add markAsPlaceholder method
- Create server/src/services/placeholder-service.ts with addEntry, replaceEntry, listEntries
- Generates PLACEHOLDERS.md with Active Placeholders and Replaced markdown tables
- Add ChatPlaceholderEntry interface to packages/shared/src/types/chat.ts
- Export ChatPlaceholderEntry from packages/shared/src/index.ts
- Add markAsPlaceholder method to chatFileService in chat-files.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
03df062bec feat(25-04): create ChatCodeFilePreview with syntax highlighting
- Add ChatCodeFilePreview component with hljs syntax highlighting
- Fetch file content from contentPath with credentials
- Use DOMParser-based safe rendering (no dangerouslySetInnerHTML)
- Include copy button, language label, and ChatFileCard download below
- Add extToLang extension-to-language mapping
- Register 14 common languages with hljs
- Add highlight.js as direct dependency in ui/package.json
2026-04-04 03:55:48 +00:00
Nexus Dev
64a90c284e feat(25-08): create VoiceRecordButton and server transcription endpoint
- Add VoiceRecordButton with MediaRecorder API, recording/transcribing/idle states
- Add POST /transcribe endpoint to chat-files.ts using execFileAsync (safe, no shell)
- Tries whisper-cpp first, falls back to openai-whisper Python CLI
- Returns 503 with helpful message if whisper is not installed
2026-04-04 03:55:48 +00:00
Nexus Dev
939ebd6dc3 fix(25): handle missing chat_files table in listMessages and update addMessage test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
9aee875239 feat(25-03): wire files into ChatMessage, ChatPanel, and server listMessages
- ChatMessage: files prop, renders ChatFilePreview for each attached file
- ChatMessageList: passes files prop through to ChatMessage
- ChatPanel: wires useChatFileUpload, passes pendingFiles/onRemoveFile/onFilesPicked to ChatInput
- ChatPanel handleSend: attaches uploaded files to message after creation, invalidates query
- chatApi: adds attachFilesToMessage (parallel PATCH /files/:fileId for each fileId)
- server/chat.ts: listMessages fetches chatFiles by messageId (inArray), attaches files array
- server/chat.ts: addMessage returns files: [] for consistency
2026-04-04 03:55:48 +00:00
Nexus Dev
928cefa189 feat(25-01): create chatFileRoutes and wire into app.ts
- Create chatFileRoutes with upload, list, content, references, attach endpoints
- Wire into app.ts after assetRoutes, export from routes/index.ts
- Real tests replacing todo stubs in chat-file-routes.test.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
1cf231a540 feat(25-01): create chatFileService with DB operations and deriveCategory helper
- Implement chatFileService(db) with create, getById, listByConversation, listByMessage, createReference, listReferences, attachToMessage
- Export deriveCategory() helper mapping MIME types to image/code/document/other
- Add unit tests verifying service methods and category derivation with mocked DB
2026-04-04 03:55:48 +00:00
Nexus Dev
f335d3762b feat(25-00): add shared types, validators, and test stubs for file system
- Add ChatFile, ChatFileReference, ChatFileUploadResponse, ChatFileListResponse interfaces to types/chat.ts
- Add optional files?: ChatFile[] field to ChatMessage interface
- Add uploadChatFileSchema and createFileReferenceSchema Zod validators to validators/chat.ts
- Re-export all new types and validators from shared/src/index.ts
- Create test stubs for chat-file-service.test.ts and chat-file-routes.test.ts with it.todo() entries
2026-04-04 03:55:48 +00:00
Nexus Dev
505f5e2262 feat(24-01): add search, bookmark, branch, and export Express route handlers
- GET /companies/:companyId/messages/search: FTS search with ZodError 400 guard
- POST /conversations/:id/bookmarks: toggle bookmark with UUID validation
- GET /companies/:companyId/bookmarks: list bookmarks with optional conversationId filter
- POST /conversations/:id/branch: branch conversation from message point
- GET /conversations/:id/branches: list child conversations
- GET /conversations/:id/export: download Markdown or JSON with Content-Disposition header
2026-04-04 03:55:48 +00:00
Nexus Dev
61161a3561 feat(24-01): add searchMessages, toggleBookmark, getBookmarks, branchConversation, listBranches, exportConversation service methods
- searchMessages: tsvector FTS with ts_rank ordering, joins conversations for companyId scoping
- toggleBookmark: transactional insert-or-delete bookmark
- getBookmarks: joins bookmarks+messages+conversations, supports conversationId filter
- branchConversation: copies messages up to branch point into new child conversation
- listBranches: queries child conversations by parentConversationId
- exportConversation: LEFT JOINs agents for name resolution, produces Markdown or JSON with file headers
2026-04-04 03:55:48 +00:00
Nexus Dev
dc6316cf28 feat(24-00): shared types, validators, and Wave 0 test stubs for phase 24
- Add ChatMessageSearchResult, ChatMessageSearchResponse to shared types
- Add ChatBookmark, ChatBookmarkWithMessage, ChatBookmarkListResponse, ChatBookmarkToggleResponse
- Add parentConversationId + branchFromMessageId to ChatConversation and ChatConversationListItem
- Add searchMessagesSchema + branchConversationSchema to validators
- Re-export all new types and validators from shared/src/index.ts
- Add Wave 0 it.todo stubs: searchMessages, toggleBookmark, branchConversation, exportConversation
- Add Wave 0 it.todo stubs for 4 new route groups in chat-routes.test.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
9205ee82e3 feat(23-01): add handoff and status-update routes to chat API
- POST /conversations/:id/handoff: resolves companyId, inserts handoff
  message, creates issue from spec, inserts task_created message
- POST /conversations/:id/status-update: inserts status_update message
- Import issueService and handoffSchema; instantiate issueSvc in chatRoutes
- Both routes use assertBoard for authentication
2026-04-04 03:55:48 +00:00