Commit graph

659 commits

Author SHA1 Message Date
Nexus Dev
0d318a31d3 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-03 22:33:43 +00:00
Nexus Dev
d3dc1b73bd 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-03 22:15:39 +00:00
Nexus Dev
0bfec2a3c8 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-03 22:03:09 +00:00
Nexus Dev
f2b38f1eb2 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-03 00:36:31 +00:00
Nexus Dev
d750d15f49 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-03 00:35:53 +00:00
Nexus Dev
13bc39b1d4 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-03 00:35:11 +00:00
Nexus Dev
c41ec162d0 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-03 00:34:39 +00:00
Nexus Dev
720455132a 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-03 00:33:46 +00:00
Nexus Dev
86e30e5c69 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-02 23:22:20 +00:00
Nexus Dev
766460a163 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-02 23:19:09 +00:00
Nexus Dev
bd1c0967c8 feat(29-02): Hermes skill injection + default provider integration tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 17:43:47 +00:00
Nexus Dev
e0a82ed2f2 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-02 17:34:10 +00:00
Nexus Dev
a3802a9dd6 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-02 17:08:53 +00:00
Nexus Dev
5266d25727 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-02 17:07:53 +00:00
Nexus Dev
f052066f58 feat(28-01): Ollama service, routes, model catalog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:57:27 +00:00
Nexus Dev
6a7b9bd5f0 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-02 16:27:20 +00:00
Nexus Dev
d6f5e595d9 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-02 15:08:51 +00:00
Nexus Dev
3f1535f295 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-02 15:08:51 +00:00
Nexus Dev
3b3bdc2b39 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-02 15:08:51 +00:00
Nexus Dev
73859ab014 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-02 15:08:51 +00:00
Nexus Dev
2cafff8054 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-02 15:08:51 +00:00
Nexus Dev
ff3aa8793d 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-02 15:08:51 +00:00
Nexus Dev
f2f15aa9ad 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-02 15:08:51 +00:00
Nexus Dev
41f1880a29 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-02 15:08:51 +00:00
Nexus Dev
35a7814032 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-02 15:08:51 +00:00
Nexus Dev
5483991d38 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-02 15:08:51 +00:00
Nexus Dev
db4eb801d3 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-02 15:08:51 +00:00
Nexus Dev
16a849bd69 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-02 15:08:51 +00:00
Nexus Dev
2af9de913d 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-02 15:08:51 +00:00
Nexus Dev
430588a54e 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-02 15:08:51 +00:00
Nexus Dev
3eb4463cbb 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-02 15:08:51 +00:00
Nexus Dev
7feacb121f 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-02 15:08:51 +00:00
Nexus Dev
2a0c5769f3 feat(23-01): extend chat service with messageType support and addSystemMessage
- addMessage now accepts optional messageType parameter
- addSystemMessage helper inserts system-role messages with typed messageType
- Both methods bump conversation updatedAt for correct sort order
2026-04-02 15:08:51 +00:00
Nexus Dev
ea1a176b67 feat(22-01): add SSE streaming endpoint and edit/truncate service methods
- Add editMessage, truncateMessagesAfter, streamEcho methods to chatService
- Add POST /conversations/:id/stream SSE endpoint with flushHeaders before loop (PERF-02)
- Add PATCH /conversations/:id/messages/:msgId for message editing
- Add DELETE /conversations/:id/messages/after/:msgId for message truncation
- Import gt from drizzle-orm for createdAt comparison in truncateMessagesAfter
- Guard all res.write() calls with res.writable check (prevents write-after-end)
2026-04-02 15:08:50 +00:00
Nexus Dev
6367789992 feat(21-06): add search and agentId filter to listConversations
- Add ilike import and search/agentId conditions in chatService.listConversations
- Extract search and agentId from req.query in GET /conversations route
- Extend chatApi.listConversations opts with search and agentId params
- Update useChatConversations to accept opts.search and include in queryKey
2026-04-02 15:08:50 +00:00
Nexus Dev
54e1925b9e feat(21-03): add chatRoutes, mount in app.ts, export chat schemas from shared
- chatRoutes factory with 7 REST endpoints for conversations and messages
- All routes gated by assertBoard; company-scoped routes also use assertCompanyAccess
- Mounted as api.use(chatRoutes(db)) after activityRoutes in app.ts
- Export createConversationSchema/updateConversationSchema/createMessageSchema
  from @paperclipai/shared (were missing from main package index)
