@supacloud/cli 0.32.0 → 0.33.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 +29 -0
- package/dist/index.js +281 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -440,6 +440,35 @@ Use `--data_mode full_clone` only for an explicitly approved non-sensitive or
|
|
|
440
440
|
masked debugging dataset. Whole-database replacement is an administrator-only
|
|
441
441
|
break-glass API mode and is intentionally not exposed by this project CLI.
|
|
442
442
|
|
|
443
|
+
## SupaCloud Lite CLI adapter
|
|
444
|
+
|
|
445
|
+
Lite can be used from its standalone `supacloud-lite` CLI and from the main
|
|
446
|
+
`supacloud-cli` through the local-only `lite` module. The adapter never calls
|
|
447
|
+
the Management API, never invokes the official Supabase CLI, and never treats a
|
|
448
|
+
PGlite data directory as a Postgres DSN.
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
supacloud-cli lite migrate --project_dir .
|
|
452
|
+
supacloud-cli lite status --project_dir .
|
|
453
|
+
supacloud-cli lite db_diff --project_dir . --file add_accounts
|
|
454
|
+
supacloud-cli lite db_pull --project_dir . --file remote_schema
|
|
455
|
+
supacloud-cli lite gen_types --project_dir . --output src/database.types.ts
|
|
456
|
+
supacloud-cli lite snapshot_create --project_dir . --output backups/lite.tar.gz
|
|
457
|
+
supacloud-cli lite doctor --project_dir . --json
|
|
458
|
+
supacloud-cli lite start --project_dir . --port 54321
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
The adapter resolves the executable in this order:
|
|
462
|
+
|
|
463
|
+
1. `SUPACLOUD_LITE_CLI_BIN`
|
|
464
|
+
2. `<workdir>/node_modules/@supacloud/lite/dist/launcher.cjs`
|
|
465
|
+
3. `supacloud-lite` on `PATH`
|
|
466
|
+
|
|
467
|
+
Install `@supacloud/lite` or provide an explicit binary before using the
|
|
468
|
+
adapter. Lite actions are local-only, so Management API context and project
|
|
469
|
+
refs are not required. The `supabase` module remains the official CLI adapter;
|
|
470
|
+
use it for upstream Supabase CLI actions and Management-backed remote pushes.
|
|
471
|
+
|
|
443
472
|
## Official Supabase CLI adapter
|
|
444
473
|
|
|
445
474
|
The `supabase` command group is a thin, allowlisted adapter around the official
|
package/dist/index.js
CHANGED
|
@@ -6471,6 +6471,24 @@ var ACTION_POLICY = {
|
|
|
6471
6471
|
local: ["version", "migration_new", "db_diff", "db_reset", "db_pull", "db_dump", "migration_list", "gen_types"],
|
|
6472
6472
|
write: ["push"]
|
|
6473
6473
|
},
|
|
6474
|
+
lite: {
|
|
6475
|
+
local: [
|
|
6476
|
+
"version",
|
|
6477
|
+
"start",
|
|
6478
|
+
"migrate",
|
|
6479
|
+
"status",
|
|
6480
|
+
"keys",
|
|
6481
|
+
"gen_types",
|
|
6482
|
+
"db_reset",
|
|
6483
|
+
"db_diff",
|
|
6484
|
+
"db_pull",
|
|
6485
|
+
"snapshot_create",
|
|
6486
|
+
"snapshot_restore",
|
|
6487
|
+
"upgrade",
|
|
6488
|
+
"inspect",
|
|
6489
|
+
"doctor"
|
|
6490
|
+
]
|
|
6491
|
+
},
|
|
6474
6492
|
auth: {
|
|
6475
6493
|
read: ["list_users", "get_user", "list_providers", "get_provider", "supported_providers", "get_settings", "get_config", "get_oauth_server"],
|
|
6476
6494
|
write: ["generate_link", "configure_provider", "update_provider", "disable_provider", "wechat_mini", "wechat_open", "update_settings", "update_config", "migrate_oauth_server"]
|
|
@@ -12894,10 +12912,236 @@ function registerSupabaseCliTools(server, options = {}) {
|
|
|
12894
12912
|
}, (request) => executeSupabaseAction(request, runtime));
|
|
12895
12913
|
}
|
|
12896
12914
|
|
|
12915
|
+
// src/shared/tools/lite-cli-tools.ts
|
|
12916
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
12917
|
+
import { existsSync as existsSync6, statSync as statSync4 } from "node:fs";
|
|
12918
|
+
import { join as join4, resolve as resolve4 } from "node:path";
|
|
12919
|
+
function requireWorkdir(workdir, fallback) {
|
|
12920
|
+
const resolved = resolve4(workdir || fallback);
|
|
12921
|
+
if (!existsSync6(resolved) || !statSync4(resolved).isDirectory()) {
|
|
12922
|
+
throw new Error(`Lite workdir not found: ${resolved}`);
|
|
12923
|
+
}
|
|
12924
|
+
return resolved;
|
|
12925
|
+
}
|
|
12926
|
+
function optionalFlag(args, flag, value) {
|
|
12927
|
+
if (value !== undefined)
|
|
12928
|
+
args.push(flag, String(value));
|
|
12929
|
+
}
|
|
12930
|
+
function booleanFlag(args, flag, value) {
|
|
12931
|
+
if (value === true)
|
|
12932
|
+
args.push(flag);
|
|
12933
|
+
}
|
|
12934
|
+
function buildLiteArgs(request) {
|
|
12935
|
+
const args = [];
|
|
12936
|
+
if (request.action === "version")
|
|
12937
|
+
return ["--version"];
|
|
12938
|
+
switch (request.action) {
|
|
12939
|
+
case "start":
|
|
12940
|
+
case "migrate":
|
|
12941
|
+
case "status":
|
|
12942
|
+
case "keys":
|
|
12943
|
+
case "upgrade":
|
|
12944
|
+
case "inspect":
|
|
12945
|
+
case "doctor":
|
|
12946
|
+
args.push(request.action);
|
|
12947
|
+
break;
|
|
12948
|
+
case "gen_types":
|
|
12949
|
+
args.push("gen", "types");
|
|
12950
|
+
break;
|
|
12951
|
+
case "db_reset":
|
|
12952
|
+
args.push("db", "reset");
|
|
12953
|
+
break;
|
|
12954
|
+
case "db_diff":
|
|
12955
|
+
args.push("db", "diff");
|
|
12956
|
+
break;
|
|
12957
|
+
case "db_pull":
|
|
12958
|
+
args.push("db", "pull");
|
|
12959
|
+
if (request.file)
|
|
12960
|
+
args.push(request.file);
|
|
12961
|
+
break;
|
|
12962
|
+
case "snapshot_create":
|
|
12963
|
+
args.push("snapshot", "create");
|
|
12964
|
+
break;
|
|
12965
|
+
case "snapshot_restore":
|
|
12966
|
+
if (!request.snapshot_file)
|
|
12967
|
+
throw new Error("snapshot_restore requires --snapshot_file");
|
|
12968
|
+
args.push("snapshot", "restore", request.snapshot_file);
|
|
12969
|
+
break;
|
|
12970
|
+
default:
|
|
12971
|
+
throw new Error(`Unsupported Lite CLI action: ${String(request.action)}`);
|
|
12972
|
+
}
|
|
12973
|
+
optionalFlag(args, "--project-dir", request.project_dir);
|
|
12974
|
+
optionalFlag(args, "--state-dir", request.state_dir);
|
|
12975
|
+
optionalFlag(args, "--data-dir", request.data_dir);
|
|
12976
|
+
optionalFlag(args, "--storage-dir", request.storage_dir);
|
|
12977
|
+
optionalFlag(args, "--storage-backend", request.storage_backend);
|
|
12978
|
+
optionalFlag(args, "--s3-prefix", request.s3_prefix);
|
|
12979
|
+
optionalFlag(args, "--engine", request.engine);
|
|
12980
|
+
optionalFlag(args, "--host", request.host);
|
|
12981
|
+
optionalFlag(args, "--port", request.port);
|
|
12982
|
+
optionalFlag(args, "--api-url", request.api_url);
|
|
12983
|
+
optionalFlag(args, "--site-url", request.site_url);
|
|
12984
|
+
optionalFlag(args, "--replication-profile", request.replication_profile);
|
|
12985
|
+
optionalFlag(args, "--replication-host", request.replication_host);
|
|
12986
|
+
optionalFlag(args, "--replication-port", request.replication_port);
|
|
12987
|
+
optionalFlag(args, "--replication-allow-cidrs", request.replication_allow_cidrs);
|
|
12988
|
+
optionalFlag(args, "--powersync-tables", request.powersync_tables);
|
|
12989
|
+
optionalFlag(args, "--replication-tls-cert", request.replication_tls_cert);
|
|
12990
|
+
optionalFlag(args, "--replication-tls-key", request.replication_tls_key);
|
|
12991
|
+
optionalFlag(args, "--output", request.output);
|
|
12992
|
+
optionalFlag(args, "--file", request.action === "db_diff" ? request.file : undefined);
|
|
12993
|
+
booleanFlag(args, "--service-role", request.service_role);
|
|
12994
|
+
booleanFlag(args, "--force", request.force);
|
|
12995
|
+
booleanFlag(args, "--memory", request.memory);
|
|
12996
|
+
booleanFlag(args, "--json", request.json);
|
|
12997
|
+
return args;
|
|
12998
|
+
}
|
|
12999
|
+
function resolveLiteCommand(workdir, environment = process.env) {
|
|
13000
|
+
const explicitBinary = environment.SUPACLOUD_LITE_CLI_BIN?.trim();
|
|
13001
|
+
if (explicitBinary) {
|
|
13002
|
+
if (explicitBinary.includes("\x00"))
|
|
13003
|
+
throw new Error("Invalid SUPACLOUD_LITE_CLI_BIN");
|
|
13004
|
+
return [explicitBinary];
|
|
13005
|
+
}
|
|
13006
|
+
const localPackageEntry = join4(resolve4(workdir), "node_modules", "@supacloud", "lite", "dist", "launcher.cjs");
|
|
13007
|
+
if (existsSync6(localPackageEntry))
|
|
13008
|
+
return [process.execPath, localPackageEntry];
|
|
13009
|
+
return ["supacloud-lite"];
|
|
13010
|
+
}
|
|
13011
|
+
function spawnLiteCommand(command, workdir, environment, inheritOutput) {
|
|
13012
|
+
const [executable, ...commandArguments] = command;
|
|
13013
|
+
return new Promise((resolveExecution, rejectExecution) => {
|
|
13014
|
+
const child = spawn2(executable, commandArguments, {
|
|
13015
|
+
cwd: workdir,
|
|
13016
|
+
env: { ...environment, NO_COLOR: "1" },
|
|
13017
|
+
shell: false,
|
|
13018
|
+
stdio: inheritOutput ? ["inherit", "inherit", "inherit"] : ["ignore", "pipe", "pipe"],
|
|
13019
|
+
windowsHide: true
|
|
13020
|
+
});
|
|
13021
|
+
const forwardSignal = (signal) => child.kill(signal);
|
|
13022
|
+
process.once("SIGINT", forwardSignal);
|
|
13023
|
+
process.once("SIGTERM", forwardSignal);
|
|
13024
|
+
const cleanup = () => {
|
|
13025
|
+
process.off("SIGINT", forwardSignal);
|
|
13026
|
+
process.off("SIGTERM", forwardSignal);
|
|
13027
|
+
};
|
|
13028
|
+
if (inheritOutput) {
|
|
13029
|
+
child.once("error", (error) => {
|
|
13030
|
+
cleanup();
|
|
13031
|
+
rejectExecution(error);
|
|
13032
|
+
});
|
|
13033
|
+
child.once("close", (exitCode) => {
|
|
13034
|
+
cleanup();
|
|
13035
|
+
resolveExecution({ exitCode: exitCode ?? 1, stdout: "", stderr: "" });
|
|
13036
|
+
});
|
|
13037
|
+
return;
|
|
13038
|
+
}
|
|
13039
|
+
if (!child.stdout || !child.stderr) {
|
|
13040
|
+
cleanup();
|
|
13041
|
+
rejectExecution(new Error("Lite CLI child process did not expose piped output"));
|
|
13042
|
+
return;
|
|
13043
|
+
}
|
|
13044
|
+
let standardOutput = "";
|
|
13045
|
+
let standardError = "";
|
|
13046
|
+
child.stdout.setEncoding("utf8");
|
|
13047
|
+
child.stderr.setEncoding("utf8");
|
|
13048
|
+
child.stdout.on("data", (chunk) => {
|
|
13049
|
+
standardOutput += chunk;
|
|
13050
|
+
});
|
|
13051
|
+
child.stderr.on("data", (chunk) => {
|
|
13052
|
+
standardError += chunk;
|
|
13053
|
+
});
|
|
13054
|
+
child.once("error", (error) => {
|
|
13055
|
+
cleanup();
|
|
13056
|
+
rejectExecution(error);
|
|
13057
|
+
});
|
|
13058
|
+
child.once("close", (exitCode) => {
|
|
13059
|
+
cleanup();
|
|
13060
|
+
resolveExecution({ exitCode: exitCode ?? 1, stdout: standardOutput, stderr: standardError });
|
|
13061
|
+
});
|
|
13062
|
+
});
|
|
13063
|
+
}
|
|
13064
|
+
async function executeLiteCli(request, environment, fallbackWorkdir) {
|
|
13065
|
+
const workdir = requireWorkdir(request.workdir, fallbackWorkdir);
|
|
13066
|
+
const command = [...resolveLiteCommand(workdir, environment), ...buildLiteArgs({ ...request, workdir })];
|
|
13067
|
+
try {
|
|
13068
|
+
return await spawnLiteCommand(command, workdir, environment, request.action === "start");
|
|
13069
|
+
} catch (error) {
|
|
13070
|
+
const failureMessage = error instanceof Error ? error.message : String(error);
|
|
13071
|
+
throw new Error([
|
|
13072
|
+
"SupaCloud Lite CLI could not be started.",
|
|
13073
|
+
"Install @supacloud/lite, put supacloud-lite on PATH, or set SUPACLOUD_LITE_CLI_BIN.",
|
|
13074
|
+
failureMessage
|
|
13075
|
+
].join(" "));
|
|
13076
|
+
}
|
|
13077
|
+
}
|
|
13078
|
+
function formatExecutionText2(action, execution) {
|
|
13079
|
+
const combinedOutput = [execution.stdout.trim(), execution.stderr.trim()].filter(Boolean).join(`
|
|
13080
|
+
`);
|
|
13081
|
+
const heading = execution.exitCode === 0 ? `✅ SupaCloud Lite ${action} completed` : `❌ SupaCloud Lite ${action} failed (exit ${execution.exitCode})`;
|
|
13082
|
+
return combinedOutput ? `${heading}
|
|
13083
|
+
${combinedOutput}` : heading;
|
|
13084
|
+
}
|
|
13085
|
+
function registerLiteCliTools(server, options = {}) {
|
|
13086
|
+
const environment = options.environment || process.env;
|
|
13087
|
+
const fallbackWorkdir = options.currentWorkingDirectory || process.cwd();
|
|
13088
|
+
const execute = options.executeLiteCli || ((request) => executeLiteCli(request, environment, fallbackWorkdir));
|
|
13089
|
+
server.tool("lite", "Controlled adapter for the local SupaCloud Lite CLI. Lite actions are local-only and never use the Management API or official Supabase CLI.", {
|
|
13090
|
+
action: withDescription(stringEnum([
|
|
13091
|
+
"version",
|
|
13092
|
+
"start",
|
|
13093
|
+
"migrate",
|
|
13094
|
+
"status",
|
|
13095
|
+
"keys",
|
|
13096
|
+
"gen_types",
|
|
13097
|
+
"db_reset",
|
|
13098
|
+
"db_diff",
|
|
13099
|
+
"db_pull",
|
|
13100
|
+
"snapshot_create",
|
|
13101
|
+
"snapshot_restore",
|
|
13102
|
+
"upgrade",
|
|
13103
|
+
"inspect",
|
|
13104
|
+
"doctor"
|
|
13105
|
+
]), "Lite CLI action"),
|
|
13106
|
+
workdir: optional(Type.String(), "[*] Process working directory (default: current directory)"),
|
|
13107
|
+
project_dir: optional(Type.String(), "[*] Project containing supabase/"),
|
|
13108
|
+
state_dir: optional(Type.String(), "[*] Lite state root"),
|
|
13109
|
+
data_dir: optional(Type.String(), "[*] PGlite/native data directory"),
|
|
13110
|
+
storage_dir: optional(Type.String(), "[*] Object storage directory"),
|
|
13111
|
+
storage_backend: optional(stringEnum(["fs", "memory", "s3"]), "[*] Storage backend"),
|
|
13112
|
+
s3_prefix: optional(Type.String(), "[*] S3 object key prefix"),
|
|
13113
|
+
engine: optional(stringEnum(["pglite", "native"]), "[*] Database engine"),
|
|
13114
|
+
host: optional(Type.String(), "[start] Listen host"),
|
|
13115
|
+
port: optional(Type.Number(), "[start] Listen port"),
|
|
13116
|
+
api_url: optional(Type.String(), "[start] Public API URL"),
|
|
13117
|
+
site_url: optional(Type.String(), "[start] Auth site URL"),
|
|
13118
|
+
replication_profile: optional(stringEnum(["powersync"]), "[start/doctor] Replication profile"),
|
|
13119
|
+
replication_host: optional(Type.String(), "[start] Replication listener host"),
|
|
13120
|
+
replication_port: optional(Type.Number(), "[start] Replication listener port"),
|
|
13121
|
+
replication_allow_cidrs: optional(Type.String(), "[start] Replication client CIDRs"),
|
|
13122
|
+
powersync_tables: optional(Type.String(), "[start] PowerSync publication tables"),
|
|
13123
|
+
replication_tls_cert: optional(Type.String(), "[start] Replication TLS certificate"),
|
|
13124
|
+
replication_tls_key: optional(Type.String(), "[start] Replication TLS private key"),
|
|
13125
|
+
output: optional(Type.String(), "[gen_types/snapshot_create/upgrade] Output path"),
|
|
13126
|
+
file: optional(Type.String(), "[db_diff/db_pull] Migration suffix or name"),
|
|
13127
|
+
snapshot_file: optional(Type.String(), "[snapshot_restore] Snapshot archive"),
|
|
13128
|
+
service_role: optional(Type.Boolean(), "[keys] Also print the service_role key"),
|
|
13129
|
+
force: optional(Type.Boolean(), "[snapshot_restore] Replace non-empty restore targets"),
|
|
13130
|
+
memory: optional(Type.Boolean(), "[*] Use an in-memory PGlite database"),
|
|
13131
|
+
json: optional(Type.Boolean(), "[doctor] Emit machine-readable output")
|
|
13132
|
+
}, async (request) => {
|
|
13133
|
+
const execution = await execute(request);
|
|
13134
|
+
return {
|
|
13135
|
+
isError: execution.exitCode !== 0,
|
|
13136
|
+
content: [{ type: "text", text: formatExecutionText2(request.action, execution) }]
|
|
13137
|
+
};
|
|
13138
|
+
});
|
|
13139
|
+
}
|
|
13140
|
+
|
|
12897
13141
|
// src/shared/tools/ai-tools.ts
|
|
12898
13142
|
import {
|
|
12899
13143
|
cpSync,
|
|
12900
|
-
existsSync as
|
|
13144
|
+
existsSync as existsSync7,
|
|
12901
13145
|
lstatSync as lstatSync2,
|
|
12902
13146
|
mkdirSync as mkdirSync2,
|
|
12903
13147
|
mkdtempSync as mkdtempSync2,
|
|
@@ -12907,13 +13151,13 @@ import {
|
|
|
12907
13151
|
rmSync as rmSync2
|
|
12908
13152
|
} from "node:fs";
|
|
12909
13153
|
import { homedir as homedir2 } from "node:os";
|
|
12910
|
-
import { dirname as dirname2, join as
|
|
13154
|
+
import { dirname as dirname2, join as join5, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
|
|
12911
13155
|
import { fileURLToPath } from "node:url";
|
|
12912
13156
|
var SKILL_NAME = "supacloud-cli";
|
|
12913
13157
|
function regularFiles(rootDirectory, currentDirectory = rootDirectory) {
|
|
12914
13158
|
const files = [];
|
|
12915
13159
|
for (const directoryEntry of readdirSync3(currentDirectory, { withFileTypes: true })) {
|
|
12916
|
-
const entryPath =
|
|
13160
|
+
const entryPath = join5(currentDirectory, directoryEntry.name);
|
|
12917
13161
|
if (directoryEntry.isSymbolicLink())
|
|
12918
13162
|
throw new Error(`Skill directories cannot contain symlinks: ${entryPath}`);
|
|
12919
13163
|
if (directoryEntry.isDirectory())
|
|
@@ -12924,13 +13168,13 @@ function regularFiles(rootDirectory, currentDirectory = rootDirectory) {
|
|
|
12924
13168
|
return files.sort();
|
|
12925
13169
|
}
|
|
12926
13170
|
function directoriesMatch(sourceDirectory, destinationDirectory) {
|
|
12927
|
-
if (!
|
|
13171
|
+
if (!existsSync7(destinationDirectory) || !lstatSync2(destinationDirectory).isDirectory())
|
|
12928
13172
|
return false;
|
|
12929
13173
|
const sourceFiles = regularFiles(sourceDirectory);
|
|
12930
13174
|
const destinationFiles = regularFiles(destinationDirectory);
|
|
12931
13175
|
if (sourceFiles.join("\x00") !== destinationFiles.join("\x00"))
|
|
12932
13176
|
return false;
|
|
12933
|
-
return sourceFiles.every((file) => readFileSync5(
|
|
13177
|
+
return sourceFiles.every((file) => readFileSync5(join5(sourceDirectory, file)).equals(readFileSync5(join5(destinationDirectory, file))));
|
|
12934
13178
|
}
|
|
12935
13179
|
function backupTimestamp(now) {
|
|
12936
13180
|
return now.toISOString().replace(/[-:.]/g, "");
|
|
@@ -12939,7 +13183,7 @@ function availableBackupDirectory(destinationDirectory, now) {
|
|
|
12939
13183
|
const baseDirectory = `${destinationDirectory}.backup-${backupTimestamp(now)}`;
|
|
12940
13184
|
let candidate = baseDirectory;
|
|
12941
13185
|
let suffix = 2;
|
|
12942
|
-
while (
|
|
13186
|
+
while (existsSync7(candidate)) {
|
|
12943
13187
|
candidate = `${baseDirectory}-${suffix}`;
|
|
12944
13188
|
suffix += 1;
|
|
12945
13189
|
}
|
|
@@ -12947,8 +13191,8 @@ function availableBackupDirectory(destinationDirectory, now) {
|
|
|
12947
13191
|
}
|
|
12948
13192
|
function stagedSkill(sourceDirectory, targetRoot) {
|
|
12949
13193
|
mkdirSync2(targetRoot, { recursive: true });
|
|
12950
|
-
const stagingRoot = mkdtempSync2(
|
|
12951
|
-
const stagingSkill =
|
|
13194
|
+
const stagingRoot = mkdtempSync2(join5(targetRoot, ".supacloud-cli-install-"));
|
|
13195
|
+
const stagingSkill = join5(stagingRoot, SKILL_NAME);
|
|
12952
13196
|
try {
|
|
12953
13197
|
cpSync(sourceDirectory, stagingSkill, { recursive: true, errorOnExist: true });
|
|
12954
13198
|
} catch (error) {
|
|
@@ -12980,13 +13224,13 @@ function replaceSkill(sourceDirectory, targetRoot, destinationDirectory, backupD
|
|
|
12980
13224
|
}
|
|
12981
13225
|
}
|
|
12982
13226
|
function skillSummary(request, action, files, backupDirectory) {
|
|
12983
|
-
const sourceDirectory =
|
|
12984
|
-
const targetRoot =
|
|
13227
|
+
const sourceDirectory = resolve5(request.sourceDirectory);
|
|
13228
|
+
const targetRoot = resolve5(request.targetRoot);
|
|
12985
13229
|
return {
|
|
12986
13230
|
name: SKILL_NAME,
|
|
12987
13231
|
sourceDirectory,
|
|
12988
13232
|
targetRoot,
|
|
12989
|
-
destinationDirectory:
|
|
13233
|
+
destinationDirectory: join5(targetRoot, SKILL_NAME),
|
|
12990
13234
|
action,
|
|
12991
13235
|
mode: request.mode,
|
|
12992
13236
|
changed: action !== "none",
|
|
@@ -12995,14 +13239,14 @@ function skillSummary(request, action, files, backupDirectory) {
|
|
|
12995
13239
|
};
|
|
12996
13240
|
}
|
|
12997
13241
|
function installSkill(request) {
|
|
12998
|
-
const sourceDirectory =
|
|
12999
|
-
const targetRoot =
|
|
13000
|
-
const destinationDirectory =
|
|
13001
|
-
if (!
|
|
13242
|
+
const sourceDirectory = resolve5(request.sourceDirectory);
|
|
13243
|
+
const targetRoot = resolve5(request.targetRoot);
|
|
13244
|
+
const destinationDirectory = join5(targetRoot, SKILL_NAME);
|
|
13245
|
+
if (!existsSync7(join5(sourceDirectory, "SKILL.md"))) {
|
|
13002
13246
|
throw new Error(`Bundled SupaCloud CLI skill not found: ${sourceDirectory}`);
|
|
13003
13247
|
}
|
|
13004
13248
|
const files = regularFiles(sourceDirectory);
|
|
13005
|
-
if (!
|
|
13249
|
+
if (!existsSync7(destinationDirectory))
|
|
13006
13250
|
return installNewSkill(request, files);
|
|
13007
13251
|
if (directoriesMatch(sourceDirectory, destinationDirectory)) {
|
|
13008
13252
|
return skillSummary(request, "none", files, null);
|
|
@@ -13013,17 +13257,17 @@ function installSkill(request) {
|
|
|
13013
13257
|
return installReplacementSkill(request, files);
|
|
13014
13258
|
}
|
|
13015
13259
|
function installNewSkill(request, files) {
|
|
13016
|
-
const sourceDirectory =
|
|
13017
|
-
const targetRoot =
|
|
13260
|
+
const sourceDirectory = resolve5(request.sourceDirectory);
|
|
13261
|
+
const targetRoot = resolve5(request.targetRoot);
|
|
13018
13262
|
if (request.mode === "write") {
|
|
13019
|
-
createSkill(sourceDirectory, targetRoot,
|
|
13263
|
+
createSkill(sourceDirectory, targetRoot, join5(targetRoot, SKILL_NAME));
|
|
13020
13264
|
}
|
|
13021
13265
|
return skillSummary(request, "create", files, null);
|
|
13022
13266
|
}
|
|
13023
13267
|
function installReplacementSkill(request, files) {
|
|
13024
|
-
const sourceDirectory =
|
|
13025
|
-
const targetRoot =
|
|
13026
|
-
const destinationDirectory =
|
|
13268
|
+
const sourceDirectory = resolve5(request.sourceDirectory);
|
|
13269
|
+
const targetRoot = resolve5(request.targetRoot);
|
|
13270
|
+
const destinationDirectory = join5(targetRoot, SKILL_NAME);
|
|
13027
13271
|
const backupDirectory = availableBackupDirectory(destinationDirectory, request.now);
|
|
13028
13272
|
if (request.mode === "write") {
|
|
13029
13273
|
replaceSkill(sourceDirectory, targetRoot, destinationDirectory, backupDirectory);
|
|
@@ -13032,15 +13276,15 @@ function installReplacementSkill(request, files) {
|
|
|
13032
13276
|
}
|
|
13033
13277
|
function resolveDefaultCodexSkillRoot(environment = process.env, homeDirectory = homedir2()) {
|
|
13034
13278
|
const codexHome = environment.CODEX_HOME?.trim();
|
|
13035
|
-
return
|
|
13279
|
+
return join5(resolve5(codexHome || join5(homeDirectory, ".codex")), "skills");
|
|
13036
13280
|
}
|
|
13037
13281
|
function resolveBundledSkillDirectory(moduleUrl = import.meta.url) {
|
|
13038
13282
|
const moduleDirectory = dirname2(fileURLToPath(moduleUrl));
|
|
13039
13283
|
const candidates = [
|
|
13040
|
-
|
|
13041
|
-
|
|
13284
|
+
resolve5(moduleDirectory, "../../../skills", SKILL_NAME),
|
|
13285
|
+
resolve5(moduleDirectory, "../skills", SKILL_NAME)
|
|
13042
13286
|
];
|
|
13043
|
-
const skillDirectory = candidates.find((candidate) =>
|
|
13287
|
+
const skillDirectory = candidates.find((candidate) => existsSync7(join5(candidate, "SKILL.md")));
|
|
13044
13288
|
if (!skillDirectory)
|
|
13045
13289
|
throw new Error("Bundled SupaCloud CLI skill is missing from this installation");
|
|
13046
13290
|
return skillDirectory;
|
|
@@ -13062,7 +13306,7 @@ function registerAiTools(server) {
|
|
|
13062
13306
|
name: SKILL_NAME,
|
|
13063
13307
|
sourceDirectory,
|
|
13064
13308
|
defaultTargetRoot,
|
|
13065
|
-
defaultDestination:
|
|
13309
|
+
defaultDestination: join5(defaultTargetRoot, SKILL_NAME)
|
|
13066
13310
|
});
|
|
13067
13311
|
}
|
|
13068
13312
|
return textResponse(installSkill({
|
|
@@ -13077,8 +13321,8 @@ function registerAiTools(server) {
|
|
|
13077
13321
|
|
|
13078
13322
|
// src/shared/tools/scheduled-function-tools.ts
|
|
13079
13323
|
import { randomUUID } from "node:crypto";
|
|
13080
|
-
import { readFileSync as readFileSync6, statSync as
|
|
13081
|
-
import { resolve as
|
|
13324
|
+
import { readFileSync as readFileSync6, statSync as statSync5 } from "node:fs";
|
|
13325
|
+
import { resolve as resolve6 } from "node:path";
|
|
13082
13326
|
import { isDeepStrictEqual } from "node:util";
|
|
13083
13327
|
var HEADER_NAME_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$/;
|
|
13084
13328
|
var ENVIRONMENT_NAME_PATTERN2 = /^[A-Za-z_][A-Za-z0-9_]{0,255}$/;
|
|
@@ -13162,8 +13406,8 @@ function validScheduledFunctionCron(expression) {
|
|
|
13162
13406
|
function readScheduleBodyFile(bodyPathInput) {
|
|
13163
13407
|
if (!bodyPathInput.trim())
|
|
13164
13408
|
throw new Error("'body_file' must be a path");
|
|
13165
|
-
const bodyPath =
|
|
13166
|
-
const bodyStat =
|
|
13409
|
+
const bodyPath = resolve6(bodyPathInput);
|
|
13410
|
+
const bodyStat = statSync5(bodyPath);
|
|
13167
13411
|
if (!bodyStat.isFile() || bodyStat.size > MAX_BODY_FILE_BYTES) {
|
|
13168
13412
|
throw new Error("Scheduled Function body file must be a regular file no larger than 1 MiB");
|
|
13169
13413
|
}
|
|
@@ -14121,7 +14365,7 @@ function registerReleaseTools(server, http, options = {}) {
|
|
|
14121
14365
|
// package.json
|
|
14122
14366
|
var package_default = {
|
|
14123
14367
|
name: "@supacloud/cli",
|
|
14124
|
-
version: "0.
|
|
14368
|
+
version: "0.33.0",
|
|
14125
14369
|
description: "Project-scoped CLI for SupaCloud users",
|
|
14126
14370
|
type: "module",
|
|
14127
14371
|
main: "./dist/index.js",
|
|
@@ -14386,6 +14630,9 @@ EXAMPLES
|
|
|
14386
14630
|
${preferredCommand} supabase db_diff --schema public --name add_accounts
|
|
14387
14631
|
${preferredCommand} supabase push --ref abc123 --dir supabase/migrations --dry_run
|
|
14388
14632
|
${preferredCommand} supabase db_dump --db_url "postgresql://..." --file backups/schema.sql
|
|
14633
|
+
${preferredCommand} lite migrate --project_dir .
|
|
14634
|
+
${preferredCommand} lite start --project_dir . --port 54321
|
|
14635
|
+
${preferredCommand} lite doctor --project_dir . --json
|
|
14389
14636
|
${preferredCommand} branch create --name feature-auth --data_mode schema_only
|
|
14390
14637
|
${preferredCommand} branch promotion_plan --branch_ref preview123
|
|
14391
14638
|
${preferredCommand} branch promote --branch_ref preview123 --plan_checksum <sha256>
|
|
@@ -14438,6 +14685,7 @@ function createCliTools(context, confirmProduction) {
|
|
|
14438
14685
|
projectRef: context.projectRef || undefined,
|
|
14439
14686
|
readOnly: context.readOnly
|
|
14440
14687
|
})));
|
|
14688
|
+
Object.assign(tools, captureTools((server) => registerLiteCliTools(server)));
|
|
14441
14689
|
Object.assign(tools, captureTools((server) => registerAiTools(server)));
|
|
14442
14690
|
const registerContextAwareHelp = () => {
|
|
14443
14691
|
tools.project = {
|
|
@@ -14599,7 +14847,7 @@ async function main() {
|
|
|
14599
14847
|
return;
|
|
14600
14848
|
}
|
|
14601
14849
|
const cliTools = createCliTools(context, globalOptions.confirmProduction);
|
|
14602
|
-
if (args.length === 1 && !["ai", "supabase"].includes(args[0]) && cliTools[args[0]]) {
|
|
14850
|
+
if (args.length === 1 && !["ai", "supabase", "lite"].includes(args[0]) && cliTools[args[0]]) {
|
|
14603
14851
|
const result = await cliTools[args[0]].callback({});
|
|
14604
14852
|
if (result?.content && Array.isArray(result.content)) {
|
|
14605
14853
|
for (const chunk of result.content) {
|