Evidence — things that were actually run, with what came back·
Each entry names the commit it was run against, the command, and the observable result. Secrets never appear here; where a token was involved the file that held it (0600, outside the repo) is named instead.
CLI — npx tiny-vercel against the live scratch deployment (C4), 2026-09-15 18:37–18:42Z·
Commit 6b9b0f0 (apps/cli), scratch web redeployed from that commit via vercel deploy --prod
so /api/health advertises siteName + workerUrl. Isolated TINY_HOME=/tmp/tv-home-1e0A
(nothing under the operator's real ~/.tiny was read or written).
| Step | Command | Result |
|---|---|---|
| 0 | curl https://tiny-vercel-scratch.vercel.app/api/health |
{"ok":true,"service":"web","siteName":"tiny-vercel","workerUrl":"https://tiny-vercel-worker.cagatay.workers.dev",…} |
| 1 | node apps/cli/dist/cli.js init https://tiny-vercel-scratch.vercel.app |
✓ tiny-vercel at https://tiny-vercel-scratch.vercel.app · worker https://tiny-vercel-worker.cagatay.workers.dev — config.json (0600) = {version:1, api, worker, siteName:"tiny-vercel", updatedAt}. 0.21 s including the probe. |
| 2 | session for the consent click | The scratch app has no GitHub OAuth App (D-010), so the browser sign-in that normally precedes /auth/cli cannot happen. A 40-minute tiny_session JWT was minted with the scratch AUTH_JWT_SECRET (~/.tiny/tiny-vercel-scratch/AUTH_JWT_SECRET, 0600) for sub gh:1234567 / login cagataycali; GET /api/me with it → 200. This stands in for "the user is signed in on the web"; everything after it is the real CLI path. |
| 3 | TINY_NO_BROWSER=1 node dist/cli.js login |
CLI listened on 127.0.0.1:64264, printed …/auth/cli?port=64264&state=0bJuN8Db…. The consent page's Approve action was reproduced exactly: POST /api/auth/cli {port,state} with the session cookie → {"redirect":"http://127.0.0.1:64264/callback?code=<5-min aud:tiny-cli-code JWT>&state=…"}; curl of that redirect → loopback 200. The CLI exchanged the code at POST /api/auth/cli/token and printed ✓ Logged in as @cagataycali (token valid ~90 days) then ✓ Device enrolled: cagatay-mac (fb1aa09a…) — manage at https://tiny-vercel-scratch.vercel.app/devices. Files: credentials.json (apiUrl = scratch origin, expires 90 d), device.json (deviceId fb1aa09a-821a-4d48-b6cf-73aca773d7c0, name cagatay-mac, apiUrl = scratch origin), all 0600. |
| 4 | node dist/cli.js whoami / devices |
@cagataycali (C2 (cli proof)) · no tinys yet — create one … at tiny-vercel-scratch.vercel.app (host is the configured app, not a constant) · ● cagatay-mac [cli/darwin-arm64] seen 2026-09-15 18:37 (this machine) |
| 5 | node dist/cli.js mesh (daemon: heartbeat + relay poller + tray socket) |
📡 relay: polling for web-agent envelopes (use_device) · 🎛 tray: /tmp/tv-home-1e0A/tray.sock · 🧰 presence: 43 tools advertised. Also joined the owner's LAN zenoh mesh as a wire-compatible peer (11 devduck/tiny-tech peers discovered) — the mesh does not depend on the backend. |
| 6 | GET /api/devices (web, session cookie) |
{"id":"fb1aa09a-…","name":"cagatay-mac","kind":"cli","platform":"darwin-arm64","capabilities":"[\"mcp\",\"files\",\"apple\",\"spotify\",\"computer\",\"windows\",\"flipper\",\"adb\",\"whatsapp\",\"google\",\"telegram\",\"npm\",\"pypi\",\"openapi\",\"memory\",\"github\",\"image\",\"integrations\"]","last_seen":1789497535,"online":true} — the heartbeat is visible on the scratch app's device list with the capabilities this Mac actually has. |
| 7 | use_device round-trip — POST /api/chat on the scratch web (session cookie, x-tiny-name: tiny) asking the agent to use_device list → invoke cagatay-mac with cat /tmp/tv-proof-335ad3a4.txt && uname -m && sw_vers -productVersion |
96 SSE events, 22.2 s. beforeToolCallEvent use_device {"action":"list"} → {"ok":true,"devices":[{"id":"fb1aa09a-…","online":true,"last_seen_seconds_ago":5,…}]}; use_device {"action":"invoke","device_id":"fb1aa09a-…","prompt":"run the shell command: …"} → {"ok":true,"device_id":"fb1aa09a-…","envelope_id":"7c45250b-0f2e-412d-ba08-192cd408da71","result":"tiny-vercel-proof-335ad3a4\narm64\n26.4.1"}. Final assistant text: tiny-vercel-proof-335ad3a4 / arm64 / 26.4.1 / Device ID invoked: fb1aa09a-821a-4d48-b6cf-73aca773d7c0. The nonce file existed only on this Mac and was created seconds before the request, so the answer could only have come through relay → this CLI → shell. |
| 8 | tray protocol | node dist/cli.js tray status → device: cagatay-mac — online · peers: 11 · relay: polling; raw socket status reply carries webUrl: https://tiny-vercel-scratch.vercel.app (the field the menu bar now opens instead of a hard-coded site). |
Cleanup: daemon stopped, device fb1aa09a… revoked via the web, /tmp/tv-home-1e0A and the session JWT deleted (see the journal entry for the exact commands).
CLI — size and startup (C5), same commit·
| Measure | Value |
|---|---|
tsc build |
2.3 s, 73 .js files, dist/ 1.4 MB |
node dist/cli.js help |
0.08 s wall (5 runs; the help path imports only config/auth) |
node dist/cli.js init <url> |
0.21 s including the /api/health probe |
MCP serve: process start → initialize reply |
744 ms (loads the MCP SDK + 30 tool schemas) |
node --test test/*.test.mjs |
1445 tests, 0 failures, 17 s |
swift test (menubar) |
all pass, 14 s |
npm pack |
tiny-vercel-0.1.0.tgz — 425.5 kB packed, 1.4 MB unpacked, 75 files: dist/** (73), package.json, README.md; shasum 3d0b09a1625663e6668983231f7cf5a0e9fd16a6; gitleaks over the extracted tarball: no leaks; grep tiny.technology: 0 files |
fresh npm install <tarball> in an empty dir |
223 packages, 3.1 s, 120 MB node_modules, node_modules/.bin/tiny-vercel help prints the banner |
npm publish --dry-run --ignore-scripts |
would publish tiny-vercel@0.1.0 to registry.npmjs.org, tag latest, default (public) access |
| registry | npm view tiny-vercel → 404 (name free); npm whoami on this Mac → E401 (no npm login here — publishing needs the owner's npm login or a granular token) |