@usecontextlayer/cli 0.15.0 → 0.16.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/dist/auth.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { i as listOrganizations, n as getAccessToken, r as getCurrentUser, t as LoginRequiredError } from "./auth-CMrKVwsH.mjs";
1
+ import { i as listOrganizations, n as getAccessToken, r as getCurrentUser, t as LoginRequiredError } from "./auth-DOsE8GwJ.mjs";
2
2
  export { LoginRequiredError, getAccessToken, getCurrentUser, listOrganizations };
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as __commonJSMin } from "./rolldown-runtime-EAsCxrDo.mjs";
3
- import { S as uuid, a as login, b as unknown, c as array, d as hostname, f as literal, g as record, h as object, i as listOrganizations, l as boolean, n as getAccessToken, p as looseObject, r as getCurrentUser, t as LoginRequiredError, v as string, x as url, y as union } from "./auth-CMrKVwsH.mjs";
4
- import { c as resourcesForConsumer, f as execa, i as ownerSchema, l as secretNameSchema, n as saveLocalConnection, o as joinApp, r as appResourceConfigurationSchema, s as env, t as prepareLocalResourceConfiguration, u as databaseQuerySchema } from "./resources-5FTDu19i.mjs";
3
+ import { S as uuid, a as login, b as unknown, c as array, d as hostname, f as literal, g as record, h as object, i as listOrganizations, l as boolean, n as getAccessToken, p as looseObject, r as getCurrentUser, t as LoginRequiredError, v as string, x as url, y as union } from "./auth-DOsE8GwJ.mjs";
4
+ import { a as env, c as resourcesForConsumer, f as execa, i as joinSlate, l as secretNameSchema, n as saveLocalConnection, o as slateResourceConfigurationSchema, s as ownerSchema, t as prepareLocalResourceConfiguration, u as databaseQuerySchema } from "./resources-B-EYHG1j.mjs";
5
5
  import { cp, readFile, writeFile } from "node:fs/promises";
6
6
  import path, { join } from "node:path";
7
7
  import { EventEmitter } from "node:events";
