@supacloud/cli 0.93.0 → 0.95.0
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/README.md +23 -32
- package/dist/index.js +195 -549
- package/dist/shared/deployment-upgrade.d.ts +2 -0
- package/dist/shared/tools/app-starter-database.d.ts +1 -1
- package/dist/shared/tools/app-starter-reactive.d.ts +2 -2
- package/dist/shared/tools/application-tools.d.ts +1 -1
- package/dist/shared/tools/deploy-tools.d.ts +0 -8
- package/dist/shared/tools/developer-experience-tools.d.ts +1 -1
- package/dist/shared/tools/project-deployment.d.ts +1 -0
- package/dist/shared/tools/remote-dev-tools.d.ts +1 -1
- package/dist/tool-runtime.js +25 -0
- package/package.json +3 -3
- package/skills/supacloud/SKILL.md +9 -0
- package/skills/supacloud/references/command-map.md +3 -5
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment is no longer supported. Upgrade with `npm install -g @supacloud/cli@latest`, bind application.id and application.environmentId in supacloud.json (or SUPACLOUD_APPLICATION_ID and SUPACLOUD_ENV), then run `supacloud deploy`. SupaCloud owns deployment planning and activation; do not retry with legacy commands.";
|
|
2
|
+
export declare function assertCurrentDeploymentInput(tool: string, input: unknown): void;
|
|
@@ -10,5 +10,5 @@ export declare const STARTER_DATABASE_CONFIG: {
|
|
|
10
10
|
role: string;
|
|
11
11
|
};
|
|
12
12
|
export declare const STARTER_DATABASE_SCHEMA = "import { sql } from \"drizzle-orm\";\nimport { boolean, check, integer, jsonb, pgTable, primaryKey, text, uuid } from \"drizzle-orm/pg-core\";\n\n// Structure for the reviewed starter migrations. Grants/policies stay in those migrations.\nexport const application = pgTable.withRLS(\"starter_application\", {\n singleton: boolean().default(true).primaryKey(),\n projectId: text(\"project_id\").notNull(),\n tenantId: text(\"tenant_id\").notNull(),\n}, table => [\n check(\"starter_application_singleton_check\", sql`${table.singleton}`),\n check(\"starter_application_project_id_check\", sql`length(${table.projectId}) > 0`),\n check(\"starter_application_tenant_id_check\", sql`length(${table.tenantId}) > 0`),\n]);\n\nexport const reviews = pgTable.withRLS(\"starter_reviews\", {\n id: text().primaryKey(),\n ownerId: text(\"owner_id\").notNull(),\n state: text({ enum: [\"draft\", \"approved\"] }).notNull(),\n version: integer().notNull(),\n}, table => [\n check(\"starter_reviews_state_check\", sql`${table.state} IN ('draft', 'approved')`),\n check(\"starter_reviews_version_check\", sql`${table.version} > 0`),\n]);\n\nexport const members = pgTable.withRLS(\"starter_members\", {\n subject: text().primaryKey(),\n enabled: boolean().default(true).notNull(),\n canApprove: boolean(\"can_approve\").default(false).notNull(),\n storageSubject: uuid(\"storage_subject\").unique(),\n});\n\nexport const attachments = pgTable.withRLS(\"starter_attachments\", {\n reviewId: text(\"review_id\").primaryKey().references(() => reviews.id),\n artifactId: uuid(\"artifact_id\").notNull().unique(),\n ownerId: text(\"owner_id\").notNull(),\n runId: uuid(\"run_id\").notNull().unique(),\n objectPath: text(\"object_path\").notNull().unique(),\n});\n\nexport const attachmentResults = pgTable.withRLS(\"starter_attachment_results\", {\n reviewId: text(\"review_id\").notNull().references(() => reviews.id),\n version: integer().notNull(),\n artifactId: uuid(\"artifact_id\").notNull(),\n result: jsonb().$type<unknown>().notNull(),\n}, table => [\n primaryKey({ columns: [table.reviewId, table.version, table.artifactId] }),\n check(\"starter_attachment_results_version_check\", sql`${table.version} >= 2`),\n]);\n\nexport type ReviewRow = typeof reviews.$inferSelect;\nexport type NewReview = typeof reviews.$inferInsert;\n";
|
|
13
|
-
export declare const STARTER_DATABASE_GUIDE = "\n## Database Source Workflow\n\nDrizzle owns table declarations and inferred row types in db/schema.ts.\nUse the existing @supacloud/db/drizzle-bun adapters for typed queries and governed\ntransactions; never replace permission, idempotency or audit checks with plain CRUD.\nOpaque JSON still needs runtime decoding.\n\nAfter installing dependencies, run `bun run db:generate` once and commit db/contracts/.\nThe default `bun run check` and build fail on stale database contracts before any\ncompiler regeneration. After an intentional source change, run db:generate again,\nreview the diff, then run check. Ordinary checks are offline.\n\n- Maintain one schema-qualified function with explicit grants per db/functions/*.sql.\n- Preserve migrations/ and its existing executor/ledger. Add forward migrations only.\n- `bun run db:diff` generates Drizzle drafts under db/migration-candidates/, never\n into the deployment directory. The starter has existing SQL history, so establish\n and review a matching Drizzle baseline before promoting any draft; the first\n draft is not automatically an incremental production migration.\n- `bun run db:pull` requires an explicitly selected DATABASE_URL and writes only\n output/database-audit/drizzle-candidate/. Review candidates; never overwrite source blindly.\n- Full SQL dumps belong under the ignored output/database-audit/ directory. They are\n audit/recovery artifacts, never ordinary type, application or test inputs.\n- `bun run db:assess` explains adoption/findings without writing or connecting.\n- GraphQL/PostgREST exports remain legitimate protocol contracts. This check is not\n proof of deployed schema, effective role permissions or complete RLS equivalence.\n\nDo not introduce any/@ts-ignore to bypass a contract. Use Drizzle-inferred types,\npreserve bigint/numeric precision and decode unknown results at the boundary.\n";
|
|
13
|
+
export declare const STARTER_DATABASE_GUIDE = "\n## Database Source Workflow\n\nDrizzle owns table declarations and inferred row types in db/schema.ts.\nUse the existing @supacloud/db/drizzle-bun adapters for typed queries and governed\ntransactions; never replace permission, idempotency or audit checks with plain CRUD.\nOpaque JSON still needs runtime decoding.\n\nAfter installing dependencies, run `bun run db:generate` once and commit db/contracts/.\nThe default `bun run check` and build fail on stale database contracts before any\ncompiler regeneration. After an intentional source change, run db:generate again,\nreview the diff, then run check. Ordinary checks are offline.\nThe compiler also runs this source-contract gate on compile/check/dev through\ndatabaseGovernance.mode = \"check\", including incremental cache hits. Missing\nadoption files or stale contracts fail closed; no contracts are silently regenerated.\nThis is not SQL lint or live Catalog reconciliation. Before promotion, declare\nthe real database modules, their SQL and tests, then explicitly use mode \"enforce\"\nwith a separately selected read-only local/test database connection.\n\n- Maintain one schema-qualified function with explicit grants per db/functions/*.sql.\n- Preserve migrations/ and its existing executor/ledger. Add forward migrations only.\n- `bun run db:diff` generates Drizzle drafts under db/migration-candidates/, never\n into the deployment directory. The starter has existing SQL history, so establish\n and review a matching Drizzle baseline before promoting any draft; the first\n draft is not automatically an incremental production migration.\n- `bun run db:pull` requires an explicitly selected DATABASE_URL and writes only\n output/database-audit/drizzle-candidate/. Review candidates; never overwrite source blindly.\n- Full SQL dumps belong under the ignored output/database-audit/ directory. They are\n audit/recovery artifacts, never ordinary type, application or test inputs.\n- `bun run db:assess` explains adoption/findings without writing or connecting.\n- GraphQL/PostgREST exports remain legitimate protocol contracts. This check is not\n proof of deployed schema, effective role permissions or complete RLS equivalence.\n\nDo not introduce any/@ts-ignore to bypass a contract. Use Drizzle-inferred types,\npreserve bigint/numeric precision and decode unknown results at the boundary.\n";
|
|
14
14
|
export declare function starterDatabaseFiles(): Record<string, string>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Shared reactive conventions for command, HTTP and edge starters. */
|
|
2
|
-
export declare const STARTER_REACTIVE_GUIDE = "# Reactive development / \u54CD\u5E94\u5F0F\u5F00\u53D1\n\nRxJS is
|
|
3
|
-
export declare const STARTER_REACTIVE_AGENTS = "# Application development rules\n\nRead README.md and REACTIVE.md before adding asynchronous features. If the\napplication is hosted by Angular, read the @supacloud/app/angular guidance\nbefore choosing a signal API.\nPrefer the generated contracts and existing project-bound @supacloud/js client.\nUse async/await for a single result; RxJS is the default event-composition library.\nBind subscriptions to an explicit owner and propagate cancellation to native I/O.\nNever automatically retry a write or turn observable delivery into durable ack.\nDo not bypass authorization, transactions, idempotency or audit to simplify code.\nRun bun run check; include negative and cleanup tests. Never store live credentials.\n";
|
|
2
|
+
export declare const STARTER_REACTIVE_GUIDE = "# Reactive development / \u54CD\u5E94\u5F0F\u5F00\u53D1\n\nRxJS is the default and only reactive event library in the starter ecosystem.\nOrdinary queries and business commands still use async/await. Use RxJS for\nongoing events and timing/composition, not as a new\ntransaction, retry or durable-delivery system.\n\nHost defaults:\n- In a native Angular host, use signal/resource APIs from @supacloud/app/angular\n and Angular's scheduler. Do not mix them with the legacy root signal graph.\n- In framework-neutral code, use async/await for one result and RxJS for event\n composition. Raw continuous protocols use AsyncIterable unless an existing\n RxJS/Angular boundary is the better fit. The host owns cancellation through\n an explicit signal.\n\n- Import native operators from rxjs; do not invent another event/operator library.\n- Import takeUntilAborted / toReadableStream from @supacloud/app/reactive.\n- Every subscription belongs to a request, connection, task or application owner.\n Bind the owner's AbortSignal before starting work; release it on exit.\n- toReadableStream has a bounded item buffer and fails on overflow. It is not\n an event journal. Do not silently drop durable business events or audit records.\n- Never wrap command submission in defer/retry/repeat or submit from subscribe.\n Await the existing governed command and then observe its existing receipt.\n- Do not shareReplay authenticated values globally across projects or sessions.\n- subscribe(async ...) does not await processing. Keep acknowledged task-output\n consumers on the SDK's for-await watch path; do not advance onCursor via next().\n\n## SupaCloud JS\n\nThe platform SDK is @supacloud/js, not a replacement Supabase client. Keep the\nclient from createSupaCloudClient. Database/Auth/Storage calls use client.supabase;\nplatform commands/tasks use the existing client.commands / client.tasks APIs.\nFor applications using this SDK, import observeQuery and observeTask from\n@supacloud/js/reactive. Pass the request signal to the native query builder:\n\n observeQuery(signal => client.supabase.from(\"widgets\").select(\"id\").abortSignal(signal), { signal: owner.signal })\n\nThe query result keeps data/error/count/status; non-null errors enter error().\nThe query factory runs once per subscriber. This is intended for reads, not\nreplaying writes. A PromiseLike is supported; an already-started Promise is not\nan appropriate factory. Unsubscribe aborts cooperative I/O, not committed work.\n\nSubmit a background task ONCE with the existing SDK, then observe the receipt:\n\n const task = await client.functions.invokeBackground(\"render\", { body: input });\n const progress = observeTask(task, { signal: owner.signal });\n\nUnsubscribing progress does not cancel the server task. Task read/decoder errors\nterminate observation; there is no automatic business retry. Realtime-to-polling\nfallback and project validation remain the SDK's responsibilities. Do not invent\na public.tasks table or copy service credentials into browser code.\n\nRun bun run check. Add cancellation, error, overflow and cross-owner isolation\ncoverage whenever adding streaming behavior. These APIs require the matching\nframework/SDK release or the packed candidate packages used by repository CI.\n";
|
|
3
|
+
export declare const STARTER_REACTIVE_AGENTS = "# Application development rules\n\nRead README.md and REACTIVE.md before adding asynchronous features. If the\napplication is hosted by Angular, read the @supacloud/app/angular guidance\nbefore choosing a signal API.\nPrefer the generated contracts and existing project-bound @supacloud/js client.\nUse async/await for a single result; RxJS is the default event-composition\nlibrary. Do not introduce another reactive library without a documented special\nrequirement and equivalent lifecycle tests.\nBind subscriptions to an explicit owner and propagate cancellation to native I/O.\nNever automatically retry a write or turn observable delivery into durable ack.\nDo not bypass authorization, transactions, idempotency or audit to simplify code.\nRun bun run check; include negative and cleanup tests. Never store live credentials.\n";
|
|
4
4
|
export declare const STARTER_REACTIVE_TEST = "import { expect, test } from \"bun:test\";\nimport { Observable } from \"rxjs\";\nimport { takeUntilAborted, toReadableStream } from \"@supacloud/app/reactive\";\n\ntest(\"the owner's signal releases reactive work exactly once\", () => {\n const owner = new AbortController();\n let starts = 0, stops = 0;\n const source = new Observable<number>(() => { starts++; return () => { stops++; }; });\n source.pipe(takeUntilAborted(owner.signal)).subscribe();\n owner.abort();\n source.pipe(takeUntilAborted(owner.signal)).subscribe();\n expect(starts).toBe(1);\n expect(stops).toBe(1);\n});\n\ntest(\"cancelled stream consumers release their subscription\", async () => {\n let stops = 0;\n const source = new Observable<number>(() => () => { stops++; });\n const stream = toReadableStream(source);\n await stream.cancel();\n expect(stops).toBe(1);\n});\n";
|
|
@@ -9,7 +9,7 @@ export declare const APPLICATION_TOOL_SCHEMA: {
|
|
|
9
9
|
ttl_seconds: Type.TOptional<Type.TInteger>;
|
|
10
10
|
wait: Type.TOptional<Type.TBoolean>;
|
|
11
11
|
timeout_seconds: Type.TOptional<Type.TInteger>;
|
|
12
|
-
action: Type.TEnum<("
|
|
12
|
+
action: Type.TEnum<("upload_release" | "activate_release" | "list_releases" | "get_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_release_transfer_plan" | "get_promotion_plan" | "get_promotion_status" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "get_preview_plan" | "list_previews" | "get_preview" | "put_configuration" | "deploy_application" | "transfer_release" | "promote_application" | "reconcile_promotion" | "create_preview" | "reconcile_preview" | "cleanup_preview" | "deploy_release" | "rollback_release" | "reconcile_activation" | "retire_activation")[]>;
|
|
13
13
|
ref: Type.TString;
|
|
14
14
|
id: Type.TString;
|
|
15
15
|
environment_id: Type.TOptional<Type.TString>;
|
|
@@ -14,7 +14,6 @@ interface DeployToolOptions {
|
|
|
14
14
|
manifestPath?: string;
|
|
15
15
|
};
|
|
16
16
|
applicationRelease?: (args: Record<string, unknown>) => Promise<ToolResponse>;
|
|
17
|
-
edgeFunctionDeploy?: (args: Record<string, unknown>) => Promise<ToolResponse>;
|
|
18
17
|
}
|
|
19
18
|
interface ToolResponse {
|
|
20
19
|
content: Array<{
|
|
@@ -25,15 +24,8 @@ interface ToolResponse {
|
|
|
25
24
|
}
|
|
26
25
|
export declare const deployToolSchema: {
|
|
27
26
|
ref: Type.TOptional<Type.TString>;
|
|
28
|
-
target: Type.TOptional<Type.TString>;
|
|
29
|
-
id: Type.TOptional<Type.TString>;
|
|
30
27
|
cwd: Type.TOptional<Type.TString>;
|
|
31
|
-
build_command: Type.TOptional<Type.TString>;
|
|
32
|
-
output_dir: Type.TOptional<Type.TString>;
|
|
33
28
|
skip_build: Type.TOptional<Type.TBoolean>;
|
|
34
|
-
dry_run: Type.TOptional<Type.TBoolean>;
|
|
35
|
-
plan: Type.TOptional<Type.TBoolean>;
|
|
36
|
-
diff: Type.TOptional<Type.TBoolean>;
|
|
37
29
|
json: Type.TOptional<Type.TBoolean>;
|
|
38
30
|
};
|
|
39
31
|
export declare function findDeployConfigRoot(startDirectory: string, environmentName?: string): Promise<string>;
|
|
@@ -15,7 +15,7 @@ export declare const environmentToolSchema: ToolSchema;
|
|
|
15
15
|
declare function outputDirectoryFor(manifest: PackageManifest): string;
|
|
16
16
|
declare function profileNameFromFile(name: string): string | null;
|
|
17
17
|
declare function statusMissing(context: ResolvedContext): string[];
|
|
18
|
-
declare function deployMissing(context: ResolvedContext): string[];
|
|
18
|
+
declare function deployMissing(context: ResolvedContext, application?: Record<string, unknown> | null): string[];
|
|
19
19
|
export declare function registerDeveloperExperienceTools(server: ToolServer, options?: DeveloperExperienceOptions): void;
|
|
20
20
|
export declare const __internal: {
|
|
21
21
|
outputDirectoryFor: typeof outputDirectoryFor;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { ToolResult } from "../tool-server";
|
|
2
2
|
import type { HttpTransport } from "../transports/http";
|
|
3
|
+
export declare function requireProjectDeploymentProtocol(http: Pick<HttpTransport, "get">, projectRef: string, environmentId: string): Promise<void>;
|
|
3
4
|
export declare function runProjectDeployment(http: Pick<HttpTransport, "post" | "get">, args: Record<string, unknown>): Promise<ToolResult>;
|
|
@@ -20,7 +20,7 @@ export interface RemoteDevToolOptions {
|
|
|
20
20
|
}
|
|
21
21
|
export declare const remoteDevToolSchema: {
|
|
22
22
|
action: Type.TEnum<("status" | "migrate" | "watch" | "sync")[]>;
|
|
23
|
-
target: Type.TOptional<Type.TEnum<("
|
|
23
|
+
target: Type.TOptional<Type.TEnum<("frontend" | "project" | "db" | "functions")[]>>;
|
|
24
24
|
project_dir: Type.TOptional<Type.TString>;
|
|
25
25
|
remote_root: Type.TOptional<Type.TString>;
|
|
26
26
|
remote_host: Type.TOptional<Type.TString>;
|
package/dist/tool-runtime.js
CHANGED
|
@@ -129,12 +129,37 @@ function schemaProperties(schema) {
|
|
|
129
129
|
// src/shared/tool-server.ts
|
|
130
130
|
import { Type as Type2 } from "typebox";
|
|
131
131
|
import { Value as Value2 } from "typebox/value";
|
|
132
|
+
|
|
133
|
+
// src/shared/deployment-upgrade.ts
|
|
134
|
+
var DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment is no longer supported. Upgrade with `npm install -g @supacloud/cli@latest`, bind application.id and application.environmentId in supacloud.json (or SUPACLOUD_APPLICATION_ID and SUPACLOUD_ENV), then run `supacloud deploy`. SupaCloud owns deployment planning and activation; do not retry with legacy commands.";
|
|
135
|
+
var removedFrontendActions = new Set([
|
|
136
|
+
"deploy_git",
|
|
137
|
+
"deploy_upload",
|
|
138
|
+
"redeploy",
|
|
139
|
+
"upload_release",
|
|
140
|
+
"activate_release"
|
|
141
|
+
]);
|
|
142
|
+
var removedDeployFlags = ["target", "id", "build_command", "output_dir", "plan", "diff", "dry_run"];
|
|
143
|
+
function assertCurrentDeploymentInput(tool, input) {
|
|
144
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
145
|
+
return;
|
|
146
|
+
const args = input;
|
|
147
|
+
if (tool === "frontend" && typeof args["action"] === "string" && removedFrontendActions.has(args["action"])) {
|
|
148
|
+
throw new Error(DEPLOYMENT_UPGRADE);
|
|
149
|
+
}
|
|
150
|
+
if (tool === "deploy" && removedDeployFlags.some((flag) => Object.hasOwn(args, flag))) {
|
|
151
|
+
throw new Error(`${DEPLOYMENT_UPGRADE} Put build settings in the frontend configuration. For read-only review use \`supacloud app deploy-plan\`.`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/shared/tool-server.ts
|
|
132
156
|
var resultSchema = Type2.Object({
|
|
133
157
|
content: Type2.Array(Type2.Object({ type: Type2.Literal("text"), text: Type2.String() })),
|
|
134
158
|
isError: Type2.Optional(Type2.Boolean())
|
|
135
159
|
});
|
|
136
160
|
function registerTool(server, name, description, schema, callback) {
|
|
137
161
|
server.tool(name, description, schema, async (input) => {
|
|
162
|
+
assertCurrentDeploymentInput(name, input);
|
|
138
163
|
const args = parseToolArguments(schema, input);
|
|
139
164
|
const result = await callback(args);
|
|
140
165
|
if (!Value2.Check(resultSchema, result))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.95.0",
|
|
4
4
|
"description": "Project-scoped CLI for SupaCloud users",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"directory": "packages/cli"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@supacloud/compiler": "^0.
|
|
55
|
+
"@supacloud/compiler": "^0.45.0",
|
|
56
56
|
"@supacloud/delivery": "0.16.0",
|
|
57
|
-
"@supacloud/db": "0.16.
|
|
57
|
+
"@supacloud/db": "0.16.2",
|
|
58
58
|
"typebox": "1.3.36"
|
|
59
59
|
},
|
|
60
60
|
"overrides": {
|
|
@@ -29,6 +29,15 @@ Use `supacloud` as the project-level control surface and keep durable changes re
|
|
|
29
29
|
|
|
30
30
|
## Workflow
|
|
31
31
|
|
|
32
|
+
For normal application deployment, run `supacloud --env <name> deploy`.
|
|
33
|
+
Use the current application delivery configuration and a bound application ID.
|
|
34
|
+
Do not assemble a client-side sequence of scope generation, backup, migration
|
|
35
|
+
apply, PostgREST refresh, Function deployment and Web activation.
|
|
36
|
+
The server owns that sequence. Old `deploy --target` and `frontend` publishing
|
|
37
|
+
actions are removed: upgrade CLI and server together, migrate the configuration,
|
|
38
|
+
and retry the unified command. Do not substitute a legacy endpoint when it fails.
|
|
39
|
+
The inspection and database-maintenance workflow below is not a deployment checklist.
|
|
40
|
+
|
|
32
41
|
1. Classify the request using [references/command-map.md](references/command-map.md).
|
|
33
42
|
2. For database work, load [references/database-workflow.md](references/database-workflow.md) and choose either new-change or historical-drift reconciliation.
|
|
34
43
|
3. For AI-assisted database changes, first request bounded context:
|
|
@@ -6,6 +6,7 @@ Load this reference when selecting a command surface or when a user asks an AI t
|
|
|
6
6
|
|
|
7
7
|
| Intent | Use | Guardrail |
|
|
8
8
|
| --- | --- | --- |
|
|
9
|
+
| Deploy the bound application | `supacloud --env <name> deploy` | Use current CLI/server and application delivery configuration; never fall back to standalone target or direct frontend activation commands |
|
|
9
10
|
| Inspect current project binding | `supacloud status` | Read-only; run first |
|
|
10
11
|
| Inspect selected project API/Auth/Studio origins | `supacloud project endpoints` | Uses the Management API's authoritative projection; do not reconstruct domains locally |
|
|
11
12
|
| Enumerate projects or endpoint projections | `supacloud-admin project list` / `project list_endpoints` | Platform-wide read; never promote a project credential to Admin authority |
|
|
@@ -23,9 +24,6 @@ Load this reference when selecting a command surface or when a user asks an AI t
|
|
|
23
24
|
| Inspect or back up a remote database | `supabase db_pull`, `migration_list`, `db_dump`, `gen_types` | Requires explicit PostgreSQL DSN; redact it |
|
|
24
25
|
| Replay the release-canary fixture stage receipt | `release release_canary_fixture_stage_replay` | Dual-bind Management project context and that project's service-role application origin; accepts only the exact subject/request UUID pair and a strict idempotent receipt |
|
|
25
26
|
| Disable a staged release-canary fixture | `release release_canary_fixture_disable_replay` | Uses the fixed disable RPC once, accepts idempotent false/true receipts, then queries the existing pending RPC with issuer/subject and requires authoritative JSON `false`; fixture binding comes from the strict disable receipt |
|
|
26
|
-
| Rebind release scope manifest to upstream base commit | `release scope_rebind` | Local maintenance action; requires the exact `--environment_id`, updates only scopes bound to that environment, supports `--dry_run`/`--task`, and recalculates `scope_sha256` |
|
|
27
|
-
| Inspect release scope manifest and git alignment | `release scope_inspect` | Local maintenance action; requires the exact `--environment_id`, rejects legacy or cross-environment scopes, returns canonical hash, and checks alignment with HEAD / origin/main |
|
|
28
|
-
| Scaffold a new canonical release scope manifest | `release scope_create` | Local maintenance action; requires `--environment_id` and outputs a current-main-bound scope with sorted functions, migrations, and environment identity |
|
|
29
27
|
| Preview/apply migrations remotely | `supabase push` | Always dry-run first; production needs explicit approval |
|
|
30
28
|
| Mark proven-equivalent historical migrations as applied | `database baseline_migrations` | Dry-run, schema-equivalence proof, backup, explicit approval |
|
|
31
29
|
| Inspect auth users or generate a controlled login link | `auth list_users`, `auth get_user`, `auth generate_link` | User reads are bounded; generation supports only `magiclink`, `recovery`, and `invite`, requires production confirmation, and returns only a validated action URL |
|
|
@@ -47,11 +45,11 @@ until a project-scoped context is resolved.
|
|
|
47
45
|
- `auth`: provider/configuration plus bounded user lookup and production-confirmed `magiclink`, `recovery`, or `invite` generation. Search/email/redirect inputs and returned action URLs are bounded and validated before use.
|
|
48
46
|
- `storage`: buckets and object-management workflows.
|
|
49
47
|
- `edge_functions`: list, atomically read one active or deleted identity with `get_config`, read immutable source, deploy, activate, configure, and delete Edge Functions. For every mutation, pass the `activation_id` read from the same `list` or `get_config` snapshot as `--expected-activation-id`; use `legacy` only for a never-created or listed legacy Function, not for a deleted slug with a tombstone UUID. Deploy and activate actions also require the non-negative observed version as `--expected-active-version`; use `absent` for a never-created slug or a `get_config` tombstone. Version `0` is a legacy version token and cannot be used as a source or activation target.
|
|
50
|
-
- `frontend`:
|
|
48
|
+
- `frontend`: hosting management, release inspection and operator rollback. Publishing uses `supacloud deploy`; `deploy_git`, `deploy_upload`, `redeploy`, `upload_release` and `activate_release` are removed.
|
|
51
49
|
- `secrets`: project secret management; never print values after write.
|
|
52
50
|
- `queue`, `task_events`, `diagnostics`: asynchronous workload operations and bounded diagnostics.
|
|
53
51
|
- `gateway`: project route/config/rebuild operations.
|
|
54
|
-
- `release`:
|
|
52
|
+
- `release`: explicit backup/PostgREST maintenance and release-canary replay diagnostics. Do not run these or generate release scopes as prerequisites for `supacloud --env <name> deploy`; the platform owns deployment orchestration.
|
|
55
53
|
- `ai`: inspect or install this packaged Skill.
|
|
56
54
|
|
|
57
55
|
## Safe inspection pattern
|