argsbarg 6.1.2 → 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 +65 -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 +52 -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 +431 -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/{json-leaf.test.ts → core/json-leaf.test.ts} +4 -4
  144. package/src/{leaf-inputs.test.ts → core/leaf-inputs.test.ts} +7 -7
  145. package/src/{leaf-inputs.ts → core/leaf-inputs.ts} +16 -12
  146. package/src/{parse.test.ts → core/parse.test.ts} +97 -109
  147. package/src/{parse.ts → core/parse.ts} +129 -31
  148. package/src/{schema.ts → core/schema.ts} +25 -13
  149. package/src/{types.ts → core/types.ts} +225 -35
  150. package/src/{validate.ts → core/validate.ts} +39 -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 +3 -3
  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 +36 -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 +9 -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} +159 -49
  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
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
 
@@ -7,12 +7,12 @@ How to describe JSON stdout on leaf commands — and the **argsbarg schemagen**
7
7
  On **leaf commands**, set `outputSchema` to a JSON Schema object when the handler emits JSON (typically with `--json`, always for JSON-only commands, or on the MCP headless path).
8
8
 
9
9
  ```typescript
10
- import { outputSchema } from "./__generated__/index.ts";
10
+ import { StatusJsonOutputSchema } from "./__generated__";
11
11
 
12
12
  export const status = {
13
13
  key: "status",
14
14
  description: "Show environment status.",
15
- outputSchema,
15
+ outputSchema: StatusJsonOutputSchema,
16
16
  handler: async (ctx) => { /* writes JSON to stdout */ },
17
17
  } satisfies CliLeaf;
18
18
  ```
