Commit Graph

12 Commits

Author SHA1 Message Date
Devin Foley 236588c753
fix(ui): stamp the service worker with a per-build id so deploys reach parked tabs (#12725)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The web UI ships a service worker (`ui/public/sw.js`) plus update
logic (`ui/src/lib/service-worker-updates.ts`) whose job is to keep
long-lived, parked SPA tabs on the freshly deployed bundle.
> - That reload-on-update path fires only on `controllerchange` — i.e.,
only when the browser installs a new `sw.js`.
> - But `sw.js` was a static public asset (`CACHE_NAME =
"paperclip-v2"`), copied verbatim and never varying per deploy, so a
normal deploy (new app bundle, unchanged `sw.js`) installed no new
worker and triggered no reload.
> - So a parked tab kept running the old bundle after a deploy until a
manual reload — the exact failure the update logic was written to
prevent.
> - This pull request makes `sw.js` change whenever the app bundle
changes, by stamping it with a per-build id at build time.
> - The benefit is that shipped UI fixes actually reach open tabs,
instead of waiting for each user to reload by hand.

## Linked Issues or Issue Description

No separate issue. Describing the bug in-PR using the bug-report fields:

**What happened?**
After a deploy that changes the app bundle but not `sw.js`, tabs left
open across the upgrade keep running the old bundle indefinitely. The
network-first service worker means a manual reload always recovers, but
nothing triggers that reload automatically. Concretely, the `2026.831.1`
onboarding fix did not reach tabs that were open on `2026.831.0`.

**Expected behavior**
When a new bundle is deployed, the existing update machinery
(`registration.update()` on visibility/interval, reload on
`controllerchange`) should bring parked tabs onto the new bundle without
a manual reload.

**Steps to reproduce**
1. Open the app and leave the tab open.
2. Deploy a build that changes the app bundle but not `sw.js` (the
common case — `sw.js` was static).
3. Observe the open tab keeps running the previous bundle; no new worker
installs, so no `controllerchange` and no reload.

**Paperclip version or commit**
Reproduced against `2026.831.1` and `master` before this change.

**Deployment mode**
Any web deployment that serves the built UI (local trusted quickstart,
managed, or self-hosted).

Related PRs (searched open + closed before opening this one):
- Refs #12198 (merged) — added the parked-tab
`update()`/`controllerchange` reload logic this PR completes by making
`sw.js` actually change per deploy.
- Refs #9951 (open) — an alternative "prompt to reload on new build"
approach to the same problem; this PR instead reuses the existing silent
auto-reload path. Reviewers may want to pick one.
- Refs #8112 (open) — serves `sw.js` with `no-cache`; complementary
(that keeps the worker script itself fresh; this makes the script vary
per build).

## What Changed

- `ui/public/sw.js`: derive `CACHE_NAME` from a `__PAPERCLIP_BUILD_ID__`
placeholder so the worker source varies per build.
- `ui/src/lib/vite-sw-build-id.ts`: new Vite build plugin that rewrites
the placeholder in the emitted `sw.js` with the entry chunk's content
hash (stable when the app is unchanged, new when it changes). Throws if
the placeholder is missing, so the worker can never silently stop
rotating.
- `ui/vite.config.ts`: register the plugin.
- `ui/src/lib/vite-sw-build-id.test.ts`: unit tests for the stamping
helper, the build-id derivation, and a contract test that `public/sw.js`
still carries the placeholder.

## Verification

- `vitest run ui/src/lib/vite-sw-build-id.test.ts` — 7 tests pass.
- `vite build` — the emitted `dist/sw.js` contains `BUILD_ID =
"index-<hash>"` matching the entry chunk `dist/assets/index-<hash>.js`,
and the `__PAPERCLIP_BUILD_ID__` placeholder is gone. A subsequent build
with unchanged app code produces the same id (no needless worker churn);
a build with changed code produces a new id.
- Dev (`vite serve`) leaves the literal placeholder in `sw.js`, where
HMR (not the worker) drives refreshes.

## Risks

- Low risk, build-time only. No runtime service-worker logic changes
beyond the cache name being build-specific; the activate handler already
deletes all caches, so a rotating name is inert there.
- If a future edit removes the placeholder, the build fails loudly
rather than silently shipping a non-rotating worker.

## Model Used

- Claude (Anthropic), model id `claude-fable-5` (Claude Fable 5), used
with tool use, shell commands, file editing, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-03 13:08:19 -07:00
Tonio 384e5f6178
revert(ui): back out onboarding port (#10786) (#11067)
This reverts commit 11e56654f8.

#10786 ported the onboarding flow from a standalone prototype and
repointed `/onboarding` at the new `CloudOnboardingFlow`, deleting the
existing `OnboardingWizard.tsx` in the process. The ported flow is not
ready to be the shipping onboarding experience: it landed as a single
large port rather than an incremental migration, it pulled `motion`,
`three` and `@types/three` onto the UI dependency list for prototype
visuals, and it deleted the wizard that four in-flight pull requests
(#9900, #9501, #8982 and one more) were building on — those went
CONFLICTING the moment the file disappeared.

Rather than keep the half-migrated state on master while that is sorted
out, back the port out whole and re-land it incrementally. This restores
`OnboardingWizard.tsx` and the previous versions of the four e2e specs,
drops the `onboarding-preview.html` Vite entry, the DesignGuide
onboarding section and the `data-viz-misc` storybook story, and removes
the three prototype dependencies from `ui/package.json`.

This is an exact mechanical inverse of the squash commit — 41 files,
+2089/-3647, no hand edits. Reverting this commit restores all 41 files
byte for byte, so the port is recoverable in full when it is ready.

`pnpm-lock.yaml` is deliberately not touched. #10786 never updated it;
bot commit 4683f26c9 (#11036) added the `motion`/`three` entries
afterwards, so the lockfile is now ahead of the manifest. CI owns
lockfile updates (`.github/workflows/pr.yml`) and the policy job
regenerates it from the changed manifest.

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-07 14:55:34 -07:00
Tonio 11e56654f8
feat(ui): port onboarding flow from prototype; add cloud + local variants (#10786)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - First-run onboarding is the subsystem that turns a brand-new install
into a working company: it creates the company, its goal, a lead agent,
and that agent's first task
> - The existing `OnboardingWizard` carried all of that wiring
correctly, but its UI had drifted from the current design direction, and
a separate design prototype (`paperclip-onboard`) existed as a
standalone visual mock with no backend
> - Porting the prototype's *logic* would have thrown away working,
well-tested backend orchestration; leaving the two apart meant the
design never shipped
> - Separately, cloud and local (self-hosted) installs need meaningfully
different first runs — local has no sign-in and must let the user pick a
locally-installed CLI adapter — so a single linear wizard could not
serve both
> - This pull request rebuilds the presentational layer from the
prototype on top of the existing backend orchestration, and splits it
into two thin flow containers over a shared core
> - The benefit is that the shipped onboarding matches the intended
design, cloud and local can diverge without duplicating logic, and each
can later ship to a different app version while sharing one set of step
components

## Linked Issues or Issue Description

No existing issue — describing inline (feature request).

**What problem does this solve?**
Onboarding is the first thing a new user sees, and the shipped wizard
had drifted from the current design. In parallel, cloud and local
installs need different first-run paths: local has no hosted sign-in,
and its agent runs on a CLI adapter installed on the user's machine,
which the cloud path never has to ask about. There was no way to express
that difference without either forking the whole wizard or bolting
conditionals onto a single linear flow.

**Proposed solution**
Extract the onboarding step views and shell into a shared core, then
compose two thin flow containers (cloud and local) over it. Keep all
backend orchestration in the existing `useOnboardingFlow` hook so no
working logic is rewritten.

**Alternatives considered**
- *Single flow with a `variant` prop* — most DRY, but the two flows are
intended to ship on different app versions, and a shared file would have
to be split later anyway.
- *Two fully independent copies* — simplest per-flow, but every shared
refinement (spacing, motion, copy) would have to be made twice and would
drift.

## What Changed

- **Shared core** under `ui/src/components/onboarding/`:
`OnboardingScaffold` owns the full-screen shell and the single
`AnimatePresence` step crossfade, so both flows transition identically;
step views (Start / Company / Agent / Task), `FooterNav`, `AgentPreview`
and the motion constants are extracted for reuse.
- **`CloudOnboardingFlow`** — `start → company → agent → task`; mounted
in the real app via `OnboardingWizardVariant`. Behaviour matches the
retired wizard, including `previewMock` and the existing-company ("add
an agent") entry point.
- **`LocalOnboardingFlow`** — skips sign-in and adds an optional email
ask (with a privacy assurance), a local model/adapter step that hires
with `requireEnvProbe: true`, and a "star us on GitHub" interstitial
before completing. **Harness-only for now** — the real app still mounts
the cloud flow.
- **Deleted `OnboardingWizard.tsx`** (1,786 lines); updated its
Storybook stories and the `OnboardingWizardVariant` test to the new
components.
- **Orbiting 3D paperclip backdrop** behind the auth and welcome screens
(`three`), code-split so it only downloads on those screens; honours
`prefers-reduced-motion` and disposes its GL context on unmount.
- **`motion`** added for step transitions and the agent-capsule
choreography.
- Visual values routed through design tokens per `DESIGN.md`; `Stepper`
generalized to take a step total (backward compatible); `/design-guide`
page and the component index updated.
- **Standalone preview harness** (`ui/onboarding-preview.html`) with
`?flow=` and `?step=` for backend-free review, wired as a second Vite
rollup input.
- **Adapter env probe bound to the adapter it ran against.**
`hireLeadAgent` reused `adapterEnvResult` for any adapter, so when a
hire failed and the user picked a *different* local adapter and retried,
the previous adapter's verdict satisfied the `requireEnvProbe` guard
while the hire posted the new adapter's config — hiring it unprobed. The
cache is now keyed on the adapter type plus the exact config posted to
the test endpoint, the config is built once and shared by probe and
hire, a failed probe clears the cache, and `clearAdapterEnvResult()`
(called on adapter change) stops the step displaying a stale verdict.
Cloud is unaffected — it hires with `requireEnvProbe: false`. Reported
by Greptile.
- **E2E specs re-pointed at the new flow.** Four specs still drove the
deleted wizard (`onboarding`, `conference-room-typing-intro`,
`planning-mode-visual-verification`, `nux-phase4-screenshots`) and
failed with `element(s) not found` on `"Name your company"` /
`input[placeholder="Acme Corp"]`. Rather than repeat the new drive
sequence four times, `tests/e2e/onboarding-flow.ts` adds one driver per
step (`startCloudOnboarding`, `completeCompanyStep`,
`completeAgentStep`, `completeTaskStep`, `completeCloudOnboarding`) and
the specs import it, so the next flow change touches a single file. Two
now-dead `**/test-environment` route stubs went with it — the cloud flow
hires with `requireEnvProbe: false`, so that probe never fires.

## Verification

- `pnpm --filter @paperclipai/ui typecheck` — clean.
- `npx vitest run` over the onboarding suites
(`OnboardingWizardVariant`, `AgentCapsule`, `onboarding-launch`,
`onboarding-goal`, `onboarding-route`, `onboarding-adapter-config`) — 33
tests pass.
- `pnpm --filter @paperclipai/ui build` — succeeds; the three.js chunk
splits out separately (522 kB raw / 133 kB gzip) rather than entering
the main bundle.
- Both flows driven end-to-end in the preview harness in `previewMock`
(no database writes), plus the cloud flow rendered in the real
authenticated app at `/onboarding` to confirm the mount swap.
- The four re-pointed e2e specs pass locally against the new flow.
- New `ui/src/hooks/useOnboardingFlow.test.tsx` — 4 cases pinning the
adapter-probe cache (switch-adapter retry, cold path, explicit clear,
and the cloud flow's `requireEnvProbe: false`). Verified non-vacuous:
the switch-adapter case fails against the pre-fix code.
- Rebased onto current `master`; `pnpm-lock.yaml` is deliberately
**not** committed — `.github/workflows/pr.yml` regenerates it when a
manifest changes and shares it with downstream jobs as the `pr-lockfile`
artifact.

## Risks

- **Deleting `OnboardingWizard.tsx` is the one change that alters
existing app behaviour.** The cloud flow is intended to be
behaviour-equivalent, and its entry points are covered by the updated
`OnboardingWizardVariant` test, but this is the area to review most
closely.
- **Conflict risk with open PRs that touch the old wizard**: #9900,
#9501, #8982 and #6636 all modify
`ui/src/components/OnboardingWizard.tsx`, which this PR removes.
Whichever lands second will need its change re-applied to the new step
components. Flagging so ordering can be decided deliberately.
- **New dependencies**: `motion` and `three` (+ `@types/three`). `three`
is large, so it is lazily imported and code-split — it does not affect
the main bundle. Both are MIT.
- The **local flow is not reachable in the app** yet (harness/canary
only), so it carries no runtime risk today; wiring it up is a follow-up.
- The auth screens remain **presentational only** — they are not wired
to real auth, unchanged from before this PR.
- **Pre-existing, not introduced here:** `OnboardingWizardVariant`
renders outside `<Routes>` in `App.tsx`, so its `useParams()` never
resolves `:companyPrefix` and `/{prefix}/onboarding` opens the welcome
screen instead of jumping to the agent step. `master` has the identical
structure, so this PR faithfully ports existing behaviour; the working
"add an agent" entry is the launcher card behind the overlay, which is
what the screenshot spec drives. Worth a separate fix.

## Model Used

Claude Opus 5 (`claude-opus-5`) via Claude Code, with extended thinking
and tool use (repo search/edit, local test + build execution, and
browser-driven visual verification of the rendered flows). Portions of
the session also ran on `claude-opus-4-8` and `claude-fable-5`.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:35:05 -07:00
Devin Foley 97590ff8c4
feat(dev): add pnpm dev:mobile and dev:both for prebuilt UI preview (#10718)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The board UI is a React SPA served by the paperclip server; the
standard local dev flow is `pnpm dev`, which runs vite in dev mode with
HMR and an unbundled module graph
> - The unbundled dev bundle is hundreds of MB of JS across many
requests, which is fine on a local machine but unusable from a phone or
tablet on slow/lossy links (airplane wifi, mobile data, distant tailnet
peers)
> - Contributors who want to iterate on the board from a mobile device
today have no supported way to preview a small production-shaped bundle
without stopping the dev server and running a one-off `vite preview`
with manual proxy plumbing
> - This pull request adds `pnpm dev:mobile` — build the UI and serve
`ui/dist` via `vite preview` on port 3101, with `/api` proxied to the
running dev server on 3100 — plus `pnpm dev:both` to run both flavors
together
> - The benefit is a supported second flavor of the dev server for
phones/tablets that runs alongside the normal one, without touching the
primary `pnpm dev` flow

## Linked Issues or Issue Description

**Subsystem affected**

ui/ — React + Vite board UI

**Problem or motivation**

The vite dev server serves an unbundled module graph, which is fine on
localhost but unusable from a phone or tablet on a slow link.
Contributors testing responsive behavior on mobile devices have no
supported way to serve a small production-shaped SPA against the running
dev API. Running `vite preview` directly does not work either — the
server's board mutation guard checks that the browser's Origin matches
the request Host, and a preview on a second port would fail every
mutation.

**Proposed solution**

Add two root scripts:

- `pnpm dev:mobile` — build `ui/dist` and serve it via `vite preview` on
port 3101, with `/api` proxied to the API server on 3100.
- `pnpm dev:both` — run `pnpm dev` and `pnpm dev:mobile` together in a
single terminal with prefixed output and shared signal handling.

The vite preview config binds `0.0.0.0`, sets `allowedHosts: true` so it
accepts arbitrary hostnames (LAN, tailnet, ngrok, etc.), and the shared
`/api` proxy forwards the client's original Host header as
`x-forwarded-host`. The paperclip server's mutation guard already
prefers `x-forwarded-host` over `host` when computing trusted origins,
so the browser's Origin becomes trusted automatically.

**Alternatives considered**

- Bespoke node proxy script — works but duplicates what vite preview
already does.
- Loosen the mutation guard to accept arbitrary origins — reduces
security for the primary server for the sake of a dev-only workflow.
- Second server config that binds a second port from the paperclip
server itself — much larger change and mixes runtime concerns with a
dev-tooling convenience.

## What Changed

- New `pnpm dev:mobile` script — build UI then run `vite preview` on
port 3101.
- New `pnpm dev:both` script — run `pnpm dev` and `pnpm dev:mobile`
together via `scripts/dev-both.mjs`, which prefixes each child's output,
propagates SIGINT/SIGTERM, and exits when either child exits.
- `ui/vite.config.ts` — add a `preview` block (port 3101, host
`0.0.0.0`, `allowedHosts: true`, shared `/api` proxy).
- New `ui/src/lib/vite-api-proxy.ts` — extracts the `/api` proxy factory
shared by dev and preview, and forwards the client Host as
`x-forwarded-host` (plus `x-forwarded-proto`).
- New unit test `ui/src/lib/vite-api-proxy.test.ts` covering the
header-injection behavior and the pass-through when no Host is present.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/vite-api-proxy.test.ts` — 3 tests pass.
- `pnpm --filter @paperclipai/ui typecheck` — clean.
- `pnpm --filter @paperclipai/ui build` — clean.
- Manual: ran `vite preview` against an echo listener and confirmed the
request arrives with `x-forwarded-host` set to the client Host header
and `x-forwarded-proto: http`. Then ran `pnpm dev:mobile` against the
live dev server and verified board mutations (mark issue read, resolve
recovery action, run routine) succeed from a second-port browser session
that previously 403'd.

## Risks

Low risk. Changes are limited to dev tooling — no runtime code paths, no
server changes, no schema/migrations. The `apiProxy` refactor is a no-op
behaviorally for the existing dev server (same target, same `ws: true`);
the only new behavior is the two `x-forwarded-*` headers, and the server
side already prefers those headers when trusting origins. `dev:mobile`
and `dev:both` are additive; existing `pnpm dev` is untouched.

## Model Used

Claude Opus 4.7 (1M context), extended thinking, tool use (bash, file
edits).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-08-02 20:26:03 -07:00
Nicky Leach 2ef70c3673
build(deps): upgrade lexical family to 0.46.0 and pin via overrides (fixes dual-version getType crash) (#9180) 2026-07-07 13:00:26 -07:00
Dotta c1a02497b0
[codex] fix worktree dev dependency ergonomics (#3743)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Local development needs to work cleanly across linked git worktrees
because Paperclip itself leans on worktree-based engineering workflows
> - Dev-mode asset routing, Vite watch behavior, and workspace package
links are part of that day-to-day control-plane ergonomics
> - The current branch had a small but coherent set of
worktree/dev-tooling fixes that are independent from both the issue UI
changes and the heartbeat runtime changes
> - This pull request isolates those environment fixes into a standalone
branch that can merge without carrying unrelated product work
> - The benefit is a smoother multi-worktree developer loop with fewer
stale links and less noisy dev watching

## What Changed

- Serve dev public assets before the HTML shell and add a routing test
that locks that behavior in.
- Ignore UI test files in the Vite dev watch helper so the dev server
does less unnecessary work.
- Update `ensure-workspace-package-links.ts` to relink stale workspace
dependencies whenever a workspace `node_modules` directory exists,
instead of only inside linked-worktree detection paths.

## Verification

- `pnpm vitest run server/src/__tests__/app-vite-dev-routing.test.ts
ui/src/lib/vite-watch.test.ts`
- `node cli/node_modules/tsx/dist/cli.mjs
scripts/ensure-workspace-package-links.ts`

## Risks

- The asset routing change is low risk but sits near app shell behavior,
so a regression would show up as broken static assets in dev mode.
- The workspace-link repair now runs in more cases, so the main risk is
doing unexpected relinks when a checkout has intentionally unusual
workspace symlink state.

## Model Used

- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-04-15 09:47:29 -05:00
Jannes Stubbemann 390502736c
chore(ui): drop console.* and legal comments in production builds (#3728)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The web UI is a single-page app built with Vite and shipped as a
static bundle to every deployment
> - Production bundles carry `console.log` / `console.debug` calls from
dev code and `/*! … */` legal-comment banners from third-party packages
> - The console calls leak internals to anyone opening devtools and
waste bytes per call site; the legal banners accumulate throughout the
bundle
> - Both problems affect every self-hoster, since they all ship the same
UI bundle
> - This pull request configures esbuild (via `vite.config.ts`) to strip
`console` and `debugger` statements and drop inline legal comments from
production builds only

## What Changed

- `ui/vite.config.ts`:
  - Switch to the functional `defineConfig(({ mode }) => …)` form.
- Add `build.minify: "esbuild"` (explicit — it's the existing default).
- Add `esbuild.drop: ["console", "debugger"]` and
`esbuild.legalComments: "none"`, gated on `mode === "production"` so
`vite dev` is unaffected.

## Verification

- `pnpm --filter @paperclipai/ui build` then grep the
`ui/dist/assets/*.js` bundle for `console.log` — no occurrences.
- `pnpm --filter @paperclipai/ui dev` — `console.log` calls in source
still reach the browser console.
- Bundle size: small reduction (varies with project but measurable on a
fresh build).

## Risks

Low. No API surface change. Production code should not depend on
`console.*` for side effects; any call that did is now a dead call,
which is the same behavior most minifiers apply.

## Model Used

Claude Opus 4.6 (1M context), extended thinking mode.

## Checklist

- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Tests run locally and pass
- [x] CI green
- [x] Greptile review addressed
2026-04-15 09:46:12 -05:00
HenkDz c757a07708 fix(adapters): stable sort order, npm/local icons, reinstall dialog, HMR polling on WSL
- Sort GET /api/adapters alphabetically by type (reload no longer shuffles)
- Show red Package icon for npm adapters, amber FolderOpen for local path
- Add reinstall confirmation dialog with current vs latest npm version
- Enable Vite polling when running on /mnt/ (WSL inotify doesn't work on NTFS)
2026-04-03 21:11:24 +01:00
dotta bd0b76072b Fix atomic markdown mention deletion
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-23 16:57:27 -05:00
Forgotten 3dc3813266 Adopt React Query and live updates across all UI pages
Replace custom useApi/useAgents hooks with @tanstack/react-query.
Add LiveUpdatesProvider for WebSocket-driven cache invalidation.
Add queryKeys module for centralized cache key management. Rework
all pages and dialogs to use React Query mutations and queries.
Improve CompanyContext with query-based data fetching.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:24:48 -06:00
Forgotten 22e7930d0b Overhaul UI with shadcn components and new pages
Add shadcn/ui components (badge, button, card, input, select,
separator). Add company context provider. New pages: Activity,
Approvals, Companies, Costs, Org chart. Restyle existing pages
(Dashboard, Agents, Issues, Goals, Projects) with shadcn components
and dark theme. Update layout, sidebar navigation, and routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:32 -06:00
Forgotten c3d82ed857 Add React UI with Vite
Dashboard, agents, goals, issues, and projects pages with sidebar
navigation. API client layer, custom hooks, and shared layout
components. Built with Vite and TypeScript.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:32:04 -06:00