@@ -2967,7 +2967,7 @@ function useColor() {
2967
2967
  new Command();
2968
2968
  //#endregion
2969
2969
  //#region agents.ts
2970
- const platformInstructions = "You are a ContextLayer app agent. The user message is the task for this run. Work in the app directory and return the task's result. Use database_query to read and save persistent data in declared databases. Files are scratch data; schema changes belong in explicitly authored SQL migrations.";
2970
+ const platformInstructions = "You are an agent of a ContextLayer slate.The user message is the task for this run. Work in the checkout and return the task's result. Use database_query to read and save persistent data in declared databases. Files are scratch data; schema changes belong in explicitly authored SQL migrations.";
2971
2971
  async function runLocalAgent(name, prompt) {
2972
2972
  const instructions = await readFile(join("agents", name, "instructions.md"), "utf8");
2973
2973
  const { createServer } = await import("vite");
@@ -3880,10 +3880,6 @@ ${f}
3880
3880
  };
3881
3881
  `${styleText("gray", S_BAR)}`;
3882
3882
  //#endregion
3883
- //#region ../shared/dist/app-connections.mjs
3884
- const appConnectionSchema = appResourceConfigurationSchema.shape.connections.valueType.extend({ slug: string() });
3885
- const appConnectionsSchema = object({ connections: array(appConnectionSchema) });
3886
- //#endregion
3887
3883
  //#region ../shared/dist/connections.mjs
3888
3884
  const connectionSchema = object({
3889
3885
  alias: string().nullable(),
@@ -3894,12 +3890,16 @@ const connectionSchema = object({
3894
3890
  });
3895
3891
  const connectionsSchema = object({ connections: array(connectionSchema) });
3896
3892
  //#endregion
3893
+ //#region ../shared/dist/slate-connections.mjs
3894
+ const slateConnectionSchema = slateResourceConfigurationSchema.shape.connections.valueType.extend({ slug: string() });
3895
+ const slateConnectionsSchema = object({ connections: array(slateConnectionSchema) });
3896
+ //#endregion
3897
3897
  //#region owner.ts
3898
3898
  const ownerOptionsSchema = object({ org: string().min(1).optional() });
3899
3899
  async function resolveOwner(org, headers) {
3900
3900
  if (!org) return {
3901
3901
  id: (await getCurrentUser(env, headers)).id,
3902
- type: "user"
3902
+ type: "personal"
3903
3903
  };
3904
3904
  const organization = (await listOrganizations(env, headers)).find((organization) => organization.slug === org);
3905
3905
  if (!organization) throw new Error("Organization is not in your memberships");
@@ -3909,7 +3909,7 @@ async function resolveOwner(org, headers) {
3909
3909
  };
3910
3910
  }
3911
3911
  function ownerPath(owner) {
3912
- return `${owner.type === "organization" ? "org" : "user"}/${encodeURIComponent(owner.id)}`;
3912
+ return `${owner.type === "organization" ? "org" : "personal"}/${encodeURIComponent(owner.id)}`;
3913
3913
  }
3914
3914
  //#endregion
3915
3915
  //#region connections.ts
@@ -3924,7 +3924,7 @@ const connectionAssignmentSchema = object({
3924
3924
  path: ["connection_id"]
3925
3925
  });
3926
3926
  });
3927
- async function assignAppConnection(target, slug, connectionId) {
3927
+ async function assignSlateConnection(target, slug, connectionId) {
3928
3928
  if (target === "local") {
3929
3929
  const configuration = await prepareLocalResourceConfiguration();
3930
3930
  const requirement = new Map(Object.entries(configuration.connections)).get(slug);
@@ -3933,31 +3933,31 @@ async function assignAppConnection(target, slug, connectionId) {
3933
3933
  const url = new URL("/api/connections", env.CTX_PLATFORM_URL);
3934
3934
  url.searchParams.set("toolkit", requirement.toolkit);
3935
3935
  const response = await fetch(url, { headers: { authorization: `Bearer ${await getAccessToken(env)}` } });
3936
- if (!response.ok) throw new Error(`Personal connection list failed: HTTP ${response.status}`);
3936
+ if (!response.ok) throw new Error(`Personal connected account list failed: HTTP ${response.status}`);
3937
3937
  const { connections } = connectionsSchema.parse(await response.json());
3938
- if (connections.length === 0) throw new Error(`No personal ${requirement.toolkit} accounts. Run npx @usecontextlayer/cli connections add ${requirement.toolkit}, approve access in your browser, then rerun this assignment.`);
3938
+ if (connections.length === 0) throw new Error(`No personal connected accounts for ${requirement.toolkit}. Run npx @usecontextlayer/cli connections add ${requirement.toolkit} to connect an account in your browser, then rerun this assignment.`);
3939
3939
  if (connectionId === void 0) {
3940
- const selected = await select({
3941
- message: `Your ${requirement.toolkit} account for ${slug}`,
3940
+ const accountId = await select({
3941
+ message: `Assign a connected ${requirement.toolkit} account to ${slug}`,
3942
3942
  options: connections.map((connection) => ({
3943
3943
  label: `${connection.display_name ?? connection.alias ?? connection.id} (${connection.id}; ${connection.status})`,
3944
3944
  value: connection.id
3945
3945
  })),
3946
3946
  output: process.stderr
3947
3947
  });
3948
- if (isCancel(selected)) {
3948
+ if (isCancel(accountId)) {
3949
3949
  process.exitCode = 130;
3950
3950
  return;
3951
3951
  }
3952
- connectionId = selected;
3952
+ connectionId = accountId;
3953
3953
  }
3954
- if (!connections.some(({ id }) => id === connectionId)) throw new Error(`Account ${connectionId} is not one of your ${requirement.toolkit} accounts`);
3954
+ if (!connections.some(({ id }) => id === connectionId)) throw new Error(`Connected account ${connectionId} is not one of your connected ${requirement.toolkit} accounts`);
3955
3955
  await saveLocalConnection(slug, connectionId);
3956
3956
  console.log(`${slug} → ${connectionId}`);
3957
3957
  console.log("Start or restart pnpm dev to use this assignment.");
3958
3958
  return;
3959
3959
  }
3960
- const response = await fetch(new URL(`/api/apps/${encodeURIComponent(target)}/connections/assign`, env.CTX_PLATFORM_URL), {
3960
+ const response = await fetch(new URL(`/api/slates/${encodeURIComponent(target)}/connections/assign`, env.CTX_PLATFORM_URL), {
3961
3961
  body: JSON.stringify({
3962
3962
  connection_id: connectionId,
3963
3963
  slug
@@ -3975,7 +3975,7 @@ async function assignAppConnection(target, slug, connectionId) {
3975
3975
  }).parse(await response.json());
3976
3976
  console.log(`${assignment.slug} → ${assignment.connection_id}`);
3977
3977
  }
3978
- async function listAppConnections(target) {
3978
+ async function listSlateConnections(target) {
3979
3979
  if (target === "local") {
3980
3980
  const { connections } = await prepareLocalResourceConfiguration();
3981
3981
  if (Object.keys(connections).length === 0) {
@@ -3983,7 +3983,7 @@ async function listAppConnections(target) {
3983
3983
  return;
3984
3984
  }
3985
3985
  console.table(Object.entries(connections).map(([slug, { connection_id, consumers, mode, toolkit }]) => ({
3986
- connection: connection_id ?? "unassigned",
3986
+ connected_account: connection_id ?? "unassigned",
3987
3987
  consumers: consumers.map((consumer) => consumer.type === "app" ? "app" : `agent:${consumer.name}`).join(", "),
3988
3988
  mode,
3989
3989
  slug,
@@ -3991,7 +3991,7 @@ async function listAppConnections(target) {
3991
3991
  })));
3992
3992
  return;
3993
3993
  }
3994
- const response = await fetch(new URL(`/api/apps/${encodeURIComponent(target)}/connections/list`, env.CTX_PLATFORM_URL), {
3994
+ const response = await fetch(new URL(`/api/slates/${encodeURIComponent(target)}/connections/list`, env.CTX_PLATFORM_URL), {
3995
3995
  body: JSON.stringify({}),
3996
3996
  headers: {
3997
3997
  authorization: `Bearer ${await getAccessToken(env)}`,
@@ -3999,18 +3999,18 @@ async function listAppConnections(target) {
3999
3999
  },
4000
4000
  method: "POST"
4001
4001
  });
4002
- if (!response.ok) throw new Error(`App connections request failed: HTTP ${response.status}`);
4003
- const { connections } = appConnectionsSchema.parse(await response.json());
4002
+ if (!response.ok) throw new Error(`Slate connections request failed: HTTP ${response.status}`);
4003
+ const { connections } = slateConnectionsSchema.parse(await response.json());
4004
4004
  if (!connections.length) {
4005
4005
  console.log("No connection requirements.");
4006
4006
  return;
4007
4007
  }
4008
4008
  console.table(connections.map(({ connection_id, ...requirement }) => ({
4009
4009
  ...requirement,
4010
- connection: connection_id ?? "unassigned"
4010
+ connected_account: connection_id ?? "unassigned"
4011
4011
  })));
4012
4012
  }
4013
- async function addConnection(toolkit, org) {
4013
+ async function connectAccount(toolkit, org) {
4014
4014
  const headers = { authorization: `Bearer ${await getAccessToken(env)}` };
4015
4015
  const owner = await resolveOwner(org, headers);
4016
4016
  const response = await fetch(new URL(`/api/connections/${ownerPath(owner)}`, env.CTX_PLATFORM_URL), {
@@ -4021,18 +4021,18 @@ async function addConnection(toolkit, org) {
4021
4021
  },
4022
4022
  method: "POST"
4023
4023
  });
4024
- if (!response.ok) throw new Error(`Connection authorization failed: HTTP ${response.status}`);
4024
+ if (!response.ok) throw new Error(`Connecting account failed: HTTP ${response.status}`);
4025
4025
  const { redirect_url } = object({ redirect_url: url() }).parse(await response.json());
4026
- console.log(`Open this link to authorize the Owner's account:\n${redirect_url}`);
4027
- console.log("After approving access in your browser, assign the account to an app's declared connection slug.");
4028
- if (!org) console.log("From your app directory, choose your account for a slug in public/slate.json:\n npx @usecontextlayer/cli connection local assign <slug>");
4029
- console.log(`For a hosted app, get the account ID and assign it:\n npx @usecontextlayer/cli connections${org ? ` --org '${org.replaceAll("'", "'\\''")}'` : ""} list\n npx @usecontextlayer/cli connection <AppID-or-hostname> assign <slug> <connection_id>`);
4026
+ console.log(`Open this link to connect the Owner's account:\n${redirect_url}`);
4027
+ console.log("After connecting in your browser, assign the connected account to a slate's declared connection.");
4028
+ if (!org) console.log("From your checkout, assign your connected account to a connection declared in slate.json:\n npx @usecontextlayer/cli connection local assign <slug>");
4029
+ console.log(`For a hosted slate, get the connected account ID and assign it:\n npx @usecontextlayer/cli connections${org ? ` --org '${org.replaceAll("'", "'\\''")}'` : ""} list\n npx @usecontextlayer/cli connection <SlateID-or-hostname> assign <slug> <connection_id>`);
4030
4030
  }
4031
4031
  async function listConnections(org) {
4032
4032
  const headers = { authorization: `Bearer ${await getAccessToken(env)}` };
4033
4033
  const owner = await resolveOwner(org, headers);
4034
4034
  const response = await fetch(new URL(`/api/connections/${ownerPath(owner)}`, env.CTX_PLATFORM_URL), { headers });
4035
- if (!response.ok) throw new Error(`Connection list failed: HTTP ${response.status}`);
4035
+ if (!response.ok) throw new Error(`Connected account list failed: HTTP ${response.status}`);
4036
4036
  const { connections } = connectionsSchema.parse(await response.json());
4037
4037
  if (connections.length === 0) {
4038
4038
  console.log("No connected accounts.");
@@ -4042,7 +4042,7 @@ async function listConnections(org) {
4042
4042
  }
4043
4043
  //#endregion
4044
4044
  //#region git-credential.ts
4045
- async function setupGit(cli) {
4045
+ async function configureGit(cli) {
4046
4046
  const key = `credential.${new URL("/git", env.CTX_PLATFORM_URL).href}.helper`;
4047
4047
  const command = [
4048
4048
  process.execPath,
@@ -4082,7 +4082,7 @@ async function gitCredential(operation) {
4082
4082
  }
4083
4083
  //#endregion
4084
4084
  //#region package.json
4085
- var version = "0.15.0";
4085
+ var version = "0.16.1";
4086
4086
  //#endregion
4087
4087
  //#region secrets.ts
4088
4088
  const secretOptionsSchema = ownerOptionsSchema.extend({ stdin: boolean().default(false) });
@@ -4151,7 +4151,7 @@ async function authenticate(command) {
4151
4151
  async function requireLogin(command) {
4152
4152
  await authenticate(command);
4153
4153
  }
4154
- program.command("init <directory>").description("Create a private ContextLayer app on main with React Router, Tailwind, and shadcn; requires login, Node.js 24+, pnpm, and Git author identity; sets the Git remote and prints how to start and publish the app").option("--org <slug>", "Create the app under an organization you belong to").hook("preAction", requireLogin).action(async (directory, options) => {
4154
+ program.command("init <directory>").description("Create a private ContextLayer slate on main with React Router, Tailwind, and shadcn; requires login, Node.js 24+, pnpm, and Git author identity; sets the Git remote and prints how to start and deploy the slate").option("--org <slug>", "Create the slate under an organization you belong to").hook("preAction", requireLogin).action(async (directory, options) => {
4155
4155
  const input = object({ organization_slug: string().min(1).optional() }).parse({ organization_slug: options.org });
4156
4156
  const accessToken = await getAccessToken(env);
4157
4157
  const gitIdentity = await execa("git", ["var", "GIT_AUTHOR_IDENT"], {
@@ -4256,10 +4256,10 @@ program.command("init <directory>").description("Create a private ContextLayer a
4256
4256
  process.exitCode = migrationTool.exitCode;
4257
4257
  if (migrationTool.exitCode !== 0) return;
4258
4258
  const packagePath = join(directory, "package.json");
4259
- const projectPackage = looseObject({ scripts: record(string(), string()) }).parse(JSON.parse(await readFile(packagePath, "utf8")));
4260
- projectPackage.scripts["db:migration"] = "drizzle-kit generate --custom";
4261
- await writeFile(packagePath, `${JSON.stringify(projectPackage, null, 2)}\n`);
4262
- const response = await fetch(new URL("/api/apps", env.CTX_PLATFORM_URL), {
4259
+ const checkoutPackage = looseObject({ scripts: record(string(), string()) }).parse(JSON.parse(await readFile(packagePath, "utf8")));
4260
+ checkoutPackage.scripts["db:migration"] = "drizzle-kit generate --custom";
4261
+ await writeFile(packagePath, `${JSON.stringify(checkoutPackage, null, 2)}\n`);
4262
+ const response = await fetch(new URL("/api/slates", env.CTX_PLATFORM_URL), {
4263
4263
  body: JSON.stringify(input),
4264
4264
  headers: {
4265
4265
  authorization: `Bearer ${accessToken}`,
@@ -4267,12 +4267,12 @@ program.command("init <directory>").description("Create a private ContextLayer a
4267
4267
  },
4268
4268
  method: "POST"
4269
4269
  });
4270
- if (!response.ok) throw new Error(`App creation failed: HTTP ${response.status}`);
4271
- const app = object({
4270
+ if (!response.ok) throw new Error(`Slate creation failed: HTTP ${response.status}`);
4271
+ const slate = object({
4272
4272
  id: uuid(),
4273
4273
  public_hostname: hostname()
4274
4274
  }).parse(await response.json());
4275
- const remote = new URL(`/git/${app.id}`, env.CTX_PLATFORM_URL);
4275
+ const remote = new URL(`/git/${slate.id}`, env.CTX_PLATFORM_URL);
4276
4276
  const git = await execa("git", [
4277
4277
  "remote",
4278
4278
  "add",
@@ -4286,16 +4286,16 @@ program.command("init <directory>").description("Create a private ContextLayer a
4286
4286
  process.exitCode = git.exitCode;
4287
4287
  if (git.exitCode !== 0) return;
4288
4288
  console.log(`
4289
- ContextLayer app created: ${app.id}
4290
- Dashboard: ${new URL(`/dashboard/apps/${app.id}`, env.CTX_PLATFORM_URL).href}
4291
- Hosted URL: https://${app.public_hostname}/ (available after deployment)
4289
+ ContextLayer slate created: ${slate.id}
4290
+ Dashboard: ${new URL(`/dashboard/slates/${slate.id}`, env.CTX_PLATFORM_URL).href}
4291
+ Hosted URL: https://${slate.public_hostname}/ (available after deployment)
4292
4292
 
4293
4293
  Start locally:
4294
4294
  cd '${directory.replaceAll("'", "'\\''")}'
4295
4295
  pnpm dev
4296
4296
  Open the local URL printed by the development server.
4297
4297
 
4298
- Publish your changes:
4298
+ Deploy your changes:
4299
4299
  git add .
4300
4300
  git commit
4301
4301
  git push -u origin main
@@ -4305,7 +4305,7 @@ See README.md for the development and connection workflow.
4305
4305
  });
4306
4306
  program.command("login").description("Sign in by approving a browser code and configure Git credentials for ContextLayer repositories").action(async () => {
4307
4307
  await login(env);
4308
- await setupGit(new URL(import.meta.url));
4308
+ await configureGit(new URL(import.meta.url));
4309
4309
  console.log("Git credentials configured for ContextLayer.");
4310
4310
  });
4311
4311
  program.command("git-credential <operation>").description("Git credential helper using the saved login; invoked automatically by Git").hook("preAction", async (command) => {
@@ -4314,35 +4314,35 @@ program.command("git-credential <operation>").description("Git credential helper
4314
4314
  program.command("whoami").description("Show your ContextLayer user ID verified by the auth server").action(async (_options, command) => {
4315
4315
  console.log((await authenticate(command)).id);
4316
4316
  });
4317
- program.command("join").argument("<target>", "AppID, public hostname, or local (run from the app root)").description("Join a private app you can view using ctx login, enabling member-scoped unattended work; returns app and user IDs").hook("preAction", requireLogin).action(async (target) => {
4318
- await joinApp(union([
4317
+ program.command("join").argument("<target>", "SlateID, public hostname, or local (run from the checkout root)").description("Join a private slate you can view using ctx login, enabling member-scoped unattended work; returns slate and user IDs").hook("preAction", requireLogin).action(async (target) => {
4318
+ await joinSlate(union([
4319
4319
  literal("local"),
4320
4320
  uuid(),
4321
4321
  hostname()
4322
4322
  ]).parse(target));
4323
4323
  });
4324
- const connections = program.command("connections").description("Manage Owner-owned connected accounts or list app and agent connection requirements; local reads only the current folder and its saved development choices").option("--org <org_slug>", "Manage this organization's connections; defaults to the signed-in user").argument("[target]", "AppID or public hostname (pushed requirements), or local (current folder; no platform request)").addArgument(new Argument("[operation]", "App connection operation").choices(["list"])).hook("preAction", async (command, actionCommand) => {
4324
+ const connections = program.command("connections").description("Manage Owner-owned connected accounts or list app and agent connections and assignments; local reads only the current checkout and its saved development assignments").option("--org <slug>", "Manage this organization's connected accounts; defaults to the signed-in user").argument("[target]", "SlateID or public hostname (pushed requirements), or local (current checkout; no platform request)").addArgument(new Argument("[operation]", "Slate connection operation").choices(["list"])).hook("preAction", async (command, actionCommand) => {
4325
4325
  if (actionCommand !== command || command.args[0] !== "local") await requireLogin(actionCommand);
4326
4326
  }).action(async (target, operation) => {
4327
4327
  if (!target || !operation) connections.error("Expected: ctx connections <target> list");
4328
- await listAppConnections(target);
4328
+ await listSlateConnections(target);
4329
4329
  });
4330
- connections.command("list").description("List the selected Owner's Composio accounts with their toolkit, identity, and status").action(async (_options, command) => {
4330
+ connections.command("list").description("List the selected Owner's connected accounts with their toolkit, identity, and status").action(async (_options, command) => {
4331
4331
  await listConnections(ownerOptionsSchema.parse(command.optsWithGlobals()).org);
4332
4332
  });
4333
- connections.command("add <toolkit>").description("Authorize the selected Owner's account in your browser (for example, gmail), then assign it to an app's declared connection slug with ctx connection").action(async (toolkit, _options, command) => {
4333
+ connections.command("add <toolkit>").description("Connect the selected Owner's account in your browser (for example, gmail), then assign the connected account to a slate's declared connection with ctx connection").action(async (toolkit, _options, command) => {
4334
4334
  const options = ownerOptionsSchema.parse(command.optsWithGlobals());
4335
- await addConnection(string().min(1).parse(toolkit), options.org);
4335
+ await connectAccount(string().min(1).parse(toolkit), options.org);
4336
4336
  });
4337
- program.command("connection").description("Bind a declared slug: local saves your personal account in .contextlayer/connections.json; AppID/hostname saves a hosted assignment under its declared Owner").argument("<target>", "AppID, public hostname, or local (run from the app root)").addArgument(new Argument("<operation>").choices(["assign"])).argument("<slug>", "Connection slug declared in your Slate (for example, work-email)").argument("[connection_id]", "Connected account ID; omit locally to choose your accounts for the declared toolkit; required for hosted targets").hook("preAction", requireLogin).action(async (target, _operation, slug, connectionId) => {
4337
+ program.command("connection").description("Assign a connected account to a declared connection: local saves a personal connected account assignment in .contextlayer/connections.json; SlateID/hostname saves a hosted assignment under its declared Owner").argument("<target>", "SlateID, public hostname, or local (run from the checkout root)").addArgument(new Argument("<operation>").choices(["assign"])).argument("<slug>", "Connection slug declared in slate.json (for example, work-email)").argument("[connection_id]", "Connected account ID; omit locally to assign a connected account for the declared toolkit interactively; required for hosted targets").hook("preAction", requireLogin).action(async (target, _operation, slug, connectionId) => {
4338
4338
  const input = connectionAssignmentSchema.parse({
4339
4339
  connection_id: connectionId,
4340
4340
  slug,
4341
4341
  target
4342
4342
  });
4343
- await assignAppConnection(input.target, input.slug, input.connection_id);
4343
+ await assignSlateConnection(input.target, input.slug, input.connection_id);
4344
4344
  });
4345
- program.command("agent").addArgument(new Argument("<target>", "Run from the app root").choices(["local"])).addArgument(new Argument("<operation>").choices(["run"])).argument("<name>", "Agent directory under agents/").argument("<prompt>", "Task to send as the user message").description("Run agents/<name>/instructions.md locally with Claude Agent SDK and native Claude authentication; no platform server or ctx login required").action(async (_target, _operation, name, prompt) => {
4345
+ program.command("agent").addArgument(new Argument("<target>", "Run from the checkout root").choices(["local"])).addArgument(new Argument("<operation>").choices(["run"])).argument("<name>", "Agent directory under agents/").argument("<prompt>", "Task to send as the user message").description("Run agents/<name>/instructions.md locally with Claude Agent SDK and native Claude authentication; Vite startup also requires ctx login when the app declares connections").action(async (_target, _operation, name, prompt) => {
4346
4346
  const input = object({
4347
4347
  name: string().min(1),
4348
4348
  prompt: string().min(1)
@@ -4352,7 +4352,7 @@ program.command("agent").addArgument(new Argument("<target>", "Run from the app
4352
4352
  });
4353
4353
  console.log(await runLocalAgent(input.name, input.prompt));
4354
4354
  });
4355
- const secrets = program.command("secrets").description("Save or drop Owner-owned shared secrets through the authenticated platform").option("--org <org_slug>", "Use this organization's Owner; defaults to the signed-in user").hook("preAction", requireLogin);
4355
+ const secrets = program.command("secrets").description("Save or drop Owner-owned shared secrets through the authenticated platform").option("--org <slug>", "Use this organization's Owner; defaults to the signed-in user").hook("preAction", requireLogin);
4356
4356
  secrets.command("set").argument("<name>", "Secret name: uppercase letters, digits, and underscores; cannot start with a digit").description("Save a secret with a masked password prompt; returns only Owner and name").option("--stdin", "Read the exact UTF-8 value from stdin instead of prompting; preserves whitespace and newlines").action(async (name, _options, command) => {
4357
4357
  await setSecret(secretNameSchema.parse(name), secretOptionsSchema.parse(command.optsWithGlobals()));
4358
4358
  });