argsbarg 5.0.3 → 5.1.1
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/CHANGELOG.md +19 -1
- package/docs/cli-program.md +4 -4
- package/docs/config-schema.md +9 -9
- package/docs/configure.md +5 -1
- package/docs/mcp.md +1 -1
- package/examples/full-example/README.md +2 -2
- package/examples/full-example/src/program.ts +0 -3
- package/index.d.ts +2 -2
- package/package.json +1 -1
- package/src/builtins/builtins.test.ts +9 -3
- package/src/builtins/completion-bash.ts +2 -100
- package/src/builtins/completion-simulate-shared.ts +120 -0
- package/src/builtins/completion-zsh.ts +4 -102
- package/src/builtins/config.test.ts +4 -4
- package/src/builtins/config.ts +19 -22
- package/src/builtins/configure.ts +35 -4
- package/src/builtins/dispatch.ts +10 -15
- package/src/builtins/registry.ts +0 -2
- package/src/capabilities.ts +6 -12
- package/src/config/entry.ts +2 -2
- package/src/config/resolve.ts +2 -2
- package/src/configure/prompt.ts +2 -4
- package/src/docs/docs.test.ts +1 -1
- package/src/install/install-validate.test.ts +11 -0
- package/src/install/target-effective.ts +14 -2
- package/src/install/target-registry.ts +17 -0
- package/src/install/targets.test.ts +2 -0
- package/src/parse.ts +51 -172
- package/src/schema.ts +1 -1
- package/src/types.ts +2 -2
- package/src/validate.ts +12 -1
package/src/builtins/config.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Built-in `
|
|
2
|
+
Built-in `configure get` / `configure set` subcommands.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { bootstrapAppConfig } from "../config/bootstrap.ts";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
configCommandsEnabled,
|
|
8
|
+
configEntrySensitive,
|
|
9
|
+
configMcpSetEnabled,
|
|
10
|
+
defaultConfigEntryTitle,
|
|
11
|
+
} from "../config/entry.ts";
|
|
7
12
|
import { writeAppConfigFile } from "../config/file.ts";
|
|
8
13
|
import { captureMappedHostEnv, exportConfigToEnv, resolveAppConfig } from "../config/resolve.ts";
|
|
9
14
|
import { configPropertySchema, effectiveJsonSchema } from "../config/schema.ts";
|
|
10
15
|
import { parseConfigSetValue } from "../config/validate.ts";
|
|
11
|
-
import type { CliLeaf, CliOption, CliProgram
|
|
16
|
+
import type { CliLeaf, CliOption, CliProgram } from "../types.ts";
|
|
12
17
|
import { CliOptionKind } from "../types.ts";
|
|
13
18
|
|
|
14
19
|
const JSON_OPTION: CliOption = {
|
|
@@ -182,16 +187,16 @@ function configSetLeaf(program: CliProgram, mcpSetEnabled: boolean): CliLeaf {
|
|
|
182
187
|
handler: (ctx) => {
|
|
183
188
|
const key = ctx.args[0];
|
|
184
189
|
if (!key) {
|
|
185
|
-
process.stderr.write("
|
|
190
|
+
process.stderr.write("configure set requires a key.\n");
|
|
186
191
|
process.exit(1);
|
|
187
192
|
}
|
|
188
193
|
const raw = ctx.args[1];
|
|
189
194
|
if (raw === undefined || raw.length === 0) {
|
|
190
195
|
if (!ctx.hasFlag("json")) {
|
|
191
|
-
process.stderr.write("
|
|
196
|
+
process.stderr.write("configure set requires a value (or --json).\n");
|
|
192
197
|
process.exit(1);
|
|
193
198
|
}
|
|
194
|
-
process.stderr.write("
|
|
199
|
+
process.stderr.write("configure set requires a value.\n");
|
|
195
200
|
process.exit(1);
|
|
196
201
|
}
|
|
197
202
|
configSetRun(program, key, raw, ctx.hasFlag("json"));
|
|
@@ -199,23 +204,15 @@ function configSetLeaf(program: CliProgram, mcpSetEnabled: boolean): CliLeaf {
|
|
|
199
204
|
};
|
|
200
205
|
}
|
|
201
206
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
207
|
+
/** `configure get` / `configure set` leaves when app config commands are enabled. */
|
|
208
|
+
export function configureConfigSubcommands(
|
|
209
|
+
program: CliProgram,
|
|
210
|
+
mcpSetEnabled = configMcpSetEnabled(program),
|
|
211
|
+
): CliLeaf[] {
|
|
206
212
|
if (!program.appConfig) {
|
|
207
|
-
throw new Error("config
|
|
213
|
+
throw new Error("configure config subcommands require program.appConfig");
|
|
208
214
|
}
|
|
209
|
-
return
|
|
210
|
-
key: "config",
|
|
211
|
-
description: "Read or write app configuration.",
|
|
212
|
-
commands: [configGetLeaf(program), configSetLeaf(program, configMcpSetEnabled(program))],
|
|
213
|
-
};
|
|
215
|
+
return [configGetLeaf(program), configSetLeaf(program, mcpSetEnabled)];
|
|
214
216
|
}
|
|
215
217
|
|
|
216
|
-
export
|
|
217
|
-
if (!configCommandsEnabled(program)) {
|
|
218
|
-
return undefined;
|
|
219
|
-
}
|
|
220
|
-
return cliBuiltinConfigGroup(program);
|
|
221
|
-
}
|
|
218
|
+
export { configCommandsEnabled };
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { resolveCapabilities } from "../capabilities.ts";
|
|
2
|
-
import {
|
|
2
|
+
import { configCommandsEnabled, configMcpSetEnabled } from "../config/entry.ts";
|
|
3
|
+
import {
|
|
4
|
+
CliFallbackMode,
|
|
5
|
+
type CliLeaf,
|
|
6
|
+
type CliOption,
|
|
7
|
+
CliOptionKind,
|
|
8
|
+
type CliProgram,
|
|
9
|
+
type CliRouter,
|
|
10
|
+
} from "../types.ts";
|
|
11
|
+
import { configureConfigSubcommands } from "./config.ts";
|
|
3
12
|
import {
|
|
4
13
|
configureCommandDescription,
|
|
5
14
|
configureCommandNotes,
|
|
6
15
|
configureSyncOptionDescription,
|
|
7
16
|
} from "./configure-copy.ts";
|
|
8
17
|
|
|
18
|
+
/** Hidden fallback leaf for bare `configure` (interactive / flag modes). */
|
|
19
|
+
export const CONFIGURE_RUN_KEY = "run";
|
|
20
|
+
|
|
9
21
|
/** Configure command options. */
|
|
10
22
|
export function configureBuiltinOptions(root: CliProgram): CliOption[] {
|
|
11
23
|
const caps = resolveCapabilities(root);
|
|
@@ -57,14 +69,33 @@ export function configureBuiltinOptions(root: CliProgram): CliOption[] {
|
|
|
57
69
|
return opts;
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
/**
|
|
61
|
-
export function
|
|
72
|
+
/** True when argv resolved to `configure get` or `configure set`. */
|
|
73
|
+
export function isConfigureConfigPath(path: string[]): boolean {
|
|
74
|
+
return path.length >= 2 && (path[1] === "get" || path[1] === "set");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Builds the `configure` built-in router. */
|
|
78
|
+
export function cliBuiltinConfigureCommand(root: CliProgram): CliRouter {
|
|
62
79
|
const caps = resolveCapabilities(root);
|
|
80
|
+
const run: CliLeaf = {
|
|
81
|
+
key: CONFIGURE_RUN_KEY,
|
|
82
|
+
hidden: true,
|
|
83
|
+
description: "Interactive or flag-driven configure (skills, MCP, app config).",
|
|
84
|
+
handler: () => {},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const commands: CliLeaf[] = [run];
|
|
88
|
+
if (configCommandsEnabled(root)) {
|
|
89
|
+
commands.push(...configureConfigSubcommands(root, configMcpSetEnabled(root)));
|
|
90
|
+
}
|
|
91
|
+
|
|
63
92
|
return {
|
|
64
93
|
key: "configure",
|
|
65
94
|
description: configureCommandDescription(root, caps),
|
|
66
95
|
options: configureBuiltinOptions(root),
|
|
67
96
|
notes: configureCommandNotes(root, caps),
|
|
68
|
-
|
|
97
|
+
fallbackCommand: CONFIGURE_RUN_KEY,
|
|
98
|
+
fallbackMode: CliFallbackMode.MissingOnly,
|
|
99
|
+
commands,
|
|
69
100
|
};
|
|
70
101
|
}
|
package/src/builtins/dispatch.ts
CHANGED
|
@@ -11,8 +11,11 @@ import { completionBashScript } from "./completion-bash.ts";
|
|
|
11
11
|
import { completionFishScript } from "./completion-fish.ts";
|
|
12
12
|
import { cliBuiltinCompletionGroup as completionGroup } from "./completion-group.ts";
|
|
13
13
|
import { completionZshScript } from "./completion-zsh.ts";
|
|
14
|
-
import {
|
|
15
|
-
|
|
14
|
+
import {
|
|
15
|
+
CONFIGURE_RUN_KEY,
|
|
16
|
+
cliBuiltinConfigureCommand,
|
|
17
|
+
isConfigureConfigPath,
|
|
18
|
+
} from "./configure.ts";
|
|
16
19
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
17
20
|
import { cliPresentationRoot } from "./presentation.ts";
|
|
18
21
|
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
@@ -101,7 +104,11 @@ export async function dispatchBuiltin(
|
|
|
101
104
|
process.stderr.write(capabilityDeniedMessage("configure"));
|
|
102
105
|
process.exit(1);
|
|
103
106
|
}
|
|
104
|
-
if (pr.path
|
|
107
|
+
if (isConfigureConfigPath(pr.path)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const runSeg = pr.path[1];
|
|
111
|
+
if (pr.path.length > 2 || (pr.path.length === 2 && runSeg !== CONFIGURE_RUN_KEY)) {
|
|
105
112
|
process.stderr.write(`Unknown subcommand: configure ${pr.path.slice(1).join(" ")}\n`);
|
|
106
113
|
process.exit(1);
|
|
107
114
|
}
|
|
@@ -177,17 +184,5 @@ export function builtinInterceptRoot(
|
|
|
177
184
|
};
|
|
178
185
|
}
|
|
179
186
|
|
|
180
|
-
const configGroup = cliBuiltinConfigGroupIfEnabled(program);
|
|
181
|
-
if (first === "config" && configGroup) {
|
|
182
|
-
return {
|
|
183
|
-
parseRoot: {
|
|
184
|
-
key: program.key,
|
|
185
|
-
description: program.description,
|
|
186
|
-
commands: [configGroup],
|
|
187
|
-
},
|
|
188
|
-
isLeafCompletionIntercept: false,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
187
|
return { parseRoot: program, isLeafCompletionIntercept: false };
|
|
193
188
|
}
|
package/src/builtins/registry.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { CliCapabilities } from "../capabilities.ts";
|
|
|
2
2
|
import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
3
3
|
import type { CliNode, CliProgram } from "../types.ts";
|
|
4
4
|
import { cliBuiltinCompletionGroup } from "./completion-group.ts";
|
|
5
|
-
import { cliBuiltinConfigGroupIfEnabled } from "./config.ts";
|
|
6
5
|
import { cliBuiltinConfigureCommand } from "./configure.ts";
|
|
7
6
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
8
7
|
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
@@ -37,6 +36,5 @@ export function resolveBuiltins(program: CliProgram, caps: CliCapabilities): Cli
|
|
|
37
36
|
if (caps.mcp) {
|
|
38
37
|
pushBuiltin(builtins, program, (p) => cliBuiltinMcpCommand(p));
|
|
39
38
|
}
|
|
40
|
-
pushBuiltin(builtins, program, (p) => cliBuiltinConfigGroupIfEnabled(p) ?? null);
|
|
41
39
|
return builtins;
|
|
42
40
|
}
|
package/src/capabilities.ts
CHANGED
|
@@ -42,17 +42,17 @@ export function reservedCommandNames(caps: CliCapabilities): string[] {
|
|
|
42
42
|
if (caps.mcp) {
|
|
43
43
|
names.push("mcp");
|
|
44
44
|
}
|
|
45
|
-
if (caps.configCommands) {
|
|
46
|
-
names.push("config");
|
|
47
|
-
}
|
|
48
45
|
return names;
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
/** Commands that may run without required appConfig values (read-only / config introspection). */
|
|
52
49
|
export function skipsRequiredAppConfigExit(path: string[], caps: CliCapabilities): boolean {
|
|
53
50
|
const root = path[0];
|
|
54
|
-
if (root === "
|
|
55
|
-
|
|
51
|
+
if (root === "configure" && caps.configCommands) {
|
|
52
|
+
const sub = path[1];
|
|
53
|
+
if (sub === "get" || sub === "set") {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
56
|
}
|
|
57
57
|
if (root === "docs" && caps.docs) {
|
|
58
58
|
return true;
|
|
@@ -60,7 +60,7 @@ export function skipsRequiredAppConfigExit(path: string[], caps: CliCapabilities
|
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
export type CapabilityFeature = "mcp" | "configure" | "docs" | "
|
|
63
|
+
export type CapabilityFeature = "mcp" | "configure" | "docs" | "completion";
|
|
64
64
|
|
|
65
65
|
/** Stderr message when a disabled built-in is invoked from the CLI. */
|
|
66
66
|
export function capabilityDeniedMessage(feature: CapabilityFeature): string {
|
|
@@ -73,8 +73,6 @@ export function capabilityDeniedMessage(feature: CapabilityFeature): string {
|
|
|
73
73
|
return "Configure is not available for this app.\n";
|
|
74
74
|
case "docs":
|
|
75
75
|
return "Documentation commands are not available for this app.\n";
|
|
76
|
-
case "config":
|
|
77
|
-
return "Configuration commands are not available for this app.\n";
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
@@ -100,8 +98,4 @@ export function assertBuiltinAllowed(argv: string[], caps: CliCapabilities): voi
|
|
|
100
98
|
process.stderr.write(capabilityDeniedMessage("docs"));
|
|
101
99
|
process.exit(1);
|
|
102
100
|
}
|
|
103
|
-
if (first === "config" && !caps.configCommands) {
|
|
104
|
-
process.stderr.write(capabilityDeniedMessage("config"));
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
101
|
}
|
package/src/config/entry.ts
CHANGED
|
@@ -29,7 +29,7 @@ export function configEntryRequired(
|
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/** Whether prompts and `
|
|
32
|
+
/** Whether prompts and `configure get` should redact this entry. */
|
|
33
33
|
export function configEntrySensitive(key: string, entry: CliAppConfigEntry): boolean {
|
|
34
34
|
return entry.sensitive ?? defaultConfigEntrySensitive(key);
|
|
35
35
|
}
|
|
@@ -56,7 +56,7 @@ export function jsonSchemaRequiredKeys(
|
|
|
56
56
|
return new Set(required.filter((k): k is string => typeof k === "string"));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
/** Whether built-in
|
|
59
|
+
/** Whether built-in `configure get` / `configure set` subcommands are enabled. */
|
|
60
60
|
export function configCommandsEnabled(program: CliProgram): boolean {
|
|
61
61
|
if (!program.appConfig) {
|
|
62
62
|
return false;
|
package/src/config/resolve.ts
CHANGED
|
@@ -227,7 +227,7 @@ export function formatMissingConfigMessage(program: CliProgram, keys: string[]):
|
|
|
227
227
|
return [
|
|
228
228
|
`Missing required configuration: ${list}`,
|
|
229
229
|
`Configure interactively: ${program.key} configure`,
|
|
230
|
-
`Or set via: ${program.key}
|
|
230
|
+
`Or set via: ${program.key} configure set <key> <value>`,
|
|
231
231
|
`Config file: ${path}`,
|
|
232
232
|
`See: ${program.key} docs mcp`,
|
|
233
233
|
].join("\n");
|
|
@@ -240,7 +240,7 @@ export function formatMcpMissingConfigMessage(program: CliProgram, keys: string[
|
|
|
240
240
|
return [
|
|
241
241
|
`Missing required configuration: ${list}`,
|
|
242
242
|
`Configure: ${program.key} configure`,
|
|
243
|
-
`Or set via: ${program.key}
|
|
243
|
+
`Or set via: ${program.key} configure set`,
|
|
244
244
|
`Config file: ${path}`,
|
|
245
245
|
].join("\n");
|
|
246
246
|
}
|
package/src/configure/prompt.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
TTY prompts for per-target install, skip, or uninstall during interactive `configure`.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { readSync } from "node:fs";
|
|
6
5
|
import type { CliInstallArtifactKey } from "../install/target-types.ts";
|
|
6
|
+
import { readPromptLine } from "../prompt.ts";
|
|
7
7
|
|
|
8
8
|
/** Human-readable labels for each install artifact key in interactive prompts. */
|
|
9
9
|
const LABELS: Record<CliInstallArtifactKey, string> = {
|
|
@@ -35,9 +35,7 @@ export type TargetPromptAction = "install" | "skip" | "uninstall";
|
|
|
35
35
|
export function promptTargetAction(label: string, installed: boolean): TargetPromptAction | null {
|
|
36
36
|
const hint = installed ? `${label} [y/N]: ` : `${label} [Y/n]: `;
|
|
37
37
|
process.stderr.write(hint);
|
|
38
|
-
const
|
|
39
|
-
const n = readSync(0, buf, { length: 256 });
|
|
40
|
-
const ans = buf.toString("utf8", 0, n).trim().toLowerCase();
|
|
38
|
+
const ans = readPromptLine().trim().toLowerCase();
|
|
41
39
|
if (installed) {
|
|
42
40
|
if (ans === "n") return "uninstall";
|
|
43
41
|
return "skip";
|
package/src/docs/docs.test.ts
CHANGED
|
@@ -167,7 +167,7 @@ test("skipsRequiredAppConfigExit includes docs and config builtins", () => {
|
|
|
167
167
|
};
|
|
168
168
|
const caps = resolveCapabilities(program);
|
|
169
169
|
expect(skipsRequiredAppConfigExit(["docs", "api"], caps)).toBe(true);
|
|
170
|
-
expect(skipsRequiredAppConfigExit(["
|
|
170
|
+
expect(skipsRequiredAppConfigExit(["configure", "get"], caps)).toBe(true);
|
|
171
171
|
expect(skipsRequiredAppConfigExit(["run"], caps)).toBe(false);
|
|
172
172
|
});
|
|
173
173
|
|
|
@@ -63,4 +63,15 @@ describe("validateConfigureConfig", () => {
|
|
|
63
63
|
};
|
|
64
64
|
expect(() => cliValidateProgram(program)).not.toThrow();
|
|
65
65
|
});
|
|
66
|
+
|
|
67
|
+
test("rejects explicit MCP target without mcpServer", () => {
|
|
68
|
+
const program: CliProgram = {
|
|
69
|
+
...base,
|
|
70
|
+
configure: {
|
|
71
|
+
agentIntegration: "both",
|
|
72
|
+
targets: { cursorMcp: true },
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
expect(() => cliValidateProgram(program)).toThrow(/mcpServer\.enabled/);
|
|
76
|
+
});
|
|
66
77
|
});
|
|
@@ -7,7 +7,12 @@ import type {
|
|
|
7
7
|
InstallTargetSpec,
|
|
8
8
|
} from "../types.ts";
|
|
9
9
|
import type { InstallPaths } from "./paths.ts";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
AGENT_PAIRS,
|
|
12
|
+
INSTALL_ARTIFACT_KEYS,
|
|
13
|
+
installTargetForKey,
|
|
14
|
+
mcpServerRequiredForArtifact,
|
|
15
|
+
} from "./target-registry.ts";
|
|
11
16
|
import type { CliInstallArtifactKey, InstallPlanMode } from "./target-types.ts";
|
|
12
17
|
|
|
13
18
|
export type { InstallTargetSpec, ResolvedInstallTarget } from "../types.ts";
|
|
@@ -44,9 +49,13 @@ export function resolveInstallTargetSpec(
|
|
|
44
49
|
function artifactDefaults(
|
|
45
50
|
key: CliInstallArtifactKey,
|
|
46
51
|
integration: InstallAgentIntegration,
|
|
52
|
+
mcpServerEnabled: boolean,
|
|
47
53
|
): { enabled: boolean; includedInAll: boolean } {
|
|
48
54
|
const target = installTargetForKey(key);
|
|
49
55
|
const includedInAll = target?.defaultIncludedInAll(integration) ?? false;
|
|
56
|
+
if (!mcpServerRequiredForArtifact(key, mcpServerEnabled)) {
|
|
57
|
+
return { enabled: false, includedInAll: false };
|
|
58
|
+
}
|
|
50
59
|
return { enabled: true, includedInAll };
|
|
51
60
|
}
|
|
52
61
|
|
|
@@ -86,7 +95,10 @@ export function resolveEffectiveInstallTargets(
|
|
|
86
95
|
const user = configure?.targets;
|
|
87
96
|
const out = {} as Record<CliInstallArtifactKey, { enabled: boolean; includedInAll: boolean }>;
|
|
88
97
|
for (const key of INSTALL_ARTIFACT_KEYS) {
|
|
89
|
-
out[key] = resolveInstallTargetSpec(
|
|
98
|
+
out[key] = resolveInstallTargetSpec(
|
|
99
|
+
user?.[key],
|
|
100
|
+
artifactDefaults(key, integration, mcpEnabled),
|
|
101
|
+
);
|
|
90
102
|
}
|
|
91
103
|
applyAgentPairDedupe(out, user, integration);
|
|
92
104
|
return out;
|
|
@@ -37,6 +37,23 @@ export function installTargetForKey(key: CliInstallArtifactKey): InstallTarget |
|
|
|
37
37
|
return targetByKey.get(key);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/** True when the artifact key is an MCP install target (requires mcpServer.enabled). */
|
|
41
|
+
export function isMcpArtifactKey(key: CliInstallArtifactKey): boolean {
|
|
42
|
+
return installTargetForKey(key)?.category === "mcp";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* MCP install targets are inactive without mcpServer.enabled.
|
|
47
|
+
* Defaults: artifactDefaults in target-effective.ts.
|
|
48
|
+
* Explicit spec rejection: validateConfigureConfig in validate.ts.
|
|
49
|
+
*/
|
|
50
|
+
export function mcpServerRequiredForArtifact(
|
|
51
|
+
key: CliInstallArtifactKey,
|
|
52
|
+
mcpServerEnabled: boolean,
|
|
53
|
+
): boolean {
|
|
54
|
+
return !isMcpArtifactKey(key) || mcpServerEnabled;
|
|
55
|
+
}
|
|
56
|
+
|
|
40
57
|
/** Lookup by plan action kind. */
|
|
41
58
|
export function installTargetForActionKind(kind: InstallActionKind): InstallTarget | undefined {
|
|
42
59
|
return INSTALL_TARGETS.find((t) => t.actionKind === kind);
|
|
@@ -50,7 +50,9 @@ describe("resolveEffectiveInstallTargets", () => {
|
|
|
50
50
|
const program: Pick<CliProgram, "mcpServer"> = {};
|
|
51
51
|
const t = resolveEffectiveInstallTargets(undefined, program);
|
|
52
52
|
expect(t.cursorSkill.includedInAll).toBe(true);
|
|
53
|
+
expect(t.cursorSkill.enabled).toBe(true);
|
|
53
54
|
expect(t.cursorMcp.includedInAll).toBe(false);
|
|
55
|
+
expect(t.cursorMcp.enabled).toBe(false);
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
test("mcp mode includes MCP in --all not paired skills", () => {
|