Skip to content

feat(web): add Copy link to dashboard artifact cards - #19

Draft
renagent[bot] wants to merge 1 commit into
mainfrom
lax-9-copy-artifact-link
Draft

renagent[bot] wants to merge 1 commit into
mainfrom
lax-9-copy-artifact-link

Conversation

@renagent

@renagent renagent Bot commented Sep 8, 2026

Copy link
Copy Markdown

Summary

Implements https://linear.app/laxman-personal-workspace/issue/LAX-9 after approval on the issue.

  • Add an always-visible top-left Copy link button as a sibling of the card anchor. Copies the absolute artifact URL without navigating.
  • Show Copied! with a check icon for 1600ms, with timeout cleanup and a guard against updates after unmount.
  • Name the artifact in the accessible label, announce feedback politely, and provide a keyboard focus ring.
  • Extract the existing Clipboard API / textarea fallback into a shared helper. Detail-page feedback remains unchanged.
  • Small addition to the plan: show Copy failed when both copy paths fail rather than silently leaving the action unchanged.

Validation

  • Installed dependencies with bun install --frozen-lockfile.
  • Built workspace prerequisites with bun x turbo run build --filter="@agent-artifacts/web^..." and bun run --filter @agent-artifacts/config build. Initial typecheck could not resolve the unbuilt workspace packages; it passes after building them.
  • apps/web: bun run typecheck - passed.
  • apps/web: bun run test - 4 files, 12 tests passed.
  • git diff --check - passed; full diff self-reviewed.
  • Added only two scoped helper tests: Clipboard API success and rejection with fallback success/failure. No DOM or Playwright test setup added, as approved.

Review focus / remaining verification

Please check the sibling overlay structure, focus/live feedback and timeout lifecycle. Browser clipboard interaction, visual placement, and keyboard/screen-reader behavior have not been manually exercised. Copied links preserve existing access requirements; no share-link flow is introduced.

Keep this PR draft through Review and QA. A human merges.

@renagent renagent Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What it does: moves copyText into apps/web/lib/copy-text.ts, wraps ArtifactTile in a relative div and adds an always-visible Copy link button as a sibling of the <Link> (top-left, badge-style chrome). Copies ${origin}${artifactPath}, shows Copied! / Copy failed for 1600ms, clears the timer on unmount, names the artifact in aria-label, announces via aria-live.

Checked: checked out 95c1188, read the full diff against the LAX-9 plan. bun run typecheck and bun run test (4 files, 12 tests) pass in apps/web; git diff --check clean. Button is outside the anchor so no nested interactive markup, and the existing .lip-hover-card / .artifact-card hover styles are unaffected since the button is not a descendant of either. Detail page still uses the shared helper with its original "Link copied" text. The added Copy failed state is a reasonable small extension of the plan's "never fail silently" intent.

CI: the red check is @agent-artifacts/cli#test (content integrity / Zod fixture errors). main has failed the same job on every push since 2026-07-07, so it is pre-existing and not caused by this PR. Worth a separate issue.

Not blocking, two inline notes. No manual browser/screen-reader pass was done here; QA should cover click-without-navigate, keyboard focus ring, and the announcement.

<button
type="button"
aria-label={`Copy link to ${artifact.title}`}
className="absolute left-3 top-3 inline-flex items-center gap-1 rounded-[0.3rem] border border-border bg-[var(--wb-content)]/80 px-1.5 py-0.5 font-mono text-[9px] text-foreground/70 backdrop-blur-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/70 focus-visible:ring-offset-2"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: Tailwind v4's ring-offset-2 uses --tw-ring-offset-color: #fff by default, so on the dark theme the focus ring will have a white halo between the button and the ring. Either drop the offset or set it to the page background:

Suggested change
className="absolute left-3 top-3 inline-flex items-center gap-1 rounded-[0.3rem] border border-border bg-[var(--wb-content)]/80 px-1.5 py-0.5 font-mono text-[9px] text-foreground/70 backdrop-blur-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/70 focus-visible:ring-offset-2"
className="absolute left-3 top-3 inline-flex items-center gap-1 rounded-[0.3rem] border border-border bg-[var(--wb-content)]/80 px-1.5 py-0.5 font-mono text-[9px] text-foreground/70 backdrop-blur-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/70 focus-visible:ring-offset-2 focus-visible:ring-offset-background"

expect(writeText).toHaveBeenCalledWith("https://example.com/artifact");
});

it("falls back when the Clipboard API rejects and returns the fallback result", async () => {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this case asserts both the fallback-success and fallback-failure paths in one it via chained mockReturnValueOnce. If the second branch regresses, the failure message points at the whole test. Splitting into "fallback succeeds" and "fallback reports false" would be clearer and matches the two-case shape the plan asked for. Fine to leave.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants