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
@@ -5,19 +5,18 @@ Domain-specific regression tests (split from index.test.ts).
5
5
  import { expect, test } from "bun:test";
6
6
  import { join } from "node:path";
7
7
  import { $ } from "bun";
8
- import type { CliProgram } from "./index.ts";
9
- import { buildToolCallSuccessFromResponse } from "./mcp/result.ts";
8
+ import { cliSchemaExport } from "~/core/schema.ts";
9
+ import { cliValidateProgram } from "~/core/validate.ts";
10
+ import type { CliProgram } from "~/index";
11
+ import { buildToolCallSuccessFromResponse } from "~/mcp/result.ts";
10
12
  import {
11
- apiToolName,
12
13
  collectMcpTools,
13
14
  mcpToolCallToArgv,
14
15
  mcpToolDescription,
15
16
  mcpToolName,
16
17
  sanitizeToolSegment,
17
- } from "./mcp/tools.ts";
18
- import { cliSchemaExport } from "./schema.ts";
19
- import { mcpRequest, nestedMcpFixture, testProgram } from "./test-fixtures.ts";
20
- import { cliValidateProgram } from "./validate.ts";
18
+ } from "~/mcp/tools.ts";
19
+ import { mcpRequest, nestedMcpFixture, testProgram } from "~/test/fixtures.ts";
21
20
 
