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.
- package/CHANGELOG.md +72 -1
- package/README.md +17 -19
- package/bin/argsbarg +10 -0
- package/docs/README.md +4 -3
- package/docs/ai-skills.md +4 -2
- package/docs/bundled-docs.md +50 -25
- package/docs/cli-program.md +76 -10
- package/docs/config-schema.md +10 -11
- package/docs/configure.md +2 -0
- package/docs/decisions.md +40 -0
- package/docs/developing.md +43 -5
- package/docs/http-server.md +171 -0
- package/docs/json-schema-subset.md +51 -0
- package/docs/mcp.md +4 -2
- package/docs/output-schema.md +55 -62
- package/examples/formats.ts +6 -6
- package/examples/full-example/Formula/full-example.rb +35 -0
- package/examples/full-example/README.md +20 -21
- package/examples/full-example/docs/README.md +1 -1
- package/examples/full-example/docs/cli-schema.json +1790 -98
- package/examples/full-example/docs/cli.md +1990 -0
- package/examples/full-example/docs/http.md +28 -29
- package/examples/full-example/docs/mcp.md +8 -22
- package/examples/full-example/docs/openapi.json +783 -50
- package/examples/full-example/docs/skill.md +10 -10
- package/examples/full-example/justfile +11 -1
- package/examples/full-example/src/commands/render-json/__generated__/RenderJsonInputSchema.json +15 -0
- package/examples/full-example/src/commands/render-json/__generated__/index.ts +5 -0
- package/examples/full-example/src/commands/render-json/command.test.ts +46 -0
- package/examples/full-example/src/commands/render-json/command.ts +30 -0
- package/examples/full-example/src/commands/render-json/types.ts +9 -0
- package/examples/full-example/src/commands/status/__generated__/StatusJsonOutputSchema.json +15 -0
- package/examples/full-example/src/commands/status/__generated__/index.ts +2 -2
- package/examples/full-example/src/commands/status/command.ts +5 -13
- package/examples/full-example/src/commands/status/types.ts +1 -14
- package/examples/full-example/src/commands/workspaces/__generated__/WorkspaceNameInputSchema.json +15 -0
- package/examples/full-example/src/commands/workspaces/__generated__/index.ts +5 -0
- package/examples/full-example/src/commands/workspaces/command.test.ts +58 -0
- package/examples/full-example/src/commands/workspaces/command.ts +94 -0
- package/examples/full-example/src/commands/workspaces/types.ts +6 -0
- package/examples/full-example/src/db/index.test.ts +86 -0
- package/examples/full-example/src/db/index.ts +101 -0
- package/examples/full-example/src/db/migrate.test.ts +35 -0
- package/examples/full-example/src/db/migrate.ts +69 -0
- package/examples/full-example/src/db/migrations/001_workspaces.sql +6 -0
- package/examples/full-example/src/db/tables/workspaces.ts +66 -0
- package/examples/full-example/src/program.ts +11 -36
- package/examples/full-example/src/types/argsbarg.d.ts +11 -0
- package/examples/full-example/src/types/md.d.ts +4 -0
- package/examples/full-example/tsconfig.json +5 -2
- package/examples/mcp-test.ts +1 -2
- package/examples/minimal.ts +1 -7
- package/examples/nested.ts +1 -2
- package/examples/option-required.ts +1 -1
- package/examples/servers.ts +4 -5
- package/index.d.ts +440 -136
- package/package.json +19 -2
- package/src/builtins/builtins.test.ts +7 -7
- package/src/builtins/completion-bash.ts +1 -1
- package/src/builtins/completion-fish.ts +1 -1
- package/src/builtins/completion-group.ts +4 -4
- package/src/builtins/completion-simulate-shared.ts +9 -0
- package/src/builtins/completion-zsh.ts +1 -1
- package/src/builtins/config.test.ts +3 -3
- package/src/builtins/config.ts +9 -9
- package/src/builtins/configure-copy.ts +2 -2
- package/src/builtins/configure.ts +4 -4
- package/src/builtins/dispatch.ts +19 -18
- package/src/builtins/export.ts +7 -5
- package/src/builtins/http.ts +68 -0
- package/src/builtins/mcp.ts +28 -4
- package/src/builtins/presentation.ts +6 -6
- package/src/builtins/registry.ts +6 -6
- package/src/builtins/scopes.ts +2 -2
- package/src/builtins/version.ts +1 -1
- package/src/cli-tool/full-example-capabilities.test.ts +10 -15
- package/src/cli-tool/main.ts +1 -1
- package/src/cli-tool/program.ts +3 -2
- package/src/cli-tool/prompt.ts +1 -1
- package/src/cli-tool/run-schemagen.ts +1 -3
- package/src/cli-tool/schemagen/cleanup.ts +6 -7
- package/src/cli-tool/schemagen/discover-schema-roots.ts +66 -120
- package/src/cli-tool/schemagen/index.ts +2 -2
- package/src/cli-tool/schemagen/names.ts +8 -13
- package/src/cli-tool/schemagen/run.ts +21 -28
- package/src/cli-tool/schemagen/schemagen.test.ts +136 -46
- package/src/config/bindings.test.ts +1 -1
- package/src/config/bindings.ts +1 -1
- package/src/config/bootstrap.test.ts +1 -1
- package/src/config/bootstrap.ts +36 -4
- package/src/config/context.test.ts +1 -1
- package/src/config/context.ts +1 -1
- package/src/config/entry.ts +1 -1
- package/src/config/file.test.ts +1 -1
- package/src/config/file.ts +3 -3
- package/src/config/manifest.ts +1 -1
- package/src/config/resolve.test.ts +1 -1
- package/src/config/resolve.ts +1 -1
- package/src/config/schema.ts +1 -1
- package/src/config/validate.ts +1 -1
- package/src/{install → configure/artifacts}/binary-placement.test.ts +1 -1
- package/src/{install → configure/artifacts}/binary-placement.ts +1 -1
- package/src/{install → configure/artifacts}/gh-release-update.ts +1 -1
- package/src/{install → configure/artifacts}/install-validate.test.ts +3 -3
- package/src/{install → configure/artifacts}/mcp-config.ts +1 -1
- package/src/{install → configure/artifacts}/mcp-opencode.test.ts +1 -1
- package/src/{install → configure/artifacts}/mcp-opencode.ts +1 -1
- package/src/{install → configure/artifacts}/paths.ts +5 -5
- package/src/configure/artifacts/plan.ts +24 -0
- package/src/{install → configure/artifacts}/status.test.ts +1 -1
- package/src/{install → configure/artifacts}/status.ts +2 -2
- package/src/{install → configure/artifacts}/target-base.ts +1 -1
- package/src/{install → configure/artifacts}/target-detect.ts +1 -1
- package/src/{install → configure/artifacts}/target-effective.ts +3 -9
- package/src/{install → configure/artifacts}/target-mcp-cli.ts +1 -1
- package/src/{install → configure/artifacts}/target-mcp-json.ts +1 -1
- package/src/{install → configure/artifacts}/target-plan-build.ts +2 -2
- package/src/{install → configure/artifacts}/target-registry.ts +2 -2
- package/src/{install → configure/artifacts}/target-scope.ts +3 -3
- package/src/{install → configure/artifacts}/target-skill.ts +1 -1
- package/src/{install → configure/artifacts}/target-types.ts +2 -2
- package/src/{install → configure/artifacts}/targets/app.ts +5 -5
- package/src/{install → configure/artifacts}/targets/chatgpt-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-code-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-desktop-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/codex-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/codex-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/configure.ts +5 -5
- package/src/{install → configure/artifacts}/targets/cursor-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/cursor-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/index.ts +1 -1
- package/src/{install → configure/artifacts}/targets/openclaw-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/openclaw-skill.ts +3 -3
- package/src/{install → configure/artifacts}/targets/opencode-mcp.ts +5 -5
- package/src/{install → configure/artifacts}/targets/opencode-skill.ts +3 -3
- package/src/{install → configure/artifacts}/targets.test.ts +1 -1
- package/src/{install → configure/artifacts}/uninstall.ts +1 -1
- package/src/configure/configure.test.ts +11 -11
- package/src/configure/index.ts +14 -14
- package/src/configure/prompt.ts +2 -2
- package/src/{context.ts → core/context.ts} +26 -20
- package/src/core/json-leaf.test.ts +156 -0
- package/src/{leaf-inputs.test.ts → core/leaf-inputs.test.ts} +7 -7
- package/src/{leaf-inputs.ts → core/leaf-inputs.ts} +76 -16
- package/src/{parse.test.ts → core/parse.test.ts} +97 -109
- package/src/{parse.ts → core/parse.ts} +173 -25
- package/src/{schema.ts → core/schema.ts} +25 -13
- package/src/{types.ts → core/types.ts} +238 -35
- package/src/{validate.ts → core/validate.ts} +51 -29
- package/src/docs/builtin.ts +8 -19
- package/src/docs/{api-guide.test.ts → cli-guide.test.ts} +21 -21
- package/src/docs/{api-guide.ts → cli-guide.ts} +45 -16
- package/src/docs/docs.test.ts +76 -41
- package/src/docs/http-guide.ts +37 -34
- package/src/docs/mcp-guide.ts +12 -14
- package/src/docs/mcp-resources.test.ts +2 -3
- package/src/docs/mcp-resources.ts +6 -11
- package/src/docs/resolve.ts +22 -30
- package/src/docs/save.ts +3 -3
- package/src/exports/cli.ts +47 -0
- package/src/exports/headless.ts +13 -0
- package/src/exports/http.ts +6 -0
- package/src/exports/mcp.ts +6 -0
- package/src/{headless.test.ts → headless/routing.test.ts} +3 -3
- package/src/{headless.ts → headless/routing.ts} +3 -3
- package/src/headless/tool-call.ts +114 -46
- package/src/help.test.ts +152 -0
- package/src/help.ts +54 -18
- package/src/hooks/builtin.ts +20 -0
- package/src/hooks/run.ts +142 -0
- package/src/http/openapi.ts +182 -0
- package/src/http/readiness.ts +78 -0
- package/src/{api → http}/result.ts +16 -5
- package/src/http/routes.ts +329 -0
- package/src/http/server.ts +225 -0
- package/src/index.ts +38 -25
- package/src/log/ecs.test.ts +43 -0
- package/src/log/ecs.ts +59 -0
- package/src/log/emitter.ts +166 -0
- package/src/mcp/bundle.ts +2 -2
- package/src/mcp/claude.test.ts +1 -1
- package/src/mcp/claude.ts +4 -4
- package/src/{hidden-mcpb.test.ts → mcp/hidden-mcpb.test.ts} +10 -9
- package/src/mcp/result.ts +2 -2
- package/src/mcp/server.ts +54 -6
- package/src/mcp/tools.ts +18 -20
- package/src/{capabilities.ts → runtime/capabilities.ts} +11 -11
- package/src/{cli-errors.ts → runtime/cli-errors.ts} +4 -4
- package/src/{cli.ts → runtime/cli.ts} +160 -50
- package/src/runtime/exposure.ts +102 -0
- package/src/{invoke.test.ts → runtime/invoke.test.ts} +31 -7
- package/src/server/context.ts +25 -0
- package/src/server/overrides.ts +112 -0
- package/src/skill/generate.ts +8 -8
- package/src/skill/hint.ts +1 -1
- package/src/skill/install.ts +2 -2
- package/src/skill/naming.ts +1 -1
- package/src/{test-fixtures.ts → test/fixtures.ts} +3 -2
- package/src/{config.integration.test.ts → test/integration/config.test.ts} +8 -8
- package/src/{api.integration.test.ts → test/integration/http.test.ts} +170 -67
- package/src/{mcp.integration.test.ts → test/integration/mcp.test.ts} +11 -57
- package/docs/api-server.md +0 -141
- package/examples/full-example/docs/api.md +0 -511
- package/examples/full-example/src/commands/status/__generated__/outputSchema.json +0 -28
- package/examples/full-example/src/config/__generated__/configSchema.json +0 -40
- package/examples/full-example/src/config/__generated__/index.ts +0 -5
- package/examples/full-example/src/config/types.ts +0 -24
- package/src/api/openapi.ts +0 -117
- package/src/api/server.ts +0 -120
- package/src/builtins/api.ts +0 -38
- package/src/hidden.ts +0 -30
- package/src/install/plan.ts +0 -53
- /package/src/{install → configure/artifacts}/detect-installed.ts +0 -0
- /package/src/{install → configure/artifacts}/gh-release-update.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-codex.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-codex.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-openclaw.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-openclaw.ts +0 -0
- /package/src/{install → configure/artifacts}/normalize-uninstall.ts +0 -0
- /package/src/{install → configure/artifacts}/normalize.ts +0 -0
- /package/src/{install → configure/artifacts}/opts.ts +0 -0
- /package/src/{install → configure/artifacts}/shell.ts +0 -0
- /package/src/{formats.test.ts → core/formats.test.ts} +0 -0
- /package/src/{formats.ts → core/formats.ts} +0 -0
- /package/src/{respond.ts → core/respond.ts} +0 -0
- /package/src/{types.test.ts → core/types.test.ts} +0 -0
- /package/src/{api → http}/schema-deref.test.ts +0 -0
- /package/src/{api → http}/schema-deref.ts +0 -0
|
@@ -4,12 +4,13 @@ It is the shared declarative model that parsing, validation, help, and completio
|
|
|
4
4
|
read from, so the package has one source of truth.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { AnyAppConfigSnapshot } from "~/config/context.ts";
|
|
7
8
|
import type { CliContext } from "./context.ts";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* How a leaf handler was dispatched.
|
|
11
12
|
*/
|
|
12
|
-
export type CliInvocation = "cli" | "mcp" | "
|
|
13
|
+
export type CliInvocation = "cli" | "mcp" | "http";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Option kinds: presence (boolean flag), string (free-form text), number (strict double), enum (fixed choices), or json (parsed JSON object/array).
|
|
@@ -61,14 +62,49 @@ export enum CliFallbackMode {
|
|
|
61
62
|
UnknownOnly = "unknownOnly",
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Per-surface CLI exposure (help, completions, cli-schema).
|
|
67
|
+
*/
|
|
68
|
+
export interface CliCliExposureConfig {
|
|
69
|
+
/** When `false`, not callable via CLI (cascades to descendants). Default: true. */
|
|
70
|
+
enabled?: boolean;
|
|
71
|
+
/** Callable; omit from help, completions, and schema export. */
|
|
72
|
+
hidden?: boolean;
|
|
73
|
+
completions?: { enabled?: boolean; hidden?: boolean };
|
|
74
|
+
schema?: { enabled?: boolean; hidden?: boolean };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** HTTP method for REST leaves. */
|
|
78
|
+
export type CliHttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Per-node HTTP exposure and response defaults (routers: segment/enabled/hidden; leaves: full set).
|
|
82
|
+
*/
|
|
83
|
+
export interface CliHttpExposureConfig {
|
|
84
|
+
/** When `false`, omit from HTTP route table. Default: exposed. */
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
/** Callable; omit from OpenAPI / route discovery. */
|
|
87
|
+
hidden?: boolean;
|
|
88
|
+
/** Override inferred HTTP verb. */
|
|
89
|
+
method?: CliHttpMethod;
|
|
90
|
+
/** URL path segment override (≠ `key`). */
|
|
91
|
+
segment?: string;
|
|
92
|
+
/** Default success HTTP status when handler omits `ctx.respond({ status })`. */
|
|
93
|
+
successStatus?: number;
|
|
94
|
+
/** Default success Content-Type (OpenAPI + response headers). */
|
|
95
|
+
successContentType?: string;
|
|
96
|
+
/** Default Content-Disposition for binary/downloads. */
|
|
97
|
+
contentDisposition?: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
64
100
|
/**
|
|
65
101
|
* A named flag or value option (`--long`, `-short`), listed on command `options`.
|
|
66
102
|
*/
|
|
67
103
|
export interface CliOption {
|
|
68
104
|
/** Option name (e.g., "name", "verbose"). */
|
|
69
105
|
name: string;
|
|
70
|
-
/**
|
|
71
|
-
|
|
106
|
+
/** Per-surface CLI exposure for this option. */
|
|
107
|
+
cli?: Pick<CliCliExposureConfig, "hidden">;
|
|
72
108
|
/** Description shown in help. */
|
|
73
109
|
description: string;
|
|
74
110
|
/** Option kind: presence flag, string value, or number value. */
|
|
@@ -120,7 +156,7 @@ export interface CliPositional {
|
|
|
120
156
|
argMax?: number;
|
|
121
157
|
}
|
|
122
158
|
|
|
123
|
-
/**
|
|
159
|
+
/** @experimental MCP bundle output options (program root `mcpServer.bundle` only). */
|
|
124
160
|
export interface CliMcpBundleConfig {
|
|
125
161
|
author?: {
|
|
126
162
|
name: string;
|
|
@@ -136,10 +172,15 @@ export interface CliMcpBundleConfig {
|
|
|
136
172
|
/**
|
|
137
173
|
* Enables `myapp mcp` and MCP stdio server metadata (program root only).
|
|
138
174
|
* Must include `enabled: true`; omit `mcpServer` entirely to disable MCP.
|
|
175
|
+
* @experimental
|
|
139
176
|
*/
|
|
140
177
|
export interface CliMcpServerConfig {
|
|
141
178
|
/** When `true`, enables the `mcp` built-in and MCP stdio server. */
|
|
142
179
|
enabled: boolean;
|
|
180
|
+
/** MCP error response defaults. */
|
|
181
|
+
errors?: CliMcpServerErrorsConfig;
|
|
182
|
+
/** Observe-only hooks for JSON-RPC messages. */
|
|
183
|
+
hooks?: CliMcpWireHooks;
|
|
143
184
|
/** When `true`, `mcp bundle` writes `dist/<key>.mcpb` for Claude Desktop. Default false. */
|
|
144
185
|
mcpd?: boolean;
|
|
145
186
|
/** When `true`, `mcp bundle` also writes `dist/claude-plugin/<name>.zip`. Default false. */
|
|
@@ -161,23 +202,69 @@ export interface CliMcpServerConfig {
|
|
|
161
202
|
bundle?: CliMcpBundleConfig;
|
|
162
203
|
}
|
|
163
204
|
|
|
205
|
+
/** JSON Schema for structured error responses (OpenAPI + HTTP/MCP error bodies). */
|
|
206
|
+
export type CliJsonSchema = Record<string, unknown>;
|
|
207
|
+
|
|
208
|
+
/** Wire-level HTTP hooks (observe-only; all requests including health and 404s). */
|
|
209
|
+
export interface CliHttpWireHooks {
|
|
210
|
+
onRequest?: (ctx: CliHttpWireContext) => void | Promise<void>;
|
|
211
|
+
onResponse?: (ctx: CliHttpWireContext & { status: number; durationMs: number }) => void | Promise<void>;
|
|
212
|
+
onError?: (ctx: CliHttpWireContext & { failureKind: InvokeFailureKind; error: unknown }) => void | Promise<void>;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Per-request HTTP wire context for {@link CliHttpWireHooks}. */
|
|
216
|
+
export interface CliHttpWireContext {
|
|
217
|
+
request: Request;
|
|
218
|
+
requestId: string;
|
|
219
|
+
clientIp: string;
|
|
220
|
+
path: string;
|
|
221
|
+
method: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** Wire-level MCP hooks on JSON-RPC messages (observe-only). */
|
|
225
|
+
export interface CliMcpWireHooks {
|
|
226
|
+
onRequest?: (ctx: CliMcpWireContext) => void | Promise<void>;
|
|
227
|
+
onResponse?: (ctx: CliMcpWireContext & { durationMs: number }) => void | Promise<void>;
|
|
228
|
+
onError?: (ctx: CliMcpWireContext & { failureKind: InvokeFailureKind; error: unknown }) => void | Promise<void>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Per-message MCP wire context for {@link CliMcpWireHooks}. */
|
|
232
|
+
export interface CliMcpWireContext {
|
|
233
|
+
rpcMethod: string;
|
|
234
|
+
requestId: string;
|
|
235
|
+
toolName?: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
164
238
|
/**
|
|
165
|
-
* Enables `myapp
|
|
166
|
-
* Must include `enabled: true`; omit `
|
|
239
|
+
* Enables `myapp http` and the HTTP tool server (program root only).
|
|
240
|
+
* Must include `enabled: true`; omit `httpServer` entirely to disable HTTP.
|
|
167
241
|
*/
|
|
168
|
-
export interface
|
|
169
|
-
/** When `true`, enables the `
|
|
242
|
+
export interface CliHttpServerConfig {
|
|
243
|
+
/** When `true`, enables the `http` built-in and HTTP tool server. */
|
|
170
244
|
enabled: boolean;
|
|
171
245
|
/** Listen host (default: `127.0.0.1`). */
|
|
172
246
|
host?: string;
|
|
173
247
|
/** Listen port (default: `3000`). */
|
|
174
248
|
port?: number;
|
|
249
|
+
/** Honor `X-Forwarded-For` for client IP in hooks and logs. */
|
|
250
|
+
trustProxy?: boolean;
|
|
251
|
+
/** HTTP error response defaults. */
|
|
252
|
+
errors?: { errorSchema?: CliJsonSchema; obscureUnexpected?: boolean };
|
|
253
|
+
/** Observe-only hooks for all HTTP requests. */
|
|
254
|
+
hooks?: CliHttpWireHooks;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** MCP server error defaults. */
|
|
258
|
+
export interface CliMcpServerErrorsConfig {
|
|
259
|
+
errorSchema?: CliJsonSchema;
|
|
260
|
+
obscureUnexpected?: boolean;
|
|
175
261
|
}
|
|
176
262
|
|
|
177
263
|
/**
|
|
178
|
-
* Declarative HTTP response hints
|
|
264
|
+
* Declarative HTTP response hints passed to {@link apiSuccessResponse}.
|
|
265
|
+
* @internal Prefer `CliHttpExposureConfig` on the leaf.
|
|
179
266
|
*/
|
|
180
|
-
export interface
|
|
267
|
+
export interface CliHttpResponseConfig {
|
|
181
268
|
/** Default success Content-Type (default: `application/json`). */
|
|
182
269
|
contentType?: string;
|
|
183
270
|
/** Optional Content-Disposition (e.g. `attachment; filename="invoice.pdf"`). */
|
|
@@ -219,15 +306,13 @@ export interface CliMcpResource {
|
|
|
219
306
|
export interface CliMcpToolConfig {
|
|
220
307
|
/** When `false`, omit from `tools/list` (default: exposed). */
|
|
221
308
|
enabled?: boolean;
|
|
309
|
+
/** Callable; omit from `tools/list` and MCP tool schemas. */
|
|
310
|
+
hidden?: boolean;
|
|
222
311
|
/**
|
|
223
312
|
* Override the generated MCP tool description.
|
|
224
313
|
* Default: auto-generated from command path and description.
|
|
225
314
|
*/
|
|
226
315
|
description?: string;
|
|
227
|
-
/**
|
|
228
|
-
* @deprecated Set `outputSchema` on the leaf command instead.
|
|
229
|
-
*/
|
|
230
|
-
outputSchema?: Record<string, unknown>;
|
|
231
316
|
}
|
|
232
317
|
|
|
233
318
|
/**
|
|
@@ -310,6 +395,7 @@ export interface CliCompletionConfig {
|
|
|
310
395
|
enabled?: boolean;
|
|
311
396
|
}
|
|
312
397
|
|
|
398
|
+
/** @experimental */
|
|
313
399
|
export interface CliConfigureConfig {
|
|
314
400
|
/** When `false`, hide/disable `configure` (default: enabled). */
|
|
315
401
|
enabled?: boolean;
|
|
@@ -385,21 +471,16 @@ export interface CliDocsTopic {
|
|
|
385
471
|
}
|
|
386
472
|
|
|
387
473
|
/**
|
|
388
|
-
*
|
|
389
|
-
*
|
|
474
|
+
* Opt-out and optional topics for the `docs` built-in (program root only).
|
|
475
|
+
* Docs is enabled by default; set `enabled: false` to disable.
|
|
390
476
|
*/
|
|
391
477
|
export interface CliDocsConfig {
|
|
392
|
-
/** When `
|
|
393
|
-
enabled
|
|
478
|
+
/** When `false`, hide/disable `docs` (default: enabled). */
|
|
479
|
+
enabled?: boolean;
|
|
394
480
|
/** Router description for `myapp docs` (default: "Print bundled CLI documentation."). */
|
|
395
481
|
description?: string;
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
* When omitted, uses the first key in `topics` (insertion order).
|
|
399
|
-
*/
|
|
400
|
-
defaultTopic?: string;
|
|
401
|
-
/** Topic key → bundled markdown. Reserved keys: `mcp`, `all` (supplied by the built-in). */
|
|
402
|
-
topics: Record<string, CliDocsTopic>;
|
|
482
|
+
/** Optional consumer markdown topics. Reserved keys: `mcp`, `all` (supplied by the built-in). */
|
|
483
|
+
topics?: Record<string, CliDocsTopic>;
|
|
403
484
|
}
|
|
404
485
|
|
|
405
486
|
/**
|
|
@@ -408,8 +489,10 @@ export interface CliDocsConfig {
|
|
|
408
489
|
export interface CliNodeBase {
|
|
409
490
|
/** Program or command key (e.g., "myapp", "stat", "owner"). */
|
|
410
491
|
key: string;
|
|
411
|
-
/**
|
|
412
|
-
|
|
492
|
+
/** Per-surface CLI exposure. */
|
|
493
|
+
cli?: CliCliExposureConfig;
|
|
494
|
+
/** Per-surface HTTP exposure and response defaults. */
|
|
495
|
+
http?: CliHttpExposureConfig;
|
|
413
496
|
/** Short description shown in help. */
|
|
414
497
|
description: string;
|
|
415
498
|
/** Additional notes shown in help (`{argsbarg:program}` → program key). */
|
|
@@ -418,23 +501,29 @@ export interface CliNodeBase {
|
|
|
418
501
|
options?: CliOption[];
|
|
419
502
|
}
|
|
420
503
|
|
|
504
|
+
/** Leaf input mode: `json` = pure JSON body (no CLI flags). */
|
|
505
|
+
export type CliLeafKind = "json";
|
|
506
|
+
|
|
421
507
|
/**
|
|
422
508
|
* A leaf command node with a handler and optional positionals.
|
|
423
509
|
*/
|
|
424
510
|
export type CliLeaf = CliNodeBase & {
|
|
511
|
+
/**
|
|
512
|
+
* When `"json"`, the leaf accepts a single JSON document (CLI positional or piped stdin;
|
|
513
|
+
* MCP/HTTP tool args = body). Requires `inputSchema`; forbids `options` and `positionals`.
|
|
514
|
+
*/
|
|
515
|
+
kind?: CliLeafKind;
|
|
425
516
|
/** Handler function for leaf commands. */
|
|
426
517
|
handler: CliHandler;
|
|
427
518
|
/** Positional argument definitions. */
|
|
428
519
|
positionals?: CliPositional[];
|
|
429
520
|
/**
|
|
430
521
|
* JSON Schema for structured stdout (e.g. with `--json` or MCP when the handler emits JSON).
|
|
431
|
-
* Exported in `docs cli-schema`, `docs
|
|
522
|
+
* Exported in `docs cli-schema`, `docs cli`, and MCP `tools/list`; not validated at runtime yet.
|
|
432
523
|
*/
|
|
433
524
|
outputSchema?: Record<string, unknown>;
|
|
434
525
|
/** JSON Schema for MCP/HTTP tool arguments (flat object). */
|
|
435
526
|
inputSchema?: Record<string, unknown>;
|
|
436
|
-
/** Declarative HTTP response metadata (Content-Type, Content-Disposition). */
|
|
437
|
-
apiResponse?: CliApiResponseConfig;
|
|
438
527
|
/** Per-tool MCP exposure and metadata. */
|
|
439
528
|
mcpTool?: CliMcpToolConfig;
|
|
440
529
|
};
|
|
@@ -456,6 +545,109 @@ export type CliRouter = CliNodeBase & {
|
|
|
456
545
|
*/
|
|
457
546
|
export type CliNode = CliLeaf | CliRouter;
|
|
458
547
|
|
|
548
|
+
/** Classified failure kind for invoke error pipeline and HTTP/MCP status mapping. */
|
|
549
|
+
export type InvokeFailureKind = "validation" | "help" | "unexpected" | "not_ready" | "missing_config" | "unknown_route";
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Per-invocation context attached in hooks (e.g. DB handles, auth principals).
|
|
553
|
+
* Augment in app code: `declare module "argsbarg" { interface CliLocals { db: AppDb } }`.
|
|
554
|
+
*/
|
|
555
|
+
export interface CliLocals {
|
|
556
|
+
/** Correlation id seeded before hooks run (HTTP/MCP wire id or generated UUID). */
|
|
557
|
+
requestId?: string;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Cross-request server state (HTTP/MCP runtime bag).
|
|
562
|
+
* Augment in app code: `declare module "argsbarg" { interface ServerState { db: AppDb } }`.
|
|
563
|
+
*/
|
|
564
|
+
export interface ServerState {
|
|
565
|
+
/** Set when app config soft-validation fails at server start. */
|
|
566
|
+
configFileError?: string;
|
|
567
|
+
/** Short-TTL cache for readiness probe results. */
|
|
568
|
+
readinessCache?: {
|
|
569
|
+
at: number;
|
|
570
|
+
result: { ok: boolean; checks: Record<string, { ok: boolean; error?: string; missing?: string[] }> };
|
|
571
|
+
};
|
|
572
|
+
/** Last readiness probe result. */
|
|
573
|
+
readiness?: { ok: boolean; checks: Record<string, { ok: boolean; error?: string; missing?: string[] }> };
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** Cross-request mutable state created at HTTP/MCP server start. */
|
|
577
|
+
export interface ServerRuntime {
|
|
578
|
+
/** Mutable global bag (DB pool, degraded flags, readiness cache, etc.). */
|
|
579
|
+
state: ServerState;
|
|
580
|
+
program: CliProgram;
|
|
581
|
+
surface: "http" | "mcp";
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/** Context for program-level invoke hooks (CLI, HTTP, MCP user commands). */
|
|
585
|
+
export interface InvokeHookContext {
|
|
586
|
+
invocation: CliInvocation;
|
|
587
|
+
path: string[];
|
|
588
|
+
pathParams: Record<string, string>;
|
|
589
|
+
opts: Record<string, string>;
|
|
590
|
+
/** Per-invocation bag; `beforeInvoke` may write. Framework seeds `requestId` before hooks run. */
|
|
591
|
+
locals: CliLocals;
|
|
592
|
+
runtime?: ServerRuntime;
|
|
593
|
+
appConfig: AnyAppConfigSnapshot;
|
|
594
|
+
http?: { request: Request; clientIp: string; requestId: string };
|
|
595
|
+
mcp?: { rpcMethod: string; toolName?: string; requestId: string };
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/** Error hook context after failure classification. */
|
|
599
|
+
export interface ErrorHookContext extends InvokeHookContext {
|
|
600
|
+
failureKind: InvokeFailureKind;
|
|
601
|
+
error: unknown;
|
|
602
|
+
/** Default client-facing error before `formatError` override. */
|
|
603
|
+
clientError: ClientErrorOverride;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** Client-facing error payload; `formatError` may return a partial override. */
|
|
607
|
+
export interface ClientErrorOverride {
|
|
608
|
+
message: string;
|
|
609
|
+
exitCode?: number;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/** Minimal invoke result passed to `afterInvoke` (see {@link Cli.invoke}). */
|
|
613
|
+
export interface CliInvokeHookResult {
|
|
614
|
+
kind: "ok" | "help" | "error";
|
|
615
|
+
exitCode: number;
|
|
616
|
+
failureKind?: InvokeFailureKind;
|
|
617
|
+
errorMsg?: string;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** Program-level invoke and error hooks (skipped for builtins). */
|
|
621
|
+
export interface CliProgramHooks {
|
|
622
|
+
/** May mutate `locals`, `opts`, `args`; may throw. Skipped for builtins. */
|
|
623
|
+
beforeInvoke?: (ctx: InvokeHookContext) => void | Promise<void>;
|
|
624
|
+
afterInvoke?: (ctx: InvokeHookContext & { result: CliInvokeHookResult }) => void | Promise<void>;
|
|
625
|
+
/** Mutate client-facing error payload only. Runs before `onError`. */
|
|
626
|
+
formatError?: (ctx: ErrorHookContext) => ClientErrorOverride | undefined | Promise<ClientErrorOverride | undefined>;
|
|
627
|
+
/** Observe only — runs after `formatError`; may enrich `locals`. Never mutates client response. */
|
|
628
|
+
onError?: (ctx: ErrorHookContext) => void | Promise<void>;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/** Context for optional `program.readiness` (HTTP/MCP health only). */
|
|
632
|
+
export interface ReadinessContext {
|
|
633
|
+
program: CliProgram;
|
|
634
|
+
surface: "http" | "mcp";
|
|
635
|
+
appConfig: AnyAppConfigSnapshot;
|
|
636
|
+
runtime: ServerRuntime;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/** Framework logging defaults (ECS json or human text on stderr). */
|
|
640
|
+
export interface CliLogConfig {
|
|
641
|
+
/** `json` = ECS lines; `text` = human stderr lines. Default: `json`. */
|
|
642
|
+
format?: "json" | "text";
|
|
643
|
+
/** Tee stderr + append; relative paths resolve under the app config dir. */
|
|
644
|
+
file?: string;
|
|
645
|
+
/** Emit HTTP/MCP access logs. Default: true. */
|
|
646
|
+
access?: boolean;
|
|
647
|
+
/** Emit error events after the hook pipeline. Default: true. */
|
|
648
|
+
errors?: boolean;
|
|
649
|
+
}
|
|
650
|
+
|
|
459
651
|
/**
|
|
460
652
|
* Program root passed to {@link Cli}.
|
|
461
653
|
* May be a leaf or router, plus optional program-level MCP and install config.
|
|
@@ -467,14 +659,20 @@ export type CliProgram = CliNode & {
|
|
|
467
659
|
appConfig?: CliAppConfig;
|
|
468
660
|
/** When set with `enabled: true`, enables the `mcp` built-in subcommand. */
|
|
469
661
|
mcpServer?: CliMcpServerConfig;
|
|
470
|
-
/** When set with `enabled: true`, enables the `
|
|
471
|
-
|
|
662
|
+
/** When set with `enabled: true`, enables the `http` built-in HTTP server. */
|
|
663
|
+
httpServer?: CliHttpServerConfig;
|
|
472
664
|
/** Opt-out and defaults for `configure`. */
|
|
473
665
|
configure?: CliConfigureConfig;
|
|
474
666
|
/** Opt-out for shell completion generation (`completion bash|zsh|fish`). */
|
|
475
667
|
completion?: CliCompletionConfig;
|
|
476
|
-
/**
|
|
668
|
+
/** Opt-out and optional topics for the `docs` built-in (default: enabled). */
|
|
477
669
|
docs?: CliDocsConfig;
|
|
670
|
+
/** Invoke and error hooks for user commands on CLI, HTTP, and MCP. */
|
|
671
|
+
hooks?: CliProgramHooks;
|
|
672
|
+
/** Optional readiness probe for HTTP/MCP `GET /health/ready` only. */
|
|
673
|
+
readiness?: (ctx: ReadinessContext) => boolean | Promise<boolean>;
|
|
674
|
+
/** Framework logging (stderr + optional file). */
|
|
675
|
+
log?: CliLogConfig;
|
|
478
676
|
};
|
|
479
677
|
|
|
480
678
|
/** True when the node is a leaf (has a handler). */
|
|
@@ -482,14 +680,19 @@ export function isCliLeaf(node: CliNode): node is CliLeaf {
|
|
|
482
680
|
return "handler" in node && typeof node.handler === "function";
|
|
483
681
|
}
|
|
484
682
|
|
|
683
|
+
/** True when the leaf accepts a pure JSON body (no CLI flags). */
|
|
684
|
+
export function isJsonLeaf(leaf: CliLeaf): boolean {
|
|
685
|
+
return leaf.kind === "json";
|
|
686
|
+
}
|
|
687
|
+
|
|
485
688
|
/** True when the node is a router (has subcommands). */
|
|
486
689
|
export function isCliRouter(node: CliNode): node is CliRouter {
|
|
487
690
|
return "commands" in node && Array.isArray(node.commands);
|
|
488
691
|
}
|
|
489
692
|
|
|
490
|
-
/** Resolves structured stdout schema from the leaf
|
|
693
|
+
/** Resolves structured stdout schema from the leaf. */
|
|
491
694
|
export function leafOutputSchema(leaf: CliLeaf): Record<string, unknown> | undefined {
|
|
492
|
-
return leaf.outputSchema
|
|
695
|
+
return leaf.outputSchema;
|
|
493
696
|
}
|
|
494
697
|
|
|
495
698
|
/**
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
This module validates CLI schemas before execution.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { reservedDocsTopicResourceUris } from "
|
|
7
|
-
import { DOCS_BUILTIN_TOPIC_KEYS } from "
|
|
5
|
+
import { AGENT_PAIRS, MCP_KEYS, mcpServerRequiredForArtifact } from "~/configure/artifacts/target-registry.ts";
|
|
6
|
+
import { reservedDocsTopicResourceUris } from "~/docs/mcp-resources.ts";
|
|
7
|
+
import { DOCS_BUILTIN_TOPIC_KEYS, docsEnabled } from "~/docs/resolve.ts";
|
|
8
|
+
import { resolveMcpSchemaUri } from "~/mcp/tools.ts";
|
|
9
|
+
import { reservedCommandNames, resolveCapabilities } from "~/runtime/capabilities.ts";
|
|
8
10
|
import { validateFormatValue } from "./formats.ts";
|
|
9
|
-
import { AGENT_PAIRS, MCP_KEYS, mcpServerRequiredForArtifact } from "./install/target-registry.ts";
|
|
10
|
-
import { resolveMcpSchemaUri } from "./mcp/tools.ts";
|
|
11
11
|
import {
|
|
12
12
|
type CliLeaf,
|
|
13
13
|
type CliNode,
|
|
@@ -19,24 +19,20 @@ import {
|
|
|
19
19
|
type InstallTargetSpec,
|
|
20
20
|
isCliLeaf,
|
|
21
21
|
isCliRouter,
|
|
22
|
+
isJsonLeaf,
|
|
22
23
|
} from "./types.ts";
|
|
23
24
|
|
|
24
25
|
/** Validates `docs` configuration on the program root. */
|
|
25
26
|
function validateDocsConfig(docs: import("./types.ts").CliDocsConfig): void {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
throw new CliSchemaValidationError("docs.topics must be non-empty");
|
|
29
|
-
}
|
|
27
|
+
const topics = docs.topics ?? {};
|
|
28
|
+
const keys = Object.keys(topics);
|
|
30
29
|
for (const reserved of DOCS_BUILTIN_TOPIC_KEYS) {
|
|
31
|
-
if (reserved in
|
|
30
|
+
if (reserved in topics) {
|
|
32
31
|
throw new CliSchemaValidationError(`docs.topics key '${reserved}' is reserved for the docs built-in`);
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
|
-
if (docs.defaultTopic !== undefined && !(docs.defaultTopic in docs.topics)) {
|
|
36
|
-
throw new CliSchemaValidationError(`docs.defaultTopic '${docs.defaultTopic}' is not a key in docs.topics`);
|
|
37
|
-
}
|
|
38
34
|
for (const key of keys) {
|
|
39
|
-
const text =
|
|
35
|
+
const text = topics[key]?.text;
|
|
40
36
|
if (text === undefined || text.length === 0) {
|
|
41
37
|
throw new CliSchemaValidationError(`docs.topics['${key}'].text must be non-empty`);
|
|
42
38
|
}
|
|
@@ -180,15 +176,11 @@ export function cliValidateProgram(program: CliProgram): void {
|
|
|
180
176
|
throw new CliSchemaValidationError("mcpServer requires enabled: true; omit mcpServer to disable MCP");
|
|
181
177
|
}
|
|
182
178
|
|
|
183
|
-
if (program.
|
|
184
|
-
throw new CliSchemaValidationError("
|
|
179
|
+
if (program.httpServer !== undefined && program.httpServer.enabled !== true) {
|
|
180
|
+
throw new CliSchemaValidationError("httpServer requires enabled: true; omit httpServer to disable HTTP API");
|
|
185
181
|
}
|
|
186
182
|
|
|
187
|
-
if (program
|
|
188
|
-
throw new CliSchemaValidationError("docs requires enabled: true; omit docs to disable bundled documentation");
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (program.docs?.enabled === true) {
|
|
183
|
+
if (docsEnabled(program) && program.docs?.topics !== undefined) {
|
|
192
184
|
validateDocsConfig(program.docs);
|
|
193
185
|
}
|
|
194
186
|
|
|
@@ -214,14 +206,20 @@ export function cliValidateProgram(program: CliProgram): void {
|
|
|
214
206
|
walkNode(program, program, true);
|
|
215
207
|
}
|
|
216
208
|
|
|
209
|
+
const PARAM_ROUTER_KEY = /^:[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
210
|
+
|
|
211
|
+
function isParamRouterKey(key: string): boolean {
|
|
212
|
+
return key.startsWith(":");
|
|
213
|
+
}
|
|
214
|
+
|
|
217
215
|
function walkNode(node: CliNode, program: CliProgram, isRoot: boolean): void {
|
|
218
216
|
if (!isRoot) {
|
|
219
217
|
const rogue = node as CliProgram;
|
|
220
218
|
if (rogue.mcpServer !== undefined) {
|
|
221
219
|
throw new CliSchemaValidationError(`mcpServer is only supported on the program root (not on ${node.key})`);
|
|
222
220
|
}
|
|
223
|
-
if (rogue.
|
|
224
|
-
throw new CliSchemaValidationError(`
|
|
221
|
+
if (rogue.httpServer !== undefined) {
|
|
222
|
+
throw new CliSchemaValidationError(`httpServer is only supported on the program root (not on ${node.key})`);
|
|
225
223
|
}
|
|
226
224
|
if (rogue.configure !== undefined) {
|
|
227
225
|
throw new CliSchemaValidationError(`configure is only supported on the program root (not on ${node.key})`);
|
|
@@ -238,13 +236,22 @@ function walkNode(node: CliNode, program: CliProgram, isRoot: boolean): void {
|
|
|
238
236
|
if (isRoot && node.mcpTool !== undefined) {
|
|
239
237
|
throw new CliSchemaValidationError("mcpTool is only supported on leaf commands");
|
|
240
238
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
239
|
+
if (isJsonLeaf(node)) {
|
|
240
|
+
if (node.inputSchema === undefined) {
|
|
241
|
+
throw new CliSchemaValidationError(`kind: "json" requires inputSchema on ${node.key}`);
|
|
242
|
+
}
|
|
243
|
+
if ((node.options ?? []).length > 0) {
|
|
244
|
+
throw new CliSchemaValidationError(`kind: "json" forbids options on ${node.key}`);
|
|
245
|
+
}
|
|
246
|
+
if ((node.positionals ?? []).length > 0) {
|
|
247
|
+
throw new CliSchemaValidationError(`kind: "json" forbids positionals on ${node.key}`);
|
|
248
|
+
}
|
|
245
249
|
}
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
250
|
+
const outputSchema = node.outputSchema;
|
|
251
|
+
if (
|
|
252
|
+
outputSchema !== undefined &&
|
|
253
|
+
(typeof outputSchema !== "object" || outputSchema === null || Array.isArray(outputSchema))
|
|
254
|
+
) {
|
|
248
255
|
throw new CliSchemaValidationError("outputSchema must be a JSON Schema object (not null or an array)");
|
|
249
256
|
}
|
|
250
257
|
const inputSchema = node.inputSchema;
|
|
@@ -296,11 +303,26 @@ function walkNode(node: CliNode, program: CliProgram, isRoot: boolean): void {
|
|
|
296
303
|
|
|
297
304
|
if (isCliRouter(node)) {
|
|
298
305
|
const seenNames = new Set<string>();
|
|
306
|
+
let paramRouterCount = 0;
|
|
299
307
|
for (const child of node.commands) {
|
|
300
308
|
if (seenNames.has(child.key)) {
|
|
301
309
|
throw new CliSchemaValidationError(`Duplicate command name: ${child.key}`);
|
|
302
310
|
}
|
|
303
311
|
seenNames.add(child.key);
|
|
312
|
+
if (isParamRouterKey(child.key)) {
|
|
313
|
+
if (!PARAM_ROUTER_KEY.test(child.key)) {
|
|
314
|
+
throw new CliSchemaValidationError(
|
|
315
|
+
`Param router key '${child.key}' must match :[a-zA-Z][a-zA-Z0-9_]* on '${node.key}'`,
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
if (!isCliRouter(child)) {
|
|
319
|
+
throw new CliSchemaValidationError(`Param router '${child.key}' must be a router with subcommands`);
|
|
320
|
+
}
|
|
321
|
+
paramRouterCount++;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (paramRouterCount > 1) {
|
|
325
|
+
throw new CliSchemaValidationError(`At most one param router per level on '${node.key}'`);
|
|
304
326
|
}
|
|
305
327
|
|
|
306
328
|
if (node.fallbackMode !== undefined && node.fallbackCommand === undefined) {
|
package/src/docs/builtin.ts
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { docsSkillTopicDescription } from "
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
CliFallbackMode,
|
|
5
|
-
type CliLeaf,
|
|
6
|
-
type CliOption,
|
|
7
|
-
CliOptionKind,
|
|
8
|
-
type CliProgram,
|
|
9
|
-
type CliRouter,
|
|
10
|
-
} from "../types.ts";
|
|
1
|
+
import { docsSkillTopicDescription } from "~/builtins/configure-copy.ts";
|
|
2
|
+
import { type CliLeaf, type CliOption, CliOptionKind, type CliProgram, type CliRouter } from "~/core/types.ts";
|
|
3
|
+
import { resolveCapabilities } from "~/runtime/capabilities.ts";
|
|
11
4
|
import {
|
|
12
5
|
DOCS_ROUTER_DESCRIPTION,
|
|
13
|
-
docsEffectiveDefaultTopic,
|
|
14
6
|
docsEnabled,
|
|
15
7
|
docsIncludesHttpTopic,
|
|
16
8
|
docsIncludesMcpTopic,
|
|
@@ -18,6 +10,7 @@ import {
|
|
|
18
10
|
docsTopicDescription,
|
|
19
11
|
docsUserTopicKeys,
|
|
20
12
|
printDocsTopic,
|
|
13
|
+
resolveDocsConfig,
|
|
21
14
|
} from "./resolve.ts";
|
|
22
15
|
import { saveDocsTopic } from "./save.ts";
|
|
23
16
|
|
|
@@ -54,14 +47,12 @@ function docsRouterNotes(): string {
|
|
|
54
47
|
|
|
55
48
|
/** Built-in `docs` router with bundled topic subcommands. */
|
|
56
49
|
export function cliBuiltinDocsGroup(program: CliProgram): CliRouter {
|
|
57
|
-
const docs = program
|
|
58
|
-
|
|
59
|
-
throw new Error("docs not enabled");
|
|
60
|
-
}
|
|
50
|
+
const docs = resolveDocsConfig(program);
|
|
51
|
+
const topics = docs.topics ?? {};
|
|
61
52
|
const leaves: CliLeaf[] = [];
|
|
62
53
|
|
|
63
54
|
for (const key of docsUserTopicKeys(docs)) {
|
|
64
|
-
const topic =
|
|
55
|
+
const topic = topics[key];
|
|
65
56
|
if (!topic) {
|
|
66
57
|
throw new Error(`docs topic missing: ${key}`);
|
|
67
58
|
}
|
|
@@ -82,7 +73,7 @@ export function cliBuiltinDocsGroup(program: CliProgram): CliRouter {
|
|
|
82
73
|
|
|
83
74
|
leaves.push(
|
|
84
75
|
docsLeaf(program, "cli-schema", "Print the full CLI command tree as JSON."),
|
|
85
|
-
docsLeaf(program, "
|
|
76
|
+
docsLeaf(program, "cli", "Print the full command reference as markdown."),
|
|
86
77
|
docsLeaf(program, "skill", docsSkillTopicDescription(program, resolveCapabilities(program))),
|
|
87
78
|
);
|
|
88
79
|
|
|
@@ -91,8 +82,6 @@ export function cliBuiltinDocsGroup(program: CliProgram): CliRouter {
|
|
|
91
82
|
description: docs.description ?? DOCS_ROUTER_DESCRIPTION,
|
|
92
83
|
notes: docsRouterNotes(),
|
|
93
84
|
options: [DOCS_SAVE_OPTION],
|
|
94
|
-
fallbackCommand: docsEffectiveDefaultTopic(docs),
|
|
95
|
-
fallbackMode: CliFallbackMode.MissingOnly,
|
|
96
85
|
commands: leaves,
|
|
97
86
|
};
|
|
98
87
|
}
|