Repository navigation
feat(cli): add the instatic CLI with browser sign-in and batch calls - #17
Merged
Merged
Conversation
Agents reported the Instatic MCP tools "keep disconnecting". The cause was the browser bridge, not the MCP endpoint: - A browser tool failed instantly when the editor tab's stream was in a routine reconnect gap (idle recycle, network blip, restart). Calls now wait up to 15s for the workspace (waitForEditorWorkspace). - Two open editor tabs stole the workspace from each other on every idle recycle, cancelling in-flight calls. Tabs now send a stable tabId and keep their claim across reconnects; superseded tabs stay connected and take over when the active tab closes. - Interrupted calls surfaced the in-app chat message "AI chat stream ended before tool result arrived". The transport now raises a typed BrowserToolInterruptedError recording whether the editor received the call: undelivered calls retry once transparently, delivered ones tell the agent the edit may or may not have applied and to re-read first. Agents now follow the God Mode build practice: single-page JS goes in the new site_write_page_script tool (the page script the JS panel edits, loaded only on that page), and a new script written with site_write_code_asset must declare its runtime.scope instead of silently loading on every page. MCP server instructions, the site system prompt, and docs are updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new npm package, `instatic` (packages/cli), run with `npx instatic` or `bunx instatic`. It is a thin client of the existing /_instatic/mcp endpoint using a personal access token, so capability checks, the editor bridge, and drafts-until-publish behave exactly as for any MCP client. Commands: login/logout/profiles, status, guide (prints the server's build rules, which shell agents otherwise never see), wait-editor, tools, call, publish, upload, and `mcp` — a local stdio MCP proxy for desktop clients that replaces mcp-remote and reconnects after site restarts. Reliability: failures are classified (auth / unreachable / server) into stable exit codes; reads retry on network and gateway errors; tool calls are re-sent only when the request provably never reached the server, so a write is never applied twice; tool calls get a 150s timeout to cover the server's editor wait plus its 90s per-call limit. The bundle (scripts/build-cli.ts, `bun run cli:build`) inlines every dependency into one file for Node 20+. The MCP SDK import gate now scans packages/ and allows packages/cli/. Publishing to npm stays a manual step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…upload policy
- OAuth redirects (approve and deny) carry `iss` and the metadata
advertises authorization_response_iss_parameter_supported (RFC 9207),
so a client signed in to several sites can reject a mixed-up code.
- The "no workspace connected" tool error carries
`_meta: { "instatic/error": "workspace_not_connected" }`, so clients can
tell "open the editor, then retry" from other errors without matching
message text. The retry path's fallback returns the same result.
- media_upload accepts the installation's upload policy (Settings →
Uploads) instead of a hardcoded image list, matching the Media workspace.
- handleMcpHttp gains a workspaceWaitMs test seam.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `instatic login --url <site>` signs in through the browser (OAuth 2.1 + PKCE, loopback callback, dynamic client registration, constant-time state check, RFC 9207 iss check, resource taken from the site's own metadata). `--with-token` / `--token` keep personal access tokens; `--no-browser` and `--port` cover SSH. - OAuth profiles refresh themselves. Rotated refresh tokens must never be reused, so the profile is read from disk per request and refreshes run only under a cross-process config lock after re-reading it; every config write is locked and atomic. One renew-and-resend after a 401. - A profile's credentials are never sent to a different --url. - `instatic batch` runs many tool calls over one connection (JSON array or NDJSON), one JSON line per result, stop-on-failure or --keep-going. - Exit code 5 when a call needs the editor and none is open; per-command --help; `call --timeout`; `tools --json --schemas`. - README and --help state the CLI is unofficial; README lists all tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. CodeRabbit Verify
|
npm rejects the unscoped name as too similar to the existing ecstatic package. The command stays `instatic`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Republish so the npm package page picks up the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Agents working through MCP reported that the Instatic connection kept dropping, and shell-based agents had no reliable way to drive a site. This adds an unofficial
instaticCLI (packages/cli) that is a thin client of the existing MCP endpoint, plus server fixes that make MCP sessions more reliable and steer agents toward the God Mode panels for CSS and JS.CLI
instatic login --url <site>signs in through the browser (OAuth 2.1 with PKCE, loopback callback, dynamic client registration).--with-token,--no-browser, and--portcover token use and SSH. Saved OAuth sessions refresh themselves without reusing rotated refresh tokens.call,batch,tools,guide,wait-editor,upload,publish,status,profiles, andmcp(a stdio proxy for desktop clients).5means the Site editor is not open, so an agent knows to runwait-editorand retry.packages/cli/README.mdand--helpstate that the CLI is unofficial and not made or endorsed by the Instatic project.Server and MCP
_meta["instatic/error"] = "workspace_not_connected".iss(RFC 9207), and the metadata advertises it.media_uploadfollows the installation's upload policy (Settings → Uploads), not a hardcoded image list.site_write_page_scriptand shared JS to a narrowly scopedsite_write_code_asset. Scripts therefore load only on the pages that use them.Impact
batchfor many calls over one connection.Verification
bun run buildbun test(7,669 pass, 0 fail)bun run lintAlso ran the bundled CLI under Node against a running server: login, token login, status, call, batch, and exit code 5 with no editor open.
Checklist
docs/features/cli.md,docs/features/mcp-connectors.md,docs/features/agent.md,docs/features/god-mode.md,docs/README.md)