- 11 vitest route tests passing
2026-04-02 15:08:50 +00:00
Nexus Dev
d1438192b8 feat(21-03): implement chatService with full conversation + message CRUD
- createConversation, listConversations, getConversation, updateConversation
- softDeleteConversation, listMessages, addMessage
- cursor-based pagination with hasMore for both conversations and messages
- Pitfall 3: addMessage bumps conversation updatedAt after insert
- Pitfall 5: addMessage auto-sets title from first user message (IS NULL guard)
- 21 vitest tests passing
2026-04-02 15:08:50 +00:00
Nexus Dev
cfd904830b test(21-00): add Wave 0 test stubs for chat service, routes, markdown, and input 2026-04-02 15:08:50 +00:00
db83eb2a00 [nexus] test(19-02): route-level integration tests for adapter-aware skill routes
- Add 18 supertest tests covering install/uninstall/rollback/group routes
- Verify 400 (missing agentId), 404 (unknown agent), 422 (unsupported adapter)
- Verify 403 for native skill deletion
- Verify hermes_local agents trigger syncHermesNativeSkills before list
- Verify group assign resolves dir from URL agentId param
- Fix wildcard route syntax from :skillId(*) to *skillId (Express 5 / path-to-regexp v8)
  resolves pre-existing TS errors for these routes too
2026-04-02 15:08:50 +00:00
0c587ad664 [nexus] feat(19-02): adapter-aware route handlers with agentId resolution
- Add resolveSkillsDirForAgent helper to skill-registry.ts and skill-registry-groups.ts
- Install route accepts agentId in body (not agentSkillsDir)
- Uninstall route accepts agentId as query param; returns 403 for native skills
- Rollback route accepts agentId in body (not agentSkillsDir)
- Group assign/remove routes resolve dir from URL agentId param
- List agent skills route calls syncHermesNativeSkills for hermes_local agents
- skillRegistryRoutes(db) and skillGroupRoutes(db) factory signatures updated
- app.ts passes db to both route factories
2026-04-02 15:08:50 +00:00
a06eac3278 [nexus] feat(19-01): unit tests for adapter-aware install/uninstall and Hermes dual-source
- skill-registry-adapter-install.test.ts: 9 tests covering install/uninstall/rollback/assignGroup/removeGroup
- hermes-dual-source.test.ts: 7 tests covering syncHermesNativeSkills idempotency and listAgentSkills object shape
- Fix skill-registry-install.test.ts: update uninstall() callers to pass agentSkillsDir (new required param)
- Fix removeGroup() bug: removed incorrect 'individualSkills' guard that prevented file removal for group-installed skills
  (rule 1 auto-fix: group-installed skills were never removed because they appeared in agentSkills with no way to distinguish from direct installs)
