argsbarg 6.1.9 → 6.2.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/CHANGELOG.md +17 -1
- package/README.md +187 -93
- package/docs/README.md +3 -2
- package/docs/ai-skills.md +36 -23
- package/docs/cli-program.md +12 -11
- package/docs/config-schema.md +3 -3
- package/docs/configure.md +12 -16
- package/docs/decisions.md +74 -37
- package/docs/developing.md +6 -6
- package/docs/distribution-homebrew.md +117 -104
- package/docs/mcp.md +21 -57
- package/docs/output-schema.md +2 -2
- package/examples/formats.ts +5 -6
- package/examples/full-example/README.md +7 -69
- 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 +3 -8
- 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 +22 -14
- 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/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/http-guide.ts +1 -1
- package/src/docs/mcp-guide.ts +41 -71
- package/src/docs/resolve.ts +1 -1
- package/src/docs/save.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
|
@@ -19,25 +19,17 @@ export interface SkillHostSpec {
|
|
|
19
19
|
actionKind: InstallActionKind;
|
|
20
20
|
label: string;
|
|
21
21
|
uninstallPrefix: string;
|
|
22
|
-
pairedMcpKey: CliInstallArtifactKey;
|
|
23
22
|
skillDir: (paths: InstallPaths) => string;
|
|
24
|
-
detectedKey:
|
|
25
|
-
|
|
26
|
-
"cursorSkill" | "claudeSkill" | "codexSkill" | "opencodeSkill" | "openclawSkill"
|
|
27
|
-
>;
|
|
28
|
-
statusField: keyof Pick<
|
|
29
|
-
InstallStatus,
|
|
30
|
-
"cursorSkill" | "claudeSkill" | "codexSkill" | "opencodeSkill" | "openclawSkill"
|
|
31
|
-
>;
|
|
23
|
+
detectedKey: "skill";
|
|
24
|
+
statusField: "skill";
|
|
32
25
|
isAvailable: (root: CliProgram, paths: InstallPaths) => boolean;
|
|
33
26
|
}
|
|
34
27
|
|
|
35
|
-
/** Agent shell skill directory install. */
|
|
28
|
+
/** Agent shell skill directory install (`~/.agents/skills/<key>/`). */
|
|
36
29
|
export class SkillInstallTarget extends InstallTarget {
|
|
37
30
|
readonly key: CliInstallArtifactKey;
|
|
38
31
|
readonly actionKind: InstallActionKind;
|
|
39
32
|
readonly category = "skill" as const;
|
|
40
|
-
readonly pairedKey: CliInstallArtifactKey;
|
|
41
33
|
readonly uninstallPrefix: string;
|
|
42
34
|
|
|
43
35
|
private readonly spec: SkillHostSpec;
|
|
@@ -47,7 +39,6 @@ export class SkillInstallTarget extends InstallTarget {
|
|
|
47
39
|
this.spec = spec;
|
|
48
40
|
this.key = spec.key;
|
|
49
41
|
this.actionKind = spec.actionKind;
|
|
50
|
-
this.pairedKey = spec.pairedMcpKey;
|
|
51
42
|
this.uninstallPrefix = spec.uninstallPrefix;
|
|
52
43
|
}
|
|
53
44
|
|
|
@@ -84,8 +75,8 @@ export class SkillInstallTarget extends InstallTarget {
|
|
|
84
75
|
return [
|
|
85
76
|
{
|
|
86
77
|
kind: this.actionKind,
|
|
87
|
-
summary: `${this.spec.label.toLowerCase()}
|
|
88
|
-
message: `Installing ${this.spec.label}
|
|
78
|
+
summary: `${this.spec.label.toLowerCase()}: ${displayInstallPath(dir)}/`,
|
|
79
|
+
message: `Installing ${this.spec.label.toLowerCase()} to ${displayInstallPath(dir)}/`,
|
|
89
80
|
run: () => [],
|
|
90
81
|
},
|
|
91
82
|
];
|
|
@@ -97,7 +88,7 @@ export class SkillInstallTarget extends InstallTarget {
|
|
|
97
88
|
{
|
|
98
89
|
kind: this.actionKind,
|
|
99
90
|
summary: `${this.uninstallPrefix}: ${displayInstallPath(dir)}/`,
|
|
100
|
-
message: `Removing ${this.spec.label}
|
|
91
|
+
message: `Removing ${this.spec.label.toLowerCase()} ${displayInstallPath(dir)}/`,
|
|
101
92
|
run: () => uninstallSkillDir(dir, ctx.dry),
|
|
102
93
|
},
|
|
103
94
|
];
|
|
@@ -14,37 +14,9 @@ export interface InstallScope {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Artifact keys for install.targets. */
|
|
17
|
-
export type CliInstallArtifactKey =
|
|
18
|
-
| "app"
|
|
19
|
-
| "chatgptMcp"
|
|
20
|
-
| "claudeCodeMcp"
|
|
21
|
-
| "claudeDesktopMcp"
|
|
22
|
-
| "claudeSkill"
|
|
23
|
-
| "codexMcp"
|
|
24
|
-
| "codexSkill"
|
|
25
|
-
| "configure"
|
|
26
|
-
| "cursorMcp"
|
|
27
|
-
| "cursorSkill"
|
|
28
|
-
| "openclawMcp"
|
|
29
|
-
| "openclawSkill"
|
|
30
|
-
| "opencodeMcp"
|
|
31
|
-
| "opencodeSkill";
|
|
17
|
+
export type CliInstallArtifactKey = "app" | "agentsMcp" | "configure" | "skill";
|
|
32
18
|
|
|
33
|
-
export type InstallActionKind =
|
|
34
|
-
| "app"
|
|
35
|
-
| "cursor-skill"
|
|
36
|
-
| "claude-skill"
|
|
37
|
-
| "codex-skill"
|
|
38
|
-
| "opencode-skill"
|
|
39
|
-
| "openclaw-skill"
|
|
40
|
-
| "cursor-mcp"
|
|
41
|
-
| "claude-mcp"
|
|
42
|
-
| "claude-desktop-mcp"
|
|
43
|
-
| "opencode-mcp"
|
|
44
|
-
| "codex-mcp"
|
|
45
|
-
| "openclaw-mcp"
|
|
46
|
-
| "chatgpt-desktop-mcp"
|
|
47
|
-
| "configure";
|
|
19
|
+
export type InstallActionKind = "app" | "agent-skill" | "agents-mcp" | "configure";
|
|
48
20
|
|
|
49
21
|
export type InstallTargetCategory = "core" | "skill" | "mcp";
|
|
50
22
|
|
|
@@ -64,34 +36,14 @@ export interface UninstallAction {
|
|
|
64
36
|
|
|
65
37
|
export interface InstalledArtifacts {
|
|
66
38
|
app: boolean;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
codexSkill: boolean;
|
|
70
|
-
opencodeSkill: boolean;
|
|
71
|
-
openclawSkill: boolean;
|
|
72
|
-
cursorMcp: boolean;
|
|
73
|
-
claudeMcp: boolean;
|
|
74
|
-
claudeDesktopMcp: boolean;
|
|
75
|
-
opencodeMcp: boolean;
|
|
76
|
-
codexMcp: boolean;
|
|
77
|
-
openclawMcp: boolean;
|
|
78
|
-
chatGptMcp: boolean;
|
|
39
|
+
skill: boolean;
|
|
40
|
+
agentsMcp: boolean;
|
|
79
41
|
}
|
|
80
42
|
|
|
81
43
|
export interface InstallStatus {
|
|
82
44
|
app?: string;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
codexSkill?: string;
|
|
86
|
-
opencodeSkill?: string;
|
|
87
|
-
openclawSkill?: string;
|
|
88
|
-
cursorMcp?: string;
|
|
89
|
-
claudeMcp?: string;
|
|
90
|
-
claudeDesktopMcp?: string;
|
|
91
|
-
opencodeMcp?: string;
|
|
92
|
-
codexMcp?: string;
|
|
93
|
-
openclawMcp?: string;
|
|
94
|
-
chatGptMcp?: string;
|
|
45
|
+
skill?: string;
|
|
46
|
+
agentsMcp?: string;
|
|
95
47
|
}
|
|
96
48
|
|
|
97
49
|
export interface DetectedSnapshot extends InstalledArtifacts {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { McpJsonInstallTarget } from "../target-mcp-json.ts";
|
|
2
|
+
|
|
3
|
+
export const agentsMcpTarget = new McpJsonInstallTarget({
|
|
4
|
+
key: "agentsMcp",
|
|
5
|
+
actionKind: "agents-mcp",
|
|
6
|
+
label: "agents mcp",
|
|
7
|
+
configPath: (p) => p.agentsMcpPath,
|
|
8
|
+
detectedKey: "agentsMcp",
|
|
9
|
+
statusField: "agentsMcp",
|
|
10
|
+
isAvailable: (_root, _paths) => true,
|
|
11
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { appConfigInstalled, displayAppConfigPath, uninstallAppConfig } from "../../../config/file.ts";
|
|
2
|
-
import type { CliProgram
|
|
2
|
+
import type { CliProgram } from "../../../core/types.ts";
|
|
3
3
|
import type { InstallPaths } from "../paths.ts";
|
|
4
4
|
import { InstallTarget } from "../target-base.ts";
|
|
5
5
|
import type {
|
|
@@ -17,10 +17,6 @@ class ConfigureInstallTarget extends InstallTarget {
|
|
|
17
17
|
readonly actionKind = "configure" as const;
|
|
18
18
|
readonly category = "core" as const;
|
|
19
19
|
|
|
20
|
-
defaultIncludedInAll(_integration: InstallAgentIntegration): boolean {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
20
|
isAvailable(root: CliProgram, _paths: InstallPaths): boolean {
|
|
25
21
|
return root.appConfig !== undefined;
|
|
26
22
|
}
|
|
@@ -1,50 +1,10 @@
|
|
|
1
1
|
import type { InstallTarget } from "../target-base.ts";
|
|
2
|
+
import { agentsMcpTarget } from "./agents-mcp.ts";
|
|
2
3
|
import { appTarget } from "./app.ts";
|
|
3
|
-
import { chatgptMcpTarget } from "./chatgpt-mcp.ts";
|
|
4
|
-
import { claudeCodeMcpTarget } from "./claude-code-mcp.ts";
|
|
5
|
-
import { claudeDesktopMcpTarget } from "./claude-desktop-mcp.ts";
|
|
6
|
-
import { claudeSkillTarget } from "./claude-skill.ts";
|
|
7
|
-
import { codexMcpTarget } from "./codex-mcp.ts";
|
|
8
|
-
import { codexSkillTarget } from "./codex-skill.ts";
|
|
9
4
|
import { configureTarget } from "./configure.ts";
|
|
10
|
-
import {
|
|
11
|
-
import { cursorSkillTarget } from "./cursor-skill.ts";
|
|
12
|
-
import { openclawMcpTarget } from "./openclaw-mcp.ts";
|
|
13
|
-
import { openclawSkillTarget } from "./openclaw-skill.ts";
|
|
14
|
-
import { opencodeMcpTarget } from "./opencode-mcp.ts";
|
|
15
|
-
import { opencodeSkillTarget } from "./opencode-skill.ts";
|
|
5
|
+
import { skillTarget } from "./skill.ts";
|
|
16
6
|
|
|
17
7
|
/** Ordered install targets (plan iteration order). */
|
|
18
|
-
export const INSTALL_TARGETS: InstallTarget[] = [
|
|
19
|
-
appTarget,
|
|
20
|
-
cursorSkillTarget,
|
|
21
|
-
claudeSkillTarget,
|
|
22
|
-
codexSkillTarget,
|
|
23
|
-
opencodeSkillTarget,
|
|
24
|
-
openclawSkillTarget,
|
|
25
|
-
cursorMcpTarget,
|
|
26
|
-
claudeCodeMcpTarget,
|
|
27
|
-
claudeDesktopMcpTarget,
|
|
28
|
-
opencodeMcpTarget,
|
|
29
|
-
codexMcpTarget,
|
|
30
|
-
openclawMcpTarget,
|
|
31
|
-
chatgptMcpTarget,
|
|
32
|
-
configureTarget,
|
|
33
|
-
];
|
|
8
|
+
export const INSTALL_TARGETS: InstallTarget[] = [appTarget, skillTarget, agentsMcpTarget, configureTarget];
|
|
34
9
|
|
|
35
|
-
export {
|
|
36
|
-
appTarget,
|
|
37
|
-
chatgptMcpTarget,
|
|
38
|
-
claudeCodeMcpTarget,
|
|
39
|
-
claudeDesktopMcpTarget,
|
|
40
|
-
claudeSkillTarget,
|
|
41
|
-
codexMcpTarget,
|
|
42
|
-
codexSkillTarget,
|
|
43
|
-
configureTarget,
|
|
44
|
-
cursorMcpTarget,
|
|
45
|
-
cursorSkillTarget,
|
|
46
|
-
openclawMcpTarget,
|
|
47
|
-
openclawSkillTarget,
|
|
48
|
-
opencodeMcpTarget,
|
|
49
|
-
opencodeSkillTarget,
|
|
50
|
-
};
|
|
10
|
+
export { agentsMcpTarget, appTarget, configureTarget, skillTarget };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SkillInstallTarget } from "../target-skill.ts";
|
|
2
|
+
|
|
3
|
+
export const skillTarget = new SkillInstallTarget({
|
|
4
|
+
key: "skill",
|
|
5
|
+
actionKind: "agent-skill",
|
|
6
|
+
label: "Agent skill",
|
|
7
|
+
uninstallPrefix: "agent skill",
|
|
8
|
+
skillDir: (p) => p.agentsSkillDir,
|
|
9
|
+
detectedKey: "skill",
|
|
10
|
+
statusField: "skill",
|
|
11
|
+
isAvailable: (root) => root.skill?.enabled === true,
|
|
12
|
+
});
|
|
@@ -6,7 +6,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
6
6
|
import type { CliProgram } from "../../core/types.ts";
|
|
7
7
|
import { normalizeInstallRawOpts } from "./normalize.ts";
|
|
8
8
|
import { normalizeUninstallRawOpts } from "./normalize-uninstall.ts";
|
|
9
|
-
import {
|
|
9
|
+
import { resolveEffectiveInstallTargets } from "./target-effective.ts";
|
|
10
10
|
import { isArtifactInScope } from "./target-scope.ts";
|
|
11
11
|
|
|
12
12
|
/** Tests for normalizeInstallRawOpts. */
|
|
@@ -27,17 +27,6 @@ describe("normalizeInstallRawOpts", () => {
|
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
/** Tests for resolveAgentIntegration. */
|
|
31
|
-
describe("resolveAgentIntegration", () => {
|
|
32
|
-
test("defaults to skill without MCP", () => {
|
|
33
|
-
expect(resolveAgentIntegration(undefined, false)).toBe("skill");
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("defaults to mcp when MCP enabled", () => {
|
|
37
|
-
expect(resolveAgentIntegration(undefined, true)).toBe("mcp");
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
30
|
/** Tests for resolveEffectiveInstallTargets. */
|
|
42
31
|
describe("resolveEffectiveInstallTargets", () => {
|
|
43
32
|
test("defaults app and configure not in --all", () => {
|
|
@@ -46,77 +35,50 @@ describe("resolveEffectiveInstallTargets", () => {
|
|
|
46
35
|
expect(t.configure.includedInAll).toBe(false);
|
|
47
36
|
});
|
|
48
37
|
|
|
49
|
-
test("skill
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
expect(t.
|
|
53
|
-
expect(t.
|
|
54
|
-
expect(t.cursorMcp.includedInAll).toBe(false);
|
|
55
|
-
expect(t.cursorMcp.enabled).toBe(false);
|
|
38
|
+
test("skill disabled by default", () => {
|
|
39
|
+
const t = resolveEffectiveInstallTargets(undefined, {});
|
|
40
|
+
expect(t.skill.enabled).toBe(false);
|
|
41
|
+
expect(t.skill.includedInAll).toBe(false);
|
|
42
|
+
expect(t.agentsMcp.includedInAll).toBe(false);
|
|
56
43
|
});
|
|
57
44
|
|
|
58
|
-
test("
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
expect(t.
|
|
62
|
-
expect(t.cursorSkill.includedInAll).toBe(false);
|
|
63
|
-
expect(t.claudeDesktopMcp.includedInAll).toBe(true);
|
|
45
|
+
test("skill enabled via program.skill", () => {
|
|
46
|
+
const t = resolveEffectiveInstallTargets(undefined, { skill: { enabled: true } });
|
|
47
|
+
expect(t.skill.enabled).toBe(true);
|
|
48
|
+
expect(t.skill.includedInAll).toBe(true);
|
|
64
49
|
});
|
|
65
50
|
|
|
66
|
-
test("
|
|
51
|
+
test("agentsMcp in --all when mcpServer enabled", () => {
|
|
67
52
|
const program: Pick<CliProgram, "mcpServer"> = { mcpServer: { enabled: true } };
|
|
68
|
-
const t = resolveEffectiveInstallTargets(
|
|
69
|
-
expect(t.
|
|
70
|
-
expect(t.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
test("per-key override disables one skill", () => {
|
|
74
|
-
const t = resolveEffectiveInstallTargets({
|
|
75
|
-
targets: { cursorSkill: false },
|
|
76
|
-
});
|
|
77
|
-
expect(t.claudeSkill.includedInAll).toBe(true);
|
|
78
|
-
expect(t.cursorSkill.enabled).toBe(false);
|
|
53
|
+
const t = resolveEffectiveInstallTargets(undefined, program);
|
|
54
|
+
expect(t.agentsMcp.enabled).toBe(true);
|
|
55
|
+
expect(t.agentsMcp.includedInAll).toBe(true);
|
|
56
|
+
expect(t.skill.includedInAll).toBe(false);
|
|
79
57
|
});
|
|
80
58
|
|
|
81
|
-
|
|
82
|
-
test("scoped --mcp uses effective targets not all MCP hosts", () => {
|
|
59
|
+
test("scoped --mcp includes agentsMcp when mcpServer enabled", () => {
|
|
83
60
|
const program: CliProgram = {
|
|
84
61
|
key: "app",
|
|
85
62
|
version: "1",
|
|
86
63
|
description: "x",
|
|
87
64
|
mcpServer: { enabled: true },
|
|
88
|
-
configure: { agentIntegration: "skill" },
|
|
89
65
|
handler: () => {},
|
|
90
66
|
};
|
|
91
67
|
const effective = resolveEffectiveInstallTargets(program.configure, program);
|
|
92
68
|
const scope = { mcp: true };
|
|
93
|
-
expect(isArtifactInScope("
|
|
94
|
-
expect(
|
|
95
|
-
isArtifactInScope(
|
|
96
|
-
"cursorMcp",
|
|
97
|
-
scope,
|
|
98
|
-
resolveEffectiveInstallTargets({ targets: { cursorMcp: true }, agentIntegration: "both" }, program),
|
|
99
|
-
"install-scoped",
|
|
100
|
-
program,
|
|
101
|
-
),
|
|
102
|
-
).toBe(true);
|
|
69
|
+
expect(isArtifactInScope("agentsMcp", scope, effective, "install-scoped", program)).toBe(true);
|
|
103
70
|
});
|
|
104
71
|
|
|
105
|
-
|
|
106
|
-
test("scoped --mcp --skill --configure includes skill and mcp not only configure", () => {
|
|
72
|
+
test("scoped --skill includes skill when program.skill.enabled", () => {
|
|
107
73
|
const program: CliProgram = {
|
|
108
74
|
key: "app",
|
|
109
75
|
version: "1",
|
|
110
76
|
description: "x",
|
|
111
|
-
|
|
112
|
-
configure: { agentIntegration: "both" },
|
|
77
|
+
skill: { enabled: true },
|
|
113
78
|
handler: () => {},
|
|
114
79
|
};
|
|
115
80
|
const effective = resolveEffectiveInstallTargets(program.configure, program);
|
|
116
|
-
const scope = {
|
|
117
|
-
expect(isArtifactInScope("
|
|
118
|
-
expect(isArtifactInScope("cursorMcp", scope, effective, "install-scoped", program)).toBe(true);
|
|
119
|
-
expect(isArtifactInScope("configure", scope, effective, "install-scoped", program)).toBe(true);
|
|
120
|
-
expect(isArtifactInScope("claudeSkill", scope, effective, "install-scoped", program)).toBe(true);
|
|
81
|
+
const scope = { skill: true };
|
|
82
|
+
expect(isArtifactInScope("skill", scope, effective, "install-scoped", program)).toBe(true);
|
|
121
83
|
});
|
|
122
84
|
});
|
|
@@ -28,6 +28,7 @@ const fixture: CliProgram = {
|
|
|
28
28
|
version: "0.0.0",
|
|
29
29
|
description: "Test",
|
|
30
30
|
mcpServer: { enabled: true },
|
|
31
|
+
skill: { enabled: true },
|
|
31
32
|
handler: () => {},
|
|
32
33
|
};
|
|
33
34
|
|
|
@@ -72,7 +73,7 @@ describe("configure opts", () => {
|
|
|
72
73
|
describe("configure mutation summary", () => {
|
|
73
74
|
test("interactive uninstall reports removed artifacts not file count", () => {
|
|
74
75
|
const msg = formatConfigureMutationSummary(
|
|
75
|
-
{ paths: ["~/.
|
|
76
|
+
{ paths: ["~/.agents/skills/testapp/"], installed: 0, removed: 1, configured: 0 },
|
|
76
77
|
{},
|
|
77
78
|
);
|
|
78
79
|
expect(msg).toBe("Removed 1 artifact.");
|
|
@@ -81,7 +82,7 @@ describe("configure mutation summary", () => {
|
|
|
81
82
|
test("interactive install reports installed artifacts not file count", () => {
|
|
82
83
|
const msg = formatConfigureMutationSummary(
|
|
83
84
|
{
|
|
84
|
-
paths: ["~/.
|
|
85
|
+
paths: ["~/.agents/skills/testapp/SKILL.md", "~/.agents/skills/testapp/reference.md"],
|
|
85
86
|
installed: 1,
|
|
86
87
|
removed: 0,
|
|
87
88
|
configured: 0,
|
|
@@ -110,10 +111,10 @@ describe("configure mutation summary", () => {
|
|
|
110
111
|
|
|
111
112
|
/** Tests for install paths. */
|
|
112
113
|
describe("install paths", () => {
|
|
113
|
-
test("resolveInstallPaths includes skill and mcp paths", () => {
|
|
114
|
+
test("resolveInstallPaths includes agents skill and mcp paths", () => {
|
|
114
115
|
const paths = resolveInstallPaths(fixture);
|
|
115
|
-
expect(paths.
|
|
116
|
-
expect(paths.
|
|
116
|
+
expect(paths.agentsSkillDir).toContain(".agents/skills");
|
|
117
|
+
expect(paths.agentsMcpPath).toContain(".agents/mcp.json");
|
|
117
118
|
});
|
|
118
119
|
|
|
119
120
|
test("claude desktop mcp path on darwin", () => {
|
|
@@ -131,28 +132,28 @@ describe("install paths", () => {
|
|
|
131
132
|
|
|
132
133
|
/** Tests for detect installed. */
|
|
133
134
|
describe("detect installed", () => {
|
|
134
|
-
|
|
135
|
-
test("detects cursor mcp when configured", () => {
|
|
135
|
+
test("detects agents mcp when configured", () => {
|
|
136
136
|
const paths = resolveInstallPaths(fixture);
|
|
137
|
-
mkdirSync(join(home, ".
|
|
137
|
+
mkdirSync(join(home, ".agents"), { recursive: true });
|
|
138
138
|
writeFileSync(
|
|
139
|
-
paths.
|
|
139
|
+
paths.agentsMcpPath,
|
|
140
140
|
JSON.stringify({ mcpServers: { testapp: { command: "testapp", args: ["mcp"] } } }),
|
|
141
141
|
"utf8",
|
|
142
142
|
);
|
|
143
143
|
|
|
144
144
|
const detected = detectInstalledArtifacts(paths, fixture);
|
|
145
|
-
expect(detected.
|
|
145
|
+
expect(detected.agentsMcp).toBe(true);
|
|
146
146
|
expect(detected.app).toBe(false);
|
|
147
147
|
});
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
/** Tests for sync plan. */
|
|
151
151
|
describe("sync plan", () => {
|
|
152
|
-
test("buildUpdatePlan greenfield includes
|
|
152
|
+
test("buildUpdatePlan greenfield includes skill when enabled", () => {
|
|
153
153
|
const paths = resolveInstallPaths(fixture);
|
|
154
154
|
const plan = buildUpdatePlan(fixture, paths, parseInstallOpts({ reinstall: "1", yes: "1" }));
|
|
155
155
|
expect(plan.length).toBeGreaterThan(0);
|
|
156
|
+
expect(plan.some((a) => a.kind === "agent-skill")).toBe(true);
|
|
156
157
|
expect(plan.some((a) => a.kind === "app")).toBe(false);
|
|
157
158
|
});
|
|
158
159
|
|
|
@@ -160,19 +161,14 @@ describe("sync plan", () => {
|
|
|
160
161
|
const paths = resolveInstallPaths(fixture);
|
|
161
162
|
const plan = buildInstallPlan(fixture, paths, parseInstallOpts({ all: "1" }));
|
|
162
163
|
expect(plan.some((a) => a.kind === "app")).toBe(false);
|
|
163
|
-
expect(plan.some((a) => a.kind
|
|
164
|
+
expect(plan.some((a) => a.kind === "agent-skill")).toBe(true);
|
|
165
|
+
expect(plan.some((a) => a.kind === "agents-mcp")).toBe(true);
|
|
164
166
|
});
|
|
165
167
|
|
|
166
|
-
test("buildInstallPlan
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
};
|
|
171
|
-
const paths = resolveInstallPaths(skillApp);
|
|
172
|
-
mkdirSync(join(home, ".claude"), { recursive: true });
|
|
173
|
-
mkdirSync(join(home, ".cursor"), { recursive: true });
|
|
174
|
-
const plan = buildInstallPlan(skillApp, paths, parseInstallOpts({ mcp: "1" }));
|
|
175
|
-
expect(plan.some((a) => a.kind.endsWith("-mcp"))).toBe(false);
|
|
168
|
+
test("buildInstallPlan --mcp scoped includes agentsMcp when mcp enabled", () => {
|
|
169
|
+
const paths = resolveInstallPaths(fixture);
|
|
170
|
+
const plan = buildInstallPlan(fixture, paths, parseInstallOpts({ mcp: "1" }));
|
|
171
|
+
expect(plan.some((a) => a.kind === "agents-mcp")).toBe(true);
|
|
176
172
|
});
|
|
177
173
|
});
|
|
178
174
|
|
|
@@ -184,43 +180,35 @@ describe("remove plan", () => {
|
|
|
184
180
|
expect(plan.length).toBe(0);
|
|
185
181
|
});
|
|
186
182
|
|
|
187
|
-
test("configure --remove-all removes installed
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
};
|
|
192
|
-
const paths = resolveInstallPaths(skillApp);
|
|
193
|
-
mkdirSync(paths.cursorSkillDir, { recursive: true });
|
|
194
|
-
writeFileSync(join(paths.cursorSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
183
|
+
test("configure --remove-all removes installed agent skill", async () => {
|
|
184
|
+
const paths = resolveInstallPaths(fixture);
|
|
185
|
+
mkdirSync(paths.agentsSkillDir, { recursive: true });
|
|
186
|
+
writeFileSync(join(paths.agentsSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
195
187
|
|
|
196
|
-
expect(detectInstalledArtifacts(paths,
|
|
188
|
+
expect(detectInstalledArtifacts(paths, fixture).skill).toBe(true);
|
|
197
189
|
|
|
198
|
-
const result = await new Cli(
|
|
190
|
+
const result = await new Cli(fixture).invoke(["configure", "--remove-all", "--yes"]);
|
|
199
191
|
expect(result.exitCode).toBe(0);
|
|
200
|
-
expect(existsSync(paths.
|
|
192
|
+
expect(existsSync(paths.agentsSkillDir)).toBe(false);
|
|
201
193
|
});
|
|
202
194
|
|
|
203
|
-
test("scoped skill uninstall action removes directory
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
};
|
|
208
|
-
const paths = resolveInstallPaths(skillApp);
|
|
209
|
-
mkdirSync(paths.cursorSkillDir, { recursive: true });
|
|
210
|
-
writeFileSync(join(paths.cursorSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
195
|
+
test("scoped skill uninstall action removes directory", () => {
|
|
196
|
+
const paths = resolveInstallPaths(fixture);
|
|
197
|
+
mkdirSync(paths.agentsSkillDir, { recursive: true });
|
|
198
|
+
writeFileSync(join(paths.agentsSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
211
199
|
|
|
212
|
-
const detected = buildDetectedSnapshot(
|
|
213
|
-
const ctx = buildTargetPlanContext(
|
|
214
|
-
const target = installTargetForKey("
|
|
200
|
+
const detected = buildDetectedSnapshot(fixture, paths);
|
|
201
|
+
const ctx = buildTargetPlanContext(fixture, paths, {}, detected);
|
|
202
|
+
const target = installTargetForKey("skill");
|
|
215
203
|
expect(target).toBeDefined();
|
|
216
204
|
const actions = target!.planUninstall({
|
|
217
205
|
...ctx,
|
|
218
206
|
mode: "uninstall-scoped",
|
|
219
|
-
include: (key) => key === "
|
|
207
|
+
include: (key) => key === "skill",
|
|
220
208
|
});
|
|
221
209
|
expect(actions).toHaveLength(1);
|
|
222
210
|
expect(actions[0]!.run().length).toBeGreaterThan(0);
|
|
223
|
-
expect(existsSync(paths.
|
|
211
|
+
expect(existsSync(paths.agentsSkillDir)).toBe(false);
|
|
224
212
|
});
|
|
225
213
|
});
|
|
226
214
|
|
|
@@ -247,6 +235,7 @@ describe("configure --sync bootstrap", () => {
|
|
|
247
235
|
key: "syncboot",
|
|
248
236
|
version: "0.0.0",
|
|
249
237
|
description: "Sync bootstrap test.",
|
|
238
|
+
skill: { enabled: true },
|
|
250
239
|
handler: () => {},
|
|
251
240
|
configure: { enabled: true },
|
|
252
241
|
};
|
package/src/configure/index.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { displayAppConfigPath, runConfigure } from "../config/bootstrap.ts";
|
|
|
6
6
|
import { ensureAppConfigFile } from "../config/file.ts";
|
|
7
7
|
import type { CliProgram } from "../core/types.ts";
|
|
8
8
|
import { resolveCapabilities } from "../runtime/capabilities.ts";
|
|
9
|
-
import { cliSkillInstall,
|
|
10
|
-
import { resolveInstallPaths } from "./artifacts/paths.ts";
|
|
9
|
+
import { cliSkillInstall, isAgentSkillActionKind } from "../skill/install.ts";
|
|
10
|
+
import { displayInstallPath, resolveInstallPaths } from "./artifacts/paths.ts";
|
|
11
11
|
import { buildInstallPlan, buildUpdatePlan } from "./artifacts/plan.ts";
|
|
12
12
|
import {
|
|
13
13
|
installErr,
|
|
@@ -23,7 +23,6 @@ import { buildDetectedSnapshot, buildTargetPlanContext } from "./artifacts/targe
|
|
|
23
23
|
import type {
|
|
24
24
|
CliInstallArtifactKey,
|
|
25
25
|
InstallAction,
|
|
26
|
-
InstallActionKind,
|
|
27
26
|
InstallOpts,
|
|
28
27
|
TargetPlanContext,
|
|
29
28
|
UninstallAction,
|
|
@@ -94,11 +93,9 @@ function configureToInstallOpts(opts: ConfigureOpts): InstallOpts {
|
|
|
94
93
|
return { dry: opts.dry, json: opts.json };
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
/** Installs
|
|
98
|
-
function runSkillAction(root: CliProgram,
|
|
99
|
-
|
|
100
|
-
if (!target) return [];
|
|
101
|
-
return cliSkillInstall(root, target, {
|
|
96
|
+
/** Installs the agent skill bundle and returns changed paths. */
|
|
97
|
+
function runSkillAction(root: CliProgram, opts: InstallOpts): string[] {
|
|
98
|
+
return cliSkillInstall(root, {
|
|
102
99
|
global: true,
|
|
103
100
|
rimraf: true,
|
|
104
101
|
dry: opts.dry,
|
|
@@ -171,17 +168,14 @@ function runPlanAction(
|
|
|
171
168
|
opts: InstallOpts,
|
|
172
169
|
paths: ReturnType<typeof resolveInstallPaths>,
|
|
173
170
|
): string[] {
|
|
174
|
-
if ("kind" in action && action.kind) {
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const skillDir = skillDirFromUninstallSummary(action.summary, paths);
|
|
181
|
-
return skillDir ? uninstallSkillDir(skillDir, !!opts.dry) : [];
|
|
182
|
-
}
|
|
183
|
-
return runSkillAction(root, action.kind as InstallActionKind, opts);
|
|
171
|
+
if ("kind" in action && action.kind && isAgentSkillActionKind(action.kind)) {
|
|
172
|
+
const runResult = action.run();
|
|
173
|
+
if (runResult.length > 0) return runResult;
|
|
174
|
+
if (opts.uninstall) {
|
|
175
|
+
const skillDir = skillDirFromUninstallSummary(action.summary, paths);
|
|
176
|
+
return skillDir ? uninstallSkillDir(skillDir, !!opts.dry) : [];
|
|
184
177
|
}
|
|
178
|
+
return runSkillAction(root, opts);
|
|
185
179
|
}
|
|
186
180
|
if (!("kind" in action) || !action.kind) {
|
|
187
181
|
const skillDir = skillDirFromUninstallSummary(action.summary, paths);
|
|
@@ -205,6 +199,12 @@ function executePlan(
|
|
|
205
199
|
}
|
|
206
200
|
const changed = runPlanAction(root, action, opts, paths);
|
|
207
201
|
if (changed.length === 0) continue;
|
|
202
|
+
if (action.kind === "agent-skill" && !opts.uninstall && !opts.dry) {
|
|
203
|
+
installOut(`Skill installed to ${displayInstallPath(paths.agentsSkillDir)}/`, opts);
|
|
204
|
+
}
|
|
205
|
+
if (action.kind === "agents-mcp" && !opts.uninstall && !opts.dry) {
|
|
206
|
+
installOut(`MCP server registered in ${displayInstallPath(paths.agentsMcpPath)}`, opts);
|
|
207
|
+
}
|
|
208
208
|
if (action.kind === "configure") {
|
|
209
209
|
recordArtifactMutation(summary, changed, opts.uninstall ? "removed" : "configured");
|
|
210
210
|
} else {
|
|
@@ -264,7 +264,7 @@ async function runInteractiveConfigure(root: CliProgram, opts: ConfigureOpts): P
|
|
|
264
264
|
const summary = emptyMutationSummary();
|
|
265
265
|
|
|
266
266
|
for (const target of INSTALL_TARGETS) {
|
|
267
|
-
if (target.key === "app") continue;
|
|
267
|
+
if (target.key === "app" || target.key === "skill" || target.key === "agentsMcp") continue;
|
|
268
268
|
if (!effective[target.key].enabled) continue;
|
|
269
269
|
if (target.key !== "configure" && !target.isAvailable(root, paths)) continue;
|
|
270
270
|
if (target.key === "configure" && !root.appConfig) continue;
|
package/src/configure/prompt.ts
CHANGED
|
@@ -8,18 +8,8 @@ import type { CliInstallArtifactKey } from "./artifacts/target-types.ts";
|
|
|
8
8
|
/** Human-readable labels for each install artifact key in interactive prompts. */
|
|
9
9
|
const LABELS: Record<CliInstallArtifactKey, string> = {
|
|
10
10
|
app: "App binary",
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
codexSkill: "Codex skill",
|
|
14
|
-
opencodeSkill: "OpenCode skill",
|
|
15
|
-
openclawSkill: "OpenClaw skill",
|
|
16
|
-
cursorMcp: "Cursor MCP",
|
|
17
|
-
claudeCodeMcp: "Claude Code MCP",
|
|
18
|
-
claudeDesktopMcp: "Claude Desktop MCP",
|
|
19
|
-
opencodeMcp: "OpenCode MCP",
|
|
20
|
-
codexMcp: "Codex MCP",
|
|
21
|
-
openclawMcp: "OpenClaw MCP",
|
|
22
|
-
chatgptMcp: "ChatGPT desktop MCP",
|
|
11
|
+
skill: "Agent skill",
|
|
12
|
+
agentsMcp: "Agents MCP",
|
|
23
13
|
configure: "App config",
|
|
24
14
|
};
|
|
25
15
|
|