feat(provider): optional DeepLinker capability + provider-owned open affordance (ADR-0017) #12
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/deeplinker-seam"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements #6: make deep-link capture an optional provider capability (
provider.DeepLinker=CaptureDeepLink+FallbackOpen) instead of a mandatoryAgentProvidermethod, following the existingConnectingReporterpattern. This unblocks #2 (Codex has no web Open link) and removes the provider-isolation violation where core instance code importedclaudecodeto recognise a capture miss and the SPA hardcoded the claude.ai fallback.Changes
AgentProviderlosesCaptureDeepLink; new optionalDeepLinker(CaptureDeepLink+FallbackOpen) andOpenAffordancemetadata.""(still logs loudly);FallbackOpen()owns the claude.ai picker URL + v0 tooltip.claudecodeimport; capture arms only forDeepLinkerproviders, at Start and startup re-adoption alike;""is a miss so write-only-on-hit simplifies to "non-empty → persist". A link-less provider keepsdeep_link_urlNULL.GET /providersgains an additivefallback_openfield, present only forDeepLinkerproviders.FakeimplementsDeepLinker; newNoLinkFake(AgentProvider-only) covers the link-less path end to end.openStateis provider-driven (fallback as a tri-state, so a still-loading providers list never flashes tmux-attach); a link-less row shows a copyabletmux attach -t <session>; sharedOpenAffordancecomponent. No hardcoded provider URL/tooltip in the open path.Acceptance criteria
deep_link_urlNULL.internal/instancegrep-clean; httpapi'sclaudecodeimports are the out-of-scope auth routes + chat error mapping).tmux attach -t <session>affordance with a tooltip.Review & validation
A 7-agent adversarial review (4 dimensions → verify) surfaced one low-severity finding — a missed-capture claude-code row briefly flashing tmux-attach while the providers list loaded — fixed via the fallback tri-state with regression tests. Two other findings were adversarially refuted.
go build/vet/test ./...· gofmt · golangci-lint 0 issues · tsc · ESLint · Prettier · vitest 309 passed · vite build.Unblocks #2.
🤖 Generated with Claude Code
https://claude.ai/code/session_01NP2Ai6CBkYY7Fj1fujtRDD
Validation audit — PR #12
Verdict: PASS.
Verification signal. CI (
ci / flake-check) is stuck Waiting to run — this repo's Forgejo instance has nonix-label runner, so it is not a vouching signal. This repo has no commit-time gate either (no pre-commit hook). Per the "run the project's own checks when nothing vouches" rule, I ran the repo's own gate locally:nix flake check -L→ all checks passed (exit 0). That covers:lab+labctl),go vet, fullgo test ./...— all packages OKgolangci-lint— 0 issuestsc+ ESLint + Prettier + vitest 309 passed +vite buildConvention lint. Title
feat(provider): …is Conventional Commits. ADR recorded (ADR-0017); CONTEXT.md updated. Nosecrets.yaml/ state-version concerns apply to this repo.Diff review (23 files, +851/−160) against ADR-0017 intent.
provider.go:CaptureDeepLinkremoved fromAgentProvider; new optionalDeepLinker(CaptureDeepLink + FallbackOpen) +OpenAffordancestruct — theConnectingReporterpattern. ✓instance.go: drops theclaudecodeimport; capture arms only via aDeepLinkertype assertion; a miss is"", so persistence simplifies to "non-empty → persist".launch.gonow routes throughArmCapture, so both the NULL-guard and the capability gate apply on the launch path. Behaviour for claude-code is preserved (old== GenericDeepLinkskip ≡ new== ""skip). ✓httpapi/providers.go: additivefallback_open, present only forDeepLinkerproviders. ✓openStateis a tri-state — exact link wins (provider-independent), thenconnecting, thenunknown(renders nothing while the providers list loads — the flash-fix), then the provider's generic web link, else a copyabletmux attach -t <session>. No hardcoded provider URL/tooltip in the open path.AttachButtonguardsnavigator.clipboardfor non-secure/permission contexts. ✓Tests.
NoLinkFake(AgentProvider-only) +TestStart_linklessProvider_noCaptureNoDeepLinkprove the no-arm / NULL-link / non-connecting / re-adoption path end to end;TestAPI_Providersasserts thefallback_openfield.Note — issue #6 will not auto-close. The body says "Implements #6", which is not a Forgejo closing keyword. This is a manual
feat/branch (notafk/<N>), so there's no run-claim to release — but #6 should be closed manually on merge. I'll do that as part of closing the loop.No blockers. Awaiting free-text merge go-ahead.