Commit Graph
96 Commits
Author SHA1 Message Date
ZacharyZhang-NY b6e1756f1c refactor(CommandPaletteView): extract PaletteResultSection, closeAndReset (P1-23, P3-49, P3-50)
Five near-identical 25-line entity result blocks collapse into one
PaletteResultSection. Extract closeAndReset() callback used in 5 places.
Drop dead fallback: runs.find(...)?.id.slice(0,8) === run.id.slice(0,8).
2026-04-16 22:54:53 -04:00
ZacharyZhang-NY be0ff5a041 lib(renderer): add safeJson helper; migrate 6 JSON.parse try/catch call sites 2026-04-16 22:54:20 -04:00
ZacharyZhang-NY a07b42e493 refactor(App): extract Shell wrapper for locale+titlebar chrome (P1-20)
Collapse two near-identical LocaleContext/TranslationContext/TitleBar
wrapper blocks into a single Shell component.
2026-04-16 22:53:56 -04:00
ZacharyZhang-NY 4838750009 refactor(useDataLoader): drop 16 positional setters, use getState() (P1-22)
Function signature reduced from 16 args to 4; setters sourced from
useAppStore.getState() inside callbacks (stable refs, no deps needed).
useCompanyController no longer has to thread 14 setters through.
2026-04-16 22:53:08 -04:00
ZacharyZhang-NY 8dfa69cacf refactor(useUIController): group reads via useShallow, fetch setters from getState (P1-17)
Replace 11 individual useAppStore subscriptions with a single useShallow
selector; setters read once from useAppStore.getState() (stable refs).
2026-04-16 22:52:27 -04:00
ZacharyZhang-NY bea8aa9542 ui: add Card/Eyebrow/Spinner primitives, iconOnly ActionButton, drop ui.tsx barrel 2026-04-16 22:52:16 -04:00
ZacharyZhang-NY d42901b86d refactor(renderer): consolidate navigateTo into navigation slice (P1-11)
Delete the useUIController.navigateTo duplicate; augment slice version with
task-with-run lookup (via get().snapshot) so notification-click and command
palette share one codepath. App.tsx now reads navigateTo from the store.
2026-04-16 22:51:26 -04:00
ZacharyZhang-NY e2253b92fa refactor(renderer): dismantle useAppController 47-prop god-hook
Sections now subscribe directly to the Zustand store via useSectionContext
(shared data derivation) and useAppStore fine-grained selectors. Delete
useAppController, useExecutionController, useOrganizationController, and
useCommunicationController; the three domain forwarders held no logic
beyond re-exporting store slices.

SectionContentView becomes a 50-line layout dispatcher taking only
{section, error, pageTransition}; cross-domain run actions (startRun /
cancelRun) move into App.tsx and are exposed to sections through a new
AppActionsContext alongside refresh / setError / openPathWithFeedback.
App.tsx now calls useUIController + useCompanyController directly and
composes palette + navigation plumbing itself.
2026-04-16 22:12:51 -04:00
ZacharyZhang-NY de77f5f38e refactor(onboarding): replace 50-prop drilling with OnboardingContext
OnboardingStepPanel previously forwarded ~50 props to seven step
components, so adding a single wizard field meant touching four layers.
Introduce a renderer-local React Context (OnboardingProvider /
useOnboarding) that carries all wizard state and actions (connectors,
node status, company inputs, model selection, execution mode, mission,
launch summary, locale, t, error/loading). Step panels now receive only
their navigation callbacks (onContinue / onBack / onLaunch / onFinish)
and read everything else via useOnboarding(). CompanyOnboarding wraps
the step panel tree in OnboardingProvider with a memoised value.

Business logic is unchanged: each onContinueFrom* transition, the
bootstrap call, and the welcome-step branch remain exactly as before;
this refactor only moves the data-passing mechanism.
2026-04-16 22:11:45 -04:00
ZacharyZhang-NY f3816c6115 refactor(ui): unify success/danger/warning color tokens across Toast/StatusPill/InlineNotice 2026-04-16 22:10:43 -04:00
ZacharyZhang-NY a443312f1a refactor(automation): replace ACCENT/LINE constants with design tokens 2026-04-16 22:10:04 -04:00
ZacharyZhang-NY f177e6c877 refactor(settings): use Modal for OAuthPromptDialog 2026-04-16 22:06:59 -04:00
ZacharyZhang-NY 0f1b313272 refactor(execution): split ApprovalInspector 346-line god-component
Decompose monolithic src/renderer/components/execution/ApprovalInspector.tsx
into src/renderer/components/execution/approval-inspector/:
- ApprovalInspector.tsx (168 lines, orchestrator only)
- ApprovalSummary.tsx, ProposedHireCard.tsx, ApprovalDocumentsPanel.tsx
- DeliverableReviewPanel.tsx, SchedulePicker.tsx, DecisionForm.tsx
- TypeBadge.tsx, useApprovalPayload.ts, index.ts (barrel)

Hoist JSON.parse out of JSX IIFE into useApprovalPayload hook with typed
return. Replace roll-your-own role=radio spans with native
input[type=radio]. Extract getTypeBadgeClass switch into TypeBadge
component. Update execution.tsx barrel to re-export from new path.

Business logic preserved: approval decision flow, schedule validation,
deliverable review, document editing, delete confirmation.
2026-04-16 22:06:39 -04:00
ZacharyZhang-NY 69724f0188 refactor(social): use Modal for AddAccountDialog 2026-04-16 22:04:24 -04:00
ZacharyZhang-NY 8541836b26 refactor(automation): use Modal for WorkflowEditor 2026-04-16 22:03:57 -04:00
ZacharyZhang-NY 183f22e922 fix(onboarding): derive step counter from STEP_ORDER
All six step panels previously hard-coded "X / 5" or "X / 6" in their
header captions, which drifted out of sync with the 7-step STEP_ORDER in
OnboardingHero. Export STEP_ORDER / TOTAL_STEPS / getStepNumber from
OnboardingHero and consume them in every step so the counter is always
the single source of truth.
2026-04-16 22:03:57 -04:00
ZacharyZhang-NY 5a5587c2a1 refactor(automation): use Modal for RuleFormModal 2026-04-16 22:03:24 -04:00
ZacharyZhang-NY 8243f58ef7 refactor(automation): use Modal/ConfirmDialog for DeleteConfirmDialog 2026-04-16 22:02:29 -04:00
ZacharyZhang-NY 2ec77677cb fix(renderer): classify DesktopEvent types to stop full-refresh fallthrough (D-05)
All 14+ non-specially-handled events were pushing into the batcher with
entityKeyFromEvent returning null, which set hasDomainChanged = true and
triggered a full snapshot refresh on every agent-message, run-status, and
heartbeat-status -- defeating the granular patch machinery.

Per-type classification:
- run-status         -> granular run-updated (patchRun by runId)
- heartbeat-status   -> granular agent-updated (patchAgent by agentId)
- agent-message      -> granular task-updated (patchTask refetches comments)
- new-message, thread-wait-state-updated, domain-changed
                     -> full refresh, coalesced via 500ms batcher window
- automation-fired, recovery-needed
                     -> snapshot-irrelevant, skipped at event source

Widen batcher window from 50ms to 500ms so bursts coalesce into one reload.
Granular batches still flush at the same window cadence.
2026-04-16 21:58:32 -04:00
ZacharyZhang-NY 0123103f58 fix(renderer): subscribe ConsoleView to logRevision to trigger re-render (D-04)
logRevision was bumped on every run-log event but no component subscribed,
so ref mutations to logBufferRef never triggered a re-render -- the console
pre stayed stale until something else forced a render.

