paperclip-github-plugin 0.8.9 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -227,7 +227,7 @@ The plugin exposes GitHub workflow tools to Paperclip agents, including:
227
227
 
228
228
  - repository-scoped search for issues and pull requests
229
229
  - issue reads, comment reads, comment writes, metadata updates, and `assign_to_current_user` assignment to the saved token owner
230
- - pull request creation, reads, updates, changed-file inspection, and CI-check inspection
230
+ - pull request creation, reads, updates, changed-file inspection, CI-check inspection, and asset upload for PR visual evidence
231
231
  - review-thread reads, replies, resolve and unresolve actions, and `request_pull_request_reviewers` reviewer requests
232
232
  - organization-level GitHub Project search/listing and pull-request-to-project association
233
233
 
@@ -272,6 +272,34 @@ Current host caveat: on authenticated Paperclip deployments, the Paperclip host
272
272
 
273
273
  Because the KPI attribution endpoint is a native plugin JSON route rather than a plugin tool, authenticated agent runs can still call it directly with `PAPERCLIP_API_KEY` even while that host bug blocks the GitHub Sync tool surface.
274
274
 
275
+ ### Pull request asset upload
276
+
277
+ For PRs that need durable assets in the description, agents can call the `upload_pull_request_asset` tool. The tool accepts a PR target plus `fileName` and either `contentBase64` or a `dataUrl`; optional fields include `label`, `alt` (an alias for image alt text), `caption`, `mimeType`, and `artifactBranch`. Common MIME types are inferred from filenames, including images and PDFs. Unknown types are stored as `application/octet-stream`. Assets are limited to 10 MiB.
278
+
279
+ The plugin writes the asset to a non-merge artifact branch named `paperclip-artifacts-pr-<number>` by default, stores it under `assets/pr-<number>/<head-sha>/`, and returns immutable raw GitHub URLs plus Markdown suitable for a PR description. Images return image Markdown; PDFs and other files return normal Markdown links.
280
+
281
+ Authenticated agent runs that cannot call plugin tools can post the same JSON payload to `/api/plugins/paperclip-github-plugin/api/pull-request-assets` with `Authorization: Bearer ${PAPERCLIP_API_KEY}`. The native plugin route is agent-authenticated by the Paperclip host before worker dispatch.
282
+
283
+ Example:
284
+
285
+ ```bash
286
+ contentBase64="$(base64 -w0 /tmp/review-report.pdf)"
287
+ payload="$(jq -n \
288
+ --arg repository paperclipai/example-repo \
289
+ --argjson pullRequestNumber 21 \
290
+ --arg fileName review-report.pdf \
291
+ --arg label 'Review report PDF' \
292
+ --arg contentBase64 "$contentBase64" \
293
+ '{repository:$repository,pullRequestNumber:$pullRequestNumber,fileName:$fileName,label:$label,contentBase64:$contentBase64,mimeType:"application/pdf"}')"
294
+
295
+ curl -X POST "${PAPERCLIP_API_URL%/}/api/plugins/paperclip-github-plugin/api/pull-request-assets" \
296
+ -H "content-type: application/json" \
297
+ -H "authorization: Bearer ${PAPERCLIP_API_KEY}" \
298
+ -d "${payload}"
299
+ ```
300
+
301
+ The response body contains `asset.markdown`, `asset.rawUrl`, `asset.artifactBranch`, `asset.path`, and `asset.commitSha`.
302
+
275
303
  ### Issue link API route
276
304
 
277
305
  Authenticated agent runs can link the current Paperclip issue to a GitHub issue or pull request by posting to `/api/plugins/paperclip-github-plugin/api/issue-link`. This is useful after creating a PR with `gh` in a repository that is not mapped to a Paperclip project.
package/dist/manifest.js CHANGED
@@ -523,6 +523,58 @@ var GITHUB_AGENT_TOOLS = [
523
523
  }
524
524
  }
525
525
  },
