@happyvertical/smrt-web 0.43.10 → 0.44.1
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/AGENTS.md +93 -1
- package/dist/chunks/intents-BUTyN7YQ.js +390 -0
- package/dist/chunks/intents-BUTyN7YQ.js.map +1 -0
- package/dist/chunks/{src-n14q6RHC.js → src-D1ZtD6Bt.js} +54 -24
- package/dist/chunks/{src-n14q6RHC.js.map → src-D1ZtD6Bt.js.map} +1 -1
- package/dist/index.d.ts +320 -0
- package/dist/index.js +3 -2
- package/dist/intents.d.ts +300 -0
- package/dist/intents.js +2 -0
- package/dist/webmcp.d.ts +244 -0
- package/dist/webmcp.js +2 -2
- package/package.json +7 -3
package/dist/webmcp.d.ts
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register one declared view intent (#2588) against a mounted registry
|
|
3
|
+
* binding, for as long as the returned disposer is not called.
|
|
4
|
+
*
|
|
5
|
+
* This is the ONLY way an intent reaches the browser, and it goes through
|
|
6
|
+
* {@link registerWebMcpBespokeTool}, so an intent inherits the same
|
|
7
|
+
* fail-closed `effects` exposure policy as a generated model tool. The
|
|
8
|
+
* intent's classification was resolved at declaration time by the shared
|
|
9
|
+
* rule, and the hints `compileViewIntentToolSpec` emits round-trip through
|
|
10
|
+
* the bespoke registrar's own re-resolution unchanged.
|
|
11
|
+
*
|
|
12
|
+
* The `execute` registered here is constructed by
|
|
13
|
+
* `compileViewIntentToolSpec` from `intent.target`. No author-supplied code
|
|
14
|
+
* runs, and the only thing it can do is dispatch one browser registry
|
|
15
|
+
* command — the runtime half of the no-REST invariant.
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerViewIntent(intent: ViewIntent, binding: ViewIntentBinding, options?: RegisterWebMcpBespokeToolOptions): WebMcpRegistrationDisposer;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Register one hand-written browser tool through the same fail-closed effect
|
|
21
|
+
* classification and `effects` exposure policy as {@link registerWebMcpTools}
|
|
22
|
+
* (#2586). A tool with no `annotations`, or with annotations that leave its
|
|
23
|
+
* effect undeclared, classifies destructive/non-idempotent/open-world — the
|
|
24
|
+
* same default `actionSemantics` gives an undeclared custom model action —
|
|
25
|
+
* and is excluded unless the policy allows `destructive`. `namespace` and
|
|
26
|
+
* `maxTools` are out of scope for a bespoke tool; see
|
|
27
|
+
* {@link RegisterWebMcpBespokeToolOptions}.
|
|
28
|
+
*
|
|
29
|
+
* @returns a disposer that deregisters the tool this call registered (a
|
|
30
|
+
* no-op double-call). On a browser without WebMCP, or when policy excludes
|
|
31
|
+
* the tool's effect, the call is a no-op and the disposer is inert.
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerWebMcpBespokeTool(spec: WebMcpBespokeToolSpec, options?: RegisterWebMcpBespokeToolOptions): WebMcpRegistrationDisposer;
|
|
34
|
+
|
|
35
|
+
export declare interface RegisterWebMcpBespokeToolOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Allowed effects. Omitted means read-only exposure — the same default as
|
|
38
|
+
* {@link registerWebMcpTools}. `namespace` and `maxTools` deliberately do
|
|
39
|
+
* not apply to a bespoke tool (#2586): a component author already chose a
|
|
40
|
+
* stable name, and counting one intent against a shared budget could make
|
|
41
|
+
* an unrelated generated tool set fail to register.
|
|
42
|
+
*/
|
|
43
|
+
effects?: readonly WebMcpToolEffect[];
|
|
44
|
+
}
|
|
45
|
+
|
|
1
46
|
/**
|
|
2
47
|
* Register every collection's generated tool descriptors with WebMCP.
|
|
3
48
|
*
|
|
@@ -170,6 +215,181 @@ declare interface SmrtWebToolRouteDescriptor {
|
|
|
170
215
|
optionsBag?: boolean;
|
|
171
216
|
}
|
|
172
217
|
|
|
218
|
+
/**
|
|
219
|
+
* A validated, frozen intent.
|
|
220
|
+
*
|
|
221
|
+
* `kind: 'intent'` and `id` are the exported identity a `smrt-playbooks`
|
|
222
|
+
* step reference (`{ kind: 'intent', id }`) names, and this object is
|
|
223
|
+
* directly assignable to that package's `PlaybookIntentRecord` seam —
|
|
224
|
+
* `{ id, classification, planes }` — so {@link resolveViewIntent} can be
|
|
225
|
+
* passed as its `intents` resolver unchanged.
|
|
226
|
+
*/
|
|
227
|
+
declare interface ViewIntent {
|
|
228
|
+
readonly kind: 'intent';
|
|
229
|
+
readonly id: string;
|
|
230
|
+
readonly description: string;
|
|
231
|
+
readonly inputSchema: Record<string, unknown>;
|
|
232
|
+
/** Resolved through the shared fail-closed rule at declaration time. */
|
|
233
|
+
readonly classification: WebMcpCapabilityClassification;
|
|
234
|
+
readonly target: ViewIntentTarget;
|
|
235
|
+
/**
|
|
236
|
+
* An intent moves mounted browser state, so it is browser-valid only. A
|
|
237
|
+
* server-side agent reaches one through the #2446 command/ack bridge, which
|
|
238
|
+
* a playbook must declare explicitly.
|
|
239
|
+
*/
|
|
240
|
+
readonly planes: readonly ['browser'];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** The mounted identity a binding supplies for an intent's lifetime. */
|
|
244
|
+
declare type ViewIntentBinding = {
|
|
245
|
+
registry: 'control';
|
|
246
|
+
registryPort: ViewIntentControlRegistryPort;
|
|
247
|
+
identity: ViewIntentControlIdentity;
|
|
248
|
+
} | {
|
|
249
|
+
registry: 'dataSurface';
|
|
250
|
+
registryPort: ViewIntentDataSurfaceRegistryPort;
|
|
251
|
+
identity: ViewIntentDataSurfaceIdentity;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Control commands a view intent may dispatch. Structurally mirrors
|
|
256
|
+
* `ControlCommandAction` in `@happyvertical/smrt-ui/forms`; this package
|
|
257
|
+
* cannot import that one (see AGENTS.md "No inter-smrt dependencies").
|
|
258
|
+
*/
|
|
259
|
+
declare type ViewIntentControlAction = 'focus' | 'reveal' | 'highlight' | 'explain' | 'validate' | 'stage' | 'apply' | 'discard' | 'clear' | 'undo';
|
|
260
|
+
|
|
261
|
+
/** A mounted control's full registry key, subject included. */
|
|
262
|
+
declare interface ViewIntentControlIdentity {
|
|
263
|
+
formId: string;
|
|
264
|
+
controlId: string;
|
|
265
|
+
subject?: ViewIntentSubject;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* The `ControlInteractionRegistry` surface an intent uses. Declared
|
|
270
|
+
* structurally so this package takes no dependency on
|
|
271
|
+
* `@happyvertical/smrt-ui`; the real registry satisfies it.
|
|
272
|
+
*/
|
|
273
|
+
declare interface ViewIntentControlRegistryPort {
|
|
274
|
+
execute(command: {
|
|
275
|
+
action: ViewIntentControlAction;
|
|
276
|
+
identity: ViewIntentControlIdentity;
|
|
277
|
+
value?: unknown;
|
|
278
|
+
durationMs?: number;
|
|
279
|
+
revision?: number;
|
|
280
|
+
}, context?: {
|
|
281
|
+
source: 'agent';
|
|
282
|
+
}): Promise<{
|
|
283
|
+
ok: boolean;
|
|
284
|
+
reason?: string;
|
|
285
|
+
}>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* A control-registry target: the intent dispatches exactly one
|
|
290
|
+
* `ControlInteractionRegistry` command against a mounted control.
|
|
291
|
+
*
|
|
292
|
+
* `formId`/`controlId` are the statically declared half of the identity. A
|
|
293
|
+
* binding supplies the mounted identity and must MATCH anything declared
|
|
294
|
+
* here — a declaration is authority over a binding, never the other way
|
|
295
|
+
* round.
|
|
296
|
+
*/
|
|
297
|
+
declare interface ViewIntentControlTarget {
|
|
298
|
+
registry: 'control';
|
|
299
|
+
action: ViewIntentControlAction;
|
|
300
|
+
formId?: string;
|
|
301
|
+
controlId?: string;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** A mounted data surface's full registry key, subject included. */
|
|
305
|
+
declare interface ViewIntentDataSurfaceIdentity {
|
|
306
|
+
surfaceId: string;
|
|
307
|
+
kind: ViewIntentDataSurfaceKind;
|
|
308
|
+
subject?: ViewIntentSubject;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Mirrors `DataSurfaceIdentity['kind']` in `@happyvertical/smrt-ui/data`. */
|
|
312
|
+
declare type ViewIntentDataSurfaceKind = 'table' | 'list' | 'report' | 'custom';
|
|
313
|
+
|
|
314
|
+
/** The `DataSurfaceRegistry` surface an intent uses. */
|
|
315
|
+
declare interface ViewIntentDataSurfaceRegistryPort {
|
|
316
|
+
inspect(identity: ViewIntentDataSurfaceIdentity): {
|
|
317
|
+
revision: number;
|
|
318
|
+
} | undefined;
|
|
319
|
+
execute(command: {
|
|
320
|
+
version: 1;
|
|
321
|
+
commandId: string;
|
|
322
|
+
identity: ViewIntentDataSurfaceIdentity;
|
|
323
|
+
expectedRevision: number;
|
|
324
|
+
controlId: string;
|
|
325
|
+
payload?: unknown;
|
|
326
|
+
}): Promise<{
|
|
327
|
+
ok: boolean;
|
|
328
|
+
revision?: number;
|
|
329
|
+
reason?: string;
|
|
330
|
+
}>;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* A data-surface target: the intent dispatches one
|
|
335
|
+
* `DataSurfaceVisibleCommand` — a browser-visible state transition, never a
|
|
336
|
+
* server-side query or mutation.
|
|
337
|
+
*/
|
|
338
|
+
declare interface ViewIntentDataSurfaceTarget {
|
|
339
|
+
registry: 'dataSurface';
|
|
340
|
+
/** The visible-command `controlId` the mounted surface implements. */
|
|
341
|
+
controlId: string;
|
|
342
|
+
surfaceId?: string;
|
|
343
|
+
kind?: ViewIntentDataSurfaceKind;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* The optional record a registry identity is qualified by. Rich forms use it
|
|
348
|
+
* to tell apart controls that share a `formId`/`controlId` across records.
|
|
349
|
+
* Structurally mirrors `ControlIdentity['subject']` /
|
|
350
|
+
* `DataSurfaceIdentity['subject']` in `@happyvertical/smrt-ui`.
|
|
351
|
+
*/
|
|
352
|
+
declare interface ViewIntentSubject {
|
|
353
|
+
type: string;
|
|
354
|
+
id: string;
|
|
355
|
+
label?: string;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
declare type ViewIntentTarget = ViewIntentControlTarget | ViewIntentDataSurfaceTarget;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* A hand-written browser tool from application code — not generated from a
|
|
362
|
+
* `@smrt()` model. Structurally identical to the WebMCP `registerTool` input;
|
|
363
|
+
* kept as a separate type so this framework-agnostic module never depends on
|
|
364
|
+
* a UI layer's tool-spec type.
|
|
365
|
+
*/
|
|
366
|
+
export declare interface WebMcpBespokeToolSpec {
|
|
367
|
+
name: string;
|
|
368
|
+
description: string;
|
|
369
|
+
inputSchema: Record<string, unknown>;
|
|
370
|
+
annotations?: {
|
|
371
|
+
readOnlyHint?: boolean;
|
|
372
|
+
destructiveHint?: boolean;
|
|
373
|
+
idempotentHint?: boolean;
|
|
374
|
+
openWorldHint?: boolean;
|
|
375
|
+
untrustedContentHint?: boolean;
|
|
376
|
+
};
|
|
377
|
+
execute: (args: Record<string, unknown>) => string | Promise<string>;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** A fully resolved classification. */
|
|
381
|
+
declare interface WebMcpCapabilityClassification {
|
|
382
|
+
effect: WebMcpToolEffect;
|
|
383
|
+
/**
|
|
384
|
+
* Derived, never declared: every non-read effect is annotated destructive
|
|
385
|
+
* to the browser, so a `write` capability cannot claim the MCP
|
|
386
|
+
* additive-only guarantee.
|
|
387
|
+
*/
|
|
388
|
+
destructive: boolean;
|
|
389
|
+
idempotent: boolean;
|
|
390
|
+
openWorld: boolean;
|
|
391
|
+
}
|
|
392
|
+
|
|
173
393
|
export declare interface WebMcpExposurePolicy {
|
|
174
394
|
/** Allowed effects. Omitted means read-only exposure. */
|
|
175
395
|
effects?: readonly WebMcpToolEffect[];
|
|
@@ -211,6 +431,30 @@ declare interface WebMcpToolDefinition extends WebToolDescriptor {
|
|
|
211
431
|
relationships: SmrtWebRelationship[];
|
|
212
432
|
}
|
|
213
433
|
|
|
434
|
+
/**
|
|
435
|
+
* The one capability classification rule this package applies, extracted so
|
|
436
|
+
* every declaration site in smrt-web shares a single implementation (#2587,
|
|
437
|
+
* #2588).
|
|
438
|
+
*
|
|
439
|
+
* Two sites consume it today: `webmcp.ts` (canonical definitions trusted
|
|
440
|
+
* through it directly, and its legacy CRUD switch's fail-closed default
|
|
441
|
+
* branch) and `intents.ts` (a declared view intent, which is never a CRUD
|
|
442
|
+
* verb and so resolves through the declaration rule alone). Keeping the rule
|
|
443
|
+
* here rather than private to `webmcp.ts` is what lets the intent path be a
|
|
444
|
+
* dependency-free module that never pulls the client-data engine.
|
|
445
|
+
*
|
|
446
|
+
* This module structurally mirrors `CapabilityEffect` / `CapabilityDeclaration`
|
|
447
|
+
* / `CapabilityClassification` in `@happyvertical/smrt-types` rather than
|
|
448
|
+
* importing them — this package's dependency-DAG guardrails keep it free of
|
|
449
|
+
* every `@happyvertical/*` dependency (see AGENTS.md "No inter-smrt
|
|
450
|
+
* dependencies"), the same reason `data-query.ts` mirrors that package's
|
|
451
|
+
* bounded query envelope structurally instead of importing it.
|
|
452
|
+
*/
|
|
453
|
+
/**
|
|
454
|
+
* Browser/agent-visible effect classification for a capability. `'read'`
|
|
455
|
+
* never mutates; `'write'` mutates within the application; `'destructive'`
|
|
456
|
+
* may remove or irreversibly change data.
|
|
457
|
+
*/
|
|
214
458
|
export declare type WebMcpToolEffect = 'read' | 'write' | 'destructive';
|
|
215
459
|
|
|
216
460
|
/**
|
package/dist/webmcp.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { registerWebMcpTools };
|
|
1
|
+
import { h as registerWebMcpTools, m as registerWebMcpBespokeTool, p as registerViewIntent } from "./chunks/src-D1ZtD6Bt.js";
|
|
2
|
+
export { registerViewIntent, registerWebMcpBespokeTool, registerWebMcpTools };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.1",
|
|
4
4
|
"description": "SMRT browser client data runtime: typed collection factory wrapping the client-data engine over generated REST clients",
|
|
5
5
|
"author": "HappyVertical",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"./webmcp": {
|
|
21
21
|
"types": "./dist/webmcp.d.ts",
|
|
22
22
|
"import": "./dist/webmcp.js"
|
|
23
|
+
},
|
|
24
|
+
"./intents": {
|
|
25
|
+
"types": "./dist/intents.d.ts",
|
|
26
|
+
"import": "./dist/intents.js"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"dependencies": {
|
|
@@ -33,8 +37,8 @@
|
|
|
33
37
|
"typescript": "5.9.3",
|
|
34
38
|
"vite": "8.1.4",
|
|
35
39
|
"vitest": "4.1.10",
|
|
36
|
-
"@happyvertical/smrt-core": "0.
|
|
37
|
-
"@happyvertical/smrt-scanner": "0.
|
|
40
|
+
"@happyvertical/smrt-core": "0.44.1",
|
|
41
|
+
"@happyvertical/smrt-scanner": "0.44.1"
|
|
38
42
|
},
|
|
39
43
|
"publishConfig": {
|
|
40
44
|
"registry": "https://registry.npmjs.org",
|