@camunda8/cli 2.7.0 → 2.8.0-alpha.10

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 (92) hide show
  1. package/PLUGIN-HELP.md +145 -8
  2. package/README.md +1171 -73
  3. package/dist/command-dispatch.d.ts.map +1 -1
  4. package/dist/command-dispatch.js +3 -2
  5. package/dist/command-dispatch.js.map +1 -1
  6. package/dist/command-framework.d.ts.map +1 -1
  7. package/dist/command-framework.js +22 -1
  8. package/dist/command-framework.js.map +1 -1
  9. package/dist/command-registry.d.ts +49 -346
  10. package/dist/command-registry.d.ts.map +1 -1
  11. package/dist/command-registry.js +46 -54
  12. package/dist/command-registry.js.map +1 -1
  13. package/dist/commands/completion.d.ts +16 -33
  14. package/dist/commands/completion.d.ts.map +1 -1
  15. package/dist/commands/completion.js +31 -689
  16. package/dist/commands/completion.js.map +1 -1
  17. package/dist/commands/mcp-proxy.d.ts +0 -17
  18. package/dist/commands/mcp-proxy.d.ts.map +1 -1
  19. package/dist/commands/mcp-proxy.js +3 -104
  20. package/dist/commands/mcp-proxy.js.map +1 -1
  21. package/dist/commands/open.d.ts +3 -44
  22. package/dist/commands/open.d.ts.map +1 -1
  23. package/dist/commands/open.js +5 -81
  24. package/dist/commands/open.js.map +1 -1
  25. package/dist/commands/plugins.d.ts +2 -8
  26. package/dist/commands/plugins.d.ts.map +1 -1
  27. package/dist/commands/plugins.js +2 -28
  28. package/dist/commands/plugins.js.map +1 -1
  29. package/dist/commands/run.d.ts +8 -8
  30. package/dist/commands/run.d.ts.map +1 -1
  31. package/dist/commands/run.js +60 -60
  32. package/dist/commands/run.js.map +1 -1
  33. package/dist/commands/search.d.ts +2 -39
  34. package/dist/commands/search.d.ts.map +1 -1
  35. package/dist/commands/search.js +2 -83
  36. package/dist/commands/search.js.map +1 -1
  37. package/dist/commands/session.d.ts +1 -0
  38. package/dist/commands/session.d.ts.map +1 -1
  39. package/dist/commands/session.js +5 -0
  40. package/dist/commands/session.js.map +1 -1
  41. package/dist/commands/watch.d.ts +2 -1
  42. package/dist/commands/watch.d.ts.map +1 -1
  43. package/dist/commands/watch.js +17 -8
  44. package/dist/commands/watch.js.map +1 -1
  45. package/dist/completion.d.ts +36 -0
  46. package/dist/completion.d.ts.map +1 -0
  47. package/dist/completion.js +816 -0
  48. package/dist/completion.js.map +1 -0
  49. package/dist/config.d.ts.map +1 -1
  50. package/dist/config.js +19 -1
  51. package/dist/config.js.map +1 -1
  52. package/dist/{commands/deployments.d.ts → deployments.d.ts} +1 -1
  53. package/dist/deployments.d.ts.map +1 -0
  54. package/dist/{commands/deployments.js → deployments.js} +8 -8
  55. package/dist/deployments.js.map +1 -0
  56. package/dist/help.d.ts.map +1 -0
  57. package/dist/{commands/help.js → help.js} +107 -43
  58. package/dist/help.js.map +1 -0
  59. package/dist/index.d.ts +23 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +285 -9
  62. package/dist/index.js.map +1 -1
  63. package/dist/mcp-proxy-helpers.d.ts +23 -0
  64. package/dist/mcp-proxy-helpers.d.ts.map +1 -0
  65. package/dist/mcp-proxy-helpers.js +109 -0
  66. package/dist/mcp-proxy-helpers.js.map +1 -0
  67. package/dist/open-helpers.d.ts +52 -0
  68. package/dist/open-helpers.d.ts.map +1 -0
  69. package/dist/open-helpers.js +88 -0
  70. package/dist/open-helpers.js.map +1 -0
  71. package/dist/plugin-loader.d.ts +61 -2
  72. package/dist/plugin-loader.d.ts.map +1 -1
  73. package/dist/plugin-loader.js +229 -22
  74. package/dist/plugin-loader.js.map +1 -1
  75. package/dist/plugin-version.d.ts +15 -0
  76. package/dist/plugin-version.d.ts.map +1 -0
  77. package/dist/plugin-version.js +37 -0
  78. package/dist/plugin-version.js.map +1 -0
  79. package/dist/search-helpers.d.ts +46 -0
  80. package/dist/search-helpers.d.ts.map +1 -0
  81. package/dist/search-helpers.js +90 -0
  82. package/dist/search-helpers.js.map +1 -0
  83. package/dist/watch-constants.d.ts +7 -0
  84. package/dist/watch-constants.d.ts.map +1 -0
  85. package/dist/watch-constants.js +7 -0
  86. package/dist/watch-constants.js.map +1 -0
  87. package/package.json +11 -7
  88. package/dist/commands/deployments.d.ts.map +0 -1
  89. package/dist/commands/deployments.js.map +0 -1
  90. package/dist/commands/help.d.ts.map +0 -1
  91. package/dist/commands/help.js.map +0 -1
  92. /package/dist/{commands/help.d.ts → help.d.ts} +0 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Pure helpers extracted from `src/commands/open.ts` so tests can import
