argsbarg 6.1.1 → 6.1.3

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 (229) hide show
  1. package/CHANGELOG.md +72 -1
  2. package/README.md +17 -19
  3. package/bin/argsbarg +10 -0
  4. package/docs/README.md +4 -3
  5. package/docs/ai-skills.md +4 -2
  6. package/docs/bundled-docs.md +50 -25
  7. package/docs/cli-program.md +76 -10
  8. package/docs/config-schema.md +10 -11
  9. package/docs/configure.md +2 -0
  10. package/docs/decisions.md +40 -0
  11. package/docs/developing.md +43 -5
  12. package/docs/http-server.md +171 -0
  13. package/docs/json-schema-subset.md +51 -0
  14. package/docs/mcp.md +4 -2
  15. package/docs/output-schema.md +55 -62
  16. package/examples/formats.ts +6 -6
  17. package/examples/full-example/Formula/full-example.rb +35 -0
  18. package/examples/full-example/README.md +20 -21
  19. package/examples/full-example/docs/README.md +1 -1
  20. package/examples/full-example/docs/cli-schema.json +1790 -98
  21. package/examples/full-example/docs/cli.md +1990 -0
  22. package/examples/full-example/docs/http.md +28 -29
  23. package/examples/full-example/docs/mcp.md +8 -22
  24. package/examples/full-example/docs/openapi.json +783 -50
  25. package/examples/full-example/docs/skill.md +10 -10
  26. package/examples/full-example/justfile +11 -1
  27. package/examples/full-example/src/commands/render-json/__generated__/RenderJsonInputSchema.json +15 -0
  28. package/examples/full-example/src/commands/render-json/__generated__/index.ts +5 -0
  29. package/examples/full-example/src/commands/render-json/command.test.ts +46 -0
  30. package/examples/full-example/src/commands/render-json/command.ts +30 -0
  31. package/examples/full-example/src/commands/render-json/types.ts +9 -0
  32. package/examples/full-example/src/commands/status/__generated__/StatusJsonOutputSchema.json +15 -0
  33. package/examples/full-example/src/commands/status/__generated__/index.ts +2 -2
  34. package/examples/full-example/src/commands/status/command.ts +5 -13
  35. package/examples/full-example/src/commands/status/types.ts +1 -14
  36. package/examples/full-example/src/commands/workspaces/__generated__/WorkspaceNameInputSchema.json +15 -0
  37. package/examples/full-example/src/commands/workspaces/__generated__/index.ts +5 -0
  38. package/examples/full-example/src/commands/workspaces/command.test.ts +58 -0
  39. package/examples/full-example/src/commands/workspaces/command.ts +94 -0
  40. package/examples/full-example/src/commands/workspaces/types.ts +6 -0
  41. package/examples/full-example/src/db/index.test.ts +86 -0
  42. package/examples/full-example/src/db/index.ts +101 -0
  43. package/examples/full-example/src/db/migrate.test.ts +35 -0
  44. package/examples/full-example/src/db/migrate.ts +69 -0
  45. package/examples/full-example/src/db/migrations/001_workspaces.sql +6 -0
  46. package/examples/full-example/src/db/tables/workspaces.ts +66 -0
  47. package/examples/full-example/src/program.ts +11 -36
  48. package/examples/full-example/src/types/argsbarg.d.ts +11 -0
  49. package/examples/full-example/src/types/md.d.ts +4 -0
  50. package/examples/full-example/tsconfig.json +5 -2
  51. package/examples/mcp-test.ts +1 -2
  52. package/examples/minimal.ts +1 -7
  53. package/examples/nested.ts +1 -2
  54. package/examples/option-required.ts +1 -1
  55. package/examples/servers.ts +4 -5
  56. package/index.d.ts +440 -136
  57. package/package.json +19 -2
  58. package/src/builtins/builtins.test.ts +7 -7
  59. package/src/builtins/completion-bash.ts +1 -1
  60. package/src/builtins/completion-fish.ts +1 -1
  61. package/src/builtins/completion-group.ts +4 -4
  62. package/src/builtins/completion-simulate-shared.ts +9 -0
  63. package/src/builtins/completion-zsh.ts +1 -1
  64. package/src/builtins/config.test.ts +3 -3
  65. package/src/builtins/config.ts +9 -9
  66. package/src/builtins/configure-copy.ts +2 -2
  67. package/src/builtins/configure.ts +4 -4
  68. package/src/builtins/dispatch.ts +19 -18
  69. package/src/builtins/export.ts +7 -5
  70. package/src/builtins/http.ts +68 -0
  71. package/src/builtins/mcp.ts +28 -4
  72. package/src/builtins/presentation.ts +6 -6
  73. package/src/builtins/registry.ts +6 -6
  74. package/src/builtins/scopes.ts +2 -2
  75. package/src/builtins/version.ts +1 -1
  76. package/src/cli-tool/full-example-capabilities.test.ts +10 -15
  77. package/src/cli-tool/main.ts +1 -1
  78. package/src/cli-tool/program.ts +3 -2
  79. package/src/cli-tool/prompt.ts +1 -1
  80. package/src/cli-tool/run-schemagen.ts +1 -3
  81. package/src/cli-tool/schemagen/cleanup.ts +6 -7
  82. package/src/cli-tool/schemagen/discover-schema-roots.ts +66 -120
  83. package/src/cli-tool/schemagen/index.ts +2 -2
  84. package/src/cli-tool/schemagen/names.ts +8 -13
  85. package/src/cli-tool/schemagen/run.ts +21 -28
  86. package/src/cli-tool/schemagen/schemagen.test.ts +136 -46
  87. package/src/config/bindings.test.ts +1 -1
  88. package/src/config/bindings.ts +1 -1
  89. package/src/config/bootstrap.test.ts +1 -1
  90. package/src/config/bootstrap.ts +36 -4
  91. package/src/config/context.test.ts +1 -1
  92. package/src/config/context.ts +1 -1
  93. package/src/config/entry.ts +1 -1
  94. package/src/config/file.test.ts +1 -1
  95. package/src/config/file.ts +3 -3
  96. package/src/config/manifest.ts +1 -1
  97. package/src/config/resolve.test.ts +1 -1
  98. package/src/config/resolve.ts +1 -1
  99. package/src/config/schema.ts +1 -1
  100. package/src/config/validate.ts +1 -1
  101. package/src/{install → configure/artifacts}/binary-placement.test.ts +1 -1
  102. package/src/{install → configure/artifacts}/binary-placement.ts +1 -1
  103. package/src/{install → configure/artifacts}/gh-release-update.ts +1 -1
  104. package/src/{install → configure/artifacts}/install-validate.test.ts +3 -3
  105. package/src/{install → configure/artifacts}/mcp-config.ts +1 -1
  106. package/src/{install → configure/artifacts}/mcp-opencode.test.ts +1 -1
  107. package/src/{install → configure/artifacts}/mcp-opencode.ts +1 -1
  108. package/src/{install → configure/artifacts}/paths.ts +5 -5
  109. package/src/configure/artifacts/plan.ts +24 -0
  110. package/src/{install → configure/artifacts}/status.test.ts +1 -1
  111. package/src/{install → configure/artifacts}/status.ts +2 -2
  112. package/src/{install → configure/artifacts}/target-base.ts +1 -1
  113. package/src/{install → configure/artifacts}/target-detect.ts +1 -1
  114. package/src/{install → configure/artifacts}/target-effective.ts +3 -9
  115. package/src/{install → configure/artifacts}/target-mcp-cli.ts +1 -1
  116. package/src/{install → configure/artifacts}/target-mcp-json.ts +1 -1
  117. package/src/{install → configure/artifacts}/target-plan-build.ts +2 -2
  118. package/src/{install → configure/artifacts}/target-registry.ts +2 -2
  119. package/src/{install → configure/artifacts}/target-scope.ts +3 -3
  120. package/src/{install → configure/artifacts}/target-skill.ts +1 -1
  121. package/src/{install → configure/artifacts}/target-types.ts +2 -2
  122. package/src/{install → configure/artifacts}/targets/app.ts +5 -5
  123. package/src/{install → configure/artifacts}/targets/chatgpt-mcp.ts +2 -2
  124. package/src/{install → configure/artifacts}/targets/claude-code-mcp.ts +2 -2
  125. package/src/{install → configure/artifacts}/targets/claude-desktop-mcp.ts +2 -2
  126. package/src/{install → configure/artifacts}/targets/claude-skill.ts +2 -2
  127. package/src/{install → configure/artifacts}/targets/codex-mcp.ts +2 -2
  128. package/src/{install → configure/artifacts}/targets/codex-skill.ts +2 -2
  129. package/src/{install → configure/artifacts}/targets/configure.ts +5 -5
  130. package/src/{install → configure/artifacts}/targets/cursor-mcp.ts +2 -2
  131. package/src/{install → configure/artifacts}/targets/cursor-skill.ts +2 -2
  132. package/src/{install → configure/artifacts}/targets/index.ts +1 -1
  133. package/src/{install → configure/artifacts}/targets/openclaw-mcp.ts +2 -2
  134. package/src/{install → configure/artifacts}/targets/openclaw-skill.ts +3 -3
  135. package/src/{install → configure/artifacts}/targets/opencode-mcp.ts +5 -5
  136. package/src/{install → configure/artifacts}/targets/opencode-skill.ts +3 -3
  137. package/src/{install → configure/artifacts}/targets.test.ts +1 -1
  138. package/src/{install → configure/artifacts}/uninstall.ts +1 -1
  139. package/src/configure/configure.test.ts +11 -11
  140. package/src/configure/index.ts +14 -14
  141. package/src/configure/prompt.ts +2 -2
  142. package/src/{context.ts → core/context.ts} +26 -20
  143. package/src/core/json-leaf.test.ts +156 -0
  144. package/src/{leaf-inputs.test.ts → core/leaf-inputs.test.ts} +7 -7
  145. package/src/{leaf-inputs.ts → core/leaf-inputs.ts} +76 -16
  146. package/src/{parse.test.ts → core/parse.test.ts} +97 -109
  147. package/src/{parse.ts → core/parse.ts} +173 -25
  148. package/src/{schema.ts → core/schema.ts} +25 -13
  149. package/src/{types.ts → core/types.ts} +238 -35
  150. package/src/{validate.ts → core/validate.ts} +51 -29
  151. package/src/docs/builtin.ts +8 -19
  152. package/src/docs/{api-guide.test.ts → cli-guide.test.ts} +21 -21
  153. package/src/docs/{api-guide.ts → cli-guide.ts} +45 -16
  154. package/src/docs/docs.test.ts +76 -41
  155. package/src/docs/http-guide.ts +37 -34
  156. package/src/docs/mcp-guide.ts +12 -14
  157. package/src/docs/mcp-resources.test.ts +2 -3
  158. package/src/docs/mcp-resources.ts +6 -11
  159. package/src/docs/resolve.ts +22 -30
  160. package/src/docs/save.ts +3 -3
  161. package/src/exports/cli.ts +47 -0
  162. package/src/exports/headless.ts +13 -0
  163. package/src/exports/http.ts +6 -0
  164. package/src/exports/mcp.ts +6 -0
  165. package/src/{headless.test.ts → headless/routing.test.ts} +3 -3
  166. package/src/{headless.ts → headless/routing.ts} +3 -3
  167. package/src/headless/tool-call.ts +114 -46
  168. package/src/help.test.ts +152 -0
  169. package/src/help.ts +54 -18
  170. package/src/hooks/builtin.ts +20 -0
  171. package/src/hooks/run.ts +142 -0
  172. package/src/http/openapi.ts +182 -0
  173. package/src/http/readiness.ts +78 -0
  174. package/src/{api → http}/result.ts +16 -5
  175. package/src/http/routes.ts +329 -0
  176. package/src/http/server.ts +225 -0
  177. package/src/index.ts +38 -25
  178. package/src/log/ecs.test.ts +43 -0
  179. package/src/log/ecs.ts +59 -0
  180. package/src/log/emitter.ts +166 -0
  181. package/src/mcp/bundle.ts +2 -2
  182. package/src/mcp/claude.test.ts +1 -1
  183. package/src/mcp/claude.ts +4 -4
  184. package/src/{hidden-mcpb.test.ts → mcp/hidden-mcpb.test.ts} +10 -9
  185. package/src/mcp/result.ts +2 -2
  186. package/src/mcp/server.ts +54 -6
  187. package/src/mcp/tools.ts +18 -20
  188. package/src/{capabilities.ts → runtime/capabilities.ts} +11 -11
  189. package/src/{cli-errors.ts → runtime/cli-errors.ts} +4 -4
  190. package/src/{cli.ts → runtime/cli.ts} +160 -50
  191. package/src/runtime/exposure.ts +102 -0
  192. package/src/{invoke.test.ts → runtime/invoke.test.ts} +31 -7
  193. package/src/server/context.ts +25 -0
  194. package/src/server/overrides.ts +112 -0
  195. package/src/skill/generate.ts +8 -8
  196. package/src/skill/hint.ts +1 -1
  197. package/src/skill/install.ts +2 -2
  198. package/src/skill/naming.ts +1 -1
  199. package/src/{test-fixtures.ts → test/fixtures.ts} +3 -2
  200. package/src/{config.integration.test.ts → test/integration/config.test.ts} +8 -8
  201. package/src/{api.integration.test.ts → test/integration/http.test.ts} +170 -67
  202. package/src/{mcp.integration.test.ts → test/integration/mcp.test.ts} +11 -57
  203. package/docs/api-server.md +0 -141
  204. package/examples/full-example/docs/api.md +0 -511
  205. package/examples/full-example/src/commands/status/__generated__/outputSchema.json +0 -28
  206. package/examples/full-example/src/config/__generated__/configSchema.json +0 -40
  207. package/examples/full-example/src/config/__generated__/index.ts +0 -5
  208. package/examples/full-example/src/config/types.ts +0 -24
  209. package/src/api/openapi.ts +0 -117
  210. package/src/api/server.ts +0 -120
  211. package/src/builtins/api.ts +0 -38
  212. package/src/hidden.ts +0 -30
  213. package/src/install/plan.ts +0 -53
  214. /package/src/{install → configure/artifacts}/detect-installed.ts +0 -0
  215. /package/src/{install → configure/artifacts}/gh-release-update.test.ts +0 -0
  216. /package/src/{install → configure/artifacts}/mcp-codex.test.ts +0 -0
  217. /package/src/{install → configure/artifacts}/mcp-codex.ts +0 -0
  218. /package/src/{install → configure/artifacts}/mcp-openclaw.test.ts +0 -0
  219. /package/src/{install → configure/artifacts}/mcp-openclaw.ts +0 -0
  220. /package/src/{install → configure/artifacts}/normalize-uninstall.ts +0 -0
  221. /package/src/{install → configure/artifacts}/normalize.ts +0 -0
  222. /package/src/{install → configure/artifacts}/opts.ts +0 -0
  223. /package/src/{install → configure/artifacts}/shell.ts +0 -0
  224. /package/src/{formats.test.ts → core/formats.test.ts} +0 -0
  225. /package/src/{formats.ts → core/formats.ts} +0 -0
  226. /package/src/{respond.ts → core/respond.ts} +0 -0
  227. /package/src/{types.test.ts → core/types.test.ts} +0 -0
  228. /package/src/{api → http}/schema-deref.test.ts +0 -0
  229. /package/src/{api → http}/schema-deref.ts +0 -0
