Add workspace file viewer and artifact links (#7681)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent work is issue-centered, and reviewers often need to inspect files, artifacts, and path references produced during that work. > - Before this branch, workspace-relative paths and artifact file references were not first-class inspectable objects in the board UI. > - Safe file viewing needs shared resource contracts, server-side workspace boundary checks, and UI that opens files without exposing arbitrary host paths. > - The workspace file viewer branch needed to stay as one active PR and be rebased onto current `paperclipai/paperclip:master` for review. > - This pull request adds the workspace file resource API, issue-page file viewer and browser, markdown file-reference links, and artifact file chips. > - The benefit is that board users can inspect relevant files from issue context while preserving workspace boundaries and auditability. ## Linked Issues or Issue Description No public GitHub issue exists for this branch. Internal Paperclip issues: `PAP-1953`, `PAP-10539`, `PAP-10733`. Problem / motivation: - Board users need to open workspace-relative files mentioned by agents or attached as work-product metadata without switching to a terminal. - The UI needs to support both direct file-path opening and workspace browsing/searching from an issue page. - The server must enforce company access, workspace boundaries, size limits, rate limits, and safe audit logging. Related PR: - Prior closed attempt: #4442 - Single active PR for this branch: #7681 ## What Changed - Added shared workspace file resource types, validators, and workspace-file `resourceRef` metadata validation for work products. - Added server routes/services for resolving, listing, and previewing workspace-relative files with access checks, scan caps, list-specific limits, and audit logging. - Added the issue file viewer provider, sheet, workspace browser, command-palette action, markdown workspace-file autolinks, and artifact file chips. - Updated issue workspace UI and stories/tests for file browsing and workspace file opening. - Rebased the branch onto current `paperclipai/paperclip:master` and updated the existing single PR branch. - Addressed current-head Greptile follow-ups by applying `offset` consistently across search/recent/changed file listings, restoring stopped-service port ownership checks before auto-port reuse, and stabilizing the workspace browser pagination test. ## Verification Current local verification after rebase to `public/master`: - `pnpm exec vitest run packages/shared/src/work-product.test.ts server/src/__tests__/file-resources.test.ts server/src/__tests__/instance-settings-routes.test.ts server/src/__tests__/instance-settings-service.test.ts server/src/__tests__/workspace-runtime.test.ts ui/src/components/FileViewerSheet.test.tsx ui/src/components/FileViewerSheet.copy.test.tsx ui/src/components/WorkspaceFileBrowser.test.tsx ui/src/components/WorkspaceFileMarkdownBody.test.tsx ui/src/context/FileViewerContext.test.ts ui/src/lib/remark-workspace-file-refs.test.ts ui/src/lib/workspace-file-parser.test.ts ui/src/components/IssueWorkspaceCard.test.tsx` - 13 files passed, 197 tests passed. - `pnpm -r --filter @paperclipai/shared --filter @paperclipai/server --filter @paperclipai/ui typecheck` - passed. - `pnpm exec vitest run ui/src/components/WorkspaceFileBrowser.test.tsx` - 1 file passed, 25 tests passed. - `pnpm exec vitest run server/src/__tests__/file-resources.test.ts server/src/__tests__/workspace-runtime.test.ts` - 2 files passed, 90 tests passed. - `pnpm -r --filter @paperclipai/server typecheck` - passed. - Confirmed branch is `0` behind and `46` ahead of current `public/master` after rebase and follow-up commits. - Confirmed the PR diff does not include `pnpm-lock.yaml`. - Confirmed the PR diff does not include `.github/workflows` changes. - Searched GitHub for duplicate or related workspace file viewer PRs/issues; #4442 is the prior closed attempt and this PR is the single active PR for the branch. - No screenshots were committed; the task explicitly asked not to add design screenshots or images unless they were part of the work. Current remote verification on head `a698a7bc10137baf7d25bd5722e1d6e0343387c1`: - Greptile Review - success, 64 files reviewed, 0 comments added, no unresolved Greptile review threads. - PR workflow `verify` - success. - Typecheck + Release Registry, General tests, workspace test shards, serialized server suites, Build, Canary Dry Run, e2e, Socket, and Snyk - success. - `security-review` - neutral, with output saying a draft advisory was filed for maintainer review and is not a merge block. - `commitperclip PR Review / review` - cancelled after the security gate detected flags and timed out while creating/reviewing the advisory. I reran it once and it cancelled the same way; no actionable code/test failure was exposed in the job logs. ## Risks - This is a broad UI/server feature PR, so review needs to pay attention to route authorization, workspace boundary handling, and markdown autolink false positives. - Workspace browsing intentionally caps list results and scan depth; very large workspaces may require users to refine search terms. - Remote workspace preview remains unavailable until remote file-access support is implemented. - The neutral commitperclip security-review advisory needs maintainer review, but the check output says it is not a merge block. > 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 a Paperclip/Codex local tool-use environment, medium reasoning, with shell/GitHub CLI tool use for branch inspection, verification, rebase, PR update, Greptile review, and CI inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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.7 <noreply@anthropic.com>
This commit is contained in:
+52
-8
@@ -1,9 +1,9 @@
|
||||
# Agent Artifact Upload Workflow
|
||||
|
||||
Generated files that a board user or reviewer should inspect must be attached to
|
||||
the Paperclip issue before the agent chooses a final disposition. A local
|
||||
workspace path is not enough, because cloud users and reviewers often cannot
|
||||
access the agent's disk.
|
||||
Generated files that a board user or reviewer should inspect as deliverables
|
||||
must be attached to the Paperclip issue before the agent chooses a final
|
||||
disposition. A local workspace path is not enough, because cloud users and
|
||||
reviewers often cannot access the agent's disk.
|
||||
|
||||
Use the helper bundled with the Paperclip skill from the repo root:
|
||||
|
||||
@@ -27,9 +27,50 @@ It uploads the file to
|
||||
artifact work product on `POST /api/issues/{issueId}/work-products` by default.
|
||||
The command prints issue-safe markdown links for the final task comment.
|
||||
|
||||
## Uploaded Artifacts vs Workspace Files
|
||||
|
||||
Use uploaded artifacts for deliverables: videos, PDFs, screenshots, archives,
|
||||
reports, rendered HTML, or any file the board should inspect without needing the
|
||||
agent's checkout. Attachment-backed artifact work products set `type` to
|
||||
`artifact` and `provider` to `paperclip`, with metadata canonicalized from the
|
||||
uploaded `attachmentId`.
|
||||
|
||||
Use `workspace_file` metadata only for important files that intentionally remain
|
||||
in a project or execution workspace, such as source files, committed markdown
|
||||
plans, or generated files whose meaning depends on the checkout. Workspace-only
|
||||
references are useful signposts, but they are not durable uploads.
|
||||
|
||||
Expected work product metadata shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"resourceRef": {
|
||||
"kind": "workspace_file",
|
||||
"issueId": "<issue-id>",
|
||||
"workspaceKind": "execution_workspace",
|
||||
"workspaceId": "<execution-workspace-id>",
|
||||
"relativePath": "doc/plans/example.md",
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"displayPath": "doc/plans/example.md:1:1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`workspaceKind` is `execution_workspace` or `project_workspace`. `line` and
|
||||
`column` are optional. `relativePath` must be relative to that workspace root;
|
||||
do not store host-local absolute paths as workspace references.
|
||||
|
||||
Workspace file links resolve only inside registered Paperclip workspaces. The
|
||||
default target is the current issue's execution workspace first, then its
|
||||
project workspace. A link may target another same-company project workspace only
|
||||
when it carries both that `projectId` and `workspaceId`. Paperclip does not
|
||||
resolve arbitrary machine-wide filesystem paths, absolute host paths, home
|
||||
paths, or relative paths that escape the selected workspace.
|
||||
|
||||
## Completion Pattern
|
||||
|
||||
When a task produces a user-inspectable file:
|
||||
When a task produces a user-inspectable deliverable file:
|
||||
|
||||
1. Generate and verify the file locally.
|
||||
2. Upload it with `skills/paperclip/scripts/paperclip-upload-artifact.sh`.
|
||||
@@ -38,9 +79,12 @@ When a task produces a user-inspectable file:
|
||||
4. Link the printed attachment URL in the final issue comment.
|
||||
5. Then set the final issue status.
|
||||
|
||||
Final comments should name the uploaded artifact, not just the local filesystem
|
||||
path. Local paths can be included as diagnostic context, but they cannot be the
|
||||
only access path.
|
||||
Final comments should name and link the uploaded artifact or work product, not
|
||||
just the local filesystem path. For workspace-only files, include the work
|
||||
product title and recorded relative path. Local paths can be included as
|
||||
diagnostic context, but they cannot be the only access path. Browse/search is a
|
||||
fallback for recovering workspace files when the issue link or chip is not
|
||||
available, not the preferred way to deliver files to users.
|
||||
|
||||
## Video Examples
|
||||
|
||||
|
||||
+7
-3
@@ -214,9 +214,9 @@ pnpm paperclipai configure --section storage
|
||||
|
||||
## Agent Artifact Uploads
|
||||
|
||||
When an agent generates a file that a board user or reviewer should inspect,
|
||||
attach it to the issue before marking the task complete. Do not rely on a local
|
||||
workspace path as the only access path.
|
||||
When an agent generates a file that a board user or reviewer should inspect as
|
||||
a deliverable, attach it to the issue before marking the task complete. Do not
|
||||
rely on a local workspace path as the only access path.
|
||||
|
||||
Use the helper bundled with the Paperclip skill from the repo root:
|
||||
|
||||
@@ -237,6 +237,10 @@ skills/paperclip/scripts/paperclip-upload-artifact.sh out/walkthrough.webm \
|
||||
The helper uploads the file as an issue attachment, creates an artifact work
|
||||
product by default, and prints markdown links for the final issue comment. See
|
||||
`doc/AGENT-ARTIFACTS.md` for the full completion pattern and direct API shape.
|
||||
If a file intentionally remains workspace-only, create a work product with
|
||||
`metadata.resourceRef.kind: "workspace_file"` and include the workspace-relative
|
||||
path in the final comment. Use browse/search only as the fallback for recovering
|
||||
that file, not as the main completion path for deliverables.
|
||||
|
||||
## Default Agent Workspaces
|
||||
|
||||
|
||||
@@ -402,6 +402,7 @@ Operational policy:
|
||||
- Inline-safe responses use `Content-Disposition: inline`; unsafe types and explicit download requests use `attachment`.
|
||||
- Video attachments are inline-safe and support single `Range: bytes=start-end` requests with `206`, `Content-Range`, and `Accept-Ranges: bytes` for browser playback/seeking.
|
||||
- Attachment-backed artifact work products use `type: "artifact"`, `provider: "paperclip"`, and metadata with `attachmentId`, `contentType`, `byteSize`, `contentPath`, `openPath`, `downloadPath`, and optional `originalFilename`.
|
||||
- Workspace-only file references use work product `metadata.resourceRef` with `kind: "workspace_file"`, `issueId`, `workspaceKind` (`execution_workspace` or `project_workspace`), `workspaceId`, `relativePath`, optional `line`/`column`, and `displayPath`. These references point at files in a workspace; they do not replace attachment-backed artifacts for deliverables that must be inspectable without workspace access.
|
||||
|
||||
## 7.15 `documents` + `document_revisions` + `issue_documents`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user