@topolo/sdk 0.11.11 → 0.13.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 CHANGED
@@ -148,26 +148,78 @@ any additional fields required by a declared URL-session completion action.
148
148
 
149
149
  ## Native dashboard widgets
150
150
 
151
- Launchable first-party applications populate the TopoloOne live workspace through
152
- their own `GET /api/widget` endpoint. The SDK owns the shared payload contract:
151
+ Every marketplace application populates Topolo One through its own
152
+ `GET /api/widget` endpoint. The SDK owns the complete, versioned payload
153
+ contract; Topolo One never assumes how many applications or widgets a
154
+ credential can discover.
153
155
 
154
156
  ```ts
155
- import { createTopoloWidgetResponse } from '@topolo/sdk';
157
+ import {
158
+ createTopoloWidgetResponse,
159
+ defineTopoloStatsWidget,
160
+ } from '@topolo/sdk';
156
161
 
157
162
  return Response.json(createTopoloWidgetResponse({
158
163
  appId: '<runtime-app-id>',
159
- appName: 'Example',
164
+ serviceName: 'Example',
160
165
  widgets: [
161
- {
162
- type: 'stats',
163
- stats: [{ label: 'Open items', value: 3 }],
164
- },
166
+ defineTopoloStatsWidget({
167
+ id: 'example.open-items',
168
+ version: '1.0.0',
169
+ appId: '<runtime-app-id>',
170
+ serviceName: 'Example',
171
+ lastUpdated: new Date().toISOString(),
172
+ presentation: {
173
+ title: 'Open items',
174
+ contexts: ['workspace'],
175
+ supportedSizes: ['compact', 'medium'],
176
+ defaultSize: 'compact',
177
+ },
178
+ resource: {
179
+ resourceType: 'workspace',
180
+ requiredPermissions: ['app_example.items:read'],
181
+ },
182
+ state: { status: 'ready', observedAt: new Date().toISOString() },
183
+ refresh: {
184
+ intervalSeconds: 60,
185
+ timeoutSeconds: 5,
186
+ maxAgeSeconds: 60,
187
+ staleWhileRevalidateSeconds: 300,
188
+ },
189
+ configuration: {
190
+ allowMultipleInstances: true,
191
+ fields: [],
192
+ defaults: {},
193
+ },
194
+ drilldowns: [],
195
+ controls: [],
196
+ localization: { locale: 'en', titleKey: 'widgets.openItems.title' },
197
+ accessibility: { label: 'Open items' },
198
+ metrics: [{
199
+ key: 'open_items',
200
+ label: 'Open items',
201
+ value: 3,
202
+ unit: 'count',
203
+ semantic: 'gauge',
204
+ aggregation: 'last',
205
+ period: {
206
+ start: '2026-08-29T00:00:00.000Z',
207
+ end: '2026-08-30T00:00:00.000Z',
208
+ timezone: 'UTC',
209
+ },
210
+ dimensions: [],
211
+ }],
212
+ }),
165
213
  ],
166
214
  }));
167
215
  ```
168
216
 
169
- Use `validateTopoloWidgetResponse()` in endpoint tests to prevent app-local
170
- payload drift.
217
+ Successful responses must contain at least one complete widget. Represent
218
+ legitimate no-data with the widget's explicit `empty` state; an empty widget
219
+ array is a conformance failure. Actions use published `actionId` bindings with
220
+ their confirmation, effects, verification, and recovery contract. Use
221
+ `validateTopoloWidgetResponse()` in endpoint and marketplace conformance tests
222
+ to prevent app-local payload drift.
171
223
 
172
224
  ## Escape hatch
173
225