## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The test-drive command starts an isolated instance for local
testing.
> - Source startup builds shared packages before it starts the server.
> - An interrupted build can leave an empty lock directory.
> - Later starts wait without output and fail after 60 seconds.
> - This pull request recovers abandoned locks and shows build progress.
> - Local testing can start again without manual lock removal.
## Linked Issues or Issue Description
**What happened?**
`pnpm paperclipai test-drive` stopped at “Starting Paperclip server…” in
a source checkout. A leftover plugin build lock caused a silent
60-second wait and then a timeout.
**Expected behavior**
Startup should recover an abandoned build lock. It should show when it
waits for a live build. An interrupted or failed build should not leave
partial output that the next start accepts as complete.
**Steps to reproduce**
1. Leave an empty `node_modules/.cache/paperclip-plugin-build-deps.lock`
directory after an interrupted build.
2. Make the shared or plugin SDK build output out of date.
3. Run `pnpm paperclipai test-drive --api-key placeholder --no-browser`
with a fresh data directory.
4. Observe the silent wait at server startup.
**Paperclip version or commit**
Reproduced at `2083bf6f9`.
**Deployment mode**
Local source checkout with an isolated embedded PostgreSQL instance.
Related work: #12894 added test-drive. #12898 restored its credential
inputs. Neither change handles abandoned workspace build locks. No
duplicate fix was found.
## What Changed
- Publish a lock directory with an owner record in one rename.
- Recover locks after their owner and compiler exit. Recover legacy
empty locks after two minutes.
- Keep the lock until the compiler stops on SIGINT or SIGTERM.
- Print build and lock-wait progress.
- Record source, dependency, compiler-config, and output content
fingerprints only after a successful compile. Recover partial output
even when modification times are unchanged.
- Add 12 process-level regression tests and update the development
guide.
## Verification
- `node --test scripts/__tests__/ensure-plugin-build-deps.test.mjs`: 12
tests pass.
- `pnpm exec vitest run --config cli/vitest.config.ts
cli/src/__tests__/test-drive.test.ts`: 32 tests pass.
- `pnpm --filter paperclipai typecheck`: passed.
- `pnpm --filter paperclipai build`: passed.
- Live smoke tests: fresh startup and startup with an abandoned lock
both reach ready state. The API and UI respond. The command creates the
company and CEO and enables worktree execution. Test instances stop
cleanly.
- Full repository `pnpm -r typecheck` and `pnpm build`: passed.
- Full Vitest suite coverage completed using the repository-supported
server, chat, workspace, and serialized shards. The initial local run
needed the fresh-worktree fake native-provider binary built and focused
reruns for port/socket races and load-related timeouts; all affected
tests passed on rerun. Suites skipped by fail-fast exits were run
separately and passed. The initial serial `pnpm test:run` was stopped in
favor of these shards.
- Greptile: 5/5 on commit `8b5a790c2af06a52b5dc76e5f52331966df990b8`,
with all review threads resolved.
- CI: 31 checks passed and two Storybook checks intentionally skipped.
The initial workspace and browser jobs were interrupted by runner
shutdowns; both passed on the second attempt. Build, typecheck, canary
dry run, all general and serialized tests, all browser shards, security
checks, and final verification summaries are green. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34654730783)
## Risks
- This changes shared source-build locking for the CLI and plugin SDK
commands.
- Legacy locks have no owner identity. Recovery uses a two-minute age
threshold for empty legacy directories.
- Startup reads and hashes source and output files to verify the build
cache. Identical direct builds reuse the cache. Changed or partial
output requires a rebuild.
- A reused process ID can delay recovery. Live owner or compiler
processes keep their lock.
- No database, API, or UI contract changes.
## Model Used
OpenAI GPT-6 in Codex, with reasoning, tool use, code execution, and
process-level testing. A more specific API model identifier and
context-window size are not exposed in this session.
## 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
#` 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies through
company-scoped control-plane workflows.
> - Agents need reusable, inspectable skills that can be installed,
reset, audited, exported, and assigned without bespoke local setup.
> - The existing skill truth model needed cleanup so bundled skills,
optional catalog skills, runtime skills, and adapter-provided skills
have clear provenance.
> - Operators also need a practical CLI and board UI for discovering and
managing company skills.
> - This pull request adds the skills CLI, packaged skills catalog,
company skills APIs, and catalog-aware board UI.
> - The benefit is a more reusable Paperclip company setup where skills
are portable, auditable, and easier for operators and agents to manage.
## What Changed
- Added `paperclipai skills` CLI commands and coverage for catalog
listing, installing, resetting, and inspecting company skills.
- Added a packaged `@paperclipai/skills-catalog` workspace with bundled
and optional skill content plus validation/build tests.
- Added shared company-skill types and validators used across CLI,
server, and UI contracts.
- Added server catalog APIs/services for company skill catalog
operations, reset semantics, audit behavior, and portability provenance.
- Updated adapter skill handling so runtime/catalog provenance remains
explicit across local adapters.
- Added board UI support for browsing and managing catalog-backed
company skills.
- Updated docs for the skills CLI/catalog flow and the company skills
Paperclip skill reference.
- Rebased the branch onto current `paperclipai/paperclip:master`; no
`pnpm-lock.yaml`, `.github/workflows`, or migration files are included
in the final PR diff.
## Verification
- Passed: `pnpm run preflight:workspace-links && pnpm exec vitest run
cli/src/__tests__/skills.test.ts
packages/skills-catalog/src/catalog-builder.test.ts
packages/skills-catalog/src/shipped-catalog.test.ts
packages/shared/src/validators/company-skill.test.ts
packages/adapter-utils/src/server-utils.test.ts
packages/plugins/create-paperclip-plugin/src/entrypoints.test.ts
server/src/__tests__/company-skills-catalog-service.test.ts
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/company-portability.test.ts`.
- Passed: `pnpm exec vitest run
server/src/__tests__/workspace-runtime.test.ts -t "default
branch|origin/master|symbolic-ref"`.
- Attempted: full `server/src/__tests__/workspace-runtime.test.ts`. Four
provisioning tests failed while seeding an isolated worktree database
from the local Paperclip instance because the local plugin schema dump
contains a duplicate-column foreign key
(`plugin_content_machine_18a7bc327b.content_case_signals`). The
default-branch tests touched by the rebase conflict passed in the
focused run above.
- Checked final diff: no `pnpm-lock.yaml`, no `.github/workflows`, and
no migration-file changes relative to `master`.
## Risks
- Medium: this is a broad skills/catalog change touching CLI, server
APIs, shared contracts, adapter skill sync, and UI.
- Catalog validation and reset semantics need careful reviewer attention
because they affect reusable company setup and portability.
- No database migrations are included in this PR, so there is no
migration ordering/idempotency risk in the final diff.
- No lockfile is included by design; dependency resolution will be
handled by the repository lockfile workflow.
## Model Used
- OpenAI Codex coding agent based on GPT-5, running in Paperclip via the
`codex_local` adapter with shell, git, GitHub CLI, and code-editing tool
access. Exact hosted model build/context-window metadata is not exposed
in this 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 run targeted tests locally and documented the local
workspace-runtime seed failure above
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, screenshots were intentionally
omitted per PAP-10124 instructions; UI behavior is covered by tests and
reviewer inspection
- [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
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies, and its
CLI import/export path is part of how operators move company state
safely between environments.
> - The `paperclipai company import/export` e2e test is supposed to
validate that portability flow inside a hermetic harness, not against a
developer's live Paperclip home.
> - This regression showed nested CLI subprocesses could silently fall
back to ambient `PAPERCLIP_*` state and mutate a real local instance by
creating extra companies such as `CLI-1-Roundtrip-Test`.
> - The first job was to pin the test subprocesses to isolated config,
home, instance, auth, and context paths, and to add a regression
assertion that proves the nested CLI writes stay inside the test-owned
state.
> - Once the PR was up, CI and Greptile exposed two follow-on issues
that were blocking merge: plugin SDK typecheck bootstrap was racing
across packages in fresh CI, and the new lock helper needed one more fix
to release its lock on failure.
> - This pull request therefore ends up doing two tightly related
things: fixing the original CLI isolation leak, and hardening the
supporting typecheck/bootstrap path enough for the fix to verify cleanly
in CI.
> - The benefit is that the portability e2e test is now actually
isolated, and the PR verification path is stable enough to catch
regressions instead of introducing its own nondeterministic failures.
## What Changed
- Hardened `cli/src/__tests__/company-import-export-e2e.test.ts` so
nested CLI subprocesses re-seed isolated `PAPERCLIP_CONFIG`,
`PAPERCLIP_HOME`, `PAPERCLIP_INSTANCE_ID`, `PAPERCLIP_CONTEXT`,
`PAPERCLIP_AUTH_STORE`, and throwaway `HOME` values instead of falling
back to ambient machine state.
- Added a regression assertion around `paperclipai context set --json`,
then cleared the temporary `context.json` so the isolation check and the
later export/import flow stay independent.
- Passed the same isolated `HOME` into the server subprocess so both
sides of the e2e harness are symmetric.
- Introduced locking in `scripts/ensure-plugin-build-deps.mjs` and
switched the server/plugin example `typecheck` scripts to use that
helper instead of launching concurrent raw `@paperclipai/plugin-sdk`
builds.
- Fixed the helper failure path so it releases the lock before exiting
non-zero, which prevents stale-lock timeouts during parallel typecheck
runs.
## Verification
- `pnpm vitest run cli/src/__tests__/company-import-export-e2e.test.ts
--project paperclipai`
- `pnpm --filter paperclipai typecheck`
- `pnpm -r typecheck`
- PR checks now pass on the current head, including `policy`, `verify`,
`e2e`, `security/snyk`, and `Greptile Review`.
## Risks
- Low risk. The product-facing behavior change is scoped to test harness
code in the CLI e2e suite.
- The CI stabilization changes only affect bootstrap/typecheck helper
paths for the server and plugin/example packages, but they do touch
shared verification plumbing; the main risk is changing how fresh build
artifacts are prepared in local/CI typecheck runs.
## Model Used
- Anthropic Claude via Paperclip `claude_local`, model
`claude-opus-4-7`, high-effort local coding agent, used for the initial
implementation and first peer-reviewed verification.
- OpenAI Codex via Paperclip `codex_local`, model `gpt-5.4`, high
reasoning-effort local coding agent with tool use, used for CI triage,
Greptile follow-up fixes, verification, and PR maintenance.
## 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 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