@@ -48,7 +48,7 @@ await cli.run();
48
48
 
49
49
  **`_bindings`** — reserved top-level metadata: `{ "_bindings": { "apiToken": "env" } }`. Set via wizard (Enter to use env), `configure set --from-env`, or `ctx.appConfig.set` (marks `file`). Optional keys can be bound to `skip`.
50
50
 
51
- **Validation at runtime** — argsbarg validates the config file and `configure set` / `ctx.appConfig.set` against the effective JSON Schema. Partial writes (bindings only, single-key updates) skip required-property checks.
51
+ **Validation at runtime** — argsbarg validates the config file and `configure set` / `ctx.appConfig.set` against the effective JSON Schema ([supported subset](json-schema-subset.md)). Partial writes (bindings only, single-key updates) skip required-property checks.
52
52
 
53
53
  See [cli-program.md — Configuration](cli-program.md#configuration-programappconfig) for resolution order, bootstrap timing, and `configure get`/`set`.
54
54
 
@@ -142,44 +142,43 @@ Mirror the [output-schema.md](output-schema.md) pattern for config:
142
142
 
143
143
  ```mermaid
144
144
  flowchart LR
145
- subgraph types [types.ts]
146
- Marker["export type configType = AppConfig"]
145
+ subgraph src [src/config/types.ts]
146
+ Marker["/** @sg */ export interface AppConfig"]
147
147
  end
148
148
  subgraph gen [argsbarg schemagen]
149
149
  Script["argsbarg schemagen"]
150
150
  Gen["ts-json-schema-generator"]
151
151
  end
152
152
  subgraph artifacts [Gitignored __generated__]
153
- Json["configSchema.json"]
153
+ Json["AppConfigSchema.json"]
154
154
  Index["index.ts"]
155
155
  end
156
156
  subgraph runtime [Runtime]
157
157
  Program["program.appConfig.jsonSchema"]
158
158
  Validate["argsbarg runtime subset validator"]
159
159
  end
160
- types --> Script --> Gen --> Json
160
+ src --> Script --> Gen --> Json
161
161
  Gen --> Index --> Program --> Validate
162
162
  ```
163
163
 
164
164
  | Piece | Convention |
165
165
  | --- | --- |
166
166
  | Generator | [`ts-json-schema-generator`](https://github.com/vega/ts-json-schema-generator) (bundled with argsbarg) |
167
- | Discovery | `export type configType = …` in `src/config/types.ts` |
168
- | Artifacts | `src/config/__generated__/` — gitignored; run `just schemagen` after clone |
167
+ | Discovery | `/** @sg */` on `AppConfig` in `src/config/types.ts` (or any scanned `src/**/*.ts`) |
168
+ | Artifacts | `src/config/__generated__/AppConfigSchema.json` — gitignored; run `just schemagen` after clone |
169
169
  | Consumer CI | Optional: `ajv` + `ajv-formats` against the same committed JSON (not an argsbarg runtime dep) |
170
170
 
171
171
  Example:
172
172
 
173
173
  ```typescript
174
174
  // src/config/types.ts
175
+ /** @sg */
175
176
  export interface AppConfig {
176
177
  apiToken: string;
177
178
  }
178
-
179
- export type configType = AppConfig;
180
179
  ```
181
180
 
182
- Wire on the program root: `import { configSchema } from "./config/__generated__/index.ts"`.
181
+ Wire on the program root: `import { AppConfigSchema } from "./config/__generated__"`.
183
182
 
184
183
  ### Supported AppConfig shapes (argsbarg runtime validator)
185
184
 
@@ -222,7 +221,7 @@ Object/array/`$ref` properties require `--json` on `configure set` when comma-se
222
221
 
223
222
  | Example | Role |
224
223
  | --- | --- |
225
- | [`examples/full-example/`](../examples/full-example/) | **Copy template** — `argsbarg schemagen`, `program.appConfig`, built-in `configure get`/`set` |
224
+ | [`examples/full-example/`](../examples/full-example/) | **Copy template** — `@sg` schemagen, builtins; optional `program.appConfig` |
226
225
 
227
226
  ```bash
228
227
  cd examples/full-example && just setup && just schemagen
package/docs/configure.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Configure command
2
2
 
3
+ > This feature is experimental.
4
+
3
5
  The `configure` built-in manages **agent artifacts** (skills, MCP config, app config). The **binary and shell completions** ship via Homebrew — see [distribution-homebrew.md](distribution-homebrew.md).
4
6
 
5
7
  Opt out with `configure: { enabled: false }` on the program root.
@@ -0,0 +1,40 @@
1
+ # Decisions
2
+
3
+ This doc tracks big architectural decisions so that we can avoid re-hashing the same decisions over and over.
4
+
5
+ ## HTTP REST vs flat `/tools/:name`
6
+
7
+ Decision: **nested `/api/...` REST** (7.0)
8
+
9
+ ### Context
10
+
11
+ - v6 exposed tools as `POST /tools/:flat-name` with hyphen-joined paths
12
+ - Nested resources (e.g. `workspaces/{id}`) and verb-specific methods need a route model aligned with the CLI tree
13
+
14
+ ### Rationale
15
+
16
+ 1. Command tree already encodes hierarchy — REST paths mirror `http.segment ?? key` plus `:param` routers
17
+ 2. Verb leaves (`get`, `post`, …) map to HTTP methods without duplicating path segments
18
+ 3. OpenAPI paths match real URLs clients call; query/body binding matches MCP flat args
19
+ 4. Hard break on `/tools/*` is acceptable pre-7.0-ship
20
+
21
+ ## Validation: JSON-SCHEMA vs Zod, etc
22
+
23
+ Decision: JSON-SCHEMA
24
+
25
+ ### Context
26
+ - JSON-SCHEMA is an open standard to capture a schema in json
27
+ - Zod is the leading Typescript schema management library
28
+ - Others are similar or less good than Zod
29
+
30
+ ### Rational
31
+ Zod may actually cause more complexity and little/no gain for consumers.
32
+
33
+ Yes Zod implements some features we do custom for JSON-SCHEMA, but is opinionated, less flexible, and would actually explode complexity in some situations. Zod could be a win for consumers if they require substantial, complex validation -- but then that may not convert well to json-schema anyways and json-schema generation is a big win.
34
+
35
+ 1. Argsbarg does a lot of schema patching/manipulation to create different schemas per target (cli-schema.json, MCP contract, openapi.json). This would be harder with Zod
36
+ 2. Consumers can already use zod if they want by using Zod's to-json-schema features to convert when passing to Argsbarg. So we aren't actually alienating / thwarting consumers from using Zod anyways.
37
+ 3. For uses like API pass-through, proxy, dynamic schemas, Zod may actually explode complexity for consumers.
38
+ 4. Our TS->json-schema approach is actually easier and better in many cases
39
+ - Just write plain typescript, done.
40
+ - Better intellisense -- substantially less abstraction/inference, much better control
@@ -32,14 +32,28 @@ Sibling consumer repos (machine-specific paths in the root `justfile` `consumer_
32
32
 
33
33
  | Recipe | When | Effect |
34
34
  | --- | --- | --- |
35
- | `just consumers-dev` | Before publish; hacking on argsbarg locally | `bun add argsbarg@file:<relative>`; refresh `.cursor/rules/cli-program.mdc` from template (keeps app-specific suffix) |
36
- | `just consumers-sync` | After release | Sets `"argsbarg": "^<this package.json version>"`, `bun install`, merge **argsbarg Cursor rule**, `just build`, `just docgen`, `just install-local` (Homebrew dev formula + agent artifacts; `just install` is an alias) |
35
+ | `just consumers-dev` | Before publish; hacking on argsbarg locally | `bun add argsbarg@file:<relative>`; refresh `.cursor/rules/cli-program.mdc` and `code.mdc` from template (keeps app-specific suffix) |
36
+ | `just consumers-sync` | After release | Sets `"argsbarg": "^<this package.json version>"`, `bun install`, merge **cli-program** + **code** Cursor rules, `just build`, `just docgen`, `just install-local` (Homebrew dev formula + agent artifacts; `just install` is an alias) |
37
+ | `just consumers-schemagen` | After `@sg` type changes in consumers | Runs `argsbarg schemagen` in each `consumer_apps` path (fails if missing) |
37
38
 
38
39
  `consumers-sync` reads the version from **this repo’s** `package.json` — not npm. Run it **after** `just release` so consumers pin a version that exists on the registry.
39
40
 
40
- **Argsbarg authoring rule** — `scripts/merge-cli-program-rule.ts` copies `examples/full-example/.cursor/rules/cli-program.mdc` into each consumer’s `.cursor/rules/cli-program.mdc`, preserving any existing `**… conventions:**` footer block.
41
+ **Argsbarg authoring rules** — `scripts/merge-cli-program-rule.ts` and `scripts/merge-code-rule.ts` copy templates from `examples/full-example/.cursor/rules/` into each consumer, preserving any existing `**… conventions:**` footer block.
41
42
 
42
- **Recommended in each consumer:** replace the template placeholder with `**<app> conventions:**` bullets (paths to `read*Flags`, shared flags, Ink vs JSON-only). Commit that file; merges refresh the shared top, not your footer.
43
+ **Recommended in each consumer:** replace template placeholders with `**<app> conventions:**` bullets. Commit those files; merges refresh the shared top, not your footer.
44
+
45
+ ## Upgrading consumer apps to 7.0
46
+
47
+ Breaking changes (no backward compat). See [CHANGELOG.md](../CHANGELOG.md) `[Unreleased]`.
48
+
49
+ 1. **Schemagen:** replace `export type configType|inputType|outputType` with `/** @sg */` immediately above `export interface` / `export type` (no blank line).
50
+ 2. **Imports:** `configSchema` → `{AppConfig}Schema` (type name + `Schema`); same for leaf `inputSchema` / `outputSchema` imports (`StatusJsonOutputSchema`, etc.).
51
+ 3. **Run** `argsbarg schemagen` (or `just schemagen`) after every type change.
52
+ 4. **HTTP:** use `/api/...` REST routes only (`POST /tools/*` removed).
53
+ 5. **Hooks:** remove manual `ctx.locals.requestId` in `beforeInvoke` — framework seeds it.
54
+ 6. **Exports:** stop importing `loadLeafInputs` / `CliHttpResponseConfig` from `argsbarg` (use `ctx.inputs`, leaf `http.successContentType`).
55
+ 7. **Cursor rules:** `just consumers-dev` merges `cli-program.mdc` + `code.mdc` (includes **Abstractions** needless-extraction rule).
56
+ 8. **Verify:** `just test` and `just docgen` in each consumer repo.
43
57
 
44
58
  **Consumer app skill** — `just install-local` in each consumer (part of `consumers-sync`) runs Homebrew dev install then `myapp configure --sync --yes`, which updates `~/.cursor/skills/<app>/` from that app’s schema — not the argsbarg framework rule.
45
59
 
@@ -60,7 +74,31 @@ just full-example-schemagen
60
74
  just test
61
75
  ```
62
76
 
63
- See [`.cursor/rules/examples.mdc`](../.cursor/rules/examples.mdc) for maintainer guidance.
77
+ See [docs/README.md](README.md) for the full documentation map.
78
+
79
+ ## Advanced imports
80
+
81
+ Subpath exports (root barrel still re-exports everything):
82
+
83
+ ```typescript
84
+ import { Cli, type CliProgram } from "argsbarg/cli";
85
+ import { generateOpenApi, httpServeHttp } from "argsbarg/http";
86
+ import { packMcpBundle } from "argsbarg/mcp"; // @experimental
87
+ import { shouldRunHeadless } from "argsbarg/headless";
88
+ import { runSchemagen } from "argsbarg/schemagen";
89
+ ```
90
+
91
+ ## Module boundaries
92
+
93
+ | Layer | Role |
94
+ | --- | --- |
95
+ | `schema.ts`, `parse.ts`, `context.ts` | Transport-agnostic CLI core |
96
+ | `http/` | HTTP tool server (`httpServer` capability) |
97
+ | `mcp/` | MCP stdio server and bundle (`mcpServer` capability) |
98
+ | `configure/artifacts/` | Agent artifact sync (`configure` capability) |
99
+ | `docs/` | Built-in documentation generators |
100
+
101
+ Capabilities are declared on `CliProgram`; builtins wire them in [`src/builtins/`](../src/builtins/).
64
102
 
65
103
  ## Docs
66
104
 
@@ -0,0 +1,171 @@
1
+ # HTTP API server
2
+
3
+ ArgsBarg can expose your CLI as an HTTP REST server. Each **leaf command** becomes a route under `/api/...` — nested command paths, HTTP verbs, and `:param` routers are reflected in the URL. The server uses Bun's built-in HTTP stack and binds to **localhost by default**.
4
+
5
+ The HTTP API is **opt-in**. Apps that do not set `httpServer` on the program root behave exactly as before.
6
+
7
+ ## Quick start
8
+
9
+ 1. Add `httpServer` to your program root:
10
+
11
+ ```typescript
12
+ import pkg from "../package.json" with { type: "json" };
13
+
14
+ const cli = {
15
+ key: "myapp",
16
+ version: pkg.version,
17
+ description: "My app.",
18
+ httpServer: { enabled: true },
19
+ commands: [/* ... */],
20
+ } satisfies CliProgram;
21
+ ```
22
+
23
+ `httpServer: { enabled: true }` opts in. Omit `httpServer` entirely to disable HTTP. Empty `httpServer: {}` is rejected at validation.
24
+
25
+ 2. Run the HTTP server:
26
+
27
+ ```bash
28
+ myapp http
29
+ ```
30
+
31
+ The process listens until interrupted. Startup prints the listen URL to stderr.
32
+
33
+ Optional flags on `myapp http` (and `myapp http serve`): `--host`, `--port`, `--trust-proxy`, `--obscure-errors`, `--log-format`, `--log-file`, `--no-access-log`, `--dev`.
34
+
35
+ ## Configuration
36
+
37
+ Set `httpServer` on the **program root only**. Validation rejects `httpServer` on nested nodes.
38
+
39
+ | Field | Default | Purpose |
40
+ | --- | --- | --- |
41
+ | `enabled` | *(required)* | Must be `true` when `httpServer` is set |
42
+ | `host` | `127.0.0.1` | Listen address |
43
+ | `port` | `3000` | Listen port |
44
+ | `trustProxy` | `false` | Honor `X-Forwarded-For` in hooks and access logs |
45
+ | `errors.errorSchema` | `{ error: string }` | OpenAPI + default error body shape |
46
+ | `errors.obscureUnexpected` | `false` | Client sees generic message on 500; ECS logs real stack |
47
+ | `hooks` | — | Observe-only wire hooks (`onRequest`, `onResponse`, `onError`) |
48
+
49
+ `httpServer` and `mcpServer` are independent — enable either or both.
50
+
51
+ Program-level `program.log` controls ECS JSON vs human text on stderr (and optional file tee). See [docs/decisions.md](decisions.md).
52
+
53
+ ## REST routes
54
+
55
+ Routes are derived from the command tree:
56
+
57
+ | CLI path | HTTP | Notes |
58
+ | --- | --- | --- |
59
+ | `workspaces get` | `GET /api/workspaces` | Verb leaf (`get`) omitted from URL |
60
+ | `workspaces post` | `POST /api/workspaces` | Default POST success **201** |
61
+ | `workspaces :id get` | `GET /api/workspaces/{id}` | `:id` param router |
62
+ | `stat owner lookup` | `POST /api/stat/owner/lookup` | Default method POST when key is not a verb |
63
+
64
+ Method precedence: `leaf.http.method` → verb key (`get`/`post`/…) → **POST**.
65
+
66
+ Query string binds to options (values starting with `{` or `[` are JSON-parsed). Body on POST/PUT/PATCH binds to options, positionals, and `inputSchema` fields.
67
+
68
+ Per-surface exposure: `http.enabled: false` removes a leaf from the route table; `http.hidden: true` keeps it callable but omits it from OpenAPI.
69
+
70
+ ## Endpoints
71
+
72
+ | Method | Path | Purpose |
73
+ | --- | --- | --- |
74
+ | `GET` | `/health` or `/health/live` | Liveness — 200 when server is listening |
75
+ | `GET` | `/health/ready` | Readiness — config + optional `program.readiness` |
76
+ | `GET` | `/openapi.json` | OpenAPI 3.1 REST paths |
77
+ | `GET` | `/openapi-browser` | Interactive Scalar API reference (CDN) |
78
+ | `*` | `/api/...` | Invoke user commands (method per route) |
79
+ | `OPTIONS` | `*` | CORS preflight (`GET, POST, PUT, PATCH, DELETE`) |
80
+
81
+ `POST /tools/*` was removed in 7.0 — use `/api/*` only.
82
+
83
+ ## Examples
84
+
85
+ ```bash
86
+ curl -s http://127.0.0.1:3000/health
87
+ curl -s http://127.0.0.1:3000/health/ready
88
+ curl -s http://127.0.0.1:3000/openapi.json
89
+ open http://127.0.0.1:3000/openapi-browser
90
+ curl -s http://127.0.0.1:3000/api/workspaces
91
+ curl -s -X POST http://127.0.0.1:3000/api/workspaces \
92
+ -H 'content-type: application/json' \
93
+ -d '{"name":"qa2"}'
94
+ curl -s http://127.0.0.1:3000/api/workspaces/{id}
95
+ ```
96
+
97
+ Discover paths and request shapes from `openapi.json` or `myapp docs openapi`.
98
+
99
+ ## Handler responses (`ctx.respond()`)
100
+
101
+ API and MCP tool handlers must return machine-readable output via **`ctx.respond()`** or by **returning a value** (implicit JSON). `console.log` is not included in HTTP/MCP success payloads.
102
+
103
+ ```typescript
104
+ handler: (ctx) => {
105
+ if (ctx.hasFlag("json")) {
106
+ return { user: "alice", path: "/tmp" };
107
+ }
108
+ ctx.respond({
109
+ body: pdfBytes,
110
+ contentType: "application/pdf",
111
+ headers: { "Content-Disposition": 'inline; filename="invoice.pdf"' },
112
+ });
113
+ },
114
+ ```
115
+
116
+ **CLI mode:** `ctx.respond()` prints to stdout. Handlers may still use `console.log` for human-only CLI output.
117
+
118
+ ### Leaf HTTP metadata
119
+
120
+ ```typescript
121
+ http?: {
122
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
123
+ segment?: string; // URL segment override
124
+ successStatus?: number;
125
+ successContentType?: string; // OpenAPI + default Content-Type
126
+ contentDisposition?: string;
127
+ };
128
+ ```
129
+
130
+ ## Responses
131
+
132
+ **Success:** status from `ctx.respond({ status })` → `http.successStatus` → method default (GET 200, POST 201, DELETE 204 without body).
133
+
134
+ | Body type | HTTP `Content-Type` |
135
+ | --- | --- |
136
+ | object / array | `application/json` |
137
+ | string | handler `contentType` or `text/plain` |
138
+ | `Uint8Array` | e.g. `application/pdf` (set explicitly) |
139
+
140
+ **Errors:** JSON `{ "error": "..." }` by default (override with `httpServer.errors.errorSchema`).
141
+
142
+ | Situation | Status |
143
+ | --- | --- |
144
+ | Validation / help | 400 |
145
+ | Unknown route | 404 |
146
+ | Thrown handler / missing `ctx.respond()` | 500 |
147
+ | Missing required config | 503 |
148
+
149
+ Tool invocations are **not** gated on `/health/ready`; readiness is for orchestrators only.
150
+
151
+ ## Hooks and runtime
152
+
153
+ `program.hooks` (`beforeInvoke`, `afterInvoke`, `formatError`, `onError`) run for user commands on CLI, HTTP, and MCP — **not** for builtins.
154
+
155
+ - `ctx.locals` — per-request bag (fresh each invoke); framework sets `requestId` before `beforeInvoke` (HTTP/MCP wire id when present, else a new UUID)
156
+ - `ctx.runtime` — shared `ServerRuntime.state` on HTTP/MCP server sessions
157
+ - `ctx.pathParams` — values from `:param` routers
158
+
159
+ Error order: `formatError` → `onError` → ECS log → client response.
160
+
161
+ ## CORS
162
+
163
+ All responses include wide-open CORS headers (`Access-Control-Allow-Origin: *`). Not configurable in v1.
164
+
165
+ ## OpenAPI
166
+
167
+ Call `generateOpenApi(program)` from `argsbarg/http`, fetch `GET /openapi.json`, or run `myapp docs openapi --save`. Nested `$ref` in input/output schemas are dereferenced in the spec.
168
+
169
+ ## Complex tool inputs
170
+
171
+ Set `inputSchema` on the leaf and read coerced values with `ctx.inputs` / `ctx.inputsAs<T>()`. HTTP query, body, and path params merge into inputs before validation.
@@ -0,0 +1,51 @@
1
+ # JSON Schema subset
2
+
3
+ Argsbarg validates `program.appConfig`, leaf `inputSchema`, and related documents with a **custom Draft-07 subset** in [`src/config/validate.ts`](../src/config/validate.ts). There is no runtime dependency on a full JSON Schema validator.
4
+
5
+ Use this page when authoring schemas for config files, `inputSchema` on leaves, or `@sg` schemagen output.
6
+
7
+ ## Supported constructs
8
+
9
+ | Feature | Notes |
10
+ | --- | --- |
11
+ | `type` | `object`, `array`, `string`, `integer`, `number`, `boolean`, `null` |
12
+ | `properties` / `required` | Object keys; `additionalProperties: false` enforced when set |
13
+ | `items` | Homogeneous arrays; comma-separated CLI strings coerced when `items` is a primitive |
14
+ | `enum` / `const` | Exact value checks |
15
+ | `anyOf` / `oneOf` | First matching branch wins; errors surface when none match |
16
+ | `$ref` | **Local only** — `#/definitions/Name` resolved within the same root document |
17
+ | `definitions` | Companion to local `$ref` |
18
+ | `format` | `date`, `date-time`, `duration`, `comma-list` (and related string coercions) |
19
+ | `minimum` / `maximum` | Numbers and integers |
20
+ | `minLength` / `maxLength` | Strings |
21
+ | `pattern` | String regex (ECMAScript) |
22
+
23
+ ## Partial validation
24
+
25
+ `validateConfigDocumentPartial` validates **present keys only** — root `required` is skipped. Used for `configure set` partial writes and bootstrap flows.
26
+
27
+ Leaf `inputSchema` validation uses full validation (including `required`) before the handler runs.
28
+
29
+ ## Not supported (today)
30
+
31
+ - Remote `$ref` (`http://…`, other files)
32
+ - `allOf`, conditional (`if`/`then`/`else`), `not`
33
+ - Unevaluated / dynamic references
34
+ - `default` application at validation time (defaults come from CLI option `default` or config bindings)
35
+
36
+ If schemagen emits an unsupported keyword, simplify the TypeScript type or post-process the generated JSON Schema.
37
+
38
+ ## Where validation runs
39
+
40
+ | Surface | Validator | When |
41
+ | --- | --- | --- |
42
+ | App config file | `validateConfigDocument` / `Partial` | `configure set`, config load |
43
+ | Leaf `inputSchema` | Same engine via leaf-inputs | Before handler (MCP/HTTP/CLI merged inputs) |
44
+ | `outputSchema` | Structural checks at program validate time | Startup / `cliValidateProgram` |
45
+
46
+ ## Related docs
47
+
48
+ - [cli-program.md](cli-program.md) — `inputSchema`, JSON leaves, `ctx.inputs` / `ctx.inputsAs`
49
+ - [config-schema.md](config-schema.md) — `program.appConfig` and schemagen pipeline
50
+
51
+ Implementation: [`src/config/validate.ts`](../src/config/validate.ts), [`src/core/leaf-inputs.ts`](../src/core/leaf-inputs.ts).
package/docs/mcp.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # MCP server
2
2
 
3
+ > This feature is experimental.
4
+
3
5
  ArgsBarg can expose your CLI to AI agents through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/). Each **leaf command** becomes an MCP tool; the full command tree is available as a schema resource. The server speaks JSON-RPC over stdio — one JSON object per line on stdin and stdout.
4
6
 
5
7
  MCP is **opt-in**. Apps that do not set `mcpServer` on the program root behave exactly as before.
@@ -246,7 +248,7 @@ The built-in schema resource (default URI `<sanitized-key>://schema`, e.g. `nest
246
248
 
247
249
  ### Auto docs topic resources
248
250
 
249
- When both **`docs.enabled`** and **`mcpServer.enabled`** are true, each user key in **`docs.topics`** is also exposed as an MCP resource:
251
+ When docs is enabled (default) and **`mcpServer.enabled`** is true, each user key in **`docs.topics`** is also exposed as an MCP resource:
250
252
 
251
253
  | Property | Value |
252
254
  | --- | --- |
@@ -419,7 +421,7 @@ Bare **`myapp mcp`** still runs the stdio MCP server (unchanged for `configure`
419
421
 
420
422
  ## Hidden commands and options
421
423
 
422
- Set **`hidden: true`** on a command or option to omit it from help listings, `docs cli-schema` / `docs api`, shell completions, and MCP `tools/list` / tool `inputSchema`. Hidden commands remain invocable; **`myapp hidden-cmd -h`** still works.
424
+ Set **`hidden: true`** on a command or option to omit it from help listings, `docs cli-schema` / `docs cli`, shell completions, and MCP `tools/list` / tool `inputSchema`. Hidden commands remain invocable; **`myapp hidden-cmd -h`** still works.
423
425
 
424
426
  ## Reserved names
425
427