apcore-cli 0.3.1 → 0.4.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/dist/index.js CHANGED
@@ -494,7 +494,7 @@ init_errors();
494
494
  import { readFileSync } from "fs";
495
495
  import { fileURLToPath as fileURLToPath2 } from "url";
496
496
  import * as path5 from "path";
497
- import { Command, CommanderError } from "commander";
497
+ import { Command, CommanderError, Option } from "commander";
498
498
 
499
499
  // src/ref-resolver.ts
500
500
  init_esm_shims();
@@ -1220,13 +1220,29 @@ function getCliDisplayFields(descriptor) {
1220
1220
 
1221
1221
  // src/main.ts
1222
1222
  var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
1223
- var pkg = JSON.parse(readFileSync(path5.resolve(__dirname2, "../package.json"), "utf-8"));
1224
- var VERSION = pkg.version;
1225
- function createCli(extensionsDir, progName) {
1223
+ var verboseHelp = false;
1224
+ function setVerboseHelp(verbose) {
1225
+ verboseHelp = verbose;
1226
+ }
1227
+ var docsUrl = null;
1228
+ function setDocsUrl(url) {
1229
+ docsUrl = url;
1230
+ }
1231
+ function hasVerboseFlag() {
1232
+ return process.argv.includes("--verbose");
1233
+ }
1234
+ var VERSION = "0.0.0";
1235
+ try {
1236
+ const pkg = JSON.parse(readFileSync(path5.resolve(__dirname2, "../package.json"), "utf-8"));
1237
+ VERSION = pkg.version;
1238
+ } catch {
1239
+ }
1240
+ function createCli(extensionsDir, progName, verbose = false) {
1241
+ verboseHelp = verbose;
1226
1242
  const resolvedProgName = progName ?? path5.basename(process.argv[1] ?? "apcore-cli") ?? "apcore-cli";
1227
1243
  const cliLogLevel = process.env.APCORE_CLI_LOGGING_LEVEL ?? process.env.APCORE_LOGGING_LEVEL ?? "WARNING";
1228
1244
  setLogLevel(cliLogLevel);
1229
- const program = new Command(resolvedProgName).exitOverride().version(VERSION, "--version", `Show ${resolvedProgName} version`).description("apcore CLI \u2014 execute apcore modules from the command line").option("--extensions-dir <path>", "Path to extensions directory").option("--commands-dir <path>", "Path to convention-based commands directory").option("--binding <path>", "Path to binding.yaml for display overlay").option("--log-level <level>", "Logging level (DEBUG|INFO|WARNING|ERROR)", "WARNING");
1245
+ const program = new Command(resolvedProgName).exitOverride().version(VERSION, "--version", `Show ${resolvedProgName} version`).description("apcore CLI \u2014 execute apcore modules from the command line").option("--extensions-dir <path>", "Path to extensions directory").option("--commands-dir <path>", "Path to convention-based commands directory").option("--binding <path>", "Path to binding.yaml for display overlay").option("--log-level <level>", "Logging level (DEBUG|INFO|WARNING|ERROR)", "WARNING").option("--verbose", "Show all options in help output (including built-in apcore options)");
1230
1246
  const resolvedExtDir = extensionsDir ?? process.env.APCORE_EXTENSIONS_ROOT ?? "./extensions";
1231
1247
  void resolvedExtDir;
1232
1248
  registerInitCommand(program);
@@ -1260,7 +1276,8 @@ async function applyToolkitIntegration(commandsDir, bindingPath) {
1260
1276
  }
1261
1277
  }
1262
1278
  function main(progName) {
1263
- const program = createCli(void 0, progName);
1279
+ verboseHelp = hasVerboseFlag();
1280
+ const program = createCli(void 0, progName, verboseHelp);
1264
1281
  try {
1265
1282
  program.parse(process.argv);
1266
1283
  } catch (error2) {
@@ -1275,7 +1292,7 @@ function main(progName) {
1275
1292
  process.exit(code);
1276
1293
  }
1277
1294
  }
1278
- function buildModuleCommand(moduleDef, executor, helpTextMaxLength = 1e3, cmdName) {
1295
+ function buildModuleCommand(moduleDef, executor, helpTextMaxLength = 1e3, cmdName, verbose = verboseHelp) {
1279
1296
  const moduleId = moduleDef.id;
1280
1297
  let resolvedSchema = {};
1281
1298
  let schemaOptions = [];
@@ -1293,11 +1310,32 @@ function buildModuleCommand(moduleDef, executor, helpTextMaxLength = 1e3, cmdNam
1293
1310
  schemaOptions = schemaToCliOptions(resolvedSchema, helpTextMaxLength);
1294
1311
  }
1295
1312
  const cmd = new Command(effectiveCmdName).description(cmdHelp);
1296
- cmd.option("--input <source>", "Read input from STDIN ('-')");
1297
- cmd.option("-y, --yes", "Bypass approval prompts", false);
1298
- cmd.option("--large-input", "Allow STDIN input larger than 10MB", false);
1299
- cmd.option("--format <format>", "Output format (json|table)");
1300
- cmd.option("--sandbox", "Run module in subprocess sandbox", false);
1313
+ const inputOpt = new Option("--input <source>", "Read JSON input from a file path, or use '-' to read from stdin pipe");
1314
+ const yesOpt = new Option("-y, --yes", "Skip interactive approval prompts (for scripts and CI)").default(false);
1315
+ const largeInputOpt = new Option("--large-input", "Allow stdin input larger than 10MB (default limit protects against accidental pipes)").default(false);
1316
+ const formatOpt = new Option("--format <format>", "Set output format: 'json' for machine-readable, 'table' for human-readable");
1317
+ const sandboxOpt = new Option("--sandbox", "Run module in an isolated subprocess with restricted filesystem and env access").default(false).hideHelp();
1318
+ if (!verbose) {
1319
+ inputOpt.hideHelp();
1320
+ yesOpt.hideHelp();
1321
+ largeInputOpt.hideHelp();
1322
+ formatOpt.hideHelp();
1323
+ }
1324
+ cmd.addOption(inputOpt);
1325
+ cmd.addOption(yesOpt);
1326
+ cmd.addOption(largeInputOpt);
1327
+ cmd.addOption(formatOpt);
1328
+ cmd.addOption(sandboxOpt);
1329
+ const footerParts = [];
1330
+ if (!verbose) {
1331
+ footerParts.push("Use --verbose to show all options (including built-in apcore options).");
1332
+ }
1333
+ if (docsUrl) {
1334
+ footerParts.push(`Docs: ${docsUrl}/commands/${effectiveCmdName}`);
1335
+ }
1336
+ if (footerParts.length > 0) {
1337
+ cmd.addHelpText("after", "\n" + footerParts.join("\n") + "\n");
1338
+ }
1301
1339
  for (const opt of schemaOptions) {
1302
1340
  if (opt.parseArg) {
1303
1341
  cmd.option(opt.flags, opt.description, opt.parseArg, opt.defaultValue);
@@ -1312,7 +1350,7 @@ function buildModuleCommand(moduleDef, executor, helpTextMaxLength = 1e3, cmdNam
1312
1350
  const outputFormat = options.format;
1313
1351
  const sandboxEnabled = options.sandbox;
1314
1352
  const schemaKwargs = {};
1315
- const builtinKeys = /* @__PURE__ */ new Set(["input", "yes", "largeInput", "format", "sandbox"]);
1353
+ const builtinKeys = /* @__PURE__ */ new Set(["input", "yes", "largeInput", "format", "sandbox", "verbose"]);
1316
1354
  for (const [k, v] of Object.entries(options)) {
1317
1355
  if (!builtinKeys.has(k)) {
1318
1356
  schemaKwargs[k] = v;
@@ -1876,10 +1914,14 @@ init_errors();
1876
1914
  import { readFileSync as readFileSync3 } from "fs";
1877
1915
  import { fileURLToPath as fileURLToPath3 } from "url";
1878
1916
  import * as path6 from "path";
1879
- import { Command as Command4 } from "commander";
1917
+ import { Command as Command4, Help, Option as Option2 } from "commander";
1880
1918
  var __dirname3 = path6.dirname(fileURLToPath3(import.meta.url));
1881
- var pkg2 = JSON.parse(readFileSync3(path6.resolve(__dirname3, "../package.json"), "utf-8"));
1882
- var SHELL_VERSION = pkg2.version;
1919
+ var SHELL_VERSION = "0.0.0";
1920
+ try {
1921
+ const pkg = JSON.parse(readFileSync3(path6.resolve(__dirname3, "../package.json"), "utf-8"));
1922
+ SHELL_VERSION = pkg.version;
1923
+ } catch {
1924
+ }
1883
1925
  function makeFunctionName(progName) {
1884
1926
  return "_" + progName.replace(/[^a-zA-Z0-9]/g, "_");
1885
1927
  }
@@ -2143,6 +2185,117 @@ ${meaning}`);
2143
2185
  );
2144
2186
  return sections.join("\n");
2145
2187
  }
2188
+ function roffEscape(s) {
2189
+ return s.replace(/\\/g, "\\\\").replace(/-/g, "\\-").replace(/'/g, "\\(aq");
2190
+ }
2191
+ function buildProgramManPage(program, progName, version, description, docsUrl2) {
2192
+ const help = new Help();
2193
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2194
+ const s = [];
2195
+ const resolvedDesc = description ?? program.description() ?? `${progName} CLI`;
2196
+ s.push(`.TH "${progName.toUpperCase()}" "1" "${today}" "${progName} ${version}" "${progName} Manual"`);
2197
+ s.push(".SH NAME");
2198
+ s.push(`${progName} \\- ${roffEscape(resolvedDesc)}`);
2199
+ s.push(".SH SYNOPSIS");
2200
+ s.push(`\\fB${progName}\\fR [\\fIglobal\\-options\\fR] \\fIcommand\\fR [\\fIcommand\\-options\\fR]`);
2201
+ if (resolvedDesc) {
2202
+ s.push(".SH DESCRIPTION");
2203
+ s.push(roffEscape(resolvedDesc));
2204
+ }
2205
+ const globalOpts = help.visibleOptions(program).filter((o) => !["help", "version", "all", "man"].includes(o.long?.replace("--", "") ?? ""));
2206
+ if (globalOpts.length > 0) {
2207
+ s.push(".SH GLOBAL OPTIONS");
2208
+ for (const opt of globalOpts) {
2209
+ const flag = [opt.short, opt.long].filter(Boolean).join(", ");
2210
+ s.push(".TP");
2211
+ s.push(`\\fB${roffEscape(flag)}\\fR`);
2212
+ if (opt.description) s.push(roffEscape(opt.description));
2213
+ }
2214
+ }
2215
+ const allCommands = help.visibleCommands(program);
2216
+ if (allCommands.length > 0) {
2217
+ s.push(".SH COMMANDS");
2218
+ for (const cmd of allCommands) {
2219
+ if (cmd.name() === "help") continue;
2220
+ const desc = help.subcommandDescription(cmd);
2221
+ s.push(".TP");
2222
+ s.push(`\\fB${progName} ${roffEscape(cmd.name())}\\fR`);
2223
+ if (desc) s.push(roffEscape(desc));
2224
+ const cmdHelp = new Help();
2225
+ const opts = cmdHelp.visibleOptions(cmd).filter((o) => !["help", "version"].includes(o.long?.replace("--", "") ?? ""));
2226
+ for (const opt of opts) {
2227
+ const flag = [opt.short, opt.long].filter(Boolean).join(", ");
2228
+ s.push(".RS");
2229
+ s.push(".TP");
2230
+ s.push(`\\fB${roffEscape(flag)}\\fR`);
2231
+ if (opt.description) s.push(roffEscape(opt.description));
2232
+ s.push(".RE");
2233
+ }
2234
+ const subCmds = cmdHelp.visibleCommands(cmd).filter((c) => c.name() !== "help");
2235
+ for (const sub of subCmds) {
2236
+ const subDesc = help.subcommandDescription(sub);
2237
+ s.push(".TP");
2238
+ s.push(`\\fB${progName} ${roffEscape(cmd.name())} ${roffEscape(sub.name())}\\fR`);
2239
+ if (subDesc) s.push(roffEscape(subDesc));
2240
+ const subOpts = cmdHelp.visibleOptions(sub).filter((o) => !["help", "version"].includes(o.long?.replace("--", "") ?? ""));
2241
+ for (const opt of subOpts) {
2242
+ const flag = [opt.short, opt.long].filter(Boolean).join(", ");
2243
+ s.push(".RS");
2244
+ s.push(".TP");
2245
+ s.push(`\\fB${roffEscape(flag)}\\fR`);
2246
+ if (opt.description) s.push(roffEscape(opt.description));
2247
+ s.push(".RE");
2248
+ }
2249
+ }
2250
+ }
2251
+ }
2252
+ s.push(".SH ENVIRONMENT");
2253
+ s.push(".TP");
2254
+ s.push("\\fBAPCORE_EXTENSIONS_ROOT\\fR");
2255
+ s.push("Path to the apcore extensions directory.");
2256
+ s.push(".TP");
2257
+ s.push("\\fBAPCORE_CLI_AUTO_APPROVE\\fR");
2258
+ s.push("Set to \\fB1\\fR to bypass approval prompts.");
2259
+ s.push(".TP");
2260
+ s.push("\\fBAPCORE_CLI_LOGGING_LEVEL\\fR");
2261
+ s.push("CLI\\-specific logging verbosity (DEBUG|INFO|WARNING|ERROR).");
2262
+ s.push(".SH EXIT CODES");
2263
+ const exitCodes = [
2264
+ ["0", "Success."],
2265
+ ["1", "Module execution error."],
2266
+ ["2", "Invalid CLI input or missing argument."],
2267
+ ["44", "Module not found, disabled, or failed to load."],
2268
+ ["45", "Input failed JSON Schema validation."],
2269
+ ["46", "Approval denied or timed out."],
2270
+ ["47", "Configuration error."],
2271
+ ["77", "ACL denied."],
2272
+ ["130", "Cancelled by user (SIGINT)."]
2273
+ ];
2274
+ for (const [code, meaning] of exitCodes) {
2275
+ s.push(`.TP
2276
+ \\fB${code}\\fR
2277
+ ${meaning}`);
2278
+ }
2279
+ s.push(".SH SEE ALSO");
2280
+ s.push(`\\fB${progName} \\-\\-help \\-\\-verbose\\fR for full option list.`);
2281
+ if (docsUrl2) {
2282
+ s.push(`.PP
2283
+ Full documentation at \\fI${roffEscape(docsUrl2)}\\fR`);
2284
+ }
2285
+ return s.join("\n");
2286
+ }
2287
+ function configureManHelp(program, progName, version, description, docsUrl2) {
2288
+ const manOpt = new Option2("--man", "Output man page in roff format (use with --help)").hideHelp();
2289
+ program.addOption(manOpt);
2290
+ program.addHelpText("beforeAll", () => {
2291
+ if (program.opts().man) {
2292
+ process.stdout.write(buildProgramManPage(program, progName, version, description, docsUrl2));
2293
+ process.stdout.write("\n");
2294
+ process.exit(0);
2295
+ }
2296
+ return "";
2297
+ });
2298
+ }
2146
2299
  function registerShellCommands(cli, progName = "apcore-cli") {
2147
2300
  const completionCmd = new Command4("completion").description(
2148
2301
  "Generate a shell completion script and print it to stdout."
@@ -2205,10 +2358,13 @@ export {
2205
2358
  SchemaValidationError,
2206
2359
  applyToolkitIntegration,
2207
2360
  buildModuleCommand,
2361
+ buildProgramManPage,
2208
2362
  checkApproval,
2209
2363
  collectInput,
2364
+ configureManHelp,
2210
2365
  createCli,
2211
2366
  debug,
2367
+ docsUrl,
2212
2368
  error,
2213
2369
  exitCodeForError,
2214
2370
  extractHelp,
@@ -2230,9 +2386,12 @@ export {
2230
2386
  resolveRefs,
2231
2387
  schemaToCliOptions,
2232
2388
  setAuditLogger,
2389
+ setDocsUrl,
2233
2390
  setLogLevel,
2391
+ setVerboseHelp,
2234
2392
  truncate,
2235
2393
  validateModuleId,
2394
+ verboseHelp,
2236
2395
  warn
2237
2396
  };
2238
2397
  //# sourceMappingURL=index.js.map