insta 0.0.51 → 0.0.52
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.
- package/dist/commands/setup.js +34 -13
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -16,7 +16,7 @@ import { DEFAULT_ENV, ENVS, ENV_NAMES, envForApiUrl, envFromEnvVar, isEnvName, m
|
|
|
16
16
|
import { info, openUrl } from '../util.js';
|
|
17
17
|
import { isRunnableFile, resolveSpawnable } from '../spawn.js';
|
|
18
18
|
import { loginDevice } from './auth.js';
|
|
19
|
-
import { projectLink } from './project.js';
|
|
19
|
+
import { projectCreate, projectLink, slugifyName } from './project.js';
|
|
20
20
|
import { envUse } from './env.js';
|
|
21
21
|
import { installAgentConfigs } from './mcp.js';
|
|
22
22
|
import { detectChannel } from './upgrade.js';
|
|
@@ -276,6 +276,18 @@ export function planSetupEnv(flagEnv, persistedApiUrl, apiUrlOverride = process.
|
|
|
276
276
|
const target = envVar ?? DEFAULT_ENV;
|
|
277
277
|
return { target, switch: persisted !== target };
|
|
278
278
|
}
|
|
279
|
+
/** The project step. Only a contradictory flag pair throws: rejecting a nameless `--create` here
|
|
280
|
+
* would abort the whole setup, and `projectCreate` already guides that case. */
|
|
281
|
+
export function planProject(opts) {
|
|
282
|
+
if (opts.create !== undefined && opts.project !== undefined) {
|
|
283
|
+
throw new Error('--create and --project are mutually exclusive — create a new project, or link an existing one');
|
|
284
|
+
}
|
|
285
|
+
if (opts.project)
|
|
286
|
+
return { kind: 'link', id: opts.project };
|
|
287
|
+
if (opts.create === undefined)
|
|
288
|
+
return { kind: 'none' };
|
|
289
|
+
return { kind: 'create', name: typeof opts.create === 'string' ? opts.create : undefined };
|
|
290
|
+
}
|
|
279
291
|
/** Whether setup should flow straight into login: an interactive human terminal with no session.
|
|
280
292
|
* Pure. Non-TTY (agents, CI, pipes) and -y runs never prompt — a browser OAuth flow cannot work
|
|
281
293
|
* there anyway; they get the printed `next:` hint instead, and prompt.md walks agents through
|
|
@@ -350,10 +362,12 @@ export async function setupAgent(opts, run = defaultRunner, mint, installConfigs
|
|
|
350
362
|
login: () => loginDevice({}, openUrl),
|
|
351
363
|
stdinTty: canPromptViaTty(),
|
|
352
364
|
stdoutTty: !!process.stdout.isTTY,
|
|
353
|
-
}, link = projectLink) {
|
|
365
|
+
}, link = projectLink, create = (n) => projectCreate(n, {})) {
|
|
354
366
|
if (!opts.yes && !process.stdout.isTTY) {
|
|
355
367
|
info('non-interactive shell — assuming -y');
|
|
356
368
|
}
|
|
369
|
+
// Reject an impossible --project/--create request here, while the machine is still untouched.
|
|
370
|
+
const project = planProject(opts);
|
|
357
371
|
// Pin the environment BEFORE anything is installed (see planSetupEnv). A required switch goes
|
|
358
372
|
// through `env use` — the one path that persists the choice and drops the now-foreign session —
|
|
359
373
|
// and announces itself, so the machine can never end up with its CLI on one deployment and its
|
|
@@ -411,26 +425,33 @@ export async function setupAgent(opts, run = defaultRunner, mint, installConfigs
|
|
|
411
425
|
}
|
|
412
426
|
}
|
|
413
427
|
}
|
|
414
|
-
// --project:
|
|
415
|
-
//
|
|
416
|
-
// every Windows shell, and in shells without bracketed paste the queued
|
|
417
|
-
// the answer to the login prompt above (console PR #290).
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
if (
|
|
428
|
+
// --project / --create: bind this directory to a project inside the SAME process. Never split
|
|
429
|
+
// this back into `setup agent && insta project <cmd>` as one paste: no shell joiner survives
|
|
430
|
+
// every Windows shell, and in shells without bracketed paste the queued second line is eaten
|
|
431
|
+
// as the answer to the login prompt above (console PR #290). Both need the session: without
|
|
432
|
+
// one the manual command is the hint, never a hang; a failure (bad id, no access, name taken)
|
|
433
|
+
// is a REAL error — binding a project is the entire point of the flag — so it sets the exit
|
|
434
|
+
// code instead of pretending setup succeeded.
|
|
435
|
+
if (project.kind !== 'none') {
|
|
436
|
+
const linking = project.kind === 'link';
|
|
437
|
+
const retry = linking
|
|
438
|
+
? `insta project link ${project.id}`
|
|
439
|
+
: `insta project create${project.name ? ` ${slugifyName(project.name)}` : ''}`;
|
|
422
440
|
if (!loggedIn) {
|
|
423
|
-
info(` not logged in — project not linked; run \`insta login\`, then
|
|
441
|
+
info(` not logged in — project not ${linking ? 'linked' : 'created'}; run \`insta login\`, then \`${retry}\``);
|
|
424
442
|
}
|
|
425
443
|
else {
|
|
426
444
|
try {
|
|
427
|
-
|
|
445
|
+
if (project.kind === 'link')
|
|
446
|
+
await link(project.id);
|
|
447
|
+
else
|
|
448
|
+
await create(project.name);
|
|
428
449
|
}
|
|
429
450
|
catch (e) {
|
|
430
451
|
// Stop here — like the skill-install failure above, finishing with the success summary
|
|
431
452
|
// and a cheerful `next:` after an error is mixed messaging. Setup itself did succeed,
|
|
432
453
|
// so say exactly that alongside the retry command.
|
|
433
|
-
info(` project link failed (${e instanceof Error ? e.message : String(e)}) — agent setup itself is done; run
|
|
454
|
+
info(` project ${linking ? 'link' : 'create'} failed (${e instanceof Error ? e.message : String(e)}) — agent setup itself is done; run \`${retry}\` to retry the ${linking ? 'link' : 'create'}`);
|
|
434
455
|
process.exitCode = 1;
|
|
435
456
|
return;
|
|
436
457
|
}
|
package/dist/index.js
CHANGED
|
@@ -91,6 +91,7 @@ setupCmd.command('agent').description('Install the insta CLI (if missing), the i
|
|
|
91
91
|
.option('--env <prod|staging>', 'deployment to set this machine up for (default: prod — switches and persists, like `insta env use`)')
|
|
92
92
|
.option('--mcp-token', 'register the MCP server with a minted insta_ API token instead of OAuth (headless machines / CI)')
|
|
93
93
|
.option('--project <id>', 'also link this directory to an existing project after setup (flows through login first if needed)')
|
|
94
|
+
.option('--create [name]', 'also create a new project and link this directory after setup (default name: this directory; mutually exclusive with --project)')
|
|
94
95
|
.action(guard((o) => setup.setupAgent(o)));
|
|
95
96
|
// ---- MCP server integration ----
|
|
96
97
|
const mcpCmd = program.command('mcp').description('insta-cloud remote MCP server integration');
|