argsbarg 5.1.16 → 6.0.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/README.md +33 -25
  3. package/docs/README.md +2 -1
  4. package/docs/api-server.md +141 -0
  5. package/docs/bundled-docs.md +24 -10
  6. package/docs/cli-program.md +17 -2
  7. package/docs/config-schema.md +18 -8
  8. package/docs/developing.md +1 -1
  9. package/docs/mcp.md +5 -5
  10. package/docs/output-schema.md +78 -47
  11. package/examples/full-example/README.md +15 -6
  12. package/examples/full-example/docs/README.md +27 -0
  13. package/examples/full-example/docs/api.md +511 -0
  14. package/examples/full-example/docs/cli-schema.json +453 -0
  15. package/examples/full-example/docs/http.md +81 -0
  16. package/examples/full-example/docs/mcp.md +159 -0
  17. package/examples/full-example/docs/openapi.json +222 -0
  18. package/examples/full-example/docs/skill.md +46 -0
  19. package/examples/full-example/justfile +6 -2
  20. package/examples/full-example/schemas/generated/app-config.json +1 -1
  21. package/examples/full-example/schemas/generated/status.json +1 -1
  22. package/examples/full-example/scripts/dev-formula.ts +1 -1
  23. package/examples/full-example/scripts/schemagen/discover-schema-roots.test.ts +3 -3
  24. package/examples/full-example/scripts/schemagen/discover-schema-roots.ts +90 -35
  25. package/examples/full-example/scripts/schemagen/naming.ts +17 -0
  26. package/examples/full-example/scripts/schemagen.ts +14 -3
  27. package/examples/full-example/src/commands/echo/command.ts +6 -1
  28. package/examples/full-example/src/commands/status/schema-types.ts +14 -0
  29. package/examples/full-example/src/commands/status/types.ts +1 -11
  30. package/examples/full-example/src/{types.ts → config/schema-types.ts} +3 -2
  31. package/examples/full-example/src/program.ts +3 -0
  32. package/examples/mcp-test.ts +13 -2
  33. package/examples/nested.ts +12 -3
  34. package/examples/servers.ts +72 -0
  35. package/index.d.ts +66 -7
  36. package/package.json +17 -17
  37. package/src/api/openapi.ts +117 -0
  38. package/src/api/result.ts +111 -0
  39. package/src/api/schema-deref.test.ts +99 -0
  40. package/src/api/schema-deref.ts +76 -0
  41. package/src/api/server.ts +120 -0
  42. package/src/api.integration.test.ts +441 -0
  43. package/src/builtins/api.ts +38 -0
  44. package/src/builtins/dispatch.ts +26 -0
  45. package/src/builtins/registry.ts +4 -0
  46. package/src/capabilities.ts +12 -1
  47. package/src/cli-errors.ts +3 -0
  48. package/src/cli-tool/full-example-capabilities.test.ts +3 -0
  49. package/src/cli.ts +60 -8
  50. package/src/config.integration.test.ts +22 -4
  51. package/src/context.ts +29 -1
  52. package/src/docs/api-guide.ts +2 -2
  53. package/src/docs/builtin.ts +11 -1
  54. package/src/docs/docs.test.ts +70 -12
  55. package/src/docs/http-guide.ts +132 -0
  56. package/src/docs/mcp-guide.ts +3 -3
  57. package/src/docs/mcp-resources.ts +5 -2
  58. package/src/docs/resolve.ts +26 -2
  59. package/src/docs/save.ts +5 -2
  60. package/src/headless/tool-call.ts +157 -0
  61. package/src/headless.test.ts +4 -2
  62. package/src/headless.ts +10 -5
  63. package/src/index.ts +5 -0
  64. package/src/mcp/result.ts +39 -34
  65. package/src/mcp/server.ts +18 -36
  66. package/src/mcp/tools.ts +14 -3
  67. package/src/mcp.integration.test.ts +46 -39
  68. package/src/parse.test.ts +16 -6
  69. package/src/respond.ts +48 -0
  70. package/src/schema.ts +1 -1
  71. package/src/skill/generate.ts +1 -1
  72. package/src/types.ts +46 -4
  73. package/src/validate.ts +7 -0
