Initialize project and ignore local references

This commit is contained in:
ZacharyZhang-NY committed 2026-03-15 22:17:07 -04:00
1 parent a11ac3eaba
commit 2af82b6bb3
132 files changed
+29426

No files matched your search

+205
View File
@@ -0,0 +1,205 @@
# Phase 1: ProjectManager Scope And Milestones
## Product Frame
- Product working name: `AgentCompany`
- Product type: cross-platform Electron desktop application
- Platform target: macOS, Windows, Linux
- Primary mode: local-first single-operator control plane
- Product goal: run a multi-agent company from one desktop application with explicit control over connectors, workspaces, tasks, runs, approvals, budgets, logs, and recovery
## Scope Source
- Existing Paperclip concept from `doc/GOAL.md`, `doc/PRODUCT.md`, `doc/SPEC-implementation.md`
- Rebuild constraints and product direction from `/Users/zacharyzhang/Documents/Github/paperclip/PRD.md`
## Supported MVP Domains
- Local profile with backup and restore
- Multi-company local data model
- Connector registry with capability matrix
- Agent registry and org tree
- Goals, projects, tasks, lineage
- Run orchestration with session persistence and live console
- Approval queue and governance actions
- Cost tracking and budget hard-stop behavior
- Activity timeline and run diagnostics
- Workspace and repository management
- Secret management with OS-backed encryption where available
- Packaging, signing configuration, updater wiring, and crash-safe recovery hooks
## Explicit Platform Decision
AgentCompany targets all three desktop platforms in the first implementation.
Platform-specific constraints that must be handled intentionally:
- macOS:
- standard traffic-light window controls
- `Cmd` modifiers in menus and shortcuts
- notification permission behavior
- notarization and Developer ID signing requirements
- `safeStorage` may block while Keychain access is resolved
- Windows:
- NSIS installer target
- `Ctrl` modifiers in menus and shortcuts
- AppUserModelID and toast notification expectations
- code signing certificate requirement for trusted distribution
- Linux:
- AppImage target with optional deb/rpm later
- tray behavior differs by desktop environment
- `safeStorage` backend may degrade to `basic_text`, so fallback vault behavior must stay explicit
## Delivery Milestones
### 1. Architecture Freeze
Feature scope:
- final process model
- profile/storage layout
- IPC contract surface
- connector capability model
- initial screen map
Dependencies:
- PRD audit
- Electron security research
- platform packaging research
Acceptance criteria:
- architecture docs complete
- privileged boundaries defined
- no renderer-to-Node direct access
### 2. Interactive Prototype
Feature scope:
- shell window
- top nav + sidebar + utility drawer
- onboarding flow
- fake local data rendered from real repositories/services
Dependencies:
- design system
- typed preload bridge
- renderer route skeleton
Acceptance criteria:
- navigable desktop shell
- keyboard navigation baseline
- console drawer and inspector patterns established
### 3. Internal Alpha
Feature scope:
- local SQLite profile
- connectors registry and environment checks
- agents/tasks/approvals/workspaces CRUD
- utility-process orchestrator
- real run launch for supported local connectors
Dependencies:
- repository layer
- connector host
- activity logging
Acceptance criteria:
- launch first task run from onboarding
- view live logs
- persist app state across restart
### 4. Cross-Platform Validation
Feature scope:
- window/menu differences
- path handling
- notifications
- backup/restore
- crash recovery path
Dependencies:
- packaged test builds
- platform QA checklist
Acceptance criteria:
- app boots and navigates on macOS, Windows, Linux
- core workflows verified on each target
### 5. Signed Beta Build
Feature scope:
- electron-builder config
- signing env handling
- updater channel wiring
- production logging paths
Dependencies:
- build pipeline
- signing assets
Acceptance criteria:
- signed distributables generated
- updater checks optional and disableable
- release metadata generated
### 6. Release Candidate
Feature scope:
- performance pass
- memory/resource leak pass
- e2e coverage for critical flows
- security audit fixes
Dependencies:
- alpha feedback
- perf instrumentation
Acceptance criteria:
- no known critical security issue
- no crash in scripted happy path flows
- startup and live console remain responsive under load
### 7. Production Release Readiness
Feature scope:
- release checklist
- support docs
- backup guidance
- known limitations register
Dependencies:
- verification results
- signing and packaging validation
Acceptance criteria:
- typecheck/build/tests pass or deviations are explicitly recorded
- security and packaging docs complete
- final manual QA checklist complete
## Feature Sequencing Rules
- Connector execution begins only after IPC and orchestration boundaries are documented.
- Renderer implementation begins only after screen structure and state ownership are defined.
- Packaging config begins early, but signing and updater activation stay behind environment gating.
- Kimi support is tracked explicitly. If its runtime contract remains lower capability than other first-class connectors, the UI must declare the downgrade rather than hiding it.
+162
View File
@@ -0,0 +1,162 @@
# Phase 1: Current Paperclip Audit
## Audit Boundary
This audit compares the current Paperclip repository against the target state defined in `PRD.md`: a secure Electron desktop application with strict `main` / `preload` / `renderer` separation, local-first orchestration, packaging, and OS-integrated workflows.
## Severity 0: Blocking Architectural Mismatch
### 1. No Electron process model exists
- Current repo contains no `BrowserWindow`, `preload`, `contextBridge`, `ipcMain`, `ipcRenderer`, `utilityProcess`, or packaging configuration.
- Evidence:
- root search for Electron APIs returns no application implementation
- [server/src/app.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/app.ts)
- [ui/src/App.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/App.tsx)
Impact:
- There is no privileged boundary for filesystem, keychain, window lifecycle, native dialogs, menus, notifications, updater, or desktop protocol handling.
- The current product cannot be hardened into a desktop app by shell-wrapping the existing UI.
### 2. Orchestration is server-centric, not desktop-local
- Heartbeat execution, run tracking, workspace realization, and activity propagation live in the server process.
- Evidence:
- [server/src/services/heartbeat.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/services/heartbeat.ts)
- [server/src/services/workspace-runtime.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/services/workspace-runtime.ts)
Impact:
- The current implementation assumes a long-lived backend service instead of a desktop-owned local orchestration core.
- Crash semantics, app restart recovery, and foreground/background coordination are not modeled as desktop concerns.
### 3. The product shell is a routed web board, not a desktop console
- The top-level UI is route-driven, page-centric, and optimized for browser navigation rather than split-pane desktop operations.
- Evidence:
- [ui/src/App.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/App.tsx)
- [ui/src/components/Layout.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/components/Layout.tsx)
Impact:
- No desktop-native command surfaces for file dialogs, tray, menu actions, run console docking, workspace reveal, or keyboard-first operations.
- Core runtime objects such as connector health, workspace locks, session continuity, and log streams are not first-order interaction primitives.
## Severity 1: Major Product And UX Gaps
### 4. Onboarding is web-form oriented and does not establish a desktop local profile
- Existing onboarding creates company, CEO, and task records through API calls, but it does not create a local profile boundary, filesystem roots, workspace permissions, or connector health setup.
- Evidence:
- [ui/src/components/OnboardingWizard.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/components/OnboardingWizard.tsx)
Impact:
- First launch does not establish the desktop objects required by the PRD: local profile, workspace selection, connector detection, secret storage, and first-run orchestration.
### 5. Connector differences are hidden inside adapter packages instead of surfaced as product-level capability states
- Adapters exist, but the UI treats them mainly as form configuration.
- Evidence:
- [server/src/adapters/registry.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/adapters/registry.ts)
- [ui/src/adapters/index.ts](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/adapters/index.ts)
Impact:
- Users cannot reason about installation status, auth status, session resume support, structured transcript support, graceful cancel support, or unattributed cost behavior at the product level.
### 6. Workspace and repo context are present in backend logic but weak in the product hierarchy
- Workspace realization and worktree logic already exist, but they are not promoted to a central desktop experience.
- Evidence:
- [server/src/services/workspace-runtime.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/services/workspace-runtime.ts)
- [doc/DEVELOPING.md](/Users/zacharyzhang/Documents/Github/paperclip/doc/DEVELOPING.md)
Impact:
- The codebase contains useful execution semantics, but the current UI still behaves like a CRUD admin console with runtime details buried behind secondary screens.
### 7. Run console and diagnostics are not treated as a persistent operational surface
- Logs and transcript UX exist, but not as a docked desktop utility layer with search, filtering, and background status awareness.
- Evidence:
- [ui/src/components/transcript/RunTranscriptView.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/components/transcript/RunTranscriptView.tsx)
- [ui/src/pages/RunTranscriptUxLab.tsx](/Users/zacharyzhang/Documents/Github/paperclip/ui/src/pages/RunTranscriptUxLab.tsx)
Impact:
- Long-running desktop workflows need a utility drawer, live fan-out events, failure escalation, and state restoration, which the current web UX does not provide.
## Severity 2: Security And Desktop-Readiness Gaps
### 8. No preload boundary means there is no audited API surface for privileged actions
Impact:
- Desktop actions such as open folder, reveal artifact, backup profile, launch connector, store secret, or trigger updater would currently have no typed, validated boundary.
### 9. Secret handling is designed for server deployment, not OS keychain-first desktop storage
- Current repo includes secret versioning and local encrypted storage semantics.
- Evidence:
- [server/src/services/secrets.ts](/Users/zacharyzhang/Documents/Github/paperclip/server/src/services/secrets.ts)
- [doc/DATABASE.md](/Users/zacharyzhang/Documents/Github/paperclip/doc/DATABASE.md)
Impact:
- The PRD requires OS-backed secure storage first. The current implementation does not model Electron `safeStorage`, keychain backend selection, or desktop fallback behavior.
### 10. Packaging, signing, and updater flows do not exist
Impact:
- There is no release artifact model for DMG/NSIS/AppImage, no signing config, no update metadata flow, and no environment gates for release versus dev behavior.
### 11. IPC sender validation, CSP, and custom protocol concerns are absent because there is no desktop surface yet
Impact:
- These are not bugs in the current web app, but they are missing mandatory controls for the target architecture.
## Severity 3: Maintainability Risks When Porting Directly
### 12. Existing routes and page layout would pull too much orchestration detail into the renderer
- The current UI is page-heavy and query-heavy.
- Directly transplanting it into an Electron renderer would encourage business and privileged logic to leak upward.
### 13. Current shared contracts are REST-oriented
- Existing shared types target HTTP API payloads and server validation.
- Evidence:
- [packages/shared/src/api.ts](/Users/zacharyzhang/Documents/Github/paperclip/packages/shared/src/api.ts)
- [packages/shared/src/types](/Users/zacharyzhang/Documents/Github/paperclip/packages/shared/src/types)
Impact:
- Desktop IPC contracts need operation-specific schemas, privilege labels, and request/response/error shapes rather than generic REST reuse.
### 14. Current database layer is PostgreSQL-first
- Evidence:
- [packages/db/src/schema](/Users/zacharyzhang/Documents/Github/paperclip/packages/db/src/schema)
- [doc/DATABASE.md](/Users/zacharyzhang/Documents/Github/paperclip/doc/DATABASE.md)
Impact:
- The desktop app needs an embedded local database with explicit migration and recovery semantics. The current schema is a strong domain reference, but not a direct persistence drop-in.
## Valuable Assets To Reuse
- Company-scoped domain language
- Agent org tree semantics
- Goal / project / issue lineage rules
- Approval lifecycle semantics
- Budget and cost event concepts
- Existing local connector adapter patterns for Codex, Claude, Gemini, OpenCode, Cursor, and generic process/http modes
- Workspace and runtime service orchestration ideas
## Rewrite Decision
AgentCompany should reuse domain concepts and selected adapter/runtime patterns, but it should not inherit the current app shell, server-centric topology, or browser-admin navigation model.
+99
View File
@@ -0,0 +1,99 @@
# Phase 2: ResearchAnalyst Findings
## Sources
- Electron security checklist: https://www.electronjs.org/docs/latest/tutorial/security
- Electron safeStorage API: https://www.electronjs.org/docs/latest/api/safe-storage
- Electron utilityProcess API: https://www.electronjs.org/docs/latest/api/utility-process
- electron-builder auto-update: https://www.electron.build/auto-update
- electron-builder code signing: https://www.electron.build/code-signing
- Electron releases schedule: https://releases.electronjs.org/schedule
- Electron releases index: https://releases.electronjs.org/release
- Kimi Code official product/docs entry:
- https://www.kimi.com/code
- https://www.kimi.com/code/docs/en/
## Electron Security Requirements
From current Electron guidance, AgentCompany must treat desktop privilege as a first-order security boundary:
- load only local packaged content in the main renderer
- keep `nodeIntegration` disabled
- keep `contextIsolation` enabled
- keep renderer sandboxing enabled where feasible
- expose a minimal preload API through `contextBridge`
- validate IPC sender and payloads
- restrict navigation and new window creation
- avoid `file://` in production and prefer a custom protocol
- define a restrictive CSP
- never expose shell or filesystem primitives wholesale to renderer code
## Runtime Version Decision
- Initial architecture research targeted Electron `41.0.0`.
- Build verification on March 12, 2026 found `better-sqlite3@12.6.2` failing native rebuild against Electron `41.0.0` / Node `24.14.0`.
- The implementation baseline is therefore pinned to Electron `39.8.0` for now.
Why this downgrade is deliberate:
- Electron `39.8.0` is still a stable release line as of March 12, 2026.
- It preserves the existing SQLite storage implementation without forcing a same-phase storage rewrite.
- The downgrade is narrower in scope than replacing persistence with a different driver while the product shell, IPC, and orchestration layers are still being completed.
Upgrade condition:
- Revisit Electron `41.x` after the SQLite layer is migrated to a compatible runtime path or the upstream native module supports the newer V8 ABI cleanly.
## Secret Storage Findings
- `safeStorage` is main-process only and uses OS-backed cryptography semantics.
- macOS: keychain-backed, app-specific protection
- Windows: DPAPI-backed, user-scope protection
- Linux: backend varies; it can degrade to `basic_text`
Product implication:
- AgentCompany should use `safeStorage` when encryption is available.
- On Linux, the app must surface the selected backend and explicitly fall back to an app-local encrypted vault when the selected backend is `basic_text` or unavailable.
## Background Processing Findings
- `utilityProcess.fork()` provides a Chromium-managed child process with Node enabled and message ports available.
- It is appropriate for orchestration work that should not block the renderer and should stay separate from window lifecycle concerns.
Product implication:
- Use a utility process for the orchestration core, run queue, workspace locks, and connector process supervision.
- Keep UI projection in renderer, privileged OS coordination in main, and long-running execution in the utility process.
## Packaging And Updater Findings
- electron-builder supports cross-platform packaging with:
- macOS: `dmg` plus `zip`
- Windows: `nsis`
- Linux: `AppImage` and optional deb/rpm variants
- Auto-update via `electron-updater` relies on generated metadata files such as `latest.yml`.
- macOS auto-update requires a signed app.
- Windows signing is also supported and should be treated as a release requirement.
Product implication:
- Package targets should default to DMG/ZIP, NSIS, and AppImage.
- Update checks must be opt-in/disableable by user setting, as required by the PRD.
- Signing configuration should be environment-driven and absent values must not block local development.
## Desktop UX Research Conclusions
- Desktop-first operators need split-pane information density, not a marketing-site layout.
- Keyboard navigation, command surfaces, and context-preserving utility drawers matter more than route purity.
- File reveal, open folder, drag/drop, and copy path are standard desktop affordances and should be first-class actions.
## Connector Research Conclusions
- The current Paperclip repo already contains strong local connector patterns for Codex, Claude Code, Gemini CLI, and OpenCode.
- Kimi Code is a real official CLI offering, but its desktop integration contract requires explicit treatment instead of assuming parity with the existing adapters.
Implementation decision:
- Reuse the established adapter contract ideas from current Paperclip for supported local connectors.
- Represent advanced capability differences explicitly in the connector registry and task/run UX.
@@ -0,0 +1,128 @@
# Phase 3: TechnicalImplementationResearcher Decisions
## Architecture Choice
- Runtime: Electron `39.8.0`
- Renderer: React + Vite + TypeScript
- UI motion: Framer Motion, used selectively for layout transitions, state feedback, and utility-drawer choreography
- Data: SQLite with WAL mode and a single-writer orchestration queue
- Orchestration: Electron utility process
- Packaging: electron-builder
- Updates: `electron-updater`, gated by app settings and environment
## Why This Stack
- Electron is required by the project constraints and matches the need for local CLI/runtime orchestration.
- React is already aligned with repo knowledge and keeps renderer iteration fast.
- SQLite with WAL provides embedded local durability and low setup overhead, matching the PRD requirement to start without external database installation.
- A utility process avoids freezing the renderer during process supervision, lock management, or log ingestion.
Version note:
- Electron `41.0.0` was evaluated first, but the shipping baseline moved to `39.8.0` because the current SQLite native dependency did not rebuild cleanly on the newer runtime during packaging verification.
## State Ownership
### Renderer-only state
- split-pane layout and inspector visibility
- filter/search state
- command palette visibility
- form drafts
- optimistic mutation feedback
### Main-process privileged state
- windows
- menus
- file dialogs
- notifications
- backup/import/export paths
- updater lifecycle
- safeStorage encryption/decryption
### Utility-process orchestration state
- connector child process registry
- run queue
- workspace write locks
- per-agent concurrency locks
- session persistence and resume eligibility
- unfinished run reconciliation
### Persisted local state
- companies
- connectors and connector config documents
- workspaces
- agents
- goals/projects/tasks
- approvals and comments
- runs, run events, cost events
- activity log
- app settings and window state
## IPC Model
IPC is split into three layers:
1. Renderer to preload:
- typed methods only
- no raw channel strings in UI components
2. Preload to main:
- schema-validated request/response handlers
- sender verified in main
3. Main to utility process:
- internal command bus over message ports
- used for orchestration, not for UI privilege elevation
## Storage Strategy
- Database file: `profile.sqlite` under app profile data directory
- WAL enabled
- Attachments/logs/artifacts stored as files, indexed in SQLite
- Secrets stored via `safeStorage` when available; otherwise fallback encrypted vault plus explicit risk state on Linux
- Backups stored as timestamped archives under `backups/`
## Performance Strategy
- Renderer subscribes to normalized event streams instead of raw connector protocol noise
- Utility process owns long-running child processes
- Log viewer uses chunked pagination and windowed rendering
- Expensive derived summaries are computed in main/utility and sent as projections
## Connector Strategy
Connector contract layers:
- required:
- detect installation
- health/auth check
- execute
- normalize stdout/stderr/events
- declare capability matrix
- optional:
- session resume
- graceful cancel
- model discovery
- structured transcript
- cost attribution
## Updater Strategy
- default channel: disabled unless configured
- manual update check available from app menu and settings
- before install:
- write backup manifest
- flush db/log handles
- if signature validation fails:
- reject install
- record audit event
## Failure Model
- app restart scans unfinished runs
- stale running records become `interrupted`
- retryable runs expose resume/retry actions in UI
- workspace lock conflicts enqueue runs as `queued`
- connector health failures block new run dispatch
+113
View File
@@ -0,0 +1,113 @@
# Phase 4: EnterpriseArchitect Standards
## Top-Level Structure
```text
AgentCompany/
assets/
build/
docs/
scripts/
src/
main/
preload/
renderer/
shared/
tests/
unit/
integration/
e2e/
electron-builder.yml
package.json
tsconfig.json
.env.example
```
## Process Boundaries
### Main process owns
- window lifecycle
- app protocol registration
- IPC gateway
- menu construction
- native dialogs
- notifications
- updater
- backup/restore coordination
- safeStorage and vault bridge
### Preload owns
- narrow typed API
- event subscription bridge
- no business logic
- no dynamic API exposure
### Renderer owns
- UI composition
- read-only projections
- local interaction state
- invoking approved preload methods
### Utility process owns
- run execution
- connector process supervision
- workspace and agent locking
- timeout handling
- normalized event emission
## Naming Rules
- Use descriptive file names by role: `connector-service.ts`, `run-controller.ts`, `profile-repository.ts`
- Shared schemas live under `src/shared`
- No renderer component may import from `src/main`
- No preload module may import from `src/renderer`
## IPC Rules
- All channels are constants in `src/shared/contracts/ipc.ts`
- Every handler validates input with Zod before executing
- Response shape is always `{ ok, data, error }`
- Errors use explicit codes, never arbitrary thrown text at the renderer boundary
## Security Rules
- `contextIsolation: true`
- `sandbox: true` for renderer window
- `nodeIntegration: false`
- navigation locked to `app://` content
- `window.open` denied unless explicitly whitelisted
- shell execution restricted to orchestration/connector host
- connector env injection uses allowlists, never raw `process.env`
## Resource Lifetime Rules
Following the memory-safety constraints for long-lived desktop processes:
- every event subscription returns a disposer
- every spawned child process is registered and terminated on app shutdown
- timers are stored centrally and cleared on teardown
- database handles are singleton-owned and closed during quit/update install
- utility-process channels are recreated deterministically after crash or restart
## Module Boundaries
- `src/shared`: pure types, schemas, ipc contracts, constants
- `src/main/platform`: OS integration, menu, notifications, paths
- `src/main/storage`: SQLite, migrations, repositories
- `src/main/services`: profile, connectors, backups, updater, IPC composition
- `src/main/orchestrator`: utility-process bootstrap and bridge
- `src/renderer/pages`: route-level views
- `src/renderer/components`: reusable UI primitives and panels
- `src/renderer/state`: UI store, query clients, preferences
## Non-Negotiable Constraints
- No ad hoc IPC from components
- No direct filesystem or shell access in renderer
- No secrets in renderer state
- No mixed god service containing windows, db, and orchestration together
- No placeholder routes or dead menu entries
+121
View File
@@ -0,0 +1,121 @@
# Frontend Design System
## Product Tone
- Audience: technical operators running multiple AI agents simultaneously
- Interaction style: dense, precise, keyboard-first
- Motion style: restrained, purposeful, confidence-building
- Visual identity: warm, approachable workspace — Linear meets Raycast, not a neon cyber UI
## Typography
- Body/UI family: system stack (`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`)
- Monospace family: JetBrains Mono Variable (`font-family: "JetBrains Mono Variable", monospace`)
- Scale:
- Page titles: 31px, -0.03em tracking
- Section headings: 18px semibold, -0.01em
- Body/labels: 14px
- Compact UI (sidebar, pills, badges): 13px, 0.005em tracking
- Captions/meta: 12px
- Micro labels (status pills, section headers): 10-11px uppercase, 0.08-0.12em tracking
- Monospace (logs, IDs, timestamps): JetBrains Mono, 11-12px
## Color Tokens
### Light mode (`:root` default)
| Token | Value | Purpose |
|---|---|---|
| `--bg` | `#fbfbfb` | App background |
| `--panel` | `#ffffff` | Card/sidebar surfaces |
| `--panel-soft` | `#f4f5f5` | Active/hover states |
| `--text` | `#1a202c` | Primary text |
| `--muted` | `#718096` | Secondary/caption text |
| `--muted-strong` | `#4a5568` | Emphasized secondary text |
| `--accent` | `#c06a3a` | Warm terracotta — primary action color (~4.6:1 on white) |
| `--accent-soft` | `#f7ece6` | Accent background tint |
| `--danger` | `#e5484d` | Errors, destructive actions |
| `--warn` | `#b7791f` | Warnings, budget alerts |
| `--success` | `#2f855a` | Positive states, healthy budgets |
| `--success-soft` | `#edf7f0` | Success background tint |
| `--line` | `rgba(15,23,42,0.08)` | Subtle borders |
| `--line-strong` | `rgba(15,23,42,0.14)` | Emphasized borders |
### Dark mode (`[data-theme="dark"]` and `prefers-color-scheme: dark` when `data-theme="system"`)
| Token | Value |
|---|---|
| `--bg` | `#111315` |
| `--panel` | `#1b1f23` |
| `--panel-soft` | `#232931` |
| `--text` | `#f4f7fb` |
| `--muted` | `#9aa7b5` |
| `--accent` | `#ee8a58` |
| `--accent-soft` | `rgba(238,138,88,0.14)` |
Dark mode is fully implemented via `data-theme` attribute on `:root`, with a `prefers-color-scheme` media query for the `"system"` setting.
## Accent Color
The warm terracotta accent (`#c06a3a` light / `#ee8a58` dark) is the signature color. Use it only for:
- Active navigation items (icon fill + label)
- Primary action buttons
- Focus rings
Everything else is greyscale. Overuse dilutes the signal.
## Focus Ring
```css
.focus-ring:focus-visible {
box-shadow: 0 0 0 1px rgba(192,106,58,0.5), 0 0 0 4px rgba(192,106,58,0.12);
border-color: rgba(192,106,58,0.35);
}
```
## Layout Model
- Left sidebar: 220px fixed, keyboard-navigable
- Main content: max-width 1040px centered, 40px horizontal / 32px vertical padding
- Section spacing: 56px between major sections
## Spacing & Radius
- Interactive controls: 6-8px border radius
- Cards/panels: 10px border radius
- Dividers: 1px `var(--line)` borders, no heavy card shadows
## Animation
All transitions use `cubic-bezier(0.16, 1, 0.3, 1)` (ease-out-expo feel).
| Context | Duration |
|---|---|
| Hover/focus | 150ms (`duration-150`) |
| Page transitions | 240ms, y-axis slide (12px in, -10px out) |
| Panel reveals | 220ms, height or y-axis |
Respect `prefers-reduced-motion` globally — durations collapse to `0.01ms` when set.
## Icon System
Phosphor Icons (`@phosphor-icons/react`), weight `regular` by default, `fill` for active/selected states. Standard size 16-18px. Active sidebar icons use `--accent` color.
## Design Principles
1. **Hierarchy before density** — Typography, spacing, and color create visual hierarchy; never rely on borders alone.
2. **Quiet until needed** — Default state is calm and minimal. Warnings and errors earn their visual weight through color and placement.
3. **One accent, used with intent** — Terracotta is reserved for active navigation, primary actions, and focus states.
4. **Native-feeling, not native-copying** — macOS-aware (drag regions, traffic lights) but not AppKit imitation.
5. **Content over chrome** — The user's agents, tasks, and runs are the content. Minimize decorative scaffolding.
## Required Screens
Overview · Connectors · Agents · Tasks · Task Detail · Approvals · Costs · Activity · Workspaces · Settings · Onboarding
## Desktop-Specific Behaviors
- `Cmd` (macOS) / `Ctrl` (Windows/Linux) for search, command palette, save, refresh
- Context menus on list rows and workspace rows
- Drag/drop for workspace import and artifact attachment
- Reveal in Finder/Explorer for logs and artifacts
+38
View File
@@ -0,0 +1,38 @@
# Phase 6: FrontendDeveloper Renderer Implementation
## Stack
- React `19`
- TypeScript
- Vite / electron-vite
- Framer Motion for shell transitions and utility drawer motion
## Renderer Responsibilities Implemented
- first-launch onboarding for company bootstrap and workspace selection
- persistent desktop shell with section navigation
- command palette toggle and keyboard-driven navigation hooks
- connector registry with status, version, auth posture, and configuration surfaces
- company, agent, goal, project, task, approval, cost, activity, workspace, and settings panels
- run console utility drawer with live status and log retrieval
- empty, loading, and error states for first-run and operational flows
## State Model
- snapshot-driven renderer state sourced from `window.agentCompany.loadSnapshot()`
- local UI state for section selection, command palette visibility, console visibility, dialog drafts, and selection state
- event subscription via `window.agentCompany.subscribe(...)` for domain changes and run updates
## Desktop-Native UX Decisions
- shell layout assumes resizable desktop windows, not mobile breakpoints
- keyboard shortcuts are routed from the application menu into renderer event handling
- workspace opening and log access are explicit desktop actions
- drawer, inspector, and list/detail panels remain visible at desktop densities
## Key Files
- [App.tsx](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/renderer/App.tsx)
- [main.tsx](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/renderer/main.tsx)
- [styles.css](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/renderer/styles.css)
- [index.html](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/renderer/index.html)
+35
View File
@@ -0,0 +1,35 @@
# Phase 7: BackendDeveloper Main Process And Preload Implementation
## Main Process Responsibilities Implemented
- single-instance lock with focus restoration on second launch
- secure `BrowserWindow` creation with `contextIsolation: true`, `nodeIntegration: false`, and `sandbox: true`
- custom `app://` protocol for packaged renderer content
- application menu, accelerators, native dialogs, and notifications
- typed IPC registration with sender validation and schema validation
- local SQLite profile bootstrap, backup, restore, and settings persistence
- utility-process orchestration worker for run execution and log/status fan-out
- updater wiring via `electron-updater`, gated by settings and environment
## Preload Bridge
- single exposed surface: `window.agentCompany`
- no raw Node.js or Electron APIs exposed to renderer
- typed invoke helpers only
- renderer event subscription returns unsubscribe function and hides raw Electron event objects
## Storage And Secrets
- `node:sqlite` database under profile directory
- WAL enabled
- logs, artifacts, and backups stored as profile files
- secrets encrypted with Electron `safeStorage` when available, otherwise vault fallback
## Key Files
- [index.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/main/index.ts)
- [database.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/main/database.ts)
- [vault.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/main/vault.ts)
- [worker.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/main/orchestrator/worker.ts)
- [index.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/preload/index.ts)
- [contracts.ts](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/src/shared/contracts.ts)
+41
View File
@@ -0,0 +1,41 @@
# Phase 8: BuildVerificationEngineer Validation
## Commands Run
```sh
pnpm --filter @paperclipai/agent-company lint
pnpm --filter @paperclipai/agent-company typecheck
pnpm --filter @paperclipai/agent-company test:run
pnpm --filter @paperclipai/agent-company build:dir
```
## Results
- lint: passed (0 errors, 0 warnings)
- typecheck: passed
- unit tests: passed
- integration tests: passed
- Electron smoke E2E: passed
- macOS directory packaging: passed
## Validation Refresh (2026-03-13)
- reran the full gate locally on macOS:
- `pnpm lint`
- `pnpm typecheck`
- `pnpm test:run`
- `pnpm build:dir`
- all commands passed without blocking errors
- package output again completed with ad-hoc macOS signing and no notarization credentials
## Packaging Notes
- `build:dir` now routes through [build-desktop.mjs](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/scripts/build-desktop.mjs)
- default local packaging disables automatic signing identity discovery unless explicitly overridden
- macOS packaging completed with ad-hoc signing fallback and skipped notarization when notarization credentials were not configured
- custom app icons are now provided through [electron-builder.yml](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/electron-builder.yml) and [assets](/Users/zacharyzhang/Documents/Github/paperclip/AgentCompany/assets)
## Platform Verification Boundary
- verified on local macOS host
- Windows and Linux packaging configuration exists but was not executed on this host
+41
View File
@@ -0,0 +1,41 @@
# Phase 9: Code Reviewer
## Correctness Fixes Applied
- removed `better-sqlite3` from the desktop runtime and replaced it with `node:sqlite`
- fixed packaged runtime resolution for `electron-log/main.js`
- bundled local adapter workspace packages into the main-process build instead of leaving
broken runtime imports behind after packaging
- hardened trusted-sender checks for IPC invocation
- pinned connector commands to audited runtime defaults instead of accepting arbitrary renderer
overrides
- scoped secrets to companies and resolved secret bindings by `companyId`
- validated worker messages at runtime instead of trusting unchecked casts
- closed a test coverage gap where `*.test.ts` files were present but excluded from Vitest
## Runtime Review
- renderer responsiveness is acceptable for the current feature set, but continued extraction
of shell sections into smaller components remains a maintenance priority
- heavy agent execution stays out of the renderer through the utility process boundary
- background database work is local and bounded; privileged tasks do not run directly in the
renderer
- critical run lifecycle writes now execute transactionally
- lint baseline is now warning-free via `eslint.config.mjs` and `pnpm lint`
## Remaining Performance Risks
- the renderer bundle is still large enough that future work should split heavier sections and
defer rarely used surfaces
- cross-platform production profiling has not yet been run on Windows and Linux hardware
## Performance Snapshot (2026-03-13)
- renderer JS bundle (`out/renderer/assets/index-*.js`): 1,162,405 bytes (~1.11 MB)
- renderer CSS bundle (`out/renderer/assets/index-*.css`): 43,344 bytes (~42.3 KB)
- main bundle (`out/main/index.js`): ~142.9 KB
- main connector chunk (`out/main/chunks/connectors-*.js`): ~146.2 KB
- preload bundle (`out/preload/index.js`): ~137.7 KB
The primary optimization target remains renderer bundle splitting and lazy-loading of low-frequency
surfaces.
+56
View File
@@ -0,0 +1,56 @@
# Phase 10: Security Auditor
## Security Posture
The desktop app now follows the required Electron baseline:
- `contextIsolation: true`
- `nodeIntegration: false`
- `sandbox: true`
- minimal preload bridge
- no direct renderer access to filesystem, shell, or process APIs
## Verified Controls
- IPC channels are explicitly named and typed in `src/shared/contracts.ts`
- privileged handlers validate payloads with Zod on the main-process side
- IPC invocation is rejected for untrusted sender frames
- `window.open` and `webview` attachment are denied
- navigation outside approved content is blocked
- packaged renderer content is served through a controlled `app://` protocol handler with path
traversal protection
- `openPath` is restricted to managed workspace, log, artifact, backup, and profile paths
- connector execution commands are pinned to the audited connector binary instead of renderer
overrides
- secrets are company-scoped and secret binding resolution is company-aware
- `safeStorage` is required for production secret writes; the insecure vault fallback is limited
to explicit test environments
- worker-to-main messages are validated at runtime before mutating run state
- **TODO**: Electron binary fuse hardening is NOT yet configured. Before public release,
add `@electron/fuses` to disable `runAsNode`, `NODE_OPTIONS` / inspect CLI argument injection,
enforce app-from-ASAR loading, and enable ASAR integrity validation
## Release Hygiene
- local builds do not auto-discover signing identities unless explicitly configured
- desktop packaging defaults to `--publish never` to prevent accidental channel publication from local/CI build jobs
- updater configuration remains present but still requires a real trusted update endpoint before
public distribution
- notarization and production signing credentials are intentionally external to source control
## Open Release Conditions
The app is appropriate for internal alpha and signed beta preparation. Public production release
still requires:
- real signing credentials per platform
- notarization on macOS
- trusted update hosting
- platform-native validation for Windows and Linux installers
## Re-Verification Notes (2026-03-13)
- reran lint, typecheck, tests, and macOS directory packaging with no security regressions
- static source review confirmed no renderer-side `eval` / `new Function` usage
- privileged surface remains preload-bridged through typed IPC channels only
- `child_process.spawn` usage stays in main process and is constrained to connector command checks
+199
View File
@@ -0,0 +1,199 @@
# Phase 11: ProjectManager Release Readiness
## Milestone Status
- architecture freeze: complete
- interactive prototype: complete
- internal alpha desktop shell: complete
- macOS local packaging validation: complete
- signed beta build: pending signing/notarization credentials and platform-host verification
- release candidate: pending Windows and Linux package validation
- production release readiness: pending platform signing completion and final release-channel credentials
## What Is Ready
- dedicated Electron-native desktop workspace under `AgentCompany`
- explicit main / preload / renderer / shared separation
- local-first profile, secret storage, orchestration worker, IPC contracts, and desktop shell
- onboarding to first usable shell flow
- packaging configuration for macOS, Windows, and Linux
- warning-free local lint baseline across main/preload/renderer
- validation gate rerun on 2026-03-13 passed (`lint`, `typecheck`, `test:run`, `build:dir`)
- **TODO**: PR CI quality gate workflow (`.github/workflows/agent-company-pr-verify.yml`) has not been created yet
- **TODO**: Electron production fuse hardening has not been configured yet (see doc 11)
- packaging script now defaults to `--publish never` unless explicitly overridden (`AGENTCOMPANY_ELECTRON_PUBLISH` or explicit `--publish`)
## Release Ownership Boundaries
| Area | Primary owner | Backup owner | Scope boundary | Exit evidence |
| --- | --- | --- | --- | --- |
| Release gate decision | CEO / ProjectManager | Product lead | Approves go/no-go only after all gates are green; does not bypass security/platform sign-off | Signed release checklist + release tag decision |
| Signing credentials | Security Auditor | Platform Release Engineer | Manages cert issuance/rotation and secret distribution; build operators never commit secrets | Secret inventory record + cert expiry check |
| macOS signing + notarization | macOS Release Engineer | Security Auditor | Runs signed build on macOS host and validates notarization ticket | `spctl`, `codesign`, `stapler` evidence |
| Windows signing + installer trust | Windows Release Engineer | Security Auditor | Runs NSIS build on Windows host and validates Authenticode chain | `Get-AuthenticodeSignature` evidence |
| Linux package validation | Linux Release Engineer | QA lead | Builds and smoke-tests AppImage on Linux host; verifies runtime dependencies | AppImage launch and smoke checklist |
| Updater endpoint trust | Security Auditor | SRE / Infra | Owns TLS/domain trust policy and update channel integrity checks | `latest*.yml` metadata + artifact hash verification |
| Cross-platform functional smoke | QA lead | Platform engineers | Verifies startup/onboarding/task-run/approval flows on each target OS | Smoke run logs + screenshots |
## Release Checklist (Production Candidate)
- [ ] `pnpm install --frozen-lockfile` completed on release host
- [ ] `pnpm lint` passed
- [ ] `pnpm typecheck` passed
- [ ] `pnpm test:run` passed
- [ ] `pnpm build:dir` passed
- [ ] signing environment variables are set from secret manager (not shell history files)
- [ ] `AGENTCOMPANY_UPDATE_URL` points to production or staging trusted domain (not `example.invalid`)
- [ ] updater checks are enabled for release validation (`AGENTCOMPANY_DISABLE_UPDATES=false`)
- [ ] macOS signed build + notarization validation completed on macOS host
- [ ] Windows signed installer validation completed on Windows host
- [ ] Linux AppImage validation completed on Linux host
- [ ] update metadata (`latest*.yml`) and published artifacts hash-match
- [ ] secrets regression check completed (existing local secrets remain readable after upgrade)
- [ ] local data migration test completed (old profile boots and migrates without data loss)
- [ ] final go/no-go approved by CEO / ProjectManager
## Runbook
### 1. Preflight (all platforms)
```sh
pnpm install --frozen-lockfile
pnpm lint
pnpm typecheck
pnpm test:run
pnpm build:dir
```
Expected: all commands pass; no skipped failures are allowed unless explicitly waived in release notes.
### 2. Signing Material Readiness
Prepare these values in CI secret manager or local secure vault:
- `AGENTCOMPANY_UPDATE_URL`
- `CSC_LINK`
- `CSC_KEY_PASSWORD`
- `WIN_CSC_LINK`
- `WIN_CSC_KEY_PASSWORD`
- macOS notarization credentials (`APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, `APPLE_TEAM_ID`) if using Apple ID flow
Sanity check before release build:
```sh
env | rg "^(AGENTCOMPANY_UPDATE_URL|CSC_LINK|WIN_CSC_LINK|APPLE_ID|APPLE_TEAM_ID)="
```
### 3. macOS Signed Build + Notarization (native macOS host)
1. Enable release-mode updater behavior and set trusted update URL.
2. Build signed artifacts.
3. Validate signature + notarization ticket.
```sh
export AGENTCOMPANY_DISABLE_UPDATES=false
export AGENTCOMPANY_UPDATE_URL="https://updates.<your-domain>/agentcompany/stable"
export CSC_LINK="file://$HOME/.signing/agentcompany-mac.p12"
export CSC_KEY_PASSWORD="<from-secret-manager>"
export CSC_IDENTITY_AUTO_DISCOVERY=true
export APPLE_ID="<apple-notarization-account>"
export APPLE_APP_SPECIFIC_PASSWORD="<app-specific-password>"
export APPLE_TEAM_ID="<team-id>"
pnpm build -- --mac dmg zip --publish never
spctl -a -vv "build/release/mac/AgentCompany.app"
codesign -dv --verbose=4 "build/release/mac/AgentCompany.app" 2>&1 | rg "Authority=|TeamIdentifier="
xcrun stapler validate "build/release"/*.dmg
```
Notes:
- For public macOS distribution, switch `mac.hardenedRuntime` to `true` with proper entitlements before final GA build.
- Keep ad-hoc signing only for local development and internal unsigned testing.
### 4. Windows Signed Installer Validation (native Windows host)
```powershell
$env:AGENTCOMPANY_DISABLE_UPDATES = "false"
$env:AGENTCOMPANY_UPDATE_URL = "https://updates.<your-domain>/agentcompany/stable"
$env:WIN_CSC_LINK = "C:\signing\agentcompany-win.pfx"
$env:WIN_CSC_KEY_PASSWORD = "<from-secret-manager>"
pnpm build -- --win nsis --x64 --publish never
Get-ChildItem .\build\release\*.exe | Get-AuthenticodeSignature |
Format-Table Path, Status, @{Name='Signer';Expression={$_.SignerCertificate.Subject}}
```
Expected:
- `Status` is `Valid`
- signer subject matches the intended publisher identity
### 5. Linux AppImage Validation (native Linux host)
```sh
export AGENTCOMPANY_DISABLE_UPDATES=false
export AGENTCOMPANY_UPDATE_URL="https://updates.<your-domain>/agentcompany/stable"
pnpm build -- --linux AppImage --x64 --publish never
chmod +x build/release/*.AppImage
./build/release/*.AppImage --appimage-version
```
Then run manual smoke validation on Linux:
- app launches and reaches main shell
- company/workspace/agent CRUD works
- task run + approval flow works
- settings toggle for updater works
### 6. Updater Endpoint Trust Verification
1. Validate update metadata endpoint and schema.
2. Verify published artifact hash against metadata.
3. Validate app update check in runtime.
```sh
curl -fsSL "$AGENTCOMPANY_UPDATE_URL/latest.yml" -o /tmp/latest.yml
rg "^(version|path|sha512):" /tmp/latest.yml
```
Hash verification (replace placeholders with actual artifact path/hash from metadata):
```sh
node -e "const fs=require('fs');const crypto=require('crypto');const [file,expected]=process.argv.slice(1);const got=crypto.createHash('sha512').update(fs.readFileSync(file)).digest('base64');if(got!==expected){console.error('sha512 mismatch');process.exit(1)}console.log('sha512 ok');" \
build/release/<artifact-file> \
"<sha512-from-latest-yml>"
```
Runtime verification:
- launch packaged app with `AGENTCOMPANY_DISABLE_UPDATES=false`
- trigger `Check for updates` from Settings
- confirm request goes only to trusted `AGENTCOMPANY_UPDATE_URL` domain
- confirm unsigned/untrusted update payloads are rejected by platform signing checks
### 7. Windows/Linux Native-Host QA Gate
Required evidence per platform:
- startup success + no crash in first 5 minutes
- create company + create workspace + create task + assign agent + run once
- approve one pending approval item
- inspect logs for uncaught errors
- close/reopen app and confirm local data persistence
### 8. Release Close-Out
- publish artifacts and corresponding `latest*.yml` only after all platform owners sign off
- attach evidence bundle (command output, screenshots, hash checks, signatures)
- mark release decision in changelog/release note with approver and timestamp
## Outstanding Risks Before Public GA
- current config keeps `mac.hardenedRuntime: false`; must be enabled with release entitlements for notarized public mac builds
- no trusted production updater endpoint is configured by default (`example.invalid` fallback)
- Windows and Linux validation still requires native host execution each release cycle