insta 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -285,39 +285,35 @@ const defaultMinter = async () => {
285
285
  return null;
286
286
  }
287
287
  };
288
- // Register the insta-cloud remote MCP server with Claude Code (user scope, so it follows the
289
- // machine like the skill install above). Default is OAuth: register with NO credential — the
290
- // platform's Better Auth MCP authorization server is discovered via RFC 9728 and Claude runs
291
- // the browser flow on first `/mcp` use, so no static token ever lands on disk. `--mcp-token`
292
- // is the headless fallback (CI, no browser): mint a durable token into the header instead.
293
- // Idempotent — an existing registration is left alone. Best-effort: the skill install is the
294
- // primary outcome; agents without an MCP registry are covered by the skill alone.
295
- export async function registerMcp(run = defaultRunner, mint = defaultMinter, useToken = false) {
288
+ export async function registerMcp(run = defaultRunner, mint = defaultMinter, useToken = false, announce = true) {
296
289
  const { name, url } = await resolveMcpTarget();
297
290
  if (!(await run('claude', ['--version'])).ok)
298
- return; // no Claude Code on this machine
291
+ return 'no-claude'; // no Claude Code on this machine
299
292
  if ((await run('claude', ['mcp', 'get', name])).ok) {
300
- info(`✓ MCP — ${name} already registered with Claude Code`);
301
- return;
293
+ if (announce)
294
+ info(`✓ MCP — ${name} already registered with Claude Code`);
295
+ return 'existing';
302
296
  }
303
297
  const args = ['mcp', 'add', '--transport', 'http', '--scope', 'user', name, url];
304
298
  if (useToken) {
305
299
  const token = await mint();
306
300
  if (!token) {
307
301
  info(' MCP not registered (--mcp-token needs a login) — run `insta login`, then `insta setup agent --mcp-token` again');
308
- return;
302
+ return 'no-token';
309
303
  }
310
304
  args.push('--header', `Authorization: Bearer ${token}`);
311
305
  }
312
306
  const res = await run('claude', args);
313
- if (res.ok) {
307
+ if (!res.ok) {
308
+ info(` MCP registration failed — add manually:\n claude mcp add --transport http ${name} ${url}`);
309
+ return 'failed';
310
+ }
311
+ if (announce) {
314
312
  info(`✓ MCP — ${name} registered with Claude Code (\`claude mcp list\` to verify)`);
315
313
  if (!useToken)
316
314
  info(' first use: run `/mcp` in Claude Code and authorize in the browser (headless machines: `insta setup agent --mcp-token`)');
317
315
  }
318
- else {
319
- info(` MCP registration failed — add manually:\n claude mcp add --transport http ${name} ${url}`);
320
- }
316
+ return 'new';
321
317
  }
322
318
  /** The environment `setup agent` should target, and whether the machine must be switched to it
323
319
  * first. Pure — decides only; the caller performs the switch.
@@ -414,31 +410,23 @@ export async function setupAgent(opts, run = defaultRunner, mint, installConfigs
414
410
  return;
415
411
  }
416
412
  info(summarizeInstall(res.output ?? ''));
417
- info(' every coding agent on this machine now knows InstaCloud (review skills before use — they run with full permissions).');
418
- await registerMcp(run, mint, !!opts.mcpToken);
413
+ // Register everything first, summarize ONCE below: Claude Code via `claude mcp add`, every other
414
+ // agent via a config-file entry — different mechanisms, one outcome, one line.
415
+ let claude = await registerMcp(run, mint, !!opts.mcpToken, false);
419
416
  const others = await installConfigs();
420
- if (others.length)
421
- info(`✓ MCP — also configured for ${others.join(', ')} (restart those tools to pick it up)`);
422
- // The checkmarks end the install, but the user's next move shouldn't be guesswork. Local state
423
- // only (no network): a config with a session means logged in — good enough for a hint.
424
- // Deliberately prod-hosted prompt.md even on a staging setup: it is generic onboarding (the
425
- // login/create commands in it are env-aware at runtime), and staging serves no equivalent.
426
- const stored = await readStored();
427
- const loggedIn = !!(stored.accessToken || stored.user);
428
- const nextCreate = 'next: `insta project create <name>` in your app repo — or tell your agent: "Fetch https://instacloud.com/prompt.md and follow it"';
429
- if (loggedIn)
430
- return info(nextCreate);
431
- // Default into login on an interactive terminal — see shouldOfferLogin. Best-effort: a declined
417
+ // Default into login on an interactive terminal (see shouldOfferLogin) BEFORE the MCP summary:
418
+ // a --mcp-token registration needs the session to mint, so a post-login retry must land in the
419
+ // same combined line instead of announcing Claude Code separately. Best-effort: a declined
432
420
  // prompt or a failed browser flow leaves a completed setup plus the manual hint, never an error.
421
+ const stored = await readStored();
422
+ let loggedIn = !!(stored.accessToken || stored.user);
433
423
  if (shouldOfferLogin(!!opts.yes, loggedIn, loginFlow.stdinTty, loginFlow.stdoutTty)) {
434
424
  if (await loginFlow.ask('log in now with GitHub? (Y/n) ')) {
435
425
  try {
436
426
  await loginFlow.login();
437
- // --mcp-token needs a session to mint: the registration above ran logged-out and skipped
438
- // itself with the login hint — now that the session exists, do the token registration.
427
+ loggedIn = true;
439
428
  if (opts.mcpToken)
440
- await registerMcp(run, mint, true);
441
- return info(nextCreate);
429
+ claude = await registerMcp(run, mint, true, false);
442
430
  }
443
431
  catch (e) {
444
432
  info(` login did not complete (${e instanceof Error ? e.message : String(e)}) — no problem, setup itself is done.`);
@@ -446,6 +434,21 @@ export async function setupAgent(opts, run = defaultRunner, mint, installConfigs
446
434
  }
447
435
  }
448
436
  }
449
- 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"');
437
+ // The one MCP line. The restart note exists because config-file agents only read their config
438
+ // at startup; Claude Code picks it up live.
439
+ const mcpTargets = [...(claude === 'new' || claude === 'existing' ? ['Claude Code'] : []), ...others];
440
+ if (mcpTargets.length) {
441
+ info(`✓ MCP — ${mcpTargets.join(', ')}${others.length ? ' (already-running tools load it on restart)' : ''}`);
442
+ }
443
+ if (claude === 'new' && !opts.mcpToken) {
444
+ info(' Claude Code first use: run `/mcp` and authorize in the browser (headless machines: `insta setup agent --mcp-token`)');
445
+ }
446
+ // The checkmarks end the install, but the user's next move shouldn't be guesswork. Agent-first:
447
+ // the whole point of setup is that the machine's coding agents now know InstaCloud (skill + MCP)
448
+ // and can drive `insta` themselves — project create/link, deploys, and (via the device flow)
449
+ // even login. The human's next move is simply to go build.
450
+ info(loggedIn
451
+ ? 'next: open a coding-agent session in your app directory and keep building — your agents know InstaCloud now'
452
+ : 'next: open a coding-agent session in your app directory and keep building — your agents know InstaCloud now (they will walk you through `insta login` when it is needed)');
450
453
  }
451
454
  //# sourceMappingURL=setup.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insta",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "type": "module",
5
5
  "description": "InstaCloud CLI — a thin client of the platform control-plane API.",
6
6
  "keywords": [