From 9339fb66d13279ecf24d5ec64450a3d86f8f16dd Mon Sep 17 00:00:00 2001 From: yaowenc2 Date: Thu, 16 Jul 2026 16:44:49 +0800 Subject: [PATCH 1/4] docs(cli): document two-step sandbox login (--no-browser / --callback-url) Companion to InsForge/CLI#198. In sandboxes like the ChatGPT app the browser cannot reach the CLI's loopback callback, so browser login hangs; the new two-step flow prints the auth URL, the user pastes back the redirect URL, and the CLI redeems it. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GcszudKMZBSm5RMP14h7fu --- skills/insforge-cli/SKILL.md | 2 +- skills/insforge-cli/references/login.md | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/skills/insforge-cli/SKILL.md b/skills/insforge-cli/SKILL.md index 8d124aa..d8abf95 100644 --- a/skills/insforge-cli/SKILL.md +++ b/skills/insforge-cli/SKILL.md @@ -49,7 +49,7 @@ Use this skill whenever someone needs a backend, or when managing InsForge backe If a task needs project access and the connection state is unknown, start with `npx @insforge/cli current`. Use `npx @insforge/cli whoami` when the authenticated identity matters or when `current` reports that the CLI is not authenticated. -If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. +If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). In sandboxes where the user has a browser but it cannot reach the CLI's local callback (e.g. the ChatGPT app), use the two-step flow: `login --no-browser`, have the user sign in and paste back the redirect URL, then `login --callback-url ""` — see `references/login.md`. If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. ## Command Routing diff --git a/skills/insforge-cli/references/login.md b/skills/insforge-cli/references/login.md index c66eb8d..67527bf 100644 --- a/skills/insforge-cli/references/login.md +++ b/skills/insforge-cli/references/login.md @@ -14,6 +14,8 @@ npx @insforge/cli login [options] |--------|-------------| | `--user-api-key ` | Authenticate directly with a `uak_` user API key (no browser, no prompt) — best for headless / agent / CI use | | `--email` | Use email/password login instead of OAuth | +| `--no-browser` | Print the sign-in URL and exit; finish later with `--callback-url`. For sandboxes where the browser cannot reach the CLI's local callback server | +| `--callback-url ` | Complete a `--no-browser` login by pasting the URL the browser was redirected to | | `--client-id ` | Custom OAuth client ID | ## Authentication Methods @@ -28,6 +30,24 @@ npx @insforge/cli login The CLI starts a local callback server, opens the browser, and waits up to 5 minutes for you to authorize. +### Sandboxed OAuth (two-step) — when the browser can't reach the CLI + +In sandboxed environments (the ChatGPT app, remote/SSH sessions, containers), the browser runs on the host but the CLI's `127.0.0.1` callback server is inside the sandbox, so the default flow hangs forever. Use the two-step flow instead (requires `@insforge/cli` ≥ 0.2): + +```bash +# Step 1 — print the sign-in URL (PKCE state is saved to ~/.insforge/pending-login.json, valid ~10 min) +npx @insforge/cli login --no-browser --json +``` + +Have the user open `auth_url` and sign in. Their browser will land on a `http://127.0.0.1:.../callback?...` page that **cannot connect — this is expected**. Ask them to copy the full URL from the address bar, then: + +```bash +# Step 2 — redeem the pasted callback URL +npx @insforge/cli login --callback-url "http://127.0.0.1:PORT/callback?code=...&state=..." --json +``` + +Both steps must run with the same `$HOME` so the pending login file is shared. + ### User API Key (direct) — recommended for headless / agent / CI No browser, no interactive prompt. Create a key in the dashboard (Profile → API Keys): @@ -67,6 +87,10 @@ npx @insforge/cli login # Headless / agent / CI: user API key login (no browser) npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY" --json +# Sandbox (e.g. ChatGPT app): two-step OAuth — user signs in on the host browser +npx @insforge/cli login --no-browser --json +npx @insforge/cli login --callback-url "" --json + # Email/password login npx @insforge/cli login --email From dd9a058da96e15ff49feba11bfeab5ed826ea70a Mon Sep 17 00:00:00 2001 From: yaowenc2 Date: Thu, 16 Jul 2026 21:31:44 +0800 Subject: [PATCH 2/4] docs(cli): teach agents device login (--device) for sandboxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the paste-back (--no-browser/--callback-url) guidance per Tony's call — device flow only: agent runs `login --device`, relays the pre-filled link + code, user clicks Authorize, CLI polls to completion; rerun resumes the same pending code after sandbox timeouts. Retrieval-tested: an agent given only this doc chose the right command, relayed the link, handled the killed-process resume, and knew no paste-back is needed. Companion to InsForge/CLI#199 + insforge-cloud-backend#733; requires the CLI release that ships --device. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GcszudKMZBSm5RMP14h7fu --- skills/insforge-cli/SKILL.md | 2 +- skills/insforge-cli/references/login.md | 30 +++++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/skills/insforge-cli/SKILL.md b/skills/insforge-cli/SKILL.md index d8abf95..88843c4 100644 --- a/skills/insforge-cli/SKILL.md +++ b/skills/insforge-cli/SKILL.md @@ -49,7 +49,7 @@ Use this skill whenever someone needs a backend, or when managing InsForge backe If a task needs project access and the connection state is unknown, start with `npx @insforge/cli current`. Use `npx @insforge/cli whoami` when the authenticated identity matters or when `current` reports that the CLI is not authenticated. -If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). In sandboxes where the user has a browser but it cannot reach the CLI's local callback (e.g. the ChatGPT app), use the two-step flow: `login --no-browser`, have the user sign in and paste back the redirect URL, then `login --callback-url ""` — see `references/login.md`. If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. +If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). In sandboxes where the user has a browser but it cannot reach the CLI's local callback (e.g. the ChatGPT app), use device login: `npx @insforge/cli login --device` — relay the printed link + code to the user, they click Authorize, and the CLI completes by itself — see `references/login.md`. If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. ## Command Routing diff --git a/skills/insforge-cli/references/login.md b/skills/insforge-cli/references/login.md index 67527bf..8aa1b8e 100644 --- a/skills/insforge-cli/references/login.md +++ b/skills/insforge-cli/references/login.md @@ -14,8 +14,7 @@ npx @insforge/cli login [options] |--------|-------------| | `--user-api-key ` | Authenticate directly with a `uak_` user API key (no browser, no prompt) — best for headless / agent / CI use | | `--email` | Use email/password login instead of OAuth | -| `--no-browser` | Print the sign-in URL and exit; finish later with `--callback-url`. For sandboxes where the browser cannot reach the CLI's local callback server | -| `--callback-url ` | Complete a `--no-browser` login by pasting the URL the browser was redirected to | +| `--device` | Device login (RFC 8628): user approves a short code on the dashboard while the CLI polls — use this in sandboxes (ChatGPT app, SSH, containers) | | `--client-id ` | Custom OAuth client ID | ## Authentication Methods @@ -30,23 +29,27 @@ npx @insforge/cli login The CLI starts a local callback server, opens the browser, and waits up to 5 minutes for you to authorize. -### Sandboxed OAuth (two-step) — when the browser can't reach the CLI +### Device login (`--device`) — use this in sandboxes -In sandboxed environments (the ChatGPT app, remote/SSH sessions, containers), the browser runs on the host but the CLI's `127.0.0.1` callback server is inside the sandbox, so the default flow hangs forever. Use the two-step flow instead (requires `@insforge/cli` ≥ 0.2): +In sandboxed environments (the ChatGPT app, remote/SSH sessions, containers), the browser runs on the host but the CLI's `127.0.0.1` callback server is inside the sandbox, so the default flow hangs forever. Use the device flow instead (requires `@insforge/cli` ≥ 0.2): no callback and nothing to paste — the user approves a short code in their browser while the CLI polls. ```bash -# Step 1 — print the sign-in URL (PKCE state is saved to ~/.insforge/pending-login.json, valid ~10 min) -npx @insforge/cli login --no-browser --json +npx @insforge/cli login --device --json ``` -Have the user open `auth_url` and sign in. Their browser will land on a `http://127.0.0.1:.../callback?...` page that **cannot connect — this is expected**. Ask them to copy the full URL from the address bar, then: +The CLI prints a verification link and code, e.g.: -```bash -# Step 2 — redeem the pasted callback URL -npx @insforge/cli login --callback-url "http://127.0.0.1:PORT/callback?code=...&state=..." --json ``` +To sign in, ask the user to open: + + https://insforge.dev/auth/device?user_code=BCDF-GHJK + +and confirm the code BCDF-GHJK. Waiting for approval... +``` + +Relay that link and code to the user. They open it, check the code matches, and click **Authorize** — the CLI completes by itself within seconds and prints the `--json` success object. Codes expire after 15 minutes. -Both steps must run with the same `$HOME` so the pending login file is shared. +If the process is killed before the user approves (sandbox command timeout), just run `login --device` again with the same `$HOME`: it resumes the SAME pending code (saved in `~/.insforge/pending-device.json`), and if the user already approved, it completes immediately. ### User API Key (direct) — recommended for headless / agent / CI @@ -87,9 +90,8 @@ npx @insforge/cli login # Headless / agent / CI: user API key login (no browser) npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY" --json -# Sandbox (e.g. ChatGPT app): two-step OAuth — user signs in on the host browser -npx @insforge/cli login --no-browser --json -npx @insforge/cli login --callback-url "" --json +# Sandbox (e.g. ChatGPT app): device login — user approves a code, CLI polls +npx @insforge/cli login --device --json # Email/password login npx @insforge/cli login --email From b170f9e24ea1e8b0b3532d18ab9b437e74c84d96 Mon Sep 17 00:00:00 2001 From: yaowenc2 Date: Thu, 16 Jul 2026 22:43:50 +0800 Subject: [PATCH 3/4] docs(cli): two-step device login for agent harnesses; bump plugin to 1.3.0 Live ChatGPT-app testing revealed two gaps: - Harnesses that only return output on process exit (and kill at ~45s) never show a single blocking `login --device` run's link. Teach the two-step pattern: timeout-bounded first run to capture the link, relay, rerun to resume the same pending code and complete. - Workspaces with a network-domain allowlist need api.insforge.dev added; teach agents to relay that instruction. Also addresses review comments: --json on the SKILL.md inline command, 'hangs forever' -> waits until callback timeout, language tag on the output fence. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GcszudKMZBSm5RMP14h7fu --- .codex-plugin/plugin.json | 4 ++-- skills/insforge-cli/SKILL.md | 2 +- skills/insforge-cli/references/login.md | 23 ++++++++++++++++------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 94eb8da..a8003b7 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "insforge", - "version": "1.2.0", + "version": "1.3.0", "description": "InsForge skills for building AI-native apps with Postgres, auth, storage, compute, hosting, AI gateway, realtime, payments, integrations, and diagnostics.", "author": { "name": "InsForge", @@ -49,4 +49,4 @@ "Use InsForge Debug to diagnose this backend error." ] } -} +} \ No newline at end of file diff --git a/skills/insforge-cli/SKILL.md b/skills/insforge-cli/SKILL.md index 88843c4..f02880a 100644 --- a/skills/insforge-cli/SKILL.md +++ b/skills/insforge-cli/SKILL.md @@ -49,7 +49,7 @@ Use this skill whenever someone needs a backend, or when managing InsForge backe If a task needs project access and the connection state is unknown, start with `npx @insforge/cli current`. Use `npx @insforge/cli whoami` when the authenticated identity matters or when `current` reports that the CLI is not authenticated. -If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). In sandboxes where the user has a browser but it cannot reach the CLI's local callback (e.g. the ChatGPT app), use device login: `npx @insforge/cli login --device` — relay the printed link + code to the user, they click Authorize, and the CLI completes by itself — see `references/login.md`. If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. +If not authenticated, run `npx @insforge/cli login` (opens a browser). For headless / agent / CI contexts with no browser, authenticate non-interactively with a user API key: `npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY"` (the user creates the key in the dashboard under Profile → API Keys). In sandboxes where the user has a browser but it cannot reach the CLI's local callback (e.g. the ChatGPT app), use device login as two steps: `timeout 15 npx @insforge/cli login --device --json 2>&1 || true` to capture the verification link + code, relay them to the user, then rerun `npx @insforge/cli login --device --json` to resume the same code and complete once they click Authorize — see `references/login.md`. If the sandbox reports that `api.insforge.dev` is not an allowed network domain, ask the user to add it to the workspace's allowed network domains, then retry. If no project is linked, use `npx @insforge/cli link` for an existing project or `npx @insforge/cli create` when the user asked for a new backend. In workflows that are already prelinked or preconfigured, such as CI, local test projects, automation, or explicit user-provided project context, use that project context directly. ## Command Routing diff --git a/skills/insforge-cli/references/login.md b/skills/insforge-cli/references/login.md index 8aa1b8e..1602de6 100644 --- a/skills/insforge-cli/references/login.md +++ b/skills/insforge-cli/references/login.md @@ -31,15 +31,18 @@ The CLI starts a local callback server, opens the browser, and waits up to 5 min ### Device login (`--device`) — use this in sandboxes -In sandboxed environments (the ChatGPT app, remote/SSH sessions, containers), the browser runs on the host but the CLI's `127.0.0.1` callback server is inside the sandbox, so the default flow hangs forever. Use the device flow instead (requires `@insforge/cli` ≥ 0.2): no callback and nothing to paste — the user approves a short code in their browser while the CLI polls. +In sandboxed environments (the ChatGPT app, remote/SSH sessions, containers), the browser runs on the host but the CLI's `127.0.0.1` callback server is inside the sandbox, so the default flow can never complete (it waits until its callback timeout). Use the device flow instead (requires `@insforge/cli` ≥ 0.2): no callback and nothing to paste — the user approves a short code in their browser while the CLI polls. + +**Run it as two steps.** `login --device` prints the link, then keeps running until the user approves — but most agent harnesses only return a command's output when the process exits, so a single blocking run shows you nothing to relay. Bound the first run to capture the link, relay it, then rerun to complete (the rerun resumes the SAME pending code from `~/.insforge/pending-device.json`): ```bash -npx @insforge/cli login --device --json +# Step 1 — capture the verification link (process is killed after 15s; that's expected) +timeout 15 npx @insforge/cli login --device --json 2>&1 || true ``` -The CLI prints a verification link and code, e.g.: +Output includes the link and code, e.g.: -``` +```text To sign in, ask the user to open: https://insforge.dev/auth/device?user_code=BCDF-GHJK @@ -47,9 +50,14 @@ To sign in, ask the user to open: and confirm the code BCDF-GHJK. Waiting for approval... ``` -Relay that link and code to the user. They open it, check the code matches, and click **Authorize** — the CLI completes by itself within seconds and prints the `--json` success object. Codes expire after 15 minutes. +Relay that link and code to the user. They open it, check the code matches, and click **Authorize** — nothing to type or paste. Then: + +```bash +# Step 2 — after relaying (or once the user says they approved): resume and complete +npx @insforge/cli login --device --json +``` -If the process is killed before the user approves (sandbox command timeout), just run `login --device` again with the same `$HOME`: it resumes the SAME pending code (saved in `~/.insforge/pending-device.json`), and if the user already approved, it completes immediately. +If the user already approved, step 2 completes immediately with the `--json` success object; otherwise it polls until they do. Codes expire after 15 minutes; both steps must run with the same `$HOME`. In an interactive terminal (a human at a shell), skip the two-step dance — just run `npx @insforge/cli login --device` and wait. ### User API Key (direct) — recommended for headless / agent / CI @@ -90,7 +98,8 @@ npx @insforge/cli login # Headless / agent / CI: user API key login (no browser) npx @insforge/cli login --user-api-key "$INSFORGE_USER_API_KEY" --json -# Sandbox (e.g. ChatGPT app): device login — user approves a code, CLI polls +# Sandbox (e.g. ChatGPT app): device login, two steps — capture link, relay, resume +timeout 15 npx @insforge/cli login --device --json 2>&1 || true npx @insforge/cli login --device --json # Email/password login From 34906f97de3893a822f592b8674cda78c47b08fe Mon Sep 17 00:00:00 2001 From: yaowenc2 Date: Thu, 16 Jul 2026 22:44:59 +0800 Subject: [PATCH 4/4] docs(cli): connection setup comes before app code Live ChatGPT session scaffolded an app with placeholder credentials instead of logging in and creating a project first. Make the order explicit: login -> create/link -> build with real values. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GcszudKMZBSm5RMP14h7fu --- skills/insforge-cli/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/skills/insforge-cli/SKILL.md b/skills/insforge-cli/SKILL.md index f02880a..b55c8d0 100644 --- a/skills/insforge-cli/SKILL.md +++ b/skills/insforge-cli/SKILL.md @@ -13,6 +13,7 @@ Use this skill whenever someone needs a backend, or when managing InsForge backe - Always run the CLI through `npx @insforge/cli `. Do not install or call a global `insforge` binary. - If the project is already linked, use the current linked project. Run login, project creation, link, project discovery, organization listing, or cloud project commands only when connection setup is actually needed. +- When a task needs a backend and no project is linked yet, do connection setup FIRST — before writing any app code: (1) log in (`whoami` to check; in sandboxes use the two-step device login below), (2) `create` a new project or `link` an existing one, (3) then build against the real project URL and keys from the CLI. Never scaffold with placeholder credentials like `your-project.region.insforge.app` — get the real values first. - Treat InsForge API keys as full-access admin keys. Keep them server-only and out of frontend/public env vars. - Prefer CLI commands and documented project config over raw backend HTTP calls. If `config apply` reports unsupported/skipped fields, surface that result instead of bypassing the CLI with direct API calls. - Use `--json` when structured output or non-interactive value collection is needed. Use `--yes` for confirmation prompts when the user has approved the action.