22
21
  test("sanitizeToolSegment normalizes dotted app keys", () => {
23
22
  expect(sanitizeToolSegment("minimal.ts")).toBe("minimal_ts");
@@ -31,10 +30,8 @@ test("mcpToolDescription formats CLI path and root-leaf prefix", () => {
31
30
  expect(mcpToolDescription([], "helloapp", "Tiny demo.")).toBe("helloapp — Tiny demo.");
32
31
  });
33
32
 
34
- test("apiToolName hyphen-joins path; mcpToolName sanitizes to underscores", () => {
35
- expect(apiToolName(nestedMcpFixture, ["stat", "owner", "lookup"])).toBe("stat-owner-lookup");
33
+ test("mcpToolName sanitizes path segments to underscores", () => {
36
34
  expect(mcpToolName(nestedMcpFixture, ["stat", "owner", "lookup"])).toBe("stat_owner_lookup");
37
- expect(apiToolName(nestedMcpFixture, ["render-invoice"])).toBe("render-invoice");
38
35
  expect(mcpToolName(nestedMcpFixture, ["render-invoice"])).toBe("render_invoice");
39
36
  });
40
37
 
@@ -43,7 +40,6 @@ test("collectMcpTools lists user leaf commands only", () => {
43
40
  const names = tools.map((t) => t.name);
44
41
  expect(names).toContain("stat_owner_lookup");
45
42
  const lookup = tools.find((t) => t.name === "stat_owner_lookup")!;
46
- expect(lookup.apiName).toBe("stat-owner-lookup");
47
43
  expect(lookup.description).toBe("stat owner lookup — Resolve owner info.");
48
44
  expect(names).toContain("read");
49
45
  expect(names).not.toContain("hidden");
@@ -104,13 +100,13 @@ test("collectMcpTools resolves {argsbarg:program} in appended notes", () => {
104
100
  {
105
101
  key: "run",
106
102
  description: "Run.",
107
- notes: "See `{argsbarg:program} docs api`.",
103
+ notes: "See `{argsbarg:program} docs cli`.",
108
104
  handler: () => {},
109
105
  },
110
106
  ],
111
107
  });
112
108
  const tools = collectMcpTools(root);
113
- expect(tools[0]?.description).toContain("See `myapp docs api`.");
109
+ expect(tools[0]?.description).toContain("See `myapp docs cli`.");
114
110
  });
115
111
 
116
112
  /** CliSchemaExport includes leaf outputSchema. */
@@ -139,29 +135,6 @@ test("cliSchemaExport includes leaf outputSchema", () => {
139
135
  });
140
136
  });
141
137
 
142
- /** CliSchemaExport accepts legacy mcpTool.outputSchema. */
143
- test("cliSchemaExport accepts legacy mcpTool.outputSchema", () => {
144
- const root = testProgram({
145
- key: "app",
146
- version: "1.0.0",
147
- description: "Schema export demo.",
148
- commands: [
149
- {
150
- key: "run",
151
- description: "Run.",
152
- mcpTool: {
153
- outputSchema: { type: "object", properties: { id: { type: "string" } } },
154
- },
155
- handler: () => {},
156
- },
157
- ],
158
- });
159
- expect(cliSchemaExport(root).commands?.[0]?.outputSchema).toEqual({
160
- type: "object",
161
- properties: { id: { type: "string" } },
162
- });
163
- });
164
-
165
138
  /** Tests that outputSchema must be a JSON Schema object. */
166
139
  test("outputSchema must be a JSON Schema object", () => {
167
140
  const root = testProgram({
@@ -180,25 +153,6 @@ test("outputSchema must be a JSON Schema object", () => {
180
153
  expect(() => cliValidateProgram(root)).toThrow(/outputSchema must be a JSON Schema object/);
181
154
  });
182
155
 
183
- /** Tests that outputSchema cannot be set on both leaf and mcpTool. */
184
- test("outputSchema cannot be set on both leaf and mcpTool", () => {
185
- const root = testProgram({
186
- key: "app",
187
- version: "1.0.0",
188
- description: "Duplicate output schema.",
189
- commands: [
190
- {
191
- key: "run",
192
- description: "Run.",
193
- outputSchema: { type: "object" },
194
- mcpTool: { outputSchema: { type: "object" } },
195
- handler: () => {},
196
- },
197
- ],
198
- });
199
- expect(() => cliValidateProgram(root)).toThrow(/Set outputSchema on the leaf only/);
200
- });
201
-
202
156
  test("collectMcpTools merges parent options into inputSchema", () => {
203
157
  const tools = collectMcpTools(nestedMcpFixture);
204
158
  const lookup = tools.find((t) => t.name === "stat_owner_lookup")!;
@@ -419,7 +373,7 @@ test("MCP resources/read returns schema JSON", async () => {
419
373
 
420
374
  /** MCP tools/call runs stat_owner_lookup. */
421
375
  test("MCP tools/call runs stat_owner_lookup", async () => {
422
- const readme = join(import.meta.dir, "..", "README.md");
376
+ const readme = join(import.meta.dir, "..", "..", "..", "README.md");
423
377
  const responses = await mcpRequest([
424
378
  {
425
379
  jsonrpc: "2.0",
@@ -440,7 +394,7 @@ test("MCP tools/call runs stat_owner_lookup", async () => {
440
394
 
441
395
  /** MCP tools/call returns structuredContent for JSON stdout. */
442
396
  test("MCP tools/call returns structuredContent for JSON stdout", async () => {
443
- const readme = join(import.meta.dir, "..", "README.md");
397
+ const readme = join(import.meta.dir, "..", "..", "..", "README.md");
444
398
  const responses = await mcpRequest([
445
399
  {
446
400
  jsonrpc: "2.0",
@@ -1,141 +0,0 @@
1
- # HTTP API server
2
-
3
- ArgsBarg can expose your CLI as an HTTP tool server. Each **leaf command** becomes a callable tool — the same exposure model as MCP. 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 `apiServer` on the program root behave exactly as before.
6
-
7
- ## Quick start
8
-
9
- 1. Add `apiServer` 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
- apiServer: { enabled: true },
19
- commands: [/* ... */],
20
- } satisfies CliProgram;
21
- ```
22
-
23
- `apiServer: { enabled: true }` opts in. Omit `apiServer` entirely to disable HTTP. Empty `apiServer: {}` is rejected at validation.
24
-
25
- 2. Run the HTTP server:
26
-
27
- ```bash
28
- myapp api
29
- ```
30
-
31
- The process listens until interrupted. Startup prints the listen URL to stderr.
32
-
33
- ## Configuration
34
-
35
- Set `apiServer` on the **program root only**. Validation rejects `apiServer` on nested nodes.
36
-
37
- | Field | Default | Purpose |
38
- | --- | --- | --- |
39
- | `enabled` | *(required)* | Must be `true` when `apiServer` is set |
40
- | `host` | `127.0.0.1` | Listen address |
41
- | `port` | `3000` | Listen port |
42
-
43
- `apiServer` and `mcpServer` are independent — enable either or both.
44
-
45
- ## Tool names
46
-
47
- HTTP and MCP use different tool identifiers for the same leaf command:
48
-
49
- | CLI path | HTTP API (`POST /tools/:name`) | MCP (`tools/call`) |
50
- | --- | --- | --- |
51
- | `stat owner lookup` | `stat-owner-lookup` | `stat_owner_lookup` |
52
- | `render-invoice` | `render-invoice` | `render_invoice` |
53
-
54
- OpenAPI `paths` use the API id (`/tools/render-invoice`, etc.).
55
-
56
- ## Endpoints
57
-
58
- | Method | Path | Purpose |
59
- | --- | --- | --- |
60
- | `GET` | `/health` | Liveness check |
61
- | `GET` | `/openapi.json` | OpenAPI 3.1 document (per-tool `POST /tools/{name}` paths) |
62
- | `GET` | `/openapi-browser` | Interactive Scalar API reference (CDN) |
63
- | `POST` | `/tools/:name` | Invoke tool; body is a flat JSON args object |
64
- | `OPTIONS` | `*` | CORS preflight (wide-open `Access-Control-Allow-Origin: *`) |
65
-
66
- ## Examples
67
-
68
- ```bash
69
- curl -s http://127.0.0.1:3000/health
70
- curl -s http://127.0.0.1:3000/openapi.json
71
- open http://127.0.0.1:3000/openapi-browser
72
- curl -s -X POST http://127.0.0.1:3000/tools/{tool-key} \
73
- -H 'content-type: application/json' \
74
- -d '{...}'
75
- ```
76
-
77
- Replace `{tool-key}` with a path segment from `openapi.json` (`paths` keys are `/tools/{tool-key}`); body keys match that tool's flat JSON args (see `docs cli-schema` or `openapi.json`).
78
-
79
- ## Handler responses (`ctx.respond()`)
80
-
81
- 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.
82
-
83
- ```typescript
84
- handler: (ctx) => {
85
- if (ctx.hasFlag("json")) {
86
- return { user: "alice", path: "/tmp" };
87
- }
88
- ctx.respond({
89
- body: pdfBytes,
90
- contentType: "application/pdf",
91
- headers: { "Content-Disposition": 'inline; filename="invoice.pdf"' },
92
- });
93
- },
94
- ```
95
-
96
- **CLI mode:** `ctx.respond()` prints to stdout (JSON pretty-printed, strings as-is, `Uint8Array` as raw bytes). Handlers may still use `console.log` for human-only CLI output.
97
-
98
- ### Leaf metadata
99
-
100
- ```typescript
101
- apiResponse?: {
102
- contentType?: string; // default application/json
103
- contentDisposition?: string; // e.g. attachment; filename="invoice.pdf"
104
- };
105
- ```
106
-
107
- Used by OpenAPI and as a default `Content-Type` when the handler does not set one.
108
-
109
- ## Responses
110
-
111
- **Success (`200`):** raw body — no `{ ok, stdout }` envelope.
112
-
113
- | Body type | HTTP `Content-Type` |
114
- | --- | --- |
115
- | object / array | `application/json` |
116
- | string | handler `contentType` or `text/plain` |
117
- | `Uint8Array` | e.g. `application/pdf` (required on `respond()`) |
118
-
119
- **Errors:** JSON `{ "error": "...", "exitCode?": number }` with `400` (bad args), `404` (unknown tool), `503` (missing config), or `500` (handler failure).
120
-
121
- ## MCP binary payloads
122
-
123
- Binary `ctx.respond()` bodies are encoded in MCP `structuredContent` as:
124
-
125
- ```json
126
- { "data": "<base64>", "contentType": "application/pdf", "encoding": "base64" }
127
- ```
128
-
129
- String bodies use `{ "content": "...", "contentType": "..." }`. JSON objects are returned as-is in `structuredContent`.
130
-
131
- ## CORS
132
-
133
- All responses include wide-open CORS headers (`Access-Control-Allow-Origin: *`). Not configurable in v1.
134
-
135
- ## OpenAPI
136
-
137
- Call `generateOpenApi(program)` or `openApiJson(program)` from the package, fetch `GET /openapi.json` from a running server, or run `myapp docs openapi` / `myapp docs openapi --save` (writes `./docs/openapi.json` when `docs.enabled` and `apiServer.enabled`). Nested `inputSchema` / `outputSchema` `$ref` pointers are dereferenced when the OpenAPI document is built so API reference UIs can show nested request shapes.
138
-
139
- ## Complex tool inputs
140
-
141
- For nested request bodies (e.g. invoice template data), set `inputSchema` on the leaf, declare a matching `kind: Json` option (optionally `pipable: true` for CLI stdin), and read inputs with `ctx.jsonOpt(...)` or `ctx.readLeafInputs()` — piped stdin is loaded before the handler runs.