Skip to content

Add CLI wrapper for Subtext MCP tools#10

Draft
chiplay wants to merge 40 commits intomainfrom
chip/cli-wrapper
Draft

Add CLI wrapper for Subtext MCP tools#10
chiplay wants to merge 40 commits intomainfrom
chip/cli-wrapper

Conversation

@chiplay
Copy link
Copy Markdown
Collaborator

@chiplay chiplay commented Apr 7, 2026

Summary

  • Bash CLI (tools/subtext-cli.sh) — single-file wrapper around all 30+ MCP tools using bash + curl + python3. Zero dependencies beyond what's in any sandbox.
  • Node.js CLI (cli/) — publishable as @fullstorydev/subtext-cli on npm, with yargs-based CLI entry point matching the bash CLI's 22-command surface.
  • Node.js SDKSubtextClient class with typed methods for programmatic use (import { SubtextClient } from "@fullstorydev/subtext-cli").

Both CLIs share the same command surface and env var conventions (SECRET_SUBTEXT_API_KEY, SUBTEXT_API_URL, SUBTEXT_SCREENSHOT_DIR).

Based on the integration guide from Clint's earlier CLI work that was lost in the repo cutover.

Test plan

  • 16 passing tests (transport, client, CLI smoke)
  • bash tools/subtext-cli.sh --help shows all 22 commands
  • node cli/build/src/cli/index.js --help shows matching 22 commands
  • Both CLIs error cleanly when SECRET_SUBTEXT_API_KEY is missing
  • subtext connect <url> against a real Subtext endpoint returns connection_id + viewer_url

🤖 Generated with Claude Code

@chiplay chiplay marked this pull request as draft April 7, 2026 21:06
chiplay and others added 14 commits April 8, 2026 05:36
Create tools/subtext-cli.sh with environment variable handling,
JSON-RPC 2.0 call_mcp() function with error handling and base64
screenshot saving, usage help, and command dispatch skeleton.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move help/no-args check before API key validation so --help works
without SECRET_SUBTEXT_API_KEY set. Replace unsafe heredoc JSON
construction with printf to prevent shell expansion of $ in arguments
and use $RANDOM for request IDs. Update usage examples to match
positional arg syntax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tc.)

Adds 10 browser control case branches to the CLI dispatch: connect,
disconnect, snapshot, screenshot, navigate, new-tab, close-tab, tabs,
emulate, and resize. Each validates required args and builds the
appropriate JSON-RPC call via call_mcp.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…wait)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ls, raw)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sets up the cli/ package with TypeScript compilation, SDK entry point,
and HTTP transport for calling the Subtext MCP server. Includes tests
using Node's built-in test runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Maps all CLI commands to SubtextClient methods with proper argument
parsing, image saving support via SUBTEXT_SCREENSHOT_DIR, and lazy
client initialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lidation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…JSON parse error handling

- yargs is a runtime dep needed by the CLI binary, not just dev
- Only ship build/src/ in the npm package, not build/tests/
- Add try/catch around JSON.parse in fill-multi and raw commands

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add json_escape() helper to bash CLI to prevent JSON injection via
  user-supplied strings containing quotes or special characters
- Add .fail() handler to yargs and wrap all async command handlers to
  catch errors and print clean messages instead of stack traces
- Add res.ok and body.error checks to the Node CLI tools command
- Fix README example showing screenshot without required conn_id arg

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chiplay chiplay force-pushed the chip/cli-wrapper branch from bc6131a to 909f300 Compare April 8, 2026 09:36
chiplay and others added 14 commits April 8, 2026 06:00
Implements the sightmap SDK with 7 exported functions:
- findSightmapRoot: walks up directory tree to find .sightmap/ with YAML files
- parseSightmapFile: parses YAML into SightmapConfig (js-yaml)
- flattenComponents: recursively flattens hierarchical components with compound selectors
- collectComponents/collectMemory: aggregates from all YAML files in a sightmap dir
- uploadSightmap: POSTs components+memory to server (token-in-URL, no auth header)
- autoUploadSightmap: orchestrator that silently no-ops when no sightmap found

Includes 28 tests covering discovery, parsing, flattening, collection, upload, and auto-upload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds startTunnelProxy() to the SDK — connects to a WebSocket relay and
proxies HTTP requests back to a local dev server. This replaces the need
for the separate subtext-tunnel MCP server. Requires Node 22+.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When `subtext connect` receives a localhost URL, it now automatically:
1. Calls live-tunnel to allocate a relay
2. Starts the tunnel proxy locally
3. Opens a browser view with the tunnel connection

Also adds a standalone `subtext tunnel <relayUrl>` command for manual use.
Use --no-tunnel on connect to disable auto-tunneling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…utput, version

- P0: Force string type for component_id in click, fill, hover, keypress,
  drag, wait commands (yargs was coercing numeric IDs to numbers)
- P1: Sightmap parses 'label' as fallback for 'name', warns on usage;
  sightmap show prints component names and warns on empty results
- P1: Accept both SECRET_SUBTEXT_API_KEY and SUBTEXT_API_KEY env vars
- P1: Add --output/-o flag to screenshot command for saving to a file path
- P2: --version now prints the actual package.json version (0.2.1)
- Bump version to 0.2.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds comprehensive README.md with all CLI commands, visual verification
workflow, sightmap reference, and SDK usage. Adds `get-skill` command that
prints a self-contained agent skill document to stdout. Includes README.md
in the npm package files array.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
chiplay and others added 12 commits April 8, 2026 17:50
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… docs

- Fix emulate to send `preset` instead of `device` (matches MCP schema)
- Fix exit code handling: use process.exitCode instead of process.exit()
  race, and check after handler completion
- Remove embed-token command and getEmbedToken (WIP, not ready)
- Remove integration guide and planning docs from changeset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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