@@ -12,2 +12,3 @@ // `insta setup agent` — make this machine's coding agents InstaCloud-native in one step | ||
| import os from 'node:os'; | ||
| import { createInterface } from 'node:readline'; | ||
| import { ApiClient } from '../api.js'; | ||
@@ -17,2 +18,3 @@ import { readPersistedGlobal, resolveEnv } from '../config.js'; | ||
| import { info } from '../util.js'; | ||
| import { loginOauth } from './auth.js'; | ||
| import { envUse } from './env.js'; | ||
@@ -354,3 +356,29 @@ import { installAgentConfigs } from './mcp.js'; | ||
| } | ||
| export async function setupAgent(opts, run = defaultRunner, mint, installConfigs = installAgentConfigs, ensure = (r) => ensureCliInstalled(r), readStored = readPersistedGlobal, switchEnv = (n) => envUse(n)) { | ||
| /** Whether setup should flow straight into login: an interactive human terminal with no session. | ||
| * Pure. Non-TTY (agents, CI, pipes) and -y runs never prompt — a browser OAuth flow cannot work | ||
| * there anyway; they get the printed `next:` hint instead, and prompt.md walks agents through | ||
| * login as its own step (relaying the sign-in link to the human). */ | ||
| export function shouldOfferLogin(yes, loggedIn, stdinTty, stdoutTty) { | ||
| return !yes && !loggedIn && stdinTty && stdoutTty; | ||
| } | ||
| // One Enter continues into the browser login; only an explicit n/no declines. Matches the | ||
| // curl-installer feel: the single command carries you as far as automation can go, and the one | ||
| // genuinely human step (authorizing in the browser) starts itself instead of being homework. | ||
| const defaultAsk = async (question) => { | ||
| const rl = createInterface({ input: process.stdin, output: process.stdout }); | ||
| // EOF (Ctrl-D) closes the interface without ever answering the question — resolve that as a | ||
| // decline instead of hanging forever after the checkmarks. | ||
| const answer = await new Promise((resolve) => { | ||
| rl.on('close', () => resolve('n')); | ||
| rl.question(question, resolve); | ||
| }); | ||
| rl.close(); | ||
| return !/^n/i.test(answer.trim()); | ||
| }; | ||
| export async function setupAgent(opts, run = defaultRunner, mint, installConfigs = installAgentConfigs, ensure = (r) => ensureCliInstalled(r), readStored = readPersistedGlobal, switchEnv = (n) => envUse(n), loginFlow = { | ||
| ask: defaultAsk, | ||
| login: () => loginOauth('github', {}), | ||
| stdinTty: !!process.stdin.isTTY, | ||
| stdoutTty: !!process.stdout.isTTY, | ||
| }) { | ||
| if (!opts.yes && !process.stdout.isTTY) { | ||
@@ -403,6 +431,25 @@ info('non-interactive shell — assuming -y'); | ||
| const loggedIn = !!(stored.accessToken || stored.user); | ||
| info(loggedIn | ||
| ? 'next: `insta project create <name>` in your app repo — or tell your agent: "Fetch https://instacloud.com/prompt.md and follow it"' | ||
| : 'next: `insta login --oauth github` (headless: `insta login --device`), then `insta project create <name>` — or tell your agent: "Fetch https://instacloud.com/prompt.md and follow it"'); | ||
| const nextCreate = 'next: `insta project create <name>` in your app repo — or tell your agent: "Fetch https://instacloud.com/prompt.md and follow it"'; | ||
| if (loggedIn) | ||
| return info(nextCreate); | ||
| // Default into login on an interactive terminal — see shouldOfferLogin. Best-effort: a declined | ||
| // prompt or a failed browser flow leaves a completed setup plus the manual hint, never an error. | ||
| if (shouldOfferLogin(!!opts.yes, loggedIn, loginFlow.stdinTty, loginFlow.stdoutTty)) { | ||
| if (await loginFlow.ask('log in now with GitHub? (Y/n) ')) { | ||
| try { | ||
| await loginFlow.login(); | ||
| // --mcp-token needs a session to mint: the registration above ran logged-out and skipped | ||
| // itself with the login hint — now that the session exists, do the token registration. | ||
| if (opts.mcpToken) | ||
| await registerMcp(run, mint, true); | ||
| return info(nextCreate); | ||
| } | ||
| catch (e) { | ||
| info(` login did not complete (${e instanceof Error ? e.message : String(e)}) — no problem, setup itself is done.`); | ||
| info(' on a remote/SSH machine the browser flow cannot call back here — use `insta login --device` instead.'); | ||
| } | ||
| } | ||
| } | ||
| info('next: `insta login --oauth github` (headless: `insta login --device`), then `insta project create <name>` — or tell your agent: "Fetch https://instacloud.com/prompt.md and follow it"'); | ||
| } | ||
| //# sourceMappingURL=setup.js.map |
+1
-1
| { | ||
| "name": "insta", | ||
| "version": "0.0.38", | ||
| "version": "0.0.39", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "description": "InstaCloud CLI — a thin client of the platform control-plane API.", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
300744
0.89%5210
0.91%