From 51d08664082f4b0cee8a12553202c66fee76bd2a Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Fri, 24 Jul 2026 11:10:47 +0530 Subject: [PATCH] feat: warn and suggest install for opt-in launch commands Add an init hook that intercepts commands belonging to demoted (now opt-in) plugins when the plugin is not installed. For launch:* it prints a warning and the install command (csdx plugins:install @contentstack/cli-launch) instead of a generic "command not found", then exits. If the plugin is installed, the hook is a no-op and commands run normally. Driven by a DEMOTED_PLUGINS map for easy extension. Co-Authored-By: Claude Opus 4.8 --- packages/contentstack/package.json | 3 +- .../src/hooks/init/opt-in-plugin-guide.ts | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 packages/contentstack/src/hooks/init/opt-in-plugin-guide.ts diff --git a/packages/contentstack/package.json b/packages/contentstack/package.json index 7c901df288..3ec743e825 100755 --- a/packages/contentstack/package.json +++ b/packages/contentstack/package.json @@ -156,7 +156,8 @@ ], "init": [ "./lib/hooks/init/context-init", - "./lib/hooks/init/utils-init" + "./lib/hooks/init/utils-init", + "./lib/hooks/init/opt-in-plugin-guide" ] } }, diff --git a/packages/contentstack/src/hooks/init/opt-in-plugin-guide.ts b/packages/contentstack/src/hooks/init/opt-in-plugin-guide.ts new file mode 100644 index 0000000000..8653eaf390 --- /dev/null +++ b/packages/contentstack/src/hooks/init/opt-in-plugin-guide.ts @@ -0,0 +1,38 @@ +import { Hook } from '@oclif/core'; +import { cliux } from '@contentstack/cli-utilities'; + +/** + * Commands whose plugins used to ship bundled with the CLI but are now opt-in. + * Keyed by oclif topic (the segment before the first `:` in a command id). + */ +const DEMOTED_PLUGINS: Record = { + launch: '@contentstack/cli-launch', +}; + +/** + * When a user runs a command belonging to a demoted (now opt-in) plugin that + * is not installed, warn them and point to the install command instead of + * letting the generic "command not found" handler report it as a typo. Runs on + * `init`, before command resolution, so it pre-empts `@oclif/plugin-not-found`. + */ +const hook: Hook<'init'> = async function (opts): Promise { + if (!opts.id) return; + + const topic = opts.id.split(':')[0]; + const pluginName = DEMOTED_PLUGINS[topic]; + if (!pluginName) return; + + // If the plugin is already installed, let normal command resolution proceed. + if (this.config.plugins.has(pluginName)) return; + + cliux.print( + `\nWarning: "${topic}" is now an opt-in plugin and is not installed, so "${topic}:*" commands are unavailable.`, + { color: 'yellow' }, + ); + cliux.print('\nInstall it to enable these commands:', { color: 'yellow' }); + cliux.print(` csdx plugins:install ${pluginName}\n`, { color: 'green' }); + + this.exit(127); +}; + +export default hook;