argsbarg 4.0.4 → 4.1.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 +30 -1
- package/README.md +5 -5
- package/docs/ai-skills.md +8 -5
- package/docs/cli-program.md +4 -4
- package/docs/config-schema.md +1 -4
- package/docs/developing.md +1 -1
- package/docs/install.md +160 -39
- package/docs/mcp.md +21 -9
- package/docs/templates/cursor/rules/cli-program.mdc +1 -1
- package/examples/config-app/program.ts +0 -3
- package/examples/consumer-app/README.md +0 -1
- package/examples/consumer-app/src/program.ts +3 -3
- package/examples/mcp-test.ts +8 -24
- package/index.d.ts +60 -5
- package/package.json +1 -1
- package/src/builtins/builtins.test.ts +20 -4
- package/src/builtins/config.test.ts +31 -25
- package/src/builtins/config.ts +4 -3
- package/src/builtins/install.ts +50 -57
- package/src/builtins/mcp.ts +1 -1
- package/src/capabilities.ts +4 -4
- package/src/cli.ts +2 -0
- package/src/config/bootstrap.ts +167 -66
- package/src/config/context.test.ts +22 -36
- package/src/config/context.ts +5 -4
- package/src/config/file.test.ts +66 -56
- package/src/config/file.ts +33 -25
- package/src/config/resolve.test.ts +25 -1
- package/src/config/resolve.ts +43 -8
- package/src/config.integration.test.ts +17 -10
- package/src/docs/api-guide.test.ts +1 -1
- package/src/docs/docs.test.ts +1 -1
- package/src/docs/mcp-guide.ts +1 -1
- package/src/hidden-mcpb.test.ts +41 -1
- package/src/index.ts +4 -0
- package/src/install/{binary.ts → app.ts} +13 -13
- package/src/install/bootstrap.ts +22 -0
- package/src/install/detect-installed.ts +2 -97
- package/src/install/index.ts +187 -110
- package/src/install/install-validate.test.ts +61 -0
- package/src/install/install.test.ts +138 -42
- package/src/install/mcp-openclaw.test.ts +40 -0
- package/src/install/mcp-openclaw.ts +106 -0
- package/src/install/normalize.ts +35 -0
- package/src/install/paths.ts +27 -13
- package/src/install/plan.ts +30 -259
- package/src/install/shell.ts +2 -2
- package/src/install/status.test.ts +85 -0
- package/src/install/status.ts +22 -9
- package/src/install/target-base.ts +93 -0
- package/src/install/target-detect.ts +20 -0
- package/src/install/target-effective.ts +131 -0
- package/src/install/target-mcp-cli.ts +149 -0
- package/src/install/target-mcp-json.ts +130 -0
- package/src/install/target-plan-build.ts +67 -0
- package/src/install/target-registry.ts +57 -0
- package/src/install/target-scope.ts +266 -0
- package/src/install/target-skill.ts +104 -0
- package/src/install/target-types.ts +145 -0
- package/src/install/targets/app.ts +69 -0
- package/src/install/targets/chatgpt-mcp.ts +12 -0
- package/src/install/targets/claude-code-mcp.ts +15 -0
- package/src/install/targets/claude-desktop-mcp.ts +12 -0
- package/src/install/targets/claude-skill.ts +16 -0
- package/src/install/targets/codex-mcp.ts +25 -0
- package/src/install/targets/codex-skill.ts +14 -0
- package/src/install/targets/completions.ts +133 -0
- package/src/install/targets/configure.ts +59 -0
- package/src/install/targets/cursor-mcp.ts +15 -0
- package/src/install/targets/cursor-skill.ts +16 -0
- package/src/install/targets/index.ts +53 -0
- package/src/install/targets/openclaw-mcp.ts +25 -0
- package/src/install/targets/openclaw-skill.ts +17 -0
- package/src/install/targets/opencode-mcp.ts +101 -0
- package/src/install/targets/opencode-skill.ts +15 -0
- package/src/install/targets.test.ts +136 -0
- package/src/install/uninstall.ts +16 -152
- package/src/install/update.test.ts +17 -2
- package/src/install/update.ts +2 -5
- package/src/invoke.test.ts +7 -1
- package/src/mcp/bundle.ts +16 -4
- package/src/mcp/claude.test.ts +14 -1
- package/src/mcp/claude.ts +11 -4
- package/src/mcp/zip.test.ts +17 -0
- package/src/mcp/zip.ts +62 -9
- package/src/mcp.integration.test.ts +1 -1
- package/src/parse.test.ts +12 -1
- package/src/paths/host.ts +11 -11
- package/src/paths/remove-empty-dir.ts +13 -0
- package/src/skill/generate.ts +18 -4
- package/src/skill/install.ts +33 -6
- package/src/skill/naming.ts +28 -0
- package/src/types.ts +65 -4
- package/src/validate.ts +70 -0
package/src/skill/install.ts
CHANGED
|
@@ -5,19 +5,28 @@ import type { CliProgram } from "../types.ts";
|
|
|
5
5
|
import { generateSkillBundle, type SkillTarget } from "./generate.ts";
|
|
6
6
|
import { applySkillInstallHints } from "./hint.ts";
|
|
7
7
|
|
|
8
|
+
export { skillDirNameForTarget, skillFrontmatterName, skillSlug } from "./naming.ts";
|
|
9
|
+
|
|
8
10
|
export interface SkillInstallOpts {
|
|
9
11
|
global?: boolean;
|
|
10
|
-
/** When true, remove an existing skill directory before writing. */
|
|
11
12
|
rimraf?: boolean;
|
|
12
|
-
/** When true, skip writes but return paths that would change. */
|
|
13
13
|
dry?: boolean;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function resolveSkillDir(target: SkillTarget, dirName: string, global: boolean): string {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const home = userHome();
|
|
18
|
+
switch (target) {
|
|
19
|
+
case "cursor":
|
|
20
|
+
return join(global ? home : process.cwd(), ".cursor", "skills", dirName);
|
|
21
|
+
case "claude":
|
|
22
|
+
return join(global ? home : process.cwd(), ".claude", "skills", dirName);
|
|
23
|
+
case "codex":
|
|
24
|
+
return join(global ? home : process.cwd(), ".codex", "skills", dirName);
|
|
25
|
+
case "opencode":
|
|
26
|
+
return join(global ? home : process.cwd(), ".config", "opencode", "skills", dirName);
|
|
27
|
+
case "openclaw":
|
|
28
|
+
return join(global ? home : process.cwd(), ".openclaw", "skills", dirName);
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
/** Writes SKILL.md and reference.md; returns changed file paths. */
|
|
@@ -47,3 +56,21 @@ export function cliSkillInstall(
|
|
|
47
56
|
changed.push(skillPath, refPath);
|
|
48
57
|
return changed;
|
|
49
58
|
}
|
|
59
|
+
|
|
60
|
+
/** Maps install action kind to skill target. */
|
|
61
|
+
export function skillTargetFromActionKind(kind: string): SkillTarget | undefined {
|
|
62
|
+
switch (kind) {
|
|
63
|
+
case "cursor-skill":
|
|
64
|
+
return "cursor";
|
|
65
|
+
case "claude-skill":
|
|
66
|
+
return "claude";
|
|
67
|
+
case "codex-skill":
|
|
68
|
+
return "codex";
|
|
69
|
+
case "opencode-skill":
|
|
70
|
+
return "opencode";
|
|
71
|
+
case "openclaw-skill":
|
|
72
|
+
return "openclaw";
|
|
73
|
+
default:
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Agent skill install targets. */
|
|
2
|
+
export type SkillTarget = "cursor" | "claude" | "codex" | "opencode" | "openclaw";
|
|
3
|
+
|
|
4
|
+
import { sanitizeToolSegment } from "../mcp/tools.ts";
|
|
5
|
+
|
|
6
|
+
/** Kebab-case skill folder + frontmatter name for agents that require hyphen slugs. */
|
|
7
|
+
export function skillSlug(programKey: string): string {
|
|
8
|
+
return programKey
|
|
9
|
+
.replace(/[^a-zA-Z0-9]+/g, "-")
|
|
10
|
+
.replace(/^-+|-+$/g, "")
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Directory name for a skill target (underscore vs kebab conventions). */
|
|
15
|
+
export function skillDirNameForTarget(programKey: string, target: SkillTarget): string {
|
|
16
|
+
if (target === "cursor" || target === "claude") {
|
|
17
|
+
return sanitizeToolSegment(programKey);
|
|
18
|
+
}
|
|
19
|
+
return skillSlug(programKey);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Frontmatter `name` for SKILL.md by target. */
|
|
23
|
+
export function skillFrontmatterName(programKey: string, target: SkillTarget): string {
|
|
24
|
+
if (target === "cursor" || target === "claude") {
|
|
25
|
+
return sanitizeToolSegment(programKey);
|
|
26
|
+
}
|
|
27
|
+
return skillSlug(programKey);
|
|
28
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -133,6 +133,10 @@ export interface CliMcpBundleConfig {
|
|
|
133
133
|
export interface CliMcpServerConfig {
|
|
134
134
|
/** When `true`, enables the `mcp` built-in and MCP stdio server. */
|
|
135
135
|
enabled: boolean;
|
|
136
|
+
/** When `true`, `mcp bundle` writes `dist/<key>.mcpb` for Claude Desktop. Default false. */
|
|
137
|
+
mcpd?: boolean;
|
|
138
|
+
/** When `true`, `mcp bundle` also writes `dist/claude-plugin/<name>.zip`. Default false. */
|
|
139
|
+
claudePlugin?: boolean;
|
|
136
140
|
/** Resource URI for schema export (default: `<sanitized root key>://schema`). */
|
|
137
141
|
schemaResourceUri?: string;
|
|
138
142
|
/**
|
|
@@ -224,8 +228,6 @@ export interface CliAppConfigEntry {
|
|
|
224
228
|
* App configuration block on the program root ({@link CliProgram.appConfig}).
|
|
225
229
|
*/
|
|
226
230
|
export interface CliAppConfig {
|
|
227
|
-
/** Default: `~/.config/<sanitized-key>/config` (or `%APPDATA%/<key>/config` on Windows). */
|
|
228
|
-
path?: string;
|
|
229
231
|
/** Built-in `config get` / `config set`. Default: enabled when `appConfig` is set. */
|
|
230
232
|
commands?: boolean | { enabled?: boolean; mcpSet?: boolean };
|
|
231
233
|
/** Block JSON Schema (draft-07). When omitted, synthesize all-string schema from `entries`. */
|
|
@@ -237,8 +239,15 @@ export interface CliAppConfig {
|
|
|
237
239
|
export interface CliInstallConfig {
|
|
238
240
|
/** When `false`, hide/disable `install` (default: enabled). */
|
|
239
241
|
enabled?: boolean;
|
|
240
|
-
/**
|
|
241
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Default agent integration for full install (`install --all`).
|
|
244
|
+
* - `'mcp'` when `mcpServer.enabled` (default): MCP targets in `--all`; paired skills excluded.
|
|
245
|
+
* - `'skill'` when MCP is off (default): skill targets in `--all`; paired MCP excluded.
|
|
246
|
+
* - `'both'`: install MCP and skill for the same host when both are available.
|
|
247
|
+
*/
|
|
248
|
+
agentIntegration?: InstallAgentIntegration;
|
|
249
|
+
/** Per-artifact gates for full install/uninstall. See {@link resolveEffectiveInstallTargets}. */
|
|
250
|
+
targets?: CliInstallTargets;
|
|
242
251
|
/**
|
|
243
252
|
* When set, enables `install --update` on the program root.
|
|
244
253
|
* Should download or locate the latest release binary and return its path.
|
|
@@ -246,6 +255,58 @@ export interface CliInstallConfig {
|
|
|
246
255
|
updateGetLatest?: CliUpdateGetLatest;
|
|
247
256
|
}
|
|
248
257
|
|
|
258
|
+
/** Agent integration mode for install — MCP vs shell skill per host. */
|
|
259
|
+
export type InstallAgentIntegration = "mcp" | "skill" | "both";
|
|
260
|
+
|
|
261
|
+
/** Boolean or structured gate for one install artifact. */
|
|
262
|
+
export type InstallTargetSpec =
|
|
263
|
+
| boolean
|
|
264
|
+
| {
|
|
265
|
+
/** When false, artifact is never installed (even with scoped CLI flags). Default true. */
|
|
266
|
+
enabled?: boolean;
|
|
267
|
+
/** When true, included in bare `install` / `install --all`. Default varies by key. */
|
|
268
|
+
includedInAll?: boolean;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
export interface ResolvedInstallTarget {
|
|
272
|
+
enabled: boolean;
|
|
273
|
+
includedInAll: boolean;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Per-artifact gates for full install/uninstall. See {@link resolveEffectiveInstallTargets}. */
|
|
277
|
+
export interface CliInstallTargets {
|
|
278
|
+
/** Copy app to `~/.local/bin/<key>`. Default includedInAll true (opt-out). */
|
|
279
|
+
app?: InstallTargetSpec;
|
|
280
|
+
/** ChatGPT desktop MCP. Default false. */
|
|
281
|
+
chatgptMcp?: InstallTargetSpec;
|
|
282
|
+
/** Claude Code MCP (`~/.claude.json`). Default false. */
|
|
283
|
+
claudeCodeMcp?: InstallTargetSpec;
|
|
284
|
+
/** Claude Desktop MCP. Default false. */
|
|
285
|
+
claudeDesktopMcp?: InstallTargetSpec;
|
|
286
|
+
/** Claude Code skill. Default false. */
|
|
287
|
+
claudeSkill?: InstallTargetSpec;
|
|
288
|
+
/** Codex MCP (`codex mcp add`). Default false. */
|
|
289
|
+
codexMcp?: InstallTargetSpec;
|
|
290
|
+
/** Codex skill. Default false. */
|
|
291
|
+
codexSkill?: InstallTargetSpec;
|
|
292
|
+
/** Shell completions for detected shells. Default includedInAll true (opt-out). */
|
|
293
|
+
completions?: InstallTargetSpec;
|
|
294
|
+
/** App config: wizard on install, file removal on uninstall. Default includedInAll true. */
|
|
295
|
+
configure?: InstallTargetSpec;
|
|
296
|
+
/** Cursor MCP. Default false. */
|
|
297
|
+
cursorMcp?: InstallTargetSpec;
|
|
298
|
+
/** Cursor skill. Default false. */
|
|
299
|
+
cursorSkill?: InstallTargetSpec;
|
|
300
|
+
/** OpenClaw MCP. Default false. */
|
|
301
|
+
openclawMcp?: InstallTargetSpec;
|
|
302
|
+
/** OpenClaw skill. Default false. */
|
|
303
|
+
openclawSkill?: InstallTargetSpec;
|
|
304
|
+
/** OpenCode MCP. Default false. */
|
|
305
|
+
opencodeMcp?: InstallTargetSpec;
|
|
306
|
+
/** OpenCode skill. Default false. */
|
|
307
|
+
opencodeSkill?: InstallTargetSpec;
|
|
308
|
+
}
|
|
309
|
+
|
|
249
310
|
/**
|
|
250
311
|
* One bundled documentation topic for the `docs` built-in (program root only).
|
|
251
312
|
*/
|
package/src/validate.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { reservedCommandNames, resolveCapabilities } from "./capabilities.ts";
|
|
|
6
6
|
import { reservedDocsTopicResourceUris } from "./docs/mcp-resources.ts";
|
|
7
7
|
import { DOCS_BUILTIN_TOPIC_KEYS } from "./docs/resolve.ts";
|
|
8
8
|
import { validateFormatValue } from "./formats.ts";
|
|
9
|
+
import { AGENT_PAIRS } from "./install/target-registry.ts";
|
|
9
10
|
import { resolveMcpSchemaUri } from "./mcp/tools.ts";
|
|
10
11
|
import {
|
|
11
12
|
type CliLeaf,
|
|
@@ -14,6 +15,8 @@ import {
|
|
|
14
15
|
type CliProgram,
|
|
15
16
|
CliSchemaValidationError,
|
|
16
17
|
CliValueFormat,
|
|
18
|
+
type InstallAgentIntegration,
|
|
19
|
+
type InstallTargetSpec,
|
|
17
20
|
isCliLeaf,
|
|
18
21
|
isCliRouter,
|
|
19
22
|
} from "./types.ts";
|
|
@@ -105,6 +108,69 @@ function validateConfigBlock(appConfigBlock: import("./types.ts").CliAppConfig):
|
|
|
105
108
|
}
|
|
106
109
|
}
|
|
107
110
|
|
|
111
|
+
const PAIR_HOST_LABELS: Record<string, string> = {
|
|
112
|
+
cursorMcp: "cursor",
|
|
113
|
+
claudeCodeMcp: "claudeCode",
|
|
114
|
+
codexMcp: "codex",
|
|
115
|
+
opencodeMcp: "opencode",
|
|
116
|
+
openclawMcp: "openclaw",
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
function installTargetExplicitTruthy(spec: InstallTargetSpec | undefined): boolean {
|
|
120
|
+
if (spec === undefined || spec === false) return false;
|
|
121
|
+
if (spec === true) return true;
|
|
122
|
+
return spec.enabled !== false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Validates `program.install` targets and agentIntegration. */
|
|
126
|
+
function validateInstallConfig(program: CliProgram): void {
|
|
127
|
+
const install = program.install;
|
|
128
|
+
if (!install) return;
|
|
129
|
+
|
|
130
|
+
if ("prefix" in install) {
|
|
131
|
+
throw new CliSchemaValidationError(
|
|
132
|
+
"install.prefix removed; app installs to ~/.local/bin/<key>",
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!install.targets) return;
|
|
137
|
+
|
|
138
|
+
const targets = install.targets;
|
|
139
|
+
if ("allSkills" in targets || "allMcps" in targets) {
|
|
140
|
+
throw new CliSchemaValidationError(
|
|
141
|
+
"install.targets.allSkills/allMcps removed; use agentIntegration and per-key targets",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const integration: InstallAgentIntegration =
|
|
146
|
+
install.agentIntegration ?? (program.mcpServer?.enabled === true ? "mcp" : "skill");
|
|
147
|
+
|
|
148
|
+
for (const [mcpKey, skillKey] of AGENT_PAIRS) {
|
|
149
|
+
const mcpSpec = targets[mcpKey];
|
|
150
|
+
const skillSpec = targets[skillKey];
|
|
151
|
+
const mcpOn = installTargetExplicitTruthy(mcpSpec);
|
|
152
|
+
const skillOn = installTargetExplicitTruthy(skillSpec);
|
|
153
|
+
const host = PAIR_HOST_LABELS[mcpKey] ?? mcpKey;
|
|
154
|
+
|
|
155
|
+
if (mcpOn && skillOn && integration !== "both") {
|
|
156
|
+
throw new CliSchemaValidationError(
|
|
157
|
+
`install.targets: ${host} has both MCP and skill configured; set agentIntegration: 'both' or disable one side`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (integration === "skill" && mcpOn) {
|
|
162
|
+
throw new CliSchemaValidationError(
|
|
163
|
+
`install.targets.${mcpKey} requires agentIntegration: 'both' when agentIntegration is 'skill'`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (integration === "mcp" && skillOn) {
|
|
167
|
+
throw new CliSchemaValidationError(
|
|
168
|
+
`install.targets.${skillKey} requires agentIntegration: 'both' when agentIntegration is 'mcp'`,
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
108
174
|
/** Validates a program schema. */
|
|
109
175
|
export function cliValidateProgram(program: CliProgram): void {
|
|
110
176
|
if (!program.version || program.version.trim().length === 0) {
|
|
@@ -142,6 +208,10 @@ export function cliValidateProgram(program: CliProgram): void {
|
|
|
142
208
|
}
|
|
143
209
|
}
|
|
144
210
|
|
|
211
|
+
if (program.install !== undefined) {
|
|
212
|
+
validateInstallConfig(program);
|
|
213
|
+
}
|
|
214
|
+
|
|
145
215
|
const caps = resolveCapabilities(program);
|
|
146
216
|
const reserved = reservedCommandNames(caps);
|
|
147
217
|
|