argsbarg 6.1.10 → 6.2.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/CHANGELOG.md +22 -1
- package/README.md +49 -49
- package/docs/README.md +5 -4
- package/docs/ai-skills.md +36 -23
- package/docs/bundled-docs.md +1 -1
- package/docs/cli-program.md +19 -20
- package/docs/config-schema.md +3 -3
- package/docs/configure.md +12 -16
- package/docs/developing.md +9 -9
- package/docs/mcp.md +21 -57
- package/docs/output-schema.md +3 -3
- package/examples/formats.ts +5 -6
- package/examples/full-example/AGENTS.md +75 -0
- package/examples/full-example/CLAUDE.md +1 -0
- package/examples/full-example/README.md +7 -69
- package/examples/full-example/docs/README.md +1 -1
- package/examples/full-example/docs/cli-schema.json +1 -1659
- package/examples/full-example/docs/cli.md +2 -1538
- package/examples/full-example/docs/http.md +0 -7
- package/examples/full-example/docs/mcp.md +23 -59
- package/examples/full-example/docs/openapi.json +2 -782
- package/examples/full-example/docs/skill.md +18 -14
- package/examples/full-example/justfile +5 -17
- package/examples/full-example/scripts/create-identity.ts +2 -1
- package/examples/full-example/src/commands/status/command.test.ts +2 -2
- package/examples/full-example/src/commands/status/command.ts +7 -6
- package/examples/full-example/src/program.ts +4 -10
- package/examples/full-example-json/AGENTS.md +86 -0
- package/examples/full-example-json/CLAUDE.md +1 -0
- package/examples/full-example-json/Formula/.gitkeep +0 -0
- package/examples/full-example-json/Formula/full-example-json.rb +35 -0
- package/examples/full-example-json/README.md +27 -0
- package/examples/full-example-json/biome.json +22 -0
- package/examples/full-example-json/bun.lock +48 -0
- package/examples/full-example-json/docs/README.md +27 -0
- package/examples/full-example-json/docs/cli-schema.json +2145 -0
- package/examples/full-example-json/docs/cli.md +1990 -0
- package/examples/full-example-json/docs/http.md +92 -0
- package/examples/full-example-json/docs/mcp.md +116 -0
- package/examples/full-example-json/docs/openapi.json +1246 -0
- package/examples/full-example-json/docs/skill.md +57 -0
- package/examples/full-example-json/justfile +171 -0
- package/examples/full-example-json/package.json +22 -0
- package/examples/full-example-json/scripts/create-identity.ts +12 -0
- package/examples/full-example-json/scripts/dev-formula.ts +97 -0
- package/examples/full-example-json/scripts/formula-shared.test.ts +68 -0
- package/examples/full-example-json/scripts/formula-shared.ts +170 -0
- package/examples/full-example-json/scripts/print-identity.ts +28 -0
- package/examples/full-example-json/scripts/release.ts +212 -0
- package/examples/full-example-json/src/commands/echo/command.ts +26 -0
- package/examples/full-example-json/src/commands/status/command.test.ts +10 -0
- package/examples/full-example-json/src/commands/status/command.ts +28 -0
- package/examples/full-example-json/src/index.ts +10 -0
- package/examples/full-example-json/src/program.ts +33 -0
- package/examples/full-example-json/src/types/md.d.ts +4 -0
- package/examples/full-example-json/tsconfig.json +17 -0
- package/examples/minimal.ts +17 -17
- package/examples/nested.ts +10 -10
- package/examples/option-required.ts +13 -13
- package/examples/servers.ts +10 -10
- package/index.d.ts +17 -43
- package/package.json +1 -1
- package/src/cli-tool/create.test.ts +44 -68
- package/src/cli-tool/create.ts +81 -17
- package/src/cli-tool/full-example-capabilities.test.ts +33 -18
- package/src/cli-tool/post-create.ts +31 -17
- package/src/cli-tool/program.ts +16 -7
- package/src/cli-tool/prompt.ts +27 -0
- package/src/cli-tool/run-create.ts +19 -7
- package/src/cli-tool/schemagen/schemagen.test.ts +3 -3
- package/src/configure/artifacts/install-validate.test.ts +20 -33
- package/src/configure/artifacts/paths.ts +9 -53
- package/src/configure/artifacts/status.test.ts +13 -16
- package/src/configure/artifacts/status.ts +5 -22
- package/src/configure/artifacts/target-base.ts +6 -15
- package/src/configure/artifacts/target-effective.ts +16 -54
- package/src/configure/artifacts/target-mcp-json.ts +2 -5
- package/src/configure/artifacts/target-registry.ts +0 -7
- package/src/configure/artifacts/target-scope.ts +7 -17
- package/src/configure/artifacts/target-skill.ts +6 -15
- package/src/configure/artifacts/target-types.ts +6 -54
- package/src/configure/artifacts/targets/agents-mcp.ts +11 -0
- package/src/configure/artifacts/targets/configure.ts +1 -5
- package/src/configure/artifacts/targets/index.ts +4 -44
- package/src/configure/artifacts/targets/skill.ts +12 -0
- package/src/configure/artifacts/targets.test.ts +21 -59
- package/src/configure/configure.test.ts +35 -46
- package/src/configure/index.ts +19 -19
- package/src/configure/prompt.ts +2 -12
- package/src/core/parse.test.ts +21 -32
- package/src/core/types.ts +18 -44
- package/src/core/validate.ts +28 -45
- package/src/docs/docs.test.ts +4 -4
- package/src/docs/mcp-guide.ts +41 -71
- package/src/docs/resolve.ts +1 -1
- package/src/exports/cli.ts +1 -1
- package/src/index.ts +1 -1
- package/src/skill/generate.ts +26 -45
- package/src/skill/install.ts +18 -38
- package/src/skill/naming.ts +3 -27
- package/src/test/integration/config.test.ts +3 -3
- package/src/test/integration/mcp.test.ts +4 -4
- package/{examples/mcp-test.ts → src/test/mcp-integration-fixture.ts} +20 -22
- package/src/configure/artifacts/target-mcp-cli.ts +0 -127
- package/src/configure/artifacts/targets/chatgpt-mcp.ts +0 -12
- package/src/configure/artifacts/targets/claude-code-mcp.ts +0 -15
- package/src/configure/artifacts/targets/claude-desktop-mcp.ts +0 -12
- package/src/configure/artifacts/targets/claude-skill.ts +0 -16
- package/src/configure/artifacts/targets/codex-mcp.ts +0 -25
- package/src/configure/artifacts/targets/codex-skill.ts +0 -14
- package/src/configure/artifacts/targets/cursor-mcp.ts +0 -15
- package/src/configure/artifacts/targets/cursor-skill.ts +0 -16
- package/src/configure/artifacts/targets/openclaw-mcp.ts +0 -25
- package/src/configure/artifacts/targets/openclaw-skill.ts +0 -17
- package/src/configure/artifacts/targets/opencode-mcp.ts +0 -96
- package/src/configure/artifacts/targets/opencode-skill.ts +0 -15
- /package/examples/{full-example → full-example-json}/src/commands/render-json/__generated__/RenderJsonInputSchema.json +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/render-json/__generated__/index.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/render-json/command.test.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/render-json/command.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/render-json/types.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/status/__generated__/StatusJsonOutputSchema.json +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/status/__generated__/index.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/status/types.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/workspaces/__generated__/WorkspaceNameInputSchema.json +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/workspaces/__generated__/index.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/workspaces/command.test.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/workspaces/command.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/commands/workspaces/types.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/db/index.test.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/db/index.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/db/migrate.test.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/db/migrate.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/db/migrations/001_workspaces.sql +0 -0
- /package/examples/{full-example → full-example-json}/src/db/tables/workspaces.ts +0 -0
- /package/examples/{full-example → full-example-json}/src/types/argsbarg.d.ts +0 -0
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
applyCreate,
|
|
7
7
|
type CreateOptions,
|
|
8
8
|
diffCreateDetails,
|
|
9
|
+
normalizeCreateTemplateId,
|
|
9
10
|
parseCreateArgv,
|
|
10
11
|
printCreateDiffs,
|
|
11
12
|
renderCreateTree,
|
|
12
13
|
resolveCreateOptions,
|
|
13
14
|
} from "./create.ts";
|
|
14
15
|
import { printPostCreatePlan, runPostCreate } from "./post-create.ts";
|
|
15
|
-
import { promptConfirm, promptOptional, promptRequired } from "./prompt.ts";
|
|
16
|
+
import { promptConfirm, promptOptional, promptRequired, promptTemplateChoice } from "./prompt.ts";
|
|
16
17
|
|
|
17
18
|
function isInteractiveTty(): boolean {
|
|
18
19
|
return Boolean(process.stdin.isTTY);
|
|
@@ -22,7 +23,10 @@ function collectInteractiveOptions(
|
|
|
22
23
|
partial: Partial<CreateOptions>,
|
|
23
24
|
dir: string,
|
|
24
25
|
): { opts: CreateOptions; baseDir: string } {
|
|
25
|
-
process.stderr.write("Argsbarg create — bootstrap a new CLI
|
|
26
|
+
process.stderr.write("Argsbarg create — bootstrap a new CLI\n\n");
|
|
27
|
+
|
|
28
|
+
const templateId = partial.templateId ?? promptTemplateChoice();
|
|
29
|
+
|
|
26
30
|
const targetDir = promptOptional("Target directory", dir) ?? dir;
|
|
27
31
|
const baseDir = resolve(process.cwd(), targetDir);
|
|
28
32
|
const key = promptRequired("CLI key (binary name)", partial.key);
|
|
@@ -31,6 +35,7 @@ function collectInteractiveOptions(
|
|
|
31
35
|
const opts = resolveCreateOptions(
|
|
32
36
|
{
|
|
33
37
|
...partial,
|
|
38
|
+
templateId,
|
|
34
39
|
key,
|
|
35
40
|
releaseRepo,
|
|
36
41
|
force: partial.force ?? false,
|
|
@@ -38,7 +43,8 @@ function collectInteractiveOptions(
|
|
|
38
43
|
baseDir,
|
|
39
44
|
);
|
|
40
45
|
|
|
41
|
-
process.stderr.write(`\
|
|
46
|
+
process.stderr.write(`\nTemplate: ${opts.templateId}\n`);
|
|
47
|
+
process.stderr.write(`Target: ${baseDir}\n`);
|
|
42
48
|
process.stderr.write(`Key: ${opts.key} Class: ${opts.className} Tap: ${opts.tap} Release: ${opts.releaseRepo}\n`);
|
|
43
49
|
process.stderr.write(`Homepage: ${opts.homepage}\n\n`);
|
|
44
50
|
const tree = renderCreateTree(opts);
|
|
@@ -47,7 +53,7 @@ function collectInteractiveOptions(
|
|
|
47
53
|
process.stderr.write(` ${rel}\n`);
|
|
48
54
|
}
|
|
49
55
|
process.stderr.write("\n");
|
|
50
|
-
printPostCreatePlan();
|
|
56
|
+
printPostCreatePlan(opts.templateId);
|
|
51
57
|
process.stderr.write("\n");
|
|
52
58
|
|
|
53
59
|
if (!promptConfirm("Proceed")) {
|
|
@@ -91,7 +97,13 @@ export async function runCreate(input: Partial<CreateOptions> & { dir?: string }
|
|
|
91
97
|
if (!partial.releaseRepo) {
|
|
92
98
|
throw new Error("--release-repo is required in non-interactive mode.");
|
|
93
99
|
}
|
|
94
|
-
opts = resolveCreateOptions(
|
|
100
|
+
opts = resolveCreateOptions(
|
|
101
|
+
{
|
|
102
|
+
...partial,
|
|
103
|
+
templateId: normalizeCreateTemplateId(partial.templateId),
|
|
104
|
+
},
|
|
105
|
+
baseDir,
|
|
106
|
+
);
|
|
95
107
|
return runCreateApply(baseDir, opts, partial.dryRun ?? false);
|
|
96
108
|
} catch (err) {
|
|
97
109
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
@@ -104,7 +116,7 @@ async function runCreateApply(baseDir: string, opts: CreateOptions, dryRun: bool
|
|
|
104
116
|
const written = applyCreate(baseDir, { ...opts, dryRun: true, check: false });
|
|
105
117
|
process.stdout.write(`Would write ${written.length} file(s) under ${baseDir}\n`);
|
|
106
118
|
for (const w of written) process.stdout.write(` ${relative(baseDir, w) || w}\n`);
|
|
107
|
-
printPostCreatePlan();
|
|
119
|
+
printPostCreatePlan(opts.templateId);
|
|
108
120
|
return 0;
|
|
109
121
|
}
|
|
110
122
|
|
|
@@ -120,7 +132,7 @@ async function runCreateApply(baseDir: string, opts: CreateOptions, dryRun: bool
|
|
|
120
132
|
process.stdout.write(` ${relative(baseDir, w) || w}\n`);
|
|
121
133
|
}
|
|
122
134
|
|
|
123
|
-
await runPostCreate(baseDir, false);
|
|
135
|
+
await runPostCreate(baseDir, false, opts.templateId);
|
|
124
136
|
process.stdout.write("Done.\n");
|
|
125
137
|
return 0;
|
|
126
138
|
}
|
|
@@ -6,7 +6,7 @@ import { discoverSchemaRoots } from "./discover-schema-roots.ts";
|
|
|
6
6
|
import { schemaExportName, schemaJsonBasename } from "./names.ts";
|
|
7
7
|
import { runSchemagen } from "./run.ts";
|
|
8
8
|
|
|
9
|
-
const exampleRoot = join(import.meta.dir, "../../../examples/full-example");
|
|
9
|
+
const exampleRoot = join(import.meta.dir, "../../../examples/full-example-json");
|
|
10
10
|
|
|
11
11
|
const tempRoots: string[] = [];
|
|
12
12
|
|
|
@@ -46,7 +46,7 @@ function writeSrcFile(root: string, relPath: string, body: string): void {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
describe("schemagen", () => {
|
|
49
|
-
test("discovers @sg types in full-example", () => {
|
|
49
|
+
test("discovers @sg types in full-example-json", () => {
|
|
50
50
|
const roots = discoverSchemaRoots(exampleRoot);
|
|
51
51
|
expect(roots.map((r) => r.typeName).sort()).toEqual(["RenderJsonInput", "StatusJsonOutput", "WorkspaceNameInput"]);
|
|
52
52
|
});
|
|
@@ -56,7 +56,7 @@ describe("schemagen", () => {
|
|
|
56
56
|
expect(schemaExportName("RenderJsonInput")).toBe("RenderJsonInputSchema");
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
test("runSchemagen writes __generated__ artifacts in full-example", () => {
|
|
59
|
+
test("runSchemagen writes __generated__ artifacts in full-example-json", () => {
|
|
60
60
|
const counts = runSchemagen({ projectRoot: exampleRoot });
|
|
61
61
|
expect(counts).toEqual({ schemas: 3 });
|
|
62
62
|
});
|
|
@@ -29,49 +29,36 @@ describe("validateConfigureConfig", () => {
|
|
|
29
29
|
expect(() => cliValidateProgram(program)).toThrow(/allSkills/);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
test("rejects
|
|
33
|
-
const program
|
|
32
|
+
test("rejects configure.agentIntegration", () => {
|
|
33
|
+
const program = {
|
|
34
34
|
...base,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
targets: { cursorMcp: true, cursorSkill: true },
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
expect(() => cliValidateProgram(program)).toThrow(/both/);
|
|
35
|
+
configure: { agentIntegration: "mcp" },
|
|
36
|
+
} as CliProgram;
|
|
37
|
+
expect(() => cliValidateProgram(program)).toThrow(/agentIntegration removed/);
|
|
42
38
|
});
|
|
43
39
|
|
|
44
|
-
test("rejects
|
|
45
|
-
const program
|
|
40
|
+
test("rejects legacy per-host skill targets", () => {
|
|
41
|
+
const program = {
|
|
46
42
|
...base,
|
|
47
|
-
configure: {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
expect(() => cliValidateProgram(program)).toThrow(/cursorMcp/);
|
|
43
|
+
configure: { targets: { cursorSkill: true } },
|
|
44
|
+
} as CliProgram;
|
|
45
|
+
expect(() => cliValidateProgram(program)).toThrow(/cursorSkill removed/);
|
|
53
46
|
});
|
|
54
47
|
|
|
55
|
-
test("
|
|
56
|
-
const program
|
|
48
|
+
test("rejects legacy per-host MCP targets", () => {
|
|
49
|
+
const program = {
|
|
57
50
|
...base,
|
|
58
51
|
mcpServer: { enabled: true },
|
|
59
|
-
configure: {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
expect(() => cliValidateProgram(program)).not.toThrow();
|
|
52
|
+
configure: { targets: { cursorMcp: true } },
|
|
53
|
+
} as CliProgram;
|
|
54
|
+
expect(() => cliValidateProgram(program)).toThrow(/cursorMcp removed/);
|
|
65
55
|
});
|
|
66
56
|
|
|
67
|
-
test("rejects
|
|
68
|
-
const program
|
|
57
|
+
test("rejects unknown configure.targets keys", () => {
|
|
58
|
+
const program = {
|
|
69
59
|
...base,
|
|
70
|
-
configure: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
expect(() => cliValidateProgram(program)).toThrow(/mcpServer\.enabled/);
|
|
60
|
+
configure: { targets: { unknownKey: true } },
|
|
61
|
+
} as CliProgram;
|
|
62
|
+
expect(() => cliValidateProgram(program)).toThrow(/not a valid target key/);
|
|
76
63
|
});
|
|
77
64
|
});
|
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import type { CliProgram } from "../../core/types.ts";
|
|
4
|
-
import { mcpServerId
|
|
4
|
+
import { mcpServerId } from "../../mcp/tools.ts";
|
|
5
5
|
import { displayHomePath, userHome, xdgConfigHome } from "../../paths/host.ts";
|
|
6
|
-
import {
|
|
7
|
-
import { resolveOpenclawConfigPath } from "./mcp-openclaw.ts";
|
|
8
|
-
import { resolveOpenCodeConfigPathForInstall } from "./mcp-opencode.ts";
|
|
6
|
+
import { skillDirName } from "../../skill/naming.ts";
|
|
9
7
|
|
|
10
8
|
export interface InstallPaths {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
codexSkillDir: string;
|
|
14
|
-
opencodeSkillDir: string;
|
|
15
|
-
openclawSkillDir: string;
|
|
16
|
-
cursorMcpPath: string;
|
|
17
|
-
claudeMcpPath: string;
|
|
18
|
-
claudeDesktopMcpPath: string;
|
|
19
|
-
opencodeMcpPath: string;
|
|
20
|
-
chatGptMcpPath: string;
|
|
21
|
-
codexConfigPath: string;
|
|
22
|
-
openclawConfigPath: string;
|
|
9
|
+
agentsSkillDir: string;
|
|
10
|
+
agentsMcpPath: string;
|
|
23
11
|
mcpName: string;
|
|
24
12
|
skillDirName: string;
|
|
25
13
|
}
|
|
@@ -31,7 +19,7 @@ export function displayInstallPath(path: string): string {
|
|
|
31
19
|
return displayHomePath(path);
|
|
32
20
|
}
|
|
33
21
|
|
|
34
|
-
/** Resolves Claude Desktop `claude_desktop_config.json` for the current OS. */
|
|
22
|
+
/** Resolves Claude Desktop `claude_desktop_config.json` for the current OS (manual setup docs). */
|
|
35
23
|
export function resolveClaudeDesktopMcpPath(home: string): string {
|
|
36
24
|
if (process.platform === "darwin") {
|
|
37
25
|
return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
@@ -48,47 +36,15 @@ export function claudeDesktopPresent(_home: string, configPath: string): boolean
|
|
|
48
36
|
return existsSync(configPath) || existsSync(dirname(configPath));
|
|
49
37
|
}
|
|
50
38
|
|
|
51
|
-
/** Resolves ChatGPT desktop `chatgpt_mcp_config.json` for the current OS. */
|
|
52
|
-
export function resolveChatGptMcpPath(home: string): string {
|
|
53
|
-
if (process.platform === "darwin") {
|
|
54
|
-
return join(home, "Library", "Application Support", "ChatGPT", "chatgpt_mcp_config.json");
|
|
55
|
-
}
|
|
56
|
-
if (process.platform === "win32") {
|
|
57
|
-
const appData = process.env.APPDATA ?? join(home, "AppData", "Roaming");
|
|
58
|
-
return join(appData, "OpenAI", "ChatGPT", "chatgpt_mcp_config.json");
|
|
59
|
-
}
|
|
60
|
-
return join(xdgConfigHome(home), "ChatGPT", "chatgpt_mcp_config.json");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** True when ChatGPT desktop app data exists (config file or app support directory). */
|
|
64
|
-
export function chatGptDesktopPresent(_home: string, configPath: string): boolean {
|
|
65
|
-
return existsSync(configPath) || existsSync(dirname(configPath));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
39
|
/** Resolves all install artifact paths for a program root. */
|
|
69
40
|
export function resolveInstallPaths(root: CliProgram): InstallPaths {
|
|
70
41
|
const home = userHome();
|
|
71
|
-
const
|
|
72
|
-
const codexSlug = skillDirNameForTarget(root.key, "codex");
|
|
73
|
-
const opencodeSlug = skillDirNameForTarget(root.key, "opencode");
|
|
74
|
-
const openclawSlug = skillDirNameForTarget(root.key, "openclaw");
|
|
75
|
-
const claudeDesktopMcpPath = resolveClaudeDesktopMcpPath(home);
|
|
76
|
-
const chatGptMcpPath = resolveChatGptMcpPath(home);
|
|
42
|
+
const dirName = skillDirName(root.key);
|
|
77
43
|
|
|
78
44
|
return {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
codexSkillDir: join(home, ".codex", "skills", codexSlug),
|
|
82
|
-
opencodeSkillDir: join(home, ".config", "opencode", "skills", opencodeSlug),
|
|
83
|
-
openclawSkillDir: join(home, ".openclaw", "skills", openclawSlug),
|
|
84
|
-
cursorMcpPath: join(home, ".cursor", "mcp.json"),
|
|
85
|
-
claudeMcpPath: join(home, ".claude.json"),
|
|
86
|
-
claudeDesktopMcpPath,
|
|
87
|
-
opencodeMcpPath: resolveOpenCodeConfigPathForInstall(home),
|
|
88
|
-
chatGptMcpPath,
|
|
89
|
-
codexConfigPath: join(home, ".codex", "config.toml"),
|
|
90
|
-
openclawConfigPath: resolveOpenclawConfigPath(home),
|
|
45
|
+
agentsSkillDir: join(home, ".agents", "skills", dirName),
|
|
46
|
+
agentsMcpPath: join(home, ".agents", "mcp.json"),
|
|
91
47
|
mcpName: mcpServerId(root),
|
|
92
|
-
skillDirName,
|
|
48
|
+
skillDirName: dirName,
|
|
93
49
|
};
|
|
94
50
|
}
|
|
@@ -28,8 +28,7 @@ afterEach(() => {
|
|
|
28
28
|
|
|
29
29
|
/** Tests for resolveInstallTargetPreview. */
|
|
30
30
|
describe("resolveInstallTargetPreview", () => {
|
|
31
|
-
|
|
32
|
-
test("mcp app previews MCP keys for all and mcp scopes", () => {
|
|
31
|
+
test("mcp app includes agentsMcp in all scope when mcpServer enabled", () => {
|
|
33
32
|
const program: CliProgram = {
|
|
34
33
|
key: "mcpapp",
|
|
35
34
|
version: "1",
|
|
@@ -39,38 +38,36 @@ describe("resolveInstallTargetPreview", () => {
|
|
|
39
38
|
};
|
|
40
39
|
const paths = resolveInstallPaths(program);
|
|
41
40
|
const preview = resolveInstallTargetPreview(program, paths);
|
|
42
|
-
expect(preview.
|
|
43
|
-
expect(preview.
|
|
44
|
-
expect(preview.
|
|
45
|
-
expect(preview.all.every((k) => k.endsWith("Mcp") || k === "configure")).toBe(true);
|
|
41
|
+
expect(preview.all).toEqual(["agentsMcp"]);
|
|
42
|
+
expect(preview.mcp).toEqual(["agentsMcp"]);
|
|
43
|
+
expect(preview.skill).toEqual([]);
|
|
46
44
|
});
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
test("shell app previews skill keys", () => {
|
|
46
|
+
test("skill app includes skill in all scope when enabled", () => {
|
|
50
47
|
const program: CliProgram = {
|
|
51
48
|
key: "cliapp",
|
|
52
49
|
version: "1",
|
|
53
50
|
description: "x",
|
|
51
|
+
skill: { enabled: true },
|
|
54
52
|
handler: () => {},
|
|
55
53
|
};
|
|
56
54
|
const paths = resolveInstallPaths(program);
|
|
57
55
|
const preview = resolveInstallTargetPreview(program, paths);
|
|
58
|
-
expect(preview.
|
|
59
|
-
expect(preview.
|
|
60
|
-
expect(preview.all.length).toBeGreaterThan(0);
|
|
56
|
+
expect(preview.all).toEqual(["skill"]);
|
|
57
|
+
expect(preview.skill).toEqual(["skill"]);
|
|
61
58
|
expect(preview.mcp).toEqual([]);
|
|
62
59
|
});
|
|
63
60
|
});
|
|
64
61
|
|
|
65
62
|
/** Tests for printInstallStatus json. */
|
|
66
63
|
describe("printInstallStatus json", () => {
|
|
67
|
-
|
|
68
|
-
test("includes agentIntegration and effective scopes", () => {
|
|
64
|
+
test("includes effective scopes", () => {
|
|
69
65
|
const program: CliProgram = {
|
|
70
66
|
key: "app",
|
|
71
67
|
version: "1",
|
|
72
68
|
description: "x",
|
|
73
69
|
mcpServer: { enabled: true },
|
|
70
|
+
skill: { enabled: true },
|
|
74
71
|
handler: () => {},
|
|
75
72
|
};
|
|
76
73
|
const chunks: string[] = [];
|
|
@@ -82,11 +79,11 @@ describe("printInstallStatus json", () => {
|
|
|
82
79
|
try {
|
|
83
80
|
printInstallStatus(program, { json: true });
|
|
84
81
|
const parsed = JSON.parse(chunks.join("")) as {
|
|
85
|
-
agentIntegration: string;
|
|
86
82
|
effective: { all: string[]; mcp: string[]; skill: string[] };
|
|
87
83
|
};
|
|
88
|
-
expect(parsed.
|
|
89
|
-
expect(parsed.effective.
|
|
84
|
+
expect(parsed.effective.all).toEqual(["skill", "agentsMcp"]);
|
|
85
|
+
expect(parsed.effective.skill).toEqual(["skill"]);
|
|
86
|
+
expect(parsed.effective.mcp).toEqual(["agentsMcp"]);
|
|
90
87
|
} finally {
|
|
91
88
|
process.stdout.write = orig;
|
|
92
89
|
}
|
|
@@ -34,7 +34,6 @@ export function printInstallStatus(root: CliProgram, opts: InstallOpts): void {
|
|
|
34
34
|
if (opts.json) {
|
|
35
35
|
const preview = resolveInstallTargetPreview(root, paths);
|
|
36
36
|
const json: Record<string, unknown> = {
|
|
37
|
-
agentIntegration: preview.agentIntegration,
|
|
38
37
|
effective: {
|
|
39
38
|
all: preview.all,
|
|
40
39
|
mcp: preview.mcp,
|
|
@@ -42,14 +41,8 @@ export function printInstallStatus(root: CliProgram, opts: InstallOpts): void {
|
|
|
42
41
|
},
|
|
43
42
|
};
|
|
44
43
|
if (status.app) json.app = status.app;
|
|
45
|
-
if (status.
|
|
46
|
-
if (status.
|
|
47
|
-
if (status.cursorMcp) json.cursorMcp = status.cursorMcp;
|
|
48
|
-
if (status.claudeMcp) json.claudeMcp = status.claudeMcp;
|
|
49
|
-
if (status.claudeDesktopMcp) json.claudeDesktopMcp = status.claudeDesktopMcp;
|
|
50
|
-
if (status.opencodeMcp) json.opencodeMcp = status.opencodeMcp;
|
|
51
|
-
if (status.codexMcp) json.codexMcp = status.codexMcp;
|
|
52
|
-
if (status.chatGptMcp) json.chatGptMcp = status.chatGptMcp;
|
|
44
|
+
if (status.skill) json.skill = status.skill;
|
|
45
|
+
if (status.agentsMcp) json.agentsMcp = status.agentsMcp;
|
|
53
46
|
process.stdout.write(`${JSON.stringify(json, null, 2)}\n`);
|
|
54
47
|
return;
|
|
55
48
|
}
|
|
@@ -57,14 +50,8 @@ export function printInstallStatus(root: CliProgram, opts: InstallOpts): void {
|
|
|
57
50
|
installOut(`Installed artifacts for ${root.key}:`, opts);
|
|
58
51
|
const lines: [string, string | undefined][] = [
|
|
59
52
|
["app", status.app],
|
|
60
|
-
["
|
|
61
|
-
["
|
|
62
|
-
["cursor mcp", status.cursorMcp],
|
|
63
|
-
["claude code mcp", status.claudeMcp],
|
|
64
|
-
["claude desktop mcp", status.claudeDesktopMcp],
|
|
65
|
-
["opencode mcp", status.opencodeMcp],
|
|
66
|
-
["codex mcp", status.codexMcp],
|
|
67
|
-
["chatgpt desktop mcp", status.chatGptMcp],
|
|
53
|
+
["agent skill", status.skill],
|
|
54
|
+
[".agents mcp", status.agentsMcp],
|
|
68
55
|
];
|
|
69
56
|
let any = false;
|
|
70
57
|
for (const [label, value] of lines) {
|
|
@@ -79,10 +66,6 @@ export function printInstallStatus(root: CliProgram, opts: InstallOpts): void {
|
|
|
79
66
|
|
|
80
67
|
const configStatus = appConfigStatus(root);
|
|
81
68
|
if (configStatus) {
|
|
82
|
-
installOut(` app config: ${configStatus
|
|
83
|
-
for (const req of configStatus.required) {
|
|
84
|
-
const bindingHint = req.binding && req.binding !== "missing" && req.set ? ` (${req.binding})` : "";
|
|
85
|
-
installOut(` ${req.key}: ${req.set ? "set" : "missing"}${bindingHint}`, opts);
|
|
86
|
-
}
|
|
69
|
+
installOut(` app config: ${configStatus}`, opts);
|
|
87
70
|
}
|
|
88
71
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type { CliProgram
|
|
1
|
+
import type { CliProgram } from "../../core/types.ts";
|
|
2
2
|
import type { InstallPaths } from "./paths.ts";
|
|
3
3
|
import type {
|
|
4
4
|
CliInstallArtifactKey,
|
|
5
5
|
DetectedSnapshot,
|
|
6
6
|
InstallAction,
|
|
7
|
-
InstallActionKind,
|
|
8
7
|
InstalledArtifacts,
|
|
9
8
|
InstallStatus,
|
|
10
|
-
InstallTargetCategory,
|
|
11
9
|
TargetPlanContext,
|
|
12
10
|
UninstallAction,
|
|
13
11
|
} from "./target-types.ts";
|
|
@@ -15,18 +13,11 @@ import type {
|
|
|
15
13
|
/** Shared lifecycle for one install artifact. */
|
|
16
14
|
export abstract class InstallTarget {
|
|
17
15
|
abstract readonly key: CliInstallArtifactKey;
|
|
18
|
-
abstract readonly actionKind: InstallActionKind;
|
|
19
|
-
abstract readonly category: InstallTargetCategory;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
defaultIncludedInAll(integration: InstallAgentIntegration): boolean {
|
|
25
|
-
if (this.category === "core") return true;
|
|
26
|
-
if (this.category === "mcp") {
|
|
27
|
-
return integration === "mcp" || integration === "both";
|
|
28
|
-
}
|
|
29
|
-
return integration === "skill" || integration === "both";
|
|
16
|
+
abstract readonly actionKind: import("./target-types.ts").InstallActionKind;
|
|
17
|
+
abstract readonly category: import("./target-types.ts").InstallTargetCategory;
|
|
18
|
+
|
|
19
|
+
defaultIncludedInAll(): boolean {
|
|
20
|
+
return false;
|
|
30
21
|
}
|
|
31
22
|
|
|
32
23
|
abstract isAvailable(root: CliProgram, paths: InstallPaths): boolean;
|
|
@@ -1,27 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CliConfigureConfig,
|
|
3
|
-
CliConfigureTargets,
|
|
4
|
-
CliProgram,
|
|
5
|
-
InstallAgentIntegration,
|
|
6
|
-
InstallTargetSpec,
|
|
7
|
-
} from "../../core/types.ts";
|
|
1
|
+
import type { CliConfigureConfig, CliProgram, InstallTargetSpec } from "../../core/types.ts";
|
|
8
2
|
import { resolveCapabilities } from "../../runtime/capabilities.ts";
|
|
9
|
-
import {
|
|
10
|
-
AGENT_PAIRS,
|
|
11
|
-
INSTALL_ARTIFACT_KEYS,
|
|
12
|
-
installTargetForKey,
|
|
13
|
-
mcpServerRequiredForArtifact,
|
|
14
|
-
} from "./target-registry.ts";
|
|
3
|
+
import { INSTALL_ARTIFACT_KEYS, installTargetForKey, mcpServerRequiredForArtifact } from "./target-registry.ts";
|
|
15
4
|
import type { CliInstallArtifactKey, InstallPlanMode } from "./target-types.ts";
|
|
16
5
|
|
|
17
6
|
export type { InstallTargetSpec, ResolvedInstallTarget } from "../../core/types.ts";
|
|
18
7
|
|
|
19
8
|
export type { InstallPlanMode, InstallScope } from "./target-types.ts";
|
|
20
9
|
|
|
21
|
-
export function resolveAgentIntegration(configure?: CliConfigureConfig, mcpEnabled = false): InstallAgentIntegration {
|
|
22
|
-
return configure?.agentIntegration ?? (mcpEnabled ? "mcp" : "skill");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
10
|
/** Resolves a boolean or object target spec against category defaults. */
|
|
26
11
|
export function resolveInstallTargetSpec(
|
|
27
12
|
spec: InstallTargetSpec | undefined,
|
|
@@ -44,56 +29,34 @@ export function resolveInstallTargetSpec(
|
|
|
44
29
|
|
|
45
30
|
function artifactDefaults(
|
|
46
31
|
key: CliInstallArtifactKey,
|
|
47
|
-
|
|
48
|
-
mcpServerEnabled: boolean,
|
|
32
|
+
program?: Pick<CliProgram, "mcpServer" | "skill">,
|
|
49
33
|
): { enabled: boolean; includedInAll: boolean } {
|
|
34
|
+
if (key === "skill") {
|
|
35
|
+
const on = program?.skill?.enabled === true;
|
|
36
|
+
return { enabled: on, includedInAll: on };
|
|
37
|
+
}
|
|
38
|
+
if (key === "agentsMcp") {
|
|
39
|
+
const on = program?.mcpServer?.enabled === true;
|
|
40
|
+
return { enabled: on, includedInAll: on };
|
|
41
|
+
}
|
|
50
42
|
const target = installTargetForKey(key);
|
|
51
|
-
|
|
52
|
-
if (!mcpServerRequiredForArtifact(key, mcpServerEnabled)) {
|
|
43
|
+
if (!mcpServerRequiredForArtifact(key, program?.mcpServer?.enabled === true)) {
|
|
53
44
|
return { enabled: false, includedInAll: false };
|
|
54
45
|
}
|
|
55
|
-
return { enabled: true, includedInAll };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function applyAgentPairDedupe(
|
|
59
|
-
out: Record<CliInstallArtifactKey, { enabled: boolean; includedInAll: boolean }>,
|
|
60
|
-
user: CliConfigureTargets | undefined,
|
|
61
|
-
integration: InstallAgentIntegration,
|
|
62
|
-
): void {
|
|
63
|
-
if (integration === "both") return;
|
|
64
|
-
|
|
65
|
-
for (const [mcpKey, skillKey] of AGENT_PAIRS) {
|
|
66
|
-
const mcp = out[mcpKey];
|
|
67
|
-
const skill = out[skillKey];
|
|
68
|
-
if (!mcp.includedInAll || !skill.includedInAll) continue;
|
|
69
|
-
|
|
70
|
-
const mcpKeyExplicit = user?.[mcpKey] !== undefined;
|
|
71
|
-
const skillKeyExplicit = user?.[skillKey] !== undefined;
|
|
72
|
-
|
|
73
|
-
if (mcpKeyExplicit && !skillKeyExplicit) continue;
|
|
74
|
-
if (skillKeyExplicit && !mcpKeyExplicit) continue;
|
|
75
|
-
|
|
76
|
-
if (integration === "mcp") {
|
|
77
|
-
out[skillKey] = { ...skill, includedInAll: false };
|
|
78
|
-
} else {
|
|
79
|
-
out[mcpKey] = { ...mcp, includedInAll: false };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
46
|
+
return { enabled: true, includedInAll: target?.defaultIncludedInAll() ?? false };
|
|
82
47
|
}
|
|
83
48
|
|
|
84
49
|
/** Effective per-artifact gates for install.targets. */
|
|
85
50
|
export function resolveEffectiveInstallTargets(
|
|
86
51
|
configure?: CliConfigureConfig,
|
|
87
|
-
program?: Pick<CliProgram, "mcpServer">,
|
|
52
|
+
program?: Pick<CliProgram, "mcpServer" | "skill">,
|
|
88
53
|
): Record<CliInstallArtifactKey, { enabled: boolean; includedInAll: boolean }> {
|
|
89
|
-
const mcpEnabled = program?.mcpServer?.enabled === true;
|
|
90
|
-
const integration = resolveAgentIntegration(configure, mcpEnabled);
|
|
91
54
|
const user = configure?.targets;
|
|
92
55
|
const out = {} as Record<CliInstallArtifactKey, { enabled: boolean; includedInAll: boolean }>;
|
|
93
56
|
for (const key of INSTALL_ARTIFACT_KEYS) {
|
|
94
|
-
|
|
57
|
+
const userSpec = key === "skill" || key === "agentsMcp" ? undefined : user?.[key];
|
|
58
|
+
out[key] = resolveInstallTargetSpec(userSpec, artifactDefaults(key, program));
|
|
95
59
|
}
|
|
96
|
-
applyAgentPairDedupe(out, user, integration);
|
|
97
60
|
return out;
|
|
98
61
|
}
|
|
99
62
|
|
|
@@ -103,7 +66,6 @@ export function mcpCategoryEnabled(root: CliProgram): boolean {
|
|
|
103
66
|
}
|
|
104
67
|
|
|
105
68
|
export interface InstallTargetPreview {
|
|
106
|
-
agentIntegration: InstallAgentIntegration;
|
|
107
69
|
all: CliInstallArtifactKey[];
|
|
108
70
|
mcp: CliInstallArtifactKey[];
|
|
109
71
|
skill: CliInstallArtifactKey[];
|
|
@@ -23,10 +23,9 @@ export interface McpJsonHostSpec {
|
|
|
23
23
|
key: CliInstallArtifactKey;
|
|
24
24
|
actionKind: InstallActionKind;
|
|
25
25
|
label: string;
|
|
26
|
-
pairedSkillKey?: CliInstallArtifactKey;
|
|
27
26
|
configPath: (paths: InstallPaths) => string;
|
|
28
|
-
detectedKey: keyof Pick<InstalledArtifacts, "
|
|
29
|
-
statusField: keyof Pick<InstallStatus, "
|
|
27
|
+
detectedKey: keyof Pick<InstalledArtifacts, "agentsMcp">;
|
|
28
|
+
statusField: keyof Pick<InstallStatus, "agentsMcp">;
|
|
30
29
|
isAvailable: (root: CliProgram, paths: InstallPaths) => boolean;
|
|
31
30
|
/** Append server name to status line (default false). */
|
|
32
31
|
statusIncludesServer?: boolean;
|
|
@@ -41,7 +40,6 @@ export class McpJsonInstallTarget extends InstallTarget {
|
|
|
41
40
|
readonly key: CliInstallArtifactKey;
|
|
42
41
|
readonly actionKind: InstallActionKind;
|
|
43
42
|
readonly category = "mcp" as const;
|
|
44
|
-
readonly pairedKey?: CliInstallArtifactKey;
|
|
45
43
|
|
|
46
44
|
private readonly spec: McpJsonHostSpec;
|
|
47
45
|
|
|
@@ -50,7 +48,6 @@ export class McpJsonInstallTarget extends InstallTarget {
|
|
|
50
48
|
this.spec = spec;
|
|
51
49
|
this.key = spec.key;
|
|
52
50
|
this.actionKind = spec.actionKind;
|
|
53
|
-
this.pairedKey = spec.pairedSkillKey;
|
|
54
51
|
}
|
|
55
52
|
|
|
56
53
|
isAvailable(root: CliProgram, paths: InstallPaths): boolean {
|
|
@@ -18,13 +18,6 @@ export const ACTION_KIND_TO_ARTIFACT: Record<InstallActionKind, CliInstallArtifa
|
|
|
18
18
|
INSTALL_TARGETS.map((t) => [t.actionKind, t.key]),
|
|
19
19
|
) as Record<InstallActionKind, CliInstallArtifactKey>;
|
|
20
20
|
|
|
21
|
-
/** Hosts with both MCP config and shell skill install targets. */
|
|
22
|
-
export const AGENT_PAIRS: [CliInstallArtifactKey, CliInstallArtifactKey][] = INSTALL_TARGETS.flatMap((t) =>
|
|
23
|
-
t.category === "mcp" && t.pairedKey !== undefined
|
|
24
|
-
? [[t.key, t.pairedKey] as [CliInstallArtifactKey, CliInstallArtifactKey]]
|
|
25
|
-
: [],
|
|
26
|
-
);
|
|
27
|
-
|
|
28
21
|
const targetByKey = new Map(INSTALL_TARGETS.map((t) => [t.key, t]));
|
|
29
22
|
|
|
30
23
|
/** Lookup a registered install target by artifact key. */
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
type InstallPlanMode,
|
|
7
7
|
type InstallScope,
|
|
8
8
|
type InstallTargetPreview,
|
|
9
|
-
resolveAgentIntegration,
|
|
10
9
|
resolveEffectiveInstallTargets,
|
|
11
10
|
resolveInstallPlanMode,
|
|
12
11
|
} from "./target-effective.ts";
|
|
@@ -30,18 +29,8 @@ export { mcpCategoryEnabled } from "./target-effective.ts";
|
|
|
30
29
|
function emptyInstalledArtifacts(): InstalledArtifacts {
|
|
31
30
|
return {
|
|
32
31
|
app: false,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
codexSkill: false,
|
|
36
|
-
opencodeSkill: false,
|
|
37
|
-
openclawSkill: false,
|
|
38
|
-
cursorMcp: false,
|
|
39
|
-
claudeMcp: false,
|
|
40
|
-
claudeDesktopMcp: false,
|
|
41
|
-
opencodeMcp: false,
|
|
42
|
-
codexMcp: false,
|
|
43
|
-
openclawMcp: false,
|
|
44
|
-
chatGptMcp: false,
|
|
32
|
+
skill: false,
|
|
33
|
+
agentsMcp: false,
|
|
45
34
|
};
|
|
46
35
|
}
|
|
47
36
|
|
|
@@ -75,6 +64,7 @@ export function buildDetectedSnapshot(root: CliProgram, paths: InstallPaths): De
|
|
|
75
64
|
}
|
|
76
65
|
|
|
77
66
|
function targetExplicitlyConfigured(user: CliConfigureTargets | undefined, key: CliInstallArtifactKey): boolean {
|
|
67
|
+
if (key === "skill" || key === "agentsMcp") return false;
|
|
78
68
|
return user?.[key] !== undefined;
|
|
79
69
|
}
|
|
80
70
|
|
|
@@ -101,6 +91,8 @@ export function isArtifactInScope(
|
|
|
101
91
|
root: CliProgram,
|
|
102
92
|
targets?: CliConfigureTargets,
|
|
103
93
|
): boolean {
|
|
94
|
+
const userTargets = targets ?? root.configure?.targets;
|
|
95
|
+
|
|
104
96
|
if (mode === "uninstall-all") {
|
|
105
97
|
return true;
|
|
106
98
|
}
|
|
@@ -119,10 +111,10 @@ export function isArtifactInScope(
|
|
|
119
111
|
|
|
120
112
|
let inScope = false;
|
|
121
113
|
if (scope.skill) {
|
|
122
|
-
inScope = inScope || agentCategoryInScope(key, SKILL_KEYS, "skill", effective,
|
|
114
|
+
inScope = inScope || agentCategoryInScope(key, SKILL_KEYS, "skill", effective, userTargets, root);
|
|
123
115
|
}
|
|
124
116
|
if (scope.mcp) {
|
|
125
|
-
inScope = inScope || agentCategoryInScope(key, MCP_KEYS, "mcp", effective,
|
|
117
|
+
inScope = inScope || agentCategoryInScope(key, MCP_KEYS, "mcp", effective, userTargets, root);
|
|
126
118
|
}
|
|
127
119
|
if (scope.configure && key === "configure") {
|
|
128
120
|
inScope = true;
|
|
@@ -225,13 +217,11 @@ export function detectedForArtifact(key: CliInstallArtifactKey, detected: Detect
|
|
|
225
217
|
/** Resolved artifact keys for `--all`, `--mcp`, and `--skill` (availability-gated). */
|
|
226
218
|
export function resolveInstallTargetPreview(program: CliProgram, paths: InstallPaths): InstallTargetPreview {
|
|
227
219
|
const effective = resolveEffectiveInstallTargets(program.configure, program);
|
|
228
|
-
const integration = resolveAgentIntegration(program.configure, program.mcpServer?.enabled === true);
|
|
229
220
|
|
|
230
221
|
const keysForScope = (scope: InstallScope, mode: InstallPlanMode): CliInstallArtifactKey[] =>
|
|
231
222
|
INSTALL_ARTIFACT_KEYS.filter((key) => shouldIncludeArtifact(key, program, paths, scope, mode, effective));
|
|
232
223
|
|
|
233
224
|
return {
|
|
234
|
-
agentIntegration: integration,
|
|
235
225
|
all: keysForScope({ all: true }, "install-all"),
|
|
236
226
|
mcp: keysForScope({ mcp: true }, "install-scoped"),
|
|
237
227
|
skill: keysForScope({ skill: true }, "install-scoped"),
|