3
+ * them without violating the test→commands import boundary (#291). The
4
+ * `openAppCommand` / `feedbackCommand` handlers in `src/commands/open.ts`
5
+ * re-import these.
6
+ */
7
+ import { spawn } from "node:child_process";
8
+ import { platform } from "node:os";
9
+ import { requireOneOf, requirePositional } from "./command-validation.js";
10
+ import { getLogger } from "./logger.js";
11
+ export const OPEN_APPS = [
12
+ "operate",
13
+ "tasklist",
14
+ "modeler",
15
+ "optimize",
16
+ ];
17
+ export function isAppName(value) {
18
+ // biome-ignore lint/plugin: safe widening — readonly tuple to readonly string[] for .includes() compatibility
19
+ return OPEN_APPS.includes(value);
20
+ }
21
+ /** Pattern that matches a self-managed REST API version suffix, e.g. `/v2` */
22
+ const VERSION_SUFFIX_RE = /\/v\d+\/?$/;
23
+ /**
24
+ * Derive the URL of a Camunda web application from the cluster base URL.
25
+ *
26
+ * Only supported for self-managed clusters where the base URL is the REST API
27
+ * endpoint (e.g. `http://localhost:8080/v2`). Returns `null` when the URL
28
+ * does not look like a self-managed gateway (no `/v<n>` suffix).
29
+ */
30
+ export function deriveAppUrl(baseUrl, app) {
31
+ if (!VERSION_SUFFIX_RE.test(baseUrl)) {
32
+ return null;
33
+ }
34
+ const base = baseUrl.replace(VERSION_SUFFIX_RE, "").replace(/\/$/, "");
35
+ return `${base}/${app}`;
36
+ }
37
+ /**
38
+ * Determine the platform-appropriate command and arguments to open a URL.
39
+ *
40
+ * WSL is detected explicitly because it reports `linux`, but should use the
41
+ * Windows opener via interop rather than relying on `xdg-open`.
42
+ *
43
+ * Accepts optional overrides for testing.
44
+ */
45
+ export function getBrowserCommand(url, plat = platform(), env = process.env) {
46
+ const isWsl = plat === "linux" && Boolean(env.WSL_DISTRO_NAME || env.WSL_INTEROP);
47
+ if (plat === "darwin") {
48
+ return { command: "open", args: [url] };
49
+ }
50
+ if (plat === "win32" || isWsl) {
51
+ return { command: "cmd.exe", args: ["/c", "start", "", url] };
52
+ }
53
+ // Linux
54
+ return { command: "xdg-open", args: [url] };
55
+ }
56
+ /**
57
+ * Open a URL in the default system browser.
58
+ * Works on macOS, Linux, native Windows, and WSL.
59
+ */
60
+ export function openUrl(url) {
61
+ const logger = getLogger();
62
+ const { command, args } = getBrowserCommand(url);
63
+ const child = spawn(command, args, { detached: true, stdio: "ignore" });
64
+ child.on("error", (error) => {
65
+ if (error.code === "ENOENT") {
66
+ logger.error(`Could not open the browser automatically because '${command}' is not available on PATH.`);
67
+ logger.info(`Open this URL manually: ${url}`);
68
+ return;
69
+ }
70
+ logger.error(`Could not open the browser automatically: ${error.message}`);
71
+ logger.info(`Open this URL manually: ${url}`);
72
+ });
73
+ child.unref();
74
+ }
75
+ const OPEN_USAGE = "Usage: c8 open <app> [--profile <name>]";
76
+ /**
77
+ * Validate raw CLI positional + options for the open command.
78
+ * Returns a fully validated and type-narrowed input object.
79
+ * Exits with code 1 on invalid input.
80
+ */
81
+ export function validateOpenAppOptions(app, options) {
82
+ return {
83
+ app: requireOneOf(requirePositional(app, "Application", OPEN_USAGE), OPEN_APPS, "application", OPEN_USAGE),
84
+ profile: options.profile,
85
+ dryRun: options.dryRun,
86
+ };
87
+ }
88
+ //# sourceMappingURL=open-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-helpers.js","sourceRoot":"","sources":["../src/open-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,55 @@
1
1
  /**
2
2
  * Plugin loader for dynamic command loading
3
3
  */
4
+ import type { FlagDef } from "./command-registry.ts";
5
+ type CommandHandler = (args: string[], flags?: Record<string, unknown>) => Promise<void>;
6
+ interface CommandWithFlags {
7
+ flags: Record<string, FlagDef>;
8
+ handler: CommandHandler;
9
+ }
10
+ type PluginCommand = CommandHandler | CommandWithFlags;
4
11
  interface PluginCommands {
5
- [commandName: string]: (args: string[]) => Promise<void>;
12
+ [commandName: string]: PluginCommand;
13
+ }
14
+ /**
15
+ * Per-command plugin metadata.
16
+ *
17
+ * A plugin command is **either** metadata-driven (declares typed flags via
18
+ * the `{ flags, handler }` command form) **or** a passthrough command
19
+ * (`passthrough: true` + `passthroughHint`). Mutually exclusive — see
20
+ * #251 / #366. Declaring both is rejected at load time.
21
+ */
22
+ export interface PluginCommandMeta {
23
+ description?: string;
24
+ helpDescription?: string;
25
+ examples?: {
26
+ command: string;
27
+ description: string;
28
+ }[];
29
+ /** Subcommands for shell completion (e.g. cluster → start, stop, status). */
30
+ subcommands?: {
31
+ name: string;
32
+ description: string;
33
+ }[];
34
+ /**
35
+ * If true, c8ctl strips GLOBAL_FLAGS from argv and forwards everything
36
+ * else verbatim to the bare-function handler. Help and JSON help
37
+ * advertise the boundary explicitly.
38
+ *
39
+ * MUST NOT appear together with the `{ flags, handler }` command form;
40
+ * the load-time validator drops any command that declares both.
41
+ */
42
+ passthrough?: boolean;
43
+ /**
44
+ * Required when `passthrough` is true. Short text rendered in help that
45
+ * advertises the boundary, e.g. "Forwards args to `kubectl`".
46
+ */
47
+ passthroughHint?: string;
48
+ /**
49
+ * Optional documentation-only flag list rendered in help under
50
+ * passthrough commands. NOT parsed by c8ctl.
51
+ */
52
+ flagsHint?: string[];
6
53
  }
7
54
  /**
8
55
  * Load all installed plugins from global plugins directory
@@ -15,7 +62,7 @@ export declare function getPluginCommands(): PluginCommands;
15
62
  /**
16
63
  * Execute a plugin command if it exists
17
64
  */
18
- export declare function executePluginCommand(commandName: string, args: string[]): Promise<boolean>;
65
+ export declare function executePluginCommand(commandName: string, args: string[], flags?: Record<string, unknown>): Promise<boolean>;
19
66
  /**
20
67
  * Check if a command is provided by a plugin
21
68
  */
@@ -31,6 +78,7 @@ export interface PluginCommandInfo {
31
78
  commandName: string;
32
79
  pluginName: string;
33
80
  description?: string;
81
+ helpDescription?: string;
34
82
  examples?: {
35
83
  command: string;
36
84
  description: string;
@@ -40,8 +88,19 @@ export interface PluginCommandInfo {
40
88
  name: string;
41
89
  description: string;
42
90
  }[];
91
+ /** True when the command opted into the #366 passthrough contract. */
92
+ passthrough?: boolean;
93
+ /** Required when passthrough is true — short text that names the boundary. */
94
+ passthroughHint?: string;
95
+ /** Optional documentation-only flag list rendered under passthrough help. */
96
+ flagsHint?: string[];
43
97
  }
44
98
  export declare function getPluginCommandsInfo(): PluginCommandInfo[];
99
+ /**
100
+ * True if the named command is a registered passthrough plugin command
101
+ * (#366). Used by the dispatcher to gate the strip-and-forward path.
102
+ */
103
+ export declare function isPassthroughPluginCommand(commandName: string): boolean;
45
104
  /**
46
105
  * Clear all loaded plugins (useful for testing and after uninstall)
47
106
  */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,UAAU,cAAc;IACvB,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAiHD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2H1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAQlD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,6EAA6E;IAC7E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD;AAED,wBAAgB,qBAAqB,IAAI,iBAAiB,EAAE,CAgB3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
1
+ {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAKrD,KAAK,cAAc,GAAG,CACrB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,UAAU,gBAAgB;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,EAAE,cAAc,CAAC;CACxB;AAED,KAAK,aAAa,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEvD,UAAU,cAAc;IACvB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAAC;CACrC;AAUD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,6EAA6E;IAC7E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAwQD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CA8J1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAQlD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,6EAA6E;IAC7E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,qBAAqB,IAAI,iBAAiB,EAAE,CAqB3D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAOvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -15,6 +15,135 @@ import { ensurePluginsDir } from "./config.js";
15
15
  import { getLogger } from "./logger.js";
16
16
  import { c8ctl } from "./runtime.js";
17
17
  const loadedPlugins = new Map();
18
+ /**
19
+ * Validate the passthrough/flags mutual-exclusion rule (#366). Removes
20
+ * offending commands from the registered set so they cannot be invoked,
21
+ * and emits a `logger.warn` naming the plugin and command so the
22
+ * misconfiguration is visible at startup.
23
+ *
24
+ * The contract: a command MUST NOT declare `passthrough: true` AND use the
25
+ * `{ flags, handler }` form. Pick one. A passthrough command without a
26
+ * `passthroughHint` is also rejected (the hint is what makes the boundary
27
+ * legible to users and agents).
28
+ *
29
+ * Mutates `plugin.commands` in place. Safe to call after each plugin is
30
+ * loaded.
31
+ */
32
+ function validatePassthroughCommands(plugin) {
33
+ const logger = getLogger();
34
+ const meta = plugin.metadata?.commands ?? {};
35
+ for (const commandName of Object.keys(plugin.commands)) {
36
+ const commandMeta = meta[commandName];
37
+ if (commandMeta?.passthrough === undefined)
38
+ continue;
39
+ // `passthrough: false` is equivalent to "not opted in" — silently
40
+ // skip. Any other non-`true` value (e.g. the string "true", a
41
+ // number) is a contract violation: dispatch and help both gate on
42
+ // `=== true`, so a truthy non-true value would silently disagree
43
+ // with them. Reject loudly at load time.
44
+ if (commandMeta.passthrough === false)
45
+ continue;
46
+ if (commandMeta.passthrough !== true) {
47
+ logger.warn(`Plugin '${plugin.name}' command '${commandName}' has metadata.passthrough set to ` +
48
+ `${JSON.stringify(commandMeta.passthrough)} but the contract requires the boolean ` +
49
+ "literal `true` (or `false` / omitted to opt out). Dropping this command (#366).");
50
+ delete plugin.commands[commandName];
51
+ continue;
52
+ }
53
+ const cmd = plugin.commands[commandName];
54
+ const hasFlagsForm = typeof cmd !== "function";
55
+ if (hasFlagsForm) {
56
+ logger.warn(`Plugin '${plugin.name}' command '${commandName}' declares both passthrough:true AND flags. ` +
57
+ "Pick one \u2014 a passthrough command must use the bare-function handler form. " +
58
+ "Dropping this command (#366).");
59
+ delete plugin.commands[commandName];
60
+ continue;
61
+ }
62
+ if (typeof commandMeta.passthroughHint !== "string" ||
63
+ commandMeta.passthroughHint.trim() === "") {
64
+ logger.warn(`Plugin '${plugin.name}' command '${commandName}' declares passthrough:true ` +
65
+ "but is missing a non-empty passthroughHint. The hint is required so help and " +
66
+ "agents can advertise the boundary. Dropping this command (#366).");
67
+ delete plugin.commands[commandName];
68
+ continue;
69
+ }
70
+ // `flagsHint` is documentation-only and consumed by the help
71
+ // renderer, which assumes `string[]`. Validate the shape here so a
72
+ // mis-typed value can't reach the renderer. The field is optional;
73
+ // invalid shapes are stripped (not fatal) so the command itself
74
+ // continues to work — only the doc affordance is lost.
75
+ const flagsHint = commandMeta.flagsHint;
76
+ if (flagsHint !== undefined) {
77
+ const valid = Array.isArray(flagsHint) &&
78
+ flagsHint.every((entry) => typeof entry === "string");
79
+ if (!valid) {
80
+ logger.warn(`Plugin '${plugin.name}' command '${commandName}' declares metadata.flagsHint ` +
81
+ "but it is not a string[]. Ignoring flagsHint (#366).");
82
+ delete commandMeta.flagsHint;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ /**
88
+ * Reject duplicate plugin command names at load time. If `plugin` declares
89
+ * a command name that is already registered by an earlier-loaded plugin,
90
+ * drop it from `plugin.commands` and emit `logger.warn` naming both
91
+ * plugins so the conflict is visible at startup.
92
+ *
93
+ * **Conflict policy: first registration wins.** This is an explicit
94
+ * choice (#366) and replaces the previous implicit "last-loaded wins"
95
+ * behaviour produced by `Object.assign` over `loadedPlugins` in
96
+ * insertion order. Plugins cannot override one another by registering
97
+ * the same command name; if you want a different command, give it a
98
+ * different name. Default plugins always load first, so user-installed
99
+ * plugins cannot override default commands by name.
100
+ *
101
+ * This guarantees that the merged map returned by `getPluginCommands()`
102
+ * has a single owning plugin per command name, which keeps dispatch and
103
+ * `isPassthroughPluginCommand()` consistent: the help renderer and the
104
+ * runtime always agree on which plugin handles a given verb.
105
+ *
106
+ * Mutates `plugin.commands` in place. Safe to call after each plugin is
107
+ * loaded; relies on `loadedPlugins` already containing previously-loaded
108
+ * plugins.
109
+ */
110
+ function rejectDuplicateCommandNames(plugin) {
111
+ const logger = getLogger();
112
+ for (const commandName of Object.keys(plugin.commands)) {
113
+ for (const existing of loadedPlugins.values()) {
114
+ if (Object.hasOwn(existing.commands, commandName)) {
115
+ logger.warn(`Plugin '${plugin.name}' tried to register command '${commandName}' but it is ` +
116
+ `already provided by plugin '${existing.name}'. The first registration wins; ` +
117
+ `dropping the duplicate from '${plugin.name}'.`);
118
+ delete plugin.commands[commandName];
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ /**
125
+ * Reject a plugin whose name collides with an already-loaded plugin.
126
+ * This is a separate concern from the command-name collision policy
127
+ * tracked under #363: that policy rejects two plugins exporting the
128
+ * same command name, while this one rejects two plugins sharing the
129
+ * same `package.json#name`. Both follow first-registration-wins.
130
+ * Without this guard a user-installed package sharing a name with a
131
+ * default plugin (or with another already-loaded plugin) would
132
+ * silently overwrite the prior `loadedPlugins.set()` entry, bypassing
133
+ * the command-name policy entirely.
134
+ *
135
+ * Returns `true` when the caller should skip the load; `false` when
136
+ * the name is free.
137
+ */
138
+ function isDuplicatePluginName(pluginName) {
139
+ const logger = getLogger();
140
+ if (loadedPlugins.has(pluginName)) {
141
+ logger.warn(`Plugin name '${pluginName}' is already loaded; refusing to load a second plugin ` +
142
+ `with the same name. The first registration wins.`);
143
+ return true;
144
+ }
145
+ return false;
146
+ }
18
147
  /**
19
148
  * Load default plugins bundled with c8ctl
20
149
  */
@@ -44,7 +173,12 @@ async function loadDefaultPlugins() {
44
173
  logger.debug("No default-plugins directory found");
45
174
  return;
46
175
  }
47
- const pluginDirs = readdirSync(defaultPluginsDir);
176
+ // Sort to make load order deterministic across filesystems/OSes.
177
+ // The first-registration-wins duplicate-name policy in
178
+ // `rejectDuplicateCommandNames` relies on this — without a stable
179
+ // sort, "who wins" would depend on `readdirSync()` order, which
180
+ // varies across platforms and filesystems.
181
+ const pluginDirs = readdirSync(defaultPluginsDir).sort();
48
182
  logger.debug(`Found ${pluginDirs.length} default plugin(s)`);
49
183
  for (const pluginDir of pluginDirs) {
50
184
  const pluginPath = join(defaultPluginsDir, pluginDir);
@@ -64,6 +198,13 @@ async function loadDefaultPlugins() {
64
198
  // Read package.json
65
199
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
66
200
  const pluginName = packageJson.name || `default-${pluginDir}`;
201
+ // Check for duplicate plugin name BEFORE the dynamic import
202
+ // so a duplicate-name plugin's module code never runs (the
203
+ // import has top-level side effects we don't want to execute
204
+ // only to throw the result away).
205
+ if (isDuplicatePluginName(pluginName)) {
206
+ continue;
207
+ }
67
208
  const pluginFile = existsSync(pluginFileJs)
68
209
  ? pluginFileJs
69
210
  : pluginFileTs;
@@ -72,12 +213,15 @@ async function loadDefaultPlugins() {
72
213
  logger.debug(`Loading default plugin from: ${pluginUrl}`);
73
214
  const plugin = await import(__rewriteRelativeImportExtension(pluginUrl));
74
215
  if (plugin.commands && typeof plugin.commands === "object") {
75
- loadedPlugins.set(pluginName, {
216
+ const loaded = {
76
217
  name: pluginName,
77
- commands: plugin.commands,
218
+ commands: { ...plugin.commands },
78
219
  metadata: plugin.metadata || {},
79
- });
80
- const commandNames = Object.keys(plugin.commands);
220
+ };
221
+ validatePassthroughCommands(loaded);
222
+ rejectDuplicateCommandNames(loaded);
223
+ loadedPlugins.set(pluginName, loaded);
224
+ const commandNames = Object.keys(loaded.commands);
81
225
  logger.debug(`Successfully loaded default plugin: ${pluginName} with ${commandNames.length} commands:`, commandNames);
82
226
  }
83
227
  }
@@ -108,7 +252,12 @@ export async function loadInstalledPlugins() {
108
252
  return;
109
253
  }
110
254
  try {
111
- const entries = readdirSync(nodeModulesPath);
255
+ // Sort to make load order deterministic across filesystems/OSes.
256
+ // The first-registration-wins duplicate-name policy in
257
+ // `rejectDuplicateCommandNames` relies on this — without a stable
258
+ // sort, "who wins" would depend on `readdirSync()` order, which
259
+ // varies across platforms and filesystems.
260
+ const entries = readdirSync(nodeModulesPath).sort();
112
261
  logger.debug(`Scanning ${entries.length} entries in node_modules`);
113
262
  const packagesToScan = [];
114
263
  // Collect regular packages and scoped packages
@@ -117,10 +266,10 @@ export async function loadInstalledPlugins() {
117
266
  continue;
118
267
  }
119
268
  if (entry.startsWith("@")) {
120
- // Scoped package - scan subdirectories
269
+ // Scoped package - scan subdirectories (sorted for determinism).
121
270
  const scopePath = join(nodeModulesPath, entry);
122
271
  try {
123
- const scopedPackages = readdirSync(scopePath);
272
+ const scopedPackages = readdirSync(scopePath).sort();
124
273
  for (const scopedPkg of scopedPackages) {
125
274
  if (!scopedPkg.startsWith(".")) {
126
275
  packagesToScan.push(join(entry, scopedPkg));
@@ -136,6 +285,11 @@ export async function loadInstalledPlugins() {
136
285
  packagesToScan.push(entry);
137
286
  }
138
287
  }
288
+ // Final defensive sort: `@scope/pkg` paths interleave with bare
289
+ // `pkg` paths in the order we appended them, but for
290
+ // duplicate-name resolution we want a single, stable lexicographic
291
+ // order over the full set.
292
+ packagesToScan.sort();
139
293
  logger.debug(`Found ${packagesToScan.length} packages to scan:`, packagesToScan);
140
294
  for (const packageName of packagesToScan) {
141
295
  const packagePath = join(nodeModulesPath, packageName);
@@ -165,18 +319,39 @@ export async function loadInstalledPlugins() {
165
319
  const pluginFile = existsSync(pluginFileJs)
166
320
  ? pluginFileJs
167
321
  : pluginFileTs;
322
+ // Use the package.json#name (not the filesystem directory
323
+ // entry) as the canonical plugin name / loadedPlugins key.
324
+ // Under npm aliases (e.g. `npm i my-alias@npm:real-plugin`),
325
+ // the install directory is `my-alias` but the package name is
326
+ // `real-plugin`. Keying by directory would miss real
327
+ // duplicate-name collisions and surface the wrong name in
328
+ // duplicate warnings. `packageName` is kept for filesystem /
329
+ // logging purposes only.
330
+ const pluginName = typeof packageJson.name === "string" && packageJson.name.length > 0
331
+ ? packageJson.name
332
+ : packageName;
333
+ // Check for duplicate plugin name BEFORE the dynamic import
334
+ // so a duplicate-name plugin's module code never runs (the
335
+ // import has top-level side effects we don't want to execute
336
+ // only to throw the result away).
337
+ if (isDuplicatePluginName(pluginName)) {
338
+ continue;
339
+ }
168
340
  // Use file:// protocol and add timestamp to bust cache
169
341
  const pluginUrl = `file://${pluginFile}?t=${Date.now()}`;
170
342
  logger.debug(`Loading plugin from: ${pluginUrl}`);
171
343
  const plugin = await import(__rewriteRelativeImportExtension(pluginUrl));
172
344
  if (plugin.commands && typeof plugin.commands === "object") {
173
- loadedPlugins.set(packageName, {
174
- name: packageName,
175
- commands: plugin.commands,
345
+ const loaded = {
346
+ name: pluginName,
347
+ commands: { ...plugin.commands },
176
348
  metadata: plugin.metadata || {},
177
- });
178
- const commandNames = Object.keys(plugin.commands);
179
- logger.debug(`Successfully loaded plugin: ${packageName} with ${commandNames.length} commands:`, commandNames);
349
+ };
350
+ validatePassthroughCommands(loaded);
351
+ rejectDuplicateCommandNames(loaded);
352
+ loadedPlugins.set(pluginName, loaded);
353
+ const commandNames = Object.keys(loaded.commands);
354
+ logger.debug(`Successfully loaded plugin: ${pluginName} (dir: ${packageName}) with ${commandNames.length} commands:`, commandNames);
180
355
  }
181
356
  }
182
357
  catch (error) {
@@ -193,7 +368,7 @@ export async function loadInstalledPlugins() {
193
368
  * Get all loaded plugin commands
194
369
  */
195
370
  export function getPluginCommands() {
196
- const allCommands = {};
371
+ const allCommands = Object.create(null);
197
372
  for (const plugin of loadedPlugins.values()) {
198
373
  Object.assign(allCommands, plugin.commands);
199
374
  }
@@ -202,10 +377,23 @@ export function getPluginCommands() {
202
377
  /**
203
378
  * Execute a plugin command if it exists
204
379
  */
205
- export async function executePluginCommand(commandName, args) {
380
+ export async function executePluginCommand(commandName, args, flags) {
206
381
  const commands = getPluginCommands();
207
- if (commands[commandName]) {
208
- await commands[commandName](args);
382
+ const cmd = Object.hasOwn(commands, commandName)
383
+ ? commands[commandName]
384
+ : undefined;
385
+ if (cmd) {
386
+ if (typeof cmd === "function") {
387
+ if (flags !== undefined) {
388
+ await cmd(args, flags);
389
+ }
390
+ else {
391
+ await cmd(args);
392
+ }
393
+ }
394
+ else {
395
+ await cmd.handler(args, flags);
396
+ }
209
397
  return true;
210
398
  }
211
399
  return false;
@@ -215,7 +403,7 @@ export async function executePluginCommand(commandName, args) {
215
403
  */
216
404
  export function isPluginCommand(commandName) {
217
405
  const commands = getPluginCommands();
218
- return commandName in commands;
406
+ return Object.hasOwn(commands, commandName);
219
407
  }
220
408
  /**
221
409
  * Get list of all plugin command names
@@ -227,17 +415,36 @@ export function getPluginCommandsInfo() {
227
415
  const infos = [];
228
416
  for (const plugin of loadedPlugins.values()) {
229
417
  for (const commandName of Object.keys(plugin.commands)) {
418
+ const meta = plugin.metadata?.commands?.[commandName];
230
419
  infos.push({
231
420
  commandName,
232
421
  pluginName: plugin.name,
233
- description: plugin.metadata?.commands?.[commandName]?.description,
234
- examples: plugin.metadata?.commands?.[commandName]?.examples,
235
- subcommands: plugin.metadata?.commands?.[commandName]?.subcommands,
422
+ description: meta?.description,
423
+ helpDescription: meta?.helpDescription,
424
+ examples: meta?.examples,
425
+ subcommands: meta?.subcommands,
426
+ passthrough: meta?.passthrough === true ? true : undefined,
427
+ passthroughHint: meta?.passthroughHint,
428
+ flagsHint: meta?.flagsHint,
236
429
  });
237
430
  }
238
431
  }
239
432
  return infos;
240
433
  }
434
+ /**
435
+ * True if the named command is a registered passthrough plugin command
436
+ * (#366). Used by the dispatcher to gate the strip-and-forward path.
437
+ */
438
+ export function isPassthroughPluginCommand(commandName) {
439
+ for (const plugin of loadedPlugins.values()) {
440
+ if (!Object.hasOwn(plugin.commands, commandName))
441
+ continue;
442
+ const meta = plugin.metadata?.commands?.[commandName];
443
+ if (meta?.passthrough === true)
444
+ return true;
445
+ }
446
+ return false;
447
+ }
241
448
  /**
242
449
  * Clear all loaded plugins (useful for testing and after uninstall)
243
450
  */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Pure helpers extracted from `src/commands/plugins.ts` so tests can
3
+ * import them without violating the test→commands import boundary
4
+ * (#291). Plugin command handlers in `src/commands/plugins.ts` re-import
5
+ * these.
6
+ */
7
+ /**
8
+ * Get installed plugin version from package.json
9
+ */
10
+ export declare function getInstalledPluginVersion(nodeModulesPath: string, packageName: string): string | null;
11
+ /**
12
+ * Extract version from a registry source like package@version
13
+ */
14
+ export declare function getVersionFromSource(source: string, packageName: string): string | null;
15
+ //# sourceMappingURL=plugin-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-version.d.ts","sourceRoot":"","sources":["../src/plugin-version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAcf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAQf"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Pure helpers extracted from `src/commands/plugins.ts` so tests can
3
+ * import them without violating the test→commands import boundary
4
+ * (#291). Plugin command handlers in `src/commands/plugins.ts` re-import
5
+ * these.
6
+ */
7
+ import { existsSync, readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ /**
10
+ * Get installed plugin version from package.json
11
+ */
12
+ export function getInstalledPluginVersion(nodeModulesPath, packageName) {
13
+ const packagePath = join(nodeModulesPath, ...packageName.split("/"));
14
+ const packageJsonPath = join(packagePath, "package.json");
15
+ if (!existsSync(packageJsonPath)) {
16
+ return null;
17
+ }
18
+ try {
19
+ const pkgJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
20
+ return typeof pkgJson.version === "string" ? pkgJson.version : null;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /**
27
+ * Extract version from a registry source like package@version
28
+ */
29
+ export function getVersionFromSource(source, packageName) {
30
+ const packagePrefix = `${packageName}@`;
31
+ if (!source.startsWith(packagePrefix)) {
32
+ return null;
33
+ }
34
+ const version = source.slice(packagePrefix.length).trim();
35
+ return version.length > 0 ? version : null;
36
+ }
37
+ //# sourceMappingURL=plugin-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-version.js","sourceRoot":"","sources":["../src/plugin-version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACxC,eAAuB,EACvB,WAAmB;IAEnB,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAE1D,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,OAAO,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CACnC,MAAc,EACd,WAAmB;IAEnB,MAAM,aAAa,GAAG,GAAG,WAAW,GAAG,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC"}