Re-organize the command tree: 24 noun-first groups, global --api-url - #252
Conversation
…_API_URL Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
… of --group Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ver runtime-health, query engine guard Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ess/upgrade/secrets verbs Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…h move under domain Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ics, agent + config groups, global --api-url Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mmand paths Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…billing subscribe / service add Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cture rules in the dev skill Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…y live paths Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…--api-url; spawn-test timeouts; wording - billing/secrets group commands now set allowExcessArguments(false), so a retired/mistyped subcommand under either group (`billing upgrade pro`, `secrets lst`) fails instead of silently running the group's own default action (commander 12 defaults allowExcessArguments to true). - `insta config autoupdate <on|off>` now reads via readPersistedGlobal() before its read-modify-write, instead of readGlobal() — readGlobal() folds in a runtime --api-url/INSTA_API_URL override and scrubs the stored session when it points elsewhere, so writing it back re-pointed ~/.insta/config.json and logged the user out just from toggling autoupdate. - Add explicit 30s timeouts to the remaining spawnSync-backed vitest `it` cases in help-surface.test.ts and retired-policy.test.ts (CI's windows-latest spawns are 3-5x slower than the 5s vitest default). - Wording: SKILL.md's observe hook reference, the root --api-url description (compute exec needs it before `compute`), volumeWriteLine and serviceLimits now say "database" instead of implying every managed type has a deploy step. - Tests: pin `billing upgrade` as retired and `secrets lst` as loud-failing; broaden the retired-path stderr regex to also accept commander's "too many arguments"; add a managedStatus-level (not just statusLine-level) test for runtime-health omitting the resolved service. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 59 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/config.ts">
<violation number="1" location="src/config.ts:75">
P2: When a command using a same-deployment `--api-url` override refreshes an expired session, `ApiClient.refresh()` persists this returned config and rewrites the stored `apiUrl`. Keep refresh persistence tied to the persisted config so a runtime debugging override cannot alter the machine's login configuration.</violation>
<violation number="2" location="src/config.ts:85">
P1: When `logout` runs with `--api-url` for another deployment, `readGlobal()` returns the scrubbed runtime view and `logout()` persists it. This permanently switches the stored API URL and deletes the original session, violating the flag's runtime-only contract; persist the stored config instead.</violation>
</file>
<file name="src/commands/compute.ts">
<violation number="1" location="src/commands/compute.ts:660">
P3: The no-volume guidance for managed databases tells users `insta redis volume <name> --size <gi>` will attach a volume, but the redis/mysql/mongodb `volume` command's declared surface in src/index.ts only documents grow and delete ("--size grows it (paid plans; grow-only)") — no attach. One of the two surfaces is wrong for the user: if --size cannot attach a disk to a volumeless managed DB, this newly added line sends users into a failing command; if it can, the new command help is missing the attach semantics. Align the message and the --help text with the actual platform behavior for managed-DB volume attach.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| return { apiUrl: override ?? DEFAULT_API } | ||
| parsed = null | ||
| } | ||
| return pickApiUrl(parsed, process.env, cliApiUrlOverride) |
There was a problem hiding this comment.
P1: When logout runs with --api-url for another deployment, readGlobal() returns the scrubbed runtime view and logout() persists it. This permanently switches the stored API URL and deletes the original session, violating the flag's runtime-only contract; persist the stored config instead.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/config.ts, line 85:
<comment>When `logout` runs with `--api-url` for another deployment, `readGlobal()` returns the scrubbed runtime view and `logout()` persists it. This permanently switches the stored API URL and deletes the original session, violating the flag's runtime-only contract; persist the stored config instead.</comment>
<file context>
@@ -33,41 +33,56 @@ export type ProjectConfig = { projectId: string; orgId: string; branch: string }
- return { apiUrl: override ?? DEFAULT_API }
+ parsed = null
}
+ return pickApiUrl(parsed, process.env, cliApiUrlOverride)
}
</file context>
| delete scrubbed.agentCredential | ||
| return scrubbed | ||
| } | ||
| return { ...parsed, apiUrl: override ?? persisted } |
There was a problem hiding this comment.
P2: When a command using a same-deployment --api-url override refreshes an expired session, ApiClient.refresh() persists this returned config and rewrites the stored apiUrl. Keep refresh persistence tied to the persisted config so a runtime debugging override cannot alter the machine's login configuration.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/config.ts, line 75:
<comment>When a command using a same-deployment `--api-url` override refreshes an expired session, `ApiClient.refresh()` persists this returned config and rewrites the stored `apiUrl`. Keep refresh persistence tied to the persisted config so a runtime debugging override cannot alter the machine's login configuration.</comment>
<file context>
@@ -33,41 +33,56 @@ export type ProjectConfig = { projectId: string; orgId: string; branch: string }
+ delete scrubbed.agentCredential
+ return scrubbed
+ }
+ return { ...parsed, apiUrl: override ?? persisted }
+}
+
</file context>
| `compute ${name}: no volume attached (attach one: \`insta compute volume ${name} --size <gi>\` — it mounts at /data on the next deploy)`, | ||
| type === 'compute' | ||
| ? `compute ${name}: no volume attached (attach one: \`insta compute volume ${name} --size <gi>\` — it mounts at /data on the next deploy)` | ||
| : `${type} ${name}: no volume attached (attach one: \`insta ${type} volume ${name} --size <gi>\` — it mounts at the image's data directory)`, |
There was a problem hiding this comment.
P3: The no-volume guidance for managed databases tells users insta redis volume <name> --size <gi> will attach a volume, but the redis/mysql/mongodb volume command's declared surface in src/index.ts only documents grow and delete ("--size grows it (paid plans; grow-only)") — no attach. One of the two surfaces is wrong for the user: if --size cannot attach a disk to a volumeless managed DB, this newly added line sends users into a failing command; if it can, the new command help is missing the attach semantics. Align the message and the --help text with the actual platform behavior for managed-DB volume attach.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/compute.ts, line 660:
<comment>The no-volume guidance for managed databases tells users `insta redis volume <name> --size <gi>` will attach a volume, but the redis/mysql/mongodb `volume` command's declared surface in src/index.ts only documents grow and delete ("--size grows it (paid plans; grow-only)") — no attach. One of the two surfaces is wrong for the user: if --size cannot attach a disk to a volumeless managed DB, this newly added line sends users into a failing command; if it can, the new command help is missing the attach semantics. Align the message and the --help text with the actual platform behavior for managed-DB volume attach.</comment>
<file context>
@@ -627,31 +653,38 @@ export function parseCpu(raw: string): number {
- `compute ${name}: no volume attached (attach one: \`insta compute volume ${name} --size <gi>\` — it mounts at /data on the next deploy)`,
+ type === 'compute'
+ ? `compute ${name}: no volume attached (attach one: \`insta compute volume ${name} --size <gi>\` — it mounts at /data on the next deploy)`
+ : `${type} ${name}: no volume attached (attach one: \`insta ${type} volume ${name} --size <gi>\` — it mounts at the image's data directory)`,
]
return [
</file context>
…iner) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
… — the volume is the data directory) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
jwfing
left a comment
There was a problem hiding this comment.
Summary
The command-tree reorganization is broadly coherent and includes useful surface, API override, and managed-database tests. One managed-database command violates the checked-in command-shape requirement: query requires the service and places query arguments after it, instead of supporting the documented optional trailing [service]. No security or production-performance regression was identified from the supplied diff.
Requirements context
Intent was derived from the PR description, README changes, and the command-architecture rules added to .claude/skills/developing-insta-cli/SKILL.md. The linked superproject design and plan are outside this standalone CLI checkout, so they could not be inspected directly; review therefore used the explicit requirements reproduced in the PR and checked-in documentation, including the hard cutover, 24 visible commands, permanent aliases, per-resource observability, and runtime-only --api-url.
Findings
Critical
- src/index.ts:326: Managed database
querybreaks the documented common command shape - The new architecture rule states thatcompute|postgres|redis|mysql|mongodb <verb> [service]use an optional trailing service resolved withresolveSoleServicewhen omitted. However, each managed database registersquery <service> [args...], anddbQueryrequires a service string. Consequently the sole-service convenience does not work forquery, and the service is not trailing: for example,insta redis query GET keytreatsGETas the service name instead of selecting the sole Redis service. Align this verb with the documented shape (with an unambiguous query-argument convention) or explicitly amend the governing design ifqueryis intended as an exception, and add CLI coverage for the decided behavior.
Suggestion
(none)
Information
- Testing: Good coverage of the reorganized surface, but the query-shape conflict is not exercised - The added tests pin the 24 visible commands, retired paths, aliases, moved group verbs, API URL precedence, and managed-database status behavior. The help test only checks that managed groups contain a
queryverb; it does not compare its service-selection shape with the architecture rule or exercise omission of the service. - Security: API override avoids forwarding credentials across deployments -
pickApiUrlremoves access tokens, refresh tokens, user data, and agent credentials when an override selects a different normalized API URL. The changed telemetry allowlists continue to redact service names, query text, paths, and other free-form arguments, and the PR introduces no dependency or new shell/SQL interpolation surface. - Performance: No material production performance regression found - The new managed-database status path performs two bounded API reads—service resolution followed by runtime health—and selects one entry locally. The other moved handlers retain their prior request patterns; no unbounded loops, N+1 request patterns, or new synchronous production hot-path work were introduced.
- Rollout: Merge must remain coordinated with the release and downstream documentation - The README switches to commands unavailable in currently published binaries, while
setup agentremains compatible for installation. As the PR description notes, this branch should be held until the CLI release/tag and downstream skills, frontend, MCP, e2e, and platform-copy changes can be coordinated.
Tests
I could not execute npm run typecheck or npm test: every shell invocation failed before the command started because the environment could not create its read-only bwrap namespace (No permissions to create a new namespace). I performed a static review of the supplied full diff and surrounding repository documentation available through read-only interfaces; the PR author's reported 3,449 passing tests was not independently verified.
Verdict
request_changes: Changes are requested because the explicit common command-shape requirement has one correctness/specification violation in the managed-database query registration.
Two conflicts, both in the registration surface this branch rewrote: - src/index.ts: the whole registration section is ours (the 24 noun-first groups), so main's block was dropped and its two additions ported into our tree instead. main's top-level `build-logs <build-id>` becomes `insta build logs <build-id>` — a hyphenated top-level verb would break the branch's level-1-is-a-resource rule and the 24-command surface; `build` now carries both its own action and a subcommand, so it gets the same allowExcessArguments(false) guard as `billing` and `secrets`. main's `--org <id>` on `domain list` / `domain status` (#251) is kept verbatim inside our `domain` group. - README.md: our rewritten Commands table wins; main's `insta build-logs` row is folded into the `insta build` / `insta deploy` row as `insta build logs`. test/help-surface.test.ts pins the move: `build-logs` joins RETIRED, and a new case asserts `build --help` lists `logs` and `build logs --help` exits 0 with --source/--follow/--json. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…on bought names, managed-DB volume help, shape-rule exception) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 18 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/api.ts">
<violation number="1" location="src/api.ts:52">
P1: When `env use` switches deployments while another process refreshes, `readPersistedGlobal()` can return staging while `this.cfg` contains freshly refreshed production tokens, so this write stores production credentials under staging. Compare the persisted URL with `this.apiUrl` before writing and skip persistence if the deployment changed.</violation>
</file>
<file name="src/commands/services.ts">
<violation number="1" location="src/commands/services.ts:33">
P2: When a project has multiple managed database services of this type, this suggested command omits the service selector and exits with an ambiguity error instead of changing a service. Tell users to add the service name after `on|off` when multiple services exist.</violation>
<violation number="2" location="src/commands/services.ts:38">
P2: When a project has multiple managed database services of this type, this suggested command omits the service selector and fails with an ambiguity error. Tell users to add the service name after `volume` when multiple services exist.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| // authenticated against — may move the stored URL; everything else keeps what is on disk. | ||
| async persist(): Promise<void> { | ||
| if (this.apiUrlExplicit) return writeGlobal(this.cfg) | ||
| await writeGlobal({ ...this.cfg, apiUrl: (await readPersistedGlobal()).apiUrl }) |
There was a problem hiding this comment.
P1: When env use switches deployments while another process refreshes, readPersistedGlobal() can return staging while this.cfg contains freshly refreshed production tokens, so this write stores production credentials under staging. Compare the persisted URL with this.apiUrl before writing and skip persistence if the deployment changed.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/api.ts, line 52:
<comment>When `env use` switches deployments while another process refreshes, `readPersistedGlobal()` can return staging while `this.cfg` contains freshly refreshed production tokens, so this write stores production credentials under staging. Compare the persisted URL with `this.apiUrl` before writing and skip persistence if the deployment changed.</comment>
<file context>
@@ -40,9 +40,23 @@ export class ApiClient {
+ // authenticated against — may move the stored URL; everything else keeps what is on disk.
+ async persist(): Promise<void> {
+ if (this.apiUrlExplicit) return writeGlobal(this.cfg)
+ await writeGlobal({ ...this.cfg, apiUrl: (await readPersistedGlobal()).apiUrl })
+ }
</file context>
| await writeGlobal({ ...this.cfg, apiUrl: (await readPersistedGlobal()).apiUrl }) | |
| const persisted = await readPersistedGlobal() | |
| if (persisted.apiUrl.replace(/\/+$/, '') !== this.apiUrl.replace(/\/+$/, '')) return | |
| await writeGlobal({ ...this.cfg, apiUrl: persisted.apiUrl }) |
|
|
||
| export function volumeTypeError(type: string): string { | ||
| const base = '--volume is only valid for compute services' | ||
| return hasOwnGroup(type) ? `${base} (${type} has one by default — grow it with \`insta ${type} volume --size <gi>\`)` : base |
There was a problem hiding this comment.
P2: When a project has multiple managed database services of this type, this suggested command omits the service selector and fails with an ambiguity error. Tell users to add the service name after volume when multiple services exist.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/services.ts, line 38:
<comment>When a project has multiple managed database services of this type, this suggested command omits the service selector and fails with an ambiguity error. Tell users to add the service name after `volume` when multiple services exist.</comment>
<file context>
@@ -21,6 +21,23 @@ export function assertServiceName(name: string): void {
+
+export function volumeTypeError(type: string): string {
+ const base = '--volume is only valid for compute services'
+ return hasOwnGroup(type) ? `${base} (${type} has one by default — grow it with \`insta ${type} volume --size <gi>\`)` : base
+}
+
</file context>
| return hasOwnGroup(type) ? `${base} (${type} has one by default — grow it with \`insta ${type} volume --size <gi>\`)` : base | |
| return hasOwnGroup(type) ? `${base} (${type} has one by default — grow it with \`insta ${type} volume --size <gi>\`; add the service name after volume when multiple services exist)` : base |
|
|
||
| export function alwaysOnTypeError(type: string): string { | ||
| const base = '--always-on / --no-always-on is only valid for compute services' | ||
| return hasOwnGroup(type) ? `${base} (for ${type}, use \`insta ${type} always-on on|off\` after creation)` : base |
There was a problem hiding this comment.
P2: When a project has multiple managed database services of this type, this suggested command omits the service selector and exits with an ambiguity error instead of changing a service. Tell users to add the service name after on|off when multiple services exist.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/services.ts, line 33:
<comment>When a project has multiple managed database services of this type, this suggested command omits the service selector and exits with an ambiguity error instead of changing a service. Tell users to add the service name after `on|off` when multiple services exist.</comment>
<file context>
@@ -21,6 +21,23 @@ export function assertServiceName(name: string): void {
+
+export function alwaysOnTypeError(type: string): string {
+ const base = '--always-on / --no-always-on is only valid for compute services'
+ return hasOwnGroup(type) ? `${base} (for ${type}, use \`insta ${type} always-on on|off\` after creation)` : base
+}
+
</file context>
| return hasOwnGroup(type) ? `${base} (for ${type}, use \`insta ${type} always-on on|off\` after creation)` : base | |
| return hasOwnGroup(type) ? `${base} (for ${type}, use \`insta ${type} always-on on|off\` after creation; add the service name after on|off when multiple services exist)` : base |
There was a problem hiding this comment.
1 issue found across 22 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="test/api-url-override.test.ts">
<violation number="1" location="test/api-url-override.test.ts:102">
P2: This test makes every run contact the live production API because `logout()` intentionally uses the persisted host. Use a localhost server or an injected/mock transport so the persistence assertion remains deterministic and does not send fake credentials externally.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| mkdirSync(join(home, '.insta'), { recursive: true }) | ||
| const file = join(home, '.insta', 'config.json') | ||
| writeFileSync(file, JSON.stringify(stored, null, 2)) | ||
| const r = spawnSync(process.execPath, ['--import', 'tsx', entry, 'logout', '--api-url', STAGING], { |
There was a problem hiding this comment.
P2: This test makes every run contact the live production API because logout() intentionally uses the persisted host. Use a localhost server or an injected/mock transport so the persistence assertion remains deterministic and does not send fake credentials externally.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At test/api-url-override.test.ts, line 102:
<comment>This test makes every run contact the live production API because `logout()` intentionally uses the persisted host. Use a localhost server or an injected/mock transport so the persistence assertion remains deterministic and does not send fake credentials externally.</comment>
<file context>
@@ -38,3 +69,94 @@ describe('pickApiUrl', () => {
+ mkdirSync(join(home, '.insta'), { recursive: true })
+ const file = join(home, '.insta', 'config.json')
+ writeFileSync(file, JSON.stringify(stored, null, 2))
+ const r = spawnSync(process.execPath, ['--import', 'tsx', entry, 'logout', '--api-url', STAGING], {
+ encoding: 'utf8',
+ timeout: 30_000,
</file context>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jwfing
left a comment
There was a problem hiding this comment.
Summary
No blocking correctness, security, or performance defect was identified in the supplied diff. The command reorganization is internally consistent and includes strong surface-level regression coverage, though several generalized mutation paths would benefit from direct handler tests. Per the PR’s own rollout warning, approval should be held and the PR must not be merged until the coordinated release and downstream documentation changes are ready.
Requirements context
Intent was derived from the PR title and description, the README changes, and the command-architecture requirements included in .claude/skills/developing-insta-cli/SKILL.md. These establish the noun-first 24-command surface, hard cutover rules, permanent service aliases and hidden setup agent compatibility path, managed-database command shapes, and runtime-only --api-url behavior. The referenced superproject design and plan are outside this checkout and could not be independently inspected; the review therefore relies on the detailed PR description and repository guidance supplied in the diff.
Findings
Critical
(none)
Suggestion
- src/commands/compute.ts: serviceAlwaysOn, serviceLimits, serviceVolume, computeScale; src/commands/storage.ts: storageSetAccess: Add direct flow coverage for newly generalized mutation handlers - The help-surface tests verify registration, and existing tests cover parsers and some rendering, but the new managed-database variants and moved scale/access handlers are not all directly exercised through an injected API seam. Focused tests should assert service-type resolution, branch propagation, HTTP method/path/body, approval handling, and JSON output, especially for redis/mysql/mongodb limits, volume, and always-on.
Information
- Functionality: Command tree matches the described hard cutover - The visible 24-command surface, permanent
services|svcaliases, hiddensetup agentalias, resource-scoped observability commands, database-specific groups, and retired paths are consistently wired and documented in the supplied changes. The unified domain attach/check/detach behavior also preserves the distinct purchased-domain and bring-your-own flows. - Security: Runtime API overrides avoid cross-deployment credential reuse - A foreign
--api-urlproduces an in-memory configuration with stored user and agent credentials removed, while persistence paths retain the on-disk control-plane URL unless login explicitly selects a new one. Logout deliberately revokes the sole stored session against its persisted deployment, preventing a runtime override from discarding the local token without revoking the corresponding server session. No new dependency or newly exposed secret logging was introduced. - Performance: No material performance regression identified - The new handlers perform bounded control-plane calls appropriate for a CLI. Managed-database status adds a services lookup followed by one runtime-health lookup, and persistence may add one small configuration-file read; neither is a hot-path or unbounded operation.
- Testing: Surface and API override regressions are well represented - The added tests pin the visible and retired command paths, group argument shapes, compatibility aliases,
--api-urlprecedence and non-persistence, cross-deployment session scrubbing, managed-database status, and domain routing behavior. The child-process tests also include explicit timeouts for slower platforms. - Rollout: Merge remains intentionally gated on coordinated release work - The PR updates README examples to the new canonical commands even though released binaries do not yet support them. The description explicitly requires holding this PR until the version bump, tag, skills/e2e/frontend/MCP/platform-copy changes, and release sequence are ready; this operational gate remains necessary despite the code-review verdict.
Tests
Attempted read-only shell inspection with sed, git, rg, and pwd, but the command runner could not start because its sandbox failed to create a namespace (bwrap: No permissions to create a new namespace). Consequently, no tests or typecheck could be run in this review. Assessment used the supplied full diff; the PR description reports npm run typecheck and 3,449 tests across 185 files passing, but that claim was not independently verified.
Verdict
approved: There are no Critical findings, so the strict verdict rule yields approved; the testing suggestion and rollout hold are non-blocking review observations.
src/build-logs.ts conflicted: main enriched the failure message with a reason (timeout / HTTP status) while this branch renamed the command to the `build logs` subcommand. Took both — main's detail, this branch's spelling. Main's new work also reintroduced `insta build-logs` in src/deploy-archive.ts and three test assertions; re-pointed all of them, since that path now exits with `unknown command`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
All review findings are addressed and pushed — the human review's Critical, cubic's 18 inline comments, and two problems the review surfaced indirectly. The Critical: managed-database
|
The command re-organization (#252) is a hard cutover of the whole command surface, so it earns the minor rather than another patch. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements superproject
docs/superpowers/specs/2026-09-17-cli-command-reorg-design.md(plan:docs/superpowers/plans/2026-09-17-cli-command-reorg.md, Tasks 1–8 and 17).What changes
Hard cutover, 32 → 24 top-level commands. Retired paths answer
unknown command(ortoo many argumentsfor the two groups that carry their own action):services scale|upgrade|set-access|secrets,compute set-domain|check-domain|remove-domain,db …, and top-levelmetrics|logs|usage|manifest|approvals|agent-policy|observe|events|mcp|regions|autoupdate|billing upgrade.services/svcstay as permanent aliases ofservice;envis hidden but unchanged;setup agentstays as a permanent hidden alias ofagent setup(identical options) becausenpx -y insta@latest setup agent …is the onboarding one-liner printed by the console, the landing page and third-party docs.New / moved surface (
insta --help):service(services,svc)addlistremoverenamedomainattach(bought and bring-your-own, one verb)checkdetach+searchbuyliststatusrecords …computescale <count> [service]logsmetrics; domain verbs leavebuild[dir], gainslogs <build-id>— main's top-levelbuild-logsmoves here (a hyphenated level-1 verb breaks rule 1);--source archive|github,--follow,--jsonpostgresurlconnectstatslimitsvolumealways-onlogsmetrics— every verb takes[service](wasdb … --group)redismysqlmongodbquerystatuslimitsvolumealways-onlogsmetrics(statusreads/projects/:id/runtime-health)storageset-access <public|private> --service <name>billingsubscribe(wasupgrade)portalusageagentsetupmanifestpolicy …approvals …observe …eventsconfiginstall-mcpregionsautoupdateEvery command accepts
--api-url <url>(runtime only; beatsINSTA_API_URL; a URL for another host runs logged-out).install.shkeeps callingsetup agent, which works on every release thanks to the alias (no probe). The developer skill gains the command-level rules;test/help-surface.test.tspins the visible surface.Platform facts relied on (checked at insta-platform 56b6482)
/services/:id/{limits,volume,always-on}accept managed databases (openapi.yamlsummaries);/services/:id/stateis compute-only (src/provisioning/services.tsstate), henceruntime-healthfor managed-DBstatus; the metrics/logs component enum has no storage (src/observability/service.tsCOMPONENT_ENUM_MSG).Review
Eight task-scoped reviews, one whole-branch review, then a full round against this PR's review comments — the human review's Critical plus cubic's 18 inline findings, all fixed in-branch. Highlights: a runtime
--api-urlcould be persisted bylogoutand by a 401 refresh, permanently re-pointing the machine and dropping its login;logoutunder a foreign override skipped the server-side revoke while still deleting local tokens;domain detachwould have half-released a bought hostname;billing upgradefell through to the billing overview at exit 0; managed-databasevolumehelp contradicted the platform.mainwas merged twice along the way.npm run typecheckclean;npm test189 files / 3525 tests green.Rollout — read before merging
Do not MERGE this PR yet. Its README documents
npx -y insta@latest agent setup, which fails on every published binary until the release exists (the console'ssetup agentline keeps working). Sequence (design §9): get this PR approved and hold it → prepare the skills / e2e / frontend (one policy-hint string) / mcp / platform-copy PRs → merge this PR, the0.1.0version-bump PR, and tag in one sitting → merge the downstream PRs minutes after the tag (skills first: agents fetch that text at setup time).🤖 Generated with Claude Code