@keystrokehq/cli 0.1.112 → 0.1.113

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/index.mjs CHANGED
@@ -6260,6 +6260,11 @@ function listActionsHint(app) {
6260
6260
  const bin = cliBinaryName();
6261
6261
  return `\nNext steps:\n Inspect a tool: ${bin} apps actions get ${app} <TOOL_SLUG>\n Run a tool: ${bin} apps execute ${app} <TOOL_SLUG> --input '{...}'\n`;
6262
6262
  }
6263
+ /** Hint when listing actions for a custom org app (no toolkit tools). */
6264
+ function listCustomAppActionsHint(app) {
6265
+ const bin = cliBinaryName();
6266
+ return `\nCustom org apps have no catalog action list.\n Inspect app: ${bin} apps get ${app}\n Scaffold code: ${bin} apps sync ${app}\n Connect secret: ${bin} connect ${app}\n Author actions: defineApp({ slug: "${app}", ... }).action(...)\n`;
6267
+ }
6263
6268
  /** Next-step hint printed after showing one action's schema. */
6264
6269
  function showActionHint(app, tool, inputParameters) {
6265
6270
  const bin = cliBinaryName();
@@ -6267,6 +6272,12 @@ function showActionHint(app, tool, inputParameters) {
6267
6272
  }
6268
6273
  //#endregion
6269
6274
  //#region src/commands/apps/run-app-catalog.ts
6275
+ const CUSTOM_APP_ACTIONS_MESSAGE = "Custom org apps do not expose catalog actions. Actions live in your project as defineApp(...).action(...). Use `keystroke apps get <slug>` for the credential template, or `keystroke apps sync <slug>` to scaffold the app module.";
6276
+ function isNotFoundError(error) {
6277
+ if (!(error instanceof PlatformError)) return false;
6278
+ if (error.status === 404) return true;
6279
+ return /not found/i.test(error.message);
6280
+ }
6270
6281
  async function runAppSearch(client, query, options) {
6271
6282
  const trimmed = query.trim();
6272
6283
  if (!trimmed) throw new Error("Search query is required");
@@ -6280,22 +6291,58 @@ async function runAppSearch(client, query, options) {
6280
6291
  async function runAppShow(client, slug) {
6281
6292
  const trimmed = slug.trim();
6282
6293
  if (!trimmed) throw new Error("App slug is required");
6283
- return client.apps.getCatalogApp(trimmed);
6294
+ const parsed = parseAppSlug(trimmed);
6295
+ if (parsed.kind === "org") return {
6296
+ kind: "custom",
6297
+ app: await client.apps.get(parsed.slug)
6298
+ };
6299
+ try {
6300
+ return {
6301
+ kind: "catalog",
6302
+ app: await client.apps.getCatalogApp(trimmed)
6303
+ };
6304
+ } catch (error) {
6305
+ if (!isNotFoundError(error)) throw error;
6306
+ try {
6307
+ return {
6308
+ kind: "custom",
6309
+ app: await client.apps.get(trimmed)
6310
+ };
6311
+ } catch (fallbackError) {
6312
+ if (isNotFoundError(fallbackError)) throw error;
6313
+ throw fallbackError;
6314
+ }
6315
+ }
6284
6316
  }
6285
6317
  async function runAppActions(client, options) {
6286
6318
  const slug = options.slug?.trim();
6287
6319
  const search = options.search?.trim();
6288
- if (slug) return client.apps.listCatalogActions(slug, {
6289
- search,
6290
- limit: options.limit,
6291
- cursor: options.cursor
6292
- });
6320
+ if (slug) {
6321
+ const parsed = parseAppSlug(slug);
6322
+ if (parsed.kind === "org") return {
6323
+ kind: "custom",
6324
+ toolkit: parsed.slug,
6325
+ items: [],
6326
+ message: CUSTOM_APP_ACTIONS_MESSAGE
6327
+ };
6328
+ return {
6329
+ kind: "catalog",
6330
+ ...await client.apps.listCatalogActions(slug, {
6331
+ search,
6332
+ limit: options.limit,
6333
+ cursor: options.cursor
6334
+ })
6335
+ };
6336
+ }
6293
6337
  if (!search) throw new Error("App slug or --search is required");
6294
- return client.apps.searchCatalogActions({
6295
- search,
6296
- limit: options.limit,
6297
- cursor: options.cursor
6298
- });
6338
+ return {
6339
+ kind: "catalog",
6340
+ ...await client.apps.searchCatalogActions({
6341
+ search,
6342
+ limit: options.limit,
6343
+ cursor: options.cursor
6344
+ })
6345
+ };
6299
6346
  }
6300
6347
  async function runAppAction(client, toolSlug) {
6301
6348
  const trimmed = toolSlug.trim().toUpperCase();
@@ -6305,8 +6352,8 @@ async function runAppAction(client, toolSlug) {
6305
6352
  //#endregion
6306
6353
  //#region src/commands/apps/actions.ts
6307
6354
  function registerAppActionsCommands(app) {
6308
- const actions = app.command("actions").description("List and inspect catalog app actions");
6309
- actions.command("list").description("List or search a catalog app's actions").argument("[slug]", "App slug (omit for cross-app search with --search)").option("--search <query>", "Search actions within the app or across all apps").option("--limit <n>", "Page size", (value) => Number.parseInt(value, 10)).option("--cursor <cursor>", "Pagination cursor").action((slug, options) => runCliCommand("App actions list failed", async () => {
6355
+ const actions = app.command("actions").description("List and inspect built-in catalog app actions (not custom org apps)");
6356
+ actions.command("list").description("List or search catalog toolkit actions; custom org apps return kind:custom with guidance").argument("[slug]", "App slug (omit for cross-app search with --search)").option("--search <query>", "Search actions within the app or across all apps").option("--limit <n>", "Page size", (value) => Number.parseInt(value, 10)).option("--cursor <cursor>", "Pagination cursor").action((slug, options) => runCliCommand("App actions list failed", async () => {
6310
6357
  const config = createCliConfig();
6311
6358
  const client = createCliPlatformClient(config);
6312
6359
  await resolveActiveOrganization(config);
@@ -6315,9 +6362,15 @@ function registerAppActionsCommands(app) {
6315
6362
  ...options
6316
6363
  });
6317
6364
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
6318
- if (slug?.trim()) process.stderr.write(listActionsHint(slug.trim().toLowerCase()));
6365
+ const trimmedSlug = slug?.trim();
6366
+ if (!trimmedSlug) return;
6367
+ if (result.kind === "custom") {
6368
+ process.stderr.write(listCustomAppActionsHint(trimmedSlug));
6369
+ return;
6370
+ }
6371
+ process.stderr.write(listActionsHint(trimmedSlug.toLowerCase()));
6319
6372
  }, void 0, { orgScoped: true }));
6320
- actions.command("get").description("Get a catalog action schema, plus how to run and import it").argument("<app>", "App slug (e.g. github)").argument("<tool>", "Tool slug (e.g. github_create_an_issue)").action((appSlug, toolSlug) => runCliCommand("App action get failed", async () => {
6373
+ actions.command("get").description("Get a catalog action schema, plus how to run and import it").argument("<app>", "Catalog app slug (e.g. github) — not a custom org app").argument("<tool>", "Tool slug (e.g. github_create_an_issue)").action((appSlug, toolSlug) => runCliCommand("App action get failed", async () => {
6321
6374
  const config = createCliConfig();
6322
6375
  const client = createCliPlatformClient(config);
6323
6376
  await resolveActiveOrganization(config);
@@ -6439,7 +6492,7 @@ function parseFieldOverrides(flags) {
6439
6492
  return parseCustomAppFields(flags);
6440
6493
  }
6441
6494
  function registerAppCreateCommand(app) {
6442
- app.command("create").description("Create a custom org app").option("--name <name>", "App display name").option("--slug <slug>", "App slug segment (defaults from name)").option("--description <description>", "App description").option("--field <field>", "Credential field as key, key:secret, key:optional, or key:secret:optional (repeatable)", collectValues$1, []).option("--mcp <url>", "Create from an MCP server URL (auto-detect auth)").option("--openapi <url>", "Create from an OpenAPI spec URL (auto-detect auth)").option("--graphql <url>", "Create from a GraphQL endpoint URL (auto-detect auth)").option("--auth <kind>", "Override detected auth: oauth or api_key (MCP only)").option("--preview", "Show the request that would be created without creating").action((options) => runCliCommand("Create app failed", async () => {
6495
+ app.command("create").description("Create a custom org app").option("--name <name>", "App display name").option("--slug <slug>", "App slug segment (defaults from name)").option("--description <description>", "App description (defaults to --name)").option("--field <field>", "Credential field as key, key:secret, key:optional, or key:secret:optional (repeatable)", collectValues$1, []).option("--mcp <url>", "Create from an MCP server URL (auto-detect auth)").option("--openapi <url>", "Create from an OpenAPI spec URL (auto-detect auth)").option("--graphql <url>", "Create from a GraphQL endpoint URL (auto-detect auth)").option("--auth <kind>", "Override detected auth: oauth or api_key (MCP only)").option("--preview", "Show the request that would be created without creating").action((options) => runCliCommand("Create app failed", async () => {
6443
6496
  const config = createCliConfig();
6444
6497
  const client = createCliPlatformClient(config);
6445
6498
  await resolveActiveOrganization(config);
@@ -6459,12 +6512,11 @@ function registerAppCreateCommand(app) {
6459
6512
  return;
6460
6513
  }
6461
6514
  if (!options.name?.trim()) throw new Error("--name is required for custom apps");
6462
- if (!options.description?.trim()) throw new Error("--description is required for custom apps");
6463
- const slug = options.slug?.trim() || slugifyAppName(options.name);
6515
+ const name = options.name.trim();
6464
6516
  const result = await runAppCreate(client, {
6465
- name: options.name.trim(),
6466
- slug,
6467
- description: options.description.trim(),
6517
+ name,
6518
+ slug: options.slug?.trim() || slugifyAppName(name),
6519
+ description: options.description?.trim() || name,
6468
6520
  source: "custom",
6469
6521
  fields: parseCustomAppFields(options.field)
6470
6522
  }, { preview: options.preview ?? false });
@@ -6536,7 +6588,7 @@ Examples:
6536
6588
  //#endregion
6537
6589
  //#region src/commands/apps/get.ts
6538
6590
  function registerAppGetCommand(app) {
6539
- app.command("get").description("Get a Composio app from the live catalog").argument("<slug>", "App slug").action((slug) => runCliCommand("App get failed", async () => {
6591
+ app.command("get").description("Get an app: catalog toolkit detail, or custom org app credential template (kind: catalog|custom)").argument("<slug>", "App slug (e.g. github or acme/internal-api)").action((slug) => runCliCommand("App get failed", async () => {
6540
6592
  const config = createCliConfig();
6541
6593
  const client = createCliPlatformClient(config);
6542
6594
  await resolveActiveOrganization(config);