Commit graph

1909 commits

Author SHA1 Message Date
Nexus Dev
3b8857cc9d docs(21): create gap closure plan for HIST-02 search + INPUT-07 Cmd+K 2026-04-02 15:08:50 +00:00
Nexus Dev
64b2302f93 docs(21-05): complete chat UI wiring plan — chatApi, TanStack Query hooks, conversation list, message thread
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:08:50 +00:00
Nexus Dev
f6c6a1573f feat(21-05): wire full chat UI with conversation list, message thread, and ChatPanel integration
- Add ChatConversationItem with DropdownMenu actions (Rename, Pin/Unpin, Archive, Delete) and active highlight
- Add ChatConversationList with IntersectionObserver infinite scroll, loading skeletons, delete confirmation dialog, and CRUD handlers
- Add ChatMessageList with auto-scroll-to-bottom on new messages and empty state
- Update ChatPanel to render ChatConversationList (left column) and ChatMessageList (right column); handleSend uses two paths: direct chatApi for new conversations, hook mutation for existing ones
2026-04-02 15:08:50 +00:00
Nexus Dev
2d7e1374ba feat(21-05): create chat API client and TanStack Query hooks
- Add ui/src/api/chat.ts with chatApi (7 methods: list/create/get/update/delete conversations + list/post messages)
- Add ui/src/hooks/useChatConversations.ts with useInfiniteQuery + placeholderData + CRUD mutations
- Add ui/src/hooks/useChatMessages.ts with useInfiniteQuery + sendMutation + flattened/reversed messages array
- Fix [Rule 3 - Blocking]: export ChatConversation, ChatMessage, ChatConversationListResponse, ChatMessageListResponse from packages/shared/src/index.ts (types existed in types/chat.ts but were not re-exported at package root)
2026-04-02 15:08:50 +00:00
Nexus Dev
e7411ab727 docs(21-03): complete chat service and REST API plan
- SUMMARY.md created with service/route implementation details
- STATE.md: advanced to plan 5/6, recorded 6min duration, added 3 decisions
- ROADMAP.md: updated phase 21 progress (5/6 summaries)
- REQUIREMENTS.md: marked CHAT-04, CHAT-05, CHAT-06, HIST-05 complete
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
c3c4145f9b docs(21-04): complete chat panel shell plan
- 21-04-SUMMARY.md with task details, deviations, known stubs
- STATE.md: advanced to plan 4, updated progress 67%, added decisions
- ROADMAP.md: phase 21 updated (4/6 summaries)
- REQUIREMENTS.md: INPUT-01 and THEME-01 marked complete
2026-04-02 15:08:50 +00:00
Nexus Dev
6bfabdb701 feat(21-04): create ChatPanel shell and wire into Layout and main.tsx
- ChatPanel: 380px right-side drawer with transition-[width] and hidden md:flex
- Two-column skeleton: 160px conversation list + flex thread area with ChatInput
- Layout: import ChatPanel, MessageSquare, useChatPanel; add chat toggle button
- Layout: useEffect closes PropertiesPanel when chatOpen becomes true
- Layout: ChatPanel rendered before PropertiesPanel in flex row
- main.tsx: ChatPanelProvider wrapping app inside PanelProvider
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
ea0b12d87b feat(21-04): create ChatPanelContext, ChatInput, and ChatMessage components
- ChatPanelContext with localStorage persistence (nexus:chat-panel-open)
- ChatInput with Enter/Shift+Enter/Escape keyboard shortcuts and auto-resize
- ChatMessage renders user bubbles (bg-secondary) and assistant markdown via ChatMarkdownMessage
- ChatInput.test.tsx with 6 passing tests (keyboard shortcuts, max-height, submit state)
2026-04-02 15:08:50 +00:00
Nexus Dev
7db3efe84c feat(21-01): add migration snapshot metadata 2026-04-02 15:08:50 +00:00
Nexus Dev
d651b4aa32 feat(21-02): create ChatCodeBlock and ChatMarkdownMessage components
- ChatMarkdownMessage: renders markdown with rehype-highlight syntax highlighting
- ChatCodeBlock: pre override with language label and copy button (1500ms success state)
- Uses ExtraProps from react-markdown for correct TypeScript types
- All tests pass, TypeScript compiles without errors
2026-04-02 15:08:50 +00:00
Nexus Dev
d3eefa0ef4 test(21-02): add failing tests for ChatMarkdownMessage and ChatCodeBlock 2026-04-02 15:08:50 +00:00
Nexus Dev
dbbc313701 feat(21-02): install rehype-highlight and add hljs theme CSS overrides
- Add rehype-highlight ^7.0.2 to ui/package.json dependencies
- Add highlight.js syntax theme CSS overrides to ui/src/index.css
- Cover Catppuccin Mocha (.dark), Tokyo Night (.theme-tokyo-night), Catppuccin Latte (:root)
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
Nexus Dev
ec345f6067 docs(21-02): complete markdown renderer plan — ChatMarkdownMessage, ChatCodeBlock, hljs theme CSS 2026-04-02 15:08:50 +00:00
Nexus Dev
9e9b38d587 docs(21-00): complete chat-foundation test stubs plan 2026-04-02 15:08:50 +00:00
Nexus Dev
44a5124cf3 docs(21-01): complete chat schema and shared types plan
- SUMMARY.md with accomplishments, commits, and deviation notes
- STATE.md advanced to plan 2 of 6, 33% progress
- ROADMAP.md updated with plan progress
- REQUIREMENTS.md: marked HIST-01 and HIST-06 complete
2026-04-02 15:08:50 +00:00
Nexus Dev
c2ef322835 feat(21-01): add shared chat types and Zod validators
- Create ChatConversation, ChatConversationListItem, ChatMessage, and list response types
- Create createConversationSchema, updateConversationSchema, createMessageSchema validators
- Re-export from @paperclipai/shared barrel files (types/index.ts, validators/index.ts)
2026-04-02 15:08:50 +00:00
Nexus Dev
d9aab2e1fb feat(21-01): add chat_conversations and chat_messages Drizzle schema + migration
- Create chatConversations table with companyId FK, agentId FK (set null), pinned/archived/deleted timestamps
- Create chatMessages table with conversationId FK (cascade delete), role, content, agentId
- Export both tables from packages/db/src/schema/index.ts
- Generate migration 0047_nebulous_klaw.sql with full DDL, FK constraints, and indexes
2026-04-02 15:08:50 +00:00
Nexus Dev
3c9decdd20 fix(21): revise plans based on checker feedback 2026-04-02 15:08:50 +00:00
Nexus Dev
dc91b3ad14 docs(21-chat-foundation): create phase plan — 5 plans across 3 waves 2026-04-02 15:08:50 +00:00
Nexus Dev
2f2843d32c docs(phase-21): add validation strategy 2026-04-02 15:08:50 +00:00
Nexus Dev
3af6ef7d12 docs(21): fix Cancel → Keep conversation per copywriting rules 2026-04-02 15:08:50 +00:00
Nexus Dev
3d0a25c9e5 docs(21): fix UI-SPEC typography, spacing, and visuals per checker 2026-04-02 15:08:50 +00:00
Nexus Dev
3019aa7ae7 docs(21): UI design contract for chat-foundation phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:08:50 +00:00
4d3ba0f81b [nexus] docs: log upstream rebase status — 0 behind, build verified 2026-04-02 15:08:50 +00:00
3c85784b6d [nexus] chore: migrate .planning/ from agent repo to nexus repo
Planning artifacts (milestones v1.0-v1.2.1, v1.3 queue, PROJECT.md,
STATE.md, config) now live alongside the code they describe.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:08:50 +00:00
f5ccdd5ff8 feat(20-02): add compatibleAdapters prop to SkillCard and wire Browse/Trending tabs
- Add optional compatibleAdapters prop to SkillCardProps interface
- Render 'Works with: ...' line when compatibleAdapters is provided and non-empty
- Pass COMPATIBLE_ADAPTER_LABELS to all Browse tab SkillCard renders
- Pass COMPATIBLE_ADAPTER_LABELS to all Trending tab SkillCard renders (gainingTraction, recentlyUpdated, youMightLike)
- Installed tab SkillCards intentionally omit compatibleAdapters (already agent-scoped)
2026-04-02 15:08:50 +00:00
f79e0aa628 feat(20-02): add adapter labels and unsupported install guard to SkillBrowser
- Import getUIAdapter and resolveAdapterSkillConfig/listAdapterSkillConfigs
- Show adapter type label in parentheses next to agent name in Installed tab selector
- Show adapter type label in install dialog agent list
- Guard handleInstallForAgent: show unsupportedMessage if adapter does not support install
- Dismissible error alert in install dialog for unsupported adapter attempts
- Clear unsupportedMessage on dialog open/close
- Compute COMPATIBLE_ADAPTER_LABELS at module level for Task 2
2026-04-02 15:08:50 +00:00
1c44dabf51 [nexus] feat(20-01): expand HermesLocalConfigFields with model, toolsets, persistSession, timeoutSec
- Add Model field (both create + edit modes) using CreateConfigValues.model
- Add Toolsets field (both create + edit modes) using extraArgs in create, adapterConfig.toolsets in edit
- Add Persist Session checkbox (edit mode only) wired to adapterConfig.persistSession
- Add Timeout (seconds) field (edit mode only) wired to adapterConfig.timeoutSec
- Restructure component to use fragment with conditional hideInstructionsFile guard
- TypeScript compiles cleanly
2026-04-02 15:08:50 +00:00
79b6105964 [nexus] feat(20-01): add gemini_local to AGENT_ADAPTER_TYPES constant
- Add gemini_local to AGENT_ADAPTER_TYPES array after hermes_local
- Closes TypeScript gap where gemini_local was valid in UI adapter registry but missing from AgentAdapterType union type
- TypeScript compiles cleanly for @paperclipai/shared and @paperclipai/ui
2026-04-02 15:08:50 +00:00
0be50b8686 [nexus] feat(19-03): dual-section Installed tab and read-only SkillCard for native skills
- SkillCard: add isReadOnly and source props; hide update/rollback/install when isReadOnly
- SkillCard: show Native badge when isReadOnly or source=native
- SkillBrowser: remove agentSkillsDir state and text input from install dialog
- SkillBrowser: add selectedAgentId state for per-agent installed skills view
- SkillBrowser: add agentInstalledSkills query using skillGroupsApi.listAgentSkills
- SkillBrowser: split installed skills into managedSkills/nativeSkills sections
- SkillBrowser: render Managed/Native section headings when nativeSkills.length > 0
- SkillBrowser: uninstall dialog now carries agentId and calls skillRegistryApi.uninstall
- SkillBrowser: install dialog sends agentId directly (no agentSkillsDir text input)
2026-04-02 15:08:50 +00:00
305ea411da [nexus] feat(19-03): update API client to use agentId instead of agentSkillsDir
- Add AgentSkillEntry type with skillId, source, installedAt fields
- install() now sends agentId in body not agentSkillsDir
- uninstall() new function that sends agentId as query param
- rollback() now sends agentId in body not agentSkillsDir
- skillGroups.assignGroup/removeGroup no longer accept agentSkillsDir param
- listAgentSkills now returns AgentSkillEntry[] not string[]
- Fix AgentDetail.tsx callers and entry rendering for new AgentSkillEntry type
- Fix SkillDetail.tsx callers to use agentId param
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
ad69f829ae [nexus] feat(18-01): implement adapter skill config resolver
- Static ADAPTER_SKILL_CONFIGS array with all 10 adapter types
- CONFIG_BY_TYPE Map for O(1) lookup by adapter type string
- FALLBACK_CONFIG for unknown types (supportsInstall: false, never throws)
- resolveAdapterSkillConfig returns correct config for all known adapters
- listAdapterSkillConfigs returns full readonly config array
- All 15 unit tests pass, no regressions in full test suite
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
06345e12b5 [nexus] chore: regenerate pnpm-lock.yaml after upstream rebase 2026-04-02 15:08:50 +00:00
bbcbc86035 feat(12-02): SkillDetail Ratings tab and Overview usage stats
- Add Ratings tab (4th tab) with rate form, personal history, community section
- Overview tab: conditionally render taskCount, avgCostUsd, lastUsedAt rows
- Import StarRating, Separator, Skeleton, Textarea, EmptyState, TooltipProvider
- saveRatingMutation calls addRating, invalidates ratings query on success
- ratingsQuery loads personal history with loading/empty/error states
2026-04-02 15:08:50 +00:00
bf52c56f5a feat(12-02): StarRating component, API extensions, DesignGuide entry
- Create StarRating component with interactive/readonly modes, amber stars, size sm/md
- Add PersonalRating type and taskCount/avgCostUsd/lastUsedAt to SkillListItem
- Add getRatings and addRating to skillRegistryApi
- Add Rating System section to DesignGuide with all variants
- Fix SkillCard fixture and DesignGuide examples to include new SkillListItem fields
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
4c771b8051 feat(11-04): extend AgentSkillsTab with groups section and dialogs
- Add imports: skillGroupsApi, SkillGroupRow, GroupBadge, Dialog, Separator, ScrollArea, Textarea
- Add agentGroups + allGroups + agentEffectiveSkills queries in AgentSkillsTab
- Add assignGroup + removeGroup + createGroup mutations
- Add state for add/create/remove dialogs, search, new group fields
- Insert Assigned Groups section with loading/empty/populated states
- Insert Combined Effective Skills collapsible section with ScrollArea
- Insert Additional Individual Skills label above existing skill list
- Add Add Skill Group, Create Skill Group, Remove group from agent dialogs
- Add Skill Groups section to DesignGuide with all GroupBadge variants
2026-04-02 15:08:50 +00:00
609c5b30b7 feat(11-04): create GroupBadge component
- Built-in variant: Badge secondary, no dismiss, hover:bg-accent/30
- Custom variant: Badge outline, X dismiss button with spinner, hover:bg-accent/50
- Tooltip on both variants showing name · built-in · N skills or name · N skills
- text-sm font-semibold typography per UI-SPEC (no font-bold or font-medium)
2026-04-02 15:08:50 +00:00
37476870a2 feat(11-03): add skill groups frontend API client and query keys
- Create ui/src/api/skillGroups.ts with skillGroupsApi object
- All 14 methods covering group CRUD, members, export/import, agent assignments
- removeGroup uses raw fetch for DELETE-with-body (api.delete has no body support)
- Add skillGroups namespace to ui/src/lib/queryKeys.ts with 6 key factories
2026-04-02 15:08:50 +00:00