Commit Graph
10 Commits
Author SHA1 Message Date
Devin Foley 5ec7ce76e5 Upload company import packages as compressed zip uploads (fix large-company imports through Cloud) (#10531)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Company Import (#10507, hardened in #10523) lets a user upload a
company package on the Import page
> - The page expanded the user's `.zip` into a files map and POSTed it
as ONE inline JSON body — ~40MB for a real company because attachment
blobs get base64-inflated
> - On Paperclip Cloud that body travels browser → harness proxy →
tenant, where it truncated in transit → body-parser 400 → the browser
saw "Failed to fetch", and nothing imported
> - Two compounding causes: the giant inline body itself, and the board
async opt-in riding an `x-paperclip-cloud-*` header that the Cloud
harness strips as anti-spoofing (so async never engaged and the import
held one fragile synchronous connection)
> - This pull request uploads the raw compressed `.zip` as a multipart
request (about a third the size, already compressed) parsed server-side
into the same bundle the importer consumes, and moves the async opt-in
to a proxy-safe `?async=1`
> - The benefit is that a large-company import actually completes
through Cloud: a small compressed upload, a real async job that survives
dropped connections

## Linked Issues or Issue Description

- Refs #10507 / #10523 (Import/Export and its hardening). No open issue;
problem described above (large-company browser import through a proxy:
inline JSON body truncates → 400 → "Failed to fetch"; async opt-in
header stripped by the front door → async never engages).

## What Changed

- **Multipart zip transport.** The Import page uploads the raw `File` as
`multipart/form-data` (field `package`, import options in a JSON `meta`
field); the server unzips it into `{ rootPath, files }` and runs the
exact existing preview/import logic. The `application/json` inline path
is byte-identical for CLI/programmatic callers. Bare `application/zip`
(meta via `?meta=`) is also accepted for programmatic use.
- **Shared node zip reader.** `packages/shared/src/portability-zip.ts`
(node-only subpath, not re-exported to the browser bundle — same pattern
as `portability-hash.ts`); the CLI's `zip.ts` becomes a thin re-export.
Identical codec (STORE + DEFLATE via `inflateRawSync`, rejects data
descriptors/zip64).
- **Proxy-safe async signal.** `wantsAsyncImport` = `?async=1` (board
browsers, survives the harness) OR the existing
`x-paperclip-cloud-async-import` header (cloud tenants, set
server-side). The UI async client now uses `?async=1`. Backward
compatible.
- **Size + preflight.** New `PORTABLE_ZIP_UPLOAD_LIMIT_BYTES = 128MB`;
the inline 56MB preflight no longer gates the zip path (it shows the
compressed size instead). Async submit/poll/resume, the duplicate-guard
fingerprint (now over the resolved bundle), pause-on-import,
progress/error panels, and activation all apply to the multipart path.
- OpenAPI documents json + multipart + zip bodies and the `async` query
param.

## Verification

- Full typecheck chain (shared, server, ui, cli) clean.
- 152 tests across 8 files: new `portability-zip.test.ts`
(STORE/DEFLATE/base64-blob byte-exact round-trip, truncation throws,
data-descriptor rejection); `company-portability-routes.test.ts` +7
(multipart import+preview equals the inline bundle; async multipart
202→poll→success; board async via `?async=1` with no cloud header;
cloud-tenant async via header; sync fallback with neither; truncated-zip
400, nothing imported); `CompanyImport.test.tsx` asserts the local zip
sends the raw File and the inline preflight no longer blocks;
`openapi-routes.test.ts` green.
- NOT yet measured: the end-to-end browser upload through the live Cloud
harness — verified on staging after deploy before closing out.

## Risks

- Import semantics unchanged — only transport changed; the JSON inline
path is byte-identical, the cloud-tenant header async path untouched.
Multipart parsing is server-side (memory-bound: a ~13MB zip → ~30MB
files map, fine on the server).
- The bare `application/zip` path is programmatic-only and covered by
content-type dispatch but not a dedicated route test (the multipart path
is).

## Model Used

- Claude Fable 5 (`claude-fable-5`, Anthropic), Claude Code CLI,
extended thinking + tool use; root-caused against live logs/DB and the
harness proxy source.

## 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 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-07-30 18:48:22 -07:00
Devin Foley 276ae3a75d Harden company import: durable UI, async jobs, integrity guard, batched inserts (#10523)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Company Import/Export (#10507) moves whole companies between
instances as portability bundles
> - Real-world use on a large company (1,418 issues, ~10.6k comments)
surfaced a cluster of related failures: the import took hours and the
browser connection died while the server kept running, a retry silently
produced a second partial import, the progress/error UI gave no durable
signal, and a cloud-tenant user couldn't even open the companies
afterward
> - Root cause of the slowness: importBundle inserted every issue,
comment, and document as a separate round-trip to a network Postgres —
an N+1-over-network pattern
> - This pull request hardens the whole import path: durable
progress/error UI, an async server-side job so imports survive dropped
connections (with a duplicate-submit guard), a fail-closed guard against
incomplete payloads, and batched inserts that cut a large import from
hours to minutes
> - The benefit is that migrating a real, large company actually
completes, is legible while it runs, and can't half-import twice

## Linked Issues or Issue Description

- Refs #10507 (the Import/Export feature this hardens). Supersedes
#10513 (the progress/error-UI piece, folded in here). No open issue;
problem described above (large-company import: slow, connection-fragile,
silently duplicable, opaque UI).

## What Changed

- **Batched inserts (perf):** importBundle pre-generates entity ids in
JS and inserts in chunked multi-row statements, so children no longer
wait on parents' generated ids. A 1,418-issue import drops from ~15,600
insert statements to **82** (190×); benchmark below. Import semantics —
collision handling, pause-on-import,
label/blocker/monitor/attachment/embedded-asset handling, blob sha
verification — are unchanged (full portability suite green).
- **Async import jobs for board sessions:** the existing cloud-tenant
async job path opens to board sessions with per-actor job keys; the
import page submits, polls, and resumes watching after a reload or
dropped connection instead of holding one fragile request. A
non-terminal job blocks a duplicate submit (409 returns the running
job), preventing the double-import.
- **Fail-closed completeness guard:** an optional `expectedFileCount` on
inline imports; the server rejects (422 `import_payload_incomplete`) a
body carrying fewer files than declared, so a re-framed/short payload
fails loudly instead of half-importing.
- **Durable progress/error UI (was #10513):** persistent progress panels
with size-aware copy, persistent error panels with retry guidance, and
inline explanation when the preview button is disabled;
request-lifecycle guards so stale previews/imports can't publish or
detach.

## Verification

- `pnpm -r` typechecks (shared, server, ui) clean.
- `company-portability.test.ts` (76) +
`company-portability-routes.test.ts` (30) green — the import correctness
net — plus new `CompanyImport.test.tsx` async/resume/409 coverage and a
new batching regression test (a 50-issue import issues <50 issue-insert
statements; rows land unchanged).
- **Batching benchmark (embedded Postgres):** at 1,418 issues × 7
comments × 1 doc — 82 insert statements vs ~15,598 one-per-row (190×),
~1s wall-clock; a row-verifying run at that scale imports all 1,418
issues / 9,926 comments / 1,418 documents with unique identifiers and no
warnings (no rows dropped by chunking). Over a network DB the round-trip
reduction is the hours→minutes lever.
- What is NOT directly measured here: wall-clock against a real network
Postgres (that happens on a staging deploy); the local timing is
network-free.

## Risks

- Batching is the load-bearing change: it rewrites the import write
path. Mitigated by the unchanged 106-test correctness suite, a new
scale/row-integrity test, and per-writer transactions (a failure rolls
back its table group; not a single outer transaction across writers —
noted, correctness preserved).
- Async jobs are in-memory (lost on server restart → pollers 404 and can
resubmit); matches the pre-existing cloud-tenant job semantics.
- `expectedFileCount` is optional (older callers unaffected); over-count
is allowed, only under-count fails closed.

## Model Used

- Claude Fable 5 (`claude-fable-5`, Anthropic), Claude Code CLI,
extended thinking + tool use; implementation across Fable 5 subagents
with live diagnosis against a running instance.

## 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 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-07-30 16:52:58 -07:00
DottaandPaperclip a116713b9a feat(mcp) [split 6/8]: add Tools and Profiles UI foundation (#9561)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Governed MCP access spans contracts, runtime enforcement, adapters,
UI surfaces, and operator verification
> - The parity reference PR #9534 is too large for effective automated
or human review
> - The feature therefore needs a linear stack whose individual diffs
stay below the 100-file review limit
> - This pull request is split 6/8 and focuses on UI API, shared
components, and Tools/Profile surfaces
> - The benefit is a standalone, testable review boundary while
preserving byte-for-byte parity at the top of the stack

## Linked Issues or Issue Description

- Related parity reference: #9534
- Problem: Operators need typed clients and administration surfaces that
compile independently before navigation exposes them.
- Proposed solution: Adds UI APIs, hooks, libraries, shared components,
Tools/Profiles pages, and the plugin settings consumer required by the
new company-scoped API.
- Alternatives considered: keeping #9534 as one 403-file review, or
rewriting the feature to manufacture seams; both were rejected in favor
of path extraction plus compile-driven boundary moves.
- Roadmap alignment: this advances the existing governed MCP/tool-access
work already represented by #9534; it does not introduce a separate
roadmap initiative.
- Stack position: base branch is
`pap10341-split/05-runtime-integration`.
- Merge policy: merge bottom-up, in order, only after the complete
eight-PR stack has been reviewed and the top-of-stack parity gate
remains empty.
- Requested review: UXDesigner sanity pass on Tools/Profile surfaces;
Greptile on every PR.

## What Changed

- Adds UI APIs, hooks, libraries, shared components, Tools/Profiles
pages, and the plugin settings consumer required by the new
company-scoped API.
- Keeps this PR below 100 changed files and independently typecheckable.
- Preserves the final tree from #9534 when combined with the other seven
stack levels.

## Verification

- `pnpm typecheck`
- `pnpm check:token-gates` — all gates clean
- Focused UI Vitest run with `NODE_ENV=test` — 28 files, 183 tests
passed

## Risks

- Large dead-code UI additions can drift from activation routes; PR 7
supplies the registration layer and top-level parity catches omissions.
- Stack risk: merging out of order can expose incomplete layers;
mitigate by following the documented bottom-up merge policy.
- Parity risk: later edits to an intermediate branch can drift from
#9534; mitigate by re-running the empty top-of-stack diff before merge.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.4`; runtime-managed context
window; medium reasoning with repository, shell, Git, GitHub CLI, and
code-execution tools enabled.

## 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] Internal references are omitted except the execution-plan link
explicitly required for this coordinated split stack
- [x] My branch name describes the change 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


## Stack Coordination

- Internal execution plan:
[PAP-13874](/PAP/issues/PAP-13874#document-plan)
- Parity reference: #9534
- Stack: #9556 → #9557 → #9558 → #9559 → #9560 → #9561 → #9562 → #9563
- Merge bottom-up only after full-stack review and an empty parity diff
at #9563.


## UI Evidence

QA captured these from the live Garden MCP split stack at 1440px and
verified clean rendering:

![Profiles
index](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/profiles-index.png)

![Profile
wizard](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/profile-wizard.png)


![Policies](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/policies.png)

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-14 15:31:12 -05:00
DottaandPaperclip 176645187c Fix request storm polling and issue-list coalescing (#9190)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The board UI keeps issue, agent, activity, and run state fresh
through polling across several pages and sidebar surfaces
> - When multiple components or browser tabs poll the same company data
at the same time, the API can receive bursts of duplicate issue-list
requests
> - Those duplicate requests increase database and server load without
returning meaningfully different data
> - This pull request adds server-side compression/coalescing plus
client-side visibility-aware and cross-tab shared polling
> - The benefit is lower request volume during normal board usage while
preserving fresh UI data for active users

## Linked Issues or Issue Description

No exact public GitHub issue was found for this request.

Problem:
- The board can issue redundant polling requests for the same issue-list
data from multiple UI surfaces and tabs.
- In busy operator sessions, those bursts can trigger request-storm
behavior and unnecessary issue-list load.
- Expected behavior is to reuse identical in-flight work server-side and
reduce hidden-tab or duplicate-tab polling client-side while preserving
normal refresh behavior.

Related public context found during duplicate search:
- #8206 covers a different board UI 404-storm scope.
- #5165 covers separate issue-list behavior around page-size truncation.

## What Changed

- Added API compression middleware foundation and a company/created-at
index for heartbeat run access.
- Added server-side issue-list request storm detection and identical
in-flight request coalescing.
- Added UI fetch metadata, visibility-aware polling, and request
deduplication for issue/activity/client calls.
- Added cross-tab shared polling primitives and wired them into the
sidebar, inbox, dashboard, issue, project, routine, and agent surfaces.
- Resolved the latest `master` migration collision by keeping upstream
`0140_built_in_managed_resources.sql` and renumbering this branch's
heartbeat-run index migration to
`0141_heartbeat_runs_company_created_at_index.sql`; the SQL uses `CREATE
INDEX IF NOT EXISTS` for idempotency.
- Stabilized server heartbeat cleanup tests exposed by the PR check
matrix.
- Fixed the Greptile compression follow-up by weakening strong ETags on
encoded JSON responses and bypassing compression for streamed/download
responses.

## Verification

- `pnpm exec vitest run ui/src/components/IssuesList.test.tsx
ui/src/pages/Inbox.test.tsx` — passed after resolving the latest
`master` conflict in `IssuesList.tsx` and updating the 200-result cap
expectations.
- `pnpm check:token-gates` — passed after the UI conflict resolution.
- `jq -e '.entries | length as $n | (map(.idx) | unique | length == $n)
and (map(.tag) | unique | length == $n)'
packages/db/src/migrations/meta/_journal.json` — passed after
renumbering the migration to `0141`.
- `pnpm exec vitest run server/src/__tests__/api-compression.test.ts` -
passed after the compression follow-up.
- `pnpm exec vitest run
server/src/__tests__/issue-list-assignee-filter-routes.test.ts` - passed
after the compression follow-up.
- `pnpm --filter @paperclipai/server typecheck` - passed after the
compression follow-up.
- Greptile Review for head `8dbddac41ec273fda404100b4981ddb912fad57b` -
passed after the latest conflict/migration fix; all Greptile review
threads are resolved.
- `pnpm exec vitest run server/src/__tests__/api-compression.test.ts
server/src/__tests__/issue-list-assignee-filter-routes.test.ts
ui/src/api/client.test.ts ui/src/api/issues.test.ts
ui/src/lib/polling.test.ts ui/src/lib/cross-tab-poll.test.ts
ui/src/pages/Inbox.test.tsx ui/src/components/SidebarProjects.test.tsx
ui/src/components/SidebarAccountMenu.test.tsx
ui/src/lib/issueDetailCache.test.ts` — passed.
- `pnpm exec vitest run ui/src/api/client.test.ts` — passed.
- `pnpm exec vitest run ui/src/pages/Inbox.test.tsx
ui/src/components/SidebarProjects.test.tsx
ui/src/components/SidebarAccountMenu.test.tsx
ui/src/lib/issueDetailCache.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/heartbeat-worktree-suppression.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/low-trust-red-team-routes.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts` —
passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- GitHub PR checks for head `8dbddac41ec273fda404100b4981ddb912fad57b`:
all GitHub Actions/status checks passed; Greptile, Superagent, Socket,
Snyk, build, typecheck/release registry, general tests, serialized
server suites, e2e, canary dry run, policy, and commitperclip review are
green; Storybook visual regression and security-review were
skipped/neutral by policy.
- Confirmed this branch does not include `pnpm-lock.yaml` or
`.github/workflows` changes.

## Risks

- Medium risk: issue-list coalescing changes request timing and cache
semantics for a hot API path.
- Medium risk: cross-tab polling uses browser coordination primitives,
so older or unusual browser environments need fallback behavior to stay
correct.
- Low migration risk: the new index migration is ordered after current
`master` and uses `CREATE INDEX IF NOT EXISTS`.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex coding agent, GPT-5-based model, tool-enabled with
shell/git execution. Exact hosted deployment identifier and
context-window size were not surfaced in the agent runtime.

## 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
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 17:38:34 -05:00
b13eb5b2b5 Skill Studio: three-pane skill IDE with sandboxed test runs (#9241)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Skills Manager gives operators a reusable skill layer, but
iteration still required manual edits, ad hoc prompts, and indirect run
inspection.
> - Skill authors need a focused workflow for editing skill files,
saving representative test inputs, and running those inputs through an
agent without exposing harness tasks as normal company work.
> - The backend therefore needs durable test inputs, reusable run
templates, hidden harness issues, scoped run execution, retention
metadata, and read-containment rules around hidden work.
> - The frontend needs a three-pane Studio that keeps skill files, saved
inputs/templates, and run output/history visible together while
preserving the existing design system and token rules.
> - This pull request ships that Skill Studio surface end to end:
database migrations, shared contracts, server APIs/services, hidden
harness execution behavior, UI routes/components, and focused tests.
> - The benefit is faster and safer skill iteration, with inspectable
outputs and fewer ways for internal harness work to leak into normal
task lists, costs, or adjacent read APIs.

## Linked Issues or Issue Description

No public GitHub issue exists for this feature. Feature request summary:

- Problem: Skill authors need to edit and test company skills in one
place instead of switching between the skill detail page, task creation,
run output, and manual prompt history.
- Proposed solution: Add a Skill Studio workbench with saved inputs,
reusable templates, hidden sandboxed test runs, live run status, output
inspection, run history, rerun/delete controls, and frontmatter-aware
editing.
- Expected users: Paperclip operators and agent-company maintainers who
create, fork, import, and tune skills.
- Related public PRs: Supersedes #9205, which was replaced so the public
PR branch name follows contributor policy.
- Duplicate search: searched public GitHub issues and PRs for "Skill
Studio"; no other active public issue or PR directly covers this
feature.

## What Changed

- Added database migrations for Skill Studio test inputs, test runs,
test run retention, and reusable run templates.
- Added shared Skill Studio types, validators, route helpers,
frontmatter utilities, and status handling.
- Added server services and routes for saved inputs, test runs,
templates, reruns, terminal-run deletion, hidden harness issue
execution, and run-detail hydration.
- Strengthened hidden-issue read containment across issue-adjacent
routes and cost rollups used by skill test harness work.
- Added the Skill Studio UI with skill file editing, frontmatter
editing, saved inputs, templates, run creation/cancel/rerun/delete
flows, output rendering, history, route support, and responsive pane
behavior.
- Added focused backend, shared, and UI tests for the new APIs, routing
logic, editor/run behavior, hidden-issue containment, and migration
safety.
- Rebased onto current `master`, removed the generated lockfile diff
from the PR, and verified no workflow files are changed.

## Verification

- [x] `pnpm --filter @paperclipai/db check:migrations`
- [x] `pnpm check:token-gates`
- [x] `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/company-skill-test-runs-service.test.ts
ui/src/lib/skill-studio.test.ts ui/src/pages/SkillStudio.test.tsx` — 5
files, 132 tests passed
- [x] Greptile review on the latest PR head
- [x] GitHub PR checks on the latest PR head

## Risks

- Medium risk because this is a broad feature touching database schema,
server orchestration, issue visibility, and a large UI surface.
- Hidden harness issue containment is security-sensitive; this PR
includes regression coverage for adjacent read paths and cost rollups.
- The new migrations are additive and use idempotent guards where
applicable, but deployed databases that previously tested draft
migration numbers should still be checked carefully.
- The UI depends on a new resizable panels package in `ui/package.json`;
the lockfile is intentionally left to repository automation.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex, GPT-5 coding agent with shell, git, and GitHub CLI tool
use. Earlier feature commits include assistance from other Paperclip
coding agents; this PR preparation, rebase, cleanup commit, and PR body
were completed by OpenAI Codex in a Paperclip worktree.

## 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
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:08:56 -05:00
dottaandPaperclip 21765f8118 Fix trigger delete: handle 204 No Content in API client
The DELETE /routine-triggers/:id endpoint returns 204 No Content, but
the API client unconditionally called res.json() on all responses,
causing a JSON parse error that surfaced as "API route not found".

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-19 17:31:27 -05:00
DottaandPaperclip 45998aa9a0 feat(issues): add issue documents and inline editing
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-13 21:30:48 -05:00
ForgottenandClaude Opus 4.6 2ec45c49af feat(ui): add auth pages, company rail, inbox redesign, and page improvements
Add Auth sign-in/sign-up page and InviteLanding page for invite acceptance.
Add CloudAccessGate that checks deployment mode and redirects to /auth when
session is required. Add CompanyRail with drag-and-drop company switching.
Add MarkdownBody prose renderer. Redesign Inbox with category filters and
inline join-request approval. Refactor AgentDetail to overview/configure/runs
views with claude-login support. Replace navigate() anti-patterns with <Link>
components in Dashboard and MetricCard. Add live-run indicators in sidebar
agents. Fix LiveUpdatesProvider cache key resolution for issue identifiers.
Add auth, health, and access API clients.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 14:41:21 -06:00
ForgottenandClaude Opus 4.6 6d0f58d559 fix: storage S3 stream conversion, API client FormData support, and attachment API
Fix S3 provider to use async generator for web stream conversion instead
of Readable.fromWeb, add postForm helper and attachment API methods to
the UI client, and add local disk storage provider tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:33:10 -06:00
ForgottenandClaude Opus 4.6 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