Commit graph

1903 commits

Author SHA1 Message Date
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
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
3612b3ae66 feat(11-01): add five Drizzle table definitions for skill groups
- Add primaryKey import from drizzle-orm/sqlite-core
- Add skillGroups table with id, name, description, isBuiltin, timestamps
- Add skillGroupMembers junction table with composite PK (groupId, skillId)
- Add skillGroupInheritance table with composite PK (childGroupId, parentGroupId)
- Add agentSkillGroups table with composite PK (agentId, groupId)
- Add agentSkills table with composite PK (agentId, skillId)
2026-04-02 15:08:50 +00:00
f9e632ca18 fix(10): correct toast error messages in SkillDetail — Update/Uninstall not Install/Rollback 2026-04-02 15:08:50 +00:00
c7a5280c84 feat(10-03): update DesignGuide SkillCard section with all 5 required variants
- Expand grid to lg:grid-cols-3 for 5-card layout
- Add Loading (updating) variant (5th card per UI-SPEC requirement)
- Add onRollback/onUninstall props to installed variants
- Add descriptive comments for each variant state
2026-04-02 15:08:50 +00:00