526
+ {
527
+ name: "upload_pull_request_asset",
528
+ displayName: "Upload Pull Request Asset",
529
+ description: "Upload a PR-visible asset such as an image, PDF, log, archive, or report to a non-merge artifact branch and return durable markdown that can be embedded in the PR body.",
530
+ parametersSchema: {
531
+ type: "object",
532
+ additionalProperties: false,
533
+ required: ["fileName"],
534
+ allOf: [pullRequestTargetSchema],
535
+ anyOf: [
536
+ { required: ["contentBase64"] },
537
+ { required: ["dataUrl"] }
538
+ ],
539
+ properties: {
540
+ repository: repositoryProperty,
541
+ pullRequestNumber: pullRequestNumberProperty,
542
+ paperclipIssueId: paperclipIssueIdProperty,
543
+ fileName: {
544
+ type: "string",
545
+ description: "Asset filename. The plugin sanitizes it and preserves a safe extension."
546
+ },
547
+ label: {
548
+ type: "string",
549
+ description: "Human-readable link text for the returned Markdown. Defaults to the sanitized filename."
550
+ },
551
+ alt: {
552
+ type: "string",
553
+ description: "Backward-compatible alias for label, useful as image alt text."
554
+ },
555
+ caption: {
556
+ type: "string",
557
+ description: "Optional human-facing caption returned with the uploaded asset metadata."
558
+ },
559
+ contentBase64: {
560
+ type: "string",
561
+ description: "Base64-encoded asset bytes. Assets are limited to 10 MiB."
562
+ },
563
+ dataUrl: {
564
+ type: "string",
565
+ description: "Alternative base64 data URL input such as data:application/pdf;base64,... or data:image/png;base64,... ."
566
+ },
567
+ mimeType: {
568
+ type: "string",
569
+ description: "Optional MIME type such as application/pdf or image/png. If omitted, the plugin infers common types from fileName and otherwise uses application/octet-stream."
570
+ },
571
+ artifactBranch: {
572
+ type: "string",
573
+ description: "Optional artifact branch name. Defaults to paperclip-artifacts-pr-<pullRequestNumber>."
574
+ }
575
+ }
576
+ }
577
+ },
526
578
  {
527
579
  name: "link_github_item",
528
580
  displayName: "Link GitHub Item",
@@ -582,12 +634,15 @@ var COMPANY_METRIC_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_ID}/a
582
634
  var ISSUE_LINK_API_ROUTE_KEY = "link-github-item";
583
635
  var ISSUE_LINK_API_ROUTE_PATH = "/issue-link";
584
636
  var ISSUE_LINK_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_ID}/api${ISSUE_LINK_API_ROUTE_PATH}`;
637
+ var PULL_REQUEST_ASSET_API_ROUTE_KEY = "upload-pull-request-asset";
638
+ var PULL_REQUEST_ASSET_API_ROUTE_PATH = "/pull-request-assets";
639
+ var PULL_REQUEST_ASSET_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_ID}/api${PULL_REQUEST_ASSET_API_ROUTE_PATH}`;
585
640
 
586
641
  // src/manifest.ts
587
642
  var require2 = createRequire(import.meta.url);
588
643
  var packageJson = require2("../package.json");
589
644
  var SCHEDULE_TICK_CRON = "* * * * *";
590
- var MANIFEST_VERSION = "0.8.9"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
645
+ var MANIFEST_VERSION = "0.8.10"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
591
646
  var manifest = {
592
647
  id: GITHUB_SYNC_PLUGIN_ID,
593
648
  apiVersion: 1,
@@ -666,6 +721,13 @@ var manifest = {
666
721
  path: ISSUE_LINK_API_ROUTE_PATH,
667
722
  auth: "agent",
668
723
  capability: "api.routes.register"
724
+ },
725
+ {
726
+ routeKey: PULL_REQUEST_ASSET_API_ROUTE_KEY,
727
+ method: "POST",
728
+ path: PULL_REQUEST_ASSET_API_ROUTE_PATH,
729
+ auth: "agent",
730
+ capability: "api.routes.register"
669
731
  }
670
732
  ],
671
733
  tools: GITHUB_AGENT_TOOLS,
package/dist/ui/index.js CHANGED
@@ -11984,7 +11984,7 @@ var urlAttributes = {
11984
11984
  ]
11985
11985
  };
11986
11986
 
11987
- // node_modules/.pnpm/react-markdown@10.1.0_@types+react@19.2.14_react@19.2.5/node_modules/react-markdown/lib/index.js
11987
+ // node_modules/.pnpm/react-markdown@10.1.0_@types+react@19.2.14_react@19.2.6/node_modules/react-markdown/lib/index.js
11988
11988
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11989
11989
  import { useEffect, useState } from "react";
11990
11990
 
@@ -19140,7 +19140,7 @@ function isUint8Array2(value) {
19140
19140
  );
19141
19141
  }
19142
19142
 
19143
- // node_modules/.pnpm/react-markdown@10.1.0_@types+react@19.2.14_react@19.2.5/node_modules/react-markdown/lib/index.js
19143
+ // node_modules/.pnpm/react-markdown@10.1.0_@types+react@19.2.14_react@19.2.6/node_modules/react-markdown/lib/index.js
19144
19144
  var changelog = "https://github.com/remarkjs/react-markdown/blob/main/changelog.md";
19145
19145
  var emptyPlugins = [];
19146
19146
  var emptyRemarkRehypeOptions = { allowDangerousHtml: true };