@bluealba/platform-cli 1.0.1 → 1.0.2
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 +277 -9
- package/docs/404.mdx +5 -0
- package/docs/architecture/api-explorer.mdx +478 -0
- package/docs/architecture/architecture-diagrams.mdx +12 -0
- package/docs/architecture/authentication-system.mdx +903 -0
- package/docs/architecture/authorization-system.mdx +886 -0
- package/docs/architecture/bootstrap.mdx +1442 -0
- package/docs/architecture/gateway-architecture.mdx +845 -0
- package/docs/architecture/multi-tenancy.mdx +1150 -0
- package/docs/architecture/overview.mdx +776 -0
- package/docs/architecture/scheduler.mdx +818 -0
- package/docs/architecture/shell.mdx +885 -0
- package/docs/architecture/ui-extension-points.mdx +781 -0
- package/docs/architecture/user-states.mdx +794 -0
- package/docs/development/overview.mdx +21 -0
- package/docs/development/workflow.mdx +914 -0
- package/docs/getting-started/core-concepts.mdx +892 -0
- package/docs/getting-started/installation.mdx +780 -0
- package/docs/getting-started/overview.mdx +83 -0
- package/docs/getting-started/quick-start.mdx +940 -0
- package/docs/guides/adding-documentation-sites.mdx +1367 -0
- package/docs/guides/creating-services.mdx +1736 -0
- package/docs/guides/creating-ui-modules.mdx +1860 -0
- package/docs/guides/identity-providers.mdx +1007 -0
- package/docs/guides/mermaid-diagrams.mdx +212 -0
- package/docs/guides/using-feature-flags.mdx +1059 -0
- package/docs/guides/working-with-rooms.mdx +566 -0
- package/docs/index.mdx +57 -0
- package/docs/platform-cli/commands.mdx +604 -0
- package/docs/platform-cli/overview.mdx +195 -0
- package/package.json +5 -2
- package/skills/ba-platform/platform-cli.skill.md +26 -0
- package/skills/ba-platform/platform.skill.md +35 -0
- package/templates/application-monorepo-template/gitignore +95 -0
- package/templates/bootstrap-service-template/gitignore +57 -0
- package/templates/bootstrap-service-template/src/main.ts +6 -16
- package/templates/customization-ui-module-template/gitignore +73 -0
- package/templates/nestjs-service-module-template/gitignore +56 -0
- package/templates/platform-init-template/{{platformName}}-core/gitignore +97 -0
- package/templates/react-ui-module-template/Dockerfile +1 -1
- package/templates/react-ui-module-template/caddy/Caddyfile +1 -1
- package/templates/react-ui-module-template/gitignore +72 -0
package/dist/index.js
CHANGED
|
@@ -213,7 +213,7 @@ import { join as join2, dirname as dirname2 } from "path";
|
|
|
213
213
|
|
|
214
214
|
// src/utils/template-engine.ts
|
|
215
215
|
import { readdir, readFile, writeFile, mkdir, copyFile, stat, chmod } from "fs/promises";
|
|
216
|
-
import { join, dirname, extname } from "path";
|
|
216
|
+
import { join, dirname, extname, basename } from "path";
|
|
217
217
|
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
218
218
|
".pem",
|
|
219
219
|
".crt",
|
|
@@ -239,6 +239,13 @@ function applyVariables(text, variables) {
|
|
|
239
239
|
}
|
|
240
240
|
return result;
|
|
241
241
|
}
|
|
242
|
+
function transformFilename(relativePath) {
|
|
243
|
+
const base = basename(relativePath);
|
|
244
|
+
if (base === "gitignore") {
|
|
245
|
+
return join(dirname(relativePath), ".gitignore");
|
|
246
|
+
}
|
|
247
|
+
return relativePath;
|
|
248
|
+
}
|
|
242
249
|
function isBinary(filePath) {
|
|
243
250
|
return BINARY_EXTENSIONS.has(extname(filePath).toLowerCase());
|
|
244
251
|
}
|
|
@@ -263,7 +270,7 @@ async function applyTemplate(config, onProgress) {
|
|
|
263
270
|
const relativePath = srcPath.slice(templateDir4.length + 1);
|
|
264
271
|
if (relativePath.endsWith(".gitkeep")) continue;
|
|
265
272
|
if (exclude.includes(relativePath)) continue;
|
|
266
|
-
const transformedRelative = applyVariables(relativePath, variables);
|
|
273
|
+
const transformedRelative = transformFilename(applyVariables(relativePath, variables));
|
|
267
274
|
const destPath = join(outputDir, transformedRelative);
|
|
268
275
|
await mkdir(dirname(destPath), { recursive: true });
|
|
269
276
|
if (isBinary(srcPath)) {
|
|
@@ -2047,8 +2054,8 @@ async function checkIdpProviders(layout) {
|
|
|
2047
2054
|
return { configured: false, providers: [], error: `gateway responded with ${response.status}` };
|
|
2048
2055
|
}
|
|
2049
2056
|
const data = await response.json();
|
|
2050
|
-
const
|
|
2051
|
-
return { configured:
|
|
2057
|
+
const providers2 = data.map((p) => ({ name: p.name, type: p.type, active: p.active }));
|
|
2058
|
+
return { configured: providers2.length > 0, providers: providers2 };
|
|
2052
2059
|
}
|
|
2053
2060
|
async function gatherStatus() {
|
|
2054
2061
|
const layout = await findPlatformLayout();
|
|
@@ -2268,6 +2275,91 @@ async function removePlatformAdmin(ruleId, logger) {
|
|
|
2268
2275
|
return true;
|
|
2269
2276
|
}
|
|
2270
2277
|
|
|
2278
|
+
// src/commands/install-ai-plugin/plugins/ba-platform/index.ts
|
|
2279
|
+
var baPlatformPlugin = {
|
|
2280
|
+
name: "ba-platform-plugin",
|
|
2281
|
+
description: "Blue Alba Platform knowledge and CLI skills for AI assistants",
|
|
2282
|
+
version: "1.0.0",
|
|
2283
|
+
skills: [
|
|
2284
|
+
{
|
|
2285
|
+
name: "platform",
|
|
2286
|
+
description: "Comprehensive Blue Alba Platform architecture and concepts knowledge",
|
|
2287
|
+
type: "skill",
|
|
2288
|
+
sourceFile: "skills/ba-platform/platform.skill.md"
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
name: "platform-cli",
|
|
2292
|
+
description: "Blue Alba Platform CLI commands and usage knowledge",
|
|
2293
|
+
type: "skill",
|
|
2294
|
+
sourceFile: "skills/ba-platform/platform-cli.skill.md"
|
|
2295
|
+
}
|
|
2296
|
+
]
|
|
2297
|
+
};
|
|
2298
|
+
|
|
2299
|
+
// src/commands/install-ai-plugin/plugins/registry.ts
|
|
2300
|
+
var pluginCatalog = [baPlatformPlugin];
|
|
2301
|
+
function findPlugin(name) {
|
|
2302
|
+
return pluginCatalog.find((p) => p.name === name);
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// src/commands/install-ai-plugin/install-ai-plugin.command.ts
|
|
2306
|
+
var INSTALL_AI_PLUGIN_COMMAND_NAME = "install-ai-plugin";
|
|
2307
|
+
var installAiPluginCommand = {
|
|
2308
|
+
name: INSTALL_AI_PLUGIN_COMMAND_NAME,
|
|
2309
|
+
description: "Install AI assistant plugins (skills, MCPs, hooks) for your AI provider"
|
|
2310
|
+
};
|
|
2311
|
+
async function installAiPlugin(params, context) {
|
|
2312
|
+
const { provider, docsSource, logger, confirmUpdate } = context;
|
|
2313
|
+
for (const pluginName of params.plugins) {
|
|
2314
|
+
const plugin = findPlugin(pluginName);
|
|
2315
|
+
if (!plugin) {
|
|
2316
|
+
logger.log(`Error: Plugin "${pluginName}" not found in catalog.`);
|
|
2317
|
+
continue;
|
|
2318
|
+
}
|
|
2319
|
+
const manifest = await provider.readManifest(pluginName);
|
|
2320
|
+
const diff = provider.calculateDiff(manifest, plugin);
|
|
2321
|
+
const hasStructuralChanges = diff.versionChanged || diff.newSkills.length > 0 || diff.removedSkills.length > 0;
|
|
2322
|
+
if (manifest && hasStructuralChanges) {
|
|
2323
|
+
logger.log(
|
|
2324
|
+
`Plugin "${pluginName}" is already installed (v${diff.currentVersion} \u2192 v${diff.targetVersion}).`
|
|
2325
|
+
);
|
|
2326
|
+
if (diff.newSkills.length > 0) {
|
|
2327
|
+
logger.log(` New skills: ${diff.newSkills.map((s) => s.name).join(", ")}`);
|
|
2328
|
+
}
|
|
2329
|
+
if (diff.removedSkills.length > 0) {
|
|
2330
|
+
logger.log(` Removed skills: ${diff.removedSkills.join(", ")}`);
|
|
2331
|
+
}
|
|
2332
|
+
if (diff.existingSkills.length > 0) {
|
|
2333
|
+
logger.log(` Updated skills: ${diff.existingSkills.map((s) => s.name).join(", ")}`);
|
|
2334
|
+
}
|
|
2335
|
+
if (!params.force && confirmUpdate) {
|
|
2336
|
+
const proceed = await confirmUpdate(diff, plugin);
|
|
2337
|
+
if (!proceed) {
|
|
2338
|
+
logger.log(`Skipped "${pluginName}".`);
|
|
2339
|
+
continue;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
for (const skillName of diff.removedSkills) {
|
|
2343
|
+
await provider.removeSkill(skillName, logger);
|
|
2344
|
+
}
|
|
2345
|
+
} else if (!manifest) {
|
|
2346
|
+
logger.log(`Installing plugin "${pluginName}" v${plugin.version}...`);
|
|
2347
|
+
}
|
|
2348
|
+
for (const skill of plugin.skills) {
|
|
2349
|
+
await provider.installSkill(skill, docsSource, logger);
|
|
2350
|
+
}
|
|
2351
|
+
await provider.writeManifest({
|
|
2352
|
+
plugin: pluginName,
|
|
2353
|
+
version: plugin.version,
|
|
2354
|
+
provider: provider.name,
|
|
2355
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2356
|
+
skills: plugin.skills.map((s) => s.name)
|
|
2357
|
+
});
|
|
2358
|
+
await provider.updatePermissions(docsSource, logger);
|
|
2359
|
+
logger.log(`Plugin "${pluginName}" v${plugin.version} installed successfully.`);
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2271
2363
|
// src/commands/registry.ts
|
|
2272
2364
|
var CommandRegistry = class {
|
|
2273
2365
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -2308,6 +2400,7 @@ for (const cmd of localScriptCommands) {
|
|
|
2308
2400
|
}
|
|
2309
2401
|
registry.register(statusCommand);
|
|
2310
2402
|
registry.register(managePlatformAdminsCommand);
|
|
2403
|
+
registry.register(installAiPluginCommand);
|
|
2311
2404
|
|
|
2312
2405
|
// src/app-state.ts
|
|
2313
2406
|
var APP_STATE = {
|
|
@@ -2405,12 +2498,12 @@ async function configureIdpUiController(ctx) {
|
|
|
2405
2498
|
ctx.log("Error: Cannot configure an IDP \u2014 no platform initialized in this directory.");
|
|
2406
2499
|
return;
|
|
2407
2500
|
}
|
|
2408
|
-
const
|
|
2501
|
+
const providers2 = getAllProviders();
|
|
2409
2502
|
const providerType = await ctx.select(
|
|
2410
2503
|
"Select IDP type:",
|
|
2411
|
-
|
|
2504
|
+
providers2.map((p) => ({ label: p.displayName, value: p.type }))
|
|
2412
2505
|
);
|
|
2413
|
-
const provider =
|
|
2506
|
+
const provider = providers2.find((p) => p.type === providerType);
|
|
2414
2507
|
const name = await ctx.prompt("Provider name:");
|
|
2415
2508
|
const issuer = await ctx.prompt("Issuer URL:");
|
|
2416
2509
|
const clientId = await ctx.prompt("Client ID:");
|
|
@@ -2819,6 +2912,153 @@ async function handleRemove(ctx) {
|
|
|
2819
2912
|
ctx.log(`Successfully removed ${successCount} of ${selected.length} admin(s).`);
|
|
2820
2913
|
}
|
|
2821
2914
|
|
|
2915
|
+
// src/services/install-ai-plugin.service.ts
|
|
2916
|
+
async function installAiPluginService(params, context) {
|
|
2917
|
+
await installAiPlugin(params, context);
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
// src/commands/install-ai-plugin/providers/claude.provider.ts
|
|
2921
|
+
import { homedir as homedir2 } from "os";
|
|
2922
|
+
import { join as join26 } from "path";
|
|
2923
|
+
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir3, rm } from "fs/promises";
|
|
2924
|
+
var ClaudeProvider = class {
|
|
2925
|
+
name = "claude";
|
|
2926
|
+
baseDir = join26(homedir2(), ".claude");
|
|
2927
|
+
getInstallPath(skillName) {
|
|
2928
|
+
return join26(this.baseDir, "skills", skillName, "SKILL.md");
|
|
2929
|
+
}
|
|
2930
|
+
manifestPath(pluginName) {
|
|
2931
|
+
return join26(this.baseDir, `${pluginName}.manifest.json`);
|
|
2932
|
+
}
|
|
2933
|
+
async readManifest(pluginName) {
|
|
2934
|
+
try {
|
|
2935
|
+
const content = await readFile10(this.manifestPath(pluginName), "utf-8");
|
|
2936
|
+
return JSON.parse(content);
|
|
2937
|
+
} catch {
|
|
2938
|
+
return null;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
async writeManifest(manifest) {
|
|
2942
|
+
await mkdir3(this.baseDir, { recursive: true });
|
|
2943
|
+
await writeFile9(
|
|
2944
|
+
this.manifestPath(manifest.plugin),
|
|
2945
|
+
JSON.stringify(manifest, null, 2),
|
|
2946
|
+
"utf-8"
|
|
2947
|
+
);
|
|
2948
|
+
}
|
|
2949
|
+
calculateDiff(manifest, plugin) {
|
|
2950
|
+
const installedSkills = manifest?.skills ?? [];
|
|
2951
|
+
const targetSkillNames = plugin.skills.map((s) => s.name);
|
|
2952
|
+
return {
|
|
2953
|
+
newSkills: plugin.skills.filter((s) => !installedSkills.includes(s.name)),
|
|
2954
|
+
removedSkills: installedSkills.filter((name) => !targetSkillNames.includes(name)),
|
|
2955
|
+
existingSkills: plugin.skills.filter((s) => installedSkills.includes(s.name)),
|
|
2956
|
+
versionChanged: manifest?.version !== plugin.version,
|
|
2957
|
+
currentVersion: manifest?.version ?? null,
|
|
2958
|
+
targetVersion: plugin.version
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
async installSkill(skill, docsSource, logger) {
|
|
2962
|
+
const sourcePath = docsSource.resolve(skill.sourceFile);
|
|
2963
|
+
let content = await readFile10(sourcePath, "utf-8");
|
|
2964
|
+
const docsPath = docsSource.resolve("docs");
|
|
2965
|
+
content = content.replaceAll("{{docsPath}}", docsPath);
|
|
2966
|
+
const installPath = this.getInstallPath(skill.name);
|
|
2967
|
+
await mkdir3(join26(installPath, ".."), { recursive: true });
|
|
2968
|
+
await writeFile9(installPath, content, "utf-8");
|
|
2969
|
+
logger.log(` Installed skill: ${installPath}`);
|
|
2970
|
+
}
|
|
2971
|
+
async removeSkill(skillName, logger) {
|
|
2972
|
+
const skillDir = join26(this.baseDir, "skills", skillName);
|
|
2973
|
+
try {
|
|
2974
|
+
await rm(skillDir, { recursive: true, force: true });
|
|
2975
|
+
logger.log(` Removed skill: ${skillDir}`);
|
|
2976
|
+
} catch {
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
async updatePermissions(docsSource, logger) {
|
|
2980
|
+
const settingsPath = join26(this.baseDir, "settings.json");
|
|
2981
|
+
const docsPath = docsSource.resolve("docs");
|
|
2982
|
+
let settings = {};
|
|
2983
|
+
try {
|
|
2984
|
+
const content = await readFile10(settingsPath, "utf-8");
|
|
2985
|
+
settings = JSON.parse(content);
|
|
2986
|
+
} catch {
|
|
2987
|
+
}
|
|
2988
|
+
const permissions = settings.permissions ?? {};
|
|
2989
|
+
const additionalDirectories = permissions.additionalDirectories ?? [];
|
|
2990
|
+
if (additionalDirectories.includes(docsPath)) {
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2993
|
+
permissions.additionalDirectories = [...additionalDirectories, docsPath];
|
|
2994
|
+
settings.permissions = permissions;
|
|
2995
|
+
await mkdir3(this.baseDir, { recursive: true });
|
|
2996
|
+
await writeFile9(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
2997
|
+
logger.log(` Granted read access to docs: ${docsPath}`);
|
|
2998
|
+
}
|
|
2999
|
+
};
|
|
3000
|
+
|
|
3001
|
+
// src/commands/install-ai-plugin/providers/index.ts
|
|
3002
|
+
var providers = {
|
|
3003
|
+
claude: () => new ClaudeProvider()
|
|
3004
|
+
};
|
|
3005
|
+
var providerNames = Object.keys(providers);
|
|
3006
|
+
function getProvider(name) {
|
|
3007
|
+
const factory = providers[name];
|
|
3008
|
+
if (!factory) {
|
|
3009
|
+
throw new Error(`Unknown AI provider: "${name}". Available: ${providerNames.join(", ")}`);
|
|
3010
|
+
}
|
|
3011
|
+
return factory();
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
// src/commands/install-ai-plugin/docs-source/local.docs-source.ts
|
|
3015
|
+
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
3016
|
+
import { join as join27, dirname as dirname12 } from "path";
|
|
3017
|
+
var packageRoot = join27(dirname12(fileURLToPath10(import.meta.url)), "..");
|
|
3018
|
+
var LocalDocsSource = class {
|
|
3019
|
+
resolve(relativePath) {
|
|
3020
|
+
return join27(packageRoot, relativePath);
|
|
3021
|
+
}
|
|
3022
|
+
};
|
|
3023
|
+
|
|
3024
|
+
// src/controllers/ui/install-ai-plugin.ui-controller.ts
|
|
3025
|
+
async function installAiPluginUiController(ctx) {
|
|
3026
|
+
const providerName = await ctx.select(
|
|
3027
|
+
"Select AI provider:",
|
|
3028
|
+
providerNames.map((name) => ({
|
|
3029
|
+
label: name.charAt(0).toUpperCase() + name.slice(1),
|
|
3030
|
+
value: name
|
|
3031
|
+
}))
|
|
3032
|
+
);
|
|
3033
|
+
const selectedPlugins = await ctx.multiselect(
|
|
3034
|
+
"Select plugins to install:",
|
|
3035
|
+
pluginCatalog.map((p) => ({
|
|
3036
|
+
label: `${p.name} \u2014 ${p.description}`,
|
|
3037
|
+
value: p.name
|
|
3038
|
+
}))
|
|
3039
|
+
);
|
|
3040
|
+
if (selectedPlugins.length === 0) {
|
|
3041
|
+
ctx.log("No plugins selected.");
|
|
3042
|
+
return;
|
|
3043
|
+
}
|
|
3044
|
+
const provider = getProvider(providerName);
|
|
3045
|
+
const docsSource = new LocalDocsSource();
|
|
3046
|
+
await installAiPluginService(
|
|
3047
|
+
{ provider: providerName, plugins: selectedPlugins },
|
|
3048
|
+
{
|
|
3049
|
+
provider,
|
|
3050
|
+
docsSource,
|
|
3051
|
+
logger: ctx,
|
|
3052
|
+
confirmUpdate: async (diff, plugin) => {
|
|
3053
|
+
return ctx.confirm(
|
|
3054
|
+
`Update "${plugin.name}" from v${diff.currentVersion} to v${diff.targetVersion}?`,
|
|
3055
|
+
true
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
|
|
2822
3062
|
// src/controllers/ui/registry.ts
|
|
2823
3063
|
var uiControllers = /* @__PURE__ */ new Map([
|
|
2824
3064
|
[CREATE_APPLICATION_COMMAND_NAME, createApplicationUiController],
|
|
@@ -2832,7 +3072,8 @@ var uiControllers = /* @__PURE__ */ new Map([
|
|
|
2832
3072
|
[START_COMMAND_NAME, createLocalScriptUiController(START_COMMAND_NAME)],
|
|
2833
3073
|
[STOP_COMMAND_NAME, createLocalScriptUiController(STOP_COMMAND_NAME)],
|
|
2834
3074
|
[DESTROY_COMMAND_NAME, createLocalScriptUiController(DESTROY_COMMAND_NAME)],
|
|
2835
|
-
[MANAGE_PLATFORM_ADMINS_COMMAND_NAME, managePlatformAdminsUiController]
|
|
3075
|
+
[MANAGE_PLATFORM_ADMINS_COMMAND_NAME, managePlatformAdminsUiController],
|
|
3076
|
+
[INSTALL_AI_PLUGIN_COMMAND_NAME, installAiPluginUiController]
|
|
2836
3077
|
]);
|
|
2837
3078
|
|
|
2838
3079
|
// src/hooks/use-command-runner.ts
|
|
@@ -3463,6 +3704,32 @@ async function managePlatformAdminsCliController(args2) {
|
|
|
3463
3704
|
}
|
|
3464
3705
|
}
|
|
3465
3706
|
|
|
3707
|
+
// src/controllers/cli/install-ai-plugin.cli-controller.ts
|
|
3708
|
+
async function installAiPluginCliController(args2) {
|
|
3709
|
+
const { provider: providerName, plugins: pluginsArg, force } = args2;
|
|
3710
|
+
if (!providerName) {
|
|
3711
|
+
console.error('Error: "provider" argument is required (e.g., provider=claude).');
|
|
3712
|
+
process.exit(1);
|
|
3713
|
+
}
|
|
3714
|
+
if (!pluginsArg) {
|
|
3715
|
+
console.error(
|
|
3716
|
+
'Error: "plugins" argument is required (e.g., plugins=ba-platform-plugin).'
|
|
3717
|
+
);
|
|
3718
|
+
process.exit(1);
|
|
3719
|
+
}
|
|
3720
|
+
const plugins = pluginsArg.split(",").map((s) => s.trim());
|
|
3721
|
+
const provider = getProvider(providerName);
|
|
3722
|
+
const docsSource = new LocalDocsSource();
|
|
3723
|
+
await installAiPluginService(
|
|
3724
|
+
{ provider: providerName, plugins, force: force === "true" },
|
|
3725
|
+
{
|
|
3726
|
+
provider,
|
|
3727
|
+
docsSource,
|
|
3728
|
+
logger: { log: console.log }
|
|
3729
|
+
}
|
|
3730
|
+
);
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3466
3733
|
// src/controllers/cli/registry.ts
|
|
3467
3734
|
var cliControllers = /* @__PURE__ */ new Map([
|
|
3468
3735
|
[CREATE_APPLICATION_COMMAND_NAME, createApplicationCliController],
|
|
@@ -3476,7 +3743,8 @@ var cliControllers = /* @__PURE__ */ new Map([
|
|
|
3476
3743
|
[START_COMMAND_NAME, createLocalScriptCliController(START_COMMAND_NAME)],
|
|
3477
3744
|
[STOP_COMMAND_NAME, createLocalScriptCliController(STOP_COMMAND_NAME)],
|
|
3478
3745
|
[DESTROY_COMMAND_NAME, createLocalScriptCliController(DESTROY_COMMAND_NAME)],
|
|
3479
|
-
[MANAGE_PLATFORM_ADMINS_COMMAND_NAME, managePlatformAdminsCliController]
|
|
3746
|
+
[MANAGE_PLATFORM_ADMINS_COMMAND_NAME, managePlatformAdminsCliController],
|
|
3747
|
+
[INSTALL_AI_PLUGIN_COMMAND_NAME, installAiPluginCliController]
|
|
3480
3748
|
]);
|
|
3481
3749
|
|
|
3482
3750
|
// src/utils/parse-args.ts
|