@@ -19,12 +19,13 @@ export const status = {
19
19
 
20
20
  | Where argsbarg uses it | Purpose |
21
21
  | --- | --- |
22
- | `myapp docs schema` | Full command tree JSON export |
22
+ | `myapp docs cli-schema` | Full command tree JSON export |
23
23
  | `myapp docs api` | Markdown per-command **Output** section |
24
24
  | `myapp docs skill` | `reference.md` for agent skills |
25
25
  | MCP `tools/list` | Optional `outputSchema` on each tool |
26
+ | HTTP `GET /openapi.json` | Response schema per tool |
26
27
 
27
- **Not validated at runtime** — argsbarg does not parse or reject handler stdout against the schema today. The schema is documentation and MCP metadata.
28
+ **Not validated at runtime** — argsbarg does not parse or reject handler stdout against the schema today. The schema is documentation and MCP/HTTP metadata.
28
29
 
29
30
  **Set on the leaf only** — not under `mcpTool` (legacy `mcpTool.outputSchema` still resolves but is deprecated).
30
31
 
@@ -43,31 +44,29 @@ Production CLIs with several JSON commands tend to use **codegen** so types, han
43
44
 
44
45
  ## Recommended pipeline (copy per repo)
45
46
 
46
- No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-manager-poc**, **sqsp-workspaces**, **sqsp-i18n-tools-poc** (see each repo’s `docs/architecture.md` for which commands use which schema root).
47
+ No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-manager-poc**, **sqsp-workspaces**, **sqsp-i18n-tools-poc**, **pdf-gen** (see each repo’s `docs/architecture.md` for which commands use which schema root).
47
48
 
48
49
  ```mermaid
49
50
  flowchart LR
50
- subgraph types [Schema-facing TS + JSDoc]
51
- TypesTs["src/**/types.ts"]
52
- Marker["JSDoc contains JSON payload"]
53
- Narrow["Narrowed types where needed"]
51
+ subgraph types [schema-types.ts]
52
+ Config["export type configType = AppConfig"]
53
+ Output["export type outputType = StatusJsonOutput"]
54
+ Input["export type inputType = ToolInput (optional)"]
54
55
  end
55
56
  subgraph gen [just schemagen]
56
- Discover["scripts/schemagen/discover-schema-roots.ts"]
57
- Script["scripts/generate-output-schemas.ts"]
57
+ Discover["discover-schema-roots.ts"]
58
+ Script["schemagen.ts / generate-output-schemas.ts"]
58
59
  Gen["ts-json-schema-generator"]
59
60
  end
60
61
  subgraph artifacts [Committed]
61
- Json["src/schemas/generated/*.json"]
62
- Bridge["src/schemas/outputSchemas.ts"]
62
+ Json["schemas/generated/*.json"]
63
+ Bridge["outputSchemas.ts / inputSchemas.ts"]
63
64
  end
64
65
  subgraph runtime [Runtime]
65
- Leaves["leaf outputSchema"]
66
+ Leaves["leaf outputSchema / inputSchema"]
66
67
  Docgen["just docgen"]
67
68
  end
68
- TypesTs --> Marker --> Discover
69
- Narrow --> Discover
70
- Discover --> Script --> Gen --> Json
69
+ types --> Discover --> Script --> Gen --> Json
71
70
  Script --> Bridge --> Leaves --> Docgen
72
71
  ```
73
72
 
@@ -75,61 +74,95 @@ flowchart LR
75
74
  | --- | --- |
76
75
  | Generator | [`ts-json-schema-generator`](https://github.com/vega/ts-json-schema-generator) (`createGenerator` with `jsDoc: "extended"`) |
77
76
  | Config | `tsconfig: "tsconfig.json"`, `topRef: false`, `skipTypeCheck: false` |
78
- | Discovery | Walk `src/**/types.ts`; treat `export interface` as a schema root when its JSDoc contains **`JSON payload`** |
79
- | Artifacts | Commit `src/schemas/generated/*.json` **and** auto-generated `src/schemas/outputSchemas.ts` |
77
+ | Discovery | Walk `src/**/schema-types.ts`; generate from `export type outputType = …` / `inputType` / `configType` when the target type is **defined in that file** |
78
+ | Artifacts | Commit `schemas/generated/*.json` **and** auto-generated bridge modules |
80
79
  | tsconfig | `"resolveJsonModule": true` |
81
- | CI | `just check`: `schemagen` → `git diff --exit-code src/schemas/generated/ src/schemas/outputSchemas.ts` → typecheck |
82
- | Docgen | `docgen` depends on `schemagen` so saved `./docs/api.md` and `./docs/schema.json` are fresh |
80
+ | CI | `just check`: `schemagen` → `git diff --exit-code schemas/` → typecheck |
81
+ | Docgen | `docgen` depends on `schemagen` so saved `./docs/api.md` and `./docs/cli-schema.json` are fresh |
83
82
 
84
83
  Copy these scripts into each consumer repo (they are intentionally duplicated, not published):
85
84
 
86
- - `scripts/generate-output-schemas.ts` — generate JSON + rewrite the bridge
85
+ - `scripts/schemagen.ts` or `scripts/generate-output-schemas.ts` — generate JSON + rewrite bridges
87
86
  - `scripts/schemagen/discover-schema-roots.ts` — find roots and map names → filenames / export constants
88
87
  - `scripts/schemagen/discover-schema-roots.test.ts` — lock discovery and naming per app
89
88
 
90
- ### Marking a schema root
89
+ ### Declaring a schema root
91
90
 
92
- Put schema-facing interfaces in **`src/**/types.ts`** (e.g. `src/commands/status/types.ts`, `src/ui/runHeadless/types.ts`, `src/core/types.ts`). Add a JSDoc line containing **`JSON payload`** on the exported interface:
91
+ Put schema-facing interfaces in **`schema-types.ts`** next to the command (or in a shared module when several commands reuse one shape). Export a role alias:
93
92
 
94
93
  ```typescript
95
- /** JSON payload for `myapp status --json`. */
94
+ // src/commands/status/schema-types.ts
95
+ import type { WorkspaceStatus } from "./types.ts";
96
+
97
+ /** JSON stdout for `myapp status --json`. */
96
98
  export interface StatusJsonOutput {
97
- items: StatusJsonItem[];
99
+ workspaces: WorkspaceStatus[];
98
100
  }
99
101
 
100
- /** JSON payload written to stdout after a headless mutating command. */
102
+ /** Schemagen root for leaf outputSchema. */
103
+ export type outputType = StatusJsonOutput;
104
+ ```
105
+
106
+ ```typescript
107
+ // src/ui/runHeadless/schema-types.ts — shared by many mutating commands
108
+ import type { HeadlessTaskResult } from "./types.ts";
109
+
101
110
  export interface HeadlessOpResult {
102
111
  command: string;
103
112
  exitCode: number;
104
113
  tasks: HeadlessTaskResult[];
105
114
  }
115
+
116
+ export type outputType = HeadlessOpResult;
106
117
  ```
107
118
 
108
- `discoverSchemaRoots` scans only files named `types.ts` under `src/`. Nested helper interfaces in the same file are included in the generated schema when referenced by a root; they are **not** separate JSON files unless they are also marked roots.
119
+ ```typescript
120
+ // src/commands/render-invoice/schema-types.ts — custom HTTP/MCP body (pdf-gen)
121
+ export interface RenderInvoiceToolInput {
122
+ format: "pdf" | "html";
123
+ invoice: InvoiceData;
124
+ }
125
+
126
+ export type inputType = RenderInvoiceToolInput;
127
+ export type outputType = RenderInvoiceWrittenOutput;
128
+ ```
129
+
130
+ | Export | Role |
131
+ | --- | --- |
132
+ | `export type configType = AppConfig` | `program.appConfig.jsonSchema` (one per repo, typically `src/config/schema-types.ts`) |
133
+ | `export type outputType = …` | `leaf.outputSchema` |
134
+ | `export type inputType = …` | `leaf.inputSchema` (only when the tool body is not flat CLI flags) |
135
+
136
+ **Domain helpers** stay in `types.ts` (or `core/types.ts`). Discovery scans only `schema-types.ts`. Re-export-only files (`export type outputType = HeadlessOpResult` pointing at another module) are **not** generation roots — generate once from the canonical definition file.
137
+
138
+ Commands without structured JSON omit `schema-types.ts` and import a shared bridge constant (e.g. `HEADLESS_OP_RESULT_OUTPUT_SCHEMA`).
139
+
140
+ When you do **not** set `inputSchema`, argsbarg builds tool input from CLI `options` + `positionals`.
109
141
 
110
142
  ### Stable naming (outfile + bridge export)
111
143
 
112
- Discovery maps each root type name to a generated filename and `outputSchemas.ts` constant. Suffix conventions (implemented in `outfileForType` / `schemaExportName`):
144
+ Discovery maps each root type name to a generated filename and bridge constant. Suffix conventions (implemented in `outfileForOutputType` / `outputSchemaExportName`):
113
145
 
114
146
  | Type suffix | Example type | Generated file | Bridge export |
115
147
  | --- | --- | --- | --- |
116
148
  | `JsonOutput` | `StatusJsonOutput` | `status.json` | `STATUS_JSON_OUTPUT_SCHEMA` |
117
149
  | `OpResult` | `HeadlessOpResult` | `headless-op-result.json` | `HEADLESS_OP_RESULT_OUTPUT_SCHEMA` |
118
150
  | `Output` | `OpenUrlOutput` | `open-url.json` | `OPEN_URL_OUTPUT_SCHEMA` |
119
- | `Result` | `UidsResult` | `uids.json` | `UIDS_OUTPUT_SCHEMA` |
151
+ | `Result` | `PrResult` | `pr.json` | `PR_RESULT_OUTPUT_SCHEMA` |
152
+ | `ToolInput` | `RenderInvoiceToolInput` | `render-invoice-tool-input.json` | `RENDER_INVOICE_TOOL_INPUT_SCHEMA` |
120
153
 
121
154
  Prefer these suffixes for new roots so filenames and import constants stay predictable across repos.
122
155
 
123
156
  ### Generated bridge
124
157
 
125
- `scripts/generate-output-schemas.ts` rewrites `src/schemas/outputSchemas.ts` on every run:
158
+ `scripts/schemagen.ts` rewrites `schemas/outputSchemas.ts` on every run:
126
159
 
127
160
  ```typescript
128
- // Auto-generated by scripts/generate-output-schemas.ts — do not edit by hand.
161
+ // Auto-generated by scripts/schemagen.ts — do not edit by hand.
129
162
 
130
163
  import status from "./generated/status.json";
131
164
 
132
- /** JSON Schema for `myapp status --json`. */
165
+ /** JSON Schema for leaf outputSchema from `StatusJsonOutput`. */
133
166
  export const STATUS_JSON_OUTPUT_SCHEMA = status as Record<string, unknown>;
134
167
  ```
135
168
 
@@ -139,26 +172,24 @@ Wire the constant on each leaf that emits that shape (several commands may share
139
172
 
140
173
  **Goal:** generated schemas match what handlers actually print, with descriptions agents can read in `docs api`.
141
174
 
142
- 1. **Schema roots** — `export interface` in a `types.ts` file, with **`JSON payload`** in the interface JSDoc naming which command(s) emit it.
175
+ 1. **Schema roots** — `export interface` in `schema-types.ts`, with `export type outputType = …` (or `inputType` / `configType`).
143
176
  2. **Per property** — `/** … */` on every field that should appear in JSON Schema `properties` (including nested named types).
144
177
  3. **Unions / enums** — document the alias; generator emits `enum` / `anyOf` with type-level description.
145
178
  4. **Formats** — property JSDoc can include `@format date-time` for ISO timestamps; add a smoke test that the generated property has `format: "date-time"`.
146
- 5. **Do not hand-edit** `src/schemas/generated/` or `src/schemas/outputSchemas.ts` — change types/JSDoc, run `just schemagen`, commit both.
179
+ 5. **Do not hand-edit** `schemas/generated/` or bridge modules — change types/JSDoc, run `just schemagen`, commit both.
147
180
 
148
181
  ### Narrowing when runtime ≠ stdout
149
182
 
150
- When a shared runtime type is **wider** than one command’s JSON, add a **schema-facing** root in `types.ts` (still marked `JSON payload`):
183
+ When a shared runtime type is **wider** than one command’s JSON, add a **schema-facing** root in `schema-types.ts`:
151
184
 
152
185
  ```typescript
153
- /** Runtime union across commands. */
154
- export type ResultSource = TranslationReadinessSource | { kind: "uids"; uids: string[] };
155
-
156
- /** JSON payload for `myapp pr` and `myapp file`. */
186
+ /** JSON stdout for `myapp pr` and `myapp file`. */
157
187
  export interface TranslationReadinessResult {
158
188
  source: TranslationReadinessSource;
159
189
  evaluatedAt: string;
160
- // ...
161
190
  }
191
+
192
+ export type outputType = TranslationReadinessResult;
162
193
  ```
163
194
 
164
195
  Patterns:
@@ -173,18 +204,18 @@ Handlers keep using runtime types; only discovered roots (and their type graph)
173
204
  Per repo:
174
205
 
175
206
  - **`scripts/schemagen/discover-schema-roots.test.ts`** — asserts which roots are discovered and stable outfile / export-name mapping.
176
- - **`src/schemas/outputSchemas.test.ts`** (optional) — schema shape smoke tests: object root, key `description` fields, enums, `@format date-time`.
207
+ - **`schemas/outputSchemas.test.ts`** (optional) — schema shape smoke tests: object root, key `description` fields, enums, `@format date-time`.
177
208
 
178
209
  ## Contributor workflow
179
210
 
180
- 1. Add or edit schema-facing interfaces in `src/**/types.ts` with **`JSON payload`** JSDoc and per-field descriptions.
181
- 2. `just schemagen` — refresh `src/schemas/generated/` and `src/schemas/outputSchemas.ts`.
182
- 3. Import the bridge constant on the relevant leaf `outputSchema` fields.
183
- 4. Commit generated JSON and the bridge with the type changes.
211
+ 1. Add or edit schema roots in `src/**/schema-types.ts` with `outputType` / `inputType` / `configType` and per-field JSDoc.
212
+ 2. `just schemagen` — refresh `schemas/generated/` and bridge modules.
213
+ 3. Import the bridge constant on the relevant leaf `outputSchema` / `inputSchema` fields.
214
+ 4. Commit generated JSON and bridges with the type changes.
184
215
  5. `just docgen` / `myapp docs api --save` — refresh consumer docs.
185
216
  6. Document which commands use which roots in **your** `docs/architecture.md` (argsbarg does not maintain per-app tables).
186
217
 
187
- Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/cli-program.mdc` pointing at `node_modules/argsbarg/docs/output-schema.md` and your `src/schemas/` layout.
218
+ Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/cli-program.mdc` pointing at `node_modules/argsbarg/docs/output-schema.md` and your `schemas/` layout.
188
219
 
189
220
  **Reference implementation:** [`examples/full-example/`](../examples/full-example/) in this repo (shipped in npm as `node_modules/argsbarg/examples/full-example/`) — discovery script, bridges, and `status` leaf with `outputSchema`.
190
221
 
@@ -193,11 +224,11 @@ Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/c
193
224
  - Shared codegen package or monorepo tooling
194
225
  - Runtime Zod / `.parse()` on stdout in argsbarg
195
226
  - `outputSchema` for plain-text, streaming, or Ink-only commands
196
- - Schema roots outside `src/**/types.ts` (use a dedicated `types.ts` next to handlers instead of `resolve.ts`)
197
227
 
198
228
  ## See also
199
229
 
230
+ - [config-schema.md](config-schema.md) — `configType` / `program.appConfig`
200
231
  - [cli-program.md](cli-program.md) — structured stdout, headless JSON, `read*Flags`
201
232
  - [mcp.md](mcp.md) — `tools/list`, `structuredContent`
202
- - [bundled-docs.md](bundled-docs.md) — `docs api` / `docs schema` docgen
233
+ - [bundled-docs.md](bundled-docs.md) — `docs api` / `docs cli-schema` docgen
203
234
  - [docs/README.md](README.md) — documentation map
@@ -9,7 +9,7 @@ From a git checkout at this directory (requires [Homebrew](https://brew.sh), [ju
9
9
  ```bash
10
10
  brew install just bun
11
11
  just setup
12
- just schemagen # after changing src/**/types.ts
12
+ just schemagen # after changing src/**/schema-types.ts
13
13
  just run status --json
14
14
  just run docs readme
15
15
  ```
@@ -60,14 +60,23 @@ just test-release
60
60
 
61
61
  Undo a local dev install: `just uninstall` (formula + agent artifacts; app config removed by formula `uninstall`), `just uninstall-config` (app config only, without uninstalling the formula).
62
62
 
63
- ## Schemagen markers
63
+ ## Schemagen roots
64
64
 
65
- | Marker in interface JSDoc | Artifact |
65
+ | Export in `schema-types.ts` | Artifact |
66
66
  | --- | --- |
67
- | `Config schema` | `schemas/configSchemas.ts` + `schemas/generated/*-config.json` |
68
- | `JSON payload` | `schemas/outputSchemas.ts` + `schemas/generated/*.json` |
67
+ | `export type configType = …` | `schemas/configSchemas.ts` + `schemas/generated/*-config.json` |
68
+ | `export type outputType = …` | `schemas/outputSchemas.ts` + `schemas/generated/*.json` |
69
+ | `export type inputType = …` | `schemas/inputSchemas.ts` + `schemas/generated/*-tool-input.json` |
69
70
 
70
- Discovery walks `src/**/types.ts` only.
71
+ Discovery walks `src/**/schema-types.ts` only. Domain helpers stay in sibling `types.ts`.
72
+
73
+ ## Consumer docs
74
+
75
+ Regenerate committed reference docs under `docs/` (see [docs/README.md](docs/README.md)):
76
+
77
+ ```bash
78
+ just docgen
79
+ ```
71
80
 
72
81
  ## Environment
73
82
 
@@ -0,0 +1,27 @@
1
+ # full-example documentation
2
+
3
+ Reference template for argsbarg consumer docgen. Every builtin is enabled in `src/program.ts`.
4
+
5
+ | If you are… | Read |
6
+ | --- | --- |
7
+ | **Using the CLI** | [../README.md](../README.md) |
8
+ | **Authoring argsbarg schema** | `node_modules/argsbarg/docs/cli-program.md` — see `.cursor/rules/cli-program.mdc` |
9
+ | **HTTP API / curl** | [http.md](http.md) — generated; or run `full-example docs http` |
10
+ | **MCP tools** | [mcp.md](mcp.md) — generated; or run `full-example docs mcp` |
11
+ | **Full command tree (markdown)** | [api.md](api.md) — generated |
12
+ | **Full command tree (JSON)** | [cli-schema.json](cli-schema.json) — generated |
13
+ | **OpenAPI 3.1** | [openapi.json](openapi.json) — generated |
14
+ | **Agent skill index** | [skill.md](skill.md) — generated |
15
+
16
+ ## Framework docs vs this directory
17
+
18
+ | Layer | Contents |
19
+ | --- | --- |
20
+ | **Argsbarg framework** | How to author `CliProgram`, MCP, HTTP API | `node_modules/argsbarg/docs/` |
21
+ | **This `docs/` folder** | *full-example* command tree and guides | `just docgen` |
22
+
23
+ Do not hand-edit generated files. Refresh with:
24
+
25
+ ```bash
26
+ just docgen
27
+ ```