Subscribe to logRevision via useAppStore and depend on it in the useMemo
that reads logBufferRef, keeping the ref-based buffer (cheap writes) while
restoring re-renders.
2026-04-16 21:57:08 -04:00
ZacharyZhang-NY 0119872db6 fix(renderer): use snapshot.currentCompanyId as single source of truth (D-03)
CompanySlice's standalone currentCompanyId field + setCurrentCompanyId action
were never written by any caller, so useDesktopEvents.ts read null and fell
through to full refresh for every entity event -- the granular patch
machinery was dead code.

- Remove currentCompanyId field + setCurrentCompanyId from CompanySlice
- refreshBadges reads from snapshot.currentCompanyId
- useDesktopEvents reads companyId from snapshot.currentCompanyId
- Update store unit test to seed snapshot instead of calling removed action
2026-04-16 21:56:40 -04:00
ZacharyZhang-NY a612ea7bea fix(communication): set searchLoading=true in setSearchQuery
setSearchQuery only incremented searchRequestId without flipping
searchLoading, so the UI could not distinguish "searching" from "no
results". Now loading flips true on non-empty query and clears
(results + loading) on empty query. setSearchResults keeps the
existing id-match logic to flip loading false on arrival.
2026-04-16 21:36:37 -04:00
ZacharyZhang-NY 1b578c111a update 2026-04-16 14:48:51 -04:00
ZacharyZhang-NY 9145572422 update 2026-04-05 20:14:48 -04:00
ZacharyZhang-NY b8dda3c8d0 update 2026-04-04 17:01:26 -04:00
ZacharyZhang-NY 67c757f481 update 2026-04-04 12:03:50 -04:00
ZacharyZhang-NY aed312124b update 2026-03-30 16:24:29 -04:00
ZacharyZhang-NY 6f1de8047e update 2026-03-30 00:15:21 -04:00
ZacharyZhang-NY 65e85135c1 large update 2026-03-29 14:08:15 -04:00
ZacharyZhang-NY 6480b7f49f fix(11): repair broken color patterns from CSS variable migration
- ChannelSidebar: replace inline color-mix style with Tailwind classes for task discussion icons
- MessageItem: replace broken priority config (color-mix inline) with Tailwind utility classes
- MessageItem: replace broken department badge hex-alpha pattern with Tailwind classes
- automation-config: restore ACCENT/LINE as hex values (used in template literal alpha suffixes)
- desktop-shell-service: set nativeTheme.themeSource to sync Windows title bar with app theme
2026-03-27 22:44:14 -04:00
ZacharyZhang-NY 831acc3b06 fix: use tinted backgrounds for message priority badges
Priority badges had identical bg and text colors (both solid destructive
red for urgent), creating oversized solid-color blocks. Use 15% tinted
backgrounds so text remains readable and badges appear as subtle pills.
2026-03-27 22:36:35 -04:00
ZacharyZhang-NY c780fb7a1c fix: correct task discussion channel colors in sidebar
The task discussion avatar used solid var(--primary) background making a
dark square. Use 12% tinted primary instead (matching other channel icons).
Also change selected state from bg-muted to bg-accent for consistency
with regular channel items.
2026-03-27 22:36:19 -04:00
ZacharyZhang-NY 259c0a279d fix: hide cancel button on first-launch onboarding
Add isFirstLaunch check to cancel button visibility so it only shows
when user is creating additional companies, not during initial setup.
2026-03-27 22:34:52 -04:00
ZacharyZhang-NY 0a0b2fdce4 fix: prevent onboarding page scrollbar by constraining to viewport height
Change outer container from min-h-[100dvh] to h-[100dvh] and hero panel
from overflow-y-auto to overflow-hidden to prevent unwanted scrollbar
caused by ASCII animation background content.
2026-03-27 22:34:38 -04:00
ZacharyZhang-NY 2106ee1feb fix(11-02): repair broken text strings from mass CSS variable replacement
The mass find-and-replace incorrectly replaced the word 'surface' in
human-readable text strings and type literals, not just CSS class contexts.
Fixed: App.tsx control surface text, DocumentCenter knowledge base text,
i18n en.ts, and Panel tone prop type literal.
2026-03-27 22:24:43 -04:00
ZacharyZhang-NY 06ea4c6aec feat(11-02): replace 1113 old CSS variable references with Paperclip design tokens
- Replace all bg-[color:var(--old)] with bg-background/bg-card/bg-muted/bg-primary etc.
- Replace all text-[color:var(--old)] with text-foreground/text-muted-foreground/text-primary etc.
- Replace all border-[color:var(--line)] with border-border
- Replace all inline var(--old) with var(--new) equivalents
- Replace all rounded-[6px]/rounded-[8px] with rounded-lg
- Replace .surface class with bg-card border border-border shadow-sm
- Replace .focus-ring class with focus-visible Tailwind utilities
- Replace .mono class with font-mono
- Replace data-theme attribute with class-based dark mode
- 99 files updated, ~1265 lines changed, zero old references remaining
2026-03-27 22:12:00 -04:00
ZacharyZhang-NY 2ed5dd3388 chore: merge wave 1 (plan 11-01) with conflict resolution 2026-03-27 22:08:16 -04:00
ZacharyZhang-NY 22314876b3 feat(11-01): create status-colors.ts module and remove font packages
- Add status-colors.ts with Paperclip semantic status color mappings
- Export statusBadge, issueStatusIcon, issueStatusText, agentStatusDot, priorityColor
- Remove @fontsource-variable/inter, @fontsource-variable/jetbrains-mono, @fontsource/instrument-serif
2026-03-27 22:06:02 -04:00
ZacharyZhang-NY 02426bc861 feat(11-01): replace hex CSS vars with Paperclip OKLCH design tokens
- Replace entire styles.css with OKLCH token system (light + dark modes)
- Switch dark mode from data-theme attribute to .dark CSS class
- Update App.tsx theme toggle to use classList.toggle with system preference detection
- Switch fonts from Inter/JetBrains Mono to Maple Mono/Maple Mono NF CN
- Add chart tokens, sidebar tokens, 0px border radius
- Preserve sidebar-drag, ascii-scroll-track, reduced-motion support
- Remove fontsource font imports from main.tsx
2026-03-27 22:05:10 -04:00
ZacharyZhang-NYandClaude Opus 4.6 41c5dccae4 feat(09-02): wire App.tsx granular event routing with batch handler
- Replace createEventBatcher with createDomainEventBatcher in App.tsx
- Add handleGranularBatch for task, run, approval, agent, and budget events
- Task/run/approval events trigger targeted IPC fetch and Zustand patch
- Run completion and budget changes trigger full refresh (cross-entity)
- Failed entity fetches fall back to removeTask or full refresh
- Unknown event types trigger full refresh (PERF-03 safety)
- Sidebar badges refresh after every successful granular batch
- Add 12 integration tests for handleGranularBatch in selective-ipc.test.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:49:55 -04:00
ZacharyZhang-NY 039c1d117f Merge branch 'worktree-agent-a2f30682'
# Conflicts:
#	.planning/STATE.md
#	src/main/ipc-core-read-handlers.ts
#	src/shared/contracts.ts
2026-03-27 19:40:29 -04:00
ZacharyZhang-NYandClaude Opus 4.6 f172a3d9b3 feat(09-01): build enhanced event batcher with granular event coalescing
- Add createDomainEventBatcher with entity type+ID dedup within 50ms window
- Domain-changed overrides all granular events in same batch
- More than 10 unique entities triggers full refresh fallback
- Delete action preserved during coalescing (last-write-wins otherwise)
- Unknown event types trigger full refresh as safety fallback
- Legacy createEventBatcher preserved for backward compatibility
- Add 12 comprehensive tests for all coalescing behaviors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:35:05 -04:00
ZacharyZhang-NYandClaude Opus 4.6 920a764856 feat(09-01): define granular event types, IPC channels, entity getters, and Zustand patch methods
- Add 5 granular event interfaces (TaskUpdated, RunUpdated, ApprovalUpdated, AgentUpdated, BudgetChanged) to DesktopEvent union
- Add 4 entity getter IPC channels (getTask, getAgent, getRun, getApproval) with Zod validation and company ownership checks
- Add getRun method to AppDatabase following existing getTask pattern
- Add 4 preload bridge methods for entity getters
- Add 8 patch/remove methods and refreshBadges to CompanySlice
- Add selective-ipc.test.ts with exhaustive union type tests
- Extend store.test.ts with 14 patch method tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:33:33 -04:00
ZacharyZhang-NY 76a69494a1 fix(08): use getBudgetStatus IPC for company/agent/project scope budget utilization 2026-03-27 18:45:32 -04:00
ZacharyZhang-NY 907a5dfe2f Merge branch 'worktree-agent-a5b08020'
# Conflicts:
#	.planning/STATE.md
#	package.json
#	pnpm-lock.yaml
2026-03-27 09:04:16 -04:00
ZacharyZhang-NYandClaude Opus 4.6 b6c5b2a9ee feat(08-02): create 5 dashboard chart components with ChartSection container
- Add RunActivityChart (area chart), SuccessRateChart (line chart), CostTrendChart (area chart), AgentWorkloadChart (bar chart) using Recharts
- Add BudgetUtilization with CSS progress bars, color thresholds (success/warn/danger), and empty state
- Create ChartSection container orchestrating all charts with Framer Motion entrance animation
- Integrate ChartSection into Dashboard.tsx between MetricsGrid and NeedsAttention
- Add companyId prop to DashboardProps and pass from App.tsx
- Include Plan 01 infrastructure: chart-utils.ts, ChartCard.tsx, ChartTooltip.tsx, recharts dependency
- All charts respect reduced motion via useReducedMotion hook
- 16 unit tests pass for aggregation functions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 08:59:59 -04:00
ZacharyZhang-NY 40b01f24e9 Merge branch 'worktree-agent-a1f54db6'
# Conflicts:
#	.planning/STATE.md
2026-03-27 08:51:34 -04:00
ZacharyZhang-NYandClaude Opus 4.6 31328d5a3b feat(08-01): create ChartCard wrapper and ChartTooltip components
- ChartCard: shared chart card with title, period badge, empty state, role="img" accessibility
- ChartTooltip: custom Recharts tooltip with design system tokens, color dots, mono font
- Both use CSS custom properties for automatic dark mode support
- TypeScript compiles cleanly with Recharts TooltipContentProps type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 08:47:07 -04:00
ZacharyZhang-NYandClaude Opus 4.6 a45e6bc10c feat(08-01): install Recharts and create tested data aggregation functions
- Install recharts@3.8.1 as dependency
- Create chart-utils.ts with 4 exported pure functions: aggregateRunsByDay, aggregateCostsByDay, aggregateAgentWorkload, formatShortDate
- Create dashboard-charts.test.ts with 16 unit tests covering all aggregation behaviors
- All tests pass: 14-day bucketing with zero-fill, timed_out/interrupted as failed, null cost handling, top-8 + Others grouping, name truncation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 08:44:49 -04:00
ZacharyZhang-NY 1c462d571c feat(05-03): policy-level BudgetSummary, incident-based BudgetAlertBanner, AgentEditor policy wiring
- BudgetSummary shows policy-level utilization bars when companyId provided, falls back to agent-level
- BudgetAlertBanner loads open incidents for policy-based alerts (warn_threshold/hard_stop), falls back to agent thresholds
- AgentEditor reads budget from budget_policies and writes budget as policy on save (D-11)
- Dashboard passes companyId through to BudgetAlertBanner
2026-03-26 21:17:02 -04:00