@happyvertical/smrt-types 0.43.9 → 0.44.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/AGENTS.md CHANGED
@@ -12,6 +12,7 @@ Shared TypeScript type definitions. Prevents circular dependencies between packa
12
12
  | `identity.ts` | `User`, `Tenant`, `Role`, `Membership`, `SmrtEntityFields` — cross-package identity data contracts (runtime classes live in smrt-users, which `implements` these) |
13
13
  | `knowledge.ts` | Additive schema-version-1 domain knowledge contracts shared by core generation and development tooling |
14
14
  | `data-query.ts` | Serializable bounded query request/result envelope, allowlisted schema, filters, paging, totals, freshness, and facets |
15
+ | `capability.ts` | `CapabilityEffect`, `CapabilityClassification`, `CapabilityDeclaration` — the one classification contract (effect/idempotent/openWorld + fail-closed default) shared by generated model tools, view intents, and playbook steps (#2587) |
15
16
 
16
17
  ## Rules
17
18
 
package/dist/index.d.ts CHANGED
@@ -137,6 +137,69 @@ export declare interface AiUsageSummaryOptions extends Omit<AiUsageListOptions,
137
137
  groupBy?: AiUsageGroupBy;
138
138
  }
139
139
 
140
+ /**
141
+ * Fully resolved capability classification for one declared action.
142
+ *
143
+ * **Fail-closed rule**: an undeclared capability resolves to
144
+ * `{ effect: 'destructive', idempotent: false, openWorld: true }` — the most
145
+ * restrictive exposure a policy can select. Every classifier in the mirror
146
+ * (core's generator, smrt-web's legacy fallback, and any future declaration
147
+ * site) MUST apply this exact default rather than inventing its own.
148
+ *
149
+ * **CRUD is fixed** and never overridden by a declaration:
150
+ * - `list` / `get` → `{ effect: 'read', idempotent: true, openWorld: false }`
151
+ * - `create` → `{ effect: 'write', idempotent: false, openWorld: false }`
152
+ * - `update` → `{ effect: 'write', idempotent: true, openWorld: false }`
153
+ * - `delete` → `{ effect: 'destructive', idempotent: true, openWorld: false }`
154
+ *
155
+ * Anything else (a custom action, a view intent, a playbook step) resolves
156
+ * through an explicit {@link CapabilityDeclaration}, defaulted per-field by
157
+ * the fail-closed rule above.
158
+ */
159
+ export declare interface CapabilityClassification {
160
+ effect: CapabilityEffect;
161
+ /** Whether repeating the action with the same arguments is safe. */
162
+ idempotent: boolean;
163
+ /** Whether the action may interact outside the SMRT application. */
164
+ openWorld: boolean;
165
+ }
166
+
167
+ /**
168
+ * An author-supplied, partial classification. Any field a declaration omits
169
+ * resolves through the fail-closed rule documented on
170
+ * {@link CapabilityClassification}, never through a CRUD- or name-based guess.
171
+ */
172
+ export declare type CapabilityDeclaration = Partial<CapabilityClassification>;
173
+
174
+ /**
175
+ * One capability classification contract shared by every WebMCP declaration
176
+ * site (#2587). This module intentionally has no runtime code.
177
+ *
178
+ * Core classifies every canonical model tool at build time
179
+ * (`packages/core/src/generators/tool-schema.ts`) and emits the resolved
180
+ * `effect` / `idempotent` / `openWorld` on each `webMcpToolDefinitions` entry.
181
+ * smrt-web's browser registrar trusts that emitted metadata for canonical
182
+ * definitions instead of recomputing it, and keeps its own CRUD switch only
183
+ * as the fail-closed fallback for legacy definitions that carry no metadata.
184
+ * View intents (#2588) classify by this same contract where they are
185
+ * declared; playbook steps (#2589) inherit classification from the model
186
+ * operation they reference and never classify anything themselves.
187
+ *
188
+ * `smrt-web` cannot import this package — its dependency-DAG guardrails keep
189
+ * it free of every `@happyvertical/*` dependency (see its AGENTS.md) — so its
190
+ * `WebMcpToolEffect` mirrors {@link CapabilityEffect} structurally rather than
191
+ * importing it, the same way `data-query.ts` mirrors this package's bounded
192
+ * query envelope there. `smrt-core`'s `ToolEffect` (`src/registry/types.ts`)
193
+ * DOES alias {@link CapabilityEffect} directly, since core already depends on
194
+ * this package.
195
+ */
196
+ /**
197
+ * Browser/agent-visible effect classification for a generated capability.
198
+ * `'read'` never mutates; `'write'` mutates within the application;
199
+ * `'destructive'` may remove or irreversibly change data.
200
+ */
201
+ export declare type CapabilityEffect = 'read' | 'write' | 'destructive';
202
+
140
203
  /** One typed predicate. `in` and `notIn` require a non-empty value array. */
