insta 0.0.36 → 0.0.38

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/index.js CHANGED
@@ -74,7 +74,7 @@ const envCmd = program.command('env').description('Show or switch the deployment
74
74
  envCmd.command('show', { isDefault: true }).description('Show the current environment and its hosts')
75
75
  .option('--json').action(guard((o) => envCmd_.envShow(o)));
76
76
  envCmd.command('use <name>').description(`Switch environment (${ENV_NAMES.join(' | ')}) — drops the stored session, which is deployment-specific`)
77
- .action(guard((name) => envCmd_.envUse(name)));
77
+ .option('--json').action(guard((name, o) => envCmd_.envUse(name, o)));
78
78
  // ---- run (per-request secret injection — nothing written to disk) ----
79
79
  program.command('run <cmd> [args...]').description('Run a command with the branch credential bundle injected into its environment (no .env written)')
80
80
  .option('--branch <b>', 'branch bundle to inject (default: linked branch)')
@@ -82,8 +82,9 @@ program.command('run <cmd> [args...]').description('Run a command with the branc
82
82
  .action(guard((cmd, args, o) => runCmd.run([cmd, ...(args ?? [])], o)));
83
83
  // ---- agent setup (the `curl … | sh --agents` target) ----
84
84
  const setupCmd = program.command('setup').description('Set up this machine for InstaCloud agent workflows');
85
- setupCmd.command('agent').description('Install the insta skill user-globally for all coding agents')
85
+ setupCmd.command('agent').description('Install the insta CLI (if missing), the insta skill for all coding agents, and the MCP server — targets production; pass --env staging for the staging deployment')
86
86
  .option('-y, --yes', 'non-interactive')
87
+ .option('--env <prod|staging>', 'deployment to set this machine up for (default: prod — switches and persists, like `insta env use`)')
87
88
  .option('--mcp-token', 'register the MCP server with a minted insta_ API token instead of OAuth (headless machines / CI)')
88
89
  .action(guard((o) => setup.setupAgent(o)));
89
90
  // ---- MCP server integration ----
@@ -95,21 +96,21 @@ mcpCmd.command('install').description('Register the remote MCP server with codin
95
96
  // ---- org ----
96
97
  const orgCmd = program.command('org').description('Manage organizations');
97
98
  orgCmd.command('list').option('--json').action(guard((o) => org.orgList(o)));
98
- orgCmd.command('create <name>').action(guard((name) => org.orgCreate(name)));
99
+ orgCmd.command('create <name>').option('--json').action(guard((name, o) => org.orgCreate(name, o)));
99
100
  // ---- project ----
100
101
  const pj = program.command('project').description('Manage projects');
101
- pj.command('create [name]').option('--org <id>', 'org to create under (default: personal)').action(guard((name, o) => project.projectCreate(name, o)));
102
+ pj.command('create [name]').option('--org <id>', 'org to create under (default: personal)').option('--json').action(guard((name, o) => project.projectCreate(name, o)));
102
103
  pj.command('list').option('--org <id>').option('--json').action(guard((o) => project.projectList(o)));
103
- pj.command('link <id>').description('Link a project to this directory').action(guard((id) => project.projectLink(id)));
104
- pj.command('delete').option('--project <id>').action(guard((o) => project.projectDelete(o)));
104
+ pj.command('link <id>').description('Link a project to this directory').option('--json').action(guard((id, o) => project.projectLink(id, o)));
105
+ pj.command('delete').option('--project <id>').option('--json').action(guard((o) => project.projectDelete(o)));
105
106
  // ---- branch ----
106
107
  const br = program.command('branch').description('Manage branch environments');
107
- br.command('create <name>').option('--from <branch>', 'parent branch (default: current)').action(guard((name, o) => branch.branchCreate(name, o)));
108
+ br.command('create <name>').option('--from <branch>', 'parent branch (default: current)').option('--json').action(guard((name, o) => branch.branchCreate(name, o)));
108
109
  br.command('list').option('--json').action(guard((o) => branch.branchList(o)));
109
- br.command('switch <name>').action(guard((name) => branch.branchSwitch(name)));
110
- br.command('delete <name>').action(guard((name) => branch.branchDelete(name)));
110
+ br.command('switch <name>').option('--json').action(guard((name, o) => branch.branchSwitch(name, o)));
111
+ br.command('delete <name>').option('--json').action(guard((name, o) => branch.branchDelete(name, o)));
111
112
  br.command('merge <source>').description('Merge a branch service set into another (structural, no data)')
112
- .option('--into <branch>', 'target branch (default: current)').action(guard((source, o) => branch.branchMerge(source, o)));
113
+ .option('--into <branch>', 'target branch (default: current)').option('--json').action(guard((source, o) => branch.branchMerge(source, o)));
113
114
  // ---- services (opt-in postgres/storage/compute/redis/mysql/mongodb) ----
114
115
  const svc = program.command('services').alias('svc').description('Manage project services (postgres|storage|compute|redis|mysql|mongodb)');
115
116
  // [type] [name] are optional so the command can answer "what can I add?" — a terminal is walked
@@ -131,7 +132,7 @@ svc.command('add [type] [name]').description('Provision a service on demand (ass
131
132
  svc.command('list').option('--json').option('--branch <branch>', 'branch (default: current)')
132
133
  .action(guard((o) => services.servicesList(o)));
133
134
  svc.command('remove <type> <name>').description('Remove a service and destroy its resources')
134
- .option('--branch <branch>', 'branch (default: current)')
135
+ .option('--branch <branch>', 'branch (default: current)').option('--json')
135
136
  .action(guard((type, name, o) => services.servicesRemove(type, name, o)));
136
137
  svc.command('rename <type> <name> <new-name>').description('Rename a service and re-key its managed secret names')
137
138
  .option('--json').option('--branch <branch>', 'branch (default: current)')
@@ -151,9 +152,9 @@ const sec = program.command('secrets').description('Fetch the credential bundle
151
152
  sec.command('list').description('List secret names, grouped by service').option('--branch <branch>').option('--json').action(guard((o) => secretsCmd.secretsList(o)));
152
153
  sec.command('set <name> [value]').description('Set a user secret (project-wide; value from stdin if omitted)')
153
154
  .option('--branch <branch>', 'scope to one branch').option('--service <type/name>', 'bind to a branch service (implies current branch)')
154
- .action(guard((n, v, o) => secretsCmd.secretsSet(n, v, o)));
155
+ .option('--json').action(guard((n, v, o) => secretsCmd.secretsSet(n, v, o)));
155
156
  sec.command('unset <name>').description('Remove a user secret')
156
- .option('--branch <branch>', 'scope to one branch').action(guard((n, o) => secretsCmd.secretsUnset(n, o)));
157
+ .option('--branch <branch>', 'scope to one branch').option('--json').action(guard((n, o) => secretsCmd.secretsUnset(n, o)));
157
158
  sec.command('bind <env-name> <source>').description('Bind a service credential into a compute env var')
158
159
  .option('--branch <branch>', 'branch (default: current)')
159
160
  .option('--to <compute-service>', 'target compute service, e.g. compute/api')
@@ -186,6 +187,7 @@ program.command('build [dir]').description('Verify a source directory would buil
186
187
  program.command('deploy [dir]').description('Deploy a source directory (built remotely on Fly) or a prebuilt --image to a branch compute group')
187
188
  .option('--image <url>', 'prebuilt container image to deploy (instead of a source dir)').option('--branch <b>').option('--group <g>').option('--port <p>')
188
189
  .option('--websocket', 'run a WebSocket app (larger guest + connection-based concurrency)')
190
+ .option('--json', 'print the deploy result as JSON (build progress goes to stderr)')
189
191
  .action(guard((dir, o) => deploy(dir, o)));
190
192
  // `insta compute exec` needs the command verbatim after a literal `--`; split it out of argv here,
191
193
  // before commander parses anything (see splitExecArgs's own comment for why `service` being
@@ -198,7 +200,7 @@ compute.command('set-domain <host>').description('Attach a custom domain to a br
198
200
  compute.command('check-domain <host>').description("Show a custom domain's cert status + required DNS records")
199
201
  .option('--branch <b>').option('--group <g>').option('--json').action(guard((host, o) => computeCmd.checkDomain(host, o)));
200
202
  compute.command('remove-domain <host>').description('Detach a custom domain (gated: deploy)')
201
- .option('--branch <b>').option('--group <g>').action(guard((host, o) => computeCmd.removeDomain(host, o)));
203
+ .option('--branch <b>').option('--group <g>').option('--json').action(guard((host, o) => computeCmd.removeDomain(host, o)));
202
204
  compute.command('start [service]').description('Bring a compute service online (persistent — re-enables auto-wake)')
203
205
  .option('--json').option('--branch <branch>', 'branch (default: current)').action(guard((service, o) => computeCmd.computeStart(service, o)));
204
206
  compute.command('stop [service]').description('Take a compute service offline; traffic will NOT wake it until `start`')
@@ -264,6 +266,9 @@ program.command('metrics <target> [group]').description('Service metrics (target
264
266
  .action(guard((target, group, o) => obs.metrics(target, group, o)));
265
267
  program.command('logs <target> [group]').description('Service logs (runtime by default; --deploy = machine lifecycle events; target: db|compute|redis|mysql|mongodb)')
266
268
  .option('--branch <b>').option('--limit <n>').option('--region <r>').option('--instance <i>').option('--deploy', 'show deploy events (machine lifecycle) instead of runtime logs — Fly-backed targets only, not db').option('--json')
269
+ .option('--from <t>', 'window start: unix seconds or ISO-8601 — pages history (~7-day retention); without a window one recent provider page (~100 lines) is returned')
270
+ .option('--to <t>', 'window end: unix seconds or ISO-8601 (default: now)')
271
+ .option('--since <dur>', 'relative window start, e.g. 90s, 30m, 2h, 1d (shorthand for --from now-dur)')
267
272
  .action(guard((target, group, o) => obs.logs(target, group, o)));
268
273
  program.command('usage').description('Usage for the current billing cycle by billing dimension (org by default; --proj for one project)')
269
274
  .option('--from <unix>').option('--to <unix>').option('--proj [id]', 'show one project (the linked one, or a given id) instead of the whole org').option('--json')
@@ -282,8 +287,8 @@ program.command('events').description('Show the audit + agent-event timeline').o
282
287
  // ---- approvals ----
283
288
  const ap = program.command('approvals').description('Governance approvals (HITL)');
284
289
  ap.command('list').option('--status <s>', 'pending|granted|denied|consumed').option('--json').action(guard((o) => govern.approvalsList(o)));
285
- ap.command('approve <id>').option('--always', 'also set the policy to allow').action(guard((id, o) => govern.approvalsApprove(id, o)));
286
- ap.command('deny <id>').action(guard((id) => govern.approvalsDeny(id)));
290
+ ap.command('approve <id>').option('--always', 'also set the policy to allow').option('--json').action(guard((id, o) => govern.approvalsApprove(id, o)));
291
+ ap.command('deny <id>').option('--json').action(guard((id, o) => govern.approvalsDeny(id, o)));
287
292
  // ---- observe (local credential audit) ----
288
293
  const ob = program.command('observe').description('Local credential-audit hook');
289
294
  ob.command('install').description('Install the PostToolUse hook into this project').action(guard(() => observe.observeInstall()));
@@ -293,7 +298,7 @@ ob.command('sync').description('Upload findings into the project timeline').acti
293
298
  // ---- policy ----
294
299
  const pol = program.command('policy').description('Governance policy');
295
300
  pol.command('get').option('--json').action(guard((o) => govern.policyGet(o)));
296
- pol.command('set <action> <decision>').description('action: secrets.read|secrets.write|deploy|project.delete|branch.delete|service.add|service.remove|service.scale|service.upgrade|service.setAccess|storage.read|storage.write|storage.delete; decision: allow|deny|approve').action(guard((a, d) => govern.policySet(a, d)));
301
+ pol.command('set <action> <decision>').description('action: secrets.read|secrets.write|deploy|project.delete|branch.delete|service.add|service.remove|service.scale|service.upgrade|service.setAccess|storage.read|storage.write|storage.delete; decision: allow|deny|approve').option('--json').action(guard((a, d, o) => govern.policySet(a, d, o)));
297
302
  // ---- feedback (agent + human hurdle reports → the InstaCloud team) ----
298
303
  program.command('feedback')
299
304
  .description('Report an InstaCloud-side hurdle (bug / missing feature / friction) to the InstaCloud team — about the insta toolkit itself, NEVER about the app you are building. Works logged-out and unlinked.')
package/dist/util.js CHANGED
@@ -26,10 +26,17 @@ export function info(msg) {
26
26
  process.stdout.write(msg + '\n');
27
27
  }
28
28
  // If the platform gated the action (HTTP 202), tell the user how to get it approved. Returns
29
- // true when an approval is pending (caller should stop).
30
- export function handleApproval(res) {
29
+ // true when an approval is pending (caller should stop). The hint goes to STDERR and the exit
30
+ // code is set to 2: a pending gate is not success (redirected stdout must never swallow it as
31
+ // output), and not a plain error either (die() owns 1) — it's approvable and re-runnable, and
32
+ // scripts/agents branch on the distinct code. With json, stdout carries the platform's raw 202
33
+ // envelope so a scripted caller can lift approvalId/action.
34
+ export function handleApproval(res, json) {
31
35
  if (res.status === 202 && res.body?.status === 'approval_required') {
32
- info(`approval required for ${res.body.action} — run: insta approvals approve ${res.body.approvalId}`);
36
+ if (json)
37
+ printJson(res.body);
38
+ process.stderr.write(`approval required for ${res.body.action} — run: insta approvals approve ${res.body.approvalId}\n`);
39
+ process.exitCode = 2;
33
40
  return true;
34
41
  }
35
42
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insta",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "type": "module",
5
5
  "description": "InstaCloud CLI — a thin client of the platform control-plane API.",
6
6
  "keywords": [