@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.
Files changed (3) hide show
  1. package/README.md +9 -6
  2. package/dist/index.js +96 -24
  3. 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, zero questions with name + prompt)
45
- agentlink my-app "Build a project management tool with kanban boards"
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 (asks project name and frontend choice)
50
+ # Interactive wizard
48
51
  agentlink
49
52
  ```
50
53
 
51
54
  ## Commands
52
55
 
53
- ### `agentlink [name] [prompt]`
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 name and prompt (zero questions express mode)
65
- agentlink my-app "Build a project management tool with kanban boards"
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
- "select vault.create_secret('http://host.docker.internal:54321', 'SUPABASE_URL');",
192
- `select vault.create_secret('${publishableKey}', 'SB_PUBLISHABLE_KEY');`,
193
- `select vault.create_secret('${secretKey}', 'SB_SECRET_KEY');`,
194
- "select vault.create_secret('', 'ALLOWED_SIGNUP_DOMAINS');"
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
- `select vault.create_secret('${apiUrl}', 'SUPABASE_URL');`,
200
- `select vault.create_secret('${publishableKey}', 'SB_PUBLISHABLE_KEY');`,
201
- `select vault.create_secret('${secretKey}', 'SB_SECRET_KEY');`,
202
- "select vault.create_secret('', 'ALLOWED_SIGNUP_DOMAINS');"
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 agentlinksh/cli?@latest:*)",
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
- const launchArgs = prompt ? `${JSON.stringify(prompt)}` : "";
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, initialPrompt, opts = {}) {
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 && initialPrompt) {
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 = initialPrompt ?? "";
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 projectDir = mode === "existing" ? process.cwd() : path15.resolve(process.cwd(), name);
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 (mode === "new") {
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").argument("[prompt]", "What do you want to build?").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 (alternative to positional arg)").option("--resume", "Resume a previously failed scaffold").option("--non-interactive", "Error instead of prompting when info is missing").action(async (name, prompt) => {
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, prompt, {
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 = `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlink.sh/cli",
3
- "version": "0.10.2",
3
+ "version": "0.11.1",
4
4
  "description": "CLI for scaffolding Supabase apps with AI agents",
5
5
  "bin": {
6
6
  "agentlink": "dist/index.js"