mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 04:02:18 +01:00
3536b3649f98155d92b45cfb5dc3abcc2fea97d6
14
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bd77ffe78d |
perf(connections): scope profile rule and binding reads (#17589)
Read current company/agent profile bindings and rules matching the exact catalog rows being evaluated. Preserve all five selector kinds, null application matches, exclusions, and the existing access evaluator without a cross-call cache. Verified with full build and typecheck, 652 affected tests across ten suites, all 18 strengthened effective-assignment tests, exclusion mutation and byte counterfactuals, complete exact-head CI, and Greptile 5/5 Medium with no unresolved comments. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2f637fe8c4 |
perf(tools): scope connection readiness assignment reads (#17541)
Connection readiness reads current permitted connection identities without unrelated catalog rows or complete profile-rule payloads. Reuse profile precedence and selector logic, preserve full public/runtime summaries, and keep installed connections, identity checks, and gateway authorization current. Verified with 106 focused tests, the full build, and typecheck. The direct catalog inventory regression fails at 102 rows when the scope filter is removed and passes at two rows with the filter. One unrelated CI timing assertion differed by 1 ms; the exact local test and the single failed shard rerun passed on unchanged source. CI is green and exact-head Greptile is 5/5 at Medium impact with no unresolved comments. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
9c442cf48e |
feat(connections): deploy and configure Supabase and Vercel (#17217)
Add governed Supabase and Vercel deployment/configuration connectors with vaulted credentials, agent access policies, approvals, audit, and bounded provider operations. Deliver reviewed REST actions to native agents and guard Vercel preview intent on empty projects. Preserve secret-safe request identity and durable retry behavior. Verified by current-head CI, fresh Greptile 5/5 review, and real-agent deployment/configuration walkthroughs on disposable provider resources. Test resources and temporary provider tokens were removed after verification. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
059ae49cab |
feat(connections): add Unikraft Cloud connection (#17139)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Apps connections give agents governed access to external services through vault credentials, grants, action policies, the tool gateway, and audit. > - Unikraft Cloud runs unikernel micro-VMs, services, and volumes across regional metros, and it offers a sandbox plugin for commands and files. > - Unikraft is not in the catalog. It has no hosted MCP server, so the generic "Connect your own MCP server" flow cannot reach it. > - Daytona (#16483) added a native REST pattern for this case: a catalog generated from the provider's published OpenAPI specifications and executed through the gateway. > - This pull request adds Unikraft on that pattern and moves the shared native-provider code into one registry, so the shared connection code does not name each provider. > - The benefit is governed agent access to all published Unikraft actions, with the token kept in the vault and sent only to published Unikraft hosts. ## Linked Issues or Issue Description Refs #16483 **Problem or motivation** Teams that run workloads on Unikraft Cloud want their agents to list instances, read logs, deploy and scale services, and run commands in sandboxes. Unikraft is not in the Apps catalog. Unikraft has no hosted MCP server, so operators cannot connect it through the remote MCP flow. **Proposed solution** Add a native Unikraft connection. Generate its actions from Unikraft's official OpenAPI specifications for the platform API and the sandbox plugin. Pin the specifications to a reviewed commit. The operator connects an API token. The token stays in the vault and goes only to the five published metro hosts. Every action takes an optional metro. Actions without a metro use the connection's default metro, which the operator can change under Advanced. **Alternatives considered** A catalog-only AppDefinition was not possible because no hosted MCP endpoint exists. Wrapping the `unikraft` CLI was rejected because it would expose host filesystem behavior and CLI login state. A second copy of the Daytona bridge was rejected; the shared transport and catalog contract are now one module with a provider registry. **Roadmap alignment** This extends the existing Apps and Connections provider coverage. It uses the existing credential, grant, policy, gateway, and audit model. It does not overlap planned core work. ## What Changed - Added `scripts/generate-unikraft-tools.mjs` and its tests. The generator reads the platform and sandbox plugin specifications at commit `5dd107ea1cd8716b83cb86a83ed2a6ee46f99b5b`, resolves shared parameters, records source SHA-256 hashes, and writes `server/src/services/unikraft/operations.generated.json`. - The catalog has 105 actions: 89 platform operations and 16 sandbox plugin operations. The server-sent audit event stream is recorded in the inventory and is not advertised as an action. - Classification: GET operations and sandbox reads and waits are reads. Delete, stop, suspend, detach, unpin, and sandbox command execution, signals, and stdin are destructive. All other operations are writes. - Added `server/src/services/connectors/unikraft/client.ts` and its generated catalog. It validates arguments against the generated schemas, accepts only published metros, rejects path traversal, sends JSON bodies on GET and DELETE as the specification requires, and verifies the token with `GET /v1/users/quotas`. A sandbox wait that times out (documented HTTP 408) returns a still-running result instead of a failure. - Moved the bounded, credential-redacting HTTP sender and the catalog contract helpers from `daytona.ts` to `native-rest-client.ts`. Added `native-provider-catalogs.ts`. `tool-access.ts`, the `tool-access/catalog` and `token-broker` modules, `connectors/tool-policy.ts`, and `tool-gateway.ts` now use this registry instead of Daytona-specific checks. Daytona behavior does not change. - Added the Unikraft definition source, the generated definition, the brand mark and manifest entry, and the permission review (`liveProof: not-run`). - Added `doc/connections/UNIKRAFT.md` with a sequence diagram, endpoints, setup, actions, and limits. Updated the connections README, the permission audit, and both capability maps. - Tests: definition shape, database-backed gateway reads, writes, deletes, and sandbox commands for personal and shared grants, default and per-call metros, rejection of unpublished metros and traversal, Off policies, revocation, stale-contract blocking, credential export denial, schema validation for all actions, pinned-transport tests for GET and DELETE bodies, and a browser setup check. ## Verification - `pnpm exec vitest run packages/shared/src server/src/__tests__/unikraft-connection.test.ts server/src/__tests__/unikraft-http-boundary.test.ts server/src/__tests__/daytona-connection.test.ts server/src/__tests__/daytona-http-boundary.test.ts server/src/__tests__/tool-access-service.test.ts server/src/__tests__/tool-gateway-service.test.ts server/src/__tests__/tool-gateway.test.ts ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx ui/src/lib/app-brand-assets.test.ts` plus `connector-tool-policy` and `tool-catalog-publication`: all passed after the rebase onto the split tool-access modules. - `node --test scripts/generate-unikraft-tools.test.mjs scripts/generate-daytona-tools.test.mjs scripts/app-brand-validation.test.mjs`: 20 passed. - `node scripts/check-app-brand-assets.mjs`, `node scripts/check-maps.mjs`, and `git diff --check`: passed. - `pnpm --filter @paperclipai/shared typecheck`, `pnpm --filter @paperclipai/server typecheck`, and `pnpm --filter @paperclipai/ui typecheck`: clean. - `npx playwright test --config tests/e2e/playwright.config.ts tests/e2e/unikraft-connector.spec.ts tests/e2e/daytona-connector.spec.ts`: 2 passed. - `node scripts/generate-unikraft-tools.mjs` regenerates the committed catalog with the recorded hashes. - Manual: on a local instance, open Connectors, search for Unikraft, and select **Add key**. Confirm the icon, the password field, the key guidance, and the default metro select under **Change**. - Not verified: a real Unikraft account. Live provider read and write proof is pending. ## Risks - A Unikraft token acts for the whole organization in every metro. Unikraft offers no narrower token permissions. Assign only trusted agents and review action permissions. - Sandbox actions run arbitrary commands inside the selected instance. They are classified as destructive. - A timed-out write can still complete at the provider. The bridge does not retry writes automatically. - New metros fail closed until the specification is regenerated and reviewed. Legacy `*.kraft.cloud` hosts are not reachable. - The Daytona refactor moves code without behavior changes. All Daytona tests pass without edits. - The generated JSON snapshot is large because it holds the provider input contracts. No migration or lockfile change is required. ## Model Used - Claude Opus 5.5 (Anthropic), model ID `claude-opus-5-5`, 1M context window, used through Claude Code with tool use (shell, file editing, web research, browser tests). ## 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 |
||
|
|
4dfcb4c9b8 |
refactor(tools): isolate connection access and removal (#17167)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connection grants and installations control which identities and agents can reach tools. > - Removal must close those access paths and stop runtimes before cleaning up owned secrets. > - These responsibilities still shared the setup coordinator after earlier extractions. > - This pull request gives grants, installations, credential validation and removal explicit owners. > - The benefit is a smaller coordinator and focused access-lifecycle modules with existing security ordering intact. ## Linked Issues or Issue Description Depends on #17165. Earlier stack: #17144 → #17146 → #17147 → #17155 → #17157 → #17159 → #17161 → #17162 → #17165 → this PR. **What existing behavior does this improve?** Maintenance of connection audiences, delegation, installation and removal. **Current behavior** The 6,419-line service still owns grant mutation, installation reach and resumable credential cleanup alongside app setup. **Proposed behavior** A grant owner manages audiences and delegation. An installation owner manages reach and its profile bindings. A removal owner keeps access revocation, runtime shutdown, secret classification and cleanup together. The coordinator delegates through typed APIs. **Reason and benefit** The entry point falls to 4,821 lines / 198,065 bytes, meeting the requested under-5,000-line target. Across the full stack it falls from 21,525 lines / 829,519 bytes. App setup remains together in the coordinator. ## What Changed - Extract credential validation (75 lines), grants (603), installations (350) and removal (658). - Preserve company boundaries, audience advisory locks, membership locks, assignment locks and audit order. - Keep the existing runtime supervisor and secret client. Retain live HTTP options for provider shutdown. - Keep Slack credential-mutation leasing and resumable owned-secret cleanup with removal. ## Verification - Removal, grant-resolution and the stronger real HTTP OAuth fixture pass before extraction (13 cases); the existing service and publication baselines also pass. - The original combined targeted run passed 525 cases across seven suites. After replaying onto master, 601 cases pass across nine suites, including Braintrust lifecycle and connector-policy coverage, with one database worker. - Full repository typecheck and build passed before merge integration. After integration, server typecheck, module-boundary and whitespace gates pass; fresh CI covers the full repository gates. - All 94 pre-existing function/method bodies match by normalized syntax comparison. A full-stack TypeScript symbol audit preserves all 18 exports and 89 service methods. - The earlier local full-suite run was interrupted after 79 minutes and remains unverified. All current-head CI gates pass on `d5307fcea2365e51a75d49db82deeed236d19951`, including the full sharded test matrix, browser suites, typecheck, build and canary dry run. Greptile is 5/5 with no open review threads after merge integration. - GitHub canceled duplicate CI run [39716841632](https://github.com/paperclipai/paperclip/actions/runs/39716841632) during the atomic stack update. Replacement run [39716843243](https://github.com/paperclipai/paperclip/actions/runs/39716843243) passed on the same head; no failing test was retried. ## Risks - Audience replacement must not erase an inactive member marker and widen authority. Its advisory and membership locks remain in the grant owner. - Uninstall must remove only its own profile bindings. Existing operator-authored bindings keep their current behavior. - Removal must remain fail-closed and retryable after provider failures. Its order, shared-secret retention, supervisor and cleanup references are unchanged and covered by removal tests. - No schema, public API, policy or scheduling change is intended. The first eight PRs have landed; this PR follows the updated catalog extraction. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
f7210cd31f |
refactor(tools): isolate catalog ownership (#17165)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents receive reviewed actions discovered from their connections. > - Transport, discovery, risk classification, publication and account inventory lived in the same service. > - Their ownership differs: transport guards requests, discovery reads providers, and publication changes the catalog under locks. > - This pull request gives those phases separate modules with explicit capabilities. > - The benefit is a visible discovery-to-publication path that preserves permission and quarantine behavior. ## Linked Issues or Issue Description Builds on merged #17162 and preserves the connector policy from #17141. Earlier stack: #17144 → #17146 → #17147 → #17155 → #17157 → #17159 → #17161 → #17162 → this PR. **What existing behavior does this improve?** Maintenance of tool discovery, catalog publication, health and upstream account inventory. **Current behavior** The 8,988-line service handles HTTP guards, MCP sessions, provider probes, risk classification, quarantine, cached reads and account sync. **Proposed behavior** Discovery returns descriptors through the existing credential and transport owners. Publication owns catalog writes and default access. A reader owns refresh deduplication. Health and aggregator inventory have separate owners. **Reason and benefit** The entry point falls to 6,419 lines, a reduction of 2,569. Provider discovery no longer shares a closure with connection setup and teardown. ## What Changed - Extract guarded remote HTTP, descriptor policy, discovery, publication, default access, cached reads, health, attention and aggregator account sync. - Keep the public descriptor/risk exports and existing service methods. - Preserve database locks, transaction-scoped default-access writes, quarantine decisions, current grant checks and failure classification. - Preserve per-service catalog flights and aggregator jobs, lease ownership and live remote-request options. - New modules range from 39 to 492 lines. ## Verification - Before and after the move, 470 public service/HTTP integration cases and 44 publication, HTTP rebinding and aggregator sync cases pass. - Server typecheck, module-boundary gate and whitespace checks pass. - All 157 pre-existing function/method bodies match by normalized syntax comparison. - Before merge integration, the completed stack passed 525 targeted cases, repository-wide typecheck and build. Its stronger rotating-token fixture is included. - After replaying onto master, the integrated stack passes 601 cases across nine suites, including Braintrust lifecycle and connector-policy coverage. Server typecheck and module-boundary checks pass. All 157 moved bodies still match the current master versions. - The earlier local full-suite run was interrupted after 79 minutes and remains unverified. All current-head CI gates pass on `a21595f20809a514b7619d8a8748c56f8e546e2f`, including the full sharded test matrix, browser suites, typecheck, build and canary dry run. Greptile is 5/5 with no open review threads after merge integration. ## Risks - Discovery must keep its current grant and session behavior; publication must retain its locks and quarantine rules. Existing authority, schema-drift and publication-race tests exercise these paths. - Aggregator account observations must not become authorization. Lease, freshness, failure and credential-fingerprint behavior stay unchanged. - Live transport options must not be snapshotted. The HTTP owner retains the same options object. - No schema, public API, access-policy or scheduling change is intended. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
ba9e6e4bc5 |
refactor(tools): isolate authorization lifecycle (#17162)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Browser authorization binds a consenting identity to a company connection. > - Direct OAuth, managed-cloud claims and Vercel authorization have different state and persistence rules. > - Keeping all of them in the general tool service obscures those rules and their cleanup owners. > - This pull request separates state, initiation, provider completion and explicit identity promotion. > - The benefit is reviewable authorization flows with their existing authority checks and ordering preserved. ## Linked Issues or Issue Description Depends on #17161. Earlier stack: #17144 → #17146 → #17147 → #17155 → #17157 → #17159 → #17161 → this PR. **What existing behavior does this improve?** Maintenance of browser authorization and credential-sharing lifecycle. **Current behavior** The 12,019-line service combines provider callbacks, actor-bound states, authorization URLs and personal-to-company credential promotion. **Proposed behavior** Separate owners handle authorization state, start, direct/cloud/Vercel callbacks, catalog completion and explicit access finalization. Shared setup policy and identity checks have typed APIs used by the coordinator and authorization owners. **Reason and benefit** The entry point falls to 8,997 lines, a reduction of 3,022. Provider-specific state consumption and durable-write rules are visible in their own modules. ## What Changed - Extract authorization flows and their constraints; the largest new module is 700 lines. - Preserve direct/Vercel terminal state consumption and managed-cloud retryability until claim persistence commits. - Keep membership and grant locks, secret transaction clients, interaction resolution and catalog ordering unchanged. - Keep partial secret acquisition and cleanup together in access finalization. - Give shared organization-grant persistence, personal identity checks, setup policy and response projections named owners. ## Verification - All 470 public service and real local HTTP/PostgreSQL OAuth cases pass before and after extraction. - Coverage includes same-actor state binding, replay/denial, scope selection, membership revocation, provider failures, refresh concurrency and persisted usable credentials. - Server typecheck, module-boundary gate and whitespace checks pass. - All 182 pre-existing function/method bodies match by normalized syntax comparison. - The completed stack passes 525 targeted cases, full repository typecheck and build. The earlier interrupted local full suite remains unverified; all current-head CI gates pass; Greptile is 5/5 with no open review threads. - Original CI failure retained: [server shard 1/12](https://github.com/paperclipai/paperclip/actions/runs/39710536789/job/119600621627), `workspace-runtime.test.ts` case “replaces a reused Paperclip dev runtime whose 2xx health payload is unhealthy”. The fixture failed its initial health readiness with `ECONNREFUSED` after 97 probes / 10 seconds. The fixture and runtime implementation are unchanged and do not import this service. The isolated case passes without changing its timeout or assertions. One retry of only that shard passed at the same commit. All CI gates are now green; the original failure remains recorded here. ## Risks - Provider flows intentionally consume authorization state at different points. This extraction preserves each flow rather than sharing its completion algorithm. - Promotion must remove partially created secrets on failure and retire source secrets only after persistence. Both phases remain in the same owner with unchanged ordering. - Local HTTP fixtures prove assembled application behavior, not live third-party qualification. - No schema, public API or authorization policy change is intended. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
4fdef9457f |
refactor(tools): isolate credential ownership (#17161)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections need durable credentials that survive authorization and token rotation. > - Storage, registration, refresh coordination and credential selection lived in the general tool service. > - Each has a different ownership boundary: secrets, process-wide registration, database leases and per-service refresh work. > - This pull request gives those responsibilities named modules and passes their narrow capabilities to consumers. > - The benefit is visible credential ownership while retaining current concurrency and failure behavior. ## Linked Issues or Issue Description Depends on #17159. Earlier stack: #17144 → #17146 → #17147 → #17155 → #17157 → #17159 → this PR. **What existing behavior does this improve?** Maintenance of OAuth credential persistence, refresh and provider credential access. **Current behavior** The 14,877-line service owns registration flights, refresh leases, secret writes and provider selection alongside app setup. **Proposed behavior** Dedicated owners handle credential storage, client registration, refresh leases, connection/grant refresh, GitHub continuity and Vercel credential access. Credential selection composes those owners. Authorization callbacks remain in the coordinator for the next extraction. **Reason and benefit** The entry point falls to 12,019 lines, a reduction of 2,858. Lease acquisition and cleanup can be reviewed together, independently of callback completion. ## What Changed - Extract credential owners and shared single-flight/connection-link primitives. The largest new module is 650 lines. - Preserve process-wide client-registration flights, per-service refresh maps and GitHub sweep state. - Preserve live cloud-connector lookup, options and environment reads; use the existing secret client and transaction-scoped clients. - Extend the real local HTTP/PostgreSQL OAuth fixture with concurrent refresh across two service instances and authenticated use of rotated credentials. ## Verification - The two extended HTTP integration cases pass before extraction for public and client-secret-basic clients. - After extraction, all 470 public service and HTTP integration cases pass, including refresh failure, abandoned leases, secret redaction and membership revocation cases. The fixture was then strengthened after review: a second expiry must use the persisted rotated refresh token, and the provider rejects the old token. Both cases pass before and after extraction; server typecheck also passes. - Server typecheck, module-boundary gate and diff whitespace checks pass. - All 233 pre-existing function/method bodies match by normalized syntax comparison. - Full typecheck/build will run at the stack handoff. The earlier interrupted local full suite remains unverified; all current-head CI gates pass, with Greptile 5/5 and no open review findings. - Prior-head CI failure retained: run 39708550066, general server shard 2/12, `native-session-executor.test.ts` case “preserves a real listening process and its marker when a health RPC times out” raised `runner_remote_process_identity_unavailable` / `process_identity_changed`. Both the fixture and runner implementation are unchanged. The isolated case passes without changing assertions or timeouts. The fresh full CI run passes for the test-only review fix; the prior failure remains recorded here. ## Risks - Changing state lifetime could permit duplicate refreshes or registrations. Existing concurrency cases and the real HTTP fixture exercise these paths. - A transaction-scoped secret write must stay inside its authority lock. Function bodies, await ordering and client arguments are preserved. - The fixture proves assembled local HTTP/database behavior, not live third-party qualification. - No schema, public API, policy or scheduling change is intended. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
ffcd113761 |
refactor(tools): isolate runtime and activity ownership (#17159)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators inspect tool execution, review pending actions and control local runtimes. > - These paths shared a large service with token exchange and app authorization. > - Runtime state and execution history need explicit owners and stable public responses. > - This pull request separates runtime controls, health summaries, activity reads and the review queue. > - The benefit is focused modules that preserve the current supervisor and approval behavior. ## Linked Issues or Issue Description Depends on #17157. Earlier stack: #17144 → #17146 → #17147 → #17155 → #17157 → this PR. **What existing behavior does this improve?** Maintenance of tool runtime administration and execution activity views. **Current behavior** The 16,100-line service contains runtime slot controls, health calculations, usage history, invocation decisions and action review queries. **Proposed behavior** Runtime modules own slot persistence, operator controls and health summaries. Activity modules own history, response projections and the review queue. The public service delegates to these owners. **Reason and benefit** The entry point falls to 14,877 lines, a reduction of 1,223 lines. The coordinator no longer needs execution-history joins or runtime alert calculations. ## What Changed - Extract five modules totaling 1,282 lines. The largest is 426 lines. - Pass the existing supervisor to slot controls. Pass the same live deployment options, clock and host getter to runtime health. - Keep activity reads scoped as before. Keep unsigned-request grace and invalid-signature cancellation in the review-queue owner. - Preserve public methods, response projections, query order and audit writes. ## Verification - The public service and unsigned review-queue tests pass before and after the move. The combined post-move run passes 469 cases with one database worker. - Existing cases exercise actual local stdio stop/restart, route permissions, stale-slot and audit-failure health, activity attribution, run decisions and unsigned pending requests. - Server TypeScript check, module-boundary gate and `git diff --check` pass. - Normalized syntax comparison finds all 256 pre-existing function/method bodies unchanged. - Full typecheck/build will run at the stack handoff. The earlier interrupted local full suite remains unverified; all current-head CI gates pass, with Greptile 5/5 and no open review threads. ## Risks - Creating another supervisor would split process ownership. The new module receives the same instance; it does not construct one. - Copying deployment settings could freeze live values. The health reader holds the existing options object and getter. - Review-queue reads can cancel invalid requests. Those writes and the unsigned-request grace period are preserved and covered by the existing regression test. - No schema, public API, authorization policy or background scheduling change is intended. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
a42f213244 |
refactor(tools): isolate connection token broker (#17157)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents can request short-lived tokens for connections that allow token exchange. > - Admission, scope checks, exchange protocols and issuance records lived inside the general tool service. > - The security flow needs one visible owner while provider payloads need a separate boundary. > - This pull request extracts the broker into admission, configuration, endpoint, exchange and issuance modules. > - The benefit is a focused issuance flow with its locks, authority checks and audit order intact. ## Linked Issues or Issue Description Depends on #17155. Earlier stack: #17144 → #17146 → #17147 → #17155 → this PR. **What existing behavior does this improve?** Maintenance and verification of connection token issuance for agent runs. **Current behavior** A 17,752-line service contains broker configuration, endpoint policy, credential exchange, admission and issuance. **Proposed behavior** A dedicated broker coordinates the same admission and transaction flow. The exchange owner returns normalized token material. It receives the existing secret client, including the transaction-scoped client at issuance time. **Reason and benefit** The entry point falls to 16,100 lines, a reduction of 1,652 lines. Reviewers can see the responsible-user lock and hash-only issuance write without navigating app setup or OAuth callbacks. ## What Changed - Extract six broker modules. The largest is 755 lines; together they contain 1,721 lines. - Give tool-access audit persistence a named owner shared by the broker and coordinator. - Keep current-state checks, policy decisions, rate limits, secret resolution and transaction order unchanged. Private-host configuration is still read live. - Add two public-route integration cases with a real local HTTP server and disposable PostgreSQL. Cover Pages and RFC 8693 success and upstream failure. ## Verification - Baseline: all 466 existing public service tests passed before this move. The two new real HTTP cases passed on the original implementation before extraction. - After extraction: 495 tests pass across the public service and HTTP rebinding suites, with one database worker. This includes the two new cases, membership revocation ordering, scope denials, disabled broker behavior and hash-only persistence. - Server TypeScript checking, the module-boundary gate and `git diff --check` pass. - Normalized syntax comparison finds all 294 pre-existing function/method bodies unchanged. - Full typecheck and build passed for the preceding batch. Its interrupted local full-suite result remains unverified. All current-head CI gates pass; Greptile is 5/5 with no open review threads. ## Risks - A new closure could use the wrong secret client or move exchange outside the membership lock. The existing transaction still passes `secretService(tx)` to the exchange owner after taking that lock. - Endpoint validation must preserve live configuration and fail before credential disclosure. Existing rebinding and private-host tests cover this path. - The local fixture proves real HTTP and persisted application behavior. It does not qualify a live third-party broker. - No schema, API or access policy change is intended. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
233753e577 |
refactor(tools): isolate profile ownership (#17155)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Tool profiles select the actions each agent can use. > - Profile reads, review, mutation and assignment resolution shared a large OAuth and connection service. > - Those paths have their own company checks, lock order and database projections. > - This pull request gives profiles explicit owners while preserving the existing transactions and public API. > - The benefit is a smaller coordinator and a reviewable access boundary. ## Linked Issues or Issue Description Depends on #17147. Stack: #17144 → #17146 → #17147 → this PR. These PRs remain open. **What existing behavior does this improve?** Maintenance of tool profile management and effective agent assignments. **Current behavior** The service entry point contains 19,293 lines. Profile behavior is spread across its closure and returned object. **Proposed behavior** Profile management accepts only a database and clock. Assignment resolution accepts three named capabilities. Projection and shared lock functions have explicit homes. Public methods and responses remain unchanged. **Reason and benefit** Reviewers can follow profile transactions, lightweight reads and precedence without navigating OAuth setup. The entry point falls to 17,752 lines, a reduction of 1,541 lines in this PR. ## What Changed - Extract profile management, projections and effective assignment resolution into three modules. Their sizes are 886, 268 and 216 lines. - Move shared actor/transaction types, identifiers and assignment locks into named modules. Preserve the public lock export. - Keep all database reads, transaction boundaries, lock order and method signatures. Add no cache or background work. - Record the next ownership cuts toward an entry point below 5,000 lines. ## Verification - Before and after: 466 cases in `tool-access-service.test.ts` and 33 cases across profile entry validation, effective assignments and catalog publication. All 499 cases pass with one database worker. - Server TypeScript check and `node scripts/check-module-boundaries.mjs` pass. `git diff --check` passes. - Normalized syntax comparison finds all 329 pre-existing function/method bodies unchanged. Wiring passes the unchanged public service tests. - The previous stack passed full typecheck and build. Its full local test run was interrupted and remains unverified; its complete CI matrix passed. This PR will record its own current-head CI result below. - Current-head CI is green. Current review: Greptile is 5/5 at `0f5c85905e`, with no inline review threads. - CI failure preserved: [general server shard 1](https://github.com/paperclipai/paperclip/actions/runs/39704932041/job/119582710174) failed the unchanged workspace-runtime test that replaces an unhealthy local process. The replacement refused connections for its original 10-second readiness budget. The fixture and runtime service are unchanged and do not import tool-access. One isolated run passed without changes or timeout increases. The failure log is preserved; the cause is not reproduced. Only that failed job was retried; it passed at the same head without code changes. The original failure remains recorded above. ## Risks - Moving profile mutations could change transaction clients or lock order. Both are unchanged and the existing database tests cover publication and assignment behavior. - Effective assignment resolution still uses the same installed-connection loader and full catalog projection. The lightweight path still omits large schema and metadata fields. - No schema, public API or access policy change is intended. Existing tests provide characterization coverage; no new test mirrors the extraction. ## Model Used OpenAI Codex, GPT-6 family, with repository tools and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
4413bb262f |
refactor(tools): isolate OAuth protocol boundaries (#17147)
## Thinking Path > - Paperclip manages AI agents and their access to external tools. > - Tool connections use OAuth to obtain credentials from remote providers. > - The tool-access service mixed provider protocol parsing with database and secret writes. > - This made protocol changes hard to review without reading the full coordinator. > - This PR gives discovery, endpoint policy, and client exchange explicit owners. > - The coordinator keeps authorization, leases, persistence, and audit decisions. > - A real local provider fixture checks the boundary through public routes. ## Linked Issues or Issue Description **What existing behavior does this improve?** The ownership of OAuth discovery, registration, token exchange, and client metadata. **Current behavior** The tool-access service contains over 20,000 lines. Provider responses, endpoint policy, and stateful operations share the same closure. **Proposed behavior** Small protocol modules accept settings and named request capabilities. They return normalized results. The service owns durable state and existing public exports. This is part 3 of the stack: #17144, then #17146, then this PR. It targets #17146's branch. Review only this PR's diff. ## What Changed - Extract endpoint policy, metadata parsing/discovery, registration/token exchange, provider error normalization, and the public client metadata document. - Validate remote registration responses in the protocol module. Return client material to the coordinator for secret and connection writes. - Remove the unused raw provider response from the internal token result. Keep every consumed field. - Preserve process-wide registration single-flight, service-local maps, refresh leases, membership checks, callback checks, and transaction ownership. - Reuse connection-method URL normalization. Keep the endpoint setting and clock callbacks live. - Add a real local HTTP OAuth/MCP route fixture for public and Basic-authenticated clients. - Reduce `tool-access.ts` from 20,917 lines / 808,777 bytes to 19,293 lines / 749,158 bytes. The seven OAuth modules total 1,697 lines; the largest has 582 lines. The stack removes 2,232 lines from the original service. - Record the next profile-resolution and token-broker boundaries in the dated plan. ## Verification - Baseline: 466 service cases and 80 protocol/provider-policy cases pass. The new two-case HTTP fixture passes before moving production code. - After: `pnpm exec vitest run server/src/__tests__/tool-access-oauth-protocol.integration.test.ts server/src/__tests__/tool-access-service.test.ts server/src/__tests__/remote-mcp-connectors.test.ts server/src/__tests__/remote-http-rebinding.test.ts server/src/__tests__/oauth-client-metadata.test.ts` — 508 tests pass with one worker and disposable PostgreSQL. - The fixture drives connect, metadata discovery, DCR, PKCE code exchange, callback, catalog review, and finish. It checks persisted active state, secret references, issuer/auth-method binding, and wire-level authentication. - `pnpm -r --workspace-concurrency=2 typecheck` passes. The sandbox-only attempt could not open a local IPC socket; the same command passed with local process permissions. - `node scripts/check-module-boundaries.mjs` and `git diff --check` pass. - AST comparison confirms 37 moved bodies are unchanged. Registration protocol and persistence statements match their original halves. Token exchange only drops its unused raw result. Preflight uses explicit defaults and a clock callback. - Initial fixture authoring used a nonexistent catalog enabled field; the corrected assertion checks persisted status and reviewer identity. An initial typecheck found optional defaults at the new boundary; the caller now passes its already-validated defaults. - Final-stack local verification: `pnpm -r --workspace-concurrency=2 typecheck` and `pnpm build` pass. Remote CI is green at `3dc46c132408556ecb31038a9b9621ac20aacefc`. Greptile is 5/5 with no actionable findings or open inline threads. - Full local-suite limitation: `pnpm test:run` was interrupted after 79 minutes during the serial general-server phase, after CI had completed the full test matrix. Before interruption, it flagged the unchanged `company-search-service.test.ts` suite (26 database cases skipped). One isolated rerun passed all 28 cases without code changes. The original log and a pre-interruption copy are preserved. The original failure cause was not reproduced. The full local suite and its later groups are not claimed as passed; the complete CI matrix is green on this stack. ## Risks - OAuth endpoint checks and issuer/resource binding are security boundaries. Existing denial, redirect, scope, DCR, secret-redaction, and refresh tests cover the preserved paths. - A moved closure could capture stale policy or split registration/refresh ownership. The new modules hold no mutable state. Policy is read through the existing callback, and state stays in the service. - The local fixture proves real HTTP and database behavior. It does not claim a live third-party provider sign-in. - No schema, API, authorization policy, or persisted-data migration changes are intended. ## Model Used OpenAI Codex, GPT-6 family, with code execution and repository tools. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
8e95caf9ae |
refactor(tools): isolate connection method projection (#17146)
## Thinking Path > - Paperclip manages AI agents and their access to external tools. > - Connection methods define operator settings and managed tool arguments. > - Setup, catalog discovery, and gateway invocation must use the same projection rules. > - These rules were embedded in a large database service. > - This PR gives them one module with a narrow settings contract. > - Existing provider policy modules still decide their provider-specific restrictions. ## Linked Issues or Issue Description **What existing behavior does this improve?** Connection method configuration and tool input projection. **Current behavior** The tool-access database service owns settings validation and pure input/schema transforms. Callers import these through the service. **Proposed behavior** A connection-method module owns these transforms and accepts only connection settings. Existing imports remain compatible. This PR depends on #17144 and targets its branch. Review only this PR's diff. It is part 2 of the three-PR stack. #17147 follows this PR. ## What Changed - Move method selection, settings validation, and header/schema/argument projection into `tool-access/connection-methods.ts`. - Replace database row parameter types with required config and transport settings. No new validation is added inside typed calls. - Keep Honcho, Google Chat, and Gmail policy in their existing modules. Preserve their call order. - Retain the service's public exports for routes, gateway consumers, and tests. - Reduce `tool-access.ts` from 21,237 lines / 820,116 bytes to 20,917 lines / 808,777 bytes. The new module is 359 lines / 12,665 bytes. ## Verification - Baseline: all 466 tool-access service tests and 80 protocol/provider-policy cases pass before the move. - After: `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts server/src/__tests__/memory-connectors.test.ts server/src/services/google-chat-tool-policy.test.ts server/src/services/gmail-tool-governance.test.ts` — 506 tests pass with one worker and disposable PostgreSQL. - `pnpm --filter @paperclipai/server exec tsc --noEmit` passes after the existing workspace prerequisites were built. - AST body comparison confirms the 11 moved functions and private record parser are unchanged. `git diff --check` passes. - The first typecheck found optional config in the public DTO. The new input type now states the existing required-config invariant directly. - Final-stack local verification: `pnpm -r --workspace-concurrency=2 typecheck` and `pnpm build` pass. Greptile is 5/5 at `2d0bb86b5830c0306580e3ddc8637c4994b2a75a` with no actionable findings. - CI passed all non-browser gates. [The first browser attempt](https://github.com/paperclipai/paperclip/actions/runs/39675461620/job/119484152569) failed in the unchanged Cases read-only test: the status filter remained All statuses while the announcement-dismiss locator handler interrupted the assertion. The same test passed on #17144. The failure log is preserved. One retry of only the failed jobs passed without code changes; all CI gates are now green on the same head. - Full local-suite limitation: `pnpm test:run` was interrupted after 79 minutes during the serial general-server phase, after CI had completed the full test matrix. Before interruption, it flagged the unchanged `company-search-service.test.ts` suite (26 database cases skipped). One isolated rerun passed all 28 cases without code changes. The original log and a pre-interruption copy are preserved. The original failure cause was not reproduced. The full local suite and its later groups are not claimed as passed; the complete CI matrix is green on this stack. ## Risks - A projection-order change could alter managed arguments or advertised schemas. Function bodies and call order are unchanged, and tests exercise setup, discovery, and gateway consumers. - Legacy Gmail method aliases, GitHub toolset headers, missing unrelated settings, and disabled method filtering retain their previous behavior. - The module has no database dependency, new network work, or mutable state. ## Model Used OpenAI Codex, GPT-6 family, with code execution and repository tools. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |
||
|
|
9db3a5726e |
refactor(tools): isolate GitHub access discovery (#17144)
## Thinking Path > - Paperclip manages AI agents and their access to external tools. > - Tool connections discover repositories through GitHub account grants. > - The tool-access service mixes GitHub response parsing with grant authorization and persistence. > - These responsibilities have different inputs and failure rules. > - This PR puts GitHub discovery in one provider module. > - The service keeps current authority checks and stored grant updates. ## Linked Issues or Issue Description **What existing behavior does this improve?** The ownership and review of GitHub access discovery in the tool-access service. **Current behavior** The 21,525-line service contains GitHub pagination, account metadata validation, and grant lifecycle code. **Proposed behavior** A GitHub module returns normalized access metadata. Existing service exports remain compatible. This is the first PR in a three-part refactor stack. No behavior change is intended. A search found no existing tool-access refactor PR or issue. Stack order: this PR, #17146, then #17147. Each PR targets its predecessor. ## What Changed - Move six functions into `tool-access/github-access-discovery.ts`. Their bodies are unchanged. - Keep grant selection, credential resolution, refresh retry, membership locks, revision checks, and webhook updates in the service. - Add public-entry characterization tests for HTTP error classification and invalid pagination. - Record five candidate boundaries and the initial three-PR scope in the dated plan. - Reduce `tool-access.ts` from 21,525 lines / 829,519 bytes to 21,237 lines / 820,116 bytes. The new module is 294 lines / 9,722 bytes. ## Verification - Before and after: `pnpm exec vitest run server/src/__tests__/github-grant-metadata.test.ts server/src/__tests__/project-repositories.test.ts` — 13 tests pass. - Before and after: `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts -t 'GitHub|github'` — 11 selected tests pass with disposable PostgreSQL; 455 cases are outside this selection. - `pnpm --filter @paperclipai/server typecheck` passes. - Exact text comparison confirms all six moved bodies match the base. `git diff --check` passes. - The initial baseline attempt failed because the plugin SDK had not been built. The normal workspace prerequisite build resolved it before behavioral validation. - Final-stack local verification: `pnpm -r --workspace-concurrency=2 typecheck` and `pnpm build` pass. CI is green at `07e78dd1b1c26e0bd4234006766444c71e234451`. Greptile is 5/5 with no actionable findings. - Full local-suite limitation: `pnpm test:run` was interrupted after 79 minutes during the serial general-server phase, after CI had completed the full test matrix. Before interruption, it flagged the unchanged `company-search-service.test.ts` suite (26 database cases skipped). One isolated rerun passed all 28 cases without code changes. The original log and a pre-interruption copy are preserved. The original failure cause was not reproduced. The full local suite and its later groups are not claimed as passed; the complete CI matrix is green on this stack. ## Risks - Import wiring could break existing consumers. Existing imports remain supported and all four production call sites are unchanged. - Provider requests retain their ordering, timeout, fixed GitHub origin, and response redaction. The new module has no database dependency or shared mutable state. - Tests simulate GitHub responses. They do not qualify live GitHub access. ## Model Used OpenAI Codex, GPT-6 family, with code execution and repository tools. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `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> |