@agentlink.sh/cli 0.10.2 → 0.11.1
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 +9 -6
- package/dist/index.js +96 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,16 +41,19 @@ The install scripts automatically detect your OS, install Node.js if needed, and
|
|
|
41
41
|
## Quick start
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
# Create a new project (cloud by default
|
|
45
|
-
agentlink my-app
|
|
44
|
+
# Create a new project (cloud by default)
|
|
45
|
+
agentlink my-app
|
|
46
|
+
|
|
47
|
+
# With a prompt for Claude Code
|
|
48
|
+
agentlink my-app --prompt "Build a project management tool with kanban boards"
|
|
46
49
|
|
|
47
|
-
# Interactive wizard
|
|
50
|
+
# Interactive wizard
|
|
48
51
|
agentlink
|
|
49
52
|
```
|
|
50
53
|
|
|
51
54
|
## Commands
|
|
52
55
|
|
|
53
|
-
### `agentlink [name]
|
|
56
|
+
### `agentlink [name]`
|
|
54
57
|
|
|
55
58
|
Interactive wizard that scaffolds a new project or updates an existing one. Uses Supabase Cloud by default — region is auto-detected from your timezone, all recommended skills are installed automatically.
|
|
56
59
|
|
|
@@ -61,8 +64,8 @@ agentlink
|
|
|
61
64
|
# With project name
|
|
62
65
|
agentlink my-app
|
|
63
66
|
|
|
64
|
-
# With
|
|
65
|
-
agentlink my-app "Build a project management tool
|
|
67
|
+
# With prompt (passed to Claude Code on launch)
|
|
68
|
+
agentlink my-app --prompt "Build a project management tool"
|
|
66
69
|
|
|
67
70
|
# Local Docker mode (instead of cloud)
|
|
68
71
|
agentlink my-app --local
|
package/dist/index.js
CHANGED
|
@@ -186,20 +186,33 @@ function listEnvironments(cwd) {
|
|
|
186
186
|
var check_setup_default = "SELECT jsonb_build_object(\n 'extensions', jsonb_build_object(\n 'pg_net', EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_net'),\n 'pg_cron', EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_cron'),\n 'vault', EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'supabase_vault'),\n 'pgmq', EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pgmq')\n ),\n 'queues', jsonb_build_object(\n 'agentlink_tasks', EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'pgmq' AND table_name = 'q_agentlink_tasks'\n )\n ),\n 'tables', jsonb_build_object(\n 'profiles', EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'profiles'\n ),\n 'tenants', EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'tenants'\n ),\n 'memberships', EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'memberships'\n ),\n 'invitations', EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'invitations'\n )\n ),\n 'functions', jsonb_build_object(\n '_internal_admin_get_secret',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_internal_admin_get_secret'\n ),\n '_internal_admin_call_edge_function',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_internal_admin_call_edge_function'\n ),\n 'api._admin_enqueue_task',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = '_admin_enqueue_task'\n ),\n 'api._admin_queue_read',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = '_admin_queue_read'\n ),\n 'api._admin_queue_delete',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = '_admin_queue_delete'\n ),\n 'api._admin_queue_archive',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = '_admin_queue_archive'\n ),\n 'set_updated_at',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = 'set_updated_at'\n ),\n '_internal_admin_handle_new_user',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_internal_admin_handle_new_user'\n ),\n 'api.profile_get',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'profile_get'\n ),\n 'api.profile_update',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'profile_update'\n ),\n '_hook_before_user_created',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_hook_before_user_created'\n ),\n '_hook_send_email',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_hook_send_email'\n ),\n '_auth_tenant_id',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_auth_tenant_id'\n ),\n '_auth_tenant_role',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_auth_tenant_role'\n ),\n '_auth_has_role',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_auth_has_role'\n ),\n '_auth_is_tenant_member',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public'\n AND routine_name = '_auth_is_tenant_member'\n ),\n 'api.tenant_select',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'tenant_select'\n ),\n 'api.tenant_list',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'tenant_list'\n ),\n 'api.tenant_create',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'tenant_create'\n ),\n 'api.invitation_create',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'invitation_create'\n ),\n 'api.invitation_accept',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'invitation_accept'\n ),\n 'api.membership_list',\n EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api'\n AND routine_name = 'membership_list'\n )\n ),\n 'triggers', jsonb_build_object(\n 'trg_profiles_updated_at',\n EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_profiles_updated_at'\n ),\n 'trg_auth_users_new_user',\n EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_auth_users_new_user'\n ),\n 'trg_tenants_updated_at',\n EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_tenants_updated_at'\n )\n ),\n 'secrets', jsonb_build_object(\n 'SUPABASE_URL',\n EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SUPABASE_URL'),\n 'SB_PUBLISHABLE_KEY',\n EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SB_PUBLISHABLE_KEY'),\n 'SB_SECRET_KEY',\n EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SB_SECRET_KEY')\n ),\n 'api_schema', EXISTS (\n SELECT 1 FROM information_schema.schemata WHERE schema_name = 'api'\n ),\n 'ready', (\n EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_net')\n AND EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_cron')\n AND EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'supabase_vault')\n AND EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pgmq')\n AND EXISTS (SELECT 1 FROM information_schema.schemata WHERE schema_name = 'api')\n AND EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'pgmq' AND table_name = 'q_agentlink_tasks'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_internal_admin_get_secret'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_internal_admin_call_edge_function'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = '_admin_enqueue_task'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = '_admin_queue_read'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = '_admin_queue_delete'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = '_admin_queue_archive'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'profiles'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'tenants'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'memberships'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = 'public' AND table_name = 'invitations'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = 'set_updated_at'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_internal_admin_handle_new_user'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'profile_get'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'profile_update'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_hook_before_user_created'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_hook_send_email'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_auth_tenant_id'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_auth_tenant_role'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_auth_has_role'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'public' AND routine_name = '_auth_is_tenant_member'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'tenant_select'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'tenant_list'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'tenant_create'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'invitation_create'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'invitation_accept'\n )\n AND EXISTS (\n SELECT 1 FROM information_schema.routines\n WHERE routine_schema = 'api' AND routine_name = 'membership_list'\n )\n AND EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_profiles_updated_at'\n )\n AND EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_auth_users_new_user'\n )\n AND EXISTS (\n SELECT 1 FROM pg_trigger WHERE tgname = 'trg_tenants_updated_at'\n )\n AND EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SUPABASE_URL')\n AND EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SB_PUBLISHABLE_KEY')\n AND EXISTS (SELECT 1 FROM vault.secrets WHERE name = 'SB_SECRET_KEY')\n )\n) AS setup_status;\n";
|
|
187
187
|
|
|
188
188
|
// src/sql.ts
|
|
189
|
+
function upsertSecret(value, name) {
|
|
190
|
+
const safeValue = value.replace(/'/g, "''");
|
|
191
|
+
return `DO $$ DECLARE
|
|
192
|
+
_id uuid;
|
|
193
|
+
BEGIN
|
|
194
|
+
SELECT id INTO _id FROM vault.secrets WHERE name = '${name}';
|
|
195
|
+
IF _id IS NOT NULL THEN
|
|
196
|
+
PERFORM vault.update_secret(_id, '${safeValue}', '${name}');
|
|
197
|
+
ELSE
|
|
198
|
+
PERFORM vault.create_secret('${safeValue}', '${name}');
|
|
199
|
+
END IF;
|
|
200
|
+
END $$;`;
|
|
201
|
+
}
|
|
189
202
|
function seedSQL(publishableKey, secretKey) {
|
|
190
203
|
return [
|
|
191
|
-
"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
"
|
|
204
|
+
upsertSecret("http://host.docker.internal:54321", "SUPABASE_URL"),
|
|
205
|
+
upsertSecret(publishableKey, "SB_PUBLISHABLE_KEY"),
|
|
206
|
+
upsertSecret(secretKey, "SB_SECRET_KEY"),
|
|
207
|
+
upsertSecret("", "ALLOWED_SIGNUP_DOMAINS")
|
|
195
208
|
].join("\n");
|
|
196
209
|
}
|
|
197
210
|
function cloudSeedSQL(apiUrl, publishableKey, secretKey) {
|
|
198
211
|
return [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
"
|
|
212
|
+
upsertSecret(apiUrl, "SUPABASE_URL"),
|
|
213
|
+
upsertSecret(publishableKey, "SB_PUBLISHABLE_KEY"),
|
|
214
|
+
upsertSecret(secretKey, "SB_SECRET_KEY"),
|
|
215
|
+
upsertSecret("", "ALLOWED_SIGNUP_DOMAINS")
|
|
203
216
|
].join("\n");
|
|
204
217
|
}
|
|
205
218
|
|
|
@@ -3521,7 +3534,7 @@ var CLAUDE_SETTINGS = {
|
|
|
3521
3534
|
"Bash(supabase functions:*)",
|
|
3522
3535
|
"Bash(psql:*)",
|
|
3523
3536
|
"Bash(npx create-next-app@latest:*)",
|
|
3524
|
-
"Bash(npx
|
|
3537
|
+
"Bash(npx @agentlink.sh/cli@latest:*)",
|
|
3525
3538
|
"Bash(npm install:*)",
|
|
3526
3539
|
"Bash(npx next:*)",
|
|
3527
3540
|
"Bash(npx vite:*)",
|
|
@@ -3711,6 +3724,9 @@ async function scaffold(options) {
|
|
|
3711
3724
|
if (options.cloud) {
|
|
3712
3725
|
await trackedStep("start-supabase", "Creating Supabase cloud project", async (spinner) => {
|
|
3713
3726
|
if (isResume && ctx.projectRef) {
|
|
3727
|
+
if (ctx.apiUrl && ctx.publishableKey && ctx.secretKey) {
|
|
3728
|
+
return;
|
|
3729
|
+
}
|
|
3714
3730
|
spinner.text = "Creating Supabase cloud project \u2014 Waiting for project to be ready";
|
|
3715
3731
|
await waitForProjectReady(ctx.projectRef, spinner);
|
|
3716
3732
|
return;
|
|
@@ -3775,6 +3791,9 @@ async function scaffold(options) {
|
|
|
3775
3791
|
});
|
|
3776
3792
|
}
|
|
3777
3793
|
await trackedStep("read-config", "Reading Supabase configuration", async () => {
|
|
3794
|
+
if (ctx.apiUrl && ctx.publishableKey && ctx.secretKey && (ctx.dbUrl || options.cloud)) {
|
|
3795
|
+
return;
|
|
3796
|
+
}
|
|
3778
3797
|
if (options.cloud) {
|
|
3779
3798
|
const keys = await getApiKeys(ctx.projectRef);
|
|
3780
3799
|
ctx.apiUrl = `https://${ctx.projectRef}.supabase.co`;
|
|
@@ -4438,25 +4457,71 @@ function finishScaffold(summary, frontend, cloudConfig, prompt, launchClaude, sk
|
|
|
4438
4457
|
console.log(` ${dim("Switch env")} agentlink env use <name>`);
|
|
4439
4458
|
console.log(dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4440
4459
|
console.log();
|
|
4441
|
-
if (launchClaude === false || nonInteractive) {
|
|
4460
|
+
if (launchClaude === false || nonInteractive || !prompt) {
|
|
4442
4461
|
return;
|
|
4443
4462
|
}
|
|
4444
4463
|
console.log(blue(" Launching Claude Code..."));
|
|
4445
4464
|
console.log();
|
|
4446
|
-
|
|
4447
|
-
execSync(`claude ${launchArgs}`, {
|
|
4465
|
+
execSync(`claude ${JSON.stringify(prompt)}`, {
|
|
4448
4466
|
cwd: summary.projectDir,
|
|
4449
4467
|
stdio: "inherit"
|
|
4450
4468
|
});
|
|
4451
4469
|
}
|
|
4452
|
-
async function wizard(initialName,
|
|
4470
|
+
async function wizard(initialName, opts = {}) {
|
|
4453
4471
|
const { forceUpdate, frontend: initialFrontend, local: localMode, skills: installSkills, launch: launchClaude, yes: autoYes, nonInteractive } = opts;
|
|
4454
|
-
if (opts.prompt) {
|
|
4455
|
-
initialPrompt = opts.prompt;
|
|
4456
|
-
}
|
|
4457
4472
|
if (opts.token) {
|
|
4458
4473
|
process.env.SUPABASE_ACCESS_TOKEN = opts.token;
|
|
4459
4474
|
}
|
|
4475
|
+
if (opts.link) {
|
|
4476
|
+
const { projectRef, dbUrl, apiUrl, publishableKey, secretKey } = opts.link;
|
|
4477
|
+
if (!projectRef || !dbUrl || !apiUrl || !publishableKey || !secretKey) {
|
|
4478
|
+
throw new Error(
|
|
4479
|
+
"--link requires all connection flags:\n --project-ref, --db-url, --api-url, --publishable-key, --secret-key"
|
|
4480
|
+
);
|
|
4481
|
+
}
|
|
4482
|
+
const name2 = initialName === "." ? path15.basename(process.cwd()) : initialName ?? "my-app";
|
|
4483
|
+
const scaffoldHere2 = initialName === ".";
|
|
4484
|
+
const projectDir2 = scaffoldHere2 ? process.cwd() : path15.resolve(process.cwd(), name2);
|
|
4485
|
+
const frontend2 = initialFrontend ?? "vite";
|
|
4486
|
+
const skills2 = installSkills === false ? [] : getCompanionSkills(frontend2);
|
|
4487
|
+
const region = projectRef.length > 0 ? "us-east-1" : "us-east-1";
|
|
4488
|
+
if (!scaffoldHere2) {
|
|
4489
|
+
fs15.mkdirSync(projectDir2, { recursive: true });
|
|
4490
|
+
}
|
|
4491
|
+
const cloudConfig2 = { orgId: "", region, label: "dev" };
|
|
4492
|
+
printBanner();
|
|
4493
|
+
console.log(dim(` v${pkg2.version}`));
|
|
4494
|
+
console.log();
|
|
4495
|
+
console.log(` ${blue("\u25CF")} Linking to Supabase project ${dim(projectRef)}`);
|
|
4496
|
+
console.log();
|
|
4497
|
+
const scaffoldOpts2 = { name: name2, skills: skills2, mode: "new", frontend: frontend2, cloud: cloudConfig2, nonInteractive: true };
|
|
4498
|
+
saveProgress(projectDir2, {
|
|
4499
|
+
version: pkg2.version,
|
|
4500
|
+
options: scaffoldOpts2,
|
|
4501
|
+
ctx: {
|
|
4502
|
+
dbUrl,
|
|
4503
|
+
apiUrl,
|
|
4504
|
+
publishableKey,
|
|
4505
|
+
secretKey,
|
|
4506
|
+
projectRef
|
|
4507
|
+
},
|
|
4508
|
+
completedSteps: [],
|
|
4509
|
+
prompt: opts.prompt ?? "",
|
|
4510
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4511
|
+
});
|
|
4512
|
+
saveSession(projectDir2, name2);
|
|
4513
|
+
const summary2 = await scaffold({
|
|
4514
|
+
...scaffoldOpts2,
|
|
4515
|
+
resume: {
|
|
4516
|
+
completedSteps: [],
|
|
4517
|
+
ctx: { dbUrl, apiUrl, publishableKey, secretKey, projectRef },
|
|
4518
|
+
prompt: opts.prompt ?? "",
|
|
4519
|
+
projectDir: projectDir2
|
|
4520
|
+
}
|
|
4521
|
+
});
|
|
4522
|
+
finishScaffold(summary2, frontend2, cloudConfig2, opts.prompt ?? "", launchClaude, skills2, true);
|
|
4523
|
+
return;
|
|
4524
|
+
}
|
|
4460
4525
|
printBanner();
|
|
4461
4526
|
console.log(dim(` v${pkg2.version}`));
|
|
4462
4527
|
console.log();
|
|
@@ -4676,7 +4741,6 @@ Run without --resume to start fresh.`
|
|
|
4676
4741
|
});
|
|
4677
4742
|
}
|
|
4678
4743
|
} else if (initialName === ".") {
|
|
4679
|
-
mode = "existing";
|
|
4680
4744
|
name = path15.basename(process.cwd());
|
|
4681
4745
|
} else if (initialName) {
|
|
4682
4746
|
if (mode === "new") {
|
|
@@ -4704,7 +4768,7 @@ ${red("Error:")} ${error}`);
|
|
|
4704
4768
|
if (mode === "new") {
|
|
4705
4769
|
if (initialFrontend !== void 0) {
|
|
4706
4770
|
frontend = initialFrontend;
|
|
4707
|
-
} else if (nonInteractive || initialName &&
|
|
4771
|
+
} else if (nonInteractive || initialName && opts.prompt) {
|
|
4708
4772
|
frontend = "vite";
|
|
4709
4773
|
} else {
|
|
4710
4774
|
frontend = await select3({
|
|
@@ -4775,7 +4839,7 @@ ${red("Error:")} No organizations found. Create one at ${link("https://supabase.
|
|
|
4775
4839
|
if (mode === "existing") {
|
|
4776
4840
|
prompt = "Analyze the current project and plan a migration to the architecture proposed by AgentLink";
|
|
4777
4841
|
} else {
|
|
4778
|
-
prompt =
|
|
4842
|
+
prompt = opts.prompt ?? "";
|
|
4779
4843
|
}
|
|
4780
4844
|
if (!useCloud && mode === "existing" && !autoYes && !nonInteractive) {
|
|
4781
4845
|
const proceed = await confirm5({
|
|
@@ -4791,9 +4855,10 @@ ${amber("Aborted.")} Stop other Supabase instances manually before running again
|
|
|
4791
4855
|
process.exit(0);
|
|
4792
4856
|
}
|
|
4793
4857
|
}
|
|
4794
|
-
const
|
|
4858
|
+
const scaffoldHere = mode === "existing" || initialName === ".";
|
|
4859
|
+
const projectDir = scaffoldHere ? process.cwd() : path15.resolve(process.cwd(), name);
|
|
4795
4860
|
const scaffoldOpts = { name, skills, mode, frontend, cloud: cloudConfig, nonInteractive };
|
|
4796
|
-
if (
|
|
4861
|
+
if (!scaffoldHere) {
|
|
4797
4862
|
fs15.mkdirSync(projectDir, { recursive: true });
|
|
4798
4863
|
}
|
|
4799
4864
|
saveProgress(projectDir, {
|
|
@@ -4819,7 +4884,7 @@ function enableDebug(cmd) {
|
|
|
4819
4884
|
if (debug) initLog(true);
|
|
4820
4885
|
}
|
|
4821
4886
|
program.hook("preAction", (thisCommand) => enableDebug(thisCommand));
|
|
4822
|
-
program.name("agentlink").description("CLI for scaffolding Supabase apps with AI agents").version(pkg3.version).argument("[name]", "Project name
|
|
4887
|
+
program.name("agentlink").description("CLI for scaffolding Supabase apps with AI agents").version(pkg3.version).argument("[name]", "Project name (use . to scaffold in current directory)").option("--debug", "Write debug log to agentlink-debug.log").option("--force-update", "Force update even if project is up to date").option("--no-frontend", "Skip frontend scaffolding").option("--nextjs", "Use NextJS instead of React + Vite for frontend").option("--local", "Use local Docker instead of Supabase Cloud").option("--no-skills", "Skip companion skill installation").option("--no-launch", "Skip launching Claude Code after scaffold").option("-y, --yes", "Auto-confirm all prompts").option("--token <token>", "Supabase access token (skips interactive login)").option("--org <id>", "Supabase organization ID").option("--region <region>", "Supabase Cloud region (e.g. us-east-1)").option("--prompt <prompt>", "What to build (passed to Claude Code on launch)").option("--resume", "Resume a previously failed scaffold").option("--non-interactive", "Error instead of prompting when info is missing").option("--link", "Link to an existing Supabase project (requires --project-ref and connection flags)").option("--project-ref <ref>", "Supabase project ref (used with --link)").option("--db-url <url>", "Database URL (used with --link)").option("--api-url <url>", "Supabase API URL (used with --link)").option("--publishable-key <key>", "Supabase publishable key (used with --link)").option("--secret-key <key>", "Supabase secret key (used with --link)").action(async (name) => {
|
|
4823
4888
|
const opts = program.opts();
|
|
4824
4889
|
const debug = opts.debug ?? false;
|
|
4825
4890
|
initLog(debug);
|
|
@@ -4832,7 +4897,7 @@ program.name("agentlink").description("CLI for scaffolding Supabase apps with AI
|
|
|
4832
4897
|
} else if (opts.frontend !== void 0) {
|
|
4833
4898
|
frontend = "vite";
|
|
4834
4899
|
}
|
|
4835
|
-
await wizard(name,
|
|
4900
|
+
await wizard(name, {
|
|
4836
4901
|
forceUpdate: opts.forceUpdate,
|
|
4837
4902
|
frontend,
|
|
4838
4903
|
local: opts.local,
|
|
@@ -4844,7 +4909,14 @@ program.name("agentlink").description("CLI for scaffolding Supabase apps with AI
|
|
|
4844
4909
|
region: opts.region,
|
|
4845
4910
|
prompt: opts.prompt,
|
|
4846
4911
|
resume: opts.resume,
|
|
4847
|
-
nonInteractive: opts.nonInteractive
|
|
4912
|
+
nonInteractive: opts.nonInteractive,
|
|
4913
|
+
link: opts.link ? {
|
|
4914
|
+
projectRef: opts.projectRef,
|
|
4915
|
+
dbUrl: opts.dbUrl,
|
|
4916
|
+
apiUrl: opts.apiUrl,
|
|
4917
|
+
publishableKey: opts.publishableKey,
|
|
4918
|
+
secretKey: opts.secretKey
|
|
4919
|
+
} : void 0
|
|
4848
4920
|
});
|
|
4849
4921
|
} catch (err) {
|
|
4850
4922
|
const msg = `
|