@krak-stack/registry 0.1.37 → 0.1.39

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 (38) hide show
  1. package/README.md +131 -7
  2. package/dist/components/ui/app-brand.js +17 -17
  3. package/dist/components/ui/code-block.js +4 -4
  4. package/dist/components/ui/copy-button.js +2 -2
  5. package/dist/components/ui/data-table.js +56 -56
  6. package/dist/components/ui/editing-locale-switcher.js +8 -8
  7. package/dist/components/ui/effect-form.js +12 -12
  8. package/dist/components/ui/error-component.js +6 -6
  9. package/dist/components/ui/file-picker.js +2 -2
  10. package/dist/components/ui/form.js +24 -24
  11. package/dist/components/ui/icon-input.js +5 -5
  12. package/dist/components/ui/locale-switcher.js +2 -2
  13. package/dist/components/ui/search-menu.js +2 -2
  14. package/dist/components/ui/sidebar-layout.js +1 -1
  15. package/dist/components/ui/theme-switcher.js +3 -3
  16. package/dist/lib/docs.js +52 -111
  17. package/dist/lib/docs.server.js +1 -29
  18. package/dist/lib/documentation-toolkit.js +0 -28
  19. package/dist/lib/httpapi-adapter.d.ts +73 -0
  20. package/dist/lib/httpapi-adapter.js +189 -0
  21. package/dist/lib/httpapi-cli.d.ts +4 -22
  22. package/dist/lib/httpapi-cli.js +227 -533
  23. package/dist/lib/httpapi-toolkit.d.ts +15 -12
  24. package/dist/lib/httpapi-toolkit.js +175 -381
  25. package/dist/lib/query.d.ts +2 -2
  26. package/dist/lib/query.js +18 -5
  27. package/dist/lib/webfetch-toolkit.d.ts +1 -1
  28. package/dist/lib/webfetch-toolkit.js +48 -50
  29. package/dist/oxlint/anti-slop/index.js +2 -2
  30. package/dist/services/agent/client/index.js +6 -6
  31. package/dist/services/agent/index.js +3 -3
  32. package/package.json +5 -13
  33. package/dist/lib/httpapi-client.d.ts +0 -30
  34. package/dist/lib/httpapi-client.js +0 -112
  35. package/dist/lib/httpapi-helpers.d.ts +0 -101
  36. package/dist/lib/httpapi-helpers.js +0 -286
  37. package/dist/lib/httpapi-mcp.d.ts +0 -20
  38. package/dist/lib/httpapi-mcp.js +0 -477
package/README.md CHANGED
@@ -52,12 +52,9 @@ import { Pagination } from "@krak-stack/registry/pagination";
52
52
  import { AgentService } from "@krak-stack/registry/agent";
53
53
  import { AgentWidget, makeAgentAtoms } from "@krak-stack/registry/agent/client";
54
54
  import { makeAgentApiGroup } from "@krak-stack/registry/agent/schema";
55
- import {
56
- HttpApiToolkit,
57
- HttpApiToolkitLayer,
58
- } from "@krak-stack/registry/httpapi-toolkit";
59
- import { ApiClient } from "@krak-stack/registry/httpapi/client";
60
- import { HttpApiSpec } from "@krak-stack/registry/httpapi/helpers";
55
+ import { makeHttpApiToolkit } from "@krak-stack/registry/httpapi/toolkit";
56
+ import { makeHttpApiCli } from "@krak-stack/registry/httpapi/cli";
57
+ import { HttpApiAdapter } from "@krak-stack/registry/httpapi/adapter";
61
58
  import { HttpApiOtlp } from "@krak-stack/registry/opentelemetry/api";
62
59
  import { BrowserOtlp } from "@krak-stack/registry/opentelemetry/browser";
63
60
  import { createDocsSource, makeDocs } from "@krak-stack/registry/docs";
@@ -129,10 +126,137 @@ const siteSeo = createSeo({
129
126
 
130
127
  The returned object contains `meta`, `links`, and derived JSON-LD `scripts`. Website pages receive `WebSite` and `Organization` data; documentation pages can pass `type: "article"` for `Article` data. Use the lower-level `seo` function directly when a configured factory is not useful.
131
128
 
132
- HTTP API client, schema, AI tool, CLI, and MCP utilities are available under
129
+ HTTP API adapter, AI tool, and CLI utilities are available under
133
130
  the `@krak-stack/registry/httpapi/*` subpaths. Keep application-specific API
134
131
  layers, handlers, authentication, and client bindings in the application.
135
132
 
133
+ Use `@krak-stack/registry/httpapi/toolkit` for HTTP API tools.
134
+
135
+ ### HTTP API tools and MCP
136
+
137
+ Static toolkits keep definitions and implementations separate:
138
+ `DocumentationToolkit` / `DocumentationToolkitLayer({ docs, locale })` and
139
+ `WebFetchToolkit` / `WebFetchToolkitLayer(options?)`. Merge the definitions with
140
+ `Toolkit.merge`, then provide their handler layers. Web-fetch options are
141
+ validated during layer acquisition through the Effect error channel.
142
+
143
+ HTTP API tools are generated dynamically, so `makeHttpApiToolkit()` returns
144
+ matching definitions and handlers together.
145
+
146
+ CLI, toolkit, and MCP registration share `HttpApiAdapter.operations`. Each operation
147
+ contains its tool name, typed `inputSchema`, derived `inputJsonSchema`, and method
148
+ annotations. Inputs use `{ params, query, headers, body }`; only the CLI turns
149
+ terminal arguments into that shape. The generated HTTP client handles wire
150
+ encoding, and payload codecs retain their transformations.
151
+
152
+ Use `makeHttpApiToolkit(config)` to construct matching tools and handlers once:
153
+
154
+ ```ts
155
+ import { makeHttpApiToolkit } from "@krak-stack/registry/httpapi/toolkit";
156
+
157
+ const { toolkit, handlers } = yield * makeHttpApiToolkit();
158
+ const tools = yield * toolkit.pipe(Effect.provide(handlers));
159
+ ```
160
+
161
+ Provide one `HttpApiAdapter` layer through the surrounding Effect layers:
162
+
163
+ ```ts
164
+ const adapterLayer = HttpApiAdapter.layer({
165
+ api: AppApi,
166
+ baseUrl: "https://example.com",
167
+ methods: ["get"],
168
+ }).pipe(Layer.provide(FetchHttpClient.layer));
169
+ ```
170
+
171
+ This replaces the separate `HttpApiSpec` and `ApiClient` services. The catalogue,
172
+ input/success codecs, execution client, and result encoder all use the same API.
173
+ Import from `@krak-stack/registry/httpapi/adapter`, or install
174
+ `@krak-stack/httpapi-adapter` with shadcn. The old client/helper package subpaths
175
+ and client registry item have been removed.
176
+ Configuration is optional. Construct once and use the returned pair for agents
177
+ or MCP; the separate `HttpApiToolkit` and `HttpApiToolkitLayer` factories have
178
+ been removed.
179
+
180
+ For CLI commands, `makeHttpApiCli()` returns `{ command, run }`. Provide the same
181
+ `HttpApiAdapter` layer and supply the platform CLI services when
182
+ running commands. `run` derives the CLI version from the API metadata:
183
+
184
+ ```ts
185
+ const { command, run } = yield * makeHttpApiCli();
186
+ yield * run(args);
187
+ ```
188
+
189
+ `makeHttpApiCli` is the only public CLI export. `HttpApiCli`, its layer, and the
190
+ custom runners have been removed. Process arguments, platform services, error
191
+ reporting, and exit handling belong to the application's Effect runtime:
192
+
193
+ ```ts
194
+ import { NodeRuntime, NodeServices } from "@effect/platform-node";
195
+
196
+ Effect.gen(function* () {
197
+ const { run } = yield* makeHttpApiCli();
198
+ yield* run(process.argv.slice(2));
199
+ }).pipe(
200
+ Effect.provide(adapterLayer),
201
+ Effect.provide(NodeServices.layer),
202
+ NodeRuntime.runMain,
203
+ );
204
+ ```
205
+
206
+ Install `@effect/platform-node` matching your Effect version for this example;
207
+ `adapterLayer` supplies the application's `HttpApiAdapter`.
208
+
209
+ For an HTTP MCP server, register the toolkit directly with Effect. Keep the
210
+ transport and server identity in the application:
211
+
212
+ ```ts
213
+ import { Effect, Layer } from "effect";
214
+ import { McpProtocol, McpServer } from "effect/ai";
215
+ import { FetchHttpClient } from "effect/http";
216
+ import { HttpApiAdapter } from "@krak-stack/registry/httpapi/adapter";
217
+ import { makeHttpApiToolkit } from "@krak-stack/registry/httpapi/toolkit";
218
+ import { AppApi } from "@/api";
219
+
220
+ export const mcpLayer = Layer.effectDiscard(
221
+ Effect.gen(function* () {
222
+ const { toolkit, handlers } = yield* makeHttpApiToolkit({});
223
+ yield* McpServer.registerToolkit(toolkit).pipe(Effect.provide(handlers));
224
+ }),
225
+ ).pipe(
226
+ Layer.provideMerge(
227
+ McpServer.layerHttp({
228
+ name: "app",
229
+ version: "1.0.0",
230
+ path: "/api/mcp",
231
+ protocols: [McpProtocol.v2025_11_25],
232
+ }),
233
+ ),
234
+ Layer.provide(
235
+ HttpApiAdapter.layer({
236
+ api: AppApi,
237
+ baseUrl: "http://localhost:3000",
238
+ methods: ["get"],
239
+ }),
240
+ ),
241
+ Layer.provide(FetchHttpClient.layer),
242
+ );
243
+ ```
244
+
245
+ This example explicitly selects GET operations; `HttpApiAdapter` otherwise includes
246
+ all supported methods. Use `include` to narrow exposure further. Supply an
247
+ authenticated `HttpClient` instead of `FetchHttpClient.layer` when the downstream
248
+ API requires credentials. Inbound MCP authentication and authorization remain
249
+ application-owned; tool annotations are not access controls.
250
+
251
+ If intentionally exposing writes, enforce authorization or confirmation in the
252
+ application before opting out of agent approval with `needsApproval: () => false`.
253
+ Approval requirements are no longer silently disabled by an MCP adapter.
254
+
255
+ The `HttpApiMcp` service, `@krak-stack/registry/httpapi/mcp` export, and
256
+ `@krak-stack/httpapi-mcp` registry item have been removed. Replace them with the
257
+ composition above. Any Effect toolkit can be registered this way; it does not
258
+ need to originate from an HttpApi.
259
+
136
260
  Documentation consumers load and compile their application-owned MDX on the
137
261
  server, then pass the validated page records to `createDocsSource` and
138
262
  `makeDocs`:
@@ -53,38 +53,38 @@ function AppBrand(brandProps) {
53
53
  ].filter(Boolean).join(" ");
54
54
  if (isStaticBrand(brandProps)) {
55
55
  const {
56
- className: _className2,
57
- label: _label2,
58
- subtitle: _subtitle2,
59
- icon: _icon2,
60
- imageSrc: _imageSrc2,
61
- variant: _variant2,
56
+ className: _className,
57
+ label: _label,
58
+ subtitle: _subtitle,
59
+ icon: _icon,
60
+ imageSrc: _imageSrc,
61
+ variant: _variant,
62
62
  to: _to,
63
- href: _href2,
64
- ...props2
63
+ href: _href,
64
+ ...props
65
65
  } = brandProps;
66
66
  return /* @__PURE__ */ jsx("div", {
67
67
  className: brandClassName,
68
- ...props2,
68
+ ...props,
69
69
  children: content
70
70
  });
71
71
  }
72
72
  if (isAnchorBrand(brandProps)) {
73
73
  const {
74
- className: _className2,
75
- label: _label2,
76
- subtitle: _subtitle2,
77
- icon: _icon2,
78
- imageSrc: _imageSrc2,
79
- variant: _variant2,
74
+ className: _className,
75
+ label: _label,
76
+ subtitle: _subtitle,
77
+ icon: _icon,
78
+ imageSrc: _imageSrc,
79
+ variant: _variant,
80
80
  to: _to,
81
81
  href,
82
- ...props2
82
+ ...props
83
83
  } = brandProps;
84
84
  return /* @__PURE__ */ jsx("a", {
85
85
  className: brandClassName,
86
86
  href,
87
- ...props2,
87
+ ...props,
88
88
  children: content
89
89
  });
90
90
  }
@@ -65,7 +65,7 @@ function CopyButton({
65
65
  valueDescription,
66
66
  copyVariant = "default",
67
67
  locale: localeOverride,
68
- messages: messages2,
68
+ messages,
69
69
  onCopied,
70
70
  onCopyError,
71
71
  resetDelay = 1500,
@@ -77,7 +77,7 @@ function CopyButton({
77
77
  const locale = useKrakstackLocale(localeOverride);
78
78
  const [copyState, setCopyState] = useState("idle");
79
79
  const copyTimeout = useRef(undefined);
80
- const labels = copyButtonMessages(locale, messages2);
80
+ const labels = copyButtonMessages(locale, messages);
81
81
  const accessibleLabel = ariaLabel ?? (valueDescription ? `${labels.copy} ${valueDescription}` : labels.copy);
82
82
  const isLarge = copyVariant === "large";
83
83
  const defaultSize = copyVariant === "sm" ? "icon-xs" : isLarge ? "sm" : "icon-sm";
@@ -179,12 +179,12 @@ function CodeBlock({
179
179
  code,
180
180
  language = "text",
181
181
  locale: localeOverride,
182
- messages: messages3
182
+ messages
183
183
  }) {
184
184
  const locale = useKrakstackLocale2(localeOverride);
185
185
  const normalizedLanguage = language.toLowerCase() || "text";
186
186
  const highlighted = highlight(code, { lang: normalizedLanguage });
187
- const labels = codeBlockMessages(locale, messages3);
187
+ const labels = codeBlockMessages(locale, messages);
188
188
  return /* @__PURE__ */ jsxs2("div", {
189
189
  className: "not-prose bg-muted overflow-hidden rounded-md border text-[var(--th-token)]",
190
190
  "data-code-theme": true,
@@ -65,7 +65,7 @@ function CopyButton({
65
65
  valueDescription,
66
66
  copyVariant = "default",
67
67
  locale: localeOverride,
68
- messages: messages2,
68
+ messages,
69
69
  onCopied,
70
70
  onCopyError,
71
71
  resetDelay = 1500,
@@ -77,7 +77,7 @@ function CopyButton({
77
77
  const locale = useKrakstackLocale(localeOverride);
78
78
  const [copyState, setCopyState] = useState("idle");
79
79
  const copyTimeout = useRef(undefined);
80
- const labels = copyButtonMessages(locale, messages2);
80
+ const labels = copyButtonMessages(locale, messages);
81
81
  const accessibleLabel = ariaLabel ?? (valueDescription ? `${labels.copy} ${valueDescription}` : labels.copy);
82
82
  const isLarge = copyVariant === "large";
83
83
  const defaultSize = copyVariant === "sm" ? "icon-xs" : isLarge ? "sm" : "icon-sm";