@honua/mcp-server 0.1.4-beta.0 → 0.1.8-beta.0
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/README.md +30 -2
- package/dist/src/certification/admin-parity.d.ts +96 -0
- package/dist/src/certification/admin-parity.d.ts.map +1 -0
- package/dist/src/certification/admin-parity.js +235 -0
- package/dist/src/certification/target.d.ts.map +1 -1
- package/dist/src/certification/target.js +18 -26
- package/dist/src/credential-endpoint.d.ts +3 -0
- package/dist/src/credential-endpoint.d.ts.map +1 -0
- package/dist/src/credential-endpoint.js +24 -0
- package/dist/src/index.d.ts +22 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +31 -3
- package/dist/src/proxy.d.ts.map +1 -1
- package/dist/src/proxy.js +29 -14
- package/dist/src/release/zero-to-map-checkpoint.d.ts +34 -0
- package/dist/src/release/zero-to-map-checkpoint.d.ts.map +1 -0
- package/dist/src/release/zero-to-map-checkpoint.js +369 -0
- package/dist/src/release/zero-to-map-cli.d.ts +51 -0
- package/dist/src/release/zero-to-map-cli.d.ts.map +1 -0
- package/dist/src/release/zero-to-map-cli.js +880 -0
- package/dist/src/release/zero-to-map-provision.d.ts +37 -0
- package/dist/src/release/zero-to-map-provision.d.ts.map +1 -0
- package/dist/src/release/zero-to-map-provision.js +177 -0
- package/dist/src/release/zero-to-map.d.ts +296 -0
- package/dist/src/release/zero-to-map.d.ts.map +1 -0
- package/dist/src/release/zero-to-map.js +1069 -0
- package/dist/src/tools/admin-install-local.d.ts +30 -0
- package/dist/src/tools/admin-install-local.d.ts.map +1 -0
- package/dist/src/tools/admin-install-local.js +22 -0
- package/dist/src/tools/control-plane-command.d.ts +99 -0
- package/dist/src/tools/control-plane-command.d.ts.map +1 -0
- package/dist/src/tools/control-plane-command.js +180 -0
- package/dist/src/tools/docs-search.d.ts +100 -0
- package/dist/src/tools/docs-search.d.ts.map +1 -0
- package/dist/src/tools/docs-search.js +381 -0
- package/package.json +8 -3
- package/release/zero-to-map/README.md +174 -0
- package/release/zero-to-map/configs/claude-code.mcp.json +11 -0
- package/release/zero-to-map/configs/claude-desktop.json +11 -0
- package/release/zero-to-map/configs/cursor.json +11 -0
- package/release/zero-to-map/contracts/aws-ecs-provision-binding.schema.json +59 -0
- package/release/zero-to-map/contracts/checkpoint.schema.json +152 -0
- package/release/zero-to-map/contracts/console-receipt.schema.json +150 -0
- package/release/zero-to-map/contracts/esri-gp-mcp.v1.json +73 -0
- package/release/zero-to-map/fixtures/parcels.geojson +33 -0
- package/release/zero-to-map/fixtures/zoning.geojson +24 -0
- package/release/zero-to-map/journey.v1.json +1248 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type LocalInstallRuntime } from "@honua/sdk-js/local-install";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const schema: z.ZodObject<{
|
|
4
|
+
directory: z.ZodString;
|
|
5
|
+
profile: z.ZodDefault<z.ZodEnum<["quickstart", "gp-dev"]>>;
|
|
6
|
+
httpPort: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
confirm: z.ZodLiteral<true>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
directory: string;
|
|
11
|
+
profile: "quickstart" | "gp-dev";
|
|
12
|
+
httpPort: number;
|
|
13
|
+
timeoutMs: number;
|
|
14
|
+
confirm: true;
|
|
15
|
+
}, {
|
|
16
|
+
directory: string;
|
|
17
|
+
confirm: true;
|
|
18
|
+
profile?: "quickstart" | "gp-dev" | undefined;
|
|
19
|
+
httpPort?: number | undefined;
|
|
20
|
+
timeoutMs?: number | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
export type AdminInstallLocalInput = z.infer<typeof schema>;
|
|
23
|
+
export declare function execute(input: AdminInstallLocalInput, runtime?: LocalInstallRuntime): Promise<{
|
|
24
|
+
content: {
|
|
25
|
+
type: "text";
|
|
26
|
+
text: string;
|
|
27
|
+
}[];
|
|
28
|
+
structuredContent: Record<string, unknown>;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=admin-install-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-install-local.d.ts","sourceRoot":"","sources":["../../../src/tools/admin-install-local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAqB,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;EAMjB,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE5D,wBAAsB,OAAO,CAAC,KAAK,EAAE,sBAAsB,EAAE,OAAO,GAAE,mBAAwB;;;;;;GAe7F"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { installHonuaLocal } from "@honua/sdk-js/local-install";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export const schema = z.object({
|
|
4
|
+
directory: z.string().min(1).describe("Directory that will own compose.yaml, .env, and MCP configuration."),
|
|
5
|
+
profile: z.enum(["quickstart", "gp-dev"]).default("quickstart"),
|
|
6
|
+
httpPort: z.number().int().min(1).max(65535).default(8080),
|
|
7
|
+
timeoutMs: z.number().int().min(1_000).max(600_000).default(180_000),
|
|
8
|
+
confirm: z.literal(true).describe("Explicit approval to create files and start Docker containers."),
|
|
9
|
+
});
|
|
10
|
+
export async function execute(input, runtime = {}) {
|
|
11
|
+
const result = await installHonuaLocal({
|
|
12
|
+
directory: input.directory,
|
|
13
|
+
profile: input.profile,
|
|
14
|
+
httpPort: input.httpPort,
|
|
15
|
+
timeoutMs: input.timeoutMs,
|
|
16
|
+
}, runtime);
|
|
17
|
+
const structuredContent = { ...result };
|
|
18
|
+
return {
|
|
19
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
20
|
+
structuredContent,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MCP transport adapter for the shared control-plane command layer.
|
|
3
|
+
*
|
|
4
|
+
* Every tool registered here is *generated* from `HONUA_COMMANDS` in
|
|
5
|
+
* `@honua/sdk-js/control-plane`: the name, title, description, and argument
|
|
6
|
+
* schema are projections of the command's own declaration, and the handler
|
|
7
|
+
* does exactly three things — build a `HonuaCommandInvocation`, call
|
|
8
|
+
* `HonuaCommandRuntime.execute`, and render the returned receipt. There is no
|
|
9
|
+
* MCP-side sequencing, no MCP-side validation beyond the projected schema, and
|
|
10
|
+
* no MCP-side authorization: an equivalent `honua map publish` invocation, an
|
|
11
|
+
* equivalent Studio invocation, and a direct `runtime.execute(...)` call all
|
|
12
|
+
* produce the same receipt and the same `auditKey`, differing only in the
|
|
13
|
+
* recorded `transport`.
|
|
14
|
+
*
|
|
15
|
+
* ## Why the projected object is `passthrough`
|
|
16
|
+
*
|
|
17
|
+
* A Zod object strips unknown keys by default. Stripping here would mean an
|
|
18
|
+
* agent that sent `approvedBy` got a *silent success* instead of the shared
|
|
19
|
+
* typed refusal, and MCP would then be the one transport where a sealed input
|
|
20
|
+
* schema is enforced by omission rather than by the command. So the projection
|
|
21
|
+
* lets unknown keys through to the runtime, where the command's closed schema
|
|
22
|
+
* (`additionalProperties: false`) rejects them with the same `validation`
|
|
23
|
+
* `HonuaCommandError` every other transport gets.
|
|
24
|
+
*
|
|
25
|
+
* ## What an agent may not assert
|
|
26
|
+
*
|
|
27
|
+
* The tool arguments carry no identity fields and no request headers. Acting
|
|
28
|
+
* identity and tenant come from the host that constructed the runtime — a
|
|
29
|
+
* model-supplied `actor` would be an authority claim dressed as an argument.
|
|
30
|
+
* `Idempotency-Key` and `If-Match` are likewise not header inputs: `ifMatch`
|
|
31
|
+
* and `idempotencyKey` travel as invocation fields so the value on the wire is
|
|
32
|
+
* the value the receipt records.
|
|
33
|
+
*
|
|
34
|
+
* @module
|
|
35
|
+
*/
|
|
36
|
+
import { type HonuaAnyCommand, type HonuaCommandIdentity, type HonuaCommandRuntime } from "@honua/sdk-js/control-plane";
|
|
37
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
38
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
39
|
+
import { z } from "zod";
|
|
40
|
+
/** Prefix every generated command tool carries. */
|
|
41
|
+
export declare const CONTROL_PLANE_COMMAND_TOOL_PREFIX = "honua_command_";
|
|
42
|
+
/**
|
|
43
|
+
* Host wiring for the command tools.
|
|
44
|
+
*
|
|
45
|
+
* The host owns the credential (through the runtime's client) and the acting
|
|
46
|
+
* identity echo. Neither is reachable from tool arguments.
|
|
47
|
+
*/
|
|
48
|
+
export interface ControlPlaneCommandMcpHost {
|
|
49
|
+
/** Runtime built from the caller's own `HonuaClient`; never a shared admin key. */
|
|
50
|
+
readonly runtime: HonuaCommandRuntime;
|
|
51
|
+
/** Acting identity echoed onto every receipt. Host-supplied, never model-supplied. */
|
|
52
|
+
readonly identity?: HonuaCommandIdentity;
|
|
53
|
+
}
|
|
54
|
+
/** `map-package.publish` → `honua_command_map_package_publish`. */
|
|
55
|
+
export declare function controlPlaneCommandToolName(commandId: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Project a command's JSON-schema input into the tool's argument schema.
|
|
58
|
+
*
|
|
59
|
+
* `input` is the command's own declared shape; the three siblings are the
|
|
60
|
+
* invocation fields a caller is allowed to set. The outer object is `strict`
|
|
61
|
+
* so an unknown *invocation* field is an MCP-level mistake, while the inner
|
|
62
|
+
* object is `passthrough` so an unknown *input* field reaches the command's
|
|
63
|
+
* sealed schema and is refused there.
|
|
64
|
+
*/
|
|
65
|
+
export declare function controlPlaneCommandToolSchema(command: HonuaAnyCommand): z.ZodObject<{
|
|
66
|
+
input: z.ZodTypeAny;
|
|
67
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
68
|
+
idempotencyKey: z.ZodOptional<z.ZodString>;
|
|
69
|
+
ifMatch: z.ZodOptional<z.ZodString>;
|
|
70
|
+
}, "strict", z.ZodTypeAny, {
|
|
71
|
+
input?: any;
|
|
72
|
+
dryRun?: boolean | undefined;
|
|
73
|
+
idempotencyKey?: string | undefined;
|
|
74
|
+
ifMatch?: string | undefined;
|
|
75
|
+
}, {
|
|
76
|
+
input?: any;
|
|
77
|
+
dryRun?: boolean | undefined;
|
|
78
|
+
idempotencyKey?: string | undefined;
|
|
79
|
+
ifMatch?: string | undefined;
|
|
80
|
+
}>;
|
|
81
|
+
type ControlPlaneCommandToolArgs = z.infer<ReturnType<typeof controlPlaneCommandToolSchema>>;
|
|
82
|
+
/**
|
|
83
|
+
* Run one command for the MCP transport and render its receipt.
|
|
84
|
+
*
|
|
85
|
+
* A {@link HonuaCommandError} is returned as a tool error carrying the shared
|
|
86
|
+
* serialized taxonomy, not rethrown as an opaque MCP failure: an agent has to
|
|
87
|
+
* be able to tell a `validation` refusal from a `conflict` it should retry.
|
|
88
|
+
*/
|
|
89
|
+
export declare function execute(host: ControlPlaneCommandMcpHost, command: HonuaAnyCommand, args: ControlPlaneCommandToolArgs): Promise<CallToolResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Register one MCP tool per catalog command.
|
|
92
|
+
*
|
|
93
|
+
* Opt-in, exactly like the NL map-control tools: the platform-free standalone
|
|
94
|
+
* catalog stays read-only and Honua-server-free unless a host supplies a
|
|
95
|
+
* control-plane runtime.
|
|
96
|
+
*/
|
|
97
|
+
export declare function registerControlPlaneCommandTools(server: McpServer, host: ControlPlaneCommandMcpHost): void;
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=control-plane-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-plane-command.d.ts","sourceRoot":"","sources":["../../../src/tools/control-plane-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,oBAAoB,EAGzB,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mDAAmD;AACnD,eAAO,MAAM,iCAAiC,mBAAmB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CAC1C;AAED,mEAAmE;AACnE,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,eAAe;;;;;;;;;;;;;;;GAgBrE;AAED,KAAK,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC,CAAC;AAE7F;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,0BAA0B,EAChC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,cAAc,CAAC,CAsBzB;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,0BAA0B,GAAG,IAAI,CAkB1G"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MCP transport adapter for the shared control-plane command layer.
|
|
3
|
+
*
|
|
4
|
+
* Every tool registered here is *generated* from `HONUA_COMMANDS` in
|
|
5
|
+
* `@honua/sdk-js/control-plane`: the name, title, description, and argument
|
|
6
|
+
* schema are projections of the command's own declaration, and the handler
|
|
7
|
+
* does exactly three things — build a `HonuaCommandInvocation`, call
|
|
8
|
+
* `HonuaCommandRuntime.execute`, and render the returned receipt. There is no
|
|
9
|
+
* MCP-side sequencing, no MCP-side validation beyond the projected schema, and
|
|
10
|
+
* no MCP-side authorization: an equivalent `honua map publish` invocation, an
|
|
11
|
+
* equivalent Studio invocation, and a direct `runtime.execute(...)` call all
|
|
12
|
+
* produce the same receipt and the same `auditKey`, differing only in the
|
|
13
|
+
* recorded `transport`.
|
|
14
|
+
*
|
|
15
|
+
* ## Why the projected object is `passthrough`
|
|
16
|
+
*
|
|
17
|
+
* A Zod object strips unknown keys by default. Stripping here would mean an
|
|
18
|
+
* agent that sent `approvedBy` got a *silent success* instead of the shared
|
|
19
|
+
* typed refusal, and MCP would then be the one transport where a sealed input
|
|
20
|
+
* schema is enforced by omission rather than by the command. So the projection
|
|
21
|
+
* lets unknown keys through to the runtime, where the command's closed schema
|
|
22
|
+
* (`additionalProperties: false`) rejects them with the same `validation`
|
|
23
|
+
* `HonuaCommandError` every other transport gets.
|
|
24
|
+
*
|
|
25
|
+
* ## What an agent may not assert
|
|
26
|
+
*
|
|
27
|
+
* The tool arguments carry no identity fields and no request headers. Acting
|
|
28
|
+
* identity and tenant come from the host that constructed the runtime — a
|
|
29
|
+
* model-supplied `actor` would be an authority claim dressed as an argument.
|
|
30
|
+
* `Idempotency-Key` and `If-Match` are likewise not header inputs: `ifMatch`
|
|
31
|
+
* and `idempotencyKey` travel as invocation fields so the value on the wire is
|
|
32
|
+
* the value the receipt records.
|
|
33
|
+
*
|
|
34
|
+
* @module
|
|
35
|
+
*/
|
|
36
|
+
import { HONUA_COMMANDS, HonuaCommandError, } from "@honua/sdk-js/control-plane";
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
/** Prefix every generated command tool carries. */
|
|
39
|
+
export const CONTROL_PLANE_COMMAND_TOOL_PREFIX = "honua_command_";
|
|
40
|
+
/** `map-package.publish` → `honua_command_map_package_publish`. */
|
|
41
|
+
export function controlPlaneCommandToolName(commandId) {
|
|
42
|
+
return `${CONTROL_PLANE_COMMAND_TOOL_PREFIX}${commandId.replace(/[.-]/g, "_")}`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Project a command's JSON-schema input into the tool's argument schema.
|
|
46
|
+
*
|
|
47
|
+
* `input` is the command's own declared shape; the three siblings are the
|
|
48
|
+
* invocation fields a caller is allowed to set. The outer object is `strict`
|
|
49
|
+
* so an unknown *invocation* field is an MCP-level mistake, while the inner
|
|
50
|
+
* object is `passthrough` so an unknown *input* field reaches the command's
|
|
51
|
+
* sealed schema and is refused there.
|
|
52
|
+
*/
|
|
53
|
+
export function controlPlaneCommandToolSchema(command) {
|
|
54
|
+
return z
|
|
55
|
+
.object({
|
|
56
|
+
input: zodForSchema(command.inputSchema),
|
|
57
|
+
dryRun: z
|
|
58
|
+
.boolean()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe("Preview the plan without contacting the server. The command never reaches `execute`."),
|
|
61
|
+
idempotencyKey: z
|
|
62
|
+
.string()
|
|
63
|
+
.min(1)
|
|
64
|
+
.optional()
|
|
65
|
+
.describe("Explicit Idempotency-Key. Derived deterministically from the input when omitted."),
|
|
66
|
+
ifMatch: z.string().min(1).optional().describe("Optimistic-concurrency validator, sent as If-Match."),
|
|
67
|
+
})
|
|
68
|
+
.strict();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Run one command for the MCP transport and render its receipt.
|
|
72
|
+
*
|
|
73
|
+
* A {@link HonuaCommandError} is returned as a tool error carrying the shared
|
|
74
|
+
* serialized taxonomy, not rethrown as an opaque MCP failure: an agent has to
|
|
75
|
+
* be able to tell a `validation` refusal from a `conflict` it should retry.
|
|
76
|
+
*/
|
|
77
|
+
export async function execute(host, command, args) {
|
|
78
|
+
const invocation = {
|
|
79
|
+
transport: "mcp",
|
|
80
|
+
...(host.identity ? { identity: host.identity } : {}),
|
|
81
|
+
...(args.idempotencyKey ? { idempotencyKey: args.idempotencyKey } : {}),
|
|
82
|
+
...(args.ifMatch ? { ifMatch: args.ifMatch } : {}),
|
|
83
|
+
...(args.dryRun ? { dryRun: true } : {}),
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
const receipt = await host.runtime.execute(command, args.input, invocation);
|
|
87
|
+
return { content: [{ type: "text", text: JSON.stringify(receipt, null, 2) }] };
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error instanceof HonuaCommandError) {
|
|
91
|
+
return {
|
|
92
|
+
isError: true,
|
|
93
|
+
content: [
|
|
94
|
+
{ type: "text", text: JSON.stringify({ ...error.toJSON(), message: error.message }, null, 2) },
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Register one MCP tool per catalog command.
|
|
103
|
+
*
|
|
104
|
+
* Opt-in, exactly like the NL map-control tools: the platform-free standalone
|
|
105
|
+
* catalog stays read-only and Honua-server-free unless a host supplies a
|
|
106
|
+
* control-plane runtime.
|
|
107
|
+
*/
|
|
108
|
+
export function registerControlPlaneCommandTools(server, host) {
|
|
109
|
+
for (const command of Object.values(HONUA_COMMANDS)) {
|
|
110
|
+
server.registerTool(controlPlaneCommandToolName(command.id), {
|
|
111
|
+
title: command.title,
|
|
112
|
+
description: `${command.description} Runs the shared \`${command.id}\` control-plane command and returns its deterministic receipt; the receipt's auditKey matches the equivalent CLI, Studio, or direct-JS invocation.`,
|
|
113
|
+
inputSchema: controlPlaneCommandToolSchema(command),
|
|
114
|
+
annotations: {
|
|
115
|
+
readOnlyHint: command.mode === "read",
|
|
116
|
+
destructiveHint: false,
|
|
117
|
+
idempotentHint: true,
|
|
118
|
+
openWorldHint: true,
|
|
119
|
+
},
|
|
120
|
+
}, async (args) => execute(host, command, args));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// JSON Schema → Zod projection
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
function zodForSchema(schema) {
|
|
127
|
+
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
128
|
+
let base;
|
|
129
|
+
switch (type) {
|
|
130
|
+
case "string": {
|
|
131
|
+
let value = z.string();
|
|
132
|
+
if (schema.minLength !== undefined)
|
|
133
|
+
value = value.min(schema.minLength);
|
|
134
|
+
if (schema.maxLength !== undefined)
|
|
135
|
+
value = value.max(schema.maxLength);
|
|
136
|
+
base = value;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case "integer":
|
|
140
|
+
case "number": {
|
|
141
|
+
let value = z.number();
|
|
142
|
+
if (type === "integer")
|
|
143
|
+
value = value.int();
|
|
144
|
+
if (schema.minimum !== undefined)
|
|
145
|
+
value = value.min(schema.minimum);
|
|
146
|
+
if (schema.maximum !== undefined)
|
|
147
|
+
value = value.max(schema.maximum);
|
|
148
|
+
base = value;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case "boolean":
|
|
152
|
+
base = z.boolean();
|
|
153
|
+
break;
|
|
154
|
+
case "array":
|
|
155
|
+
base = z.array(schema.items ? zodForSchema(schema.items) : z.unknown());
|
|
156
|
+
break;
|
|
157
|
+
case "object":
|
|
158
|
+
base = zodForObject(schema);
|
|
159
|
+
break;
|
|
160
|
+
default:
|
|
161
|
+
base = z.unknown();
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
return schema.description ? base.describe(schema.description) : base;
|
|
165
|
+
}
|
|
166
|
+
function zodForObject(schema) {
|
|
167
|
+
const properties = schema.properties;
|
|
168
|
+
// An object with no declared properties (`options` on `import.create`) is a
|
|
169
|
+
// free-form bag the command passes through verbatim.
|
|
170
|
+
if (!properties)
|
|
171
|
+
return z.record(z.unknown());
|
|
172
|
+
const required = new Set(schema.required ?? []);
|
|
173
|
+
const shape = {};
|
|
174
|
+
for (const [name, property] of Object.entries(properties)) {
|
|
175
|
+
const value = zodForSchema(property);
|
|
176
|
+
shape[name] = required.has(name) ? value : value.optional();
|
|
177
|
+
}
|
|
178
|
+
// Passthrough is deliberate — see this module's header.
|
|
179
|
+
return z.object(shape).passthrough();
|
|
180
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const schema: z.ZodObject<{
|
|
3
|
+
query: z.ZodString;
|
|
4
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
pathPrefix: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
query: string;
|
|
8
|
+
limit?: number | undefined;
|
|
9
|
+
pathPrefix?: string | undefined;
|
|
10
|
+
}, {
|
|
11
|
+
query: string;
|
|
12
|
+
limit?: number | undefined;
|
|
13
|
+
pathPrefix?: string | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export type Input = z.infer<typeof schema>;
|
|
16
|
+
/** One document sliced out of the concatenated corpus. */
|
|
17
|
+
export interface CorpusDocument {
|
|
18
|
+
file: string;
|
|
19
|
+
title: string;
|
|
20
|
+
body: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DocsVersionCitation {
|
|
23
|
+
package: string;
|
|
24
|
+
version: string;
|
|
25
|
+
channel: string;
|
|
26
|
+
/** Whether the corpus text is trunk development documentation or a release snapshot. */
|
|
27
|
+
documentationChannel: "development";
|
|
28
|
+
policy: string;
|
|
29
|
+
versionsManifest: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Split `llms-full.txt` into its constituent documents. The generator emits
|
|
33
|
+
* `# File: <path>` as the delimiter for each concatenated document.
|
|
34
|
+
*/
|
|
35
|
+
export declare function splitCorpus(corpus: string): CorpusDocument[];
|
|
36
|
+
/**
|
|
37
|
+
* The terms a query is actually ranked and excerpted on: distinct tokens with
|
|
38
|
+
* the stopwords removed. A query made entirely of stopwords ("how do I") keeps
|
|
39
|
+
* its raw tokens rather than degrading to "no indexed document matched", so
|
|
40
|
+
* filtering can only ever improve a ranking, never empty one.
|
|
41
|
+
*/
|
|
42
|
+
export declare function queryTermsOf(query: string): string[];
|
|
43
|
+
/** Deterministic lexical score: path and heading matches outweigh body matches. */
|
|
44
|
+
export declare function scoreDocument(document: CorpusDocument, queryTerms: readonly string[]): number;
|
|
45
|
+
/** The most relevant window of a document, trimmed to a token-friendly size. */
|
|
46
|
+
export declare function excerptFor(document: CorpusDocument, queryTerms: readonly string[]): string;
|
|
47
|
+
/** Where the corpus is, and the documentation root its citations resolve against. */
|
|
48
|
+
export interface DocsCorpusLocation {
|
|
49
|
+
/** The file that is actually read — the configured override when there is one. */
|
|
50
|
+
corpusPath: string;
|
|
51
|
+
/** The directory `docs/versions.json`, `package.json`, and the manifest are read from. */
|
|
52
|
+
root: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Locate the corpus: an explicit `HONUA_DOCS_CORPUS_PATH` (the corpus file
|
|
56
|
+
* itself, or a directory holding one), otherwise the nearest ancestor directory
|
|
57
|
+
* holding `llms-full.txt`.
|
|
58
|
+
*
|
|
59
|
+
* The override names the file to read, so it is read — its basename is not
|
|
60
|
+
* assumed to be `llms-full.txt`. Discarding it and reading `<parent>/llms-full.txt`
|
|
61
|
+
* instead would throw `ENOENT` for a corpus under any other name, or silently
|
|
62
|
+
* answer from a different sibling file.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveDocsCorpus(env?: NodeJS.ProcessEnv, from?: string): DocsCorpusLocation | undefined;
|
|
65
|
+
/** The documentation root holding the corpus, or `undefined` when there is none. */
|
|
66
|
+
export declare function resolveDocsRoot(env?: NodeJS.ProcessEnv, from?: string): string | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* The release the corpus documents, from the same authoritative sources as
|
|
69
|
+
* `scripts/docs-versions.mjs`. Prefers the generated `docs/versions.json` and
|
|
70
|
+
* falls back to `package.json` + `.release-please-manifest.json`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveDocsVersion(root: string): DocsVersionCitation | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The exact commit the searched corpus bytes come from, or `undefined` when it
|
|
75
|
+
* cannot be established.
|
|
76
|
+
*
|
|
77
|
+
* `docs/documentation-versions.md` is explicit that a matching version string
|
|
78
|
+
* is not proof that development documentation describes the npm artifact, and
|
|
79
|
+
* that every built page identifies its 40-character source commit. A citation
|
|
80
|
+
* pinned to `trunk` breaks that: `trunk` moves, and the text a reader is sent
|
|
81
|
+
* to can stop being the text that was searched. So citations are pinned to the
|
|
82
|
+
* commit instead, using the same `HONUA_SOURCE_REVISION` override
|
|
83
|
+
* `scripts/build-docs-site.mjs` honours.
|
|
84
|
+
*
|
|
85
|
+
* The commit is only used when the corpus at `HEAD` is byte-identical to the
|
|
86
|
+
* corpus that was read (`git hash-object` against `HEAD:<path>`). A locally
|
|
87
|
+
* regenerated or edited `llms-full.txt` is not at any commit, and pinning it to
|
|
88
|
+
* `HEAD` would produce a citation that looks exact and is wrong. When nothing
|
|
89
|
+
* can be established — an installed package with no checkout, no `git`, a dirty
|
|
90
|
+
* corpus — the URL stays on `trunk` and the citation reports
|
|
91
|
+
* `sourceRevision: null` so the consumer can see the link is floating.
|
|
92
|
+
*/
|
|
93
|
+
export declare function resolveCorpusRevision(root: string, corpusPath: string, env?: NodeJS.ProcessEnv): string | undefined;
|
|
94
|
+
export declare function execute(_client: unknown, input: Input): Promise<{
|
|
95
|
+
content: Array<{
|
|
96
|
+
type: "text";
|
|
97
|
+
text: string;
|
|
98
|
+
}>;
|
|
99
|
+
}>;
|
|
100
|
+
//# sourceMappingURL=docs-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-search.d.ts","sourceRoot":"","sources":["../../../src/tools/docs-search.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmHxB,eAAO,MAAM,MAAM;;;;;;;;;;;;EAUjB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,oBAAoB,EAAE,aAAa,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAe5D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAIpD;AAYD,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAgB7F;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAgB1F;AAED,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAkBrH;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvG;AAeD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAoBhF;AAcD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,SAAS,CAepB;AAMD,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK;;;;;GA4D3D"}
|