agent-switchboard 0.2.2 → 0.3.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/README.md +68 -42
- package/dist/agents/registry.d.ts +0 -6
- package/dist/agents/registry.js +3 -13
- package/dist/agents/registry.js.map +1 -1
- package/dist/agents/trae.d.ts +16 -0
- package/dist/agents/trae.js +36 -0
- package/dist/agents/trae.js.map +1 -0
- package/dist/commands/distribution.d.ts +3 -4
- package/dist/commands/distribution.js +18 -116
- package/dist/commands/distribution.js.map +1 -1
- package/dist/config/application-config.d.ts +1 -1
- package/dist/config/application-config.js +2 -10
- package/dist/config/application-config.js.map +1 -1
- package/dist/config/mcp-config.js +1 -3
- package/dist/config/mcp-config.js.map +1 -1
- package/dist/config/paths.d.ts +24 -3
- package/dist/config/paths.js +63 -5
- package/dist/config/paths.js.map +1 -1
- package/dist/config/schemas.d.ts +331 -43
- package/dist/config/schemas.js +109 -15
- package/dist/config/schemas.js.map +1 -1
- package/dist/config/switchboard-config.js +0 -1
- package/dist/config/switchboard-config.js.map +1 -1
- package/dist/extensions/api.d.ts +49 -0
- package/dist/extensions/api.js +41 -0
- package/dist/extensions/api.js.map +1 -0
- package/dist/extensions/loader.d.ts +17 -0
- package/dist/extensions/loader.js +73 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/hooks/distribution.js +1 -16
- package/dist/hooks/distribution.js.map +1 -1
- package/dist/index.js +59 -113
- package/dist/index.js.map +1 -1
- package/dist/library/distribute-bundle.js +1 -19
- package/dist/library/distribute-bundle.js.map +1 -1
- package/dist/library/fs.d.ts +12 -0
- package/dist/library/fs.js +81 -0
- package/dist/library/fs.js.map +1 -1
- package/dist/library/sources.d.ts +6 -1
- package/dist/library/sources.js +73 -16
- package/dist/library/sources.js.map +1 -1
- package/dist/rules/agents.d.ts +0 -4
- package/dist/rules/agents.js +0 -8
- package/dist/rules/agents.js.map +1 -1
- package/dist/rules/distribution.d.ts +1 -2
- package/dist/rules/distribution.js +20 -71
- package/dist/rules/distribution.js.map +1 -1
- package/dist/skills/distribution.d.ts +0 -22
- package/dist/skills/distribution.js +84 -157
- package/dist/skills/distribution.js.map +1 -1
- package/dist/skills/importer.js +2 -33
- package/dist/skills/importer.js.map +1 -1
- package/dist/subagents/codex-distribute.d.ts +13 -0
- package/dist/subagents/codex-distribute.js +273 -0
- package/dist/subagents/codex-distribute.js.map +1 -0
- package/dist/subagents/distribution.d.ts +3 -4
- package/dist/subagents/distribution.js +30 -410
- package/dist/subagents/distribution.js.map +1 -1
- package/dist/targets/builtin/claude-code.d.ts +2 -0
- package/dist/targets/builtin/claude-code.js +73 -0
- package/dist/targets/builtin/claude-code.js.map +1 -0
- package/dist/targets/builtin/claude-desktop.d.ts +2 -0
- package/dist/targets/builtin/claude-desktop.js +10 -0
- package/dist/targets/builtin/claude-desktop.js.map +1 -0
- package/dist/targets/builtin/codex.d.ts +3 -0
- package/dist/targets/builtin/codex.js +57 -0
- package/dist/targets/builtin/codex.js.map +1 -0
- package/dist/targets/builtin/common.d.ts +22 -0
- package/dist/targets/builtin/common.js +55 -0
- package/dist/targets/builtin/common.js.map +1 -0
- package/dist/targets/builtin/cursor.d.ts +2 -0
- package/dist/targets/builtin/cursor.js +95 -0
- package/dist/targets/builtin/cursor.js.map +1 -0
- package/dist/targets/builtin/gemini.d.ts +2 -0
- package/dist/targets/builtin/gemini.js +62 -0
- package/dist/targets/builtin/gemini.js.map +1 -0
- package/dist/targets/builtin/index.d.ts +10 -0
- package/dist/targets/builtin/index.js +19 -0
- package/dist/targets/builtin/index.js.map +1 -0
- package/dist/targets/builtin/opencode.d.ts +2 -0
- package/dist/targets/builtin/opencode.js +67 -0
- package/dist/targets/builtin/opencode.js.map +1 -0
- package/dist/targets/builtin/trae.d.ts +3 -0
- package/dist/targets/builtin/trae.js +54 -0
- package/dist/targets/builtin/trae.js.map +1 -0
- package/dist/targets/dsl/compiler.d.ts +13 -0
- package/dist/targets/dsl/compiler.js +215 -0
- package/dist/targets/dsl/compiler.js.map +1 -0
- package/dist/targets/dsl/index.d.ts +2 -0
- package/dist/targets/dsl/index.js +3 -0
- package/dist/targets/dsl/index.js.map +1 -0
- package/dist/targets/dsl/transforms.d.ts +77 -0
- package/dist/targets/dsl/transforms.js +159 -0
- package/dist/targets/dsl/transforms.js.map +1 -0
- package/dist/targets/init.d.ts +14 -0
- package/dist/targets/init.js +28 -0
- package/dist/targets/init.js.map +1 -0
- package/dist/targets/registry.d.ts +36 -0
- package/dist/targets/registry.js +97 -0
- package/dist/targets/registry.js.map +1 -0
- package/dist/targets/types.d.ts +91 -0
- package/dist/targets/types.js +28 -0
- package/dist/targets/types.js.map +1 -0
- package/dist/ui/plugin-ui.d.ts +1 -1
- package/dist/ui/plugin-ui.js +5 -12
- package/dist/ui/plugin-ui.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,7 +10,6 @@ import { confirm } from '@inquirer/prompts';
|
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import ora from 'ora';
|
|
13
|
-
import { getAgentById } from './agents/registry.js';
|
|
14
13
|
import { distributeCommands } from './commands/distribution.js';
|
|
15
14
|
import { importCommandFromFile } from './commands/importer.js';
|
|
16
15
|
import { buildCommandInventory } from './commands/inventory.js';
|
|
@@ -21,12 +20,11 @@ import { getAgentsDir, getAgentsHome, getClaudeDir, getCodexDir, getCommandsDir,
|
|
|
21
20
|
import { loadSwitchboardConfig, loadSwitchboardConfigWithLayers, } from './config/switchboard-config.js';
|
|
22
21
|
import { distributeHooks } from './hooks/distribution.js';
|
|
23
22
|
import { loadHookLibrary } from './hooks/library.js';
|
|
24
|
-
import { ensureLibraryDirectories, writeFileSecure } from './library/fs.js';
|
|
23
|
+
import { copyDirRecursive, ensureLibraryDirectories, isDir, isFile, listFilesRecursively, writeFileSecure, } from './library/fs.js';
|
|
25
24
|
import { addLocalSource, addRemoteSource, getSources, inferSourceName, isGitUrl, parseGitUrl, removeSource, updateRemoteSources, validateSourcePath, } from './library/sources.js';
|
|
26
25
|
import { loadLibraryStateSection, loadMcpEnabledState, saveMcpEnabledState, } from './library/state.js';
|
|
27
26
|
import { readMarketplace } from './marketplace/reader.js';
|
|
28
27
|
import { buildPluginIndex } from './plugins/index.js';
|
|
29
|
-
import { RULE_SUPPORTED_AGENTS } from './rules/agents.js';
|
|
30
28
|
import { composeActiveRules } from './rules/composer.js';
|
|
31
29
|
import { distributeRules, listIndirectAgents, listPerFileAgents, listUnsupportedAgents, } from './rules/distribution.js';
|
|
32
30
|
import { buildRuleInventory } from './rules/inventory.js';
|
|
@@ -38,6 +36,8 @@ import { buildSkillInventory } from './skills/inventory.js';
|
|
|
38
36
|
import { distributeSubagents } from './subagents/distribution.js';
|
|
39
37
|
import { importSubagentFromFile } from './subagents/importer.js';
|
|
40
38
|
import { buildSubagentInventory } from './subagents/inventory.js';
|
|
39
|
+
import { initTargets } from './targets/init.js';
|
|
40
|
+
import { getTargetById, getTargetsForSection } from './targets/registry.js';
|
|
41
41
|
import { showCommandSelector } from './ui/command-ui.js';
|
|
42
42
|
import { showHookSelector } from './ui/hook-ui.js';
|
|
43
43
|
import { showMcpServerUI } from './ui/mcp-ui.js';
|
|
@@ -75,6 +75,7 @@ program
|
|
|
75
75
|
const scope = resolveScope(options);
|
|
76
76
|
const loadOptions = scopeToLoadOptions(scope);
|
|
77
77
|
const { config, layers } = loadSwitchboardConfigWithLayers(loadOptions);
|
|
78
|
+
await initTargets(config);
|
|
78
79
|
console.log(chalk.yellow('⚠ Sync overwrites agent config without diff.'));
|
|
79
80
|
console.log();
|
|
80
81
|
if (options.update !== false) {
|
|
@@ -110,17 +111,14 @@ program
|
|
|
110
111
|
console.log(chalk.blue('Inventory:'));
|
|
111
112
|
{
|
|
112
113
|
const sections = ['mcp', 'rules', 'commands', 'agents', 'skills', 'hooks'];
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
: ['claude-code', 'codex', 'gemini', 'opencode', 'cursor'],
|
|
122
|
-
hooks: ['claude-code'],
|
|
123
|
-
};
|
|
114
|
+
const sectionPlatforms = {};
|
|
115
|
+
for (const s of sections) {
|
|
116
|
+
let ids = getTargetsForSection(s).map((t) => t.id);
|
|
117
|
+
if (s === 'skills' && cursorSkillsDeduped) {
|
|
118
|
+
ids = ids.filter((id) => id !== 'cursor');
|
|
119
|
+
}
|
|
120
|
+
sectionPlatforms[s] = ids;
|
|
121
|
+
}
|
|
124
122
|
const termWidth = process.stdout.columns || 80;
|
|
125
123
|
const maxSectionLen = Math.max(...sections.map((s) => s.length));
|
|
126
124
|
const maxCountLen = Math.max(...sections.map((s) => `(${config[s].enabled.length})`.length));
|
|
@@ -185,9 +183,7 @@ program
|
|
|
185
183
|
// Show enabled plugins summary
|
|
186
184
|
{
|
|
187
185
|
const pluginIndex = buildPluginIndex();
|
|
188
|
-
const enabledPluginRefs =
|
|
189
|
-
.filter(([, v]) => v === true)
|
|
190
|
-
.map(([k]) => k);
|
|
186
|
+
const enabledPluginRefs = config.plugins.enabled;
|
|
191
187
|
if (enabledPluginRefs.length > 0) {
|
|
192
188
|
const names = enabledPluginRefs
|
|
193
189
|
.map((pid) => {
|
|
@@ -286,22 +282,6 @@ program
|
|
|
286
282
|
process.exit(1);
|
|
287
283
|
}
|
|
288
284
|
});
|
|
289
|
-
function isDir(p) {
|
|
290
|
-
try {
|
|
291
|
-
return fs.existsSync(p) && fs.statSync(p).isDirectory();
|
|
292
|
-
}
|
|
293
|
-
catch {
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
function isFile(p) {
|
|
298
|
-
try {
|
|
299
|
-
return fs.existsSync(p) && fs.statSync(p).isFile();
|
|
300
|
-
}
|
|
301
|
-
catch {
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
285
|
function resolveScope(input) {
|
|
306
286
|
if (!input)
|
|
307
287
|
return undefined;
|
|
@@ -368,26 +348,6 @@ function defaultSkillSourceDir(platform) {
|
|
|
368
348
|
return path.join(getCursorDir(), 'skills');
|
|
369
349
|
}
|
|
370
350
|
}
|
|
371
|
-
function listFilesRecursively(root, filterExts) {
|
|
372
|
-
const out = [];
|
|
373
|
-
const exts = new Set(filterExts.map((e) => e.toLowerCase()));
|
|
374
|
-
const walk = (dir) => {
|
|
375
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
376
|
-
for (const entry of entries) {
|
|
377
|
-
const abs = path.join(dir, entry.name);
|
|
378
|
-
if (entry.isDirectory()) {
|
|
379
|
-
walk(abs);
|
|
380
|
-
}
|
|
381
|
-
else if (entry.isFile()) {
|
|
382
|
-
const ext = path.extname(entry.name).toLowerCase();
|
|
383
|
-
if (exts.has(ext))
|
|
384
|
-
out.push(abs);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
};
|
|
388
|
-
walk(root);
|
|
389
|
-
return out;
|
|
390
|
-
}
|
|
391
351
|
async function confirmOverwrite(filePath, force) {
|
|
392
352
|
if (!fs.existsSync(filePath))
|
|
393
353
|
return true;
|
|
@@ -395,29 +355,6 @@ async function confirmOverwrite(filePath, force) {
|
|
|
395
355
|
return true;
|
|
396
356
|
return await confirm({ message: `File exists: ${filePath}. Overwrite?`, default: false });
|
|
397
357
|
}
|
|
398
|
-
function copyDirRecursive(src, dest) {
|
|
399
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
400
|
-
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
401
|
-
for (const entry of entries) {
|
|
402
|
-
const srcPath = path.join(src, entry.name);
|
|
403
|
-
const destPath = path.join(dest, entry.name);
|
|
404
|
-
if (entry.isDirectory()) {
|
|
405
|
-
copyDirRecursive(srcPath, destPath);
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
fs.copyFileSync(srcPath, destPath);
|
|
409
|
-
// Preserve executable permissions
|
|
410
|
-
try {
|
|
411
|
-
const mode = fs.statSync(srcPath).mode;
|
|
412
|
-
if (mode & 0o111)
|
|
413
|
-
fs.chmodSync(destPath, mode & 0o777);
|
|
414
|
-
}
|
|
415
|
-
catch {
|
|
416
|
-
// Ignore
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
358
|
/**
|
|
422
359
|
* Extract hooks from Claude Code's ~/.claude/settings.json and import as a
|
|
423
360
|
* bundle into ~/.asb/hooks/. Copies referenced script files if they exist
|
|
@@ -653,7 +590,7 @@ ruleCommand
|
|
|
653
590
|
console.log();
|
|
654
591
|
printAgentSyncStatus({
|
|
655
592
|
agentSync: inventory.state.agentSync,
|
|
656
|
-
agents:
|
|
593
|
+
agents: getTargetsForSection('rules').map((t) => t.id),
|
|
657
594
|
});
|
|
658
595
|
const unsupportedAgents = listUnsupportedAgents();
|
|
659
596
|
if (unsupportedAgents.length > 0) {
|
|
@@ -680,6 +617,7 @@ ruleCommand.action(async (options) => {
|
|
|
680
617
|
try {
|
|
681
618
|
const scope = resolveScope(options);
|
|
682
619
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
620
|
+
await initTargets(config);
|
|
683
621
|
const selection = await showRuleSelector({ scope, pageSize: config.ui.page_size });
|
|
684
622
|
if (!selection) {
|
|
685
623
|
return;
|
|
@@ -768,6 +706,7 @@ commandRoot.action(async (options) => {
|
|
|
768
706
|
try {
|
|
769
707
|
const scope = resolveScope(options);
|
|
770
708
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
709
|
+
await initTargets(config);
|
|
771
710
|
const selection = await showCommandSelector({ scope, pageSize: config.ui.page_size });
|
|
772
711
|
if (!selection)
|
|
773
712
|
return;
|
|
@@ -917,6 +856,7 @@ agentRoot.action(async (options) => {
|
|
|
917
856
|
try {
|
|
918
857
|
const scope = resolveScope(options);
|
|
919
858
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
859
|
+
await initTargets(config);
|
|
920
860
|
const selection = await showSubagentSelector({ scope, pageSize: config.ui.page_size });
|
|
921
861
|
if (!selection)
|
|
922
862
|
return;
|
|
@@ -1064,6 +1004,7 @@ skillRoot.action(async (options) => {
|
|
|
1064
1004
|
try {
|
|
1065
1005
|
const scope = resolveScope(options);
|
|
1066
1006
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1007
|
+
await initTargets(config);
|
|
1067
1008
|
const selection = await showSkillSelector({ scope, pageSize: config.ui.page_size });
|
|
1068
1009
|
if (!selection)
|
|
1069
1010
|
return;
|
|
@@ -1365,6 +1306,7 @@ hookRoot
|
|
|
1365
1306
|
async function applyToAgents(scope, enabledServerNames, options) {
|
|
1366
1307
|
const mcpConfig = loadMcpConfigWithPlugins();
|
|
1367
1308
|
const switchboardConfig = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1309
|
+
await initTargets(switchboardConfig);
|
|
1368
1310
|
const useSpinner = options?.useSpinner ?? true;
|
|
1369
1311
|
const results = [];
|
|
1370
1312
|
if (switchboardConfig.applications.active.length === 0) {
|
|
@@ -1395,7 +1337,18 @@ async function applyToAgents(scope, enabledServerNames, options) {
|
|
|
1395
1337
|
const activeSet = new Set(agentActiveServers);
|
|
1396
1338
|
const enabledServers = Object.fromEntries(Object.entries(mcpConfig.mcpServers).filter(([name]) => activeSet.has(name)));
|
|
1397
1339
|
const configToApply = { mcpServers: enabledServers };
|
|
1398
|
-
const
|
|
1340
|
+
const target = getTargetById(agentId);
|
|
1341
|
+
if (!target?.mcp) {
|
|
1342
|
+
persist(chalk.yellow('⚠'), `${chalk.cyan(agentId)} - no MCP handler (skipped)`);
|
|
1343
|
+
results.push({
|
|
1344
|
+
application: agentId,
|
|
1345
|
+
filePath: '(unknown)',
|
|
1346
|
+
status: 'skipped',
|
|
1347
|
+
reason: 'no MCP handler',
|
|
1348
|
+
});
|
|
1349
|
+
continue;
|
|
1350
|
+
}
|
|
1351
|
+
const mcpHandler = target.mcp;
|
|
1399
1352
|
const readFileSafe = (p) => {
|
|
1400
1353
|
try {
|
|
1401
1354
|
return fs.readFileSync(p, 'utf-8');
|
|
@@ -1404,11 +1357,10 @@ async function applyToAgents(scope, enabledServerNames, options) {
|
|
|
1404
1357
|
return null;
|
|
1405
1358
|
}
|
|
1406
1359
|
};
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
const projectPath = agent.projectConfigPath?.(scope.project) ?? 'project config';
|
|
1360
|
+
if (scope?.project && mcpHandler.applyProjectConfig) {
|
|
1361
|
+
const projectPath = mcpHandler.projectConfigPath?.(scope.project) ?? 'project config';
|
|
1410
1362
|
const before = readFileSafe(projectPath);
|
|
1411
|
-
|
|
1363
|
+
mcpHandler.applyProjectConfig(scope.project, configToApply);
|
|
1412
1364
|
const after = readFileSafe(projectPath);
|
|
1413
1365
|
const changed = before !== after;
|
|
1414
1366
|
persist(chalk.green('✓'), `${chalk.cyan(agentId)} ${chalk.dim(shortenPath(projectPath))}`);
|
|
@@ -1420,9 +1372,9 @@ async function applyToAgents(scope, enabledServerNames, options) {
|
|
|
1420
1372
|
});
|
|
1421
1373
|
}
|
|
1422
1374
|
else {
|
|
1423
|
-
const configPath =
|
|
1375
|
+
const configPath = mcpHandler.configPath();
|
|
1424
1376
|
const before = readFileSafe(configPath);
|
|
1425
|
-
|
|
1377
|
+
mcpHandler.applyConfig(configToApply);
|
|
1426
1378
|
const after = readFileSafe(configPath);
|
|
1427
1379
|
const changed = before !== after;
|
|
1428
1380
|
persist(chalk.green('✓'), `${chalk.cyan(agentId)} ${chalk.dim(shortenPath(configPath))}`);
|
|
@@ -1518,21 +1470,22 @@ pluginRoot
|
|
|
1518
1470
|
const index = buildPluginIndex();
|
|
1519
1471
|
const scope = resolveScope(options);
|
|
1520
1472
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1521
|
-
const
|
|
1473
|
+
const enabledList = config.plugins.enabled;
|
|
1474
|
+
const enabledSet = new Set(enabledList);
|
|
1522
1475
|
if (options.json) {
|
|
1523
1476
|
console.log(JSON.stringify(index.plugins.map((p) => {
|
|
1524
1477
|
const ref = p.meta.sourceKind === 'marketplace' ? `${p.id}@${p.meta.sourceName}` : p.id;
|
|
1525
1478
|
return {
|
|
1526
1479
|
id: p.id,
|
|
1527
1480
|
ref,
|
|
1528
|
-
enabled:
|
|
1481
|
+
enabled: enabledSet.has(ref),
|
|
1529
1482
|
...p.meta,
|
|
1530
1483
|
components: Object.fromEntries(Object.entries(p.components).map(([k, v]) => [k, v.length])),
|
|
1531
1484
|
};
|
|
1532
1485
|
}), null, 2));
|
|
1533
1486
|
return;
|
|
1534
1487
|
}
|
|
1535
|
-
printPluginList(index.plugins,
|
|
1488
|
+
printPluginList(index.plugins, enabledList);
|
|
1536
1489
|
}
|
|
1537
1490
|
catch (error) {
|
|
1538
1491
|
if (error instanceof Error) {
|
|
@@ -1569,7 +1522,7 @@ function pluginEnableAction(id, options) {
|
|
|
1569
1522
|
try {
|
|
1570
1523
|
const scope = resolveScope(options);
|
|
1571
1524
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1572
|
-
if (config.plugins.enabled
|
|
1525
|
+
if (config.plugins.enabled.includes(id)) {
|
|
1573
1526
|
console.log(chalk.yellow(`⚠ Plugin "${id}" is already enabled.`));
|
|
1574
1527
|
return;
|
|
1575
1528
|
}
|
|
@@ -1583,7 +1536,7 @@ function pluginEnableAction(id, options) {
|
|
|
1583
1536
|
...layer,
|
|
1584
1537
|
plugins: {
|
|
1585
1538
|
...(layer.plugins ?? {}),
|
|
1586
|
-
enabled:
|
|
1539
|
+
enabled: [...(layer.plugins?.enabled ?? []), id],
|
|
1587
1540
|
},
|
|
1588
1541
|
}), scopeToLoadOptions(scope));
|
|
1589
1542
|
console.log(chalk.green(`✓ Plugin "${id}" enabled.`));
|
|
@@ -1599,19 +1552,15 @@ function pluginDisableAction(id, options) {
|
|
|
1599
1552
|
try {
|
|
1600
1553
|
const scope = resolveScope(options);
|
|
1601
1554
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1602
|
-
if (config.plugins.enabled
|
|
1603
|
-
console.log(chalk.yellow(`⚠ Plugin "${id}" is not
|
|
1604
|
-
return;
|
|
1605
|
-
}
|
|
1606
|
-
if (config.plugins.enabled[id] === false) {
|
|
1607
|
-
console.log(chalk.yellow(`⚠ Plugin "${id}" is already disabled.`));
|
|
1555
|
+
if (!config.plugins.enabled.includes(id)) {
|
|
1556
|
+
console.log(chalk.yellow(`⚠ Plugin "${id}" is not enabled.`));
|
|
1608
1557
|
return;
|
|
1609
1558
|
}
|
|
1610
1559
|
updateConfigLayer((layer) => ({
|
|
1611
1560
|
...layer,
|
|
1612
1561
|
plugins: {
|
|
1613
1562
|
...(layer.plugins ?? {}),
|
|
1614
|
-
enabled:
|
|
1563
|
+
enabled: (layer.plugins?.enabled ?? []).filter((x) => x !== id),
|
|
1615
1564
|
},
|
|
1616
1565
|
}), scopeToLoadOptions(scope));
|
|
1617
1566
|
console.log(chalk.green(`✓ Plugin "${id}" disabled.`));
|
|
@@ -1627,18 +1576,17 @@ function pluginUninstallAction(id, options) {
|
|
|
1627
1576
|
try {
|
|
1628
1577
|
const scope = resolveScope(options);
|
|
1629
1578
|
const config = loadSwitchboardConfig(scopeToLoadOptions(scope));
|
|
1630
|
-
if (config.plugins.enabled
|
|
1631
|
-
console.log(chalk.yellow(`⚠ Plugin "${id}" is not
|
|
1579
|
+
if (!config.plugins.enabled.includes(id)) {
|
|
1580
|
+
console.log(chalk.yellow(`⚠ Plugin "${id}" is not enabled.`));
|
|
1632
1581
|
return;
|
|
1633
1582
|
}
|
|
1634
|
-
updateConfigLayer((layer) => {
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
}, scopeToLoadOptions(scope));
|
|
1583
|
+
updateConfigLayer((layer) => ({
|
|
1584
|
+
...layer,
|
|
1585
|
+
plugins: {
|
|
1586
|
+
...(layer.plugins ?? {}),
|
|
1587
|
+
enabled: (layer.plugins?.enabled ?? []).filter((x) => x !== id),
|
|
1588
|
+
},
|
|
1589
|
+
}), scopeToLoadOptions(scope));
|
|
1642
1590
|
console.log(chalk.green(`✓ Plugin "${id}" uninstalled.`));
|
|
1643
1591
|
}
|
|
1644
1592
|
catch (error) {
|
|
@@ -1652,27 +1600,25 @@ const pluginScopeOpts = [
|
|
|
1652
1600
|
['-p, --profile <name>', 'Profile configuration to use'],
|
|
1653
1601
|
['--project <path>', 'Project directory containing .asb.toml'],
|
|
1654
1602
|
];
|
|
1655
|
-
const enableCmd = pluginRoot
|
|
1656
|
-
.command('enable <id>')
|
|
1657
|
-
.description('Enable a plugin (set plugins.enabled to true)');
|
|
1603
|
+
const enableCmd = pluginRoot.command('enable <id>').description('Add a plugin to the enabled list');
|
|
1658
1604
|
for (const [flag, desc] of pluginScopeOpts)
|
|
1659
1605
|
enableCmd.option(flag, desc);
|
|
1660
1606
|
enableCmd.action(pluginEnableAction);
|
|
1661
1607
|
const installCmd = pluginRoot
|
|
1662
1608
|
.command('install <id>')
|
|
1663
|
-
.description('
|
|
1609
|
+
.description('Add a plugin to the enabled list (alias for enable)');
|
|
1664
1610
|
for (const [flag, desc] of pluginScopeOpts)
|
|
1665
1611
|
installCmd.option(flag, desc);
|
|
1666
1612
|
installCmd.action(pluginEnableAction);
|
|
1667
1613
|
const disableCmd = pluginRoot
|
|
1668
1614
|
.command('disable <id>')
|
|
1669
|
-
.description('
|
|
1615
|
+
.description('Remove a plugin from the enabled list');
|
|
1670
1616
|
for (const [flag, desc] of pluginScopeOpts)
|
|
1671
1617
|
disableCmd.option(flag, desc);
|
|
1672
1618
|
disableCmd.action(pluginDisableAction);
|
|
1673
1619
|
const uninstallCmd = pluginRoot
|
|
1674
1620
|
.command('uninstall <id>')
|
|
1675
|
-
.description('Remove a plugin from
|
|
1621
|
+
.description('Remove a plugin from the enabled list (alias for disable)');
|
|
1676
1622
|
for (const [flag, desc] of pluginScopeOpts)
|
|
1677
1623
|
uninstallCmd.option(flag, desc);
|
|
1678
1624
|
uninstallCmd.action(pluginUninstallAction);
|
|
@@ -1906,7 +1852,7 @@ program
|
|
|
1906
1852
|
.action(() => {
|
|
1907
1853
|
console.error(chalk.red('✗ `asb source` has been removed.\n' +
|
|
1908
1854
|
' Sources are now managed under `asb plugin marketplace`.\n' +
|
|
1909
|
-
' Config has moved from [library.sources] to [plugins
|
|
1855
|
+
' Config has moved from [library.sources] to [plugins].\n' +
|
|
1910
1856
|
' Run `asb plugin marketplace --help` for usage.'));
|
|
1911
1857
|
process.exit(1);
|
|
1912
1858
|
});
|