argsbarg 3.6.0 → 3.6.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.
@@ -1,455 +0,0 @@
1
- ---
2
- name: v1.3 — parser ergonomics
3
- overview: "Four targeted parser and DX improvements: nested fallbackCommand on any routing node, varargs + trailing options interleaved (fixes --flag after positionals), ctx.positional(name) named accessor, and MCP string→array coercion for varargs positionals."
4
- todos:
5
- - id: types-jsdoc
6
- content: "Step 1: Update JSDoc on fallbackCommand/fallbackMode to remove 'root-only' / 'top-level' language; no type changes needed"
7
- status: completed
8
- - id: validate-fallback
9
- content: "Step 2: Remove root-only restriction on fallbackCommand/fallbackMode in validate.ts; add validation that fallbackCommand names a valid child key on any routing node"
10
- status: completed
11
- - id: parser-fallback
12
- content: "Step 3: Extend routing loop to apply fallbackCommand/fallbackMode at non-root routing nodes (mirrors existing root logic)"
13
- status: completed
14
- - id: parser-varargs-trailing
15
- content: "Step 4: Fix finishLeaf varargs loop to interleave known-option scanning instead of greedy-consuming all remaining tokens"
16
- status: completed
17
- - id: ctx-positional
18
- content: "Step 5: Add ctx.positional(name) accessor to CliContext — named positional lookup computed from schema + commandPath + args"
19
- status: completed
20
- - id: mcp-coerce
21
- content: "Step 6: Coerce string → string[] in mcpToolCallToArgv for varargs positionals (comma-split or single-item)"
22
- status: completed
23
- - id: tests
24
- content: "Step 7: Unit + integration tests for all four features"
25
- status: completed
26
- - id: docs-changelog
27
- content: "Step 8: Update README, CHANGELOG, docs/mcp.md; run just typegen and just test"
28
- status: completed
29
- isProject: false
30
- ---
31
-
32
- # v1.3 — parser ergonomics
33
-
34
- Four parser and DX improvements. No new runtime dependencies, no public API removals, no MCP protocol changes. All four were explicitly deferred from v1.2 and follow directly from consumer app feedback.
35
-
36
- ---
37
-
38
- ## Background
39
-
40
- From reading the current source before writing this plan:
41
-
42
- - **`fallbackCommand` types already support non-root** — `CliCommand` union allows `fallbackCommand` on any router node. The restriction is purely in `validate.ts` lines 39–52 (`!isRoot && cmd.fallbackCommand !== undefined → throw`). Parser fix is in the routing `while(true)` loop.
43
- - **Trailing options are already partially wired** — `finishLeaf` calls `consumeOptions` on the tail for bounded-arity positionals (see `allowsTrailingOptions`). The gap is varargs (`argMax === 0`): the greedy loop at line 289–304 consumes all remaining tokens before any trailing option scan can happen.
44
- - **`ctx.positional(name)`** — `CliContext` has `args: string[]` and `schema: CliCommand`. Named positional access can be computed from those; no parser change required.
45
- - **MCP string→array coercion** — `mcpToolCallToArgv` currently requires `args[pos.name]` to be `string[]` for varargs. Accepts only arrays; agents passing `"a,b"` or `"a"` silently fail.
46
-
47
- ---
48
-
49
- ## Implementation order
50
-
51
- 1. JSDoc cleanup (no logic)
52
- 2. Validation: remove root-only fallback restriction
53
- 3. Parser: nested fallback routing
54
- 4. Parser: varargs + trailing options interleaved
55
- 5. `ctx.positional(name)`
56
- 6. MCP string→array coercion
57
- 7. Tests
58
- 8. Docs + changelog
59
-
60
- Do steps 3 and 4 independently — they touch different parts of `parse.ts`. Step 3 is the routing loop; step 4 is `finishLeaf`. Both must pass existing tests before moving on.
61
-
62
- ---
63
-
64
- ## Step 1: JSDoc ([`src/types.ts`](src/types.ts))
65
-
66
- No type changes. Update JSDoc on the router branch of `CliCommand`:
67
-
68
- - `fallbackCommand`: change "Default **top-level** subcommand" → "Default subcommand"
69
- - `fallbackMode`: change "How fallbackCommand is applied" — add note that both fields work on any routing node, not just root
70
-
71
- ---
72
-
73
- ## Step 2: Validation ([`src/validate.ts`](src/validate.ts))
74
-
75
- ### Remove root-only restriction
76
-
77
- Delete lines 39–52 entirely:
78
- ```typescript
79
- // DELETE:
80
- if (!isRoot && cmd.fallbackCommand !== undefined) {
81
- throw new CliSchemaValidationError(
82
- "Fallback is only supported on the program root (not on " + cmd.key + ")",
83
- );
84
- }
85
- if (!isRoot && cmd.fallbackMode !== undefined && ...) {
86
- throw new CliSchemaValidationError(
87
- "fallbackMode may only be set on the program root (not on " + cmd.key + ")",
88
- );
89
- }
90
- ```
91
-
92
- ### Add fallbackCommand child validation (apply to ALL routing nodes, not just root)
93
-
94
- After the duplicate child name check (the `seenNames` loop), add:
95
-
96
- ```typescript
97
- // fallbackMode without fallbackCommand is always invalid — check unconditionally
98
- if (cmd.fallbackMode !== undefined && cmd.fallbackCommand === undefined) {
99
- throw new CliSchemaValidationError(
100
- `fallbackMode requires fallbackCommand on '${cmd.key}'`,
101
- );
102
- }
103
-
104
- if (cmd.fallbackCommand !== undefined) {
105
- const children = cmd.commands ?? [];
106
- const valid = children.find((c) => c.key === cmd.fallbackCommand);
107
- if (!valid) {
108
- throw new CliSchemaValidationError(
109
- `fallbackCommand '${cmd.fallbackCommand}' is not a child of '${cmd.key}'`,
110
- );
111
- }
112
- }
113
- ```
114
-
115
- **Note:** The existing root-level validation already does the child-lookup check implicitly via the runtime. Moving it into schema validation means it's caught at startup, not at dispatch time.
116
-
117
- ---
118
-
119
- ## Step 3: Parser — nested `fallbackCommand` ([`src/parse.ts`](src/parse.ts))
120
-
121
- The routing `while(true)` loop (line ~459) has two places where non-root routing nodes currently error. Both need fallback logic inserted before the error return.
122
-
123
- ### Place 1: End of argv, current node has children (line ~485)
124
-
125
- Currently: `return helpResult(path, false)` when `current.commands.length > 0` and argv is exhausted.
126
-
127
- Add before that return:
128
- ```typescript
129
- if ((current.commands ?? []).length > 0) {
130
- const fb = current.fallbackCommand;
131
- const fm = current.fallbackMode ?? CliFallbackMode.MissingOnly;
132
- if (
133
- fb !== undefined &&
134
- (fm === CliFallbackMode.MissingOnly || fm === CliFallbackMode.MissingOrUnknown)
135
- ) {
136
- const fbNode = findChild(current.commands ?? [], fb);
137
- if (fbNode) {
138
- path.push(fb);
139
- current = fbNode;
140
- continue;
141
- }
142
- }
143
- return helpResult(path, false);
144
- }
145
- ```
146
-
147
- ### Place 2: Unknown subcommand token (line ~515–526)
148
-
149
- Currently: `return error "Unknown subcommand: tok"` when the token doesn't match any child.
150
-
151
- Add before that return:
152
- ```typescript
153
- if ((current.commands ?? []).length > 0) {
154
- const fb = current.fallbackCommand;
155
- const fm = current.fallbackMode ?? CliFallbackMode.MissingOnly;
156
- const canRouteUnknown =
157
- fb !== undefined &&
158
- (fm === CliFallbackMode.MissingOrUnknown || fm === CliFallbackMode.UnknownOnly);
159
-
160
- if (canRouteUnknown) {
161
- const fbNode = findChild(current.commands ?? [], fb!);
162
- if (fbNode) {
163
- // Do NOT advance i — the unrecognized token stays as argv for the fallback
164
- path.push(fb!);
165
- current = fbNode;
166
- continue;
167
- }
168
- }
169
- return { kind: ParseKind.Error, ..., errorMsg: `Unknown subcommand: ${tok}` };
170
- }
171
- ```
172
-
173
- This mirrors the root-level fallback logic at lines 406–452 exactly. The same `CliFallbackMode` semantics apply at every routing level.
174
-
175
- ---
176
-
177
- ## Step 4: Parser — varargs + trailing options ([`src/parse.ts`](src/parse.ts) — `finishLeaf`)
178
-
179
- ### The problem
180
-
181
- `finishLeaf`'s varargs branch (line ~289–304):
182
- ```typescript
183
- if (argMax === 0) {
184
- while (idx < argv.length) {
185
- args.push(argv[idx]); // ← greedy: swallows --json and all flags
186
- idx += 1;
187
- count += 1;
188
- }
189
- }
190
- ```
191
-
192
- All remaining tokens (including `--flag` tokens) are consumed as positionals. The trailing option scan at lines 307–325 never runs because `idx === argv.length` after the greedy loop.
193
-
194
- ### The fix
195
-
196
- Replace the greedy varargs loop with an interleaved loop that recognizes known options:
197
-
198
- ```typescript
199
- if (argMax === 0) {
200
- while (idx < argv.length) {
201
- const tok = argv[idx];
202
-
203
- // -- separator: force remaining tokens as positionals
204
- if (!forcePositionals && tok === "--") {
205
- forcePositionals = true;
206
- idx++;
207
- continue;
208
- }
209
-
210
- // Scoped help inside varargs tail — mirrors bounded path at lines 312–314
211
- if (!forcePositionals && isHelpTok(tok)) {
212
- return helpResult(path, true);
213
- }
214
-
215
- // Possible option token: attempt to consume as a known flag
216
- if (!forcePositionals && tok.startsWith("-")) {
217
- // MUST be false — lenient mode swallows unknown flags as positionals silently
218
- const tailRep = consumeOptions(optionDefs, false, argv, idx, opts);
219
- if (tailRep.report.err) {
220
- return errorResult(tailRep.report.err);
221
- }
222
- if (tailRep.report.sawDoubleDash) {
223
- forcePositionals = true;
224
- }
225
- if (tailRep.nextIndex > idx) {
226
- // Consumed one or more options — loop without pushing a positional
227
- idx = tailRep.nextIndex;
228
- continue;
229
- }
230
- // consumeOptions stopped without advancing (unknown token in lenient mode
231
- // would return stoppedOnUnknown, but we pass lenientUnknown=false, so
232
- // any unknown -flag is already an error above). Fallthrough to error.
233
- return errorResult(`Unexpected option token: ${tok}`);
234
- }
235
-
236
- // Plain positional token
237
- args.push(tok);
238
- idx++;
239
- count++;
240
- }
241
- }
242
- ```
243
-
244
- **Key rules:**
245
- - `consumeOptions` is called with `lenientUnknown: false` — unknown flags in varargs tails are still errors, not silently treated as positionals
246
- - `--` terminates option scanning exactly as before; tokens after it go straight to `args`
247
- - Bounded positionals are unchanged — their existing trailing option scan at lines 307–325 still runs and is unaffected
248
-
249
- **Remove `allowsTrailingOptions`** — it becomes dead code once varargs interleaves. Delete the function and its call site.
250
-
251
- ---
252
-
253
- ## Step 5: `ctx.positional(name)` ([`src/context.ts`](src/context.ts))
254
-
255
- ### Accessor
256
-
257
- ```typescript
258
- /**
259
- * Returns the value(s) for a named positional slot.
260
- * Varargs slots (argMax === 0) return string[]; single slots return string | undefined.
261
- */
262
- positional(name: string): string | string[] | undefined {
263
- return this._positionalMap()[name];
264
- }
265
- ```
266
-
267
- ### Implementation (`_positionalMap`)
268
-
269
- Compute lazily and cache. Walk `this.schema` along `this.commandPath` to find the leaf, then map positional definitions to slices of `this.args`:
270
-
271
- ```typescript
272
- private _posMap: Record<string, string | string[]> | undefined;
273
-
274
- private _positionalMap(): Record<string, string | string[]> {
275
- if (this._posMap) return this._posMap;
276
-
277
- let node: CliCommand = this.schema;
278
- for (const seg of this.commandPath) {
279
- const child = (node.commands ?? []).find((c) => c.key === seg);
280
- if (!child) { this._posMap = {}; return {}; }
281
- node = child;
282
- }
283
-
284
- const map: Record<string, string | string[]> = {};
285
- let argIdx = 0;
286
- for (const p of node.positionals ?? []) {
287
- const { argMax = 1 } = p;
288
- if (argMax === 0) {
289
- map[p.name] = this.args.slice(argIdx);
290
- argIdx = this.args.length;
291
- } else {
292
- const val = this.args[argIdx];
293
- if (val !== undefined) map[p.name] = val;
294
- argIdx++;
295
- }
296
- }
297
-
298
- this._posMap = map;
299
- return map;
300
- }
301
- ```
302
-
303
- **Return type semantics:**
304
- - Varargs (`argMax === 0`) → always `string[]` (may be empty)
305
- - Single slot (`argMax === 1`) → `string` if present, `undefined` if optional and absent
306
- - Always consistent with `ctx.args` — `ctx.positional` is a named view over the same data
307
-
308
- **No changes to `ctx.args`** — existing handlers continue to work; this is purely additive.
309
-
310
- ### Export
311
-
312
- Add `positional` to the public method list in JSDoc. No changes to `src/index.ts` needed — `CliContext` is already exported and consumers get the new method automatically.
313
-
314
- ---
315
-
316
- ## Step 6: MCP string→array coercion ([`src/mcp/tools.ts`](src/mcp/tools.ts) — `mcpToolCallToArgv`)
317
-
318
- ### Current behavior (varargs positional)
319
-
320
- ```typescript
321
- // Current:
322
- const val = args[pos.name];
323
- // assumes val is string[] — agents passing "a,b" or "a" get undefined behavior
324
- argv.push(...(val as string[]));
325
- ```
326
-
327
- ### Fix
328
-
329
- ```typescript
330
- const raw = args[pos.name];
331
- let items: string[];
332
- if (Array.isArray(raw)) {
333
- items = raw.map(String);
334
- } else if (typeof raw === "string") {
335
- // Coerce: comma-split or single item
336
- items = raw.includes(",")
337
- ? raw.split(",").map((s) => s.trim()).filter(Boolean)
338
- : raw.trim() ? [raw.trim()] : [];
339
- } else {
340
- items = [];
341
- }
342
- argv.push(...items);
343
- ```
344
-
345
- **`inputSchema` stays `{ type: "array", items: { type: "string" } }`** — array is the correct type for well-behaved agents. The coercion is a silent recovery from agents that pass strings anyway. Do not change the schema to `oneOf` — that complicates the JSON Schema unnecessarily.
346
-
347
- **Single string `"a"` → `["a"]`** (not comma-split). Comma is the delimiter only when present.
348
-
349
- ---
350
-
351
- ## Step 7: Tests ([`src/index.test.ts`](src/index.test.ts))
352
-
353
- ### Nested `fallbackCommand` — unit tests
354
-
355
- 1. Router node with `fallbackCommand` and empty argv → routes to fallback leaf.
356
- 2. Router node with `fallbackCommand` + `MissingOrUnknown` + unknown token → routes to fallback (token stays in argv for fallback leaf).
357
- 3. Router node with `fallbackCommand` + `MissingOnly` + unknown token → error "Unknown subcommand".
358
- 4. `cliValidateRoot` rejects `fallbackCommand` naming a non-existent child on a non-root node.
359
- 5. `cliValidateRoot` accepts `fallbackCommand` on a non-root router node when child exists.
360
- 6. Scoped help: `myapp docs --help` on a router with fallback → shows docs subcommands, not fallback content.
361
-
362
- ### Varargs + trailing options — unit tests
363
-
364
- 7. `cliInvoke(root, ["read", "file.txt", "--json"])` where `read` has varargs positional and `--json` is a known option → `kind: "ok"`, `args: ["file.txt"]`, `opts: { json: "1" }`.
365
- 8. `cliInvoke(root, ["read", "--json", "file.txt"])` → same result (option before varargs).
366
- 9. `cliInvoke(root, ["read", "a.txt", "b.txt", "--json"])` → `args: ["a.txt", "b.txt"]`, `opts: { json: "1" }`.
367
- 10. `cliInvoke(root, ["read", "file.txt", "--", "--json"])` → `args: ["file.txt", "--json"]`, `opts: {}` (`--` forces positional).
368
- 11. `cliInvoke(root, ["read", "--unknown"])` → `kind: "error"`, errorMsg mentions `--unknown`.
369
- 12. `parse(root, ["read", "file.txt", "--help"])` on a varargs leaf → `kind: Help`, `helpPath` contains `"read"` (scoped help, not an error). This guards the `isHelpTok` insertion.
370
-
371
- **Regression test inversion:** The existing test `"varargs tail does not parse trailing options"` (approximately line 337 in `index.test.ts`) currently *asserts the broken behavior* — `--json` ends up in `args`. Invert it: after Step 4, assert `--json` is in `opts` and absent from `args`. Do this as part of Step 7, not before.
372
-
373
- ### `ctx.positional(name)` — unit tests
374
-
375
- 13. Handler reads `ctx.positional("path")` on single-slot positional — returns the string value.
376
- 14. Handler reads `ctx.positional("files")` on varargs positional — returns `string[]`.
377
- 15. Handler reads `ctx.positional("opt")` on absent optional positional — returns `undefined`.
378
- 16. `ctx.positional("files")` consistent with `ctx.args`: `ctx.positional("files")` deep-equals `ctx.args` when there is one varargs positional.
379
-
380
- ### MCP string→array coercion — unit tests
381
-
382
- 17. `mcpToolCallToArgv` with varargs positional: `args: { files: "a,b" }` → argv includes `"a"`, `"b"` as separate tokens.
383
- 18. `mcpToolCallToArgv` with varargs positional: `args: { files: "a" }` (no comma) → argv includes `"a"` once.
384
- 19. `mcpToolCallToArgv` with varargs positional: `args: { files: ["a","b"] }` (array) → unchanged behavior.
385
- 20. `mcpToolCallToArgv` with varargs positional: `args: { files: "" }` (empty string) → no tokens appended.
386
-
387
- ---
388
-
389
- ## Step 8: Docs + changelog
390
-
391
- ### [`README.md`](README.md)
392
-
393
- - Update `fallbackCommand` / `fallbackMode` table to note they work on any routing node.
394
- - Add `ctx.positional(name)` to the Reading values section.
395
-
396
- ### [`docs/mcp.md`](docs/mcp.md)
397
-
398
- - Note MCP string→array coercion under tool arguments: agents may pass a comma-separated string for varargs positionals.
399
-
400
- ### [`CHANGELOG.md`](CHANGELOG.md) — `[Unreleased]` → Added / Fixed
401
-
402
- **Added:**
403
- - `fallbackCommand` / `fallbackMode` now work on any routing node, not just the program root
404
- - `ctx.positional(name)` — named positional lookup; varargs return `string[]`, single slots return `string | undefined`
405
- - MCP varargs coercion: agents may pass `"a,b"` or `"a"` where `string[]` is expected
406
-
407
- **Fixed:**
408
- - Known options (`--flag`) after varargs positionals now parse correctly instead of being consumed as positional tokens
409
-
410
- ### Typegen
411
-
412
- ```
413
- just typegen
414
- ```
415
-
416
- Verify `index.d.ts` reflects the new `positional` method on `CliContext`. No other new public types in this release.
417
-
418
- ---
419
-
420
- ## Pitfalls (do NOT)
421
-
422
- - Change `inputSchema` for varargs from `array` to `oneOf` — coercion is silent, schema stays canonical
423
- - Remove `ctx.args` — additive only; existing handlers must continue to work
424
- - Apply nested fallback logic before the existing root fallback — the root-level fallback code (lines 406–452 in `parse.ts`) stays as-is; the new code mirrors it in the routing loop body
425
- - Use `lenientUnknown: true` in the varargs interleaved option scan — unknown flags in varargs tails must still error
426
- - Break `allowsTrailingOptions` callers before deleting it — verify it has only one call site (line 308) before removing
427
-
428
- ---
429
-
430
- ## File change summary
431
-
432
- | File | Action |
433
- |------|--------|
434
- | [`src/types.ts`](src/types.ts) | JSDoc updates only |
435
- | [`src/validate.ts`](src/validate.ts) | Remove root-only fallback restriction; add child-key validation for all routing nodes |
436
- | [`src/parse.ts`](src/parse.ts) | Nested fallback in routing loop; varargs interleaved option scan; remove `allowsTrailingOptions` |
437
- | [`src/context.ts`](src/context.ts) | `positional(name)` accessor + `_positionalMap` private helper |
438
- | [`src/mcp/tools.ts`](src/mcp/tools.ts) | String→array coercion in `mcpToolCallToArgv` |
439
- | [`src/index.test.ts`](src/index.test.ts) | All new tests |
440
- | [`README.md`](README.md) | fallback + ctx.positional docs |
441
- | [`docs/mcp.md`](docs/mcp.md) | MCP coercion note |
442
- | [`CHANGELOG.md`](CHANGELOG.md) | Unreleased entries |
443
- | [`index.d.ts`](index.d.ts) | Regenerated via `just typegen` |
444
-
445
- ---
446
-
447
- ## Out of scope (explicitly deferred)
448
-
449
- - `ctx.positional` type overloads by argMax — return type is `string | string[] | undefined` for all slots; narrowing by schema type is possible but requires conditional types and adds complexity without clear benefit
450
- - `mcpTool.group` / `risk` / `requiresTty` annotations
451
- - `structuredError` for JSON on exit(1)
452
- - Streaming tool calls
453
- - Shared option groups / `extends`
454
- - Output truncation in MCP results
455
- - GNU-style option parsing before command routing (options mixed with subcommand tokens at root level)
@@ -1,9 +0,0 @@
1
- ---
2
- description: Code quality and style rules for TypeScript files
3
- globs: **/*.ts
4
- ---
5
-
6
- - Changes must be summarized in CHANGELOG.md under the UNRELEASED section
7
- - All imports must be ordered alphabetically by their source module path (the `from` clause).
8
- - Explicit exports using the `export { ... } from "..."` or `export type { ... } from "..."` syntax must be ordered alphabetically by their source module path and placed at the top of the file, immediately below the imports.
9
- - Types, Interfaces, Functions must have a docstring
@@ -1,8 +0,0 @@
1
- ---
2
- description: Project context for AI agents
3
- ---
4
-
5
- Always include in context before answering or making changes in this repository:
6
-
7
- - `README.md`
8
- - `.cursor/rules/*`
@@ -1,13 +0,0 @@
1
- ## Summary
2
-
3
- <!-- What does this PR change and why? -->
4
-
5
- ## Changelog
6
-
7
- **Every PR must update `CHANGELOG.md` under `## [Unreleased]`**: use `### Added`, `### Changed`, `### Fixed`, or `### Removed` as appropriate; one idea per bullet.
8
-
9
- <!-- If you claimed no-op above, briefly say why no changelog entry is warranted. -->
10
-
11
- ## Testing
12
-
13
- <!-- How did you verify this (local build, tests, manual run, etc.)? -->
@@ -1,4 +0,0 @@
1
- - [x] --schema feature for ai agents
2
- - [x] opt-out install feature?
3
- - [x] outputSchema
4
- - [x] mcpb bundle
package/CLAUDE.md DELETED
@@ -1,8 +0,0 @@
1
- ---
2
- description: Project context for AI agents
3
- ---
4
-
5
- Always include in context before answering or making changes in this repository:
6
-
7
- - `./README.md`
8
- - .cursor/rules/*
package/biome.json DELETED
@@ -1,40 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
3
- "assist": { "actions": { "source": { "organizeImports": "on" } } },
4
- "linter": {
5
- "enabled": true,
6
- "rules": {
7
- "preset": "recommended"
8
- }
9
- },
10
- "formatter": {
11
- "enabled": true,
12
- "indentStyle": "space",
13
- "lineWidth": 100
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
- ]
40
- }
package/bun.lock DELETED
@@ -1,43 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 1,
4
- "workspaces": {
5
- "": {
6
- "name": "argsbarg",
7
- "devDependencies": {
8
- "@biomejs/biome": "^2.5.0",
9
- "@types/bun": "^1.3.12",
10
- "typescript": "^5.9.3",
11
- },
12
- },
13
- },
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
-
33
- "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
34
-
35
- "@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="],
36
-
37
- "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
38
-
39
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
40
-
41
- "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
42
- }
43
- }
package/justfile DELETED
@@ -1,54 +0,0 @@
1
- # https://github.com/casey/just — run `just` to list recipes.
2
-
3
- set shell := ["bash", "-eu", "-o", "pipefail", "-c"]
4
-
5
- _:
6
- @just --list
7
-
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=(idp-trees sqsp-qa-tools sqsp-i18n-tools)
17
- for app in "${apps[@]}"; do
18
- dir="$(cd "$ss/$app" && pwd)"
19
- echo "==> $app ($dir)"
20
- (cd "$dir" && bun i argsbarg@latest && just build && just docgen && just install)
21
- done
22
-
23
- # run the minimal example
24
- example *ARGS:
25
- bun ./examples/minimal.ts {{ARGS}}
26
-
27
- # run the minimal example and watch for changes
28
- example-watch *ARGS:
29
- bun --watch ./examples/minimal.ts {{ARGS}}
30
-
31
- # format the codebase
32
- format:
33
- bun run biome check ./src ./scripts --write
34
-
35
- # lint the codebase
36
- lint:
37
- bun run biome check ./src ./scripts
38
-
39
- # Typecheck, lint, then run the test suite.
40
- test: check
41
- bun test
42
-
43
- # typecheck the codebase
44
- typecheck:
45
- bun run tsc --noEmit
46
-
47
- # generate type declarations for the package
48
- typegen:
49
- bunx dts-bundle-generator --out-file index.d.ts src/index.ts
50
-
51
- # publish to github and npm
52
- release bump: test typegen
53
- bun scripts/release.ts {{bump}}
54
-
package/logo.png DELETED
Binary file
package/plan.md DELETED
@@ -1,19 +0,0 @@
1
- # bun-argsbarg Plan
2
-
3
- ## Current Status
4
-
5
- **Overall**: Core CLI, MCP, install, docs, and `install --update` are complete. Public API is stable at **3.x**.
6
-
7
- ### Shipped
8
-
9
- - Schema-driven parsing, help, completions, subcommand routing, fallback commands
10
- - MCP server (`mcpServer: { enabled: true }`), `ctx.invocation`, `cliInvoke`
11
- - `install` built-in (`install --update` when `updateGetLatest` is set), agent skills, bundled `docs` (topics, schema, api, skill, mcp)
12
- - Headless helpers and `ghReleaseUpdateGetLatest` for GitHub release consumers
13
-
14
- ### Consumers
15
-
16
- - **qa-cli** — argsbarg program with Ink UI; commands under `src/commands/`
17
- - **idp-trees** — argsbarg program with headless JSON ops; `cli/dispatch.ts` pattern
18
-
19
- See [README.md](README.md) and [CHANGELOG.md](CHANGELOG.md) for release history.