@happyvertical/smrt-agents 0.30.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.
Files changed (94) hide show
  1. package/AGENTS.md +96 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +139 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/agent.d.ts +545 -0
  8. package/dist/agent.d.ts.map +1 -0
  9. package/dist/ai-config.d.ts +27 -0
  10. package/dist/ai-config.d.ts.map +1 -0
  11. package/dist/chunks/config-BYbOxt24.js +179 -0
  12. package/dist/chunks/config-BYbOxt24.js.map +1 -0
  13. package/dist/chunks/manifest-utils-DLXfTOq0.js +69 -0
  14. package/dist/chunks/manifest-utils-DLXfTOq0.js.map +1 -0
  15. package/dist/config.d.ts +117 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/identity.d.ts +19 -0
  18. package/dist/identity.d.ts.map +1 -0
  19. package/dist/index.d.ts +13 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +1477 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/interests.d.ts +291 -0
  24. package/dist/interests.d.ts.map +1 -0
  25. package/dist/manifest.json +2012 -0
  26. package/dist/playground.d.ts +2 -0
  27. package/dist/playground.d.ts.map +1 -0
  28. package/dist/playground.js +156 -0
  29. package/dist/playground.js.map +1 -0
  30. package/dist/schedule.d.ts +168 -0
  31. package/dist/schedule.d.ts.map +1 -0
  32. package/dist/server/action-types.d.ts +65 -0
  33. package/dist/server/action-types.d.ts.map +1 -0
  34. package/dist/server/action-types.js +2 -0
  35. package/dist/server/action-types.js.map +1 -0
  36. package/dist/server/api-routes.d.ts +57 -0
  37. package/dist/server/api-routes.d.ts.map +1 -0
  38. package/dist/server/config-loader.d.ts +17 -0
  39. package/dist/server/config-loader.d.ts.map +1 -0
  40. package/dist/server/index.d.ts +34 -0
  41. package/dist/server/index.d.ts.map +1 -0
  42. package/dist/server/manifest-utils.d.ts +63 -0
  43. package/dist/server/manifest-utils.d.ts.map +1 -0
  44. package/dist/server/serialization.d.ts +58 -0
  45. package/dist/server/serialization.d.ts.map +1 -0
  46. package/dist/server.js +105 -0
  47. package/dist/server.js.map +1 -0
  48. package/dist/smrt-knowledge.json +983 -0
  49. package/dist/summary-article.d.ts +30 -0
  50. package/dist/summary-article.d.ts.map +1 -0
  51. package/dist/summary-article.js +2 -0
  52. package/dist/summary-article.js.map +1 -0
  53. package/dist/svelte/components/AgentDashboard.svelte +250 -0
  54. package/dist/svelte/components/AgentDashboard.svelte.d.ts +21 -0
  55. package/dist/svelte/components/AgentDashboard.svelte.d.ts.map +1 -0
  56. package/dist/svelte/components/AgentRunHistory.svelte +225 -0
  57. package/dist/svelte/components/AgentRunHistory.svelte.d.ts +16 -0
  58. package/dist/svelte/components/AgentRunHistory.svelte.d.ts.map +1 -0
  59. package/dist/svelte/components/AgentScheduleForm.svelte +381 -0
  60. package/dist/svelte/components/AgentScheduleForm.svelte.d.ts +19 -0
  61. package/dist/svelte/components/AgentScheduleForm.svelte.d.ts.map +1 -0
  62. package/dist/svelte/components/AgentScheduleList.svelte +370 -0
  63. package/dist/svelte/components/AgentScheduleList.svelte.d.ts +24 -0
  64. package/dist/svelte/components/AgentScheduleList.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/ScheduleStatusBadge.svelte +23 -0
  66. package/dist/svelte/components/ScheduleStatusBadge.svelte.d.ts +9 -0
  67. package/dist/svelte/components/ScheduleStatusBadge.svelte.d.ts.map +1 -0
  68. package/dist/svelte/i18n.d.ts +33 -0
  69. package/dist/svelte/i18n.d.ts.map +1 -0
  70. package/dist/svelte/i18n.js +37 -0
  71. package/dist/svelte/index.d.ts +23 -0
  72. package/dist/svelte/index.d.ts.map +1 -0
  73. package/dist/svelte/index.js +26 -0
  74. package/dist/svelte/playground.d.ts +196 -0
  75. package/dist/svelte/playground.d.ts.map +1 -0
  76. package/dist/svelte/playground.js +151 -0
  77. package/dist/svelte/types.d.ts +155 -0
  78. package/dist/svelte/types.d.ts.map +1 -0
  79. package/dist/svelte/types.js +116 -0
  80. package/dist/tenant-agent.d.ts +106 -0
  81. package/dist/tenant-agent.d.ts.map +1 -0
  82. package/dist/types.d.ts +5 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +2 -0
  85. package/dist/types.js.map +1 -0
  86. package/dist/ui.d.ts +298 -0
  87. package/dist/ui.d.ts.map +1 -0
  88. package/dist/ui.js +133 -0
  89. package/dist/ui.js.map +1 -0
  90. package/dist/vite-plugin.d.ts +61 -0
  91. package/dist/vite-plugin.d.ts.map +1 -0
  92. package/dist/vite-plugin.js +173 -0
  93. package/dist/vite-plugin.js.map +1 -0
  94. package/package.json +104 -0