141
204
  export declare interface DataQueryCondition {
142
205
  kind: 'condition';
@@ -328,6 +391,38 @@ export declare type DataQueryTotal = {
328
391
  reason?: string;
329
392
  };
330
393
 
394
+ /**
395
+ * The package's declared agent-addressable surface beyond its generated model
396
+ * tools (#2591).
397
+ *
398
+ * Omitted entirely when a package declares no intents, playbooks, or
399
+ * diagnostics, so an artifact for a package with none stays byte-identical to
400
+ * what it emitted before this field existed.
401
+ */
402
+ export declare interface DomainKnowledgeAgentSurface {
403
+ intents: DomainKnowledgeViewIntent[];
404
+ playbooks: DomainKnowledgePlaybook[];
405
+ diagnostics: DomainKnowledgeAgentSurfaceDiagnostic[];
406
+ }
407
+
408
+ /**
409
+ * A declaration the scanner recognized but could not emit.
410
+ *
411
+ * Recorded rather than dropped: the whole point of emitting the agent surface
412
+ * is that "what can an agent do here" has one answer, and an invisible
413
+ * declaration would quietly make that answer wrong. Every message names
414
+ * `useWebMcpTool`, the escape hatch for a genuinely computed tool set.
415
+ */
416
+ export declare interface DomainKnowledgeAgentSurfaceDiagnostic {
417
+ code: string;
418
+ helper: 'defineIntent' | 'definePlaybook';
419
+ message: string;
420
+ /** Declaring module, relative to the package root, in POSIX form. */
421
+ sourceFile: string;
422
+ line?: number;
423
+ column?: number;
424
+ }
425
+
331
426
  /** Per-object configuration controlling domain-knowledge generation and exposure. */
332
427
  export declare interface DomainKnowledgeConfig {
333
428
  enabled?: boolean;
@@ -428,6 +523,15 @@ export declare interface DomainKnowledgeManifest {
428
523
  agentDoc?: string;
429
524
  /** Sibling module docs linked from `AGENTS.md`; omitted when the package links none. */
430
525
  moduleDocs?: DomainKnowledgeModuleDoc[];
526
+ /**
527
+ * Declared view intents and playbooks (#2591). Omitted when the package
528
+ * declares none, so this field is additive to schema version 1.
529
+ *
530
+ * This is deliberately a knowledge-artifact field and not a runtime-manifest
531
+ * field: `manifest.json` stays runtime-focused, and the agent-addressable
532
+ * surface is an agent/developer contract.
533
+ */
534
+ agentSurface?: DomainKnowledgeAgentSurface;
431
535
  }
432
536
 
433
537
  /** Additive structured signature; `methods: string[]` remains the compatibility surface. */
@@ -479,6 +583,31 @@ export declare interface DomainKnowledgeObject {
479
583
  risks: string[];
480
584
  }
481
585
 
586
+ /** A registered playbook (#2589) as emitted into the knowledge artifact (#2591). */
587
+ export declare interface DomainKnowledgePlaybook {
588
+ key: string;
589
+ title: string;
590
+ description: string;
591
+ steps: DomainKnowledgePlaybookStep[];
592
+ planes: Array<'browser' | 'server'>;
593
+ /** False when `planes` was derived from the step kinds rather than declared. */
594
+ planesDeclared: boolean;
595
+ onStepFailure: 'abort' | 'continue';
596
+ enabled: boolean;
597
+ /** Declaring module, relative to the package root, in POSIX form. */
598
+ sourceFile: string;
599
+ }
600
+
601
+ /** One step of an emitted playbook. Steps never nest another playbook. */
602
+ export declare type DomainKnowledgePlaybookStep = {
603
+ kind: 'operation';
604
+ model: string;
605
+ action: string;
606
+ } | {
607
+ kind: 'intent';
608
+ id: string;
609
+ };
610
+
482
611
  /** A single generated surface (one api/cli/mcp/ai operation) exposed by an object. */
483
612
  export declare interface DomainKnowledgeSurface {
484
613
  kind: DomainKnowledgeSurfaceKind;
@@ -500,6 +629,33 @@ export declare interface DomainKnowledgeTenant {
500
629
  field?: string;
501
630
  }
502
631
 
632
+ /**
633
+ * A declared view intent (#2588) as emitted into the knowledge artifact (#2591).
634
+ *
635
+ * `id` is the entry's identity everywhere: in this artifact, in a playbook step
636
+ * (`{ kind: 'intent', id }`), and in `smrt doctor`'s surface report. It is
637
+ * declared, never derived from a namespace, a generated tool name, or a route,
638
+ * so it survives every rename those could undergo.
639
+ */
640
+ export declare interface DomainKnowledgeViewIntent {
641
+ id: string;
642
+ description: string;
643
+ /** Resolved through the #2587 fail-closed rule at declaration time. */
644
+ capability: CapabilityClassification;
645
+ /** The browser registry this intent compiles into, and what it addresses. */
646
+ target: Record<string, unknown>;
647
+ hasInputSchema: boolean;
648
+ /**
649
+ * Always exactly `['browser']`. An intent moves mounted browser state; a
650
+ * server-side agent reaches one only through the #2446 command/ack bridge,
651
+ * which the referencing playbook declares. Typed as the literal tuple so a
652
+ * consumer cannot read the contract as wider than it is.
653
+ */
654
+ planes: ['browser'];
655
+ /** Declaring module, relative to the package root, in POSIX form. */
656
+ sourceFile: string;
657
+ }
658
+
503
659
  /** User↔Tenant↔Role junction. Runtime class: `@happyvertical/smrt-users:Membership`. */
504
660
  export declare interface Membership extends SmrtEntityFields {
505
661
  userId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-types",
3
- "version": "0.43.9",
3
+ "version": "0.44.0",
4
4
  "description": "Shared type definitions for the HAVE SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",