mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-09 06:15:21 +02:00
4d50fa9f296a651cf8abe4dee8cf2d9c5decff7d
353
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b13eb5b2b5 |
Skill Studio: three-pane skill IDE with sandboxed test runs (#9241)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Skills Manager gives operators a reusable skill layer, but iteration still required manual edits, ad hoc prompts, and indirect run inspection. > - Skill authors need a focused workflow for editing skill files, saving representative test inputs, and running those inputs through an agent without exposing harness tasks as normal company work. > - The backend therefore needs durable test inputs, reusable run templates, hidden harness issues, scoped run execution, retention metadata, and read-containment rules around hidden work. > - The frontend needs a three-pane Studio that keeps skill files, saved inputs/templates, and run output/history visible together while preserving the existing design system and token rules. > - This pull request ships that Skill Studio surface end to end: database migrations, shared contracts, server APIs/services, hidden harness execution behavior, UI routes/components, and focused tests. > - The benefit is faster and safer skill iteration, with inspectable outputs and fewer ways for internal harness work to leak into normal task lists, costs, or adjacent read APIs. ## Linked Issues or Issue Description No public GitHub issue exists for this feature. Feature request summary: - Problem: Skill authors need to edit and test company skills in one place instead of switching between the skill detail page, task creation, run output, and manual prompt history. - Proposed solution: Add a Skill Studio workbench with saved inputs, reusable templates, hidden sandboxed test runs, live run status, output inspection, run history, rerun/delete controls, and frontmatter-aware editing. - Expected users: Paperclip operators and agent-company maintainers who create, fork, import, and tune skills. - Related public PRs: Supersedes #9205, which was replaced so the public PR branch name follows contributor policy. - Duplicate search: searched public GitHub issues and PRs for "Skill Studio"; no other active public issue or PR directly covers this feature. ## What Changed - Added database migrations for Skill Studio test inputs, test runs, test run retention, and reusable run templates. - Added shared Skill Studio types, validators, route helpers, frontmatter utilities, and status handling. - Added server services and routes for saved inputs, test runs, templates, reruns, terminal-run deletion, hidden harness issue execution, and run-detail hydration. - Strengthened hidden-issue read containment across issue-adjacent routes and cost rollups used by skill test harness work. - Added the Skill Studio UI with skill file editing, frontmatter editing, saved inputs, templates, run creation/cancel/rerun/delete flows, output rendering, history, route support, and responsive pane behavior. - Added focused backend, shared, and UI tests for the new APIs, routing logic, editor/run behavior, hidden-issue containment, and migration safety. - Rebased onto current `master`, removed the generated lockfile diff from the PR, and verified no workflow files are changed. ## Verification - [x] `pnpm --filter @paperclipai/db check:migrations` - [x] `pnpm check:token-gates` - [x] `pnpm exec vitest run server/src/__tests__/company-skills-service.test.ts server/src/__tests__/company-skills-routes.test.ts server/src/__tests__/company-skill-test-runs-service.test.ts ui/src/lib/skill-studio.test.ts ui/src/pages/SkillStudio.test.tsx` — 5 files, 132 tests passed - [x] Greptile review on the latest PR head - [x] GitHub PR checks on the latest PR head ## Risks - Medium risk because this is a broad feature touching database schema, server orchestration, issue visibility, and a large UI surface. - Hidden harness issue containment is security-sensitive; this PR includes regression coverage for adjacent read paths and cost rollups. - The new migrations are additive and use idempotent guards where applicable, but deployed databases that previously tested draft migration numbers should still be checked carefully. - The UI depends on a new resizable panels package in `ui/package.json`; the lockfile is intentionally left to repository automation. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, GPT-5 coding agent with shell, git, and GitHub CLI tool use. Earlier feature commits include assistance from other Paperclip coding agents; this PR preparation, rebase, cleanup commit, and PR body were completed by OpenAI Codex in a Paperclip worktree. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
719da5f9b5 |
Harden environment deletion and expose delete blast radius (#9250)
## Thinking Path > - Paperclip manages AI agents that each have an associated execution environment (local, Kubernetes, etc.) > - Instance administrators can create and delete environments; currently the DELETE endpoint has no protection against deleting managed or in-use environments > - Deleting the managed local environment or the instance-default environment would break all agents using those environments with no path to recovery > - The endpoint also suffered a TOCTOU race: a check-then-delete pattern allowed the managed-local or default guard to pass if the environment's role changed between the read and the delete > - This pull request adds a blast-radius read endpoint so admins can preview impact, hard-blocks the dangerous deletes atomically, cleans up all dependent references after a valid delete, and fixes a concurrent creation race in ensureLocalEnvironment ## Linked Issues or Issue Description Fixes #9251 ## What Changed - **New endpoint** `GET /api/environments/:id/delete-blast-radius` (instance-admin gated): returns reference counts (agent defaults, workspace selections, issue selections, project selections, secret bindings, active leases, active setup sessions) and blocking reasons — no config, env-var values, or secret data returned. - **Atomic delete guard** `environmentService.removeIfDeletable(id)`: performs the DELETE with an inline `WHERE driver != 'local' AND NOT EXISTS (instanceSettings where defaultEnvironmentId = id)` predicate, eliminating the TOCTOU race between the app-level check and the DB write. - **Route hardening**: `DELETE /environments/:id` now calls `getDeleteBlastRadius` first (app-level check + logging), then calls `removeIfDeletable` (atomic guard). If the atomic guard returns null the route fetches a fresh blast-radius snapshot and rejects with a 409 Conflict carrying `deleteBlockedReasons`. - **Reference cleanup on valid delete**: after a successful delete, the route clears environment selections on all company execution workspaces, issues, and projects; syncs env-var secret bindings to `{}` (removing bindings for the deleted environment); syncs config secret refs to `[]` for the environment target; and removes the SSH private-key secret if one was stored. - **Race fix in `ensureLocalEnvironment`**: the insert-or-nothing path now catches a `environments_name_idx` unique-constraint violation and falls through to the existing SELECT, treating the name conflict as idempotent. - **Shared types**: `EnvironmentDeleteBlastRadius` and `EnvironmentDeleteBlockedReason` exported from `@paperclipai/shared`. - **OpenAPI**: registers the new blast-radius endpoint; updates the delete-environment response schema to document 403/404/409. - **Tests**: 56 existing environment-route and service tests continue to pass; new service-level regression tests assert the atomic guard rejects `local`-driver environments and instance-default environments and succeeds for deletable ones. ## Verification ``` corepack pnpm exec vitest run \ server/src/__tests__/environment-routes.test.ts \ server/src/__tests__/environment-service.test.ts # 56 tests, all passing corepack pnpm --filter @paperclipai/shared typecheck node scripts/ensure-plugin-build-deps.mjs cd server && ../node_modules/.bin/tsc --noEmit ``` ## Risks - **Blast-radius endpoint auth**: guarded by `assertCanAccessInstanceEnvironments`, the same gate as the existing environment-list and delete routes. Non-admin callers receive 401/403 before any data is returned. - **Atomic guard may reject a delete that the app-level check passed**: this is intentional — it means the environment became protected between the read and the write. The caller receives a fresh blast-radius snapshot explaining why. - **Secret cleanup ordering**: cleanup runs after the atomic DELETE succeeds, in parallel across companies. If cleanup partially fails the environment row is already gone; partial-cleanup state is recoverable by re-running the sync operations. Risk: low — these are idempotent upsert/sync operations. - **ensureLocalEnvironment race fix**: swapping a unique-constraint error for an idempotent SELECT adds one extra query on the conflict path. This path is rare (only fires during concurrent boot) and is significantly safer than the previous behavior. - **No migration**: all changes are application-level; no schema changes required. ## Model Used - Provider: Anthropic - Model: claude-sonnet-4-6 (Claude Sonnet 4.6) - Context window: 200k tokens - Mode: agentic tool use via Paperclip agent system (Claude Code) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Priya Raman <priya.raman@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Harold Kim <harold.kim@paperclip.ing> |
||
|
|
1b16f9611c |
feat(telemetry): document credential health retention (#9248)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The shared telemetry package (`packages/shared/src/telemetry`) defines the public contract for first-party telemetry events — event names, dimension shapes, and now retention windows > - A new telemetry event, `codex.credential_health`, carries credential-observability fields (enums, booleans, counts, coarse buckets) — no token material and no PII > - The retention window for this event and its class was undocumented at the contract level, leaving data-infra and reviewers without a discoverable source of truth > - This pull request adds `retention.ts` as the canonical retention-contract surface, assigns `codex.credential_health` to the `operational_enum_count` class (90-day window), exports the contract from the shared package, and updates the README > - The benefit is that the retention window is discoverable from the event definition rather than being implicit pipeline knowledge, and the no-token/no-PII note is locked in a contract test rather than relying on prose ## Issue Description No public GitHub issue exists for this change. Inline description follows the [feature request template](.github/ISSUE_TEMPLATE/feature_request.yml): ### Problem or motivation `packages/shared/src/telemetry/` applies a 90-day retention window to `codex.credential_health` events at the pipeline level, but this policy is not stated anywhere in the shared telemetry contract. Without a discoverable retention declaration, reviewers and data-infra must read pipeline configuration to understand retention behaviour — there is no contract-level source of truth. The `codex.credential_health` event carries only enums, booleans, counts, and coarse buckets — no token material and no PII. ### Proposed solution Add a `retention.ts` module to the shared telemetry package that defines the `operational_enum_count` retention class (90-day window) and maps `codex.credential_health` to it. Export the contract from the package index and add a focused contract test. Update the README with a Retention section and a pointer in the Public Sources table. This is additive documentation only — no runtime paths change. ### Alternatives considered Keep retention implicit in pipeline configuration only. Rejected: this leaves no discoverable, versioned contract for reviewers or data-infra, and means every consumer must read pipeline config to understand retention semantics. A schema-level declaration is the correct long-term home. ### Roadmap alignment Aligns with the telemetry contract hardening track — making implicit operational knowledge explicit and testable at the shared-package level. ## What Changed - **`packages/shared/src/telemetry/retention.ts`** (new): defines `RETENTION_DAYS` (class → days) and `EVENT_RETENTION_CLASS` (event name → class). `operational_enum_count` is the only class: 90-day window for enum/count/bucket events with no token material or PII. `codex.credential_health` is the first entry. The `string` key type is intentional to accommodate cross-system events (e.g. the Codex CLI) not yet promoted to the first-party `PaperclipEventName` schema. - **`packages/shared/src/telemetry/retention.test.ts`** (new): three focused assertions — `operational_enum_count` is 90 days, `codex.credential_health` is assigned that class, and the resolved window is 90 days. - **`packages/shared/src/telemetry/index.ts`**: exports `RETENTION_DAYS`, `EVENT_RETENTION_CLASS`, and `RetentionClass` from the shared package. - **`packages/shared/src/telemetry/README.md`**: adds `retention.ts` to the Public Sources table and a new Retention section with a class reference table and guidance for future assignments. ## Verification - `git diff --check` passes (no whitespace errors) - `pnpm --filter @paperclipai/shared exec vitest run src/telemetry/retention.test.ts src/telemetry/readme-contract.test.ts` — runs the new contract tests and the existing readme-contract test - `pnpm --filter @paperclipai/shared typecheck` — confirms the new exports compile cleanly - CI gates green ## Risks Low risk. This is a documentation-only addition: - No new telemetry event, dimension, emitter, or schema change - No runtime code paths changed - The new file is tree-shaken away in any consumer that doesn't import from it - `satisfies Record<string, number>` on `RETENTION_DAYS` ensures the type stays correct as new classes are added ## Model Used Claude Sonnet 4.6 (`claude-sonnet-4-6`) — Anthropic, 200k context window, tool use enabled, no extended thinking mode. Used for code authoring and PR composition. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Harold Kim <harold.kim@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Harold Kim <harold-kim@paperclip.ing> |
||
|
|
eedc7ddef2 |
Make ACP the default engine for local adapters (#9238)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Adapter packages are the bridge between the control plane and local agent harnesses such as Claude Code, Codex, and Gemini CLI. > - ACP support was concentrated in a separate `acpx_local` adapter, which made ACP feel like a separate agent choice instead of an execution capability of the harness adapters. > - Claude, Codex, and Gemini now have ACP-capable harnesses, so the native adapter should own ACP selection, fallback, config, transcript parsing, and environment diagnostics. > - The standalone ACPX adapter still needs a compatibility path for existing rows, but it should not be offered as an active adapter for new agents. > - This pull request moves the shared ACP runtime into `@paperclipai/acpx-engine`, wires Claude/Codex/Gemini local adapters to prefer ACP when prerequisites are available, and retires `acpx_local` to a tombstone. > - The benefit is one adapter per harness, richer ACP transcripts by default where possible, and a migration path for existing Claude/Codex ACPX agents. ## Linked Issues or Issue Description Closes #5932 — the broken default `acpx_local` Claude path is replaced by native `claude_local` ACP support, existing Claude/Codex ACPX rows migrate to native adapters, and new agents no longer choose the standalone ACPX adapter. Refs #4893 — original merged ACPX local adapter runtime that this PR replaces with native per-harness ACP engines. Refs #6590 — prior ACPX-Claude seamlessness work folded into the new native Claude ACP path. Refs #197 — related open generic ACP/Kiro adapter work; this PR does not close it because Kiro/custom generic ACP remains a separate adapter decision. Refs #7018 — related Kimi-specific `acpx_local` shell failure; this PR retires the built-in standalone adapter but does not add a native Kimi adapter. Refs #8864 — related ACPX prompt/API guidance PR; this PR moves runtime guidance into the shared/native ACP engine path instead of the old standalone adapter. Refs #8881 — related `acpx_local` POSIX shell failure from the old `acpx` pin; this PR updates ACP dependencies but does not claim custom/OMP ACP support as a first-class native adapter. Refs #8964 — related open `acpx_local` stderr cleanup PR; this PR makes the old runtime path obsolete for new agents but keeps it as a non-closing reference. Problem description: - The standalone `acpx_local` adapter duplicates Claude/Codex agent choices that already have first-class local adapters. - ACP should be an execution engine capability of each harness adapter when the underlying harness supports ACP. - Existing `acpx_local` agents should either migrate to native harness adapters or fail with an explicit retirement message instead of silently falling back to the process adapter. ## What Changed - Added `@paperclipai/acpx-engine` as the shared ACP execution, session-codec, CLI formatter, and UI parser package. - Wired `claude_local`, `codex_local`, and `gemini_local` to auto-select ACP by default when prerequisites pass, with `engine=cli` opt-out and `engine=acp` strict mode. - Added ACP config schema/UI fields, environment checks, session-codec preservation, transcript parsing, and adapter capability metadata for the native adapters. - Retired `acpx_local` to a server tombstone, removed its UI/package/runtime image surface, and added a migration for existing Claude/Codex ACPX agents. - Updated package manifests, lockfile, release tooling, docs, Kubernetes sandbox defaults, and tests. ## Verification - `corepack pnpm --filter @paperclipai/acpx-engine typecheck` - `corepack pnpm --filter @paperclipai/adapter-claude-local typecheck` - `corepack pnpm --filter @paperclipai/adapter-codex-local typecheck` - `corepack pnpm --filter @paperclipai/adapter-gemini-local typecheck` - `corepack pnpm --filter @paperclipai/acpx-engine exec vitest run` - `corepack pnpm --filter @paperclipai/adapter-claude-local exec vitest run src/server/acp.test.ts src/server/execute.acp-fallback.test.ts src/ui/build-config.test.ts` - `corepack pnpm --filter @paperclipai/adapter-codex-local exec vitest run src/server/acp.test.ts src/ui/build-config.test.ts` - `corepack pnpm --filter @paperclipai/adapter-gemini-local exec vitest run src/server/acp.test.ts src/ui/build-config.test.ts src/ui/parse-stdout.test.ts` - `corepack pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && corepack pnpm --filter @paperclipai/server exec tsc --noEmit` - `corepack pnpm --filter @paperclipai/server exec vitest run src/__tests__/adapter-routes.test.ts src/__tests__/adapter-session-codecs.test.ts src/__tests__/adapter-models.test.ts` - `corepack pnpm --filter @paperclipai/ui typecheck` - `corepack pnpm --filter @paperclipai/ui exec vitest run src/adapters/metadata.test.ts src/adapters/adapter-display-registry.test.ts src/components/AgentConfigForm.test.ts src/components/AgentConfigForm.render.test.tsx src/components/transcript/RunTranscriptView.test.tsx` - `node --test scripts/bootstrap-npm-package.test.mjs scripts/release-package-map.test.mjs scripts/verify-release-registry-state.test.mjs` Note: the server typecheck script calls `pnpm` internally; this dev shell exposes pnpm through Corepack only, so I ran the two script steps manually with `corepack pnpm`. ## Risks - Migration changes existing `acpx_local` Claude/Codex agents to native adapter types and clears old ACPX task sessions/runtime state. - Custom ACP commands remain on the retired tombstone and will need a separate future adapter/plugin path. - ACP auto-selection depends on local Node and ACP server command prerequisites; remote and unsupported environments fall back to CLI unless `engine=acp` is explicit. - `@paperclipai/acpx-engine` is a new public package and needs npm trusted-publishing bootstrap before release automation can publish it. > 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 via Codex coding agent. Exact hosted model build and context-window size are not exposed in this runtime. Tool use included shell execution, repository editing, GitHub CLI operations, and local test/typecheck execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3288ec4f47 |
chore: ignore materialized Paperclip runtime directory
Adds .paperclip-runtime/ to .gitignore so the materialized adapter credentials directory is never accidentally committed. |
||
|
|
4a7a732476 |
feat(skills): add company skill fork prechecks (#9235)
Adds company skill fork precheck metadata, fork result/reassignment contracts, selected-agent reassignment during fork creation, and targeted server/shared test coverage. |
||
|
|
562567fcd6 |
[codex] Improve work timeline activity story (#9222)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The work timeline helps operators understand when agent and user activity actually happened across a project. > - The timeline view needs clearer interaction context so activity is easier to inspect and reason about. > - The existing story coverage did not fully exercise the denser activity states needed to review this UI safely. > - This pull request expands the work timeline data shape, service behavior, UI rendering, tests, and Storybook story so the activity timeline is easier to verify. > - The benefit is a more inspectable timeline for project activity, backed by targeted server and UI coverage. ## Linked Issues or Issue Description No public GitHub issue found, so this PR describes the feature inline following the feature request template. **Subsystem affected** Cross-cutting: `server/`, `packages/shared`, and `ui/`. **Problem or motivation** Project operators need a clearer timeline view that shows when work activity happened, how much agent time is represented inside the selected window, and enough realistic activity states for safe visual review. Sparse mock data and unbounded summary calculations make it harder to trust the timeline when inspecting historical or capped windows. **Proposed solution** Enrich the work timeline activity data returned by the service, render clearer top-level timeline summary stats, clamp duration calculations to the returned window, prorate token totals for partially visible spans, and add Storybook/test coverage with realistic timeline activity data. **Alternatives considered** Keeping the existing sparse timeline story was considered, but it would leave dense activity layouts and selected-window summary behavior under-reviewed. Counting full span usage for partially visible spans was also considered, but it makes historical windows report activity outside the displayed range. **Roadmap alignment** Searched `ROADMAP.md` for timeline/activity references and found no conflicting planned core work. **Additional context** This PR does not include migrations and does not commit generated design screenshots or images. ## What Changed - Extended shared work timeline activity types and server timeline service behavior. - Updated the timeline page and work timeline chart for richer activity rendering. - Clamped timeline runtime summary calculations to the returned window and prorated summary token usage for clipped spans. - Added and updated targeted server/UI tests for timeline activity behavior. - Added Storybook timeline mock coverage and Storybook preview setup needed by the story. ## Verification - `git rebase origin/master` completed cleanly after fetching `paperclipai/paperclip:master`. - `git diff --check origin/master...HEAD` - `pnpm exec vitest run server/src/__tests__/work-timeline-service.test.ts ui/src/components/timeline/WorkTimelineChart.test.tsx ui/src/pages/Timeline.test.tsx` — latest run: 3 files passed, 28 tests passed. - Greptile review completed at 5/5 with no unresolved Greptile threads after fixes. - GitHub checks completed green on the latest head SHA; Storybook visual regression was skipped by the workflow. - `pnpm check:token-gates` currently fails locally on existing `origin/master` violations in `ui/src/components/ActivityCharts.tsx` and `ui/src/components/IssueRecoveryActionCard.tsx`; this PR does not modify those files. ## Risks Low to moderate risk. The change affects the work timeline service response shape and timeline UI rendering, so regressions would likely show up as missing/incorrect timeline activity display. Targeted service and UI tests cover the changed behavior. No migrations are included. ## Model Used OpenAI Codex running GPT-5 as a tool-enabled coding agent with local shell and GitHub CLI access. Exact runtime model ID/context-window size was not exposed by the 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
555391fed7 |
fix: run restart recovery, workspace self-heal, quota-aware retries, failed-run metrics (#9183)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in heartbeat runs orchestrated by the server; run
lifecycle, retry scheduling, and the dashboard's run-activity metrics
are the subsystems involved
> - A spike in "failed" tasks traced to three causes: server restarts
killing in-flight runs and mislabeling them as failures, deterministic
workspace-validation loops when a worktree's branch diverged, and
provider quota/usage-limit errors being classified as generic transient
failures (putting agents into error state and polluting metrics)
> - Killed-then-recovered runs and quota waits are not product failures,
so both the runtime behavior and the reporting needed to distinguish
them
> - This pull request drains runs gracefully on shutdown with idempotent
restart retries, self-heals workspace branch mismatches, adds a
quota-aware failure class with reset-time retry, separates recovered
restart kills from true failures on the dashboard, and documents restart
hygiene for operators
> - The benefit is fewer spurious failures, automatic recovery instead
of manual repair, and dashboard metrics that reflect real failure rates
## Linked Issues or Issue Description
No public GitHub issue exists; describing the bug inline per the
bug-report template:
**What happened?**
In-flight heartbeat runs are marked `failed` when the server restarts,
even though a retry later succeeds. Worktrees whose checked-out branch
diverges from the issue branch fail workspace validation on every
subsequent run with no recovery path. Provider quota/usage-limit
responses are treated as generic transient upstream errors, putting
agents into an error state and retrying before the quota window resets.
The dashboard counts all of these as true failures, inflating failure
metrics.
**Expected behavior**
Graceful shutdown should interrupt (not fail) running runs and chain
exactly one recovery retry. Workspace validation should repair
recoverable branch mismatches automatically. Quota errors should get
their own error class with the retry scheduled at the provider reset
time and the agent left idle. The dashboard should report recovered
restart kills separately from true failures.
**Steps to reproduce**
1. Start a heartbeat run, then restart the server (SIGTERM) while it is
in flight — the run lands as `failed` with a process-loss error code
even when its retry succeeds
2. Check out an issue whose worktree branch has diverged (e.g. after a
force-moved branch) — every subsequent run fails
`workspace_validation_failed` deterministically
3. Drive an agent into a provider usage-limit window — the run fails as
a generic transient upstream error and the agent enters an error state
instead of idling until the reset time
**Paperclip version or commit**
master (base
|
||
|
|
83f5f59842 |
[codex] Hide goals sidebar link behind experiment (#9189)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board sidebar is the primary navigation surface for operators scanning companies, projects, tasks, agents, and related control-plane tools. > - Goals still has a route and product surface, but keeping the top-level sidebar link always visible makes it part of the default navigation whether or not that surface is ready for every operator. > - Instance experimental settings already provide a controlled place to expose optional UI surfaces while they are being evaluated. > - This pull request adds a dedicated experimental setting for restoring the Goals sidebar link. > - The benefit is a quieter default sidebar with an explicit escape hatch for operators who still need the Goals entry point. ## Linked Issues or Issue Description No public GitHub issue exists for this internal task, so the feature request is described inline. **Subsystem affected** Cross-cutting: `ui/`, `server/`, and `packages/shared`. **Problem or motivation** The Goals route remains available, but the top-level Goals sidebar entry makes that surface part of the default operator navigation. While the goals surface is still being evaluated, operators need a quieter default sidebar without losing an escape hatch for teams that still rely on the link. **Proposed solution** Add a boolean instance experimental setting, `enableGoalsSidebarLink`, default it to `false`, and render the Goals sidebar link only when the setting is enabled. Expose the toggle in Instance Experimental Settings so operators can restore the link without changing routes or rebuilding the app. **Alternatives considered** - Remove the Goals route entirely: rejected because this task only asks to hide the sidebar entry point and preserve access for teams evaluating goals. - Keep the sidebar link always visible: rejected because it does not provide the requested quieter default navigation. - Hard-code a local UI flag: rejected because instance experimental settings already provide the expected operator-controlled pattern. **Roadmap alignment** Checked `ROADMAP.md`; no overlapping goals/sidebar/experimental roadmap entry was found. **Additional context** The `/goals` route is preserved. This PR only gates the sidebar navigation item. ## What Changed - Added `enableGoalsSidebarLink` to the shared instance experimental settings type and validator, defaulting to `false`. - Normalized the new setting in the server instance settings service. - Hid the Goals sidebar nav item unless the new setting is enabled. - Added a Goals Sidebar Link toggle to the Instance Experimental Settings page. - Updated shared, server, sidebar, and settings page tests for the new setting. ## Verification - `pnpm exec vitest run packages/shared/src/validators/instance.test.ts server/src/__tests__/instance-settings-service.test.ts server/src/__tests__/instance-settings-routes.test.ts ui/src/components/Sidebar.test.tsx ui/src/pages/InstanceExperimentalSettings.test.tsx` - `git diff --check origin/master...HEAD` - `git merge-tree --write-tree HEAD origin/master` - Searched for duplicate/related PRs by title and `enableGoalsSidebarLink`; none found. - Checked `ROADMAP.md` for overlapping goals/sidebar/experimental entries; none found. ## Risks Low risk. The main behavior shift is that operators who depended on the sidebar Goals link need to enable the new experimental toggle. The `/goals` route itself is not removed. > 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 Paperclip CodexCoder session with repository tool access and command execution. Exact API model identifier and context window were not exposed by the Paperclip harness. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
f17202b571 |
Add execution workspace branch reconciliation route (#9170)
## Thinking Path > - Paperclip is an open-source app that lets teams run AI agents for work tasks; each agent session uses an execution workspace — a git checkout — to track the agent's active code state. > - Every execution workspace has an expected target branch (`PAPERCLIP_WORKSPACE_BRANCH`). The workspace git HEAD should always point to that branch so agents commit in the right place. > - When workspace git HEAD diverges from the expected branch — for example after a harness branch-name fix or an accidental `checkout -b` during a CI-retrigger — the discrepancy must be corrected before agents can continue safely. > - Operators (board users) need a controlled, audited path to reconcile a workspace's live branch back to the expected target, with an override escape-hatch for cases where the normal forward path is blocked. > - This pull request adds a board-only `POST /api/execution-workspaces/:id/reconcile-branch` service operation and route that validates safety preconditions, resolves matching recovery-action fingerprints, posts source-issue audit comments, and records the reconciliation outcome. > - The benefit is that operators can correct branch divergence through the API with a full audit trail, instead of via raw database edits. ## Linked Issues or Issue Description No public GitHub issue exists for this change. Context below follows the feature-request template format. **Subsystem affected** server/ — REST API & orchestration services; packages/shared — request validation. **Problem or motivation** Execution workspaces have an expected branch record that must match the checked-out worktree branch. When the live git branch and stored branch record drift apart, operators currently lack a first-class, audited API to reconcile the record. The fallback is manual database repair or workspace replacement, both of which are risky and hard to audit. **Proposed solution** Add a board-only execution workspace branch reconciliation operation. `forward` mode re-inspects the server-side git state and only updates the branch record when the stored branch is an ancestor of the checked-out branch. `override` mode is a break-glass path that requires board access and an operator reason. Both modes require a clean, idle workspace, write audit details, post a source-issue audit comment, and resolve the matching workspace-validation recovery action. **Alternatives considered** Manual database edit (no durable audit trail and easy to mistype), recreating the workspace (heavier operational disruption), or trusting client-supplied ancestry evidence (unsafe because the server must verify the git state itself). **Roadmap alignment** This is incremental hardening for execution-workspace recovery and operator controls. It does not duplicate a public roadmap item. **Additional context** The endpoint is intended for operator recovery, not normal agent control flow, so the generated OpenAPI metadata and runtime route both classify it as board-only. ## What Changed - Added `reconcileExecutionWorkspaceBranchSchema` discriminated-union validator (`forward` with optional reason, `override` requiring a non-empty reason string) to `packages/shared/src/validators/execution-workspace.ts` - Exported `ReconcileExecutionWorkspaceBranch` type and the new schema from the shared package index - Added board-only reconcile-branch service operation in the execution workspaces service: safety checks, recovery-action fingerprint resolution, source-issue audit comment, and outcome recording - Added clean-worktree and stopped-runtime-service preconditions before branch-record mutation. - Marked the reconcile route as board-only in OpenAPI generated auth metadata. - Added `POST /api/execution-workspaces/:id/reconcile-branch` route wired to the new service operation with board-permission gate - Extended `execution-workspaces-routes.test.ts` and `execution-workspaces-service.test.ts` to cover: safety-check rejection, override-reason validation, audit-comment posting, and recovery-action fingerprint resolution (2 files / 19 tests) ## Verification ```sh pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck pnpm exec vitest run server/src/__tests__/execution-workspaces-routes.test.ts server/src/__tests__/execution-workspaces-service.test.ts pnpm exec vitest run server/src/__tests__/execution-workspaces-service.test.ts server/src/__tests__/openapi-routes.test.ts ``` ## Risks - **Board-only gate:** the operation is gated behind the board permission; no agent can trigger it without operator authorization. - **Override requires reason:** the `override` mode requires a non-empty reason string so every bypass is audited. - **Idempotent recovery-action resolution:** re-running with the same fingerprint is safe; duplicate resolution is a no-op. - **No execution-state mutation:** the route records a reconciliation intent and updates the branch record; it does not restart the workspace or modify running agent state. - Overall risk: **low**. ## Model Used - Provider: Anthropic - Model ID: `claude-sonnet-4-6` (Claude Sonnet 4.6) - Context window: 200 K tokens - Capabilities: tool use, code execution, multi-turn context Follow-up safety commit: - Provider: OpenAI - Model ID: `codex` / GPT-5 with tool use and code execution ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (`feat/execution-workspace-branch-reconciliation-route`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9d5b0e3c57 |
Add read-only issue subtree diagnostics endpoint (#9135)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The issue/task orchestration subsystem tracks parent–child and blocker–dependent relationships, forming a directed acyclic (in intention) subtree below each root issue > - Agents and operators have no lightweight way to inspect the dependency and wake state across an entire issue subtree — they must walk the tree issue-by-issue, making multiple round-trips with full object fetches > - A bounded, read-only subtree diagnostic endpoint lets callers understand the health of an entire work tree (which nodes are blocked, which are cycling, which have pending wakes) from a single authenticated request > - This pull request adds `GET /api/issues/:id/diagnostics/subtree`, a depth/node/per-node capped traversal that reuses the blocker and wake projection helpers from the companion blocker and wake diagnostics endpoints (see Refs #9114, #9133) > - The benefit is that platform operators, monitoring, and coaching tooling can surface \"why is this subtree stalled?\" across all nodes without database access or unbounded graph walks, using only data the caller already has read permission for ## Linked Issues or Issue Description Refs #9114 (companion blocker diagnostics endpoint — blocker projection helpers reused here) Refs #9133 (companion wake diagnostics endpoint — wake projection helpers reused here) ## What Changed - **New route** `GET /api/issues/:id/diagnostics/subtree` in `server/src/routes/issues.ts`: returns a bounded subtree traversal rooted at `:id`, with depth/node/per-node caps and explicit truncation flags - **Cycle-safe traversal**: visited-node set prevents infinite loops on any accidental cycle in the ancestry graph - **Per-node authorization**: each subtree node is individually filtered through `assertIssueReadAllowed`; unauthorized nodes are omitted from the response and do not influence aggregate counts - **Blocker and wake reuse**: per-node blocker rows and wake events are projected through the same helpers as #9114 and #9133 — raw wake payloads, raw errors, activity details, and trigger detail fields are stripped - **Low-trust filtering**: the `mention-scoped` low-trust path redacts node/blocker identifiers for unauthorized actors, consistent with #9133 - **Truncation reporting**: response includes `depthTruncated`, `nodeTruncated`, and per-node `blockersTruncated`/`wakesTruncated` flags when caps are hit - **Shared types** in `@paperclipai/shared`: `IssueSubtreeDiagnosticsResponse` and supporting node/blocker/wake types exported from the shared package - **OpenAPI tag registration** for the new route - **API reference docs** in `skills/paperclip/references/api-reference.md` - **Test coverage** (`server/src/__tests__/issue-subtree-diagnostics-routes.test.ts`, embedded Postgres): happy path, quiet singleton (no children/blockers), node cap truncation, mention-scoped low-trust filtering, cross-company denial ## Verification ```bash # Subtree diagnostics tests only pnpm exec vitest run server/src/__tests__/issue-subtree-diagnostics-routes.test.ts # Full diagnostics suite (blocker + wake + subtree) pnpm exec vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts server/src/__tests__/issue-wake-diagnostics-routes.test.ts server/src/__tests__/issue-subtree-diagnostics-routes.test.ts # Type-check shared and server packages pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck # Whitespace / diff check git diff --check ``` All commands passed locally (5 subtree tests, 17 total across the three diagnostics test files). ## Risks - **No schema or migration changes** — read-only projection over existing relations; no DDL risk - **Bounded traversal** — depth, node count, and per-node blocker/wake caps prevent unbounded graph walks; truncation is reported explicitly in the response - **Auth boundary** — root issue read is company-scoped and checked before the subtree is built; each subtree node is individually authorized; cross-company access is denied at `assertCompanyAccess` - **No raw payloads** — raw wake payload, raw error, activity details, and trigger detail fields are stripped from all nodes, consistent with the companion endpoints - Low overall risk; the endpoint is additive and read-only ## Model Used - **Provider:** Anthropic - **Model:** Claude Sonnet 4.6 (`claude-sonnet-4-6`) - **Tool use:** yes (file reads, edits, bash execution, Paperclip API calls) - **Reasoning mode:** standard (no extended thinking) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
31a0080e61 |
Fix wake diagnostics low-trust identifier redaction (#9133)
## Thinking Path
> - Paperclip is the open-source app people use to manage AI agents for
work
> - The task/issue lifecycle subsystem tracks when agents wake up, are
suppressed, or are deferred, recording each wake request in
`agent_wakeup_requests` and each defer/suppression event in
`activity_log`
> - When an agent appears stuck or doesn't resume after a dependency
resolves, there is currently no read-only API surface to inspect its
wake history — operators must query the database directly
> - Making wake history queryable via a first-class endpoint lets
operators, support, and monitoring tools diagnose "why didn't this agent
wake up?" without database access
> - This pull request adds `GET /api/issues/:id/diagnostics/wakes`,
returning a bounded 14-day/50-row projection of wake requests and
defer/suppression activity events, with a deterministic `diagnosis`
field and a `likelyReason` inference — including a Case-B inference ("no
wake enqueued because a visible blocker is not done") that reuses the
blocker readiness data from the companion blocker diagnostics endpoint
(see Refs #9114)
> - The benefit is that platform operators can answer "why is this agent
not waking up?" from a safe, read-only HTTP endpoint rather than needing
direct database access, and CI/monitoring can assert expected wake
behavior
## Linked Issues or Issue Description
Refs #9114 (companion blocker diagnostics endpoint, already merged —
this PR extends the same diagnostic surface to wake/activity history)
## What Changed
- **New route** `GET /api/issues/:id/diagnostics/wakes` in
`server/src/routes/issues.ts`: returns a bounded (14-day window, 50-row
cap) projection of `agent_wakeup_requests` rows and wake-relevant
`activity_log` rows (defer/suppression events)
- **Sanitized projection**: raw `payload`, `details`, `error`, and
`triggerDetail` fields are stripped; unknown free-form `source`,
`reason`, and `status` values are projected to `"other"` to prevent
schema bleed
- **Deterministic `diagnosis` and `likelyReason` fields**: includes
Case-B inference ("no wake enqueued — visible blocker not done") that
calls the existing blocker-readiness helper from Slice 1 (#9114) so the
wake surface can explain missing wakes caused by outstanding blockers
- **Auth**: `assertCompanyAccess` + `assertIssueReadAllowed`;
cross-company requests are denied; Case-B blocker inference filters by
caller trust level so hidden (low-trust) blockers are mentioned but not
identified
- **Types in `@paperclipai/shared`**: `IssueWakeDiagnosticsResponse`,
`WakeEvent`, `ActivityEvent` exported from the shared package
- **OpenAPI tag registration** for the new route
- **Skill reference docs** in
`skills/paperclip/references/api-reference.md` documenting the endpoint
contract
- **Test coverage**
(`server/src/__tests__/issue-wake-diagnostics-routes.test.ts`, embedded
Postgres): happy path, empty/null diagnosis, Case-B inference, low-trust
hidden blocker, cross-company denial, raw blob minimization, cap
behaviour, combined blocker+wake test run
## Verification
```bash
# Wake diagnostics tests only
pnpm exec vitest run server/src/__tests__/issue-wake-diagnostics-routes.test.ts
# Wake + blocker diagnostics together (integration)
pnpm exec vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts server/src/__tests__/issue-wake-diagnostics-routes.test.ts
# Type-check shared and server packages
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
# Whitespace / diff check
git diff --check
```
All commands passed locally.
## Risks
- **No schema or migration changes** — this is a read-only projection
over existing tables; no DDL risk.
- **Bounded queries** — 14-day window + 50-row cap limit per call; no
unbounded scans.
- **Auth boundary** — cross-company access is denied at
`assertCompanyAccess`; Case-B inference uses the same per-node trust
filtering as the blocker endpoint so low-trust blockers are acknowledged
but not identified.
- Low overall risk; the endpoint is additive and read-only.
## Model Used
- **Provider:** Anthropic
- **Model:** Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- **Tool use:** yes (file reads, edits, bash execution, Paperclip API
calls)
- **Reasoning mode:** standard (no extended thinking)
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
|
||
|
|
295294d7ce |
Add read-only issue blocker diagnostics endpoint (#9114)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents block each other with `blockedByIssueIds` relationships to express dependencies > - Users and tooling have no lightweight way to inspect *why* an issue is blocked or whether its blockers are themselves ready to resolve > - A read-only diagnostic endpoint over the existing blocker graph lets callers understand dependency chains without requiring a full issue-tree traversal > - This pull request adds `GET /api/issues/:id/diagnostics/blockers` — a bounded, read-only projection over each blocker's readiness state > - The benefit is that callers can surface blocking-chain diagnosis (e.g. "waiting on N blockers, M of which are themselves blocked") from a single authenticated request, using only data they already have read permission for ## Linked Issues or Issue Description No public GitHub issue exists for this change. Feature description: **Subsystem affected:** `server/` — REST API & orchestration services; `packages/shared` — types, constants, validators, API paths **Problem or motivation** There is no API endpoint to inspect *why* an issue is blocked or to get a per-blocker readiness summary. Clients must walk the issue graph manually or fetch full issue objects, which requires multiple round-trips and is expensive. **Proposed solution** A single `GET /api/issues/:id/diagnostics/blockers` endpoint returns a bounded projection: root issue summary, an ordered blocker list with per-blocker `readiness` state, and a top-level `diagnosis` field summarizing overall blocking status. Authorization mediation omits blockers the caller cannot read, so `diagnosis` only reflects visible data. **Alternatives considered** A general graph-walk query (too broad/expensive for a targeted diagnostic call); enriching the existing `GET /api/issues/:id` response (too coupled to the main response shape and adds weight for callers that do not need blocker detail). **Roadmap alignment** Read-only observability surface over existing data; no database schema changes. This aligns with tooling that helps users understand dependency state without mutating anything. ## What Changed - Added `GET /api/issues/:id/diagnostics/blockers` route to the server - Returns per-blocker `readiness` state and a top-level `diagnosis` field summarizing overall blocking status - Enforces `issue:read` authorization per-blocker: unauthorized blockers are omitted and do not influence `diagnosis` or `readiness` values - Added shared TypeScript response types in `@paperclipai/shared` - Added route-level tests using embedded Postgres - Added API documentation in the `paperclip` skill ## Verification ```sh ./node_modules/.bin/vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck ``` All three commands pass locally. ## Risks - Read-only endpoint over existing relations — no writes, no schema or migration changes — low risk - Authorization mediation intentionally omits unauthorized blockers from both the list and from `diagnosis`/`readiness`; callers with partial access will see a narrower picture than the full blocker graph ## Model Used - Provider: Anthropic - Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`) - Context window: 200k tokens - Mode: Tool use, code generation, extended reasoning ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5163208c3c |
Add workspace branch ancestry diagnostics (#9117)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents run in git worktrees tied to a workspace branch; when the actual branch diverges from the expected one (e.g. a parent feature branch was renamed), Paperclip currently has no structured field to report *why* the branch is incoherent or whether it can be auto-reconciled > - The workspace-incoherence fingerprint already captures SHA mismatches, but there is no evidence field distinguishing "actual branch is a descendant of expected" (safe to fast-forward) from "branches have diverged" (needs human review) or "SHAs are unavailable" (unknown) > - Operators and future recovery flows need a typed verdict to make decisions without re-running git commands themselves > - This pull request adds `ancestryVerdict` and `plainLanguageReason` evidence fields computed via `git merge-base --is-ancestor`, and scaffolds the off-by-default `enableWorkspaceBranchReconcileForward` instance setting with no runtime behavior yet > - The benefit is that future recovery logic can branch on a typed verdict rather than parsing prose, while the fingerprint v1 payload stays stable ## Linked Issues or Issue Description No public GitHub issue pre-exists for this diagnostic addition. **Problem or motivation** When Paperclip detects that an agent's actual workspace branch differs from the recorded expected branch, the current fingerprint carries only raw SHAs. There is no typed field indicating whether the actual branch is a descendant of the expected one (safe reconcile path) vs. a true divergence (requires human intervention) vs. an indeterminate state (missing SHAs or git errors). Downstream recovery logic cannot branch safely without re-running git. **Proposed solution** Add `ancestryVerdict` and `plainLanguageReason` to the workspace incoherence evidence type; compute via `git merge-base --is-ancestor`; scaffold a feature-flag for future forward-reconcile behavior (`enableWorkspaceBranchReconcileForward`, off by default, not yet read by any runtime path). **Alternatives considered** Encoding the verdict in the existing fingerprint string was rejected because the fingerprint is a stable identity hash, not a mutable evidence bag. Changing it would break monitors keyed on the string. **Roadmap alignment** Supports future workspace auto-reconcile work; ROADMAP.md has no conflicting entry for this diagnostic layer. ## What Changed - `packages/shared/src/types/heartbeat.ts` adds `ancestryVerdict` and `plainLanguageReason` fields to `WorkspaceIncoherenceEvidence` - `packages/shared/src/types/instance.ts` adds `enableWorkspaceBranchReconcileForward` boolean (off by default) - `packages/shared/src/validators/instance.ts` exports the new flag from the settings validator - `server/src/services/workspace-runtime.ts` computes `ancestryVerdict` via `git merge-base --is-ancestor`; falls back to `unknown` on missing SHAs or command errors; excludes verdict fields from fingerprint v1 computation - `server/src/services/instance-settings.ts` wires the new setting through to the settings service - Tests updated in `workspace-runtime.test.ts`, `instance-settings-service.test.ts`, `instance-settings-routes.test.ts`, and `instance.test.ts` (104 tests total) ## Verification ```bash pnpm exec vitest run \ server/src/__tests__/workspace-runtime.test.ts \ server/src/__tests__/instance-settings-service.test.ts \ server/src/__tests__/instance-settings-routes.test.ts \ packages/shared/src/validators/instance.test.ts # 104 tests pass pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck # both exit 0 ``` Manual: trigger a workspace incoherence event and confirm the evidence object carries `ancestryVerdict` and `plainLanguageReason`; confirm the fingerprint string stays `workspace_incoherence:v1:sha256:...`. ## Risks **Low risk.** Purely additive. Fingerprint v1 payload is unchanged. The new flag has no runtime effect in this PR. `git merge-base --is-ancestor` exits non-zero for both "not an ancestor" and "command error"; both are handled and collapsed to typed values with a prose reason. ## Model Used Provider: Anthropic, model: Claude Sonnet 4.6 (`claude-sonnet-4-6`), 200k context, 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
903886bc79 |
[codex] Add starred resource sidebar controls (#9085)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI is the main daily navigation surface for agents, projects, and their related resources. > - Operators need a lightweight way to keep frequently used agents and projects close without changing company-wide ordering or ownership. > - Resource memberships already model per-user relationships to projects and agents, so they are the right place to store user-specific starred state. > - This pull request extends that membership contract with a starred timestamp and exposes star controls in list/detail views. > - The sidebar then uses those starred memberships to show compact, user-specific shortcuts. > - The benefit is faster navigation without introducing a separate favorites system or leaking preferences across users. ## Linked Issues or Issue Description No public GitHub issue exists. Feature request: ## Problem or motivation Users cannot pin frequently used agents or projects into the main sidebar. Returning to important resources requires scanning full project/agent lists or navigating through detail pages, which adds friction to repeated daily workflows. ## Proposed solution Store a per-user `starred_at` timestamp on agent and project memberships, expose API actions to set or clear that state, add star toggle controls to list/detail pages, and render starred projects and agents as compact sidebar shortcuts. ## Alternatives considered A separate favorites table would work, but it would duplicate membership scoping and require another resource relationship model. Keeping starred state on memberships preserves existing company/user boundaries and avoids a second source of truth. ## Roadmap alignment Checked `ROADMAP.md`; no overlapping planned core work for starred resource/sidebar navigation was found. ## Additional context The affected subsystems are `packages/db`, `packages/shared`, `server/`, and `ui/`. The migration is idempotent with `IF NOT EXISTS` guards so environments that saw an earlier local migration name can still apply the final ordered migration safely. ## What Changed - Added idempotent migration `0133_resource_membership_stars` for `starred_at` columns and lookup indexes on agent/project memberships. - Extended shared resource membership types and validators with starred metadata and actions. - Updated server resource membership services/routes to read and mutate starred resource state. - Added reusable star toggle UI and resource membership hook support for starred state. - Added starred projects and agents sidebar rendering, plus star controls on list and detail pages. - Added focused shared, server, and UI coverage for starred membership behavior and sidebar rendering. ## Verification - Rebased and force-with-lease pushed current PR head `a086fc965391c9e50a51b5b83b5b44a797b2a6f4` onto current `paperclipai/paperclip:master`; `gh pr view` reports `MERGEABLE` with no merge conflicts. GitHub checks are green for this fresh head. - `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts server/src/__tests__/resource-memberships-routes.test.ts server/src/__tests__/workspace-runtime.test.ts ui/src/components/Sidebar.test.tsx ui/src/components/SidebarAgents.test.tsx ui/src/components/SidebarStarredProjects.test.tsx ui/src/components/StarToggle.test.tsx ui/src/pages/InstanceExperimentalSettings.test.tsx` passed after the rebase: 8 files, 143 tests. - Greptile re-review is 5/5; the remaining screenshot thread was resolved as non-blocking because this task explicitly requested no screenshots/images in the PR. - `pnpm exec vitest run ui/src/components/SidebarStarredProjects.test.tsx` passed after the mobile pending-spinner fix. - `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts server/src/__tests__/resource-memberships-routes.test.ts ui/src/components/Sidebar.test.tsx ui/src/components/SidebarAgents.test.tsx ui/src/components/SidebarStarredProjects.test.tsx ui/src/components/StarToggle.test.tsx ui/src/pages/InstanceExperimentalSettings.test.tsx` passed: 7 files, 68 tests. - `pnpm --filter @paperclipai/db typecheck && pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` passed db/shared/server, then failed in pre-existing UI code outside this PR: `src/pages/CompanyEnvironments.tsx` missing `@xterm/*` type declarations and `previous` possibly null. - Checked that the PR diff does not include `pnpm-lock.yaml` or `.github/workflows` changes. - Checked `ROADMAP.md` and found no overlapping planned core work for starred resource/sidebar navigation. - Searched existing GitHub PRs for duplicate starred-resource/sidebar work and found none. ## Risks - Migration touches membership tables. The SQL uses `IF NOT EXISTS` for columns and indexes so environments that saw an earlier local migration name can still apply this safely. - Sidebar ordering and visibility changes could affect users who rely on the previous flat sidebar layout. - Starred state is per-user membership metadata; code paths must continue preserving company/user scoping around memberships. > 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, tool-enabled coding agent with shell/GitHub access. Context window not disclosed 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e936ea3905 |
[codex] Deduplicate pipeline automation health warnings (#9090)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Pipeline health reports give operators early warnings when a workflow step cannot run cleanly. > - Failed stage automation is surfaced as an `automation_failed` health warning for the affected item. > - A single item can have repeated failed automation rows for the same stage, especially after retries or repeated failed attempts. > - Rendering every matching row creates duplicate warnings that make the pipeline look noisier than it is. > - This pull request deduplicates failed automation warnings by the item/stage pair before adding them to the health report. > - The benefit is that repeated failures for the same item in the same stage produce one actionable warning, while distinct items still remain visible. ## Linked Issues or Issue Description Refs #8866 Bug: pipeline health could emit duplicate `automation_failed` warnings when the input contained repeated failed automation rows for the same live item and stage. Reviewers should expect one warning per `stageId:caseId` pair, not one warning per backing execution row. ## What Changed - Deduplicated failed automation warnings with per-stage case tracking in `computePipelineHealth`, avoiding collision-prone composite string keys before pushing `automation_failed` warnings. - Added shared Vitest coverage for a single automation failure, duplicate same-stage same-item dedupe, separate warnings for different item IDs in the same stage, the same item ID in different stages, and colon-delimited ID collision cases. - Kept pipeline route behavior unchanged; this PR only changes shared warning rendering and direct shared tests. ## Verification - `pnpm vitest packages/shared/src/pipeline-health.test.ts` - 1 test file passed - 5 tests passed - PR #9090 remote checks on `bbbb2d4627f5be17ca210dedb9edb91edd047df8` - All Paperclip CI/status checks passed - Greptile Confidence Score: 5/5, 0 comments added, 0 unresolved Greptile threads No route test changed because this PR does not change the route's failed-automation query or normalization behavior. ## Risks Low risk. The change only suppresses duplicate `automation_failed` warnings when both `stageId` and `caseId` match. Distinct items in the same stage still produce separate warnings. > 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 in the Paperclip local adapter environment; exact model snapshot and context-window metadata were not exposed in the runtime. Tool use and code execution were 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8a058f9d79 |
fix: deduplicate adapter-agnostic config keys (#9058)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - When you swap an agent's adapter (e.g. from one LLM provider to another), the server merges the incoming PATCH body with stored config — keys listed in \`ADAPTER_AGNOSTIC_KEYS\` are preserved regardless of which adapter is active > - That constant was defined independently in two places: \`server/src/agents.ts\` (used by the adapter-swap route) and \`ui/src/lib/agent-config-patch.ts\` (used by the UI patch builder) > - PR #8975 fixed the bug where \`paperclipSkillSync.desiredSkills\` was dropped on adapter swap by adding it to the server-side constant, but the UI-side copy was not updated in the same PR — creating ongoing drift risk > - This pull request hoists \`ADAPTER_AGNOSTIC_KEYS\` into \`packages/shared\` so both consumers import the same constant > - The benefit is a single source of truth: any future key addition is made in one place and both the server route and the UI patch builder pick it up automatically, with a drift guard to catch any accidental re-duplication ## Linked Issues or Issue Description Refs #8975 — follow-up deduplication: #8975 fixed the runtime bug but left the constant duplicated across server and UI. This PR closes that gap. ## What Changed - Added \`ADAPTER_AGNOSTIC_KEYS\` constant and \`AdapterAgnosticKey\` type to \`packages/shared/src/adapter-agnostic-keys.ts\` - Updated \`server/src/agents.ts\` to import the shared constant, removing the local copy - Updated \`ui/src/lib/agent-config-patch.ts\` to import the shared constant, removing the local copy - Added \`packages/shared/src/adapter-agnostic-keys.test.ts\`: drift guard asserting the expected key set and both consumer import sites ## Verification \`\`\`bash pnpm exec vitest run packages/shared/src/adapter-agnostic-keys.test.ts ui/src/lib/agent-config-patch.test.ts server/src/__tests__/agent-instructions-routes.test.ts pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck pnpm --filter @paperclipai/ui typecheck \`\`\` All 15 tests pass across the three files; all three packages typecheck clean. ## Risks Low risk — behavior-preserving refactor. The key set is unchanged; only the import source changes. The drift guard will fail loudly if someone accidentally re-introduces a local copy or modifies one without updating the other. > 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 - Provider: Anthropic - Model: Claude Sonnet 4.6 (\`claude-sonnet-4-6\`) - Context: standard context window, tool use enabled - Reasoning: standard mode (no extended thinking) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with \`Fixes: #\` / \`Closes #\` / \`Refs #\` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub \`#NNN\` / \`github.com/paperclipai/paperclip\` URLs) - [ ] My branch name describes the change (e.g. \`docs/...\`, \`fix/...\`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ad961227f5 |
feat(secrets): add user-specific runtime secrets (#8825)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent runs often need provider credentials, API tokens, and other environment-bound secrets. > - Company-level secrets work for shared credentials, but they do not model values that should differ by human operator. > - Without a user-scoped model, a run can dispatch without knowing whether the responsible human has supplied the needed value. > - Paperclip also needs run attribution to make those user-scoped runtime checks deterministic and auditable. > - This pull request adds user-specific secret definitions, per-user values, environment bindings, responsible-user attribution, and runtime resolution gates. > - The benefit is that teams can define the secret once, let each user provide their own value, and block runs before dispatch when required user secrets or active definitions are unavailable. ## Linked Issues or Issue Description Refs #224 Refs #6057 This PR implements user-specific secret support as a core secret-management capability rather than a one-off adapter setting. It is related to existing public work on company secrets UI and runtime secret refs, but is distinct because the value is owned by the responsible user and resolved at run dispatch time. Related PR search before opening found existing secrets work such as #1550, #8256, #8614, #8634, and #8647; none of those add the full user-secret definition/value/runtime gate covered here. ## What Changed - Added user-secret definitions and per-user "My secrets" values, keeping stored values out of access metadata. - Added `user_secret_ref` environment bindings and UI affordances to pick them alongside existing secret refs. - Added responsible-user runtime resolution so user-secret refs resolve against the human responsible for the run. - Added pre-dispatch missing-secret gates so runs fail before adapter dispatch when required user values are absent or definitions are inactive. - Added low-trust allowlist hardening for user-secret runtime access. - Added issue, routine, run, and agent API key responsible-user attribution and fail-closed dispatch behavior when attribution cannot be resolved. - Added denial-copy mapping so responsible-user authorization failures surface as actionable run outcomes instead of opaque setup failures. - Added OpenAPI documentation for the user-secret routes. - Rebases cleanly on current `master`; migrations were renumbered incrementally as `0128_user_specific_secrets`, `0129_agent_api_key_responsible_user`, and `0130_run_responsible_user_invariant` after upstream `0126`/`0127` migrations. - Removed previously committed local design screenshots so the PR contains code/docs/tests only. ## Verification - PASS: PR head `2527febd106bcf3ca264ca0da7fca491084192d6` is based on `paperclipai/paperclip:master`. - PASS: `git diff --check` - PASS: `git diff --name-only public/master...HEAD | rg '^(pnpm-lock\\.yaml|\\.github/workflows/|screenshots/)' || true` produced no files. - PASS: migration journal audit confirmed unique indexes through `130` with tail entries `0126_issue_comment_derived_attribution`, `0127_environment_custom_images_instance_scoped`, `0128_user_specific_secrets`, `0129_agent_api_key_responsible_user`, and `0130_run_responsible_user_invariant`. - PASS: `pnpm --filter @paperclipai/ui typecheck` - PASS: `pnpm --filter @paperclipai/server typecheck` - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-responsible-user-invariant.test.ts` - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-active-run-output-watchdog.test.ts src/__tests__/heartbeat-stale-queue-invalidation.test.ts src/__tests__/heartbeat-workspace-finalize-branch.test.ts src/__tests__/issue-monitor-scheduler.test.ts` - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-comment-wake-batching.test.ts src/__tests__/heartbeat-retry-scheduling.test.ts src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts src/__tests__/heartbeat-plugin-environment.test.ts` - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/low-trust-red-team-routes.test.ts` - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/secrets-service.test.ts` (55 tests) - PASS: `pnpm vitest run server/src/__tests__/secrets-routes.test.ts server/src/__tests__/secrets-service.test.ts` (89 tests after final Greptile cleanup fixes) - PASS: `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-issue-liveness-escalation.test.ts` (17 tests after the final rebase CI fix) - PASS: focused server Vitest batches covering heartbeat recovery, project env, plugin env, routines, low-trust, pipelines, monitors, watchdog, and stale queue paths. - PASS: GitHub checks are green on `2527febd106bcf3ca264ca0da7fca491084192d6`, including Typecheck + Release Registry, Build, General tests, serialized server suites, e2e, Canary Dry Run, verify, security checks, and Greptile Review. - PASS: Greptile Review completed successfully on `2527febd106bcf3ca264ca0da7fca491084192d6` with Confidence Score 5/5, and GraphQL review-thread audit returned zero unresolved non-outdated threads. ## Risks - Runtime behavior now depends on a run having a correct responsible user; missing or incorrect responsibility assignment can block runs before adapter dispatch. - `user_secret_ref` bindings intentionally expose metadata without values, but UI/API callers may need to handle the new binding kind explicitly. - External secret providers and IAM policies are not automatically provisioned by this PR; operators still need to configure provider-side access for non-local vaults. - The PR is broad across db/shared/server/UI/runtime paths, so release validation should include both API and UI secret workflows before merge. - The migration renumbering is intentionally incremental after upstream migrations; the branch migrations use guarded column/table/index/constraint creation so users who tested the older draft numbering should not hit duplicate DDL for the existing objects. > 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 (`gpt-5`), Codex local adapter with shell/tool use and code execution. Context window and internal reasoning mode are 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
bcac517f3b |
Add browser SSH terminal for custom image setup (#8911)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Environment sandboxes already support custom image creation and refresh through a temporary SSH setup session. > - The existing workflow makes operators copy an SSH command into an external terminal before they can install packages or make image changes. > - That extra context switch is slower, easier to get wrong, and less integrated with the setup session Paperclip already tracks. > - This pull request adds an embedded browser SSH terminal for custom image setup, so operators can start working in the target sandbox directly from the environment configuration flow. > - The implementation uses short-lived websocket attachment tokens, session-lifetime SSH host-key pinning, and server-managed terminal cleanup so the feature fits the existing setup-session boundary. > - The benefit is a smoother custom image creation and refresh experience without asking users to leave Paperclip for routine sandbox setup work. ## Linked Issues or Issue Description No public GitHub issue exists. ### Subsystem affected Cross-cutting: `server/` custom image setup APIs and websocket handling, `ui/` environment configuration UI, and shared custom image contracts. ### Problem or motivation Custom image creation and refresh require an operator to open a separate SSH client, paste the command shown by Paperclip, perform setup work, then return to the browser to finish the image flow. This is functional but awkward for a setup process that already starts and tracks a temporary sandbox session. ### Proposed solution Embed an SSH terminal in the custom image setup UI. When a setup session exposes an SSH payload, Paperclip should open a browser terminal backed by a server-side websocket session, let the operator run setup commands in-place, and then close the terminal when setup is finished, cancelled, expired, or disconnected. ### Alternatives considered - Keep the existing copy/paste SSH command workflow. This remains a fallback, but it does not streamline the common path. - Put SSH credentials directly into websocket URLs. This was avoided so terminal authentication can happen in an explicit first websocket auth frame rather than in logged URLs. - Trust the SSH host blindly for every reconnect. This PR instead pins the observed host-key fingerprint for the setup-session lifetime. ### Roadmap alignment This fits the roadmap theme of making agent workspaces usable in more remote and sandboxed environments while preserving Paperclip's control-plane model. ### Additional context Public GitHub search did not find a duplicate issue or PR for `custom image terminal ssh` in `paperclipai/paperclip`. ## What Changed - Added server-side terminal session tracking for custom image setup sessions, including connect-token issuance, websocket attachment, expiry, resize, input, and shutdown handling. - Added an embedded browser terminal to the custom image creation and refresh flow when a setup session provides SSH connection details. - Moved terminal token authentication out of the websocket URL and into the first websocket JSON auth frame. - Added SSH host-key SHA-256 pinning for each terminal session and documented the provider convention for username-embedded SSH credentials. - Updated the custom image environment API and UI so the setup terminal can open, reconnect, show status, authenticate, resize, and remain active for the setup-session lifetime once attached. - Kept custom image setup routes company-scoped and closed active terminal sessions on setup finish/cancel. - Added focused unit/integration/UI coverage for token expiry, setup-session expiry, websocket close paths, host-key pinning, and terminal session lifecycle behavior. - Removed the generated lockfile delta from the PR; CI owns temporary lockfile regeneration for manifest-changing PRs. ## Verification - `pnpm exec vitest run server/src/__tests__/server-startup-feedback-export.test.ts server/src/__tests__/environment-custom-image-terminal-ws.test.ts server/src/services/environment-custom-image-terminal-sessions.test.ts server/src/__tests__/environment-custom-image-routes.test.ts packages/shared/src/environment-custom-images.test.ts ui/src/pages/CompanyEnvironments.test.tsx` - 6 test files passed - 58 tests passed - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/server build` - `pnpm --filter @paperclipai/ui build` - `pnpm run typecheck:build-gaps` - `git diff --check` - Local sensitive-content scan over the PR diff using patterns for API keys, private keys, private hostnames, local paths, token fields, and credential-like strings. - Findings were limited to removed URL-token code and synthetic test placeholders such as `ssh-token-secret` and `terminal-token-terminal-token-123456`. - No real credentials, private hostnames, local filesystem paths, or instance-local links were found. - Remote PR checks were green after the implementation commit, including Build, Typecheck + Release Registry, General tests, serialized server suites, e2e, verify, Socket, Snyk, Superagent, and Greptile 5/5. - Post-merge PR hardening on July 3, 2026: merged `origin/master` at `47448721e` into the branch, resolved the `CompanyEnvironments.tsx` import conflict, reran focused tests, server/UI typechecks, server/UI builds, `pnpm run typecheck:build-gaps`, and `git diff --check`, scanned the final diff for sensitive content, pushed `4b43558cc`, and confirmed all remote checks plus Greptile 5/5 were green. - PR metadata correction on July 3, 2026: changed the title/body framing from bug-fix language to feature-request language. No source files changed for this metadata-only update. ## Risks - Moderate surface area because this adds websocket routing, setup-session runtime state, package dependencies, and a new custom image UI path. - New websocket attachments still require valid short-lived tokens; established terminal sessions remain bounded by setup-session expiry, explicit finish/cancel, client close, or server shutdown. - The terminal-session store is in-memory, so active terminal websocket tokens and host-key pins do not survive server restarts. - SSH host-key verification uses session-lifetime TOFU pinning because the current provider payload does not expose a trusted host-key fingerprint. - The external SSH command remains important as a fallback if a browser, proxy, or network environment cannot sustain the websocket terminal. > 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 execution. Context window size was 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c48feee190 |
Improve live agent feedback during sandboxed runs (#8915)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - A core part of that experience is watching active agent runs without dropping into raw logs first > - Local and sandbox-backed adapters already record useful run output, progress, and tool activity > - But active issue threads could sit visually stale while the agent was syncing workspaces, tailing sandbox output, or emitting incremental tool-call updates > - Operators need timely, human-readable progress while preserving the raw transcript underneath > - This pull request streams sandbox run-log progress into runtime status, keeps visible issue threads refreshed, and folds repeated ACPX tool updates into stable transcript cards > - The benefit is that long-running agent work becomes easier to supervise without changing the task/comment control-plane model ## Linked Issues or Issue Description No public GitHub issue exists for this exact change. Problem/motivation: - During long-running sandboxed agent work, the issue UI can appear idle even though the agent is actively syncing, running tools, or producing incremental output. - Operators need realtime feedback at the issue-thread layer, not only after opening raw logs or waiting for the final heartbeat result. - Related public context: #1808 previously added live-run status dots to Projects; #4362 touches heartbeat wakeup behavior but is not a duplicate of this runtime/UI feedback change. ## What Changed - Added sandbox run-log streaming support and defaulted sandbox-capable local adapters into the richer live-feedback path. - Surfaced environment/sandbox sync progress through heartbeat runtime status with bounded, redacted snippets. - Added live issue-thread cache patching so visible active runs update as progress events arrive. - Folded repeated ACPX `tool_call` updates into one transcript card instead of stacking duplicate cards. - Updated adapter docs and added focused regression coverage for sandbox log streaming, runtime status, ACPX parsing, live updates, transcript rendering, and issue chat messages. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run ui/src/context/LiveUpdatesProvider.test.ts` - `pnpm exec vitest run server/src/services/heartbeat-run-runtime-status.test.ts server/src/__tests__/heartbeat-runtime-state.test.ts ui/src/context/LiveUpdatesProvider.test.ts` - `pnpm exec vitest run packages/adapter-utils/src/execution-target-sandbox.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts server/src/services/heartbeat-run-runtime-status.test.ts server/src/__tests__/agent-live-run-routes.test.ts server/src/__tests__/heartbeat-runtime-state.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts ui/src/context/LiveUpdatesProvider.test.ts ui/src/components/transcript/RunTranscriptView.test.tsx ui/src/lib/issue-chat-messages.test.ts ui/src/components/IssueChatThread.test.tsx` - GitHub PR workflow on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`: `verify`, build, typecheck/release-registry, e2e, general shards, serialized server shards, and canary dry run passed. - Greptile Review on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`: Confidence Score 5/5, no unresolved review threads. ## Risks - Live issue-thread cache patching could miss an edge case for a route shape not covered by tests. - Surfacing active-run snippets needs continued care around redaction; this PR keeps snippets bounded and adds redaction-focused coverage. - More frequent active-run UI refreshes could expose performance issues on very large issue threads, though updates are scoped to visible run/query caches. ## Model Used OpenAI GPT-5 via Codex, operating as a tool-enabled coding agent with shell, git, and repository-editing capabilities. Context window size 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
69c55d465d |
Add telemetry data contract docs (#8886)
Adds the public telemetry data contract README, links it from contributor docs, and adds a focused README contract test for generated helper names. Verification: - git diff --check origin/master..HEAD - pnpm exec vitest run packages/shared/src/telemetry/readme-contract.test.ts - PR CI green - Greptile 5/5 Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
60f7fb4223 |
PAP-12424 Work Timeline — Phase C: frontend Gantt page (Direction C) (#8880)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators need to *see* how work actually flowed across their agents over time — who was invoked, what they worked on, and how work was delegated between them > - The dashboard shows point-in-time state but nothing reconstructs the temporal, cross-actor picture of heartbeat runs and delegations > - A read-only company work-timeline endpoint was landed first (server aggregation over runs/issues/activity); it had no frontend > - This pull request adds the Gantt-style **Work Timeline** page that renders that endpoint, plus the small additive server contract change it needs (shared DTOs + a task title on each span) > - The benefit is a single dense view — actor rows, concurrency lanes, delegation connectors, zoom and a mini-map — that makes agent activity legible without an N+1 fetch storm from the client ## Linked Issues or Issue Description No public GitHub issue. Problem, in-PR: - **Gap:** the company work-timeline aggregation endpoint has no UI. There is no way to visually inspect how heartbeat runs unfolded over time or how work was delegated between agents. - **Solution:** a dashboard-adjacent Gantt-style page at `/:companyPrefix/timeline`, linked from the sidebar's "Work" section, rendering runs as bars on per-actor rows with delegation connectors, kickoff chips, zoom, a lens filter, and a mini-map. - Built with React + custom inline SVG (no chart dependency; consistent with the existing Tailwind/Radix stack). ## What Changed - **Frontend Gantt page** (`ui/src/pages/Timeline.tsx`, `ui/src/components/timeline/WorkTimelineChart.tsx`): actor rows (agents/system only — humans never get a row), overlapping runs packed into concurrency sub-lanes, bars = heartbeat runs with a left colour tab for issue identity, truncated task title + timing/status on hover, click-through to the task. - **Human activity markers & human rows** for kickoff/delegation involving people, without giving humans their own run lane. - **Kickoff avatar chips** at each bar's leading edge; straight agent→agent delegation connectors (dashed for retries/changes-requested); in-progress runs extend to a dashed "now" line and fade out. - **Zoom** (hour/day/week, auto-fit), full-window **mini-map** with a draggable brush, **lens filter** (Everyone / per-user, server-side), and colour **by task / by status**. - **Pure layout/transform module** (`ui/src/lib/timeline/layout.ts`) — packing, kickoff derivation, connector resolution, scales — unit-tested in isolation. - **Server contract (additive):** moved the `WorkTimeline*` DTOs into `@paperclipai/shared` so the aggregation service and the UI consume one contract; added `issueTitle` to each span so the tooltip shows the task title with no N+1 client fetch. - Sidebar link, query keys, API client (`ui/src/api/workTimeline.ts`), and a Storybook story with fixtures. ## Verification - `pnpm --filter @paperclipai/shared build` ✅ - `pnpm --filter @paperclipai/server typecheck` ✅ · `pnpm --filter @paperclipai/ui typecheck` ✅ - `pnpm --filter @paperclipai/ui exec vitest run src/lib/timeline/layout.test.ts src/components/timeline/WorkTimelineChart.test.tsx` ✅ (15/15) - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/work-timeline-service.test.ts` ✅ (5/5) — the DTO move + `issueTitle` are additive; existing service tests use `objectContaining` and still pass. - Rendered `WorkTimelineChart` headless against a real slice of company activity via a Storybook story; manual browser QA of the live page passed on the feature branch. ## Risks - **Low risk.** The change is UI-only plus an additive server DTO refactor (types relocated to `@paperclipai/shared`, one new optional field). No schema/migration changes, no change to endpoint behaviour beyond the extra `issueTitle` field. The page is behind its own route and does not alter existing views. ## Model Used - Claude, Opus 4.8 (`claude-opus-4-8`), via Claude Code with extended thinking and 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 (only the merged endpoint PR #8875 is related; no duplicates) - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal ticket id - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2f94a66ba1 |
Show live descendant status in inbox rows (#8876)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The inbox is where operators quickly scan which issues are active, blocked, or waiting for attention > - A blocked parent can still have active descendant work, but the inbox previously depended on only loaded rows to infer that state > - That made collapsed or partially loaded issue trees look more stuck than they really were > - This pull request carries live descendant summary data through the issue list API and inbox UI > - The benefit is a more accurate blocked-inbox signal, so operators can distinguish truly stalled work from blocked parents that still have live child activity ## Linked Issues or Issue Description No public GitHub issue was found for this exact inbox descendant-status polish. Feature request fields: **Subsystem affected** Cross-cutting: `server/`, `packages/shared`, plugin/MCP API surfaces, and `ui/` inbox rendering. **Problem or motivation** Inbox rows need to show when blocked or collapsed parents still have live descendant work, even when the live child row is not loaded in the current client tree. Without a server-provided descendant summary, a parent can look stalled even though active work continues below it. **Proposed solution** Expose an optional live descendant count on issue list results, request it from inbox views, and use it to render covered blocked status and live-below indicators. Keep the field opt-in so other issue list callers keep their existing payload shape and query cost. **Alternatives considered** Relying only on client-loaded subtree state was ruled out because it misses collapsed or unloaded descendants. Always returning the count was also avoided because most list callers do not need this extra summary. **Roadmap alignment** This is scoped operator-visibility polish for the existing inbox. It does not duplicate a named `ROADMAP.md` milestone. **Additional context** The recursive summary query is guarded against parent cycles, and the UI still falls back to loaded subtree live counts when server summary data is absent or stale. ## What Changed - Added optional `includeLiveDescendantSummary` support to issue list contracts, SDK surfaces, MCP tools, routes, services, and tests. - Added `liveDescendantCount` to issue list results when requested. - Updated inbox and blocked-inbox queries to request live descendant summaries. - Updated inbox row status rendering so blocked parents with live descendants show covered blocker treatment without duplicating the live-below chip. - Hardened live descendant summary traversal against parent cycles and preserved the loaded-subtree fallback path for blocked inbox rows. - Added focused tests for the API parameter, service behavior, helper logic, cycle handling, and inbox UI query/rendering behavior. ## Verification - `pnpm exec vitest run server/src/__tests__/issue-list-assignee-filter-routes.test.ts ui/src/lib/inbox-live-descendants.test.ts ui/src/components/IssueColumns.test.tsx ui/src/components/BlockedInboxView.test.tsx ui/src/pages/Inbox.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` - Rebased cleanly onto current upstream `master` before pushing. - Confirmed the branch diff does not include `pnpm-lock.yaml` or `.github/workflows/*` changes. ## Risks Low to moderate risk. The new descendant count is opt-in on list requests, but it adds query work when the inbox asks for it. The recursive traversal now tracks visited ancestors to avoid cycle failures. The UI uses the server count as a supplement to existing loaded-tree state, so stale or absent counts fall back to the prior behavior. > 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 with local shell and git access. Reasoning mode and context window are managed by the Paperclip/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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
b4815bf964 |
Scope environment custom images to instance environments (#8850)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Environments are now managed as instance-level runtime resources rather than per-company rows > - The custom environment image setup tables were introduced with their own `company_id` columns and route query parameters > - That split made one saved environment image state depend on an extra company context even though the environment itself is the durable owner > - It also made saved-environment probes harder because applying the active custom image template could require a company context when no secret-backed config needed one > - This pull request scopes custom image templates and setup sessions directly to the saved environment > - The benefit is that reusable environment images follow the same instance-scoped model as environments while secret resolution still uses company context only when secrets require it ## Linked Issues or Issue Description No matching public GitHub issue was found. Bug report: ### What happened? saved environment custom-image routes and persistence required a `companyId` even though environments are instance-scoped, and saved sandbox probes did not opt into active custom-image template application unless a company context was present. ### Expected behavior custom-image templates and setup sessions should be owned by the saved environment, and saved sandbox probes should apply the active template while still requiring a company context only for secret-backed runtime config. ### Steps to reproduce 1. Configure an instance-scoped sandbox environment with custom-image setup support. 2. Start or inspect a custom-image session or template for that saved environment. 3. Probe the saved environment without a custom-image-specific `companyId` query parameter. ### Paperclip version or commit current `master` after the environment custom-image template migration. ### Deployment mode Local dev (pnpm dev) or authenticated local Paperclip instance. ### Installation method Built from source (pnpm dev / pnpm build). ### Agent adapter(s) involved Not adapter-specific (core bug). ### Database mode Embedded PGlite/Postgres dev database. ### Access context Board human operator. ### Privacy checklist No logs, secrets, tokens, private URLs, or local machine paths are included. Duplicate search performed: - `gh search prs "environment custom image companyId repo:paperclipai/paperclip" --state open --limit 20` - `gh search prs "custom image environment scoped repo:paperclipai/paperclip" --state open --limit 20` - `gh search issues "environment custom image repo:paperclipai/paperclip" --state open --limit 20` The returned results were unrelated adapter, Docker, auth, or stale-workspace items. ## What Changed - Removed redundant `company_id` columns from environment custom-image templates and setup sessions. - Added migration `0127_environment_custom_images_instance_scoped` to collapse duplicate active rows per environment before dropping the old company-scoped indexes/columns. - Updated custom-image services, route handlers, shared validators, and UI API/query keys to use environment-scoped custom-image state. - Kept runtime secret resolution company-aware only when secret refs or bindings require a company context. - Made saved sandbox environment probes opt into active custom-image template application. - Updated DB, shared, server, and UI tests for the new environment-scoped contract. ## Verification - `pnpm --filter @paperclipai/db run check:migrations` - `pnpm exec vitest run packages/db/src/environment-custom-images-schema.test.ts packages/shared/src/environment-custom-images.test.ts server/src/__tests__/environment-custom-image-routes.test.ts server/src/__tests__/environment-custom-images-service.test.ts server/src/__tests__/environment-routes.test.ts ui/src/pages/CompanyEnvironments.test.tsx` - `pnpm -r typecheck` - `pnpm test:run` before rebasing onto latest `master`; after the rebase only the migration number changed, and the migration check plus focused suite, typecheck, and build were rerun. - `pnpm build` ## Risks - Migration safety: the migration supersedes duplicate active templates per environment and fails duplicate active setup sessions before adding environment-only unique indexes. Operators with duplicate historical active rows should review which active template is kept. - Behavior shift: plugin custom-image setup calls now receive `companyId: "instance"` when no secret binding determines a concrete company context. - Secret-backed configs still require an explicit or uniquely inferable company context; environments with secret bindings spread across multiple companies continue to fail fast. > 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 via the `codex_local` adapter, GPT-5-based coding model with tool-enabled repository inspection, editing, testing, git, and GitHub CLI access. Exact context-window metadata was 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
fb2b760915 |
fix(issues): attribute agent-authored comments instead of rendering them as "Board" (#8833)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Task/issue threads render each comment as a chat bubble; the author determines whether it shows as a left-aligned agent bubble (name + icon) or a right-aligned "Board" bubble > - Comments posted by an agent from a local execution environment are written with a non-human author id (`local-board`/system), so they were mis-rendered as blue "Board" bubbles instead of being attributed to the authoring agent > - This misattribution is confusing (it looks like the human board said something an agent actually said) and it can drive false wake/reconciliation behavior on the affected threads > - This pull request adds server-side attribution derivation (lossless run-id join first, then an explicit run-log post marker), persists the derived agent so the read path stops re-scanning run logs, and stops the client from labeling agent-derived comments "Board" > - The benefit is agent comments render as the correct agent, genuine human board comments are never reattributed, and reads get cheaper after a one-time persistence ## Linked Issues or Issue Description <!-- No public GitHub issue — describing the problem in-PR (bug report shape). --> **What happened?** In a task/issue comment thread, comments authored by an agent from a local execution environment are stored with a non-human author id (`local-board`/system). The UI renders these as right-aligned blue "Board" bubbles, implying a human board member authored them. The mislabeling is also a wake/reconciliation hazard: an agent comment that reads as "Board" can look like human board input. **Expected behavior** Such comments should render as the authoring agent (left-aligned bubble with agent name + icon). Genuine human/board comments must continue to render as "Board" and must never be reattributed to an agent. **Steps to reproduce** 1. Have an agent post a comment on an issue from a local execution environment (author id `local-board`). 2. Open the issue comment thread in the UI. 3. Observe the agent's comment rendered as a right-aligned blue "Board" bubble instead of the authoring agent. **Root cause** The read path did not resolve the authoring agent for these comments, and the client fell back to a "Board" label for the `local-board` author. ## What Changed - **Server derivation (`server/src/services/issues.ts`):** - Resolve the authoring agent from the comment's run id first (`createdByRunId`/`derivedCreatedByRunId` → `heartbeatRuns.agentId`) — lossless when present. - Second tier `run_log_comment_post`: read the run log lazily (only for still-unresolved comments) to match the explicit `comment id:` post marker. - **Guard:** never reattribute a comment whose author maps to a genuine user profile. Only the non-human sentinel (`local-board`, which is itself a `user` row) and authors absent from the `user` table are eligible. - Pure timing-overlap tiers are intentionally **not** used (Option A) — an agent comment and a human board comment posted during the same run are indistinguishable rows, so any timing guess risks mislabeling a real human comment. - **Persistence (`packages/db/src/migrations/0126_issue_comment_derived_attribution.sql`, `packages/db/src/schema/issue_comments.ts`):** add stored `derived_*` attribution columns and write the resolved agent back with a single bulk `UPDATE ... FROM (VALUES ...)`, so reads stop recomputing from run logs. Migration is additive (new nullable columns) with a batched, idempotent backfill of the lossless run-id tier over historical rows. - **Types (`packages/shared/src/types/issue.ts`):** expose the persisted attribution fields and the `IssueCommentDerivedAuthorSource` union. - **Client (`ui/src/lib/issue-chat-messages.test.ts`):** the message builder already prefers a resolved agent id (`authorAgentId ?? runAgentId ?? derivedAuthorAgentId`), so once the server persists the derived agent the bubble renders as the agent automatically — no client code change needed. Adds a regression guard confirming a genuine board comment with no derived agent is still rendered as "Board". - **Tests:** derivation + message-building tests, including assertions that genuine board/user comments are **not** reattributed. ## Verification - `cd server && npx vitest run issues-service` — 94 tests pass: run-id resolution, no-attribution on timing overlap alone (Option A), multi-run ambiguity, same-agent multi-run, and the genuine-user guard. Exercises the real persistence path (bulk UPDATE) against the test DB. - `cd ui && npx vitest run issue-chat-messages` — 27 tests pass; client no longer labels agent-derived comments "Board", and a genuine board comment with no derived agent is not re-labeled. - `cd server && npm run typecheck` — passes (exit 0). - Manual: on a thread containing old agent-authored comments, the blue "Board" bubbles render as the authoring agent; a genuine board comment on the same thread still renders as "Board". ## Risks - **Mis-reattributing a genuine board comment made during an agent run** → mitigated by the human-profile guard (only `local-board`/system authors are eligible) and by dropping pure timing tiers (Option A): only the lossless run-id join and the explicit run-log post marker attribute history. - **Backfill volume / run-log reads** → the migration backfill is batched (5000 rows/loop) and results are persisted so reads stop recomputing; the read-path persistence is a single bulk UPDATE rather than per-comment round-trips. Migration adds only nullable columns (no destructive change). - The persistence/backfill has **not** been run against any production database as part of opening this PR. ## Model Used Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, via Claude Code with 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 — related open PRs (#6006 narrow attribution run scan, #4729 attribution roll-up, #7014 reaped-run attribution) address different attribution paths; none fix the `local-board` "Board" bubble rendering this PR targets. Supersedes #8832 (same change; branch renamed to drop an internal ticket id per CONTRIBUTING → Branch Naming) - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3522b1c9be |
Emit interaction resolved telemetry (#8824)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Issue-thread interactions are how agents ask users or the board for decisions and structured input > - Product telemetry needs to understand when those interactions resolve without exposing private interaction content > - Resolution currently happens through several service paths, so telemetry needs to be emitted consistently from the terminal transitions > - The interaction service should describe the resolved interaction, while the telemetry backend owns unknown-value normalization for dimensions > - This pull request emits `interaction.resolved` after successful database writes and removes redundant client-side normalization from the service > - The benefit is aggregate-safe telemetry for interaction completion behavior without leaking raw IDs, answer text, rejection reasons, or document content ## Linked Issues or Issue Description No public GitHub issue exists for this internal telemetry follow-up. Feature context: - Problem/motivation: Paperclip needs aggregate product telemetry for issue-thread interaction resolution outcomes while preserving privacy boundaries around user answers and internal identifiers. - Proposed solution: Emit `interaction.resolved` once from terminal interaction resolution paths, passing runtime dimensions through the shared telemetry helper while preserving aggregate-safe counts and ID/free-text omission. - Alternatives considered: Normalizing interaction dimensions in the interaction service duplicated telemetry backend responsibility and made unknown-value handling inconsistent across telemetry clients. - Roadmap alignment: This is a focused telemetry instrumentation follow-up that builds on the generated telemetry event types from #8818. ## What Changed - Wires `interaction.resolved` telemetry into terminal issue-thread interaction resolution paths after successful database writes. - Passes raw interaction kind, status, continuation policy, resolution reason, target type, and creator agent role values to the shared telemetry helper instead of maintaining service-local allowlists. - Preserves resolver classification, target `none` derivation for non-confirmation interactions, non-negative aggregate counts, raw ID omission, and free-text omission. - Logs telemetry failures without blocking interaction resolution. - Adds service-level tests for accepted, rejected, answered, stale-target expiry, superseded-comment expiry, and raw creator-role pass-through payloads. ## Verification - `pnpm run preflight:workspace-links && pnpm exec vitest run server/src/__tests__/issue-thread-interactions-telemetry.test.ts server/src/__tests__/shared-telemetry-events.test.ts` - `pnpm typecheck` - GitHub PR checks on the latest head commit are green, including `verify`, build, e2e, general tests, serialized server suites, security scans, and Greptile Review. - Security code review completed before this branch update. ## Risks - Low operational risk: telemetry is emitted after successful persistence and telemetry failures are logged without blocking the user-visible interaction flow. - Main behavioral risk is duplicate or missing telemetry from a resolution path; the focused tests cover the terminal resolution variants. - Telemetry dimension normalization now depends on the shared telemetry backend path instead of the interaction service, so backend normalization must remain the source of truth for unknown or empty dimension values. - The existing PR branch name contains an internal task id because this update continues an already-open PR branch instead of opening a replacement PR. ## Model Used OpenAI GPT-5 Codex coding agent, API-based coding environment with shell, repository, and GitHub CLI tool use. Context window size was not reported 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8a93a0de4c |
Implement generated client telemetry types (#8818)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Telemetry is part of the control plane's operational visibility and needs stable event contracts. > - The shared telemetry client accepted first-party event names through a broad string surface, which weakened compile-time guarantees. > - Plugin telemetry still needs a dynamic path because plugin-defined events cannot be enumerated in the core generated type module. > - This pull request vendors generated Paperclip telemetry event and dimension types, closes the first-party event-name union, and keeps plugin telemetry on an explicit dynamic method. > - Review feedback clarified that backend normalization should remain the source of truth, so telemetry helpers now preserve raw categorical values while keeping generated per-event type hints. > - The benefit is stricter first-party telemetry typing without hiding backend normalization signals or changing batching, flushing, schema versioning, sinks, or endpoints. ## Linked Issues or Issue Description No public GitHub issue exists for this internal type-contract maintenance change. ### Problem or motivation The shared telemetry client should reject unregistered first-party event names at compile time, while the plugin telemetry bridge must continue to emit plugin-defined events through the existing batching and envelope path. Helper wrappers should also avoid client-side enum coercion so the backend can detect and record normalization when clients send unexpected categorical values. ### Proposed solution Generate and vendor the accepted Paperclip telemetry event and dimension types, use those types for the first-party `track()` API, keep plugin-defined telemetry on an explicit dynamic method, and let helper wrappers pass raw categorical dimensions through to backend validation. ### Alternatives considered Keeping `track()` open to arbitrary strings would preserve flexibility, but it would not give first-party callers the type safety this change is meant to provide. Enumerating plugin events in core was also ruled out because plugin-defined events are not known to the core package. Client-side enum normalization was removed after review because it duplicates backend validation and can hide misbehaving-client signals. ### Roadmap alignment This is a tightly scoped telemetry contract maintenance change and does not overlap with a roadmap-level core feature. ## What Changed - Vendored the generated Paperclip telemetry event and dimension type module under shared telemetry code. - Closed the first-party telemetry event-name union to generated backend-accepted names plus an explicit `RegisteredPluginEventName = never` extension point. - Added `TelemetryClient.trackDynamic()` for plugin telemetry bridge emission while keeping `track()` closed and typed. - Added JSDoc explaining when to use `track()` versus `trackDynamic()`. - Updated telemetry helper wrappers to type dimensions from each event's generated schema entry while passing raw categorical values through for backend normalization. - Added `trackInteractionResolved()` and updated focused shared/server tests for telemetry event typing, raw pass-through behavior, and plugin telemetry bridging. ## Verification Local verification passed before the latest push: - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm exec vitest run packages/shared/src/telemetry/client-types.test.ts server/src/__tests__/shared-telemetry-events.test.ts server/src/__tests__/plugin-telemetry-bridge.test.ts server/src/__tests__/project-goal-telemetry-routes.test.ts server/src/__tests__/routine-run-telemetry.test.ts server/src/__tests__/issue-telemetry-routes.test.ts` - `git diff --check` Post-push verification completed on head `3d973ffbea6154b19ad208dcffd1374d1b25b654`: - GitHub PR checks passed, including `verify`, build, typecheck/release registry, general test shards, serialized server shards, canary dry run, e2e, and security checks. - Greptile Review passed with 5/5 confidence. - All PR review threads are resolved. ## Risks Low runtime risk. The change is intended to affect TypeScript contracts and helper typing while preserving the existing telemetry enqueue, batching, and backend ingest path. The main intentional behavior shift is that helper wrappers no longer coerce unexpected categorical values on the client; those values reach the backend so backend normalization can record the signal. Private company import source refs still use `hashPrivateRef` when `isPrivate` is true. ## Model Used OpenAI GPT-5 Codex, tool-enabled coding agent. Exact context window was not exposed by the runtime; the agent used repository file access, shell commands, and GitHub CLI operations. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ac9a883f8b |
Expire ask-user questions superseded by comments (#8799)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Issue-thread interactions are how agents ask board users for typed decisions and structured answers inside an issue thread > - Confirmation interactions already become stale when a later board/user comment supersedes the pending decision > - Question interactions had the same workflow risk, because a board/user could answer in a comment while the old question card stayed pending > - This pull request extends the supersede-by-comment lifecycle to ask-user-question interactions and makes that status visible in the UI > - The benefit is agents get a clear continuation signal and users do not see stale question forms after the discussion has moved on ## Linked Issues or Issue Description No exact public GitHub issue was found. Bug report: **Pre-submission checklist** - [x] I have searched existing open and closed issues and this is not a duplicate. - [x] I am on the latest released version of Paperclip, or can reproduce on `master`. - [x] I have confirmed the error originates in Paperclip itself, not in an agent adapter, API provider, or local configuration. **What happened?** Pending `ask_user_questions` interactions could remain open after a later board/user comment changed or answered the request in-thread. That left a stale form visible and kept the interaction in a pending state even though the discussion had moved on. **Expected behavior** Question interactions should follow the same default supersede-on-comment behavior as confirmation interactions, with an explicit expired result that points to the superseding comment. **Steps to reproduce** 1. Create an `ask_user_questions` interaction on an issue. 2. Add a board/user comment created at or after that interaction. 3. Observe that before this change, the question interaction stayed pending instead of expiring as superseded by the comment. **Paperclip version or commit** Current `master` before this PR. **Deployment mode** Self-hosted server or local dev. The bug is in shared issue-thread interaction lifecycle handling. **Installation method** Built from source. **Agent adapter(s) involved** Not adapter-specific. This is a core issue-thread interaction bug. **Database mode** Applies to the normal Paperclip database-backed interaction lifecycle. **Access context** Board user comments supersede agent-created questions. **Relevant logs or output** No crash output. The stale pending interaction was visible in the issue thread state. **Relevant config (if applicable)** None. **Additional context** Confirmation-style interactions already supported this stale-by-comment behavior. This PR brings question interactions into the same lifecycle model. **Privacy checklist** - [x] I have reviewed all pasted output for PII and included no private instance links, local ticket ids, secrets, logs, or screenshots. ## What Changed - Added `supersedeOnUserComment` support to `ask_user_questions` payloads, defaulting it to `true` during interaction creation. - Expire pending question interactions when a later board/user comment supersedes them, including a result with `expirationReason: "superseded_by_comment"` and the superseding `commentId`. - Updated interaction summaries and cards so expired question requests show a clear amber state with a jump link to the comment and correct singular/plural copy. - Updated agent onboarding guidance to describe the new default and how to opt out. - Added shared, server, and UI test coverage for the new lifecycle behavior. ## Verification - `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 --reporter=dot` passed: 5 files, 73 tests. - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` passed. - `pnpm exec vitest run server/src/__tests__/issue-thread-interactions-service.test.ts --reporter=dot && pnpm --filter @paperclipai/server typecheck` passed after the final type-safety cleanup. - Confirmed the branch is rebased on current `origin/master`. - Confirmed the diff does not touch `pnpm-lock.yaml`, `.github/workflows`, or database migrations. ## Risks - Low-to-medium risk: `ask_user_questions` now defaults to expiring after later board/user comments. Existing callers that need questions to stay open through discussion can set `supersedeOnUserComment: false`. - Expired question interactions store an empty `answers` array, so downstream consumers should treat the explicit `expirationReason` as the meaningful outcome. > 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 Paperclip CodexCoder runtime, with terminal and repository tool use. Exact context window 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a8f0ebaa80 |
Refresh run config before reusing workspaces (#8797)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent runs are assembled by the heartbeat service from agent config, project workspaces, environment config, secret bindings, skills, and runtime session state. > - The heartbeat service intentionally reuses adapter sessions, execution workspaces, and sandbox leases when that preserves useful state. > - Reuse becomes incorrect when the effective next-run config changes after a saved session, workspace, or lease was created. > - Stale reuse can make a later run appear pinned to old agent, environment, secret, instruction, or workspace settings. > - This pull request records non-sensitive fingerprints for the effective session, workspace, and lease config at run boundaries. > - When those fingerprints drift, Paperclip refreshes persisted runtime config or starts fresh execution instead of reusing stale state. > - The benefit is predictable next-run config freshness without storing raw secret values, full env maps, provider credentials, or private path details. ## Linked Issues or Issue Description - Refs #8058 - Related PRs checked during dedup search: #4968, #4155, #84, #8480. These cover nearby workspace/session routing or model-config freshness areas, but do not duplicate this effective run config fingerprinting path. ## What Changed - Added effective run config fingerprinting for session, workspace, and lease reuse decisions, with canonicalization that ignores generated runtime noise and redacts sensitive values. - Updated heartbeat reuse logic to compare stored and next-run fingerprints, reset stale saved sessions, refresh persisted workspace config snapshots, replace stale reused workspaces when required, and avoid stale sandbox lease reuse. - Included plain environment value drift via value hashes, without storing the raw env values. - Root-bound instruction content hashing so legacy direct absolute instruction paths are represented but not read for config fingerprints. - Batched secret/version metadata lookups for environment lease fingerprinting. - Added workspace operation/run result freshness metadata so operators can inspect non-sensitive decision categories. - Surfaced config freshness labels and next-run copy in the UI and docs. - Added focused coverage for fingerprint redaction, session reset decisions, workspace refresh/replace behavior, environment lease drift, and persisted workspace restoration. ## Verification - `git diff --check` - Sensitive-data scan before push: - `git diff --unified=0 origin/master...HEAD | rg -n --pcre2 "(AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|ghp_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|sk-[A-Za-z0-9]{20,}|-----BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----|AKIA[0-9A-Z]{16})"` - `git diff --unified=0 origin/master...HEAD | rg -n --pcre2 "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"` - `pnpm exec vitest run server/src/__tests__/effective-run-config-fingerprints.test.ts server/src/__tests__/heartbeat-workspace-session.test.ts server/src/__tests__/environment-runtime.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `pnpm -r typecheck` - `pnpm --filter @paperclipai/db clean` - `pnpm test:run` - `pnpm build` - UI screenshots from Cutter: - https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-01.png - https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-02.png - https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-03.png ## Risks - Medium: overly broad fingerprints could start fresh sessions, workspaces, or sandbox leases more often than necessary. - Medium: missing a config category would allow stale reuse to persist for that category. - Medium: legacy direct absolute instruction paths are no longer content-hashed unless they are paired with an absolute managed instructions root. - Low data risk: fingerprint metadata stores hashes and category names, not raw secrets, raw env values, provider credentials, or private path details. > 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 via Codex CLI / Codex coding agent, tool-enabled with shell, Git, GitHub CLI, local test execution, and code editing. The exact deployed model variant and context window are not exposed by 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Cody <cody@paperclip.ing> |
||
|
|
8d9f9fd240 |
Add reusable sandbox custom images (#8794)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A growing part of that work runs in sandboxed environments rather than on the operator's local machine. > - Today sandbox providers can start fresh workspaces and run probes, but they do not have a shared contract for capturing and reusing prepared sandbox state. > - Operators need a way to set up tools, credentials, and project dependencies once, then reuse that prepared image for later agent runs. > - This pull request adds reusable sandbox custom images across the provider contract, server runtime, and board UI. > - It also keeps probes and sandbox copy flows aligned with pre-authenticated/custom-image environments. > - The benefit is faster, more reliable sandbox runs without repeatedly rebuilding the same environment setup. ## Linked Issues or Issue Description No public GitHub issue was found for this change. Inline feature request follows. ### Problem or motivation Sandboxed agents need reusable prepared runtime state so repeated runs do not require manual setup every time. Operators often need system packages, CLIs, SDKs, dependency caches, credentials, and project tooling available before an agent can work productively. ### Proposed solution Add a provider-level custom-image capability, server-side setup/capture lifecycle, Daytona/fake provider support, and board UI controls for creating, testing, selecting, and deleting custom images. ### Alternatives considered Leaving this as provider-specific setup outside Paperclip would keep the control plane blind to image state and would not give agents consistent environment metadata. Re-running setup commands for every lease is simpler, but slower and less reliable for interactive or credentialed setup. ### Roadmap alignment Checked `ROADMAP.md`; this aligns with the Cloud / Sandbox agents roadmap area and does not duplicate any related public issue or PR found by search. Additional context: - Subsystem affected: cross-cutting (`packages/db`, `packages/shared`, `packages/plugins`, `server`, `ui`). - Duplicate search: searched GitHub for `sandbox custom image` and `sandbox template environment`; no related public issues or PRs were found. ## What Changed - Added custom-image shared types, validators, constants, API paths, and database schema/migration. - Added server services/routes for custom-image templates and setup sessions, including runtime cleanup and provider metadata handling. - Extended plugin/sandbox provider capabilities for interactive setup, template capture, and template deletion. - Implemented custom-image support in the fake sandbox provider and Daytona provider. - Updated environment runtime/config handling so active custom images flow into leases, probes, and agent execution. - Added board UI controls and API client support for custom-image setup, capture, selection, status, and error states. - Hardened sandbox copy/probe behavior for insecure clipboard contexts and pre-authenticated sandbox images. - Added targeted coverage across shared validators, DB schema, server routes/services, provider plugins, adapter probes, and UI flows. ## Verification - `pnpm install --frozen-lockfile --ignore-scripts` - `pnpm vitest run packages/adapters/claude-local/src/server/test.probe.test.ts packages/adapters/claude-local/src/server/test.ts packages/adapters/codex-local/src/server/test.remote.test.ts packages/adapters/codex-local/src/server/test.ts` - `pnpm --filter @paperclipai/adapter-claude-local typecheck` - `pnpm --filter @paperclipai/adapter-codex-local typecheck` - `pnpm vitest run packages/db/src/environment-custom-images-schema.test.ts packages/shared/src/environment-custom-images.test.ts packages/shared/src/validators/plugin.test.ts server/src/__tests__/environment-custom-images-service.test.ts server/src/__tests__/workspace-runtime.test.ts packages/plugins/sandbox-providers/daytona/src/plugin.test.ts ui/src/pages/CompanyEnvironments.test.tsx ui/src/pages/CompanySettings.test.tsx` - `pnpm -r typecheck` - `pnpm build` - `rm -rf packages/db/dist && pnpm test:run` - Public-safety scan of the final diff found no internal Paperclip issue links, private instance URLs, or real secret patterns. ## Risks - Adds a database migration and new environment runtime tables, so migration ordering and rollback need care. - Provider implementations may differ in how reliably they can capture/delete images; unsupported providers surface capability-gated UI states. - Custom-image state can contain operator-prepared tooling and credentials inside the provider image, so providers must enforce their own access controls and cleanup semantics. - Broad surface area across shared contracts, server runtime, plugins, adapters, and UI means CI and Greptile review should be watched closely. > 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 (`gpt-5`) via Codex CLI with tool use and code execution. Assisted with branch cleanup, conflict resolution, local verification, and PR preparation. Earlier branch implementation work was assisted by Paperclip-managed Claude/Codex agents. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3e31bf09bc |
[codex] Add pipeline automation title templates (#8787)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Pipeline automations let operators standardize repeated issue and workflow actions. > - Pipeline-created issues currently need a way to derive useful titles from routine variables. > - Without a configurable title template, automated pipeline output is harder to scan and distinguish. > - This pull request adds a title-template field through shared contracts, server persistence, API routes, and the pipeline settings UI. > - The benefit is clearer issue titles for pipeline-created work while preserving the existing pipeline behavior when no template is configured. ## Linked Issues or Issue Description Refs #8790 This PR adds configurable generated-issue title templates for pipeline automations. ## What Changed - Added `issueTitleTemplate` to the shared pipeline automation contract and field constants. - Persisted and returned the title template through pipeline service and route code. - Applied title-template rendering when pipeline automations create issue work. - Added pipeline settings UI controls for editing the title template and reusing routine variables. - Moved title-token cursor restoration out of the React state updater and into a layout effect. - Added server and UI coverage for storing, returning, and rendering pipeline title templates. ## Verification - `NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test pnpm exec vitest run server/src/__tests__/pipelines-service.test.ts server/src/__tests__/pipelines-routes.test.ts ui/src/pages/PipelineSettings.test.ts` - Result before review follow-up: 3 files passed, 58 tests passed. - `pnpm --filter @paperclipai/ui exec vitest run src/pages/PipelineSettings.test.ts` - Result after review follow-up: 1 file passed, 7 tests passed. - Branch was merged with current `paperclipai:master` at `f019f54bb3` before opening this PR. - Searched existing PRs for the same head branch and for pipeline title-template duplicates; no matching existing PR was found. - Note: GitHub could not open a PR directly from `cryppadotta/paperclip` because that repository is not a fork of `paperclipai/paperclip`. The same updated branch SHA was pushed to `paperclipai/paperclip` so this PR can compare normally against `master`. ## Risks Low to moderate risk. The change touches pipeline automation persistence and generated issue creation, so regressions would most likely appear as missing or incorrectly rendered generated issue titles. Existing behavior should remain unchanged when `issueTitleTemplate` is unset. ## Model Used OpenAI Codex, GPT-5-based coding agent, tool-enabled execution in a Paperclip heartbeat, with repository inspection, Git, GitHub CLI, and local test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a7a73d5bc7 |
Fix stale server info debug metadata (#8753)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The experimental server info debug view helps local operators inspect what code a running dev instance is actually serving > - The view was moved into the account-menu drawer, which only mounts while that drawer is open > - That made stale health-query data easier to see after restarts, and the server was also caching the running commit at process boot > - A clean commit label alone is incomplete when the checkout has uncommitted local changes > - This pull request keeps the drawer health data fresh, refreshes git metadata on demand, and adds a path-free checkout-state summary > - The benefit is that the debug view reports restart time, running commit, and dirty-checkout state without exposing local paths, secrets, logs, or environment details ## Linked Issues or Issue Description Fixes: #8752 ## What Changed - `SidebarServerInfo.tsx`: refetch the health query whenever the drawer opens and poll every 2s while the dev server is active. - `server-info.ts`: keep `processStartedAt` stable while refreshing git HEAD through a short TTL cache instead of freezing commit metadata at module boot. - Shared health contract/OpenAPI: add `serverInfo.git.localChanges` with only staged, unstaged, and untracked counts plus safe unavailable fallbacks. - `SidebarServerInfo.tsx`: add a `Checkout state` row that renders clean/dirty/unavailable copy without file paths. - Tests: cover stale drawer refresh, interval polling, TTL commit refresh, health response shape, checkout-state count parsing, and path-free UI rendering. ## Verification - `npx vitest run server/src/__tests__/server-info.test.ts server/src/__tests__/health.test.ts ui/src/components/SidebarServerInfo.test.tsx` -> 3 files / 19 tests passing. - `pnpm install --frozen-lockfile --ignore-scripts` -> refreshed stale workspace links without lockfile/source churn. - `pnpm --filter @paperclipai/shared --filter @paperclipai/server --filter @paperclipai/ui typecheck` -> passing. - `pnpm --filter @paperclipai/ui typecheck` -> passing after the Greptile test-coverage fix. - `pnpm check:tokens` -> no forbidden tokens found. - Local diff scans for obvious secrets, credentials, private URLs, local paths, and PII patterns -> no matches. - GitHub PR checks on head `56defd446` -> all green, including `verify`, canary dry run, e2e, security scans, and Greptile Review. - Greptile latest summary -> Confidence Score 5/5, 0 new comments; the prior P2 polling-coverage thread is resolved. ## Risks Low risk. The UI remains behind the experimental `enableServerInfoDebugView` flag. The extra git status call is throttled by the existing server-info TTL and reports only counts, not paths or file names. If git status is unavailable, the commit row still works and the checkout-state row shows clear fallback copy. ## Model Used Claude Opus (claude-opus-4-8), extended thinking, with tool use / code execution assisted the original stale-metadata fix. OpenAI GPT-5 via Codex local, with tool use and code execution, added the checkout-state follow-up, Greptile fix-up, and PR 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5e3d6e3627 |
[codex] Preserve plan review context in agent wakes (#8649)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Planning work relies on issue documents, request-confirmation interactions, and inline plan annotations > - Agents can be woken after a plan comment, annotation, or confirmation decision > - The wake payload needs enough plan-review context for the agent to act on the specific feedback instead of losing the thread and falling back to broad refetches > - This pull request adds bounded plan-review context to wake payloads and heartbeat context > - It also teaches the adapter wake prompt renderer to surface those open plan annotations and interaction results directly > - The benefit is that agents can continue plan review and plan acceptance flows with the relevant comments in hand while keeping wake payloads bounded and company-scoped ## Linked Issues or Issue Description No matching public GitHub issue was found. ### Subsystem affected Cross-cutting: `server/`, `packages/shared`, and `packages/adapter-utils`. ### Problem or motivation Plan-review continuations can wake an agent after a plan comment, inline annotation, or request-confirmation decision without enough inline context about the open plan annotations or accepted/rejected confirmation target. That makes scoped wakes less reliable because the agent may need to refetch broad issue history before it can tell what feedback should be incorporated. ### Proposed solution Include bounded, company-scoped plan review context in wake payloads and heartbeat context. The context includes open `plan` annotation threads, recent annotation comments, truncation metadata, and plan-confirmation interaction target/result details. Render that information in the adapter wake prompt so agents see the relevant plan-review feedback immediately. ### Alternatives considered Relying on agents to fetch the full issue thread after every plan-review wake was rejected because it is slower, harder to audit, and easier to mishandle when the wake is meant to be scoped to a specific comment, annotation, or interaction result. ### Roadmap alignment This supports the roadmap areas for Agent Reviews and Approvals, Deep Planning, and Enforced Outcomes by making plan approval continuations explicit and actionable. ### Additional context The implementation keeps payload size bounded with per-thread, per-comment, and total-body limits. Resolved annotation threads are intentionally omitted so the wake focuses on feedback still needing action. ## What Changed - Added shared `PlanReviewContext` types for plan annotation threads, comments, interaction targets, and continuation results. - Added server-side plan review context assembly for open `plan` annotation threads with bounded thread/comment/body limits. - Included plan review context in heartbeat context and scoped wake payloads for planning, annotation, comment, and plan-confirmation interaction wakes. - Rendered plan annotation deltas, open plan comments, interaction results, and accepted target revisions in adapter wake prompts. - Added focused regression coverage for scoped plan review context, wake prompt rendering, annotation filtering, and safe standard-mode annotation wakes. - Addressed Greptile feedback by bounding the plan-comment DB fetch and removing unused plan review context input fields. ## Verification - `pnpm run preflight:workspace-links` - `pnpm exec vitest run --project @paperclipai/adapter-utils packages/adapter-utils/src/server-utils.test.ts` - `pnpm exec vitest run --project @paperclipai/server --no-file-parallelism --maxWorkers=1 server/src/__tests__/document-annotations-service.test.ts server/src/__tests__/issue-thread-interaction-routes.test.ts server/src/__tests__/issues-goal-context-routes.test.ts` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/adapter-utils typecheck` - `pnpm --filter @paperclipai/server typecheck` - `git diff --check public-gh/master...HEAD` - GitHub PR checks are green on `36d0ac6a5dce27b9d62e201bf6d9829170c5974e`n- Rebased onto current `paperclipai/paperclip:master` and confirmed GitHub reports the PR as mergeable - Greptile Review completed successfully after 2 comments were addressed and resolved; 0 unresolved review threads remain ## Risks - Medium: wake payloads now include additional plan-review data, so limits and truncation behavior need to stay conservative as annotation volume grows. - Low migration risk: no database schema or migration changes. - Low repository hygiene risk: this PR does not touch `pnpm-lock.yaml`, `.github/workflows`, or media assets. > 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 using `gpt-5` as a coding agent with shell/tool execution. Reasoning mode and exact context window 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
765a75207a |
Add experimental server info debug view (#8676)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The dev/server UI exposes a `/api/health` endpoint and a lower-left
account drawer, but nothing surfaces *which* build the running instance
is on or when it last restarted
> - When iterating on a local dev instance it is hard to tell whether
the server you're looking at has actually restarted onto your latest
commit, or how stale the running process is
> - Developers need a lightweight, opt-in way to confirm the running
instance's identity without digging through logs or shelling into the
host
> - This pull request adds an experimental "Server Info Debug View"
setting that surfaces the running instance's last-restart time and
current commit as read-only rows in the account drawer
> - The benefit is a quick, in-UI sanity check of what the live server
is actually running, behind an experimental flag so it ships zero cost
to users who don't opt in
## Linked Issues or Issue Description
No public GitHub issue exists. Describing the underlying request inline
following the feature request template:
**Problem or motivation:**
When working against a local Paperclip dev instance there is no in-UI
way to confirm what the running server is — its current commit or when
it last restarted. You have to check logs or the host shell to know
whether the process picked up your latest build.
**Proposed solution:**
An opt-in experimental setting ("Server Info Debug View") that, once
enabled, renders a small read-only "Server" section at the bottom of the
lower-left account drawer showing **Last restarted** (the server process
start time) and **Running commit** (the current git HEAD short SHA +
subject).
**Alternatives considered:**
A separate top-right pill/overlay (like the work-life-balance plugin).
The account drawer was chosen to reuse existing menu-row styling and
avoid adding new always-present chrome.
**Roadmap alignment:**
Small, self-contained developer-experience aid gated behind an
experimental flag; does not overlap planned core roadmap work.
## What Changed
- Added `server/src/server-info.ts`: captures a `serverInfo` snapshot
once at boot — process start time and current git commit (SHA +
subject). Git is read via `execFileSync` with SHA validation and a
timeout.
- `/api/health` exposes the `serverInfo` snapshot, but only on
full-details health responses (board/agent in authenticated mode, or
local-trusted dev).
- Gated the UI surface behind a new `enableServerInfoDebugView`
experimental setting, wired through the shared instance type, validator,
settings normalizer, and OpenAPI schema.
- UI: added `SidebarServerInfo` rendering the read-only rows in the
account drawer (`BreadcrumbBar` / `SidebarAccountMenu`), plus the
experimental settings toggle and a typed `health` API client.
- Moved `ServerGitInfo` / `ServerInfoSnapshot` into
`@paperclipai/shared` so the server and UI share one definition instead
of duplicating it.
- Added unit tests for the server-info snapshot, health route exposure,
validator/normalizer, settings routes, the experimental settings page,
and the sidebar component.
## Verification
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/health.test.ts src/__tests__/server-info.test.ts
src/__tests__/instance-settings-service.test.ts
src/__tests__/instance-settings-routes.test.ts` — 32 passed
- `pnpm --filter @paperclipai/ui exec vitest run
src/components/SidebarServerInfo.test.tsx
src/pages/InstanceExperimentalSettings.test.tsx` — 9 passed
- `tsc --noEmit` on both `@paperclipai/server` and `@paperclipai/ui` —
clean
- Manual: enable **Settings → Experimental → Server Info Debug View**,
refresh the UI, open the lower-left account drawer — a "Server" section
shows Last restarted and Running commit.
## Risks
- Low risk. The UI surface is fully opt-in via an experimental flag and
defaults off.
- The `serverInfo` field on `/api/health` is access-controlled to
full-details responses only (board/agent in authenticated mode, or
local-trusted dev) — never anonymous authenticated callers — so the git
SHA is not broadly exposed.
- The only new server work is a one-time git read at boot, guarded with
SHA validation and a timeout; failures degrade gracefully (the git block
reports `available: false` rather than throwing).
## Model Used
Claude — `claude-opus-4` (Anthropic), extended thinking with tool use,
via Claude Code.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no
instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
|
||
|
|
fd2f82ac5b |
[codex] Add built-in Hermes adapters (#8543)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent adapters are the boundary between the control plane and the runtimes that actually do work. > - Hermes support needs to be available as first-class local and gateway adapters while still preserving the adapter-manager override path for external packages. > - The adapter work touches runtime execution, UI adapter metadata, onboarding prompts, scoped credentials, release packaging, and smoke coverage, so the handoff needs concrete verification rather than only unit tests. > - This pull request adds built-in Hermes local and Hermes gateway support, keeps external adapter overrides compatible, and documents/tests the gateway flow end to end. > - The benefit is that operators can hire Hermes-backed agents without a manual plugin install, while self-hosted installs can still override/shadow the built-ins through Adapter manager packages. ## Linked Issues or Issue Description No public GitHub issue exists for this exact Hermes built-in adapter, gateway onboarding, and release-source work. Problem description: - Hermes local and gateway adapters need a public, reviewable source path in the monorepo so package artifacts and built-in adapter behavior match the application source. - Operators need built-in `hermes_local` and `hermes_gateway` adapter choices without losing the ability to install external Hermes packages as overrides. - Gateway onboarding needs secure defaults for API server URLs, API keys, and generated agent setup text. - Hermes-originated task bridge credentials need narrower API-key scope configuration. - Related public PRs found during duplicate search include #3027, #2363, #7544, #7950, #8095, and #8543. ## What Changed - Added the unified Hermes adapter package with local and gateway server/UI/CLI exports, config schemas, transcript parsing, model detection, and package metadata. - Registered `hermes_local` and `hermes_gateway` as built-in adapters across shared constants, server registries, CLI packaging, and UI adapter registries. - Kept the external adapter override path compatible so installed Hermes packages can shadow built-ins and restore the built-in parser when disabled. - Added Hermes gateway onboarding docs, board-operator docs, Docker smoke assets, and shell smoke harnesses for join/e2e validation. - Added scoped task-bridge API-key support, authorization checks, issue-origin handling, and tests for Hermes-created Paperclip tasks. - Hardened gateway transport and redaction behavior for API keys, headers, session data, and smoke diagnostics. - Updated release packaging/bootstrap checks for the Hermes packages while leaving `pnpm-lock.yaml` out of the PR per repository policy. ## Verification Targeted local verification recorded before PR handoff: - `pnpm --filter @paperclipai/hermes-paperclip-adapter exec vitest run src/gateway/server/execute.test.ts` — 14/14 passed. - `pnpm test:hermes-gateway-smoke` — 6/6 passed. - Hermes package typecheck/build checks passed. - Focused server/UI adapter tests passed — 31/31. - Release helper Node tests passed — 18/18. - `git diff --check origin/master..HEAD` passed. Fresh Docker E2E smoke evidence: - Ran `pnpm smoke:hermes-gateway-e2e` on 2026-06-26 with a fresh state directory and fresh Docker container against a live Paperclip dev server. - Hermes direct execution reached `completed`. - Hermes stop/cancel path reached `cancelled`. - Hermes gateway created a Paperclip task, Paperclip ran the Hermes agent, and the task reached `done` with the expected marker response. - Temporary board auth keys, token files, smoke state, and Docker containers were cleaned up after the run. PR checks on head `b5eae40ce`: - GitHub Actions passed: `policy`, `review`, `Typecheck + Release Registry`, all general test shards, all serialized server shards, `Build`, `Canary Dry Run`, `e2e`, and aggregate `verify`. - External checks passed: Snyk and Socket Project Report. - External Socket Pull Request Alerts remained pending after the first-party CI matrix completed. ## Risks - Medium risk: this spans adapter registration, package publishing, gateway execution, onboarding docs, API-key scoping, and UI adapter metadata. - Migration risk is low: the scope-config migration adds a nullable column and does not rewrite existing keys. - Gateway execution depends on operator-provided Hermes API configuration; the smoke covers the Docker gateway path but real deployments may differ by network/auth setup. - Direct Greptile review on the latest expanded diff is file-count limited, although the commitperclip review gate passed. > 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 use enabled in a local repository workspace. Context window size is 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Commitperclip review gate is green; direct Greptile review is file-count limited on the latest expanded diff - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
43b005b704 |
Add pipeline workflow primitives and operator UI (#7903)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The pipeline subsystem models repeatable work as items moving through stages, with agent automation, review gates, blockers, drift notices, and linked work. > - Operators need this to be usable as one coherent workflow surface, not just as backend primitives or disconnected route experiments. > - The branch now carries the pipeline data model, service/routes, CLI/tutorial path, aggregation feeds, operator UI, stage automation controls, liveness/retry handling, and follow-up polish that make the primitive reviewable end to end. > - This pull request is the single review target for that pipeline workflow primitive stack. > - The benefit is that reviewers can evaluate the full operator experience and server contract together against `master`. ## Linked Issues or Issue Description No public GitHub issue exists for this work. The underlying feature request is described inline. ### Problem or motivation Paperclip needs a first-class way to model multi-stage agent/company workflows where upstream items can spawn downstream work, request review, carry fields across pipelines, surface drift, retry automation, and show operators where work is blocked or active. Without a unified pipeline primitive, these workflows spread across ad hoc issues, routines, and comments, making the state hard to inspect or operate. ### Proposed solution Add the pipeline workflow primitive stack: database schema and migrations, shared validators/types, server services and REST routes, aggregation and liveness helpers, CLI/tutorial smoke support, and the React operator UI for pipeline lists, boards, item detail, review/learnings views, settings, stage automation, secrets, carry-over fields, and retry/recovery flows. ### Alternatives considered - Keep workflows as loosely linked issues and routines: rejected because operators need a single board/detail/settings surface for repeated workflow patterns. - Ship backend primitives first and defer UI: rejected for this branch because the operator experience is the main way to validate the primitive. - Add a narrower one-off content workflow: rejected because the same primitives are useful across future company processes. ## What Changed - Added and evolved pipeline schema, migrations, shared contracts, server services, REST routes, route tests, and CLI/tutorial smoke support. - Added pipeline aggregation, health/liveness, drift acknowledgment, blocker/carry-over, automation retry, stage automation environment, and permission recovery behavior. - Added the operator UI for pipeline index/board/item detail/settings/review/learnings flows, including stage secrets, automation controls, markdown/item descriptions, linked issue assets, liveness banners, and source automation metadata. - Refactored issue document frame rendering through the shared `DocumentFrameHeader` component to keep document controls consistent with the pipeline document surfaces. - Kept this PR as the single base-branch review target for the current pipeline branch. ## Verification Current branch refresh: - `pnpm vitest run server/src/__tests__/pipelines-service.test.ts` — 31 passed - `pnpm vitest run server/src/__tests__/pipelines-routes.test.ts` — 19 passed - `pnpm --filter ./server typecheck` — passed - `pnpm --filter ./ui typecheck` — passed - Verified Pipelines remains gated by `enablePipelines === true`: sidebar item is hidden unless the flag is enabled, direct pipeline routes redirect to `/dashboard` when disabled, and the Experimental settings UI still has no Pipelines toggle. - GitHub status checks on `df071c710646de625131064c3fb6588b5e97964a` — all complete with no failing conclusions, including Actions, Socket, Superagent/Security, and Greptile Review - Greptile summary on `df071c710646de625131064c3fb6588b5e97964a` — Confidence Score 5/5 - GitHub review-thread sweep — 0 unresolved Greptile threads Previously recorded during branch development: - Server pipeline service/route and aggregation tests - Shared validator tests - UI pipeline page/settings/item-detail/learnings/liveness tests - Pipeline tutorial smoke path ## Risks - High review surface: this is a large feature branch spanning database, shared contracts, server behavior, CLI/docs, and UI. - Migration ordering and schema compatibility need reviewer attention because this branch has been kept current across multiple `master` syncs. - GitHub still reports merge state `BLOCKED` because the PR is awaiting normal human review/branch-protection completion; all current status checks are green. - Branch-name checklist exception: this PR uses the pre-existing requested branch name, which predates the current public-branch naming rule. The PR title/body avoid internal issue references. > 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 tool use, shell execution, git/GitHub CLI operations, and local verification commands. Earlier commits in this branch were assisted by Paperclip agents and other AI coding agents as recorded in commit authorship. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b3c0fadd63 |
feat(routines): add date variable controls (#8655)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Scheduled routines can prompt agents with variables that are filled in at dispatch time. > - Existing routine variable handling supported plain text-like values, but date inputs need a structured contract so routines can pass consistent date values. > - Operators also need date variables to be easy to configure and override from the routine UI. > - This pull request adds a date variable type across shared validation, server dispatch, and UI editing/run dialogs. > - The benefit is that routine authors can define date inputs once and agents receive validated ISO-style date values when routines run. ## Linked Issues or Issue Description Refs #219 Feature request: - Problem/motivation: Scheduled routines need first-class, typed date variables so operators can configure dates without relying on free-form text conventions. - Proposed solution: Add an `x-date` routine variable type with shared parsing/validation, server dispatch support, and UI date-picker controls in routine variable editors and run dialogs. - Alternatives considered: Continue treating dates as plain text, but that leaves validation and formatting to individual operators and agents. - Roadmap alignment: This is a focused improvement to the completed Scheduled Routines milestone and does not duplicate an active roadmap item. Related PR search: - Searched existing PRs/issues for `routine date picker`, `date variables`, and `scheduled routine date variable`; no direct duplicate PR was found. ## What Changed - Added the shared `x-date` routine variable contract, parsing, defaults, and validation coverage. - Extended routine dispatch to validate and pass date variable values. - Added date input controls to the routine variable editor and routine run variables dialog. - Added focused tests for shared validation, server dispatch, and the UI date controls. ## Verification - `git diff --check public/master...HEAD` - `pnpm run preflight:workspace-links && pnpm exec vitest run packages/shared/src/routine-variables.test.ts packages/shared/src/validators/routine.test.ts server/src/__tests__/routines-service.test.ts ui/src/components/RoutineRunVariablesDialog.test.tsx ui/src/components/RoutineVariablesEditor.test.tsx` - 5 test files passed - 68 tests passed ## Risks Low to medium risk. This adds a new routine variable type across shared/server/UI paths, so the main risk is compatibility with existing routine variable payloads. The change keeps existing variable types intact and adds targeted validation tests for the new date behavior. > 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 terminal, git, GitHub CLI, and local test execution capabilities. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8f7282066e |
Add workspace file downloads
Add first-class workspace file downloads, broader attachment content-type support, and the stream-lifetime limiter fix from PR review. |
||
|
|
569b7affc4 |
[codex] Add bounded workspace overview (#8627)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The execution workspace subsystem powers project and workspace views by listing runtime state, branch metadata, issue links, and status summaries. > - The existing workspace views relied on broad list data that can grow expensive as a company accumulates many workspaces and linked issues. > - That makes the Workspaces page and project workspace cards slower than necessary because the UI does not always need the full workspace detail payload up front. > - This pull request adds a bounded overview contract for workspace listings and moves the relevant UI surfaces to that cheaper path. > - The benefit is faster workspace loading while preserving detail fetches for pages that actually need full workspace data. ## Linked Issues or Issue Description No public GitHub issue exists for this change. Inline bug report follows the repository bug template. ### What happened? Workspace index-style screens can load too much execution workspace detail before the user asks for it. Several UI surfaces used fuller workspace data paths for summary displays, which can make workspace loading slower as workspace history grows. ### Expected behavior Overview screens should request a bounded summary payload, while detail screens should keep using the full workspace detail endpoint. ### Steps to reproduce 1. Run Paperclip from source with enough execution workspace history to make workspace lists non-trivial. 2. Open the Workspaces page or a project workspace summary card. 3. Observe that summary UI needs only bounded workspace metadata but can depend on broader workspace payloads. ### Paperclip version or commit `master` at the time this branch was prepared. ### Deployment mode Local dev (`pnpm dev`) ## What Changed - Added shared types, validators, and path constants for bounded execution workspace overviews. - Added server service and route support for overview queries with bounded linked issue/runtime metadata. - Updated workspace overview UI API calls, query keys, breadcrumbs, quicklooks, close dialogs, project summaries, and detail links to consume the cheaper overview shape where appropriate. - Added regression coverage for the new server route/service behavior and the UI overview consumers. - Registered the new workspace overview route in the generated OpenAPI spec. - Kept overview totals aligned with the project join and preserved project slug links in workspace headers. ## Verification - `pnpm exec vitest run server/src/__tests__/execution-workspaces-service.test.ts server/src/__tests__/execution-workspaces-routes.test.ts ui/src/api/execution-workspaces.test.ts ui/src/components/ProjectWorkspaceSummaryCard.test.tsx ui/src/pages/Workspaces.test.tsx` - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` - `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts server/src/__tests__/execution-workspaces-routes.test.ts server/src/__tests__/execution-workspaces-service.test.ts` - `pnpm test:run:serialized -- --shard-index 1 --shard-count 4` ## Risks Low to medium risk. The change introduces a new overview contract across shared/server/ui layers, so the main risk is a mismatch between summary and detail payload expectations. The added route/service/UI tests cover the intended split, and full detail pages continue using the detail path. > 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 with repository tool use and local command execution. Exact served model identifier and context window were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ed65d08d57 |
[codex] Gate skill mutations with skills:create permission (#8616)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents and board users operate inside a company-scoped control plane where permissions decide which mutating actions they can perform > - Company skills are part of the reusable agent-company setup surface, but skill mutation had been coupled to broader agent-creation authority > - That coupling meant importing or managing skills required a permission that also implies hiring power, which is broader than the operation needs > - Paperclip already has a grant-based permission vocabulary, so skill mutation should be authorized through a dedicated `skills:create` capability while preserving existing default behavior for trusted agents > - This pull request adds the skill creation permission contract, enforces it on company skill mutations, exposes it in agent permission management, and documents the changed CLI/API expectations > - The benefit is a narrower, auditable permission path for skill import/create/update/delete flows without forcing agents to receive broader agent-creation authority ## Linked Issues or Issue Description No public issue is linked. Problem: company skill mutation APIs were effectively tied to broader agent creation authority. This PR splits skill mutation authorization onto the public `skills:create` permission while keeping existing default skill creation behavior for agents unless explicitly disabled. Related public PR found during duplicate search: #5330. That PR uses an older `canManageSkills` shape; this PR implements the `skills:create` grant path instead. ## What Changed - Added `skills:create` to shared permission constants and agent permission types/validators as `canCreateSkills`. - Backfilled default human/member role grants for `skills:create`. - Updated company skill mutation routes to require board/user or agent access to `skills:create`, while preserving legacy/default agent behavior through `canCreateSkills` unless explicitly disabled. - Updated agent permission update handling, UI permission controls, duplicate-agent payloads, plugin SDK fixtures, and agent detail API surfaces for `canCreateSkills`. - Added regression coverage for skill route authorization, permission schema/default behavior, invite grants, omitted permission updates, and duplicate-agent payloads. - Updated CLI and Paperclip skill documentation for the new skill creation permission. ## Verification - `pnpm exec vitest run server/src/__tests__/agent-permissions-service.test.ts server/src/__tests__/agent-permissions-routes.test.ts server/src/__tests__/company-skills-routes.test.ts server/src/__tests__/invite-join-grants.test.ts ui/src/lib/duplicate-agent-payload.test.ts` — 5 files, 90 tests passed. - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm test:run ...changed files...` was attempted first, but the stable wrapper rejects explicit file arguments; direct Vitest was used for the same targeted files. ## Risks - Moderate authorization risk: this changes the gate for company skill mutations, so the tests cover board grant checks, agent explicit grant checks, legacy default allowance, and explicit denial. - Migration/backfill risk is low: the migration only grants `skills:create` to existing human roles that already need broad management capability. - UI/API compatibility risk is low: `canCreateSkills` remains default-on for full agent permissions, and the update validator preserves omitted values so unrelated permission edits do not re-enable disabled skill creation. > 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 terminal/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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a27e5ad002 |
Add ephemeral sandbox runtime status plumbing (#8593)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Sandboxed agent runs can spend meaningful time preparing a remote workspace before the agent transcript shows useful output. > - Operators need short, current progress text for those setup phases, but that text should not become durable run history. > - The existing live-run websocket path already carries run updates to the UI, so the backend can reuse that channel instead of adding polling. > - This pull request adds an ephemeral runtime-progress contract, a process-local status store, and heartbeat integration for sandbox-managed runs. > - The benefit is a clearer active-run experience without database migrations or persistent progress rows. ## Linked Issues or Issue Description Refs #248 No exact public GitHub issue was found for this status-message plumbing. The underlying problem is that active sandboxed runs currently have setup phases, such as workspace sync and restore, where the operator cannot see concise current progress through the live run state. This PR addresses that gap for the backend/runtime layer while keeping progress messages ephemeral. GitHub search performed for related or duplicate work: `sandbox runtime status`, `sandbox restore index`, and `runtime progress`. No direct duplicate PR was found. ## What Changed - Added shared runtime-progress types and the `heartbeat.run.progress` live event type. - Added a process-local heartbeat run runtime-status store with TTL, bounded/redacted messages, and terminal cleanup. - Threaded runtime progress callbacks through heartbeat execution and active/live run serialization. - Emitted sandbox-managed runtime phase updates for sync, adapter startup, restore/export, and finalization paths. - Added backend and adapter-utils tests for ephemeral status behavior, terminal cleanup, live serialization, and sandbox progress callbacks. ## Verification - `pnpm install --frozen-lockfile` - Local PII scan before push: high-confidence secret patterns, internal issue links, local user paths, and private URL patterns checked across all three split diffs; no real secrets or internal links found. The only secret-like text is an intentional fake test fixture (`sk-test-secret`). - `git diff --check origin/master..feat/sandbox-runtime-status` - `pnpm exec vitest run server/src/services/heartbeat-run-runtime-status.test.ts server/src/__tests__/heartbeat-runtime-state.test.ts server/src/__tests__/agent-live-run-routes.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts` — 4 files, 23 tests passed. - `pnpm run typecheck` passed on both top stacks that include this branch: `feat/sandbox-status-ui` and `fix/sandbox-restore-index-sync`. - `pnpm run build` passed on both top stacks that include this branch; Vite reported existing CSS `::highlight` and chunk-size warnings. - `pnpm run test:run` was attempted on `fix/sandbox-restore-index-sync`; it failed in two unrelated broad-suite tests. One depends on this host's Git default branch behavior, and one depends on local Claude model-discovery environment. The changed focused suites above pass. ## Risks - Runtime progress is process-local by design, so status disappears after TTL, terminal cleanup, or server restart. - Clients that do not consume `heartbeat.run.progress` simply keep existing behavior. - Message redaction is intentionally generic; overly specific phase details should stay out of runtime-progress payloads. > 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 via Codex coding agent, with shell/tool execution in a local worktree. Exact context-window metadata 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip CTO <cto@paperclip.local> Co-authored-by: Paperclip CTO <noreply@paperclip.ing> |
||
|
|
e68188c438 |
fix: upstream deployed document-comment, routine-annotation, workspace & board-polling fixes (#8536)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - This change touches several already-shipped subsystems — document-comment annotations, the selected-agent Conference Room chat surface, routine description annotations, workspace-operation tracking, and the board polling/inbox UI > - A batch of incremental fixes and two small backend additions had accumulated on a local mainline and were deployed to a live instance, but never landed upstream — so each `origin/master` sync kept re-diverging > - Leaving them un-upstreamed means the same delta has to be re-merged on every sync and risks being lost or silently reverted > - This pull request rebases that delta cleanly on top of current `origin/master` (preserving recent upstream work such as reusable sandbox leases and the relation-list collapse controls) and brings it up for review > - The benefit is that mainline and the deployed instance converge, and these fixes/additions get normal review + CI + Greptile coverage ## Linked Issues or Issue Description No single GitHub issue tracks this; it is a bundle of bug fixes and two small feature additions. Following the issue-template fields: **Bug fixes (what was wrong → what this does):** - Document comments rendered out of document order, didn't live-update across clients, swallowed save failures, and lost the markdown text selection on re-render. Now: doc-order sort, live updates, surfaced save-failure state, stable selection across re-renders. - The board polling hot path returned oversized payloads on every poll. Now: an opt-in `summary` projection trims the heartbeat-run list payload. - Assorted UI fixes: sidebar nav peek/streamlining edge cases, markdown file-viewer re-mount/line-height issues on iOS Safari, inbox badge/skill deep-link tab selection, and `⌘.` work-mode cycling on iOS. **Feature additions:** - `workspace_operations.issue_id` — associate a workspace operation with the issue that triggered it (new migration `0106`, schema, service, shared type). - Routine **description annotations** — comment threads on a routine's description document, mirroring issue document annotations (new migration `0107`, `routine_documents` schema, routes/service, editable-sections UI). - Selected-agent **Conference Room chat** surface wiring and live issue-thread updates. **Related PR:** #8229 (`feat(control-plane): add annotation and workspace controls`, draft) covers overlapping annotation/workspace-control territory — flagging it so a reviewer can reconcile the two rather than double-merging. ## What Changed - `feat(workspace)`: `workspace_operations.issue_id` migration + schema/service/type; issue workspace property controls reconciled with upstream's evolved "Service" row. - `feat(routines)`: routine description annotations — `routine_documents` schema, migration `0107`, routes/service, `editable-sections` UI. - `fix(document-comments)`: doc-order sort, live updates, save-failure surfacing, stable markdown selection (+ storybook story, rerender test). - `feat(chat)`: selected-agent Conference Room chat surface and live issue-thread updates (`LiveUpdatesProvider`, `issue-chat-messages`, interactions service). - `perf(board)`: opt-in `summary` projection for the board polling/heartbeat-run list payload, plus assorted sidebar / file-viewer / inbox / IssueProperties UI fixes. Organized into 5 logical commits. Migrations are numbered incrementally after upstream's latest (`0105`) — `0106` then `0107`, no journal collision. ## Verification - Built by 3-way merging the deployed delta onto current `origin/master`; the only merge conflict (`IssueProperties.test.tsx`, two adjacent test blocks) was resolved in favor of upstream's evolved "green service link above the workspace row" layout, which matches the merged component's rendered output. - Confirmed recent upstream work is preserved post-merge: reusable sandbox lease teardown (`#8513`), the IssueProperties relation-list collapse controls, and the sidebar streamlined-nav default. - Confirmed the net diff vs `origin/master` is exactly the intended feature delta (65 files) and that overlapping server files (`issues.ts`, `agents.ts`, `heartbeat.ts`) only add feature code without disturbing upstream logic. - This delta is already running on a live deployed instance. - Full typecheck/test suite + Greptile to run in CI (see checklist). ## Risks - Two new migrations (`0106`, `0107`). Both are additive (new table / new nullable column) and ordered after upstream's `0105`; no data backfill, low risk. If another migration-bearing PR merges first, renumber before merge. - Largest blast radius is in the merged overlapping UI/service files; covered by the existing test suites for those files plus CI. - Overlaps thematically with draft PR #8229 — reviewers should reconcile rather than merge both blindly. ## Model Used Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, with tool use (git, shell). Agentic coding 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2dbaf4a7fa |
External object references across issue surfaces (#8512)
## Thinking Path > - Paperclip is the open source control plane people use to coordinate AI agents, issues, approvals, comments, and work products. > - The involved subsystem is issue context: markdown links, issue properties, related work, lists, filters, inbox/sidebar status, and plugin-provided external context. > - The gap is that URLs to external systems currently remain mostly plain links, so humans and agents must manually open them to understand status, identity, and liveness. > - This matters because external work objects such as GitHub issues and pull requests are part of the operational state of a Paperclip company. > - The implementation keeps core provider-neutral: shared contracts, storage, sync, routes, and UI surfaces live in core while providers can contribute detection and status resolution. > - This pull request adds the external object reference foundation, GitHub provider support, issue-surface rendering, filters, sidebar/list/inbox signals, and test/story coverage. > - The benefit is that linked external work becomes inspectable Paperclip context without hardcoding every provider directly into the UI. ## Linked Issues or Issue Description No public GitHub issue exists for this work. Feature request: - Problem: URLs in Paperclip issues, comments, documents, and related surfaces do not expose provider status or object identity inline. - Proposed behavior: detect supported external object URLs, persist normalized references, refresh provider status, and render concise status-aware links across issue surfaces. - Users affected: board users, agents, and maintainers who triage issues containing external work links. - Acceptance: external object references are company-scoped, provider-extensible, visible in key issue surfaces, filterable where relevant, and covered by focused shared/server/UI tests. Related PR search: - No open duplicate PRs found for `external object references`. - Closed related prior attempt: #4556. ## What Changed - Added shared external-object contracts, validators, status/liveness helpers, and plugin protocol declarations. - Added database schema and additive migrations for external objects, source mentions, and display metadata. - Added server services/routes for detecting, syncing, summarizing, refreshing, and resolving external objects across issues, documents, comments, projects, and plugins. - Added a GitHub external-object provider plus plugin SDK authoring docs. - Wired UI presentation across markdown links, comments, issue chat, documents, properties, related work, issue rows, filters, inbox/sidebar badges, and Storybook stories. - Rebasing cleanup: moved the branch onto current `master`, repaired stale worktree provision config, hardened environment-sensitive tests/mocks, and removed committed screenshot artifacts from the PR branch to keep the reviewable file set below tool limits. ## Verification - `pnpm exec vitest run packages/shared/src/external-objects.test.ts server/src/__tests__/external-object-routes.test.ts server/src/__tests__/external-objects-service.test.ts ui/src/components/ExternalObjectPill.test.tsx ui/src/lib/external-objects.test.ts` passed after rebasing: 5 files, 56 tests. - Historical branch verification before this PR creation included `pnpm test:run`, `pnpm -r typecheck`, and `pnpm build`; this PR body does not claim those were rerun after the final rebase. ## Risks - Medium: this adds a new cross-surface sync path on issue/document/comment writes. The implementation uses safe sync wrappers so external-object failures warn instead of blocking core mutations. - Medium: the migrations introduce new tables and indexes. They are additive and company-scoped. - Medium: provider-specific URL parsing can miss or misclassify edge cases. Shared canonicalization tests and provider tests cover current GitHub shapes. - Low: UI badge/filter behavior could add visual noise for object-heavy issues; component tests and Storybook stories cover the intended surfaces. > Roadmap checked: `ROADMAP.md` references the plugin system as the current extension path and does not list a duplicate core feature. Related long-range docs discuss external references, work products, preview URLs, and plugin extension points; this PR implements the scoped external-object reference foundation. ## Model Used OpenAI Codex, GPT-5 coding-agent runtime, with shell and GitHub CLI tool use. Reasoning mode: medium. Exact deployed runtime model ID and context window were not exposed in the 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
cd38c150b0 |
feat: reuse Daytona sandbox leases (#8513)
Add opt-in reusable Daytona sandbox lease support, including retryable pending cleanup handling.\n\nPR: https://github.com/paperclipai/paperclip/pull/8513 |
||
|
|
0b945f449b |
Make streamlined sidebar default to on (#8496)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI has an experimental streamlined left navigation mode that changes how projects and agents appear in the sidebar. > - Today that mode is opt-in, so users keep seeing the classic navigation unless they find and enable the experiment. > - The requested product behavior is to make streamlined navigation the default experience while keeping an explicit experiments opt-out. > - This pull request flips the shared/server default, updates UI consumers to treat only explicit `false` as classic mode, and covers both the default-on path and opt-out behavior in tests. > - The benefit is that new and legacy settings get the streamlined sidebar by default without removing the classic-sidebar escape hatch. ## Linked Issues or Issue Description Refs #7645 Related: #8430 takes the broader route of removing the classic sidebar. This PR intentionally keeps the opt-out path. ## What Changed - Default `enableStreamlinedLeftNavigation` to `true` in shared validation and server-side normalization. - Preserve explicit stored `false` as the experiments opt-out for the classic sidebar. - Render the sidebar and experimental settings toggle as streamlined-on unless the setting is explicitly `false`. - Add regression coverage for loading/default streamlined sidebar behavior and the opt-out patch from the experiments page. - Remove internal issue identifiers from newly touched source comments before publishing. ## Verification - `git diff --check origin/master...HEAD` — passed. - `pnpm -r typecheck` — passed. - `pnpm exec vitest run server/src/__tests__/instance-settings-service.test.ts ui/src/components/Sidebar.test.tsx ui/src/pages/InstanceExperimentalSettings.test.tsx` — passed, 3 files / 27 tests. - `pnpm build` — passed, with existing Vite/CSS/chunk-size warnings. - `pnpm test:run` — failed in unrelated `server/src/__tests__/workspace-runtime.test.ts`: the test `auto-detects the default branch via symbolic-ref when origin/HEAD is set` creates a temp repo on `main` then runs `git push -u origin main master`; `master` does not exist in that temp repo. Summary: 1 failed, 214 passed, 1780 tests passed, 1 skipped. ## Risks Low-to-medium behavioral risk: the default sidebar changes for users who never explicitly set the experiment. Explicit `false` remains respected, so users can still opt out via experimental settings. > 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 via Codex local adapter, with tool use and code execution. Exact context window was not surfaced in 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
33353ce62b |
feat(skills): remove bundled paperclip-dev skill and retire required skill attribute (#7029)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Local adapters (Claude, Codex, Cursor, Gemini, Grok, OpenCode, Pi, ACPX) ship bundled "skills" — opinionated Markdown prompt bundles materialized into the agent's runtime > - One of those bundled skills, `paperclip-dev`, existed to let agents develop Paperclip itself; it has now moved to its own external repo and no longer belongs in the core tree > - The adapter skill model also carried a `required` / `requiredReason` attribute plus a `paperclip_required` `AdapterSkillOrigin` variant, all of which only existed to mark bundled skills as non-optional in the UI and adapter sync logic > - With `paperclip-dev` gone, no bundled skill is "required" anymore, and the type / runtime surface for `required` is dead weight — but it is computed at request time and never persisted, so a clean removal is safe (no compatibility shim needed) > - This pull request deletes `skills/paperclip-dev/` and removes every trace of the `required` / `requiredReason` field and the `paperclip_required` origin across shared types, validators, adapter-utils, all eight local adapters, server routes, the company-skills service, the UI, the storybook fixtures, and the test suite > - The benefit is a smaller, simpler adapter-skill surface: one origin (`company_managed`) for managed bundled skills, `resolvePaperclipDesiredSkillNames` collapses to "just the configured desired set", and the AgentDetail skills tab no longer renders a "Required by Paperclip" section that no longer applies ## Linked Issues or Issue Description <!-- No existing public GitHub issue; describing the underlying work inline (feature_request template fields). --> **Summary** Remove the bundled `paperclip-dev` skill (now maintained in its own external repo) and retire the `required` / `requiredReason` skill attribute and the `paperclip_required` skill origin, which only existed to support it. **Problem or motivation** `paperclip-dev` is the only bundled skill that was ever marked "required". Now that it lives in a separate repository, shipping it inside the core tree is wrong, and the entire `required` surface (a type field, a validator field, a synthesized `paperclip_required` origin, UI "Required by Paperclip" section, and required-skill merging in the desired-skills calculation) becomes dead weight. The `required` value is computed at request time and never persisted, so it can be removed cleanly without a migration or compatibility shim. **Proposed solution** Delete `skills/paperclip-dev/`, drop the `required` / `requiredReason` fields and `paperclip_required` origin everywhere they are produced or consumed, collapse managed-skill origin to a single `company_managed` value, and simplify `resolvePaperclipDesiredSkillNames` to return only the configured desired set. **Alternatives considered** Keeping the `required` attribute as a no-op for forward compatibility — rejected because it is request-time only (nothing persists it), so leaving it in place is pure dead surface area with no callers. **Roadmap alignment** Internal cleanup / dead-code removal that simplifies the adapter-skill surface; it does not introduce or duplicate any planned core feature in ROADMAP.md. ## What Changed - Deleted bundled `skills/paperclip-dev/` (moved to a separate repo). - Dropped `required`, `requiredReason`, and the `paperclip_required` origin from `packages/shared/src/types/adapter-skills.ts`, `packages/shared/src/validators/adapter-skills.ts`, and `packages/adapter-utils/src/types.ts`. - In `packages/adapter-utils/src/server-utils.ts`: removed `readSkillRequired()`; dropped `required`/`requiredReason` from `listPaperclipSkillEntries()`, `normalizeConfiguredPaperclipRuntimeSkills()`, `buildPersistentSkillSnapshot()`, and `PaperclipSkillEntry`; collapsed `buildManagedSkillOrigin()` to always return `company_managed`; simplified `resolvePaperclipDesiredSkillNames()` to return only the configured desired set (signature preserved so adapter call sites are untouched). - Walked all eight local adapters (`acpx-local`, `claude-local`, `codex-local`, `cursor-local`, `gemini-local`, `grok-local`, `opencode-local`, `pi-local`) and removed every remaining `requiredReason` / `paperclip_required` reference. - `server/src/services/company-skills.ts`: dropped the `required = sourceKind === "paperclip_bundled"` synthesis when listing runtime skill entries. - `server/src/routes/agents.ts`: removed required-skill merging from the desired-skills calculation in the persist-config path and the unsupported-snapshot path (keeping the current version-aware `desiredSkillEntries` structure). - `ui/src/pages/AgentDetail.tsx`: dropped required-based filters, the required tooltip, and the entire "Required by Paperclip" section from the agent skills tab; storybook fixtures in `ui/storybook/stories/acpx-local.stories.tsx` cleaned up to match. - Tests: deleted the `required: false` case in `paperclip-skill-utils.test.ts` and the "keeps required bundled skills installed" case in every `*-local-skill-sync.test.ts`; `acpx-local-execute.test.ts`, `cursor-local-execute.test.ts`, `cursor-local-skill-sync.test.ts`, `agent-skills-routes.test.ts`, and `packages/adapter-utils/src/server-utils.test.ts` were updated to drop removed fields and map `origin: "paperclip_required"` → `"company_managed"`. - `server/src/adapters/registry.ts`: two `as unknown as ServerAdapterModule["..."]` casts on `hermesListSkills` / `hermesSyncSkills` (matching the existing `executeHermesLocal` pattern). `hermes-paperclip-adapter@0.2.0` still depends on the published `@paperclipai/adapter-utils` which keeps the retired `paperclip_required` variant; the cast bridges the workspace-vs-published type mismatch at the registry seam and can drop once hermes upgrades. ## Verification Run from the workspace root: ```sh grep -rn "skills/paperclip-dev" . grep -rn "paperclip_required" --include="*.ts" --include="*.tsx" . grep -rn "requiredReason" --include="*.ts" --include="*.tsx" . pnpm -w typecheck pnpm --filter @paperclipai/server exec vitest run paperclip-skill-utils pnpm --filter @paperclipai/server exec vitest run skill-sync ``` The first three greps return only the explanatory comment in `server/src/adapters/registry.ts` (no live `paperclip_required` / `requiredReason` usage) and zero `skills/paperclip-dev` source hits. Locally: - `pnpm -w typecheck` → all packages this PR touches pass (adapter-utils, shared, server, ui, cli, and the cursor/gemini/opencode/pi adapters). - Affected vitest suites pass: `paperclip-skill-utils`, `server-utils`, all eight `*-local-skill-sync`, `agent-skills-routes`, and the `acpx`/`cursor`/`pi` execute suites. ## Risks - Behavioral shift in the agent skills UI: the "Required by Paperclip" section disappears. No bundled skill is required anymore, so this only affects environments that previously surfaced `paperclip-dev` as a forced-on row; those installs will see the skill move into the regular "company-managed" list (and be uninstalled on next sync unless explicitly listed as desired). - Existing agents may still have the string `"paperclip-dev"` in their persisted `desiredSkills`. That entry is inert (no source for it to install from); a one-time DB cleanup is out of scope. Low risk. - Hermes adapter type bridge: two casts in `registry.ts` paper over a type-only divergence between the workspace `@paperclipai/adapter-utils` and the published version still pinned by `hermes-paperclip-adapter@0.2.0`. Runtime behavior is unaffected because the retired `paperclip_required` value is no longer produced by anything in this tree. The casts can be removed once hermes upgrades its dependency. ## Model Used - Provider: Anthropic - Model: Claude Opus 4.7 (`claude-opus-4-7`) - Capability: agent tool use via Paperclip's `claude_local` adapter ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
547463d3a2 |
refactor(environments): make execution environments instance-scoped (#8375)
## Thinking Path > - Paperclip is the control plane for AI-agent companies, so execution environment selection has to stay inspectable and predictable across companies, agents, and runs. > - The environment subsystem decides where an agent heartbeat actually runs and how remote sandbox state is realized and restored. > - That subsystem previously mixed company-scoped environment catalogs with issue-level environment stamping, so a reassigned issue could keep executing in the previous assignee's sandbox. > - That behavior breaks the control-plane contract: changing the assignee should change the executing agent/environment path unless there is an explicit current override. > - Fixing it cleanly required more than a narrow patch; the environment model had to move to instance scope with a single inherited default and per-agent override semantics. > - This pull request rewires the schema, server/API surface, runtime resolution, and UI around that model, then adds regression coverage for cross-company inheritance and per-agent isolation. > - The benefit is that environment choice now follows the approved instance/agent configuration path instead of stale issue state, while shared environments only need to be configured once per instance. ## Linked Issues or Issue Description - No directly matching public GitHub issue or PR was found while searching for this refactor. ### What happened? Reassigning work between agents with different execution environments could keep running in the previous sandbox because environment choice was stamped onto the issue and outranked the current assignee. The same subsystem also forced environment catalogs to be duplicated per company even though the underlying execution environments were instance-wide resources. ### Expected behavior Execution should resolve through the current instance and agent configuration path, with one instance-scoped environment catalog, one instance default, optional per-agent override, and no stale issue-level environment authority surviving reassignment. ### Steps to reproduce 1. Configure two agents to use different execution environments. 2. Assign an issue to the first agent so the issue records execution state in that environment. 3. Reassign the same issue to the second agent and run another heartbeat. 4. Observe that the pre-fix runtime can still sync or execute in the original sandbox instead of the second agent's environment. ### Paperclip version or commit Current `master` before this PR. ### Deployment mode Self-hosted server. ### Installation method Built from source (`pnpm dev` / `pnpm build`). ### Agent adapter(s) involved - Claude Code - Not adapter-specific (core bug in environment authority / resolution) ### Database mode External Postgres. ### Access context Both board reassignment and agent heartbeats were involved. ## What Changed - Moved environments and their default selection contract to instance scope in DB/shared types, including the migration that dedupes legacy per-company environments and seeds the instance local default. - Reworked environment CRUD/auth flows to use instance-scoped APIs and added route/service coverage for instance-level environment management. - Changed runtime resolution to prefer `agent default -> instance default -> built-in local`, removed issue-level environment stamping from the active execution path, and isolated sandbox/plugin leases by `(executionWorkspaceId, agentId)`. - Added environment env-var runtime precedence so environment-provided values act as the baseline for agent execution. - Moved the environment UI into instance settings and updated agent configuration surfaces to reflect inherit/override behavior. - Added regression coverage for instance-default inheritance across companies and for the new runtime resolution behavior. - Fixed a rebase-only duplicate `enableTaskWatchdogs` flag regression in instance settings types/validators/services so the branch typechecks cleanly on current `master`. - Updated stale server tests so CI matches the shipped instance-scoped environment contract. ## Verification - `git diff --check` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/db typecheck` - `pnpm exec vitest run server/src/__tests__/environment-runtime-driver-contract.test.ts server/src/__tests__/agent-permissions-routes.test.ts server/src/__tests__/environment-routes.test.ts server/src/__tests__/environment-instance-routes.test.ts server/src/__tests__/execution-workspace-policy.test.ts server/src/__tests__/heartbeat-plugin-environment.test.ts server/src/__tests__/instance-settings-routes.test.ts` ## Risks - The migration changes environment scope and dedupes existing rows, so installs with unusual legacy environment combinations should be reviewed carefully during upgrade. - Remote execution behavior now depends on instance-default inheritance semantics instead of issue-level stamping, so any remaining code paths that still assume issue-scoped environment authority would surface as follow-up bugs. - This PR includes both server/runtime behavior and UI relocation, so reviewers should watch for authorization edge cases around instance settings and environment management. > I checked [`ROADMAP.md`](ROADMAP.md). This work fits the existing Cloud / Sandbox agents direction as a bug-fix/refactor to current behavior, not a new parallel product surface. ## Model Used - OpenAI Codex coding agent in this Paperclip/Codex session; GPT-5-class tool-using model with code execution and shell access. The exact backend model ID is not exposed to the session runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] 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 |
||
|
|
a71c4b6782 |
[codex] feat(watchdog): add task watchdog control plane (#8339)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The task lifecycle and recovery subsystems decide when agent work is still productive, stalled, or ready for review. > - Existing recovery paths can observe stopped or incomplete work, but there was no first-class per-task watchdog model with scoped review permissions. > - Watchdog follow-ups also need strict boundaries so recovery/status-only runs cannot mutate approvals or perform deliverable work. > - This pull request adds the task watchdog data model, API/service layer, scheduler/review flow, adapter wake context, UI configuration surfaces, and docs. > - The branch has been rebased onto current `paperclipai/paperclip` `master`; the watchdog migration is now ordered after master's latest migrations as `0104_issue_watchdogs`. > - The benefit is a more explicit task-review loop that preserves Paperclip's single-assignee and governance invariants while making stalled work easier to route. ## Linked Issues or Issue Description No linked GitHub issue. Paperclip task: [PAP-11275](/PAP/issues/PAP-11275). ## Problem or motivation Task recovery needs a first-class watchdog path that can inspect stopped work and create scoped follow-ups without bypassing normal task ownership. Board/UI users need a way to configure watchdogs on tasks and see watchdog-related live work. Recovery/status-only runs must remain limited to status reporting and must not create approvals, link approvals, or submit approval comments. ## Proposed solution Add a task-watchdog data model, scheduler/classifier, scoped mutation guard, adapter wake context, API/UI configuration surfaces, and documentation so watchdog agents can review stopped task subtrees under explicit boundaries. ## Alternatives considered Reuse the existing recovery-action flow only. That would keep stopped-work detection implicit, make per-task watchdog assignment harder to expose in the UI, and would not provide a durable scoped-review issue for stalled task trees. ## Roadmap alignment This is Paperclip control-plane lifecycle infrastructure for task execution and recovery. I checked `ROADMAP.md`; this PR does not duplicate an existing planned core item. ## What Changed - Added issue watchdog schema, migration, shared contracts, validators, CRUD API, and service support. - Added task watchdog scheduler/classifier behavior, scoped mutation enforcement, adapter wake context, and default watchdog mandate guidance. - Added UI surfaces for configuring watchdogs on new/existing tasks, viewing watchdog activity, and exposing the experimental setting. - Added docs for the user-facing task watchdog workflow and implementation semantics. - Gated new-task watchdog setup behind `enableTaskWatchdogs` and blocked cheap status-only recovery runs from approval mutations. - Rebased onto current `master` and renumbered the idempotent watchdog migration from the branch-local `0102_issue_watchdogs` slot to `0104_issue_watchdogs`. - Addressed Greptile feedback by loading watchdog classifier input with a recursive subtree query and centralizing the watchdog origin-kind constant. - Added and updated focused server/UI tests for watchdog routes, scheduler/classifier behavior, scope boundaries, live task visibility, settings, and new issue dialog behavior. ## Verification - `pnpm vitest run server/src/__tests__/task-watchdogs-scheduler.test.ts server/src/__tests__/task-watchdogs-classifier.test.ts` - `pnpm vitest run server/src/__tests__/approval-routes-idempotency.test.ts server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts` - `pnpm vitest run ui/src/components/NewIssueDialog.test.tsx` - `pnpm --filter @paperclipai/server typecheck` - `git diff --check` - Verified the PR diff does not include `pnpm-lock.yaml` or `.github/workflows`. ## Risks - Medium risk: this introduces a new task lifecycle surface touching DB schema, server routes/services, adapter wake context, and UI task configuration. - Watchdog scheduling behavior depends on the new experimental setting and runtime context checks behaving consistently across local and production agents. - The watchdog migration is idempotent (`IF NOT EXISTS` / duplicate-object guards) so users who tried the previous branch-local migration number should not get duplicate-object failures. - CI and the second Greptile pass are pending after the latest review-fix push. > 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-class coding agent in the Paperclip workspace. Exact runtime model id and context window were not exposed to the agent; tool use and local command execution were 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 per Paperclip task instruction: do not add screenshots/images to this PR unless they are specifically part of the work. - [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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
7069053a1f |
[codex] Add ask issue work mode (#8334)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue work mode controls how a task starts and how the conversation composer frames the operator's intent. > - Paperclip already supports standard agent execution and planning mode, but there is no lightweight mode for asking a question without immediately implying execution or plan drafting. > - That gap makes low-commitment clarification workflows look like normal task execution. > - This pull request adds an explicit Ask mode and threads it through shared contracts, server heartbeat context, and the issue composer UI. > - The benefit is that operators can create or switch a task into a question-oriented mode while preserving existing agent and planning flows. ## Linked Issues or Issue Description No public GitHub issue exists for this change. Inline feature request follows the repository feature request template. ### Subsystem affected Cross-cutting: `packages/shared`, `server/`, and `ui/`. ### Problem or motivation Issue conversations currently distinguish standard agent work from planning work, but question-first conversations do not have a clear public mode in the shared contract or UI. Operators who want to ask an agent a focused question have to use standard mode, which can imply normal task execution, or planning mode, which asks for a plan rather than an answer. ### Proposed solution Add Ask as a first-class issue work mode. It should be selectable from issue creation and issue chat, cycle alongside Standard and Planning from the keyboard shortcut/menu, appear distinctly in composer styling, and be included in heartbeat context so agents know to answer directly instead of executing or drafting a plan. ### Alternatives considered - Keep using standard mode for questions: rejected because it does not communicate answer-only intent to the agent or the UI. - Reuse planning mode for questions: rejected because planning mode asks for a plan and is semantically different from asking a question. - Add only local UI copy: rejected because the mode needs to be represented in the shared contract and server heartbeat context to be reliable. ### Roadmap alignment This is a focused issue-workflow improvement. `ROADMAP.md` was checked and no duplicate planned core work was found. ### Additional context Related public searches performed before opening this PR: - GitHub PR search for `"ask mode" repo:paperclipai/paperclip` - GitHub issue search for `"ask mode" repo:paperclipai/paperclip` - GitHub PR search for `"work mode" "ask" repo:paperclipai/paperclip` No duplicate PR was found. ## What Changed - Added `ask` to the shared issue work-mode contract and validation coverage. - Included issue work mode in heartbeat context summaries so agents can see standard, planning, and ask state. - Added Ask mode metadata, styling, composer tone handling, and selection/cycling behavior in the issue chat/new issue UI. - Updated focused tests for shared validators, heartbeat context, and affected UI work-mode flows. ## Verification - `NODE_ENV=test pnpm exec vitest run ui/src/components/ChatComposer.test.tsx ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/lib/work-mode-meta.test.ts` - `NODE_ENV=test pnpm exec vitest run packages/shared/src/validators/issue.test.ts server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issues-service.test.ts ui/src/components/ChatComposer.test.tsx ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/lib/work-mode-meta.test.ts ui/src/pages/IssueDetail.test.tsx` The broader targeted command passed 8 test files / 245 tests. Visual reference for Standard/Planning/Ask composer states: https://gist.github.com/cryppadotta/714d8590bac55500a65e7e16de5bb4b8 It emitted an expected warning from an existing server test fixture about a missing run-log fixture while verifying derived issue comment metadata. ## Risks Low to moderate risk. This adds a new enum value that crosses shared, server, and UI contracts. Existing standard and planning modes are preserved, but any downstream code assuming only two non-terminal work modes may need to handle `ask`. > 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 coding agent in Paperclip CodexCoder mode, with shell, git, GitHub connector, and local test execution tools. Context window and exact hosted model snapshot are 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 not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`, `feat/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] 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> |
||
|
|
fc95699fde |
fix(server): enforce agent secret binding sync across lifecycle flows (#8307)
## Thinking Path > - Paperclip is the control plane people use to create, configure, and run AI agents for work. > - This change sits in the server-side agent lifecycle and secret-binding subsystem, where adapter config `env` entries can reference company secrets. > - An incident (while trying to configure a Novita sandbox) showed that an agent can reach a broken runtime state if `adapterConfig.env` contains `secret_ref` entries but the matching `company_secret_bindings` rows are missing. > - The immediate run-path guard and error-surfacing work made the failure diagnosable, but they did not fully prevent new broken agents from being created. > - The risk came from create and approval flows being responsible for remembering to sync bindings at each call site, which is easy to miss as new flows are added. > - This pull request moves the invariant into `agentService` create/update/activate paths, keeps the existing hire-flow fix, and adds regression coverage for create, update, and legacy pending-approval recovery. > - The benefit is that agent secret binding integrity is enforced closer to the data mutation point, so future callers inherit the protection automatically. ## Linked Issues or Issue Description Refs #8309 ### What happened? A Paperclip agent could persist `adapterConfig.env` `secret_ref` entries without matching agent-scoped `company_secret_bindings` rows. When that happened, the config UI could still look configured, but the real run path failed pre-dispatch because the secret was not actually bound to that agent. ### Expected behavior Every normal agent create, config-update, and pending-approval activation flow should leave the agent with secret bindings that match its persisted secret-ref env config. ### Steps to reproduce 1. Create or activate an agent through a flow that persists `adapterConfig.env` secret refs without synchronizing `company_secret_bindings`. 2. Observe that the config state can still appear populated. 3. Start a run for that agent. 4. Observe that pre-dispatch binding validation fails because the secret reference exists but the agent binding does not. ### Deployment mode Local dev (`pnpm dev`) ### Installation method Built from source (`pnpm dev` / `pnpm build`) ### Agent adapter(s) involved - Claude Code - Not adapter-specific (core bug) ### Database mode Embedded PGlite / embedded local dev database flow ### Access context Board (human operator) created or approved the agent; agent runtime later consumed the config. ### Additional context This PR focuses on preventing new broken states from normal service flows and on backfilling the covered legacy pending-approval activation path. ## What Changed - Kept the existing branch-local hire-flow fix that synchronized bindings for route and approval paths. - Moved the binding integrity invariant into `agentService.create()`, `agentService.update()` when `adapterConfig` changes, and `agentService.activatePendingApproval()`. - Added `server/src/__tests__/agents-service-secret-bindings.test.ts` covering create-time sync, update-time resync, and backfill for legacy pending-approval agents. - Removed now-redundant route-layer and approval-layer binding sync calls once the service layer became authoritative. - Simplified the affected unit tests so route/approval tests no longer assert service-owned binding writes directly. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm exec vitest run server/src/__tests__/agents-service-secret-bindings.test.ts server/src/__tests__/approvals-service.test.ts server/src/__tests__/agent-skills-routes.test.ts` ## Risks - Low to medium risk. - This changes where secret-binding synchronization is enforced, so any unexpected caller that relied on upper-layer manual sync behavior could behave differently. - Agent create/update/activation flows now perform binding synchronization consistently, which adds binding-table writes at those mutation points. - This PR does not retroactively scan and heal every already-broken historical agent row; it prevents and backfills through the covered service flows. > 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 Codex class model via `codex_local` - Session model family: GPT-5 Codex - Tool-assisted coding with shell, git, HTTP, and local test execution - Reasoning mode: medium interactive tool-use 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 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> |