35c31ca63fcdb67a56d6a4459da5e3e7df830e6b
977 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4da79a88c6 |
[codex] Refine issue comment wake handoffs (#7678)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The heartbeat and issue-comment routes decide when an assigned agent wakes up and what context it receives. > - Passive comments and annotation notes can currently wake assignees even when no actionable state changed. > - Accepted planning confirmations also need to preserve recent plan comments so child-issue creation does not lose board/user constraints. > - Runtime skill mentions should only send UUID ids into database lookups, because legacy slug-like ids are not valid runtime skill ids. > - This pull request tightens those wake and handoff rules in one server-side branch. > - The benefit is fewer noisy agent wakeups and better accepted-plan continuation context without changing the task model. ## Linked Issues or Issue Description Internal Paperclip task: [PAP-10535](/PAP/issues/PAP-10535). Problem or motivation: Passive comments and annotation notes could wake the current assignee even when no actionable state changed, and accepted plan continuations needed recent plan comments preserved in the wake handoff. Runtime skill mentions also needed to ignore non-UUID ids before database lookup. Proposed solution: Tighten server-side wake routing so passive comments do not wake assignees unless they reopen the issue, preserve mention-targeted wakeups, include recent non-deleted plan comments in accepted confirmation wake payloads, and guard runtime skill mention lookup to UUID-like ids. Alternatives considered: Leaving passive assignee wakeups in place was rejected because it keeps generating noisy non-actionable heartbeats. Treating every skill mention-like token as a runtime skill id was rejected because legacy slug-like ids are not valid runtime skill ids. Roadmap alignment: This aligns with the V1 control-plane heartbeat contract by making wakeups more intentional and preserving handoff context for approved plans. This PR was split from the local `master` branch on June 7, 2026. It covers server-side heartbeat and comment-wakeup behavior only. I searched GitHub for duplicate/related PRs; the results were broader heartbeat/run PRs, not this exact passive-comment and accepted-plan handoff change. ## What Changed - Filter runtime skill mention extraction so only UUID-like skill ids are looked up. - Stop ordinary issue comments and document annotation comments from waking the current assignee unless the comment reopens the issue. - Keep mention-targeted wakeups intact while removing passive assignee wakeups. - Include recent non-deleted issue comments in accepted-plan confirmation wake payloads and task markdown. - Updated focused server tests for the new wakeup and accepted-plan behavior. ## Verification - `git diff --check origin/master..HEAD` - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/heartbeat-project-env.test.ts server/src/__tests__/document-annotation-routes.test.ts server/src/__tests__/issue-comment-reopen-routes.test.ts server/src/__tests__/issue-update-comment-wakeup-routes.test.ts server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issue-comment-redaction.test.ts` - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts server/src/__tests__/issue-comment-redaction.test.ts server/src/__tests__/heartbeat-context-summary.test.ts` - `pnpm --filter /server typecheck` - PR checks green on head `a379a0264d384510ff8ac4a47fb1e44d7b556f68` - Greptile rerun green on head `a379a0264d384510ff8ac4a47fb1e44d7b556f68`: 9 files reviewed, 0 comments added, 0 unresolved review threads ## Risks - Medium behavioral risk: agents will no longer wake for passive comments unless mentioned or unless the comment reopens/resumes the issue. That is intentional, but any workflow relying on passive assignee comment wakeups should use explicit mentions or structured resume paths. - Low migration risk: no schema or migration changes. > 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 based on GPT-5, with shell, git, GitHub CLI, and local test execution. Exact hosted model variant and context-window size were not exposed by the 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 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] 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> |
||
|
|
8b85fdfa3c |
fix(cli): send X-Paperclip-Run-Id so agents can mutate their issues via the CLI (#7642)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents act on issues through the `paperclipai` CLI as well as the HTTP API; the server gates agent-authenticated **mutations** of an in-progress issue (checkout, release, interactions, PATCH, attachment upload) behind the `X-Paperclip-Run-Id` header (`requireAgentRunId` / `assertAgentIssueMutationAllowed`). > - The CLI's HTTP client (`client/http.ts`) already supports sending that header, but `resolveCommandContext` never populated `runId`, so there was no way to provide it — every agent-authenticated mutation via the CLI failed with `401 Agent run id required`. > - Separately, `issue attachment:upload` hand-rolls its own multipart `fetch` (bypassing the JSON client), so it never forwarded the run-id at all, and its `inferContentTypeFromPath` couldn't produce `text/html` and appended `; charset=utf-8` to `md`/`txt` — which fails the server's exact-match content-type allowlist (`422 Unsupported attachment content type`). > - This PR lets the CLI send `X-Paperclip-Run-Id` from a new global `--run-id` flag (falling back to `$PAPERCLIP_RUN_ID`), and fixes `attachment:upload` to forward the run-id and emit server-allowed bare MIME types. > - The benefit is that an embodied agent can drive the full issue lifecycle (checkout → work → disposition → upload deliverable) entirely through the official CLI, instead of dropping to raw HTTP. ## Linked Issues or Issue Description No issue exactly covers the CLI **send** side, so describing it here (bug path). Related: - `Refs #2063` — "Sub-agents cannot post comments on subtickets — Agent run id required" (same error string; that report focuses on the server gate, this PR fixes the CLI not sending the header for agent mutations). - `Refs #1199` — injects `X-Paperclip-Run-Id` on the **http adapter's** outbound request (server side). This PR is the complementary **CLI client** side. **Bug (per `bug_report.yml`):** - **What happened:** Running agent-authenticated CLI mutations (`issue checkout` / `issue update` on an in-progress issue / `issue attachment:upload`) returns `401 Agent run id required`, even with `--run-id`/`$PAPERCLIP_RUN_ID` set; `attachment:upload` of an HTML/markdown deliverable additionally returns `422 Unsupported attachment content type`. - **Expected:** The CLI forwards the agent run-id so the server authorizes the mutation, and uploads use a content-type the server accepts. - **Steps to reproduce:** As an agent token, `paperclipai issue checkout <id> --agent-id <id>` then `paperclipai issue update <id> --status done` (→ 401); `paperclipai issue attachment:upload <id> ./report.html` (→ 401, then 422 once run-id is wired). - **Deployment mode:** local_trusted (applies to all modes — server-side gate is mode-independent). ## What Changed - `cli/src/commands/client/common.ts`: resolve `runId` in `resolveCommandContext` from a new global `--run-id` flag, falling back to `$PAPERCLIP_RUN_ID`, so the existing HTTP client sends `X-Paperclip-Run-Id`; thread `runId` into the attachment-upload path; align `inferContentTypeFromPath` with the server's `DEFAULT_ALLOWED_TYPES` (add `html`/`htm`/`csv`/`zip`/`mp4`/`m4v`/`webm`/`mov`/`qt`, drop the `; charset` suffix). - `cli/src/commands/client/issue.ts`: pass `ctx.api.runId` into `uploadAttachment` and send the `X-Paperclip-Run-Id` header on the hand-rolled multipart request (matching what the JSON client injects automatically). - Tests: CLI asserts `attachment:upload` forwards `x-paperclip-run-id` + the inferred bare MIME type, and that `inferContentTypeFromPath` covers the allowed types; a server test locks the contract that an in-progress checkout owner without a run-id is rejected `401` on attachment upload. ## Verification ```bash # CLI tests (no DB) node_modules/.bin/vitest run \ cli/src/__tests__/common.test.ts \ cli/src/__tests__/issue-subresources.test.ts # → 2 files, 13 tests passed # Server contract test (embedded postgres) node_modules/.bin/vitest run \ server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts # → 37 tests passed ``` Manual: with an agent token and a valid `$PAPERCLIP_RUN_ID`, `issue checkout` / `issue update --status done` / `issue attachment:upload ./report.html` now succeed where they previously returned 401/422. ## Risks Low. Additive only: - `--run-id` is a new optional flag; behavior is unchanged when it (and `$PAPERCLIP_RUN_ID`) are unset — the header is simply omitted as before. - The content-type map only **widens** the allowed set to match the server's existing allowlist and removes a suffix the server already rejected, so no previously-accepted upload changes type. - No schema/migration changes; no server behavior changes (the server test only documents the existing gate). ## Model Used Claude Opus 4.8 (1M context window), via Claude Code (tool use / agentic file edits + local test execution). Extended reasoning 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] 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 — N/A (CLI-only) - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green — pending CI run on this PR - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups — pending review - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
71a8464fee |
[codex] prevent invalid agents from receiving assignments and runs (#7663)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The control plane owns agent lifecycle, issue assignment, routine dispatch, heartbeat wakeups, and recovery paths > - Terminated, paused, pending-approval, or otherwise invalid agents should not receive new work or new execution attempts > - The old behavior left eligibility checks spread across routes and services, so assignment and run paths could drift apart > - This pull request centralizes agent lifecycle eligibility and applies it consistently to assignment, invocation, routines, recovery, and UI affordances > - The benefit is safer autonomy: terminated agents stay paused, invalid org-chain agents are surfaced, and active agents keep receiving valid work ## Linked Issues or Issue Description Refs #5103 Related: #1864 Bug fix context: - What happened: agent assignment and heartbeat/run paths did not share one eligibility contract, so invalid lifecycle states could still be considered in some paths. - Expected behavior: terminated agents must never receive new assignments or heartbeat runs, and paused or otherwise invalid agents should be treated as non-invokable consistently. - Steps to reproduce: create or select an agent in an invalid lifecycle state, then attempt assignment, routine dispatch, or heartbeat/recovery wake paths. - Paperclip version/commit: fixed on top of `paperclipai/paperclip` `master` at the PR base. - Deployment mode: applies to the server control plane in local and authenticated deployments. ## What Changed - Added shared agent lifecycle eligibility helpers and exported the related shared types. - Centralized server-side assignability and invokability checks for issue assignment, agent routes, heartbeat dispatch, routines, recovery, and liveness logic. - Hardened issue assignment so invalid assignees are rejected instead of queued for work. - Hardened heartbeat/routine/recovery paths so terminated and otherwise invalid agents are not woken for new runs. - Updated board UI affordances to disable invalid agent actions and surface org-chain warnings where relevant. - Added targeted shared, server, and UI tests for the new eligibility behavior. ## Verification - `pnpm exec vitest run packages/shared/src/agent-eligibility.test.ts server/src/__tests__/agent-invokability.test.ts server/src/__tests__/heartbeat-archived-company-guard.test.ts server/src/__tests__/issue-liveness.test.ts server/src/__tests__/issues-service.test.ts server/src/__tests__/routines-service.test.ts ui/src/lib/company-members.test.ts ui/src/pages/Agents.test.tsx` — 8 files, 144 tests passed. - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` — passed. - Checked the PR diff does not include `pnpm-lock.yaml` or `.github/workflows` changes. - Checked `ROADMAP.md`; this is a targeted control-plane safety fix and does not duplicate a planned core feature. - Searched GitHub for duplicate or related PRs/issues; closest related items are linked above. - CI and Greptile verification are pending on the opened PR and will be followed up before requesting merge. ## Risks Low to moderate risk. The intended behavioral shift is that invalid agents are refused earlier and more consistently, which could expose existing data with paused, pending, terminated, or broken org-chain assignees. The added tests cover the critical assignment, heartbeat, routine, recovery, shared helper, and UI paths. No database migrations are included. > 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 GPT-5 Codex via the Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. Reasoning mode and context window are managed by the adapter runtime and not exposed in this environment. ## 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 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 (not applicable: no design screenshots requested; UI behavior is covered by tests) - [x] I have updated relevant documentation to reflect my changes (not applicable: no user-facing command or schema docs changed) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending CI) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending Greptile) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e50666e4c8 |
[codex] Move maintainer task skills under .agents (#7658)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The skills layout separates runtime Paperclip skills in `skills/` from maintainer/agent workflow skills in `.agents/skills/`. > - Three maintainer workflow skills still lived under root `skills/`, making them look like runtime skills shipped through the Paperclip skill path. > - Root `skills/` is documented as reserved for Paperclip runtime skills, so these task-oriented maintainer skills belong with the other `.agents/skills` entries. > - This pull request moves the three requested skill packages, updates the direct smoke path, and adds regression coverage for the maintainer-only skill boundary. > - The benefit is a cleaner skills boundary without changing skill contents or runtime behavior. ## Linked Issues or Issue Description Internal Paperclip issue: PAP-10471. No public GitHub issue exists for this repository-maintenance change. Inline feature/enhancement issue description follows the feature request template fields: ### Problem or motivation Root `skills/` is documented as reserved for Paperclip runtime skills, but `terminal-bench-loop`, `paperclip-create-plugin`, and `diagnose-why-work-stopped` lived there even though they are maintainer/agent workflow skills. ### Proposed solution Move those three skill packages to `.agents/skills/`, update the terminal-bench loop smoke script to read the new local path, and cover the moved skill names in the existing runtime-skill discovery test fixture. ### Alternatives considered Leaving the skills in root `skills/` would preserve direct old paths, but it keeps blurring the runtime-skill boundary. Moving them into the app-shipped skills catalog would be the wrong fit because these are maintainer workflow skills, not bundled company skills. ### Roadmap alignment This is a small maintenance cleanup around the existing Skills Manager/workflow-skill organization and does not introduce a roadmap-level core feature. ## What Changed - Moved `terminal-bench-loop`, `paperclip-create-plugin`, and `diagnose-why-work-stopped` into `.agents/skills/`. - Updated the terminal-bench loop smoke script and skill self-check text to use `.agents/skills/terminal-bench-loop/SKILL.md`. - Added regression coverage in `server/src/__tests__/paperclip-skill-utils.test.ts` that places these three skills under `.agents/skills` while asserting runtime discovery still lists only root runtime skills. ## Verification - `pnpm smoke:terminal-bench-loop-skill --source-issue-id "$PAPERCLIP_TASK_ID" --run-key PAP-10471-move-skill-path` - `pnpm exec vitest run server/src/__tests__/paperclip-skill-utils.test.ts` - `rg -n "skills/(terminal-bench-loop|paperclip-create-plugin|diagnose-why-work-stopped)" . --glob '!node_modules' --glob '!dist' --glob '!ui/dist'` returned no matches. ## Risks - Low risk: this is a file-location change plus direct path/test updates. - Maintainer agents that referenced the old root paths directly will need to use `.agents/skills/...` instead. > 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/tool use. ## 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 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 - [ ] 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 |
||
|
|
f09d4231e3 |
[codex] Add create-issue-interaction-ui maintainer skill (#7659)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue-thread interactions are one of the core ways agents pause for structured board or user decisions. > - Adding a new interaction kind currently requires coordinated changes across shared contracts, server behavior, UI cards, fixtures, CLI/MCP/plugin SDK helpers, and agent guidance. > - The checkbox-confirmation rollout established a good end-to-end pattern, but contributors needed a durable maintainer checklist for repeating that work. > - This pull request adds a developer/maintainer skill that captures that workflow inside the repo under `.agents/skills`. > - The benefit is a reusable implementation guide for future interaction-card work without installing that guidance on runtime Paperclip agents. ## Linked Issues or Issue Description Paperclip issue: [PAP-10457](/PAP/issues/PAP-10457) This PR documents the process for adding a new issue-thread interaction family end-to-end. There is no GitHub issue for this Paperclip-internal skill addition. ## What Changed - Added `.agents/skills/create-issue-interaction-ui/SKILL.md` as a developer/maintainer skill. - Covered shared contract, server route/service behavior, UI card wiring, fixtures/Storybook, CLI/MCP/plugin SDK helpers, agent guidance, invariants, and focused verification. - Referenced the checkbox-confirmation rollout (`4d5322c82`, PR `#7649`) as the canonical worked example. ## Verification - `git diff --check origin/master..HEAD` - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/paperclip-skill-utils.test.ts` - Reviewed the added skill markdown for scope, location, and workflow completeness. ## Risks Low risk. This is a documentation/skill-only change under `.agents/skills`; it does not change runtime code, database schema, API behavior, or installed production-agent guidance. > 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 based on GPT-5, with shell and GitHub CLI tool access. Exact hosted model variant and context-window size were not exposed by the 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 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 - [ ] 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d8e1004551 |
PAP-10440: group artifacts by task stacks (#7654)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The artifacts surface is where board users inspect files, media, and documents produced by agents. > - Grouped artifact stacks make that surface easier to scan by task, but the first pass still made grouping feel secondary to media filters. > - The follow-up request was to make grouping the default and give the grouping control the same icon-only outline treatment used on the issues page. > - This pull request keeps the existing artifact grouping API/UI, then polishes the artifacts toolbar state and Storybook review coverage. > - The benefit is that `/artifacts` now opens in the task-stack view by default while preserving explicit flat-mode filtering via `groupBy=none`. ## Linked Issues or Issue Description No public GitHub issue exists for this internal Paperclip task. ### Subsystem affected ui/ — React + Vite board UI. ### Problem or motivation The `/artifacts` grouping affordance was visually placed after the media filters, rendered as a text button, and defaulted to a flat artifact list. Internal follow-up `PAP-10465` requested the grouping icon move left of the filters, become an icon-only outlined button like `/issues`, and make Task grouping the default. ### Proposed solution Default `/artifacts` to grouped Task stacks, keep explicit flat mode available as `groupBy=none`, move the grouping control before the media chips, and restyle it as the shared icon-only outline button pattern. ### Alternatives considered Leaving flat mode as the implicit default was rejected because it does not satisfy the follow-up. Keeping a text label on the grouping trigger was rejected because `/issues` already established the icon-only outline pattern for this class of toolbar control. ### Roadmap alignment This aligns with the `Artifacts & Work Products` roadmap item by making generated outputs easier to inspect and operate from the board UI. ## What Changed - Defaulted the `/artifacts` page to `groupBy=task` when no grouping URL param is present, while keeping explicit flat mode available with `groupBy=none`. - Moved the group control before the media filter chips and changed it to an icon-only outlined button using the shared `Button` pattern. - Updated artifact page tests to cover default Task grouping, explicit flat mode, trigger ordering, and icon-only outline metadata. - Updated the artifact Storybook story so its toolbar mock matches the production ordering and grouped Task is documented as the default mode. ## Verification - `pnpm exec vitest run ui/src/pages/Artifacts.test.tsx ui/src/components/artifacts/ArtifactGroupCard.test.tsx` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `git diff --check` — passed. - QA visual validation from internal follow-up PAP-10466 passed desktop/mobile scenarios. Screenshot evidence attached there: - Desktop default: http://paperclip-dev:3100/api/attachments/bc81305d-f5de-485c-abeb-9e7c3d9d8539/content - Desktop toolbar close-up: http://paperclip-dev:3100/api/attachments/3375a62b-2110-48f3-bafa-ea98c00f99f7/content - Mobile default: http://paperclip-dev:3100/api/attachments/bfc5642e-9248-431e-9bac-36284dec1c89/content - Mobile toolbar close-up: http://paperclip-dev:3100/api/attachments/ca79401a-5ba8-464d-bc6e-aeffd47fe695/content - GitHub PR checks on head `431964c8b` — passed, including Greptile 5/5. ## Risks Low to medium risk. The main behavior shift is intentional: `/artifacts` now queries grouped Task stacks by default. Existing flat mode remains available through the grouping menu and explicit `groupBy=none` URLs. ## Model Used OpenAI Codex, GPT-5.4 class coding model in this Paperclip heartbeat environment, with shell, git, test, and GitHub CLI tool use. Context window managed by the Codex 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 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] 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> |
||
|
|
2e74d32871 |
PAP-10430: split Issue-to-Task copy migration (#7651)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI is the operator surface where users create, assign, monitor, and review work items. > - The product language is moving toward "tasks" for user-facing work items while the internal API and database still use "issues". > - PR #7543 bundled this copy migration with broader information-architecture work, which made the branch too large for Greptile review. > - This pull request peels the Issue-to-Task copy migration into a smaller, independently reviewable change. > - The benefit is clearer user-facing terminology, less agent confusion via the Paperclip skill note, and a smaller PR that Greptile can review. ## Linked Issues or Issue Description Refs #7645 Refs #7543 Refs PAP-10430 This PR was split out of #7543 so the Issue-to-Task copy migration can be reviewed separately and the remaining IA PR can fall under Greptile's file limit. ## What Changed - Preserves Scott Tong's original `PAP-57` copy-only commit, with author and co-author credit intact, to rename user-facing "Issues" copy to "Tasks" across the UI while keeping routes/API/internal symbols as `issue`. - Updates onboarding and release-smoke browser selectors from `Create & Open Issue` to `Create & Open Task`. - Adds a terminology note to `skills/paperclip/SKILL.md` clarifying that task and issue refer to the same Paperclip work item. - Resolves the only cherry-pick conflict by keeping current search artifacts support and changing visible search copy to "tasks". ## Verification - `pnpm --filter @paperclipai/ui build` passed. - `NODE_ENV=test pnpm exec vitest run ui/src/components/IssuesList.test.tsx ui/src/components/Sidebar.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/pages/IssueDetail.test.tsx` passed: 4 files, 66 tests. - `git diff --check origin/master...HEAD` passed. - Diff is 80 files, below Greptile's 100-file limit. - Before/after UI copy examples: "Issues" -> "Tasks", "New Issue" -> "New Task", "Create & Open Issue" -> "Create & Open Task". ## Risks - Medium copy-risk: this intentionally changes user-facing terminology broadly while keeping internal issue identifiers and routes unchanged. - Some docs and APIs still say `issue`; the skill note clarifies this so agents do not treat task and issue as separate entities. - Browser-level visual validation is expected from CI because this local container is missing usable browser dependencies. > 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 Scott Tong authored the original `PAP-57` copy migration, assisted by Claude Opus 4.8 and Paperclip agents per the preserved commit metadata. Codex / GPT-5-class coding agent with shell, GitHub CLI, and repository access performed the PR split, conflict resolution, skill note, and verification. ## 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 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] 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: scotttong <scott.tong@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7428fb956f |
[codex] Guard git-sensitive adapter workspaces (#7644)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The affected subsystem is the heartbeat execution path that turns issue assignment into adapter-backed work in a selected workspace. > - PAP-10409 and sibling follow-ups failed before useful adapter output because project/workspace identity became incoherent. > - A project-workspace-linked child issue could keep `projectWorkspaceId` / execution workspace state while losing `projectId`, then a git-sensitive local adapter could fall through toward an invalid fallback cwd. > - Paperclip needs to treat coherent workspace identity as part of the live-path contract, not only as post-failure cleanup. > - This pull request documents that rule, repairs issue inheritance, and blocks git-sensitive adapter launch before it can run from the wrong cwd. > - The benefit is a bounded recovery path: affected issues are repaired explicitly, future malformed workspaces fail fast with a clear recovery action, and the UI surfaces that reason. ## Linked Issues or Issue Description Refs #7646 Bug report fields: - Summary: adapter-backed follow-up issues can fail before doing work when issue creation/inheritance preserves workspace ids but drops project identity. - Affected issues: internal Paperclip issues PAP-10408 through PAP-10412, especially PAP-10409. - Steps to reproduce: create a project-scoped parent/follow-up tree where a child issue keeps `projectWorkspaceId` or an inherited execution workspace but has `projectId: null`, then launch a git-sensitive local adapter such as `codex_local`. - Expected behavior: Paperclip derives or preserves coherent project identity during issue creation, and heartbeat refuses malformed git-sensitive workspace launches with one clear recovery action. - Actual behavior before this PR: the run could reach adapter bootstrap with an incoherent workspace context and fail with git errors such as `fatal: not a git repository (or any parent up to mount point /srv)`. - Root cause: child/follow-up issue inheritance preserved workspace execution context without coherent project context. That let heartbeat workspace resolution/adapter launch reach a fallback cwd instead of refusing the malformed workspace state up front. ## What Changed - Documented the adapter workspace-coherence live-path precondition in `doc/execution-semantics.md`. - Updated issue creation/inheritance so workspace-inheriting issues preserve or derive project identity, while existing mismatch validation still rejects incoherent project/workspace combinations. - Added a heartbeat preflight guard for git-sensitive local adapters that validates effective cwd, persisted workspace identity, project workspace identity, and required git metadata before launch. - Added `workspace_validation` recovery actions for this failure class and ensured the source issue gets a visible, idempotent recovery comment. - Surfaced workspace-validation recovery state in issue rows, blocked notices, and recovery action cards, including the manual-repair wake policy label. - Added focused regression coverage for issue inheritance, all heartbeat workspace-validation guard branches, recovery display helpers, and UI recovery components. ## Verification - `pnpm exec vitest run server/src/__tests__/heartbeat-workspace-session.test.ts` - Result: 1 test file passed, 68 tests passed. - `pnpm exec vitest run ui/src/components/IssueRecoveryActionCard.test.tsx` - Result: 1 test file passed, 12 tests passed. - `pnpm exec vitest run ui/src/components/IssueBlockedNotice.test.tsx ui/src/components/IssueRecoveryActionCard.test.tsx` - Result: 2 test files passed, 18 tests passed. - `pnpm --filter @paperclipai/ui typecheck` - Result: passed. - `pnpm exec vitest run server/src/__tests__/heartbeat-plugin-environment.test.ts server/src/__tests__/issues-service.test.ts server/src/__tests__/heartbeat-workspace-session.test.ts server/src/__tests__/heartbeat-process-recovery.test.ts ui/src/components/IssueBlockedNotice.test.tsx ui/src/components/IssueRecoveryActionCard.test.tsx ui/src/lib/recovery-display.test.ts` - Result: 7 test files passed, 200 tests passed before the final guard-branch additions; the changed server file was re-run above. - UI coverage: `ui/storybook/stories/source-issue-recovery.stories.tsx` contains rendered scenarios for the generic recovery chip, workspace-validation recovery chip, blocked notice indicator, recovery action card, and issue-row chip. - Screenshot capture attempt: Storybook started successfully on `http://127.0.0.1:6016/`, but screenshots could not be captured in this runner because `agent-browser` launched an unusable Chrome binary and Playwright Chromium failed on missing system library `libatk-1.0.so.0`; the runner is non-root and lacks passwordless sudo for installing browser dependencies. - Hosted CI on final commit `969594e7` is green, including `verify`, `Build`, `Typecheck + Release Registry`, `General tests (server)`, workspace suites, serialized server suites, `Canary Dry Run`, and `e2e`. - Roadmap checked: no duplicate roadmap item; this is a tightly scoped reliability fix for existing heartbeat/workspace behavior. - Duplicate PR search checked: no open PR matched `workspace coherence adapter cwd`. ## Risks - Medium risk: heartbeat launch is stricter for git-sensitive local adapters and can now block malformed workspace states before adapter execution. - Mitigation: the guard is limited to local git-sensitive adapters and records a source-scoped recovery action with structured evidence instead of retrying indefinitely. - Compatibility: valid project/workspace execution paths continue normally; explicit project/workspace mismatches remain rejected. > 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-based `codex_local` coding agent with terminal/tool use. Work was produced through Paperclip issue execution with focused local test runs. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] 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] 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> |
||
|
|
eaef47f4c7 |
Information Architecture + project/agent visual refresh (experimental) (#7543)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI is the control surface for issues, projects, agents, goals, workspaces, and operator settings. > - The existing navigation and list surfaces make several high-frequency workflows feel harder to scan than they should, especially around projects and agents. > - The product direction is to improve those surfaces without breaking the existing route model or forcing a new IA on every operator at once. > - This pull request now keeps the dependent IA, project identity, and agent-list visual refresh work together while the Issue-to-Task copy migration is split into #7651. > - The benefit is a clearer left nav, better project identity, denser agent/project list rows, and brand-aligned status treatment while preserving the classic default experience behind a flag. ## Linked Issues or Issue Description Refs #7645 Refs #7651 Internal planning/work references: PAP-53, PAP-56, PAP-58, PAP-59, PAP-60, PAP-61, PAP-68, PAP-69, PAP-70, PAP-71, PAP-72, PAP-75, PAP-76, PAP-80, PAP-85, PAP-86, PAP-87, PAP-88, PAP-89. ## What Changed - Adds `enableStreamlinedLeftNavigation`, defaulting off, and gates sidebar presentation so classic navigation remains the default. - Adds project icon persistence, validation, portability, picker UI, and `ProjectTile` rendering while defaulting new projects to neutral gray. - Adds projects-list task-count and budget summary data with focused server/shared/UI coverage. - Refreshes agent list rows, row actions, active/recent sidebar behavior, and status capsule/chip styling for the approved brand state system. - Removes the placeholder Conference room and Artifacts nav/routes from the finalized experimental nav direction. - Removes `pnpm-lock.yaml` and the Issue-to-Task copy migration from this PR diff; the copy migration now lives in #7651. ## Verification - Existing branch verification from the authored commits: UI typecheck, targeted unit tests, and light/dark visual checks for `/agents`, agent detail, and design-guide status states. - Maintainer cleanup verification on `75e34e5`: `git diff --check origin/master...HEAD` passed, the `design/` diff is empty, and the PR diff is 61 files, below Greptile's 100-file review limit. - `pnpm --filter @paperclipai/ui build` passed. - `NODE_ENV=test pnpm exec vitest run ui/src/components/Sidebar.test.tsx` passed: 1 file, 8 tests. - CI and Greptile should rerun on the latest push. ## Risks - Broad UI surface area: the experimental flag keeps the classic nav default, but changed shared components such as `EntityRow`, `ProjectTile`, and agent status badges could affect multiple pages. - Database migration: `projects.icon` is additive and nullable, but migration ordering and portability import/export must stay aligned. - The Issue-to-Task copy migration is now separated into #7651, so reviewers should evaluate this PR as IA/project/agent presentation work only. - Visual regressions are possible across smaller widths because the PR intentionally changes dense list-row layouts. ## Model Used Claude Opus 4.8 assisted the original feature commits. Paperclip-Paperclip agents assisted some planning/design commits. Codex / GPT-5-class coding agent with shell, GitHub CLI, and repository access performed this PR-readiness cleanup and split. ## 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 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] 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> Co-authored-by: Dotta <bippadotta@protonmail.com> |
||
|
|
4d5322c821 |
[codex] Add checkbox confirmation issue interactions (#7649)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent work is coordinated through issues, comments, interactions, and approval-style handoffs. > - Existing issue-thread interactions could ask questions, suggest tasks, and request confirmation, but they did not support a structured checkbox confirmation payload for choosing one or more options. > - That gap made board/user confirmations harder to validate consistently across API callers, plugin helpers, CLI tooling, and the UI. > - This pull request adds the shared checkbox confirmation contract, server handling, client helpers, and issue-thread UI needed to render and submit structured selections. > - The benefit is that agents can request bounded multi-select confirmations in the same audited issue-thread flow as other Paperclip interactions. ## Linked Issues or Issue Description - No public GitHub issue found for this exact branch. Internal Paperclip issue: PAP-10415 / PAP-10441 requested creating this PR for the checkbox confirmation issue-thread UI component work. - GitHub duplicate search performed for checkbox confirmation / issue-thread interaction PRs; no matching open PR was found. - Related issue search result `#7497` was unrelated company file cleanup work, so it is not linked as a related issue. ## What Changed - Added shared types, validators, constants, and tests for `request_checkbox_confirmation` interactions. - Extended server issue-thread interaction service and routes for checkbox confirmation creation, validation, expiration, and response handling. - Added CLI, MCP, and plugin SDK helper coverage so external callers can create the new interaction shape consistently. - Updated the issue-thread interaction UI to render checkbox confirmations with min/max bounds, selection summaries, stale-target states, and accept/decline flows. - Documented the checkbox confirmation interaction contract in the Paperclip skill/API reference. ## Verification - Rebased cleanly on `paperclipai/paperclip` `master` fetched into `public-gh/master` at `a4fa0eaf5`. - Confirmed the PR diff does not include `pnpm-lock.yaml` or `.github/workflows` changes. - Ran focused tests with `NODE_ENV=test`: ```sh NODE_ENV=test pnpm run preflight:workspace-links NODE_ENV=test pnpm exec vitest run packages/shared/src/issue-thread-interactions.test.ts server/src/__tests__/issue-thread-interaction-routes.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts ui/src/components/IssueThreadInteractionCard.test.tsx ui/src/lib/issue-thread-interactions.test.ts cli/src/__tests__/issue-subresources.test.ts cli/src/__tests__/project-goal.test.ts packages/mcp-server/src/tools.test.ts packages/plugins/sdk/tests/testing-actions.test.ts ``` Result: 8 test files passed, 78 tests passed. - CI on latest head `63b9e55` is green. - Greptile Review passed on latest head; GraphQL review-thread check shows all Greptile threads resolved. ## Risks - Medium surface area because the interaction contract touches shared validators, server routes/services, UI rendering, CLI, MCP, plugin SDK helpers, and docs. - No database migrations are included. - `pnpm-lock.yaml` is intentionally excluded per repository lockfile policy. - UI screenshots are not attached because the task explicitly requested not to add design screenshots or images unless they were part of the work; component tests cover the new rendering and interaction states. > 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 based on GPT-5, with repository file access, shell command execution, git/GitHub CLI tooling, and Paperclip control-plane API access. Exact hosted model ID/context-window metadata is not exposed inside 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 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] 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] 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> |
||
|
|
20aea356cc |
refactor(deps-dev): bump vitest from 3.2.4 to 4.1.8 (#7581)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Test infrastructure across server, ui, packages/* runs on Vitest > - Dependabot opened a narrow bump (3.2.4 → 3.2.6), but the wider workspace is on 3.2.4 and the major-version bridge to v4 needs a coordinated change set across configs and tests > - Staying on 3.x indefinitely leaves us behind on Vitest 4 (perf, pool, and config improvements) and forces repeated patch-only dependabot churn > - This pull request upgrades Vitest to 4.1.8 across the workspace, updates `server/vitest.config.ts` and `scripts/run-vitest-stable.mjs` for the new API, and adjusts two UI tests for the new assertion semantics > - The benefit is a single, coherent Vitest 4 upgrade that supersedes #7570 and gets us on the supported major line ## What Changed - Bump `vitest` from `3.2.4` to `4.1.8` across root, `server`, `ui`, and all `packages/*` (including plugin examples and sandbox providers) - Update `server/vitest.config.ts` for Vitest 4 config surface - Update `scripts/run-vitest-stable.mjs` to match the new runner behavior - Adjust `ui/src/components/CommentThread.test.tsx` and `ui/src/components/MarkdownEditor.test.tsx` for Vitest 4 matcher/timing semantics - Refresh `pnpm-lock.yaml` ## Verification - `pnpm install` resolves cleanly with the new lockfile - `pnpm -w -r test` (server, ui, packages) runs under Vitest 4.1.8 ## Risks - Major-version Vitest bump: behavioral changes in pools, fake timers, and matcher strictness can surface flake. Test config and the two UI tests were updated to match v4 semantics; broader test runs should be watched on CI before merge. - Supersedes dependabot PR #7570 (3.2.4 → 3.2.6); that PR should be closed. ## Model Used - Claude (Anthropic) — `claude-opus-4-7`, extended thinking, tool use 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 - [ ] I have run tests locally and they pass - [ ] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] 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 Closes #7570 |
||
|
|
4693d770aa |
Add company artifacts page (#7621)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators need a way to inspect files and work products created by agents across a company without opening each issue one by one. > - The existing issue detail surfaces already show attachments and outputs, but there was no company-level artifacts index or search-result affordance for artifact-like records. > - The backend needed a company-scoped artifacts projection API that preserves issue/run attribution and safe links back to source records. > - The UI needed a first-class Artifacts page, sidebar entry, reusable artifact cards, and deep-link handling that keeps company prefixes intact. > - This pull request adds the company artifacts API and page, then wires artifacts into search and issue output surfaces. > - The benefit is a single place to browse, filter, and open generated work products and attachments while preserving company boundaries. ## Linked Issues or Issue Description Fixes #7622. Feature request fields: - Problem/motivation: company operators need a consolidated artifacts surface for attachments and work products produced by agents. - Proposed solution: add a company-scoped artifacts projection endpoint, a board Artifacts route, reusable cards, sidebar navigation, and artifact search integration. - Alternatives considered: keep artifact discovery only on individual issue pages; that forces operators to know the source issue before finding generated outputs. - Roadmap alignment: checked `ROADMAP.md`; this is a focused board UI/API improvement and does not duplicate a listed roadmap item. ## What Changed - Added shared artifact types and validators. - Added a company-scoped artifact projection service/API with tests for attachment/work-product attribution. - Added Artifacts board UI route, API client, sidebar link, cards, filters, and storybook coverage. - Added artifact result handling to company search and issue output/deep-link flows. - Rebased the branch onto the latest `public-gh/master` state and resolved the route-test conflict by preserving both upstream team-catalog coverage and artifact route coverage. - Fixed a local Sidebar test helper so it no longer depends on a runtime-undefined `React.act` export in this dependency install. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/components/artifacts/ArtifactCard.test.tsx src/api/artifacts.test.ts src/lib/company-routes.test.ts` - `pnpm --filter @paperclipai/ui exec vitest run src/pages/Artifacts.test.tsx src/pages/Search.test.tsx src/components/Sidebar.test.tsx` - `pnpm exec vitest run server/src/__tests__/company-artifacts-service.test.ts server/src/__tests__/company-search-service.test.ts server/src/__tests__/company-search-rate-limit-routes.test.ts server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts` - Confirmed the PR diff does not include `pnpm-lock.yaml` or `.github/workflows/*`. - Duplicate search: no open PRs or issues found for `artifact page ArtifactCard` in `paperclipai/paperclip`. Screenshots are intentionally omitted per the internal task instruction not to add design screenshots or images to this PR unless they are specifically part of the work. I also attempted browser capture in this runner, but `agent-browser` failed to launch Chrome and Playwright Chromium is missing `libatk-1.0.so.0`. ## Risks - Low-to-medium risk: this adds a new API projection and UI surface, so attribution/link regressions could affect artifact navigation. - Company scoping is covered in the new service/API tests. - No database migrations are included. - No lockfile or workflow changes are included. > 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 tool use and local command execution. Exact hosted model identifier 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 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots (intentionally omitted per task instruction; browser capture unavailable in this runner) - [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
dbebf30c89 |
Add low-trust review containment (#7530)
## Thinking Path > - Paperclip is a control plane for AI-agent companies, so execution policy and trust boundaries are part of the product's safety contract. > - Low-trust review work needs narrower authority than normal same-company agents because hostile PRs, comments, attachments, and generated output can carry prompt-injection payloads. > - The current V1 shape gives trusted workers broad company context, which is useful for normal execution but too permissive for a reviewer assigned to hostile content. > - This branch adds a `low_trust_review` preset, source-trust tagging, route-level containment, and quarantine handling so low-trust output does not automatically flow into higher-trust wake context. > - The branch has been rebased onto current `origin/master`, and the low-trust migration was renumbered to `0097_low_trust_source_trust.sql` to avoid collisions with existing `0091` through `0096` migrations. > - Greptile feedback was addressed by tightening low-trust detection, preserving project-level trust policy checks, fixing issue-kind promotion lookup, removing duplicate post-lease isolation assertion, documenting fail-closed source-trust behavior, bounding ancestry checks, enforcing runtime issue context for CEOs, awaiting accepted-plan monitor authorization, and making low-trust issue source-trust tagging atomic. > - The benefit is a first production slice of deny-by-default review containment with regression coverage for the main control-plane pivot surfaces. Fixes #7531. ## What Changed - Added shared trust-policy types and validators, plus database/source-trust fields for issues, comments, documents, and work products. - Implemented server enforcement for low-trust issue scope, agent self-view redaction, secret/plugin/runtime denial paths, promotion checks, and quarantined continuation/wake context. - Added focused low-trust regression tests for resolver behavior, source trust, route authorization, heartbeat preflight ordering, runtime containment, and quarantine redaction. - Added board UI affordances for selecting/reviewing the low-trust preset and surfacing source-trust badges in relevant issue views. - Added `doc/LOW-TRUST-PRESETS.md`, updated `doc/SPEC-implementation.md`, and committed the low-trust review contract plan under `doc/plans/`. - Rebasing note: the original `0097_low_trust_source_trust.sql` migration was renamed to `0097_low_trust_source_trust.sql`; the SQL uses `ADD COLUMN IF NOT EXISTS` so users who already applied the old-numbered migration are not broken by the renumbered migration. ## Verification - Rebased branch onto current `origin/master` and force-pushed with lease to `origin/PAP-10211-low-trust-agent` at head `2719f31e3`. - Confirmed the PR diff does not include `pnpm-lock.yaml` or `.github/workflows` changes. - Resolved upstream UI/comment conflicts by preserving deleted-comment tombstone behavior and low-trust source-trust badges/metadata. - Renumbered the low-trust source-trust migration to `0097_low_trust_source_trust.sql`; the SQL uses `ADD COLUMN IF NOT EXISTS` so users who already applied an old-numbered copy are not broken. - `pnpm exec vitest run ui/src/lib/issue-chat-messages.test.ts server/src/__tests__/heartbeat-workspace-session.test.ts` - `pnpm exec vitest run server/src/__tests__/source-trust.test.ts server/src/__tests__/workspace-runtime-service-authz.test.ts ui/src/lib/trust-policy-ui.test.ts ui/src/components/TrustPresetSection.test.tsx` - `pnpm run typecheck:build-gaps` - `git diff --check` - GitHub checks pass on head `2719f31e3`: build, typecheck/release registry, general tests, serialized server suites, e2e, canary, verify, policy/review, Socket, and Snyk. - Greptile Review passes with Confidence Score 5/5 and zero unresolved Greptile review threads. - No design screenshots/images were added because the task explicitly says not to add them unless they are specifically part of the work. ## Risks - Medium risk: this touches shared trust-policy contracts, server authorization paths, heartbeat context generation, migration metadata, and UI preset controls. - Low-trust containment is intentionally deny-by-default; legitimate future review workflows may need explicit allowlisted exceptions. - Plugin/runtime/security surfaces are broad, so regression tests cover the current known routes but future integrations must route through the same containment layer. - The PR is ready for review; GitHub checks are green and Greptile is 5/5. > 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, tool-enabled shell and GitHub CLI workflow. ## 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] UI changes are covered by focused tests; no screenshots were added per task instruction not to add design images unless specifically required - [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> |
||
|
|
fff3832a01 |
[codex] Add teams catalog extraction (#7550)
Fixes #7551 ## Thinking Path > - Paperclip is the control plane for AI-agent companies, and reusable company/team setup is part of making those companies faster to launch. > - The teams catalog work introduces app-shipped team templates that can be browsed, previewed, and installed into a company. > - Catalog installation crosses several contracts: bundled package contents, shared API types, server import/install behavior, CLI workflows, and the board UI. > - Agents also need a safe path through catalog installs: scoped company selection, explicit source policy, approval fallback for agent creation, and preserved catalog provenance. > - This pull request extracts the completed teams catalog branch into one reviewable PR on top of `public-gh/master`. > - The benefit is a reusable teams catalog foundation with server, CLI, package, docs, and hidden UI surfaces kept in sync. ## What Changed - Added the `@paperclipai/teams-catalog` package with bundled/optional team definitions, generated manifest, validators, catalog builder tests, and migration notes. - Added shared teams catalog types/validators plus server routes and services for listing, previewing, and installing catalog teams. - Integrated catalog install with company portability, skill/source policy checks, provenance metadata, origin hashes, target-manager reparenting, and installed/out-of-date detection. - Added CLI `teams` commands and agent-safe company selection behavior, including `company current` and approval fallback for forbidden agent-run installs. - Added hidden Team Catalog UI/API/query surfaces, Storybook fixtures, and targeted UI tests while keeping the UI route out of primary navigation. - Added docs for CLI/company/teams catalog behavior and removed generated screenshot artifacts from the PR diff. ## Verification - `pnpm exec vitest run cli/src/__tests__/company.test.ts cli/src/__tests__/teams.test.ts packages/teams-catalog/src/catalog-builder.test.ts packages/teams-catalog/src/shipped-catalog.test.ts server/src/__tests__/agent-permissions-service.test.ts server/src/__tests__/company-portability.test.ts server/src/__tests__/company-skills-service.test.ts server/src/__tests__/teams-catalog-routes.test.ts server/src/__tests__/teams-catalog-service.test.ts server/src/__tests__/teams-catalog-install-no-overrides.test.ts ui/src/lib/company-routes.test.ts ui/src/pages/TeamCard.test.tsx ui/src/pages/TeamCatalog.test.tsx ui/src/pages/useInstallTeamCatalogEntry.test.tsx` - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/teams-catalog typecheck && pnpm --filter paperclipai typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` - Confirmed branch is rebased onto `public-gh/master` (`78dc3625a`) and `public-gh/master` is an ancestor of `HEAD`. - Confirmed PR diff excludes `pnpm-lock.yaml`, `.github/workflows/*`, generated screenshot images, and screenshot helper scripts. ## Risks - Medium review surface: this crosses package generation, shared contracts, server install behavior, CLI, docs, and hidden UI code. - Catalog install behavior creates agents/projects/tasks/skills and must keep company scoping, permissions, source policy, and provenance checks strict. - `pnpm-lock.yaml` is intentionally excluded per repo policy; CI/default-branch automation owns lockfile refresh. - The Team Catalog UI is included but hidden from primary navigation, so future enablement should re-check visual QA before exposure. > 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`. > > ROADMAP checked: this aligns with reusable companies/templates and plugin-adjacent onboarding work. This PR packages work already developed on the Paperclip task branch for review. ## Model Used - OpenAI Codex, GPT-5 series coding agent in this Paperclip session; exact runtime context window was not exposed. Used shell, git, `gh`, and local test/typecheck tooling. ## 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, or documented why screenshots are intentionally omitted - [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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3657854e5e |
Merge pull request #7554 from paperclipai/codex/pap-10343-comment-redaction
[codex] Redact deleted issue comments |
||
|
|
487361a5cc |
Merge pull request #7553 from paperclipai/codex/pap-10343-operator-qol-pr
[codex] Group operator QoL fixes |
||
|
|
fb28cf38b4 |
fix(heartbeat): guard Hermes resume session state (#7516)
## Thinking Path > - Paperclip is a control plane for AI-agent companies > - Heartbeats reuse adapter session state so agents can continue work across wakeups > - Hermes can only resume from full canonical session IDs, not truncated display IDs > - #6347 exposed a case where Paperclip could save invalid Hermes output like `from`, or a shortened display ID, as resumable state > - This pull request hardens the host-side Hermes resume path so Paperclip only stores and reuses session IDs that can actually resume > - The benefit is that Hermes wakeups no longer get stuck retrying bad saved resume state ## What Changed - Added Hermes-only validation for canonical session IDs in `server/src/services/heartbeat.ts`. - Stopped building Hermes resume params from truncated display IDs such as `20260601_141558_`. - For explicit resume-from-run wakeups, pulls the full Hermes session ID from the run result payload after validation. - Preserves the previous valid Hermes session state when a run fails, times out, or is cancelled instead of replacing it with invalid adapter output like `from`. - Clears existing Hermes resume state that fails validation. - Leaves non-Hermes adapter session behavior unchanged. - Added regression coverage in `server/src/__tests__/heartbeat-workspace-session.test.ts`. Addresses #6347. Supersedes #6351 and covers the full-session resume metadata handoff from #7280. ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-workspace-session.test.ts` — passed, 50 tests. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm -r typecheck` — passed. - `pnpm build` — passed. - `git diff --check` — clean. Full suite did not finish green locally; the failures were outside this server-only heartbeat path: - `pnpm test:run`: - `@paperclipai/adapter-opencode-local` remote SSH tests timed out. - `ui/src/pages/Inbox.test.tsx` failed once in `Inbox toolbar > syncs hover with j/k selection on inbox rows`; the direct file rerun passed. - `ui/src/components/IssueDocumentAnnotations.test.tsx` failed once in `auto-opens the panel and focuses the thread when deep-linked`; the direct file rerun passed. ## Risks - Low risk: no schema, public API, shared contract, or UI changes. - If Hermes changes its canonical session ID format, the validation regex will need to be updated. - Adapter-side parsing still needs its own fix; this PR prevents non-resumable adapter output from becoming durable Paperclip resume state. - This does not add an immediate same-run retry after `Session not found`; recovery happens by clearing or preserving durable resume state for later wakeups. > 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 GPT-5.5 (`openai/gpt-5.5`) via opencode, with repository read/search tools and local shell/test execution. opencode did not expose context-window or reasoning-mode details. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used, including exact model ID 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 — targeted checks passed; full `pnpm test:run` had unrelated local failures disclosed above - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots — N/A, no UI changes - [x] I have updated relevant documentation to reflect my changes — N/A, no user-facing docs or commands changed - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
9aa065a38c |
Make deleted-comment cleanup atomic
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
1afa337841 |
Address Greptile deleted-comment feedback
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
af0c43b205 | Address operator QoL review feedback | ||
|
|
5f481d50f1 |
Allow inline video attachment previews
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
39e0fba65f | Filter issues by plan document | ||
|
|
4afe5ab7cb | Add other answers to issue questions | ||
|
|
f360fcbbb3 |
Expire confirmations after user comments
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
17fa6fe0fe | Add deleted comment regression coverage | ||
|
|
7f70759e61 | Redact deleted issue comments | ||
|
|
0cca059705 |
Address catalog review cleanup
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
bee2b25f5d | Add referenced last30days catalog entry | ||
|
|
1227bb8ead |
Improve OpenAPI spec coverage and auth metadata (#4579)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Its REST API is the control-plane contract for the board UI, agents,
plugins, and external integrations
> - This branch adds `/api/openapi.json`, which makes the generated
OpenAPI document part of that contract instead of an internal
implementation detail
> - Once the spec is published, it has to match the mounted Express
routes, auth model, and real HTTP behavior closely enough for client
generation and review
> - The existing spec drifted from the live server: it missed mounted
routes, documented a few nonexistent ones, omitted auth semantics, and
normalized response codes too aggressively
> - This pull request makes the generated spec track the real API
surface, exposes security requirements, and adds regression coverage so
drift is caught automatically
> - The benefit is that Paperclip's published API description becomes
trustworthy for integrators, SDK generation, and review without changing
runtime auth enforcement
## What Changed
- Added the OpenAPI endpoint wiring under `server/src/routes/openapi.ts`
so `/api/openapi.json` is generated from the current route-backed
OpenAPI builder.
- Replaced generic request/response bodies with typed schemas where
available so the generated document carries useful structure instead of
opaque blobs.
- Expanded the generated spec to cover the mounted route set, including
access/member flows, CLI auth challenge routes, invite acceptance, issue
thread interaction routes, adapter environment testing, budget policy
routes, resource memberships, secret provider routes, cloud upstream
routes, and `/api/openapi.json` itself.
- Corrected documented path mismatches such as `skills/scan` vs
`skills/scan-projects`, and other route-name/path drift.
- Added security schemes plus operation-level security metadata so
public, authenticated, board-only, and instance-admin endpoints are
distinguishable in the generated contract.
- Fixed reviewed response-code mismatches for create/accept flows and
authz failures, including `201`, `202`, and `403` cases that were
previously flattened away.
- Added `server/src/__tests__/openapi-routes.test.ts` to diff the
generated spec against mounted server routes and assert key
auth/response invariants.
- Hardened the route-drift test after review feedback: it now handles
single/double/template route literals, fails on unlisted route files
that declare router methods, and filters OpenAPI path-item keys to HTTP
methods only.
## Verification
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts`
- `pnpm --filter @paperclipai/ui exec vitest run
src/pages/Inbox.test.tsx`
- `pnpm -r typecheck`
- `pnpm test:run`
- `pnpm build`
Manual notes:
- Confirmed the generated spec now matches the mounted route set in the
focused regression test.
- Confirmed `/api/plugins/install` is marked privileged in the generated
security metadata.
- Confirmed `POST /api/invites/{token}/accept` documents `202`.
- Addressed the Greptile route coverage comments and reran the focused
OpenAPI test, typecheck, and build successfully.
## Risks
- Medium-low risk. The main risk is ongoing spec drift if new routes are
added without updating the OpenAPI builder, but the regression test now
fails on unknown route files that declare router methods.
- The auth metadata is descriptive only; it does not change runtime
enforcement. If reviewers assume this PR hardens server auth behavior,
that would be an incorrect expectation.
- This change increases the amount of hand-maintained OpenAPI mapping in
`server/src/routes/openapi.ts`, so future API additions still need
discipline.
> 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. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in Codex desktop. Exact
internal model variant/version and context-window size are not exposed
in this environment. Tool-enabled coding workflow with terminal
execution, git, and GitHub integration.
## 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 or confirmed screenshots are not applicable
- [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: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
d60f50e4a4 |
feat(routines): suppress scheduled ticks while project is paused (TON-2139) (#7502)
Fixes #7501 ## Thinking Path Issue checkout already rejects paused projects (`issues.ts` → 409), but that fires only *after* the routine execution issue exists. Per internal TON-1102, the pause must be honored earlier — at the scheduler tick — so no execution issue is ever created while a project is paused. The fix gates dispatch in `tickScheduledTriggers` on the due routine's `projects.pausedAt`, while preserving normal cron advancement so resume does not backfill missed firings. ## What Changed - `server/src/services/routines.ts`: - `tickScheduledTriggers` LEFT JOINs `projects` and derives `projectPaused` from `projects.pausedAt`. Routines with no project are never suppressed. - When paused: the tick is still claimed and `routineTriggers.nextRunAt` advances by a single cron step (catch-up backfill bypassed while paused — no replay on resume); `recordSuppressedScheduleRun` runs instead of `dispatchRoutineRun`. - New `recordSuppressedScheduleRun` inserts one `routine_runs` row (`source: schedule`, `status: skipped`, `failureReason: paused`, `linkedIssueId: null`, `completedAt` set), updates routine/trigger touched state, and logs a `routine.run_skipped` activity entry. - `nextResultText` gains a `skipped_paused` branch for pause-specific audit text (does not overload the live-issue `skipped` text). - `server/src/__tests__/routines-service.test.ts`: focused test proving all four acceptance criteria (no issue created while paused; one `skipped`/`paused`/null-link run; `nextRunAt` advanced; normal resume on a later unpaused tick). ## Verification ```bash pnpm --filter @paperclipai/server exec tsc --noEmit npx vitest run server/src/__tests__/routines-service.test.ts ``` - The focused test in `routines-service.test.ts` proves all four acceptance criteria: no execution issue is created while the project is paused; exactly one `routine_runs` row is written with `source: schedule` / `status: skipped` / `failureReason: paused` / `linkedIssueId: null`; the trigger's `nextRunAt` advances by a single cron step (missed firings are not backfilled); and a later tick after the project is unpaused dispatches normally. ## Risks - Catch-up backfill is intentionally bypassed while paused — missed firings are **not** replayed on resume (specified no-backfill behavior). - Scope is deliberately narrow: manual runs, webhook/API triggers, routine-level paused status, workspace runtime start/stop, `concurrencyPolicy`, and `catchUpPolicy` (beyond no-backfill) are untouched. ## Model Used claude-opus-4-8 (Paperclip CTO heartbeat) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
244a5b8002 |
fix(plugins): allow agent JWTs to access plugin tool endpoints (supersedes #3272, with regression tests from #5549) (#7480)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Plugin tools are how agents call into plugin-contributed capabilities (`GET /api/plugins/tools`, `POST /api/plugins/tools/execute`) > - Those two routes previously required board-level authentication, so agent-issued JWTs were rejected — agents couldn't actually use the very tools the plugin system was built to expose to them > - Two community PRs (#3272 by @nullEFFORT and #5549 by @aperim-agent) independently fixed this, but both went stale against master and neither could be merged as-is > - This pull request lands #3272's authz-helper approach (`assertBoardOrAgent`) rebased on current master, and adds the regression test suite from #5549 adapted to #3272's symbol names > - The benefit is agents can finally call plugin tools while preserving the existing board-scoped checks for the rest of the plugin admin surface ## What Changed - Adds `assertBoardOrAgent(req)` helper in `server/src/routes/authz.ts` — accepts either a board user or an agent JWT - Applies `assertBoardOrAgent` (in place of `assertBoard`) on `GET /api/plugins/tools` and `POST /api/plugins/tools/execute` so agent-issued tokens can list and execute plugin tools - Updates the file-level doc comment on `server/src/routes/plugins.ts` to note the agent-accessible routes - Adds `server/src/__tests__/plugin-routes-authz.test.ts` (118 lines, 34 cases) covering: agent JWT can list tools, agent JWT can execute within its company scope, agent JWT is rejected when `runContext.companyId` is outside its authenticated scope, agent JWT is rejected when `runContext.agentId` does not belong to `runContext.companyId`, plus the existing board/admin paths ## Verification - \`pnpm vitest run server/src/__tests__/plugin-routes-authz.test.ts\` → **34/34 passing** locally - Diff vs master is exactly 3 files: \`authz.ts\` (+6), \`plugins.ts\` (+5/-3), \`plugin-routes-authz.test.ts\` (+118). No other surfaces touched. ## Risks Low risk. - Authorization is being *widened* on two specific routes (board → board or agent), not narrowed elsewhere. Every other plugin admin route still uses \`assertBoard\` / \`assertInstanceAdmin\` / \`assertBoardOrgAccess\`. - Agent JWTs already encode \`companyId\` and \`agentId\`; the existing \`validateToolRunContextScope\` queue still enforces that an agent cannot execute a tool against a different company or impersonate another agent. Regression coverage for both is included. - No schema, migration, or wire-protocol changes. ## Model Used - Claude (Anthropic), \`claude-opus-4-7\` via Claude Code, extended thinking enabled, tool use 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A, server-only change - [x] I have updated relevant documentation to reflect my changes (file-level doc comment on \`plugins.ts\`) - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge ## Provenance / credit This PR supersedes two community PRs that addressed the same agent-JWT plugin-tools authz gap: - **#3272 by @nullEFFORT** — original \`assertBoardOrAgent\` helper and the two route changes. \`fix: allow agent JWTs to access plugin tool endpoints\` (commit \`6991380\`) is cherry-picked here with author attribution preserved. - **#5549 by @aperim-agent** — regression test suite. Adapted to #3272's symbol names (\`assertBoardOrAgent\`, three-row \`validateToolRunContextScope\` queue) and included here. Both originals went stale against master and could not be force-pushed to the contributor forks from our OAuth-app-scoped tooling (workflow files in our \`master\` introduce a \`workflow\` scope requirement on pushes to those forks). This PR ships the same fix from our own branch so we can land it without that blocker. --------- Co-authored-by: Chad <chad@nulleffort.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
06ce7ec5b0 |
build(deps): bump dompurify from 3.3.2 to 3.4.8 (#7326)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.3.2 to 3.4.8. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/cure53/DOMPurify/releases">dompurify's releases</a>.</em></p> <blockquote> <h2>DOMPurify 3.4.8</h2> <ul> <li>Cleaned up the repository root, renamed some and removed unneeded files</li> <li>Fixed an issue with handling of Trusted Types policies, thanks <a href="https://github.com/fulstadev"><code>@fulstadev</code></a></li> <li>Fixed the node iterator for better template scrubbing, thanks <a href="https://github.com/IamLeandrooooo"><code>@IamLeandrooooo</code></a></li> <li>Included formerly missing LICENSE-MPL in published npm package, thanks <a href="https://github.com/asamuzaK"><code>@asamuzaK</code></a></li> <li>Bumped several dependencies where possible</li> </ul> <h2>DOMPurify 3.4.7</h2> <ul> <li>Hardened the handling of Shadow Roots when using <code>IN_PLACE</code>, thanks <a href="https://github.com/GameZoneHacker"><code>@GameZoneHacker</code></a></li> <li>Removed a problem leading to permanent hook pollution, thanks <a href="https://github.com/offset"><code>@offset</code></a></li> <li>Refactored the test suite and expanded test coverage significantly</li> </ul> <h2>DOMPurify 3.4.6</h2> <ul> <li>Fixed several issues with DOM Clobbering in <code>IN_PLACE</code> mode, thanks <a href="https://github.com/offset"><code>@offset</code></a> & <a href="https://github.com/Bankde"><code>@Bankde</code></a></li> <li>Hardened the checks for cross-realm <code>IN_PLACE</code> and Shadow DOM sanitization, thanks <a href="https://github.com/offset"><code>@offset</code></a> & <a href="https://github.com/Bankde"><code>@Bankde</code></a></li> <li>Added more test coverage for <code>IN_PLACE</code> and general DOM Clobbering attacks</li> <li>Bumped several dependencies where possible</li> </ul> <h2>DOMPurify 3.4.5</h2> <ul> <li>Fixed a bypass caused by the new HTML element <code>selectedcontent</code> added in 3.4.4, thanks <a href="https://github.com/KabirAcharya"><code>@KabirAcharya</code></a></li> </ul> <p><strong>Note that this is a security release for an issue introduced in 3.4.4 and should be upgraded to immediately.</strong></p> <h2>DOMPurify 3.4.4</h2> <ul> <li>Added the <code>selectedcontent</code> element to default allow-list, thanks <a href="https://github.com/lukewarlow"><code>@lukewarlow</code></a></li> <li>Added the <code>command</code> and <code>commandfor</code> attributes to default allowed-list, thanks <a href="https://github.com/lukewarlow"><code>@lukewarlow</code></a></li> <li>Added better template scrubbing for <code>IN_PLACE</code> operations, thanks <a href="https://github.com/DEMON1A"><code>@DEMON1A</code></a></li> <li>Added stronger checks for cross-realm windows, thanks <a href="https://github.com/DEMON1A"><code>@DEMON1A</code></a> & <a href="https://github.com/fg0x0"><code>@fg0x0</code></a></li> <li>Updated demo website and made sure it uses the latest from main</li> <li>Updated existing workflows, fuzzer, dependabot, etc., added more tests</li> <li>Bumped several dependencies where possible</li> </ul> <p>🚨 <strong>This release had been flagged as deprecated, please use DOMPurify 3.4.5 instead</strong> 🚨</p> <h2>DOMPurify 3.4.3</h2> <ul> <li>Fixed an issue with handling of nested Shadow DOM trees, thanks <a href="https://github.com/fishjojo1"><code>@fishjojo1</code></a></li> <li>Fixed the template regexes to be more robust against ReDoS attacks, thanks <a href="https://github.com/aleung27"><code>@aleung27</code></a></li> <li>Updated the node iteration code to catch more Shadow DOM related issues</li> <li>Updated Playwright and added Node 26 to test matrix</li> <li>Updated existing workflows, fuzzer, release signing, etc., added more tests</li> <li>Bumped several dependencies where possible</li> </ul> <h2>DOMPurify 3.4.2</h2> <ul> <li>Fixed an issue with URI validation on attributes allowed via <code>ADD_ATTR</code> callback, thanks <a href="https://github.com/nelstrom"><code>@nelstrom</code></a></li> <li>Fixed an issue with source maps referring to non-existing files, thanks <a href="https://github.com/cmdcolin"><code>@cmdcolin</code></a></li> <li>Updated existing workflows, fuzzer, release signing, etc., added more tests</li> <li>Bumped several dependencies where possible</li> </ul> <h2>DOMPurify 3.4.1</h2> <ul> <li>Fixed an issue with on-handler stripping for HTML-spec-reserved custom element names (<code>font-face</code>, <code>color-profile</code>, <code>missing-glyph</code>, <code>font-face-src</code>, <code>font-face-uri</code>, <code>font-face-format</code>, <code>font-face-name</code>) under permissive <code>CUSTOM_ELEMENT_HANDLING</code></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/cure53/DOMPurify/commit/bcdd8285412dc9c4c149652aed2d712e790d6ccf"><code>bcdd828</code></a> release: 3.4.8 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1439">#1439</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/ca30f070c360df162a3e3848e80e6fd3c9e74bff"><code>ca30f07</code></a> release: 3.4.7 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1414">#1414</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/bb7739e5bccec7e1ab3dae3f3e42d02db3acaaae"><code>bb7739e</code></a> release: 3.4.6 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1394">#1394</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/011b0c78f2a0f57ee54f5fcccb697a46ca6e63ea"><code>011b0c7</code></a> release: 3.4.5 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1382">#1382</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/5817ad969c15e67dfcd6cb37248d6e9c1553e7c3"><code>5817ad9</code></a> release: 3.4.4 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1374">#1374</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/520edb0371a9638f9b51f1798051299a250c686b"><code>520edb0</code></a> release: 3.4.3 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1352">#1352</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/6f67fd396a7b8c64294343999fe607ca1f5299c0"><code>6f67fd3</code></a> Sync/3.4.2 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1322">#1322</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/5b0cdbbf52331e854c0a2de875b1a3790ecec2b8"><code>5b0cdbb</code></a> chore: merge main into 3.x for 3.4.1 release (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1301">#1301</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/09f59115a311469de5b625225760593e551f080a"><code>09f5911</code></a> test: added three more browsers to test setup (OSX, mobile)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/5b16e0b892e82b1779d62b9928b43c4c4ff290b9"><code>5b16e0b</code></a> Getting 3.x branch ready for 3.4.0 release (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1250">#1250</a>)</li> <li>Additional commits viewable in <a href="https://github.com/cure53/DOMPurify/compare/3.3.2...3.4.8">compare view</a></li> </ul> </details> <details> <summary>Install script changes</summary> <p>This version adds <code>prepare</code> script that runs during installation. Review the package contents before updating.</p> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
07ec29bd84 |
build(deps): bump ajv from 8.18.0 to 8.20.0 (#7323)
Bumps [ajv](https://github.com/ajv-validator/ajv) from 8.18.0 to 8.20.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/ajv-validator/ajv/releases">ajv's releases</a>.</em></p> <blockquote> <h2>v8.20.0</h2> <h2>What's Changed</h2> <ul> <li>fix: add support for node 22/24, drop node 16/21 by <a href="https://github.com/jasoniangreen"><code>@jasoniangreen</code></a> in <a href="https://redirect.github.com/ajv-validator/ajv/pull/2580">ajv-validator/ajv#2580</a></li> <li>fix: add ES2022.RegExp for RegExpIndicesArray by <a href="https://github.com/SignpostMarv"><code>@SignpostMarv</code></a> in <a href="https://redirect.github.com/ajv-validator/ajv/pull/2604">ajv-validator/ajv#2604</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ajv-validator/ajv/compare/v8.19.0...v8.20.0">https://github.com/ajv-validator/ajv/compare/v8.19.0...v8.20.0</a></p> <h2>v8.19.0</h2> <h2>What's Changed</h2> <ul> <li>fix prototype pollution via format keyword using $data ref by <a href="https://github.com/epoberezkin"><code>@epoberezkin</code></a> in <a href="https://redirect.github.com/ajv-validator/ajv/pull/2607">ajv-validator/ajv#2607</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ajv-validator/ajv/compare/v8.18.0...v8.19.0">https://github.com/ajv-validator/ajv/compare/v8.18.0...v8.19.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ajv-validator/ajv/commit/0fba0b8e649909613cfce0999b149cd08f4a4987"><code>0fba0b8</code></a> 8.20.0</li> <li><a href="https://github.com/ajv-validator/ajv/commit/9caf8d64409b05e2c670b3ff09cf7ca07937342e"><code>9caf8d6</code></a> fix: add ES2022.RegExp for RegExpIndicesArray; fixes <a href="https://redirect.github.com/ajv-validator/ajv/issues/2603">ajv-validator/ajv#2603</a> (...</li> <li><a href="https://github.com/ajv-validator/ajv/commit/206535071f776f57737394c8896d4b2dc2bfb9a3"><code>2065350</code></a> fix: add support for node 22/24, drop node 16/21 (<a href="https://redirect.github.com/ajv-validator/ajv/issues/2580">#2580</a>)</li> <li><a href="https://github.com/ajv-validator/ajv/commit/154b58d690c6596e09ca676e12720ab8234ee3d2"><code>154b58d</code></a> 8.19.0</li> <li><a href="https://github.com/ajv-validator/ajv/commit/e8d2bdc501b3ba6f03922db5e595770d4763d9da"><code>e8d2bdc</code></a> test/fix prototype pollution via $data ref with format keyword (<a href="https://redirect.github.com/ajv-validator/ajv/issues/2607">#2607</a>)</li> <li>See full diff in <a href="https://github.com/ajv-validator/ajv/compare/v8.18.0...v8.20.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
93206f73fa |
fix: Stop archived companies from waking agents (#7478)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Each agent has a heartbeat scheduler that wakes it on timers and on
events; every wake spawns an adapter (Claude / Codex / …) run that bills
the operator's subscription
> - When an operator archives a company, the agents inside it remain in
invokable states — the heartbeat scheduler never consults company status
— so timers keep firing and event-driven wakes (comments, mentions,
blockers-resolved, etc.) keep cascading
> - On real deployments this silently drains the operator's
subscription: idle archived companies wake their CEOs hourly, plus any
cross-company event cascade
> - This pull request enforces "archived ⇒ never spawns a run" as a
structural invariant by guarding the wake path AND cascading agent state
on archive/reactivate
> - The benefit is that archived companies stop billing the operator,
and the UI/queue stays consistent with the invariant
## What Changed
- `server/src/services/heartbeat.ts`:
- `enqueueWakeup()` loads the company and short-circuits when status is
not `active`. Background sources (timer, automation, events) write a
`company.inactive` skipped wake and return `null`; explicit user invokes
throw a `conflict` so the UI surfaces the real reason.
- `tickTimers()` joins agents to active companies so the scheduler does
not iterate archived-company agents at all (no skip-row noise).
- `server/src/services/companies.ts`:
- `archive(id, actor?)` pauses runnable agents with `pauseReason =
"company_archived"` inside the transaction (preserving
`pending_approval`, `terminated`, and agents paused for unrelated
reasons), then cancels `queued`/`running` heartbeat runs after the
transaction commits.
- `update(id, data, actor?)` reverses the cascade only for agents whose
`pauseReason === "company_archived"` on the `archived → active`
transition; manually-paused agents stay paused.
- Both methods emit activity-log entries (`company.archived` with
`agentsPaused` + `runsCancelled`, `company.reactivated` with
`agentsRestored`) so the audit trail fires regardless of caller.
- `packages/shared/src/constants.ts` + `server/src/services/budgets.ts`:
add `company_archived` to the legal `PauseReason` union so the
restorable marker is a first-class value.
-
`packages/db/src/migrations/0094_backfill_archived_company_agent_pauses.sql`:
backfill so existing archived-company agents become `paused /
company_archived` (excludes `pending_approval`).
- `ui/src/lib/activity-format.ts`: add the `company.reactivated` label.
## Verification
- `npx vitest run src/__tests__/companies-service.test.ts` — archive
cascade, reactivate cascade, and activity-log entries (with counts) all
pass.
- `npx vitest run
src/__tests__/heartbeat-archived-company-guard.test.ts` — timer +
on-demand + event-wake paths all blocked for archived companies;
`company.inactive` skipped-wake row written; user-initiated wakes throw
`conflict`.
- `pnpm typecheck` — clean.
- Manual repro from the bug description: archive a company, wait an
interval / post a comment on one of its issues, observe zero new
heartbeat runs.
## Risks
- Migration `0094` is a single bulk UPDATE on `agents` joined to
archived `companies`. On large deployments it briefly holds row locks on
archived-company agent rows; should be quick because the predicate is
narrow (`status NOT IN (paused, terminated, pending_approval)` and
`companies.status = 'archived'`).
- New `pauseReason` value (`company_archived`) is opaque to older
clients that only know the previous union. Acceptable because the union
is read as plain text and the contract is sync'd in the same change.
- Behavior change for users: invoking an agent in an archived company
now fails with a conflict instead of silently spawning a run. Intended.
## Model Used
- Claude (Anthropic) — model `claude-opus-4-7` ("Opus 4.7"), Claude Code
CLI, with tool use (Read/Edit/Bash/Grep). No extended thinking mode.
## 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
- [ ] If this change affects the UI, I have included before/after
screenshots — N/A, no UI changes beyond an activity-log label string
- [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
## Related Work
Fixes #1348 (`[Bug] Archived companies still running heartbeats and
consuming tokens`).
Prior attempts and parallel work in this area:
- #1365 and #1429 by @hungdqdesign (March 2026) — both closed without
merging. Same three-layer shape (`tickTimers` / `enqueueWakeup` /
`resumeQueuedRuns` + archive-route cancellation) targeting #1348. Credit
for first publicly proposing the wake-path-guard approach.
- #5865 by @stubbi (May 2026, open) — adds the same `companies.status !=
'archived'` joins to `tickTimers`, `enqueueWakeup`, `resumeQueuedRuns`,
**and** routines `tickScheduledTriggers`, bundled with plugin-table
tenant isolation (`plugin_entities` / `plugin_job_runs` / `plugin_logs`
/ `plugin_webhook_deliveries` get a `companyId` FK with `ON DELETE
CASCADE`). This PR is narrower — it does not touch routines or plugin
tables — but adds the **archive cascade** (pause agents with
`pauseReason = "company_archived"`), the **reactivate reverse**
(un-pause only that subset), the **`company_archived` pause-reason
marker**, and a **backfill migration** for pre-existing archived
companies, which #5865 does not include. Happy to coordinate sequencing
or rebase if #5865 lands first.
|
||
|
|
62863126a3 |
fix(plugin-tool-dispatcher): propagate pluginDbId so worker.isRunning resolves (#5671)
Fixes #2391 Fixes #3394 Fixes #4094 Fixes #5501 Fixes #5916 Fixes #6215 Fixes #6514 ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Plugins extend the platform by registering agent-callable tools backed by long-running worker processes > - `PluginToolDispatcher` is the boundary between the HTTP `/api/plugins/tools/execute` route and `PluginWorkerManager`, which owns those worker processes > - `PluginWorkerManager` keys live workers by the plugin's **database UUID**, but `plugin-loader` was registering tools using only `pluginKey` — so every tool call did `workerManager.isRunning(pluginKey)` and always got `false` > - As a result, every `POST /api/plugins/tools/execute` against a tool-exposing plugin returned 502 `worker for plugin X is not running`, even though the worker process was alive (hit in production by `vexion.council-chat`; `mem0-sync` would be next) > - This pull request threads the DB UUID through the dispatcher → registry hop and hardens the contract so omitting the UUID is a compile-time error, not a silent fallback > - The benefit is plugin tool execution actually works for any plugin declaring `manifest.tools[]`, and the type system prevents the same bug from recurring ## What Changed - `server/src/services/plugin-loader.ts` — pass in-scope `pluginId` (DB UUID) as the third argument to `toolDispatcher.registerPluginTools`. Single-line root fix. - `server/src/services/plugin-tool-dispatcher.ts` — `registerPluginTools` now takes `pluginDbId: string` (required, was optional). JSDoc updated to document the worker-routing contract and why the optional signature masked the bug. - `server/src/services/plugin-tool-registry.ts` — `registerPlugin` throws on missing/empty `pluginDbId` so any new call site that forgets the UUID fails immediately rather than silently falling back to `pluginKey`. - `server/src/__tests__/plugin-tool-dispatcher-pluginDbId.test.ts` — new focused regression suite covering the activation path, disable→enable lifecycle, worker re-spawn, and the empty-UUID guard. ## Verification - `pnpm vitest run server/src/__tests__/plugin-tool-dispatcher-pluginDbId.test.ts` — 6/6 passing. - `pnpm vitest run server/src/__tests__/plugin-database.test.ts server/src/__tests__/plugin-routes-authz.test.ts server/src/__tests__/plugin-lifecycle-restart.test.ts` — 48/48 passing on the merge commit. - `pnpm --filter @paperclipai/server typecheck` — no new errors introduced by these files. - Manual repro path: 1. Install a plugin that declares `manifest.tools[]` and uses `runWorker`. 2. Confirm status `ready` and a live worker (`paperclipai plugin diagnostics <key>`). 3. `POST /api/plugins/tools/execute` with `{ tool: "<pluginKey>:<toolName>", parameters, runContext }`. 4. Pre-fix: HTTP 502, `worker for plugin <key> is not running`. Post-fix: tool dispatches normally. ## Risks - Low risk. The signature tightening (`pluginDbId?` → `pluginDbId`) is a back-compatible behavioral fix at the only production call site (`plugin-loader`), which already had the UUID in scope. - Test/recovery paths that previously omitted the UUID must now supply it; the new error message identifies the missing arg explicitly. - No database migration, no API/schema change, no plugin-author-facing change. - The merge commit pulls master into the PR branch additively (no rebase); reviewers can read the fix commits independently of the merge. ## Model Used - Provider/model: Anthropic Claude (Opus 4.7, `claude-opus-4-7`) for the additive merge-conflict resolution, PR description rewrite, and Greptile follow-up; original fix authored by [@Ramon-nassa](https://github.com/Ramon-nassa). - Capabilities used: tool use (file edit, shell, GitHub CLI), extended thinking off, no code execution by the model. ## 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 - [ ] If this change affects the UI, I have included before/after screenshots (N/A — server-only change) - [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 --- ## Original Summary (preserved from contributor) `plugin-loader` activates plugins and calls ```ts toolDispatcher.registerPluginTools(pluginKey, manifest) ``` with only two args. `PluginToolDispatcher.registerPluginTools` forwards them to `registry.registerPlugin(pluginKey, manifest)`. The registry falls back `pluginDbId ?? pluginKey`, but `PluginWorkerManager` keys live workers by the DB UUID — so the downstream ```ts workerManager.isRunning(pluginKey) // always false ``` causes every `POST /api/plugins/tools/execute` to fail with `worker for plugin X is not running`, even when the worker process is alive and healthy. **This hits every plugin that exposes tools** (we hit it in `vexion.council-chat`; `mem0-sync` would too). Reported-by: Vexion / Ramon Nassar (vexion.council-chat plugin, MO-068). --------- Co-authored-by: ramon nassar <ramon@tabs.co> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Devin Foley <devin@devinfoley.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
70b1a9109d |
Improve CLI API parity coverage (#6626)
## Thinking Path > - Paperclip is a control plane for AI-agent companies, with the CLI acting as a scriptable operator and agent interface to that control plane. > - The REST API surface has grown across companies, agents, issues, routines, plugins, auth, workspaces, secrets, and operational inspection commands. > - The CLI had drifted from that API surface: some commands were missing, some command shapes differed from docs/reference material, and several edge cases only failed during end-to-end local-source testing. > - The local development runbook requires these tests to be disposable and isolated from a real `~/.paperclip`, `~/.codex`, or `~/.claude` installation. > - This pull request adds broad CLI/API parity coverage, fixes the actionable bugs found during that pass, and records the reproducible test log under `doc/logs`. > - The benefit is a more complete, scriptable CLI surface with regression coverage for the command families exercised by the parity run. ## What Changed - Added or expanded CLI command coverage for access/auth, companies, agents, projects, goals, issues and subresources, routines, plugins, workspaces, activity/run/cost/dashboard inspection, assets, skills, secrets, tokens, prompt/wake flows, and local setup helpers. - Fixed CLI/API parity bugs found during the run, including context profile patching, issue interaction optional payloads, malformed tree-hold errors, environment duplicate handling, configure invalid-section exit codes, worktree pnpm invocation, token agent ID resolution, plugin tool worker lookup, and routine webhook secret cleanup. - Added missing CLI wrappers and route coverage for health/access, invite resolution URL forwarding, join status normalization, secret lifecycle commands, LLM docs routes, available-skill isolation, positive board-claim coverage, and interactive `connect` prompt-flow tests. - Added a schema-backed `/api/openapi.json` route sufficient for CLI parity and `paperclipai openapi --json` smoke coverage. - Added `doc/logs/2026-05-24-cli-api-parity-e2e-log.md` with the detailed living test/bug log and renamed the log directory from `doc/bugs` to `doc/logs`. - Added `doc/plans/2026-05-23-cli-api-parity.md` and the OpenAPI parity reference used during the pass. OpenAPI note: this PR intentionally does not try to subsume `feature/openapi-spec`. The OpenAPI implementation here is schema-backed and better than the earlier route-inventory stub, but `feature/openapi-spec` is the fuller/better OpenAPI branch because it includes exact mounted-route coverage tests and additional current route coverage. That branch should stay as its own PR and can supersede this OpenAPI route implementation. ## Verification Targeted automated checks run: - `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts` - `pnpm exec vitest run server/src/__tests__/board-claim.test.ts` - `pnpm exec vitest run cli/src/__tests__/connect.test.ts` - `pnpm exec vitest run cli/src/__tests__/agent-lifecycle.test.ts` - `pnpm exec vitest run server/src/__tests__/plugin-database.test.ts` - `pnpm exec vitest run server/src/__tests__/routines-service.test.ts` - `pnpm --dir cli typecheck` - `pnpm --dir server typecheck` Manual/local E2E verification: - Ran the full disposable local-source CLI/API parity pass with isolated `PAPERCLIP_HOME`, `PAPERCLIP_CONFIG`, `PAPERCLIP_CONTEXT`, `PAPERCLIP_AUTH_STORE`, `CODEX_HOME`, and `CLAUDE_HOME` under `tmp/cli-api-parity`. - Verified `DATABASE_URL` and `DATABASE_MIGRATION_URL` stayed unset for the scratch server. - Verified live health and schema-backed OpenAPI responses on non-default port `3197`. - Revoked created board/agent tokens and cleaned up temporary plugins, secrets, non-default environments, and project workspaces. - See `doc/logs/2026-05-24-cli-api-parity-e2e-log.md` for the full command-by-command reproduction log. Not run: - Full `pnpm test`, `pnpm test:run`, or `pnpm build` were not run after the entire branch because the branch is broad and the parity pass used focused test/typecheck verification plus live isolated CLI reruns. ## Risks - This is a broad PR and touches many CLI command modules, so review surface is high. The changes are grouped around one theme, but a split may be easier if maintainers prefer narrower PRs. - The OpenAPI route in this PR is not the final/best OpenAPI implementation. `feature/openapi-spec` has stronger exact-route coverage and should remain the source for the dedicated OpenAPI PR. - The living log is intentionally detailed and large. It is useful for reproducibility but adds documentation weight. - No UI changes are intended; screenshots are not applicable. > 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-based coding agent in Codex desktop. Exact served model/context-window identifier was not exposed in the local app. Work used shell/Git/GitHub CLI tooling, local source inspection, targeted test execution, and live isolated Paperclip CLI/API smoke testing. ## 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 --------- Co-authored-by: Devin Foley <devin@devinfoley.com> |
||
|
|
d58a862549 |
fix(issues): coerce anchor.createdAt to Date before postgres binding (PRO-3144) (#5220)
## Thinking Path > - Paperclip orchestrates AI agents in a control plane backed by Postgres + drizzle-orm > - `listComments` is the cursor-paginated comment listing on the issues service; the cursor branch uses Drizzle's `gt`/`lt`/`eq` against `issueComments.createdAt` > - On postgres.js v3.4.8, passing a `Date` instance through the comparison helpers triggers `TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Date` > - The driver's binding path expects a Date constructed via the standard runtime, but drizzle's `select` returns instances that don't satisfy that check in this version > - This PR coerces `anchor.createdAt` through `toISOString()` → `new Date(...)` so the comparison helpers always receive a binding-safe Date, then folds in a follow-up that hoists the Date into a single allocation reused across all four `gt`/`lt`/`eq` call sites > - The benefit is `listComments` cursor pagination stops 500-ing on Pg v3.4.8 with one Date allocation per call instead of four, exercised by both ascending and descending cursor tests ## What Changed - `server/src/services/issues.ts` — coerce `anchor.createdAt` to a binding-safe `Date` once and reuse the same instance across all four cursor comparisons (`gt` / `lt` / `eq`) - `server/src/__tests__/issues-service.test.ts` — add an ascending-cursor sibling test so both `gt` and `lt` cursor paths are exercised; the existing descending test continues to pass ## Verification ```bash # Both cursor branches pnpm --filter @paperclipai/server exec vitest run \ src/__tests__/issues-service.test.ts -t "anchor comment" # → 2 passed, 41 skipped # Production smoke curl -s "$PAPERCLIP_API_URL/api/issues/<issueId>/comments?after=<commentId>&order=asc" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" # Expect: JSON array, no 500 TypeError ``` ## Risks - Low risk. Pure cursor-pagination internals in `listComments`; no schema, migration, or external contract changes - Drizzle's `gt`/`lt`/`eq` continue to receive a `Date` for the timestamp column, producing the same bound parameter as before - Behavioural surface is exercised by ascending + descending cursor tests against a real Postgres test database ## Model Used - Claude Opus 4.7 (`claude-opus-4-7`), no extended-thinking mode, used for the hoist+test follow-up commit ## Fixes Closes #2612, Closes #3661, Closes #3830 ## 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 - [ ] If this change affects the UI, I have included before/after screenshots — n/a, backend-only - [x] I have updated relevant documentation to reflect my changes — n/a, no docs touched - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Elena Voronova <elena@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Devin Foley <devin@devinfoley.com> |
||
|
|
edeab22c28 |
Merge pull request #7362 from paperclipai/pap-10195-dev-runner-race
[codex] Fix dev runner snapshot race |
||
|
|
dc58544832 | Address dev runner snapshot review feedback | ||
|
|
8f25ba6381 | Add dev runner snapshot race regression test | ||
|
|
8af359b656 |
Detect misclassified video attachments
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e080e4686a |
Move artifact upload details to skill reference
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
c4bb68c14b |
Bundle artifact upload helper with Paperclip skill
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e7cdd0f8c5 |
Move artifact upload guidance into Paperclip skill
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
04a19cbc6e | Address artifact PR review feedback | ||
|
|
bbf77fcb69 | Harden issue artifact metadata | ||
|
|
0bd13c23a9 |
Add agent artifact upload workflow
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
75f88c588c | Support video issue attachments | ||
|
|
911a1e8b0d |
Fix continuation recovery retry streaks by failure cause (#7031)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The recovery subsystem is responsible for keeping assigned work moving when a live heartbeat run disappears or fails. > - `continuation_recovery` is the path that re-enqueues stranded `in_progress` issues after an interrupted continuation attempt. > - That path recently gained cause-aware retry classes and transient retry caps, but the streak counter was still aggregating mixed failure causes into one retry history. > - That meant a sequence like `timeout -> timeout -> adapter_failed -> adapter_failed` could escalate as a false `3x adapter_failed` streak even though the latest cause had only happened twice. > - This pull request makes continuation retry streaks count only consecutive failures whose `errorCode` matches the latest run and adds a regression test for the mixed-cause case. > - The benefit is that transient retry backoff and escalation now match the actual current failure cause instead of inheriting stale budget from unrelated failures. ## What Changed - Updated `summarizeRecentContinuationRetries(...)` to stop counting as soon as the continuation failure cause no longer matches the latest run's `errorCode`. - Wired the continuation recovery escalation/backoff path to pass the latest classified `errorCode` into the retry streak summarizer. - Added a regression test proving mixed-cause continuation failures do not consume the transient retry cap for a new failure cause. ## Verification - `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts` ## Risks - Low risk. The behavioral change is intentionally narrow, but any future continuation retry modes that rely on `errorCode = null` will now be counted as a separate streak bucket and should be kept in mind when adding new retry classifications. ## Model Used - OpenAI Codex via Paperclip `codex_local` (GPT-5-based Codex coding agent; exact backend revision is not surfaced in the runtime), with tool use, shell execution, and patch application in the local repository. ## 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 - [ ] If this change affects the UI, I have included before/after screenshots - [ ] 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> |
||
|
|
5153b01ada |
[codex] Add Claude model refresh (#6953)
## Thinking Path > - Paperclip orchestrates AI-agent companies through adapter-backed local and external runtimes. > - The agent configuration UI lets operators choose adapter models and refresh model lists when adapters support live discovery. > - Codex already had a live refresh path, but Claude Local only exposed static fallback models and the UI hid the refresh action for Claude. > - A newly available Claude Opus model should not require a code release every time the model catalog changes. > - This pull request adds Anthropic model discovery for Claude Local, keeps the static fallback current with Claude Opus 4.8, and exposes the existing refresh button in the Claude Local dropdown. > - The benefit is that operators can refresh Claude models from the same model selector flow they already use for Codex. ## What Changed - Added `claude-opus-4-8` to the Claude Local fallback model list. - Added Claude model discovery through Anthropic-compatible `GET /v1/models` when `ANTHROPIC_API_KEY` is available. - Added normal cache reuse, forced refresh support, a SHA-256-based API-key fingerprint for cache keys, and warning logging for discovery errors before fallback. - Wired `claude_local.refreshModels` into the server adapter registry. - Enabled the existing `Refresh models` dropdown action for `claude_local` in `AgentConfigForm`. - Added tests for Claude fallback, live discovery, API-failure fallback, forced refresh, and the UI refresh-button gate. ## Verification - `pnpm exec vitest run server/src/__tests__/adapter-models.test.ts` - `pnpm exec vitest run ui/src/components/AgentConfigForm.test.ts` - `pnpm --filter @paperclipai/adapter-claude-local typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - Greptile review reached Confidence Score: 5/5 on commit `b796cf4f1` with addressed threads resolved. UI note: the visible change is a conditional action row inside the existing model dropdown; the regression test covers that `claude_local` now receives the refresh action. ## Risks - Low risk. Without `ANTHROPIC_API_KEY`, Claude Local still uses the static fallback list. - If Anthropic model discovery fails or times out, Paperclip falls back to the existing cached or static list. - Bedrock environments remain on Bedrock-native model IDs. ## Model Used OpenAI GPT-5 via Codex local coding agent, with repository file access, shell command execution, git operations, and targeted test/typecheck verification. Exact context window is not exposed by the 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 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 |