@@ -20,14 +20,14 @@ export const status = {
20
20
  | Where argsbarg uses it | Purpose |
21
21
  | --- | --- |
22
22
  | `myapp docs cli-schema` | Full command tree JSON export |
23
- | `myapp docs api` | Markdown per-command **Output** section |
23
+ | `myapp docs cli` | 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
26
  | HTTP `GET /openapi.json` | Response schema per tool |
27
27
 
28
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.
29
29
 
30
- **Set on the leaf only** — not under `mcpTool` (legacy `mcpTool.outputSchema` still resolves but is deprecated).
30
+ **Set on the leaf only** — not under `mcpTool`.
31
31
 
32
32
  **Draft version** — argsbarg accepts any JSON Schema object (`type`, `properties`, `definitions`, etc.). Generators may emit draft-07 or draft 2020-12; docgen embeds the object as-is.
33
33
 
@@ -38,7 +38,7 @@ See [cli-program.md — Structured stdout](cli-program.md#structured-stdout) for
38
38
  | Approach | When |
39
39
  | --- | --- |
40
40
  | **Inline object** on the leaf | One-off commands, spikes, very small shapes |
41
- | **Codegen from TypeScript** | Multiple commands share a shape, nested objects, or you want rich `description` fields in `docs api` / skills |
41
+ | **Codegen from TypeScript** | Multiple commands share a shape, nested objects, or you want rich `description` fields in `docs cli` / skills |
42
42
 
43
43
  Production CLIs with several JSON commands tend to use **codegen** so types, handlers, and schemas stay aligned.
44
44
 
@@ -50,137 +50,129 @@ Reference implementations: **sqsp-qa-manager-poc**, **sqsp-workspaces**, **sqsp-
50
50
 
51
51
  ```mermaid
52
52
  flowchart LR
53
- subgraph types [types.ts]
54
- Config["export type configType = AppConfig"]
55
- Output["export type outputType = StatusJsonOutput"]
56
- Input["export type inputType = ToolInput (optional)"]
53
+ subgraph src [src/**/*.ts]
54
+ Sg["/** @sg */ export interface TypeName"]
57
55
  end
58
56
  subgraph gen [argsbarg schemagen]
59
- Discover["discover types.ts roots"]
57
+ Walk["walk src/ minus tests and __generated__"]
60
58
  Gen["ts-json-schema-generator"]
61
59
  end
62
60
  subgraph artifacts [Gitignored __generated__]
63
- Json["configSchema.json / inputSchema.json / outputSchema.json"]
61
+ Json["TypeNameSchema.json"]
64
62
  Index["index.ts re-exports"]
65
63
  end
66
64
  subgraph runtime [Runtime]
67
- Leaves["import { outputSchema } from ./__generated__/index.ts"]
65
+ Leaves["import { TypeNameSchema } from ./__generated__"]
68
66
  Docgen["just docgen"]
69
67
  end
70
- types --> Discover --> Gen --> Json
68
+ src --> Walk --> Gen --> Json
71
69
  Gen --> Index --> Leaves --> Docgen
72
70
  ```
73
71
 
74
72
  | Piece | Convention |
75
73
  | --- | --- |
76
74
  | Generator | [`ts-json-schema-generator`](https://github.com/vega/ts-json-schema-generator) (bundled as an argsbarg dependency) |
77
- | Discovery | Walk `src/**/types.ts` for `export type outputType` / `inputType` / `configType`; generate from the aliased type in the same file |
78
- | Artifacts | `src/**/__generated__/` — gitignored; run schemagen after clone or when `types.ts` changes |
75
+ | Discovery | Walk `src/**/*.ts` (exclude `*.test.ts`, `__generated__/`); find `/** @sg */` JSDoc immediately followed by `export interface` or `export type` |
76
+ | Artifacts | One `__generated__/` per source directory; `{TypeName}Schema.json` + `export const {TypeName}Schema` in `index.ts` |
79
77
  | Invocation | `just schemagen` — justfile exports `node_modules/.bin` on `PATH` for local `argsbarg` |
80
78
  | tsconfig | `"resolveJsonModule": true` |
81
79
  | CI | `just check`: `schemagen` → typecheck (no git diff on generated files) |
82
- | Cleanup | Schemagen removes orphan `__generated__/` dirs and stale JSON when roots or kinds are removed |
83
- | Docgen | `docgen` depends on `schemagen` so saved `./docs/api.md` and `./docs/cli-schema.json` are fresh |
80
+ | Cleanup | Schemagen removes orphan `__generated__/` dirs and stale JSON when roots are removed |
81
+ | Docgen | `docgen` depends on `schemagen` so saved `./docs/cli.md` and `./docs/cli-schema.json` are fresh |
84
82
 
85
83
  ### Declaring a schema root
86
84
 
87
- Put schema-facing interfaces and role exports in **`types.ts`** (or `core/types.ts` for shared shapes):
85
+ Mark any exported interface or type with `/** @sg */` on the line immediately above the declaration (no blank line):
88
86
 
89
87
  ```typescript
90
88
  // src/commands/status/types.ts
91
- /** JSON stdout for `myapp status --json`. */
89
+ /** @sg */
92
90
  export interface StatusJsonOutput {
93
- workspaces: WorkspaceStatus[];
91
+ version: string;
94
92
  }
93
+ ```
94
+
95
+ Handlers import types from the same module; leaves import schemas from `./__generated__`:
95
96
 
96
- /** Schemagen root for leaf outputSchema. */
97
- export type outputType = StatusJsonOutput;
97
+ ```typescript
98
+ import { StatusJsonOutputSchema } from "./__generated__";
98
99
  ```
99
100
 
100
- Handlers and other modules import from the same **`types.ts`** module.
101
+ Shared shapes in one directory share one `__generated__/index.ts`:
101
102
 
102
103
  ```typescript
103
- // src/ui/runHeadless/types.ts — shared by many mutating commands
104
+ // src/ui/runHeadless/types.ts
105
+ /** @sg */
104
106
  export interface HeadlessOpResult {
105
107
  command: string;
106
108
  exitCode: number;
107
109
  tasks: HeadlessTaskResult[];
108
110
  }
109
-
110
- export type outputType = HeadlessOpResult;
111
111
  ```
112
112
 
113
113
  ```typescript
114
- // src/commands/render-invoice/types.ts — custom HTTP/MCP body (pdf-gen)
114
+ // src/commands/render-invoice/types.ts
115
+ /** @sg */
115
116
  export interface RenderInvoiceInput {
116
117
  format: "pdf" | "html";
117
118
  invoice: InvoiceData;
118
119
  }
119
120
 
121
+ /** @sg */
120
122
  export interface RenderInvoiceOutput {
121
123
  bytes: number;
122
124
  }
123
-
124
- export type inputType = RenderInvoiceInput;
125
- export type outputType = RenderInvoiceOutput;
126
125
  ```
127
126
 
128
- | Export | Role |
129
- | --- | --- |
130
- | `export type configType = AppConfig` | `program.appConfig.jsonSchema` (one per repo, typically `src/config/types.ts`) |
131
- | `export type outputType = …` | `leaf.outputSchema` |
132
- | `export type inputType = …` | `leaf.inputSchema` (only when the tool body is not flat CLI flags) |
127
+ Wire on the leaf or `program.appConfig`:
133
128
 
134
- **Domain helpers** and **role exports** live in `types.ts`. Commands without structured JSON omit role exports. Shared shapes (e.g. `HeadlessOpResult`) are defined once in `types.ts` with a single `outputType`; other commands import `{ outputSchema }` from that module’s `__generated__/index.ts`.
129
+ | Generated export | Typical use |
130
+ | --- | --- |
131
+ | `AppConfigSchema` | `program.appConfig.jsonSchema` (optional — `src/config/types.ts`) |
132
+ | `StatusJsonOutputSchema` | `leaf.outputSchema` |
133
+ | `RenderInvoiceInputSchema` | `leaf.inputSchema` |
135
134
 
136
- For nested MCP/HTTP bodies, add a `kind: Json` option (same name as the `inputType` property) and use `ctx.jsonOpt(...)` or `ctx.readLeafInputs()` — see [cli-program.md](cli-program.md#json-options-and-piped-stdin).
135
+ For nested MCP/HTTP bodies, add a `kind: Json` option (same name as the schema property) and use `ctx.jsonOpt(...)`, `ctx.inputs`, or `ctx.inputsAs<T>()` — see [cli-program.md](cli-program.md#json-options-and-piped-stdin).
137
136
 
138
137
  When you do **not** set `inputSchema`, argsbarg builds tool input from CLI `options` + `positionals`.
139
138
 
140
139
  ### Generated artifacts
141
140
 
142
- Schemagen writes under `__generated__/` beside each `types.ts` with role exports:
141
+ Schemagen writes under `__generated__/` beside the `@sg` source files in each directory:
143
142
 
144
- | Kind | Generated file | Exported const (from `__generated__/index.ts`) |
143
+ | Type name | Generated file | Exported const |
145
144
  | --- | --- | --- |
146
- | config | `configSchema.json` | `configSchema` |
147
- | output | `outputSchema.json` | `outputSchema` |
148
- | input | `inputSchema.json` | `inputSchema` |
145
+ | `StatusJsonOutput` | `StatusJsonOutputSchema.json` | `StatusJsonOutputSchema` |
146
+ | `RenderInvoiceInput` | `RenderInvoiceInputSchema.json` | `RenderInvoiceInputSchema` |
149
147
 
150
148
  Wire on the leaf:
151
149
 
152
150
  ```typescript
153
- import { outputSchema } from "./__generated__/index.ts";
151
+ import { StatusJsonOutputSchema } from "./__generated__";
154
152
 
155
153
  export const statusCommand = {
156
- outputSchema,
154
+ outputSchema: StatusJsonOutputSchema,
157
155
  // …
158
156
  } satisfies CliLeaf;
159
157
  ```
160
158
 
161
- Shared mutators:
162
-
163
- ```typescript
164
- import { outputSchema } from "../../../ui/runHeadless/__generated__/index.ts";
165
- ```
166
-
167
- App config:
159
+ App config (when used):
168
160
 
169
161
  ```typescript
170
- import { configSchema } from "./config/__generated__/index.ts";
162
+ import { AppConfigSchema } from "./config/__generated__";
171
163
 
172
- appConfig: { jsonSchema: configSchema, entries: { … } },
164
+ appConfig: { jsonSchema: AppConfigSchema, entries: { … } },
173
165
  ```
174
166
 
175
167
  ## Schema-facing types
176
168
 
177
- **Goal:** generated schemas match what handlers actually print, with descriptions agents can read in `docs api`.
169
+ **Goal:** generated schemas match what handlers actually print, with descriptions agents can read in `docs cli`.
178
170
 
179
- 1. **Schema roots** — `export interface` in `types.ts`, with `export type outputType = …` (or `inputType` / `configType`).
171
+ 1. **Schema roots** — `/** @sg */` immediately above `export interface` or `export type`, with per-field JSDoc.
180
172
  2. **Per property** — `/** … */` on every field that should appear in JSON Schema `properties` (including nested named types).
181
173
  3. **Unions / enums** — document the alias; generator emits `enum` / `anyOf` with type-level description.
182
174
  4. **Formats** — property JSDoc can include `@format date-time` for ISO timestamps; add a smoke test that the generated property has `format: "date-time"`.
183
- 5. **Do not hand-edit** `__generated__/` — change types/JSDoc in `types.ts`, run `just schemagen`.
175
+ 5. **Do not hand-edit** `__generated__/` — change types/JSDoc in source files, run `just schemagen`.
184
176
 
185
177
  ### Narrowing when runtime ≠ stdout
186
178
 
@@ -193,7 +185,8 @@ export interface TranslationReadinessResult {
193
185
  evaluatedAt: string;
194
186
  }
195
187
 
196
- export type outputType = TranslationReadinessResult;
188
+ /** @sg */
189
+ export interface TranslationReadinessResult {
197
190
  ```
198
191
 
199
192
  Patterns:
@@ -213,15 +206,15 @@ Per consumer repo (optional):
213
206
 
214
207
  ## Contributor workflow
215
208
 
216
- 1. Add or edit schema roots in `src/**/types.ts` with `outputType` / `inputType` / `configType` and per-field JSDoc.
209
+ 1. Add or edit `/** @sg */` roots in `src/**/*.ts` with per-field JSDoc.
217
210
  2. `just schemagen` — refresh `src/**/__generated__/`.
218
- 3. Import `{ outputSchema }` / `{ inputSchema }` / `{ configSchema }` from the relevant `__generated__/index.ts`.
219
- 4. `just docgen` / `myapp docs api --save` — refresh consumer docs.
211
+ 3. Import `{ TypeNameSchema }` from the relevant `./__generated__` barrel.
212
+ 4. `just docgen` / `myapp docs cli --save` — refresh consumer docs.
220
213
  5. Document which commands use which roots in **your** `docs/architecture.md` (argsbarg does not maintain per-app tables).
221
214
 
222
215
  Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/cli-program.mdc` pointing at `node_modules/argsbarg/docs/output-schema.md`.
223
216
 
224
- **Reference implementation:** [`examples/full-example/`](../examples/full-example/) in this repo — `types.ts` roots, `__generated__/`, and `status` leaf with `outputSchema`.
217
+ **Reference implementation:** [`examples/full-example/`](../examples/full-example/) in this repo — `@sg` on command types, `__generated__/`, and `status` leaf with `StatusJsonOutputSchema`.
225
218
 
226
219
  ## Out of scope
227
220
 
@@ -233,5 +226,5 @@ Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/c
233
226
  - [config-schema.md](config-schema.md) — `configType` / `program.appConfig`
234
227
  - [cli-program.md](cli-program.md) — structured stdout, headless JSON, `read*Flags`
235
228
  - [mcp.md](mcp.md) — `tools/list`, `structuredContent`
236
- - [bundled-docs.md](bundled-docs.md) — `docs api` / `docs cli-schema` docgen
229
+ - [bundled-docs.md](bundled-docs.md) — `docs cli` / `docs cli-schema` docgen
237
230
  - [docs/README.md](README.md) — documentation map