@@ -0,0 +1,106 @@
1
+ import { SmrtCollection, SmrtObject } from '@happyvertical/smrt-core';
2
+ import { AgentManifestInfo } from './ui.js';
3
+ /**
4
+ * Status of a tenant-agent binding
5
+ */
6
+ export type TenantAgentStatus = 'active' | 'disabled';
7
+ /**
8
+ * Result of resolving agent availability for a tenant
9
+ */
10
+ export interface ResolvedAgentAvailability {
11
+ /** Human-readable agent class name (e.g., 'Praeco') */
12
+ agentClass: string;
13
+ /** Canonical agent type (qualified name when available) */
14
+ agentType: string;
15
+ /** Resolved status */
16
+ status: TenantAgentStatus;
17
+ /** How this was resolved */
18
+ source: 'explicit' | 'inherited';
19
+ /** Which tenant the binding came from */
20
+ sourceTenantId: string;
21
+ /** Merged permissions (manifest defaults overridden by explicit grants/revokes) */
22
+ permissions: Record<string, boolean>;
23
+ /** The agent instance ID (row in agents table), if one exists */
24
+ agentId?: string;
25
+ /** Agent manifest from the build (if available) */
26
+ manifest?: AgentManifestInfo;
27
+ /** Tenant-level config overrides */
28
+ config?: Record<string, any>;
29
+ }
30
+ /**
31
+ * TenantAgent SmrtObject — junction between tenants and agents
32
+ *
33
+ * Each row represents an explicit binding of an agent class to a tenant.
34
+ * - Presence means explicit override (active or disabled)
35
+ * - Absence means "check parent tenant" (inheritance)
36
+ *
37
+ * Permission overrides:
38
+ * - null/missing key → use defaultGranted from manifest
39
+ * - true → explicitly granted
40
+ * - false → explicitly revoked
41
+ */
42
+ export declare class TenantAgent extends SmrtObject {
43
+ tenantId: string;
44
+ /** Canonical agent type (qualified name when available) */
45
+ agentClass: string;
46
+ /** Status of the agent for this tenant */
47
+ status: TenantAgentStatus;
48
+ /** Explicit permission overrides (JSON). null = use manifest defaults */
49
+ permissions: Record<string, boolean> | null;
50
+ /**
51
+ * Tenant-level agent config overrides (JSON).
52
+ *
53
+ * Sensitive (S5 #1398): like {@link AgentConfig.configData} and
54
+ * {@link AgentSchedule.agentConfig} (both marked sensitive in #1540), these
55
+ * per-tenant override blobs routinely carry API keys/credentials. Exclude
56
+ * them from generated API/MCP responses and reject them as a `where` filter
57
+ * key. Server-side helpers (e.g. `serializeResolvedAgent`) still read the
58
+ * property directly, so the admin dashboard flow is unaffected.
59
+ */
60
+ config: Record<string, any> | null;
61
+ }
62
+ /**
63
+ * Collection for managing tenant-agent bindings
64
+ */
65
+ export declare class TenantAgentCollection extends SmrtCollection<TenantAgent> {
66
+ static readonly _itemClass: typeof TenantAgent;
67
+ /**
68
+ * Resolve agent availability for a tenant, walking up the hierarchy.
69
+ *
70
+ * Algorithm:
71
+ * 1. Load explicit entries for this tenant
72
+ * 2. Build result map from explicit entries (source = 'explicit')
73
+ * 3. Merge permissions: manifest defaults overridden by explicit permissions
74
+ * 4. Get tenant's ancestors via hierarchyPath (immediate parent → root)
75
+ * 5. For each ancestor, add inherited agents not already resolved
76
+ * 6. Return only agents that appear somewhere in the hierarchy
77
+ *
78
+ * @param tenantId - The tenant to resolve for
79
+ * @param getAncestorIds - Function that returns ancestor tenant IDs (parent → root order)
80
+ * @param manifests - Map of agent class name to AgentManifestInfo
81
+ */
82
+ resolveForTenant(tenantId: string, getAncestorIds: (tenantId: string) => Promise<string[]>, manifests?: Map<string, AgentManifestInfo>): Promise<ResolvedAgentAvailability[]>;
83
+ /**
84
+ * Enable an agent for a tenant (creates or updates binding)
85
+ */
86
+ enableAgent(tenantId: string, agentClass: string): Promise<TenantAgent>;
87
+ /**
88
+ * Disable an agent for a tenant
89
+ */
90
+ disableAgent(tenantId: string, agentClass: string): Promise<TenantAgent>;
91
+ /**
92
+ * Remove explicit override, falling back to inheritance
93
+ */
94
+ clearOverride(tenantId: string, agentClass: string): Promise<void>;
95
+ /**
96
+ * Set permission overrides for a tenant's agent binding
97
+ */
98
+ setPermissions(tenantId: string, agentClass: string, permissions: Record<string, boolean>): Promise<TenantAgent>;
99
+ /**
100
+ * Find a tenant-agent binding by tenant and agent class
101
+ */
102
+ findByTenantAndClass(tenantId: string, agentClass: string): Promise<TenantAgent | null>;
103
+ private normalizeStoredAgentClass;
104
+ private persistCanonicalAgentClass;
105
+ }
106
+ //# sourceMappingURL=tenant-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-agent.d.ts","sourceRoot":"","sources":["../src/tenant-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,cAAc,EACd,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAUtD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,4BAA4B;IAC5B,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;IACjC,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,qBAQa,WAAY,SAAQ,UAAU;IAEzC,QAAQ,EAAE,MAAM,CAAM;IAEtB,2DAA2D;IAE3D,UAAU,EAAE,MAAM,CAAM;IAExB,0CAA0C;IAE1C,MAAM,EAAE,iBAAiB,CAAY;IAErC,yEAAyE;IAEzE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAQ;IAEnD;;;;;;;;;OASG;IAEH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAQ;CAC3C;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,WAAW,CAAC;IACpE,MAAM,CAAC,QAAQ,CAAC,UAAU,qBAAe;IAEzC;;;;;;;;;;;;;;OAcG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,EACvD,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GACzC,OAAO,CAAC,yBAAyB,EAAE,CAAC;IA+DvC;;OAEG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAkBvB;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAkBvB;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxE;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,WAAW,CAAC;IAmBvB;;OAEG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAsBhB,yBAAyB;YAQzB,0BAA0B;CAqBzC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Agent status type
3
+ */
4
+ export type AgentStatusType = 'idle' | 'initializing' | 'running' | 'error' | 'shutdown';
5
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,cAAc,GACd,SAAS,GACT,OAAO,GACP,UAAU,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,298 @@
1
+ import { ModuleUISlot, SmrtModuleMeta } from '@happyvertical/smrt-types';
2
+ /**
3
+ * UI type definitions for SMRT Agents
4
+ *
5
+ * These types allow agents to declare admin panel UI slots
6
+ * that can be implemented as Svelte components in agent packages.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { AgentUIRegistry, type AdminPanelBaseProps } from '@happyvertical/smrt-agents/ui';
11
+ *
12
+ * // In agent package: register components at import time
13
+ * AgentUIRegistry.register('MyAgent', 'settings', SettingsPanel);
14
+ *
15
+ * // In host app: use registered components
16
+ * const Component = AgentUIRegistry.get('MyAgent', 'settings');
17
+ * ```
18
+ */
19
+ /**
20
+ * Svelte component type (compatible with svelte's ComponentType)
21
+ *
22
+ * Using a generic function type to avoid requiring svelte as a dependency
23
+ * and to avoid DOM type references that don't exist in Node.js builds.
24
+ *
25
+ * In practice, the actual Svelte component will be passed and used
26
+ * with `<svelte:component this={Component} />` in SvelteKit apps.
27
+ */
28
+ export type ComponentType<Props = any> = (...args: any[]) => any;
29
+ /**
30
+ * Base props that all admin panel components receive
31
+ */
32
+ export interface AdminPanelBaseProps<TConfig = unknown> {
33
+ /** Current configuration from the agent (merged file + db) */
34
+ config: TConfig;
35
+ /** Callback to save configuration changes */
36
+ onSave: (config: TConfig) => Promise<void>;
37
+ /** Whether the panel is in read-only mode */
38
+ readonly?: boolean;
39
+ /** CSS class for styling integration */
40
+ class?: string;
41
+ /**
42
+ * Read-only file-based configuration defaults (from smrt.config.js)
43
+ * Use this to display which values come from the config file
44
+ */
45
+ fileConfig?: TConfig;
46
+ /**
47
+ * Editable database-persisted configuration overrides
48
+ * Use this to display which values have been customized in the DB
49
+ */
50
+ dbConfig?: TConfig;
51
+ }
52
+ /**
53
+ * Definition of a UI slot that an agent declares
54
+ *
55
+ * Agents define slots they support; UI packages implement them.
56
+ */
57
+ export interface AgentUISlot {
58
+ /** Unique identifier for this slot (e.g., 'sources', 'reports', 'settings') */
59
+ id: string;
60
+ /** Human-readable label for the slot */
61
+ label: string;
62
+ /** Description of what this panel configures */
63
+ description?: string;
64
+ /** Icon identifier (e.g., 'settings', 'database', 'users') */
65
+ icon?: string;
66
+ /** Display order (lower numbers first) */
67
+ order?: number;
68
+ /** Whether the slot is currently unavailable in the admin UI */
69
+ disabled?: boolean;
70
+ }
71
+ /**
72
+ * Map of slot IDs to their definitions
73
+ * Used as static property on Agent subclasses
74
+ */
75
+ export type AgentUISlots = Record<string, AgentUISlot>;
76
+ /**
77
+ * A route an agent provides for its admin UI
78
+ *
79
+ * Agents declare these so that host applications or tooling
80
+ * (for example, a Vite plugin) can wire them into a SvelteKit app.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * static adminRoutes: AgentAdminRoute[] = [
85
+ * { path: 'sources', component: 'SourcesPanel', load: 'loadSources' },
86
+ * { path: 'sources/[sourceId]', component: 'SourceDetail', load: 'loadSourceDetail' },
87
+ * ];
88
+ * ```
89
+ */
90
+ export interface AgentAdminRoute {
91
+ /** Route path relative to agent root (e.g., 'sources/[sourceId]') */
92
+ path: string;
93
+ /** Component export name from the agent's admin entry point */
94
+ component: string;
95
+ /** Optional: export name for server load function */
96
+ load?: string;
97
+ }
98
+ /**
99
+ * Context passed to agent route load functions
100
+ *
101
+ * A normalized subset of SvelteKit's ServerLoadEvent,
102
+ * so agent load functions don't need a direct SvelteKit dependency.
103
+ */
104
+ export interface AgentRouteLoadContext {
105
+ params: Record<string, string>;
106
+ parent: () => Promise<any>;
107
+ fetch: typeof fetch;
108
+ url: URL;
109
+ }
110
+ /**
111
+ * Agent route load function signature
112
+ *
113
+ * Returned data is spread into the page's `data` prop.
114
+ */
115
+ export type AgentRouteLoadFn = (context: AgentRouteLoadContext) => Promise<Record<string, unknown>> | Record<string, unknown>;
116
+ /**
117
+ * Agent manifest type (re-exported from smrt-core scanner types)
118
+ * Duplicated here to avoid hard dependency on scanner internals
119
+ */
120
+ export interface AgentManifestInfo {
121
+ name: string;
122
+ slug: string;
123
+ icon?: string;
124
+ tier: 'free' | 'standard' | 'premium';
125
+ description?: string;
126
+ uiSlots: Record<string, AgentUISlot>;
127
+ adminRoutes?: AgentAdminRoute[];
128
+ /** Default signal subscriptions declared by this agent */
129
+ signalSubscriptions?: string[];
130
+ permissions: Array<{
131
+ id: string;
132
+ label: string;
133
+ category: string;
134
+ defaultGranted?: boolean;
135
+ }>;
136
+ features: Array<{
137
+ id: string;
138
+ label: string;
139
+ description?: string;
140
+ type: string;
141
+ }>;
142
+ menuItems: Array<{
143
+ id: string;
144
+ label: string;
145
+ icon?: string;
146
+ order: number;
147
+ path: string;
148
+ requiredPermission?: string;
149
+ }>;
150
+ components: Array<{
151
+ exportPath: string;
152
+ type: string;
153
+ }>;
154
+ }
155
+ /**
156
+ * Registry of UI component implementations
157
+ * Maps agent class name + slot ID to Svelte component
158
+ */
159
+ export interface AgentUIComponentRegistry {
160
+ /** Register a component for an agent's slot */
161
+ register<TProps extends AdminPanelBaseProps>(agentClass: string, slotId: string, component: ComponentType<TProps>): void;
162
+ /** Get a component for an agent's slot */
163
+ get<TProps extends AdminPanelBaseProps>(agentClass: string, slotId: string): ComponentType<TProps> | undefined;
164
+ /** Get all registered slot IDs for an agent */
165
+ getSlots(agentClass: string): string[];
166
+ /** Check if a component is registered */
167
+ has(agentClass: string, slotId: string): boolean;
168
+ /** Get all registered agent class names */
169
+ getAgents(): string[];
170
+ /** Unregister a component (useful for testing) */
171
+ unregister(agentClass: string, slotId: string): boolean;
172
+ /** Clear all registrations (useful for testing) */
173
+ clear(): void;
174
+ /** Register a component by composite key (e.g., 'praeco:sources') */
175
+ registerByKey(key: string, component: ComponentType): void;
176
+ /** Get a component by composite key */
177
+ getByKey(key: string): ComponentType | undefined;
178
+ /** Register an agent manifest for runtime access */
179
+ registerManifest(agentClass: string, manifest: AgentManifestInfo): void;
180
+ /** Get a registered agent manifest */
181
+ getManifest(agentClass: string): AgentManifestInfo | undefined;
182
+ /** Get all registered manifests */
183
+ getAllManifests(): Map<string, AgentManifestInfo>;
184
+ /** Register a route component for an agent */
185
+ registerRouteComponent(agentClass: string, path: string, component: ComponentType): void;
186
+ /** Get a route component for an agent */
187
+ getRouteComponent(agentClass: string, path: string): ComponentType | undefined;
188
+ /** Register a route load function for an agent */
189
+ registerRouteLoad(agentClass: string, path: string, loadFn: AgentRouteLoadFn): void;
190
+ /** Get a route load function for an agent */
191
+ getRouteLoad(agentClass: string, path: string): AgentRouteLoadFn | undefined;
192
+ }
193
+ /**
194
+ * Create a new UI component registry
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * const registry = createUIRegistry();
199
+ * registry.register('MyAgent', 'settings', SettingsPanel);
200
+ *
201
+ * const Component = registry.get('MyAgent', 'settings');
202
+ * if (Component) {
203
+ * // Render component
204
+ * }
205
+ * ```
206
+ */
207
+ export declare function createUIRegistry(): AgentUIComponentRegistry;
208
+ /**
209
+ * Global UI registry singleton
210
+ *
211
+ * Agent UI packages register their components here at import time,
212
+ * enabling discovery by host applications.
213
+ *
214
+ * Uses a `globalThis.__smrtAgentUIRegistry` property to guarantee a
215
+ * single registry instance per JavaScript runtime, even when bundlers
216
+ * (Vite, webpack) duplicate this module across optimized dependency
217
+ * chunks or package versions.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * // In agent package (e.g., @happyvertical/praeco/admin)
222
+ * import { AgentUIRegistry } from '@happyvertical/smrt-agents/ui';
223
+ * import SourcesPanel from './SourcesPanel.svelte';
224
+ *
225
+ * AgentUIRegistry.register('Praeco', 'sources', SourcesPanel);
226
+ *
227
+ * // In host SvelteKit app
228
+ * import { AgentUIRegistry } from '@happyvertical/smrt-agents/ui';
229
+ * import '@happyvertical/praeco/admin'; // Registers components
230
+ *
231
+ * const Component = AgentUIRegistry.get('Praeco', 'sources');
232
+ * ```
233
+ */
234
+ declare global {
235
+ var __smrtAgentUIRegistry: AgentUIComponentRegistry | undefined;
236
+ }
237
+ export declare const AgentUIRegistry: AgentUIComponentRegistry;
238
+ /**
239
+ * What an agent's `./admin` entry point must export.
240
+ *
241
+ * This is the contract between agent packages and host apps.
242
+ * Instead of registering individual slot components, agents export
243
+ * a single root component that handles its own sub-navigation.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * // In agent package: histrio/src/ui/admin/index.ts
248
+ * export { default } from './AdminRoot.svelte';
249
+ * export { createAPIClient } from '../types.js';
250
+ * export const navItems: AgentAdminNavItem[] = [
251
+ * { id: 'characters', label: 'Characters', icon: 'users', order: 1 },
252
+ * { id: 'performers', label: 'Performers', icon: 'mic', order: 2 },
253
+ * ];
254
+ * ```
255
+ */
256
+ export interface AgentAdminExport {
257
+ /** Root admin component — renders all panels, handles its own sub-navigation */
258
+ default?: ComponentType;
259
+ /** Create a typed API client for this agent */
260
+ createAPIClient?: (baseUrl: string) => unknown;
261
+ /** Navigation items for tabs/sidebar within the agent admin */
262
+ navItems?: AgentAdminNavItem[];
263
+ }
264
+ /**
265
+ * Props passed to the root admin component
266
+ */
267
+ export interface AgentAdminRootProps {
268
+ /** Typed API client created by the agent's own factory */
269
+ apiClient: unknown;
270
+ /** Which panel to show (from URL hash, e.g., 'sources') */
271
+ activePanel?: string;
272
+ /** Called when user navigates within the agent */
273
+ onNavigate?: (panelId: string) => void;
274
+ /** Whether admin is in read-only mode */
275
+ readonly?: boolean;
276
+ }
277
+ /**
278
+ * Navigation item within an agent's admin UI
279
+ */
280
+ export interface AgentAdminNavItem {
281
+ /** Matches hash fragment and panel ID */
282
+ id: string;
283
+ /** Display label */
284
+ label: string;
285
+ /** Icon identifier */
286
+ icon?: string;
287
+ /** Display order (lower numbers first) */
288
+ order?: number;
289
+ }
290
+ /**
291
+ * Agents module UI slots (for ModuleUIRegistry)
292
+ */
293
+ export declare const AGENTS_UI_SLOTS: Record<string, ModuleUISlot>;
294
+ /**
295
+ * Agents module metadata
296
+ */
297
+ export declare const AGENTS_MODULE_META: SmrtModuleMeta;
298
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
package/dist/ui.js ADDED
@@ -0,0 +1,133 @@
1
+ function createUIRegistry() {
2
+ const components = /* @__PURE__ */ new Map();
3
+ const manifests = /* @__PURE__ */ new Map();
4
+ const routeComponents = /* @__PURE__ */ new Map();
5
+ const routeLoads = /* @__PURE__ */ new Map();
6
+ const makeKey = (agentClass, slotId) => `${agentClass}:${slotId}`;
7
+ const makeRouteKey = (agentClass, path) => `${agentClass}:route:${path}`;
8
+ return {
9
+ register(agentClass, slotId, component) {
10
+ components.set(makeKey(agentClass, slotId), component);
11
+ },
12
+ get(agentClass, slotId) {
13
+ return components.get(makeKey(agentClass, slotId));
14
+ },
15
+ getSlots(agentClass) {
16
+ const prefix = `${agentClass}:`;
17
+ return Array.from(components.keys()).filter((k) => k.startsWith(prefix)).map((k) => k.slice(prefix.length));
18
+ },
19
+ has(agentClass, slotId) {
20
+ return components.has(makeKey(agentClass, slotId));
21
+ },
22
+ getAgents() {
23
+ const agents = /* @__PURE__ */ new Set();
24
+ for (const key of components.keys()) {
25
+ const agentClass = key.split(":")[0];
26
+ agents.add(agentClass);
27
+ }
28
+ return Array.from(agents);
29
+ },
30
+ unregister(agentClass, slotId) {
31
+ return components.delete(makeKey(agentClass, slotId));
32
+ },
33
+ clear() {
34
+ components.clear();
35
+ manifests.clear();
36
+ routeComponents.clear();
37
+ routeLoads.clear();
38
+ },
39
+ registerByKey(key, component) {
40
+ components.set(key, component);
41
+ },
42
+ getByKey(key) {
43
+ return components.get(key);
44
+ },
45
+ registerManifest(agentClass, manifest) {
46
+ manifests.set(agentClass, manifest);
47
+ },
48
+ getManifest(agentClass) {
49
+ return manifests.get(agentClass);
50
+ },
51
+ getAllManifests() {
52
+ return new Map(manifests);
53
+ },
54
+ registerRouteComponent(agentClass, path, component) {
55
+ routeComponents.set(makeRouteKey(agentClass, path), component);
56
+ },
57
+ getRouteComponent(agentClass, path) {
58
+ return routeComponents.get(makeRouteKey(agentClass, path));
59
+ },
60
+ registerRouteLoad(agentClass, path, loadFn) {
61
+ routeLoads.set(makeRouteKey(agentClass, path), loadFn);
62
+ },
63
+ getRouteLoad(agentClass, path) {
64
+ return routeLoads.get(makeRouteKey(agentClass, path));
65
+ }
66
+ };
67
+ }
68
+ if (!globalThis.__smrtAgentUIRegistry) {
69
+ globalThis.__smrtAgentUIRegistry = createUIRegistry();
70
+ }
71
+ const AgentUIRegistry = globalThis.__smrtAgentUIRegistry;
72
+ const AGENTS_UI_SLOTS = {
73
+ "agent-dashboard": {
74
+ id: "agent-dashboard",
75
+ label: "Agent Dashboard",
76
+ description: "Combined overview panel for agent schedules",
77
+ icon: "activity",
78
+ category: "admin",
79
+ order: 1,
80
+ propsInterface: "AgentDashboardProps"
81
+ },
82
+ "agent-schedule-list": {
83
+ id: "agent-schedule-list",
84
+ label: "Agent Schedule List",
85
+ description: "List of scheduled agents",
86
+ icon: "calendar",
87
+ category: "list",
88
+ order: 2,
89
+ propsInterface: "AgentScheduleListProps"
90
+ },
91
+ "agent-schedule-form": {
92
+ id: "agent-schedule-form",
93
+ label: "Agent Schedule Form",
94
+ description: "Form for creating or editing agent schedules",
95
+ icon: "edit",
96
+ category: "form",
97
+ order: 3,
98
+ propsInterface: "AgentScheduleFormProps"
99
+ },
100
+ "agent-run-history": {
101
+ id: "agent-run-history",
102
+ label: "Agent Run History",
103
+ description: "History of agent runs",
104
+ icon: "clock",
105
+ category: "list",
106
+ order: 4,
107
+ propsInterface: "AgentRunHistoryProps"
108
+ },
109
+ "schedule-status-badge": {
110
+ id: "schedule-status-badge",
111
+ label: "Schedule Status Badge",
112
+ description: "Status indicator for schedule states",
113
+ icon: "tag",
114
+ category: "display",
115
+ order: 5,
116
+ propsInterface: "ScheduleStatusBadgeProps"
117
+ }
118
+ };
119
+ const AGENTS_MODULE_META = {
120
+ name: "@happyvertical/smrt-agents",
121
+ displayName: "Agents",
122
+ description: "Agent framework for building autonomous actors",
123
+ uiSlots: AGENTS_UI_SLOTS,
124
+ models: ["Agent", "AgentSchedule", "AgentRun"],
125
+ collections: ["AgentCollection", "AgentScheduleCollection"]
126
+ };
127
+ export {
128
+ AGENTS_MODULE_META,
129
+ AGENTS_UI_SLOTS,
130
+ AgentUIRegistry,
131
+ createUIRegistry
132
+ };
133
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sources":["../src/ui.ts"],"sourcesContent":["import type { ModuleUISlot, SmrtModuleMeta } from '@happyvertical/smrt-types';\n\n/**\n * UI type definitions for SMRT Agents\n *\n * These types allow agents to declare admin panel UI slots\n * that can be implemented as Svelte components in agent packages.\n *\n * @example\n * ```typescript\n * import { AgentUIRegistry, type AdminPanelBaseProps } from '@happyvertical/smrt-agents/ui';\n *\n * // In agent package: register components at import time\n * AgentUIRegistry.register('MyAgent', 'settings', SettingsPanel);\n *\n * // In host app: use registered components\n * const Component = AgentUIRegistry.get('MyAgent', 'settings');\n * ```\n */\n\n/**\n * Svelte component type (compatible with svelte's ComponentType)\n *\n * Using a generic function type to avoid requiring svelte as a dependency\n * and to avoid DOM type references that don't exist in Node.js builds.\n *\n * In practice, the actual Svelte component will be passed and used\n * with `<svelte:component this={Component} />` in SvelteKit apps.\n */\nexport type ComponentType<Props = any> = (...args: any[]) => any;\n\n/**\n * Base props that all admin panel components receive\n */\nexport interface AdminPanelBaseProps<TConfig = unknown> {\n /** Current configuration from the agent (merged file + db) */\n config: TConfig;\n /** Callback to save configuration changes */\n onSave: (config: TConfig) => Promise<void>;\n /** Whether the panel is in read-only mode */\n readonly?: boolean;\n /** CSS class for styling integration */\n class?: string;\n /**\n * Read-only file-based configuration defaults (from smrt.config.js)\n * Use this to display which values come from the config file\n */\n fileConfig?: TConfig;\n /**\n * Editable database-persisted configuration overrides\n * Use this to display which values have been customized in the DB\n */\n dbConfig?: TConfig;\n}\n\n/**\n * Definition of a UI slot that an agent declares\n *\n * Agents define slots they support; UI packages implement them.\n */\nexport interface AgentUISlot {\n /** Unique identifier for this slot (e.g., 'sources', 'reports', 'settings') */\n id: string;\n /** Human-readable label for the slot */\n label: string;\n /** Description of what this panel configures */\n description?: string;\n /** Icon identifier (e.g., 'settings', 'database', 'users') */\n icon?: string;\n /** Display order (lower numbers first) */\n order?: number;\n /** Whether the slot is currently unavailable in the admin UI */\n disabled?: boolean;\n}\n\n/**\n * Map of slot IDs to their definitions\n * Used as static property on Agent subclasses\n */\nexport type AgentUISlots = Record<string, AgentUISlot>;\n\n/**\n * A route an agent provides for its admin UI\n *\n * Agents declare these so that host applications or tooling\n * (for example, a Vite plugin) can wire them into a SvelteKit app.\n *\n * @example\n * ```typescript\n * static adminRoutes: AgentAdminRoute[] = [\n * { path: 'sources', component: 'SourcesPanel', load: 'loadSources' },\n * { path: 'sources/[sourceId]', component: 'SourceDetail', load: 'loadSourceDetail' },\n * ];\n * ```\n */\nexport interface AgentAdminRoute {\n /** Route path relative to agent root (e.g., 'sources/[sourceId]') */\n path: string;\n /** Component export name from the agent's admin entry point */\n component: string;\n /** Optional: export name for server load function */\n load?: string;\n}\n\n/**\n * Context passed to agent route load functions\n *\n * A normalized subset of SvelteKit's ServerLoadEvent,\n * so agent load functions don't need a direct SvelteKit dependency.\n */\nexport interface AgentRouteLoadContext {\n params: Record<string, string>;\n parent: () => Promise<any>;\n fetch: typeof fetch;\n url: URL;\n}\n\n/**\n * Agent route load function signature\n *\n * Returned data is spread into the page's `data` prop.\n */\nexport type AgentRouteLoadFn = (\n context: AgentRouteLoadContext,\n) => Promise<Record<string, unknown>> | Record<string, unknown>;\n\n/**\n * Agent manifest type (re-exported from smrt-core scanner types)\n * Duplicated here to avoid hard dependency on scanner internals\n */\nexport interface AgentManifestInfo {\n name: string;\n slug: string;\n icon?: string;\n tier: 'free' | 'standard' | 'premium';\n description?: string;\n uiSlots: Record<string, AgentUISlot>;\n adminRoutes?: AgentAdminRoute[];\n /** Default signal subscriptions declared by this agent */\n signalSubscriptions?: string[];\n permissions: Array<{\n id: string;\n label: string;\n category: string;\n defaultGranted?: boolean;\n }>;\n features: Array<{\n id: string;\n label: string;\n description?: string;\n type: string;\n }>;\n menuItems: Array<{\n id: string;\n label: string;\n icon?: string;\n order: number;\n path: string;\n requiredPermission?: string;\n }>;\n components: Array<{ exportPath: string; type: string }>;\n}\n\n/**\n * Registry of UI component implementations\n * Maps agent class name + slot ID to Svelte component\n */\nexport interface AgentUIComponentRegistry {\n /** Register a component for an agent's slot */\n register<TProps extends AdminPanelBaseProps>(\n agentClass: string,\n slotId: string,\n component: ComponentType<TProps>,\n ): void;\n\n /** Get a component for an agent's slot */\n get<TProps extends AdminPanelBaseProps>(\n agentClass: string,\n slotId: string,\n ): ComponentType<TProps> | undefined;\n\n /** Get all registered slot IDs for an agent */\n getSlots(agentClass: string): string[];\n\n /** Check if a component is registered */\n has(agentClass: string, slotId: string): boolean;\n\n /** Get all registered agent class names */\n getAgents(): string[];\n\n /** Unregister a component (useful for testing) */\n unregister(agentClass: string, slotId: string): boolean;\n\n /** Clear all registrations (useful for testing) */\n clear(): void;\n\n /** Register a component by composite key (e.g., 'praeco:sources') */\n registerByKey(key: string, component: ComponentType): void;\n\n /** Get a component by composite key */\n getByKey(key: string): ComponentType | undefined;\n\n /** Register an agent manifest for runtime access */\n registerManifest(agentClass: string, manifest: AgentManifestInfo): void;\n\n /** Get a registered agent manifest */\n getManifest(agentClass: string): AgentManifestInfo | undefined;\n\n /** Get all registered manifests */\n getAllManifests(): Map<string, AgentManifestInfo>;\n\n /** Register a route component for an agent */\n registerRouteComponent(\n agentClass: string,\n path: string,\n component: ComponentType,\n ): void;\n\n /** Get a route component for an agent */\n getRouteComponent(\n agentClass: string,\n path: string,\n ): ComponentType | undefined;\n\n /** Register a route load function for an agent */\n registerRouteLoad(\n agentClass: string,\n path: string,\n loadFn: AgentRouteLoadFn,\n ): void;\n\n /** Get a route load function for an agent */\n getRouteLoad(agentClass: string, path: string): AgentRouteLoadFn | undefined;\n}\n\n/**\n * Create a new UI component registry\n *\n * @example\n * ```typescript\n * const registry = createUIRegistry();\n * registry.register('MyAgent', 'settings', SettingsPanel);\n *\n * const Component = registry.get('MyAgent', 'settings');\n * if (Component) {\n * // Render component\n * }\n * ```\n */\nexport function createUIRegistry(): AgentUIComponentRegistry {\n const components = new Map<string, ComponentType<any>>();\n const manifests = new Map<string, AgentManifestInfo>();\n const routeComponents = new Map<string, ComponentType>();\n const routeLoads = new Map<string, AgentRouteLoadFn>();\n\n const makeKey = (agentClass: string, slotId: string) =>\n `${agentClass}:${slotId}`;\n\n const makeRouteKey = (agentClass: string, path: string) =>\n `${agentClass}:route:${path}`;\n\n return {\n register(agentClass, slotId, component) {\n components.set(makeKey(agentClass, slotId), component);\n },\n\n get(agentClass, slotId) {\n return components.get(makeKey(agentClass, slotId));\n },\n\n getSlots(agentClass) {\n const prefix = `${agentClass}:`;\n return Array.from(components.keys())\n .filter((k) => k.startsWith(prefix))\n .map((k) => k.slice(prefix.length));\n },\n\n has(agentClass, slotId) {\n return components.has(makeKey(agentClass, slotId));\n },\n\n getAgents() {\n const agents = new Set<string>();\n for (const key of components.keys()) {\n const agentClass = key.split(':')[0];\n agents.add(agentClass);\n }\n return Array.from(agents);\n },\n\n unregister(agentClass, slotId) {\n return components.delete(makeKey(agentClass, slotId));\n },\n\n clear() {\n components.clear();\n manifests.clear();\n routeComponents.clear();\n routeLoads.clear();\n },\n\n registerByKey(key, component) {\n components.set(key, component);\n },\n\n getByKey(key) {\n return components.get(key);\n },\n\n registerManifest(agentClass, manifest) {\n manifests.set(agentClass, manifest);\n },\n\n getManifest(agentClass) {\n return manifests.get(agentClass);\n },\n\n getAllManifests() {\n return new Map(manifests);\n },\n\n registerRouteComponent(agentClass, path, component) {\n routeComponents.set(makeRouteKey(agentClass, path), component);\n },\n\n getRouteComponent(agentClass, path) {\n return routeComponents.get(makeRouteKey(agentClass, path));\n },\n\n registerRouteLoad(agentClass, path, loadFn) {\n routeLoads.set(makeRouteKey(agentClass, path), loadFn);\n },\n\n getRouteLoad(agentClass, path) {\n return routeLoads.get(makeRouteKey(agentClass, path));\n },\n };\n}\n\n/**\n * Global UI registry singleton\n *\n * Agent UI packages register their components here at import time,\n * enabling discovery by host applications.\n *\n * Uses a `globalThis.__smrtAgentUIRegistry` property to guarantee a\n * single registry instance per JavaScript runtime, even when bundlers\n * (Vite, webpack) duplicate this module across optimized dependency\n * chunks or package versions.\n *\n * @example\n * ```typescript\n * // In agent package (e.g., @happyvertical/praeco/admin)\n * import { AgentUIRegistry } from '@happyvertical/smrt-agents/ui';\n * import SourcesPanel from './SourcesPanel.svelte';\n *\n * AgentUIRegistry.register('Praeco', 'sources', SourcesPanel);\n *\n * // In host SvelteKit app\n * import { AgentUIRegistry } from '@happyvertical/smrt-agents/ui';\n * import '@happyvertical/praeco/admin'; // Registers components\n *\n * const Component = AgentUIRegistry.get('Praeco', 'sources');\n * ```\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __smrtAgentUIRegistry: AgentUIComponentRegistry | undefined;\n}\n\nif (!globalThis.__smrtAgentUIRegistry) {\n globalThis.__smrtAgentUIRegistry = createUIRegistry();\n}\nexport const AgentUIRegistry: AgentUIComponentRegistry =\n globalThis.__smrtAgentUIRegistry;\n\n/**\n * What an agent's `./admin` entry point must export.\n *\n * This is the contract between agent packages and host apps.\n * Instead of registering individual slot components, agents export\n * a single root component that handles its own sub-navigation.\n *\n * @example\n * ```typescript\n * // In agent package: histrio/src/ui/admin/index.ts\n * export { default } from './AdminRoot.svelte';\n * export { createAPIClient } from '../types.js';\n * export const navItems: AgentAdminNavItem[] = [\n * { id: 'characters', label: 'Characters', icon: 'users', order: 1 },\n * { id: 'performers', label: 'Performers', icon: 'mic', order: 2 },\n * ];\n * ```\n */\nexport interface AgentAdminExport {\n /** Root admin component — renders all panels, handles its own sub-navigation */\n default?: ComponentType;\n /** Create a typed API client for this agent */\n createAPIClient?: (baseUrl: string) => unknown;\n /** Navigation items for tabs/sidebar within the agent admin */\n navItems?: AgentAdminNavItem[];\n}\n\n/**\n * Props passed to the root admin component\n */\nexport interface AgentAdminRootProps {\n /** Typed API client created by the agent's own factory */\n apiClient: unknown;\n /** Which panel to show (from URL hash, e.g., 'sources') */\n activePanel?: string;\n /** Called when user navigates within the agent */\n onNavigate?: (panelId: string) => void;\n /** Whether admin is in read-only mode */\n readonly?: boolean;\n}\n\n/**\n * Navigation item within an agent's admin UI\n */\nexport interface AgentAdminNavItem {\n /** Matches hash fragment and panel ID */\n id: string;\n /** Display label */\n label: string;\n /** Icon identifier */\n icon?: string;\n /** Display order (lower numbers first) */\n order?: number;\n}\n\n/**\n * Agents module UI slots (for ModuleUIRegistry)\n */\nexport const AGENTS_UI_SLOTS: Record<string, ModuleUISlot> = {\n 'agent-dashboard': {\n id: 'agent-dashboard',\n label: 'Agent Dashboard',\n description: 'Combined overview panel for agent schedules',\n icon: 'activity',\n category: 'admin',\n order: 1,\n propsInterface: 'AgentDashboardProps',\n },\n 'agent-schedule-list': {\n id: 'agent-schedule-list',\n label: 'Agent Schedule List',\n description: 'List of scheduled agents',\n icon: 'calendar',\n category: 'list',\n order: 2,\n propsInterface: 'AgentScheduleListProps',\n },\n 'agent-schedule-form': {\n id: 'agent-schedule-form',\n label: 'Agent Schedule Form',\n description: 'Form for creating or editing agent schedules',\n icon: 'edit',\n category: 'form',\n order: 3,\n propsInterface: 'AgentScheduleFormProps',\n },\n 'agent-run-history': {\n id: 'agent-run-history',\n label: 'Agent Run History',\n description: 'History of agent runs',\n icon: 'clock',\n category: 'list',\n order: 4,\n propsInterface: 'AgentRunHistoryProps',\n },\n 'schedule-status-badge': {\n id: 'schedule-status-badge',\n label: 'Schedule Status Badge',\n description: 'Status indicator for schedule states',\n icon: 'tag',\n category: 'display',\n order: 5,\n propsInterface: 'ScheduleStatusBadgeProps',\n },\n};\n\n/**\n * Agents module metadata\n */\nexport const AGENTS_MODULE_META: SmrtModuleMeta = {\n name: '@happyvertical/smrt-agents',\n displayName: 'Agents',\n description: 'Agent framework for building autonomous actors',\n uiSlots: AGENTS_UI_SLOTS,\n models: ['Agent', 'AgentSchedule', 'AgentRun'],\n collections: ['AgentCollection', 'AgentScheduleCollection'],\n};\n"],"names":[],"mappings":"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"}