- All 16 new tests pass, all existing tests still pass
2026-04-02 15:08:50 +00:00
1f33b1243a [nexus] feat(19-01): adapter-aware skill service layer — source column, uninstall file removal, syncHermesNativeSkills
- agentSkills schema gets source TEXT NOT NULL DEFAULT 'managed' column
- Migration guard in getSkillRegistryDb() handles existing DBs via ALTER TABLE
- uninstall() now accepts agentSkillsDir and removes files before soft-deleting
- syncHermesNativeSkills() reads ~/.hermes/skills/, creates stub rows with source='native'
- listAgentSkills() returns typed objects {skillId, source, installedAt} not string[]
- Interim uninstall route fix: reads agentSkillsDir from query param until Plan 02 wires agentId
2026-04-02 15:08:50 +00:00
2d546bedaf [nexus] test(18-01): add failing tests for adapter skill config resolver
- Add AdapterSkillFormat type and AdapterSkillConfig interface to types.ts
- Create stub adapter-skill-config.ts (throws not implemented)
- Re-export new types and functions from index.ts
- Add comprehensive test file covering all 10 adapter types and fallback
2026-04-02 15:08:50 +00:00
2f5e0ea189 [nexus] fix: restore upstream delegation and fact-extraction content lost during rebase 2026-04-02 15:08:50 +00:00
2e9470be62 feat(12-01): ratings routes, community ratings in fetcher, list/getById JOIN, heartbeat hook
- Add POST/GET /skill-registry/skills/:sourceId/:slug/ratings routes
- Import skillRatingService in skill-registry routes
- Add upsertCommunityRatingsStub() in fetcher, called after each skill upsert
- Import communityRatings from schema in fetcher
- Update list() and getById() in skill-registry.ts to LEFT JOIN communityRatings
- Include averageRating, ratingCount, taskCount, avgCostUsd, lastUsedAt in SkillListItem
- Add agentSkills usage aggregation via LEFT JOIN + SUM/AVG/MAX
- Add fire-and-forget recordUsageForAgent call in heartbeat after finalizeAgentStatus
- Dynamic import keeps skill-registry-ratings off critical startup path
- All 44 skill-registry tests pass, full server suite (536) green
2026-04-02 15:08:50 +00:00
b7dddfa266 feat(12-01): personalRatings schema, DB DDL, skillRatingService, and tests
- Add personalRatings table to skill-registry-schema.ts
- Add taskCount, avgCostUsd, lastUsedAt columns to agentSkills in schema
- Add CREATE_PERSONAL_RATINGS_TABLE DDL constant in skill-registry-db.ts
- Add ALTER TABLE statements for new agent_skills usage columns (idempotent)
- Create skill-registry-ratings.ts with skillRatingService factory
- rate() appends personal rating, validates stars 1-5
- getRatings() returns ratings ordered by createdAt DESC
- recordUsageForAgent() atomically updates task_count, avg_cost_usd, last_used_at
- All 8 tests pass
2026-04-02 15:08:50 +00:00
12cab29630 fix(11): default agentSkillsDir server-side — GROUP-03/GROUP-04 gap closure 2026-04-02 15:08:50 +00:00
ed87cc721f feat(11-03): add skill group routes, mount in app.ts, startup reconciliation
- Create server/src/routes/skill-registry-groups.ts with skillGroupRoutes() factory
- All 14 REST routes for group CRUD, members, export/import, and agent assignments
- Import route registered before :groupId param to avoid route collision
- assertBoard on every handler, error classification (400/404/409/500)
- Mount skillGroupRoutes() in app.ts after skillRegistryRoutes()
- Add pendingSkillGroups fire-and-forget reconciliation in index.ts startup
2026-04-02 15:08:50 +00:00
bebacf5406 feat(11-02): skillGroupService() with CRUD, membership, inheritance, assignment, import/export
- Group CRUD: listGroups, getGroup, createGroup, updateGroup, deleteGroup (guards built-in)
- Member management: addMember, removeMember, listMembers
- Inheritance: addParent (with cycle detection BFS), removeParent, listParents
- resolveEffectiveSkills: BFS walk with visited-set guard for cycle safety
- assignGroup: installs all effective skills, tracks in agent_skills, returns installed/skipped/pendingPlugin
- removeGroup: set-difference uninstall with fs.rm() for file removal (not skillRegistryService.uninstall)
- listAgentGroups, listAgentSkills, getAgentEffectiveSkills
- exportGroup / importGroup: GroupExport v1 JSON with cycle check on import
2026-04-02 15:08:50 +00:00
0294ccdd29 feat(11-01): add group table DDL and built-in group seeding to skill-registry-db
- Import LibSQLClient type for seedBuiltinGroups parameter typing
- Add DDL constants for 5 new tables: skill_groups, skill_group_members,
  skill_group_inheritance, agent_skill_groups, agent_skills
- Add BUILTIN_GROUPS constant with 5 entries (pm-essentials, engineer-core,
  frontend, backend, creative)
- Add seedBuiltinGroups() using INSERT OR IGNORE for idempotent seeding
- Extend getSkillRegistryDb() to execute all 5 new DDL statements and seed
2026-04-02 15:08:50 +00:00