Skip to content

feat: --silent to add shares and watches without opening the browser #117

Description

@scott

Summary

Add --silent so gander share and gander watch still create (or refresh) the share on gandermd and still register the watch, but do not open the URL in a browser.

gander share plan.md --silent
gander watch plan.md --silent
gander share --watch --silent plan.md
gander --watch --silent plan.md          # local watch: register, print URL, no browser

Today every successful share/watch opens the viewer. Agents and scripts that register a file for review steal a browser tab. --visibility=hidden is the wrong hammer: it unpublished the viewer (404). --silent is UX only — the share stays at its current visibility and the URL still prints to stdout.

Paired:

Why

The agent loop is gander watch plan.md so the human can open the URL when they want (or already have My Shares open, which live-updates). Opening the tab is optional. Hidden visibility 404s GET /s/{id} for everyone, including the owner — that is access control, not “don’t steal focus.”

The gander skill and MCP mcpInstructions currently tell agents to gander watch <path> on the comment round-trip. Without --silent, that path always pops a tab.

Current

  • gander share / gander watch (runShareWithCtx in share.go): always openBrowserURL(sh.URL) unless opts.DocVisibility == "hidden".
  • Local gander --watch (handOffWatch in runner.go, runWatch in watch.go): always openBrowser after the runner (or foreground server) binds.
  • One-shot gander file.md (main.go): always openBrowser on the temp file:// URL.
  • --visibility=hidden already skips the browser and 404s the hosted viewer. TestShareHiddenDoesNotOpenBrowser covers that path.
  • mcpInstructions in mcp.go: “If watching is false, run gander watch <path> first.”

Contract

--silent is a client flag. Do not send a new JSON key. POST /api/shares / watch handoff / ~/.gander mapping are unchanged.

Invocation Creates / registers Prints URL Opens browser
gander share file.md yes yes yes
gander share --silent file.md yes yes no
gander watch --silent file.md yes (hosted + runner) yes no
gander --watch --silent file.md yes (local runner) yes no
gander --silent file.md yes (temp HTML) yes no
gander share --visibility=hidden file.md yes (hidden) yes no (existing)
gander share --silent --visibility=anyone file.md yes (anyone) yes no

Rules:

  • Not --quiet. Stdout still prints Shared … as https://gander.md/s/… (or Preview at: … / runner: pushing…). Agents and scripts need the URL.
  • Orthogonal to --visibility / --private / --comments / --no-comments. --silent never changes ACL.
  • --visibility=hidden already skips the browser; combining --silent with hidden is redundant and fine.
  • Re-share / already-mapped file: still skip the browser when --silent is set (today a refresh still opens).
  • No silent key in ~/.gander/config.json this round (unlike doc_visibility / comment_access new-share defaults).
  • Flags before the markdown path (Go flag gotcha). Completions, man, README, printUsage.

Files

  • share.go--silent on the share flag set; skip openBrowserURL when set. runWatchCmdWithCtx already prepends --watch, so gander watch --silent comes along.
  • main.go--silent on the root flag set (one-shot preview + local --watch); usage lines.
  • runner.go handOffWatch / watch.go runWatch — skip openBrowser when silent.
  • mcp.go mcpInstructions — watch-first line becomes gander watch --silent <path> (same sentence as the skill).
  • completions/gander.bash, completions/_gander
  • man/man1/gander.1
  • README next to gander share / gander watch
  • share_test.go, cli_test.go / watch tests as needed; MCP instruction test if one pins that sentence.

No new MCP tool. Agents pass --silent on the CLI. Skill copy lives in gander-skill #21 and must match mcpInstructions.

Tests

  • gander share --silent file.md POSTs /api/shares, writes the mapping, prints the URL, openBrowser call count is 0. Visibility in the body is unchanged (omit unless a visibility flag was also set).
  • gander watch --silent file.md same, plus runner handoff still happens (stub IPC / skip if the test already isolates share).
  • gander share file.md (no --silent) still opens once (existing behavior).
  • --visibility=hidden still skips the browser (existing test).
  • --silent --visibility=anyone sends doc_visibility=anyone and does not open.
  • Root gander --silent file.md and gander --watch --silent file.md do not call openBrowser; they still print the preview URL.
  • Completions / man / usage mention --silent and do not describe it as hidden/unpublish.
  • mcpInstructions contains gander watch --silent and does not tell agents to gander watch <path> without the flag.

Pairing

CLI-first. No server JSON key, so this does not invert the usual pairing rule (DisallowUnknownFields).

  1. Land the flag + mcpInstructions here.
  2. Skill feat(remove): accept short_id / URL / filename, with disambiguation #21 (SKILL.md defaults to --silent unless the user asked to open). Same watch-first sentence as MCP. Do not merge the skill until this flag is on main.
  3. gandermd feat(cli): add --silent to skip opening the browser #125 docs only: /docs/share, /docs/watch, /docs/local-watch, /docs/skill. Dashboard already live-updates on CLI create (feat(cli): add dark/light theme toggle to local preview #92); silent shares must still appear there. No migration, no API field.

Out of scope

  • Changing doc_visibility or commenting.
  • Suppressing stdout / a --quiet flag.
  • Config-file default for silent.
  • A new MCP tool parameter (CLI flag is enough; update instructions only).
  • gander manage / signup browser handoff (those commands exist to open a browser).
  • Editing SKILL.md in this repo (source of truth is gander-skill).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions