argsbarg 3.4.1 → 3.5.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 +26 -1
- package/biome.json +29 -6
- package/bun.lock +22 -0
- package/docs/install.md +1 -1
- package/docs/mcp.md +63 -3
- package/index.d.ts +51 -51
- package/justfile +27 -6
- package/package.json +4 -2
- package/scripts/release.ts +26 -9
- package/src/builtins/builtins.test.ts +9 -4
- package/src/builtins/completion-bash.ts +74 -50
- package/src/builtins/completion-fish.ts +3 -8
- package/src/builtins/completion-group.ts +1 -1
- package/src/builtins/completion-zsh.ts +80 -42
- package/src/builtins/dispatch.ts +20 -16
- package/src/builtins/export.ts +19 -10
- package/src/builtins/index.ts +9 -4
- package/src/builtins/install.ts +10 -10
- package/src/builtins/mcp.ts +3 -3
- package/src/builtins/presentation.ts +8 -8
- package/src/builtins/scopes.ts +1 -1
- package/src/builtins/version.ts +1 -1
- package/src/completion.ts +4 -4
- package/src/docs/api-guide.test.ts +2 -2
- package/src/docs/api-guide.ts +2 -2
- package/src/docs/builtin.ts +27 -8
- package/src/docs/docs.test.ts +23 -12
- package/src/docs/mcp-guide.ts +112 -11
- package/src/docs/resolve.ts +10 -3
- package/src/docs/save.ts +11 -3
- package/src/headless.test.ts +8 -16
- package/src/help.ts +73 -43
- package/src/hidden-mcpb.test.ts +8 -10
- package/src/hidden.ts +2 -2
- package/src/index.test.ts +113 -89
- package/src/index.ts +24 -24
- package/src/install/binary.ts +12 -5
- package/src/install/completions.ts +7 -3
- package/src/install/detect-installed.ts +35 -4
- package/src/install/gh-release-update.ts +31 -23
- package/src/install/index.ts +69 -19
- package/src/install/install.test.ts +57 -8
- package/src/install/mcp-codex.test.ts +57 -0
- package/src/install/mcp-codex.ts +125 -0
- package/src/install/mcp-config.ts +12 -5
- package/src/install/mcp-opencode.test.ts +98 -0
- package/src/install/mcp-opencode.ts +149 -0
- package/src/install/paths.ts +51 -3
- package/src/install/plan.ts +96 -7
- package/src/install/shell.ts +1 -4
- package/src/install/status.ts +15 -7
- package/src/install/uninstall.ts +49 -5
- package/src/install/update.test.ts +2 -2
- package/src/install/update.ts +3 -1
- package/src/invoke.ts +12 -9
- package/src/mcp/bundle.ts +38 -14
- package/src/mcp/env.ts +7 -13
- package/src/mcp/server.ts +12 -6
- package/src/mcp/tools.ts +20 -4
- package/src/mcp.ts +3 -3
- package/src/parse.ts +96 -24
- package/src/runtime.ts +22 -12
- package/src/schema.ts +11 -5
- package/src/skill/generate.ts +4 -4
- package/src/skill/install.ts +6 -2
- package/src/validate.ts +21 -16
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.5.0] - 2026-06-22
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`install --mcp`** — OpenCode: merges local MCP entry into `~/.config/opencode` config (`mcp` key, OpenCode `type: "local"` format).
|
|
15
|
+
- **`install --mcp`** — Codex: runs `codex mcp add` when `codex` is on PATH.
|
|
16
|
+
- **`install --mcp`** — ChatGPT desktop: merges into `chatgpt_mcp_config.json` when ChatGPT app data exists.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **`docs mcp`** — Codex/ChatGPT guidance: Connectors for web (remote MCP); gated desktop JSON auto-install.
|
|
21
|
+
|
|
22
|
+
## [3.4.2] - 2026-06-22
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`install --mcp`** — also merges into Claude Desktop `claude_desktop_config.json` when Claude Desktop app data is present (macOS, Windows, Linux paths).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **`docs mcp`** — generated guide documents Cursor, Claude Code, and Claude Desktop install targets and platform config paths.
|
|
31
|
+
- **`mcp bundle`** — no longer macOS-only; packs `.mcpb` on any platform when the compiled binary exists.
|
|
32
|
+
|
|
10
33
|
## [3.4.1] - 2026-06-22
|
|
11
34
|
|
|
12
35
|
|
|
@@ -348,7 +371,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
|
|
|
348
371
|
- Migrate schemas: rename every `children` property to **`commands`**; move positional definitions to **`CliPositional`** objects on `positionals` and strip `positional` / `argMin` / `argMax` from flag definitions under `options` (flags only carry `name`, `description`, `kind`, and optional `shortName`).
|
|
349
372
|
- Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
|
|
350
373
|
|
|
351
|
-
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.
|
|
374
|
+
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.5.0...HEAD
|
|
375
|
+
[3.5.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.5.0
|
|
376
|
+
[3.4.2]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.4.2
|
|
352
377
|
[3.4.1]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.4.1
|
|
353
378
|
[3.4.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.4.0
|
|
354
379
|
[3.3.14]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.14
|
package/biome.json
CHANGED
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://biomejs.dev/schemas/
|
|
3
|
-
"organizeImports":
|
|
4
|
-
"enabled": true
|
|
5
|
-
},
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
|
|
3
|
+
"assist": { "actions": { "source": { "organizeImports": "on" } } },
|
|
6
4
|
"linter": {
|
|
7
5
|
"enabled": true,
|
|
8
6
|
"rules": {
|
|
9
|
-
"
|
|
7
|
+
"preset": "recommended"
|
|
10
8
|
}
|
|
11
9
|
},
|
|
12
10
|
"formatter": {
|
|
13
11
|
"enabled": true,
|
|
14
12
|
"indentStyle": "space",
|
|
15
13
|
"lineWidth": 100
|
|
16
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"overrides": [
|
|
16
|
+
{
|
|
17
|
+
"includes": ["**/completion-bash.ts", "**/completion-zsh.ts"],
|
|
18
|
+
"linter": {
|
|
19
|
+
"rules": {
|
|
20
|
+
"suspicious": {
|
|
21
|
+
"noTemplateCurlyInString": "off"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"includes": ["**/*.test.ts"],
|
|
28
|
+
"linter": {
|
|
29
|
+
"rules": {
|
|
30
|
+
"style": {
|
|
31
|
+
"noNonNullAssertion": "off"
|
|
32
|
+
},
|
|
33
|
+
"suspicious": {
|
|
34
|
+
"noTemplateCurlyInString": "off"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
17
40
|
}
|
package/bun.lock
CHANGED
|
@@ -5,17 +5,39 @@
|
|
|
5
5
|
"": {
|
|
6
6
|
"name": "argsbarg",
|
|
7
7
|
"devDependencies": {
|
|
8
|
+
"@biomejs/biome": "^2.5.0",
|
|
8
9
|
"@types/bun": "^1.3.12",
|
|
10
|
+
"typescript": "^5.9.3",
|
|
9
11
|
},
|
|
10
12
|
},
|
|
11
13
|
},
|
|
12
14
|
"packages": {
|
|
15
|
+
"@biomejs/biome": ["@biomejs/biome@2.5.0", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.0", "@biomejs/cli-darwin-x64": "2.5.0", "@biomejs/cli-linux-arm64": "2.5.0", "@biomejs/cli-linux-arm64-musl": "2.5.0", "@biomejs/cli-linux-x64": "2.5.0", "@biomejs/cli-linux-x64-musl": "2.5.0", "@biomejs/cli-win32-arm64": "2.5.0", "@biomejs/cli-win32-x64": "2.5.0" }, "bin": { "biome": "bin/biome" } }, "sha512-4kURkd9hAPrdDM3C9n82ycYgx8hvQcW6MjKTEejruj8rK0N8P3OPpdy8BvI8kt3KWY4ycF5XtDOrktetEfhfuw=="],
|
|
16
|
+
|
|
17
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Mn3Fwi3SA5fgmfCPqmzpWF2DLZnms3BVAhM088nTnGrTZmHS3wwIjcoZPqpXeNgd3DrrLH6xp8vTLIBuJoZiXw=="],
|
|
18
|
+
|
|
19
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-rg3VPL5P8mYro6pqlXYXuJWph21slVp3SZtAqWSrkZs40d2gTzYmHF8E/X1iTID25btmNKltNDJ926sqVBp7DQ=="],
|
|
20
|
+
|
|
21
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-tl+LW8fdD96/xdeWtWwc82LIOc5CoY7N2AsogLTp5R4ECErYt+8Jl/N68ezN9vzSiqPTxw6vjcihoLPYKZHrlw=="],
|
|
22
|
+
|
|
23
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vQdM4oSGaf7ZNeGO9w5+Y8SBtyser9M6znxYbm7Ec8wInxJu1WiKxFYZW5Auj2d80bcVvefuGGRxoFOE0eee8g=="],
|
|
24
|
+
|
|
25
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zpEGf4RQbFEh8Vt7OmavLyyOzRbtcE9osCqrS1kfvt8jDvxwhKXLSf7n0ebr/ov0RJ9ssP+lhs6C8a9WwFvrQA=="],
|
|
26
|
+
|
|
27
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+9hIcMngJ+yGUahXqZuZ8CoWKJE9SAZsFsM3QDvXpNsLbXZ9lqVzgBhOk/jTSYkOA0GLP9eu3teukqpLUojHMg=="],
|
|
28
|
+
|
|
29
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-jB0wAvTLI4itx5VidqVUejPQFhRUxiZ9l9FvZ26D5fl6t3qme+ZB4PD3bTSeL1vZ8NI2Rx/zj6H9zcESuGHKGw=="],
|
|
30
|
+
|
|
31
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.0", "", { "os": "win32", "cpu": "x64" }, "sha512-VT/lF+GId+67j8aDfLkxdxNoVApsPSTbyAtB3jJq0IWTrY77WXfbPfpngxq0bA6JCEv/7k8C9qWjDRKRznDlyw=="],
|
|
32
|
+
|
|
13
33
|
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
|
14
34
|
|
|
15
35
|
"@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="],
|
|
16
36
|
|
|
17
37
|
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
|
18
38
|
|
|
39
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
40
|
+
|
|
19
41
|
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
|
|
20
42
|
}
|
|
21
43
|
}
|
package/docs/install.md
CHANGED
|
@@ -31,7 +31,7 @@ myapp install --uninstall --all --yes
|
|
|
31
31
|
| Fish completion | `--completions` | `~/.config/fish/completions/<key>.fish` |
|
|
32
32
|
| Cursor skill | `--skill` | `~/.cursor/skills/<dir>/` when `~/.cursor` exists |
|
|
33
33
|
| Claude skill | `--skill` | `~/.claude/skills/<dir>/` when `~/.claude` exists |
|
|
34
|
-
| MCP config | `--mcp` | `~/.
|
|
34
|
+
| MCP config | `--mcp` | Cursor, Claude Code/Desktop, OpenCode (`~/.config/opencode`), Codex (`codex` on PATH), ChatGPT desktop (when app data exists). ChatGPT web uses Connectors — see `docs mcp` |
|
|
35
35
|
|
|
36
36
|
`--all` expands to `--bin`, `--completions`, `--skill`, and `--mcp` (when `mcpServer.enabled` is `true`) for both install and uninstall. Missing targets are skipped silently (no error if nothing is on disk or a shell/agent directory does not exist).
|
|
37
37
|
|
package/docs/mcp.md
CHANGED
|
@@ -57,7 +57,67 @@ Add a server entry under `mcpServers` in your Cursor MCP config:
|
|
|
57
57
|
}
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
Use your real binary or script path. For a compiled CLI, `command` can be the installed binary and `args` can be `["
|
|
60
|
+
Use your real binary or script path. For a compiled CLI, `command` can be the installed binary and `args` can be `["mcp"]`.
|
|
61
|
+
|
|
62
|
+
### Claude Code
|
|
63
|
+
|
|
64
|
+
`install --mcp` merges into `~/.claude.json` under `mcpServers`.
|
|
65
|
+
|
|
66
|
+
### Claude Desktop
|
|
67
|
+
|
|
68
|
+
`install --mcp` also merges into Claude Desktop config when app data is present:
|
|
69
|
+
|
|
70
|
+
| Platform | Path |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
73
|
+
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
74
|
+
| Linux | `~/.config/Claude/claude_desktop_config.json` |
|
|
75
|
+
|
|
76
|
+
Restart Claude Desktop after config changes. You can also install a **`.mcpb`** bundle via **`mcp bundle`** (see [MCP Bundle](#mcp-bundle-mcp-bundle)).
|
|
77
|
+
|
|
78
|
+
### OpenCode
|
|
79
|
+
|
|
80
|
+
When `~/.config/opencode` exists, **`install --mcp`** merges a local server under the top-level **`mcp`** key (not `mcpServers`):
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"$schema": "https://opencode.ai/config.json",
|
|
85
|
+
"mcp": {
|
|
86
|
+
"myapp": {
|
|
87
|
+
"type": "local",
|
|
88
|
+
"command": ["myapp", "mcp"],
|
|
89
|
+
"enabled": true
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
OpenCode reads `opencode.jsonc`, `opencode.json`, or `config.json` in that directory. Argsbarg updates the first existing file, or creates `config.json`. JSON-with-comments (`.jsonc`) is not auto-edited — add the block manually or use a `.json` config file.
|
|
96
|
+
|
|
97
|
+
### OpenAI Codex
|
|
98
|
+
|
|
99
|
+
When **`codex`** is on PATH, **`install --mcp`** runs `codex mcp add <server> -- <binary> mcp`, which writes **`~/.codex/config.toml`**. Otherwise add manually:
|
|
100
|
+
|
|
101
|
+
```toml
|
|
102
|
+
[mcp_servers.myapp]
|
|
103
|
+
command = "myapp"
|
|
104
|
+
args = ["mcp"]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use **`codex mcp`** to list/add/remove servers, or **Settings → MCP → Open config.toml** in the Codex app. CLI and IDE extension share the same file.
|
|
108
|
+
|
|
109
|
+
### ChatGPT
|
|
110
|
+
|
|
111
|
+
**Web / Connectors (OpenAI’s documented path)** — **Settings → Connectors → Developer mode** with a **remote HTTPS MCP URL**. ChatGPT does not spawn local stdio binaries; bridge and tunnel local servers when needed.
|
|
112
|
+
|
|
113
|
+
**Desktop JSON (gated auto-install)** — when ChatGPT app data exists, **`install --mcp`** also merges `mcpServers` into:
|
|
114
|
+
|
|
115
|
+
| Platform | Path |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| macOS | `~/Library/Application Support/ChatGPT/chatgpt_mcp_config.json` |
|
|
118
|
+
| Windows | `%APPDATA%\OpenAI\ChatGPT\chatgpt_mcp_config.json` |
|
|
119
|
+
|
|
120
|
+
Local JSON support varies by desktop build. Prefer **Connectors** for ChatGPT web or when tools do not appear after install.
|
|
61
121
|
|
|
62
122
|
### Other MCP hosts
|
|
63
123
|
|
|
@@ -295,7 +355,7 @@ You should get one JSON line on stdout with `result.capabilities` and `result.se
|
|
|
295
355
|
|
|
296
356
|
## MCP Bundle (`mcp bundle`)
|
|
297
357
|
|
|
298
|
-
When `mcpServer.enabled` is true, **`mcp bundle`** packs a Claude Desktop **`.mcpb`** bundle
|
|
358
|
+
When `mcpServer.enabled` is true, **`mcp bundle`** packs a Claude Desktop **`.mcpb`** bundle:
|
|
299
359
|
|
|
300
360
|
```bash
|
|
301
361
|
just build
|
|
@@ -305,7 +365,7 @@ just build
|
|
|
305
365
|
|
|
306
366
|
Expects the compiled binary at **`dist/<program.key>`** and writes **`dist/<program.key>.mcpb`**. Manifest metadata is generated from your schema (`mcpServerId`, tools, `requiresEnv`). Optional pack-time fields live under **`mcpServer.bundle`** (`author`, `icon`, `longDescription`).
|
|
307
367
|
|
|
308
|
-
Bare **`myapp mcp`** still runs the stdio MCP server (unchanged for `install --mcp` and MCP hosts). Use **`install --mcp`** for Cursor
|
|
368
|
+
Bare **`myapp mcp`** still runs the stdio MCP server (unchanged for `install --mcp` and MCP hosts). Use **`install --mcp`** for Cursor, Claude Code, Claude Desktop, and OpenCode JSON config.
|
|
309
369
|
|
|
310
370
|
## Hidden commands and options
|
|
311
371
|
|
package/index.d.ts
CHANGED
|
@@ -1,33 +1,5 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Values passed to a leaf command handler after parsing: app name, routed path, args, and merged options.
|
|
5
|
-
*/
|
|
6
|
-
export declare class CliContext {
|
|
7
|
-
readonly appName: string;
|
|
8
|
-
readonly commandPath: string[];
|
|
9
|
-
readonly args: string[];
|
|
10
|
-
readonly program: CliProgram;
|
|
11
|
-
readonly opts: Record<string, string>;
|
|
12
|
-
readonly invocation: CliInvocation;
|
|
13
|
-
/** Captures the program root, routed path, positional words, and option map for a leaf handler. */
|
|
14
|
-
constructor(appName: string, commandPath: string[], args: string[], opts: Record<string, string>, program: CliProgram, invocation?: CliInvocation);
|
|
15
|
-
/** Returns whether a presence flag was set (including implicit "1" for boolean options). */
|
|
16
|
-
hasFlag(name: string): boolean;
|
|
17
|
-
/** Returns the string value for a string-valued option, if present. */
|
|
18
|
-
stringOpt(name: string): string | undefined;
|
|
19
|
-
/** Parses a stored string as a number; returns null if missing or not a strict double string. */
|
|
20
|
-
numberOpt(name: string): number | null;
|
|
21
|
-
/**
|
|
22
|
-
* Generic typed accessor: parses a stored string using the provided parse function.
|
|
23
|
-
* This is the TypeScript-native advantage over the Swift version.
|
|
24
|
-
*/
|
|
25
|
-
typedOpt<T>(name: string, parse: (s: string) => T): T | null;
|
|
26
|
-
/** Returns the value(s) for a named positional slot. Varargs slots return string[]; single slots return string | undefined. */
|
|
27
|
-
positional(name: string): string | string[] | undefined;
|
|
28
|
-
private _posMap;
|
|
29
|
-
private _positionalMap;
|
|
30
|
-
}
|
|
31
3
|
/**
|
|
32
4
|
* How a leaf handler was dispatched.
|
|
33
5
|
*/
|
|
@@ -308,30 +280,34 @@ export declare class CliSchemaValidationError extends Error {
|
|
|
308
280
|
/** Creates a schema validation error with a human-readable rule violation. */
|
|
309
281
|
constructor(message: string);
|
|
310
282
|
}
|
|
311
|
-
/** Outcome of a non-exiting CLI invocation. */
|
|
312
|
-
export type CliInvokeKind = "ok" | "help" | "error";
|
|
313
|
-
/** Result of cliInvoke: captured output and exit metadata without process.exit. */
|
|
314
|
-
export interface CliInvokeResult {
|
|
315
|
-
/** Invocation outcome. */
|
|
316
|
-
kind: CliInvokeKind;
|
|
317
|
-
/** Simulated exit code. */
|
|
318
|
-
exitCode: number;
|
|
319
|
-
/** Captured stdout during handler execution. */
|
|
320
|
-
stdout: string;
|
|
321
|
-
/** Captured stderr during handler execution. */
|
|
322
|
-
stderr: string;
|
|
323
|
-
/** Set when kind === "error" (parse/validation message). */
|
|
324
|
-
errorMsg?: string;
|
|
325
|
-
}
|
|
326
283
|
/**
|
|
327
|
-
*
|
|
328
|
-
* Never calls process.exit.
|
|
284
|
+
* Values passed to a leaf command handler after parsing: app name, routed path, args, and merged options.
|
|
329
285
|
*/
|
|
330
|
-
export declare
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
286
|
+
export declare class CliContext {
|
|
287
|
+
readonly appName: string;
|
|
288
|
+
readonly commandPath: string[];
|
|
289
|
+
readonly args: string[];
|
|
290
|
+
readonly program: CliProgram;
|
|
291
|
+
readonly opts: Record<string, string>;
|
|
292
|
+
readonly invocation: CliInvocation;
|
|
293
|
+
/** Captures the program root, routed path, positional words, and option map for a leaf handler. */
|
|
294
|
+
constructor(appName: string, commandPath: string[], args: string[], opts: Record<string, string>, program: CliProgram, invocation?: CliInvocation);
|
|
295
|
+
/** Returns whether a presence flag was set (including implicit "1" for boolean options). */
|
|
296
|
+
hasFlag(name: string): boolean;
|
|
297
|
+
/** Returns the string value for a string-valued option, if present. */
|
|
298
|
+
stringOpt(name: string): string | undefined;
|
|
299
|
+
/** Parses a stored string as a number; returns null if missing or not a strict double string. */
|
|
300
|
+
numberOpt(name: string): number | null;
|
|
301
|
+
/**
|
|
302
|
+
* Generic typed accessor: parses a stored string using the provided parse function.
|
|
303
|
+
* This is the TypeScript-native advantage over the Swift version.
|
|
304
|
+
*/
|
|
305
|
+
typedOpt<T>(name: string, parse: (s: string) => T): T | null;
|
|
306
|
+
/** Returns the value(s) for a named positional slot. Varargs slots return string[]; single slots return string | undefined. */
|
|
307
|
+
positional(name: string): string | string[] | undefined;
|
|
308
|
+
private _posMap;
|
|
309
|
+
private _positionalMap;
|
|
310
|
+
}
|
|
335
311
|
/** Minimal context for headless routing helpers. */
|
|
336
312
|
export type HeadlessContext = Pick<CliContext, "invocation">;
|
|
337
313
|
/** True when `--json` was passed or the handler was invoked via MCP. */
|
|
@@ -405,6 +381,26 @@ export declare function createGhVersionCheck(config: GhVersionCheckConfig): {
|
|
|
405
381
|
};
|
|
406
382
|
/** Shared `gh release view` fetcher for hooks and version-check refresh. */
|
|
407
383
|
export declare function createGhFetchLatest(config: Pick<GhReleaseUpdateConfig, "repo" | "repoEnvHint">): () => Promise<string>;
|
|
384
|
+
/** Outcome of a non-exiting CLI invocation. */
|
|
385
|
+
export type CliInvokeKind = "ok" | "help" | "error";
|
|
386
|
+
/** Result of cliInvoke: captured output and exit metadata without process.exit. */
|
|
387
|
+
export interface CliInvokeResult {
|
|
388
|
+
/** Invocation outcome. */
|
|
389
|
+
kind: CliInvokeKind;
|
|
390
|
+
/** Simulated exit code. */
|
|
391
|
+
exitCode: number;
|
|
392
|
+
/** Captured stdout during handler execution. */
|
|
393
|
+
stdout: string;
|
|
394
|
+
/** Captured stderr during handler execution. */
|
|
395
|
+
stderr: string;
|
|
396
|
+
/** Set when kind === "error" (parse/validation message). */
|
|
397
|
+
errorMsg?: string;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Parses argv against the user root, runs the leaf handler, and returns captured output.
|
|
401
|
+
* Never calls process.exit.
|
|
402
|
+
*/
|
|
403
|
+
export declare function cliInvoke(root: CliProgram, argv: string[]): Promise<CliInvokeResult>;
|
|
408
404
|
/** Resolved paths for `mcp bundle`. */
|
|
409
405
|
export interface McpBundlePaths {
|
|
410
406
|
binaryPath: string;
|
|
@@ -422,8 +418,12 @@ export interface PackMcpBundleOpts {
|
|
|
422
418
|
}
|
|
423
419
|
/**
|
|
424
420
|
* Stages manifest + binary (+ optional icon) and writes a `.mcpb` ZIP.
|
|
425
|
-
*
|
|
421
|
+
* Requires the compiled binary to exist.
|
|
426
422
|
*/
|
|
427
423
|
export declare function packMcpBundle(program: CliProgram, opts?: PackMcpBundleOpts): string;
|
|
424
|
+
export declare function cliRun(program: CliProgram, argv?: string[]): Promise<never>;
|
|
425
|
+
export declare function cliErrWithHelp(ctx: CliContext, msg: string): never;
|
|
426
|
+
/** True when stdin is a TTY. */
|
|
427
|
+
export declare const isInteractiveTty: boolean;
|
|
428
428
|
|
|
429
429
|
export {};
|
package/justfile
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
# https://github.com/casey/just — run `just` to list recipes.
|
|
2
2
|
|
|
3
|
+
set shell := ["bash", "-eu", "-o", "pipefail", "-c"]
|
|
4
|
+
|
|
3
5
|
_:
|
|
4
6
|
@just --list
|
|
5
7
|
|
|
6
|
-
#
|
|
7
|
-
check
|
|
8
|
-
|
|
8
|
+
# check the codebase
|
|
9
|
+
check: typecheck format
|
|
10
|
+
|
|
11
|
+
# Update local consumer apps: npm i argsbarg@latest, build, docgen
|
|
12
|
+
consumers-sync *apps:
|
|
13
|
+
#!/usr/bin/env bash
|
|
14
|
+
root="$(cd "{{justfile_directory()}}" && pwd)"
|
|
15
|
+
ss="$root/../../ss"
|
|
16
|
+
apps=({{apps}})
|
|
17
|
+
if [[ ${#apps[@]} -eq 0 ]]; then
|
|
18
|
+
apps=(idp-trees sqsp-qa-tools sqsp-i18n-tools)
|
|
19
|
+
fi
|
|
20
|
+
for app in "${apps[@]}"; do
|
|
21
|
+
dir="$(cd "$ss/$app" && pwd)"
|
|
22
|
+
echo "==> $app ($dir)"
|
|
23
|
+
(cd "$dir" && npm i argsbarg@latest --no-package-lock && just build && just docgen)
|
|
24
|
+
done
|
|
9
25
|
|
|
10
26
|
# run the minimal example
|
|
11
27
|
example *ARGS:
|
|
@@ -17,16 +33,20 @@ example-watch *ARGS:
|
|
|
17
33
|
|
|
18
34
|
# format the codebase
|
|
19
35
|
format:
|
|
20
|
-
bun
|
|
36
|
+
bun run biome check ./src ./scripts --write
|
|
21
37
|
|
|
22
38
|
# lint the codebase
|
|
23
39
|
lint:
|
|
24
|
-
bun
|
|
40
|
+
bun run biome check ./src ./scripts
|
|
25
41
|
|
|
26
42
|
# Typecheck, lint, then run the test suite.
|
|
27
|
-
test: check
|
|
43
|
+
test: check
|
|
28
44
|
bun test
|
|
29
45
|
|
|
46
|
+
# typecheck the codebase
|
|
47
|
+
typecheck:
|
|
48
|
+
bun run tsc --noEmit
|
|
49
|
+
|
|
30
50
|
# generate type declarations for the package
|
|
31
51
|
typegen:
|
|
32
52
|
bunx dts-bundle-generator --out-file index.d.ts src/index.ts
|
|
@@ -34,3 +54,4 @@ typegen:
|
|
|
34
54
|
# publish to github and npm
|
|
35
55
|
release bump: test typegen
|
|
36
56
|
bun scripts/release.ts {{bump}}
|
|
57
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "argsbarg",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"bun": ">=1.3"
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@
|
|
24
|
+
"@biomejs/biome": "^2.5.0",
|
|
25
|
+
"@types/bun": "^1.3.12",
|
|
26
|
+
"typescript": "^5.9.3"
|
|
25
27
|
}
|
|
26
28
|
}
|
package/scripts/release.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* repo changes (`git add -A`), not only the version and CHANGELOG edits from this script.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { unlink } from "fs/promises";
|
|
15
|
+
import { unlink } from "node:fs/promises";
|
|
16
16
|
|
|
17
17
|
/** Returns the parent directory of an absolute file path. */
|
|
18
18
|
function parentDir(absolute: string): string {
|
|
@@ -96,9 +96,13 @@ function githubRepoBaseFromOrigin(origin: string): string | null {
|
|
|
96
96
|
function releasedSemverVersionsFromChangelog(md: string): string[] {
|
|
97
97
|
const re = /^## \[(\d+\.\d+\.\d+)\] /gm;
|
|
98
98
|
const out: string[] = [];
|
|
99
|
-
let m
|
|
100
|
-
while (
|
|
101
|
-
|
|
99
|
+
let m = re.exec(md);
|
|
100
|
+
while (m !== null) {
|
|
101
|
+
const version = m[1];
|
|
102
|
+
if (version !== undefined) {
|
|
103
|
+
out.push(version);
|
|
104
|
+
}
|
|
105
|
+
m = re.exec(md);
|
|
102
106
|
}
|
|
103
107
|
return out;
|
|
104
108
|
}
|
|
@@ -108,14 +112,18 @@ function releasedSemverVersionsFromChangelog(md: string): string[] {
|
|
|
108
112
|
* (`[...]: http...`) at the end of the file.
|
|
109
113
|
*/
|
|
110
114
|
function stripChangelogLinkDefinitions(md: string): string {
|
|
111
|
-
|
|
115
|
+
const s = md.replace(/\r?\n## Links\r?\n/, "\n");
|
|
112
116
|
const lines = s.split(/\r?\n/);
|
|
113
117
|
let i = lines.length;
|
|
114
118
|
while (i > 0 && lines[i - 1] === "") {
|
|
115
119
|
i -= 1;
|
|
116
120
|
}
|
|
117
121
|
const refLine = /^\[[^\]]+\]: .+$/;
|
|
118
|
-
while (i > 0
|
|
122
|
+
while (i > 0) {
|
|
123
|
+
const line = lines[i - 1];
|
|
124
|
+
if (line === undefined || !refLine.test(line)) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
119
127
|
i -= 1;
|
|
120
128
|
}
|
|
121
129
|
while (i > 0 && lines[i - 1] === "") {
|
|
@@ -143,7 +151,10 @@ function appendChangelogLinkDefinitions(md: string, repoBase: string): string {
|
|
|
143
151
|
if (versions.length === 0) {
|
|
144
152
|
return `${body}\n`;
|
|
145
153
|
}
|
|
146
|
-
const newest = versions[0]
|
|
154
|
+
const newest = versions[0];
|
|
155
|
+
if (newest === undefined) {
|
|
156
|
+
return `${body}\n`;
|
|
157
|
+
}
|
|
147
158
|
const lines = [
|
|
148
159
|
"",
|
|
149
160
|
"",
|
|
@@ -178,7 +189,9 @@ function promoteChangelog(content: string, version: string, date: string): strin
|
|
|
178
189
|
const bodyStart = lineEnd + 1;
|
|
179
190
|
const nextIdx = content.indexOf("\n## [", bodyStart);
|
|
180
191
|
const body =
|
|
181
|
-
nextIdx === -1
|
|
192
|
+
nextIdx === -1
|
|
193
|
+
? content.slice(bodyStart).trimEnd()
|
|
194
|
+
: content.slice(bodyStart, nextIdx).trimEnd();
|
|
182
195
|
const tail = nextIdx === -1 ? "" : content.slice(nextIdx + 1);
|
|
183
196
|
const before = content.slice(0, idx);
|
|
184
197
|
const newBlock = `${header}\n\n## [${version}] - ${date}\n${body}\n\n`;
|
|
@@ -240,7 +253,11 @@ try {
|
|
|
240
253
|
run("git tag", ["git", "tag", "-a", tag, "-m", msg], repoRoot);
|
|
241
254
|
run("git push", ["git", "push"], repoRoot);
|
|
242
255
|
run("git push tags", ["git", "push", "--tags"], repoRoot);
|
|
243
|
-
run(
|
|
256
|
+
run(
|
|
257
|
+
"gh release",
|
|
258
|
+
["gh", "release", "create", tag, "--title", tag, "--notes-file", notesPath],
|
|
259
|
+
repoRoot,
|
|
260
|
+
);
|
|
244
261
|
run("npm publish", ["npm", "publish"], repoRoot);
|
|
245
262
|
} finally {
|
|
246
263
|
await unlink(notesPath).catch(() => {});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { CliProgram } from "../types.ts";
|
|
3
|
+
import { exportPresentationBuiltins } from "./export.ts";
|
|
4
|
+
import { completionBashScript, completionFishScript, completionZshScript } from "./index.ts";
|
|
2
5
|
import { cliBuiltinInstallCommand, installBuiltinOptions } from "./install.ts";
|
|
3
6
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
4
7
|
import { cliPresentationRoot } from "./presentation.ts";
|
|
5
|
-
import { completionBashScript, completionFishScript, completionZshScript } from "./index.ts";
|
|
6
|
-
import { exportPresentationBuiltins } from "./export.ts";
|
|
7
|
-
import { CliProgram } from "../types.ts";
|
|
8
8
|
|
|
9
9
|
const fixture: CliProgram = {
|
|
10
10
|
key: "myapp",
|
|
@@ -114,7 +114,12 @@ describe("completion emitters", () => {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
test("zsh script registers compdef", () => {
|
|
117
|
-
const schema = cliPresentationRoot({
|
|
117
|
+
const schema = cliPresentationRoot({
|
|
118
|
+
key: "zapp",
|
|
119
|
+
version: "0.0.0",
|
|
120
|
+
description: "z",
|
|
121
|
+
handler: () => {},
|
|
122
|
+
});
|
|
118
123
|
const zsh = completionZshScript(schema);
|
|
119
124
|
expect(zsh).toContain("#compdef zapp");
|
|
120
125
|
expect(zsh).toContain("compdef _zapp zapp");
|