Skip to content

share: variadic + --anon + JSON array shape (PR2 of 2) - #2

Merged
godspede merged 6 commits into
mainfrom
claude/pr2-share-multifile
Apr 22, 2026
Merged

share: variadic + --anon + JSON array shape (PR2 of 2)#2
godspede merged 6 commits into
mainfrom
claude/pr2-share-multifile

Conversation

@godspede

Copy link
Copy Markdown
Owner

Summary

Second of two sequential PRs for the share UX redesign. Builds on #1.

  • ghosthost share is variadicshare a.png b.png c.png creates three independent shares in one invocation, avoiding separate permission prompts. Atomic validation: any bad path aborts the whole batch with every error reported, zero shares created. Soft cap of 64 files; --yes overrides.
  • --as rejected when N > 1 with a clear error.
  • --anon replaces each share's URL filename with a random 6-char base32 slug, preserving the file extension (secret-tax-return.pdfk9vm3q.pdf). Original filename is never sent to the recipient. Works for single and multi-file alike; --as wins over --anon when both are set with N == 1.
  • Mid-batch RPC failure prints succeeded URLs so the user can revoke them, then the error, then exits non-zero.

Spec: docs/superpowers/specs/2026-04-21-share-multifile-and-minimal-output-design.md
Plan: docs/superpowers/plans/2026-04-21-pr2-share-multifile-and-anon.md

Breaking changes

  • ghosthost share --json now always emits a JSON array — even for a single file. Previously emitted a bare SharePayload object. Callers parsing stdout must update (e.g. jq '.[0].url' instead of jq '.url'). Docs updated.

Test plan

  • go test ./... — all packages green, zero regressions
  • go vet ./... — clean
  • go build ./cmd/ghosthost — ok
  • CLI help shows share <path>... with --anon and --yes
  • AnonDisplayName slug shape, uniqueness, and pass-through of SanitizeDisplayName
  • printShares covers default-multiple, default-single, verbose, JSON array, JSON-array-for-single
  • cmdShare validation: no args, --as + multi, cap without --yes, cap with --yes (bypass), atomic bad path
  • selectDisplayName priority: --as > --anon > basename
  • Mid-batch first-file failure does not flush [] to stdout in JSON mode
  • Manual smoke against a live daemon: 3 files → 3 URLs, --anon URL has slug, 65 files without --yes rejected, 65 with --yes proceeds, mixed good+bad paths returns ExitSourceBad and creates zero shares

🤖 Generated with Claude Code

Zack Frank and others added 6 commits April 21, 2026 21:51
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… cleanups

- extract the display-name selection switch into a pure function so the
  --as > --anon > basename priority is unit-testable without a live daemon
- add 4 tests locking the priority order
- --yes flag description now uses shareMaxBatch instead of a string literal
- stub TestCmdShare_MultipleFiles_HappyPath as t.Skip (no bootstrap
  override available; covered by manual smoke in Task 6)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update README.md, CLAUDE.md, and skills/ghosthost/SKILL.md to document
the variadic `ghosthost share <path>...` form, the `--anon` flag (random
6-char slug, extension preserved), the `--yes` 64-file cap override, and
the breaking change that `--json` now always emits a JSON array.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…est --yes

- when the first share RPC fails, don't flush an empty [] to stdout before
  the stderr error; downstream pipelines otherwise see a silent empty array
- new TestCmdShare_CapWithYes_BypassesLimit confirms --yes actually bypasses
  the 64-file cap (previously only the rejection path was tested)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@godspede
godspede merged commit 643e10c into main Apr 22, 2026
0 of 2 checks passed
godspede added a commit that referenced this pull request Jul 17, 2026
* feat(share): AnonDisplayName (6-char base32 slug + ext)

* feat(cli): printShares — slice-first output, JSON always emits array

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(cli): variadic share with --anon, --yes, atomic validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(cli): extract selectDisplayName; cover --as/--anon priority; cleanups

- extract the display-name selection switch into a pure function so the
  --as > --anon > basename priority is unit-testable without a live daemon
- add 4 tests locking the priority order
- --yes flag description now uses shareMaxBatch instead of a string literal
- stub TestCmdShare_MultipleFiles_HappyPath as t.Skip (no bootstrap
  override available; covered by manual smoke in Task 6)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: variadic share, --anon, and --json array shape (breaking)

Update README.md, CLAUDE.md, and skills/ghosthost/SKILL.md to document
the variadic `ghosthost share <path>...` form, the `--anon` flag (random
6-char slug, extension preserved), the `--yes` 64-file cap override, and
the breaking change that `--json` now always emits a JSON array.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(cli): guard printShares from emitting [] on first-file failure; test --yes

- when the first share RPC fails, don't flush an empty [] to stdout before
  the stderr error; downstream pipelines otherwise see a silent empty array
- new TestCmdShare_CapWithYes_BypassesLimit confirms --yes actually bypasses
  the 64-file cap (previously only the rejection path was tested)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: godspede <jehutheawesome@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@godspede
godspede deleted the claude/pr2-share-multifile branch July 17, 2026 20:35
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.

1 participant