@happyvertical/smrt-content 0.44.0 → 0.45.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 (52) hide show
  1. package/agents/content-list.md +93 -14
  2. package/dist/chunks/{content-corrections-BxfA3tW1.js → content-corrections-B4mPd_th.js} +6 -3
  3. package/dist/chunks/content-corrections-B4mPd_th.js.map +1 -0
  4. package/dist/chunks/{content-query-B4cHfrig.js → content-query-BV41W2Dq.js} +6 -6
  5. package/dist/chunks/{content-query-B4cHfrig.js.map → content-query-BV41W2Dq.js.map} +1 -1
  6. package/dist/chunks/{content-reviews-BWrYEQc6.js → content-reviews-lBoqJY7Y.js} +6 -3
  7. package/dist/chunks/content-reviews-lBoqJY7Y.js.map +1 -0
  8. package/dist/chunks/{content-versions-OEYQVrUf.js → content-versions-dZSBU8UF.js} +6 -3
  9. package/dist/chunks/content-versions-dZSBU8UF.js.map +1 -0
  10. package/dist/chunks/{contents-BrGxWH3s.js → contents-Ba7JHu2K.js} +2 -2
  11. package/dist/chunks/{contents-BrGxWH3s.js.map → contents-Ba7JHu2K.js.map} +1 -1
  12. package/dist/content-contribution.d.ts +1 -1
  13. package/dist/content-contribution.d.ts.map +1 -1
  14. package/dist/index.js +12 -9
  15. package/dist/index.js.map +1 -1
  16. package/dist/manifest.json +2268 -4345
  17. package/dist/server/content-list-actions.d.ts +10 -3
  18. package/dist/server/content-list-actions.d.ts.map +1 -1
  19. package/dist/server/content-list-data-surface.d.ts +29 -0
  20. package/dist/server/content-list-data-surface.d.ts.map +1 -0
  21. package/dist/server/content-list-lifecycle.d.ts +20 -0
  22. package/dist/server/content-list-lifecycle.d.ts.map +1 -0
  23. package/dist/server.d.ts +2 -0
  24. package/dist/server.d.ts.map +1 -1
  25. package/dist/server.js +247 -25
  26. package/dist/server.js.map +1 -1
  27. package/dist/smrt-knowledge.json +4291 -2510
  28. package/dist/svelte/components/ContentList.svelte +538 -40
  29. package/dist/svelte/components/ContentList.svelte.d.ts +6 -1
  30. package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -1
  31. package/dist/svelte/components/ContentListLifecyclePanel.svelte +387 -0
  32. package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts +17 -0
  33. package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts.map +1 -0
  34. package/dist/svelte/content-list-controller.d.ts +10 -0
  35. package/dist/svelte/content-list-controller.d.ts.map +1 -1
  36. package/dist/svelte/content-list-controller.js +111 -26
  37. package/dist/svelte/content-list-data-surface.d.ts +45 -0
  38. package/dist/svelte/content-list-data-surface.d.ts.map +1 -0
  39. package/dist/svelte/content-list-data-surface.js +196 -0
  40. package/dist/svelte/content-list-lifecycle.d.ts +132 -0
  41. package/dist/svelte/content-list-lifecycle.d.ts.map +1 -0
  42. package/dist/svelte/content-list-lifecycle.js +439 -0
  43. package/dist/svelte/i18n.contribution.d.ts +27 -0
  44. package/dist/svelte/i18n.contribution.d.ts.map +1 -1
  45. package/dist/svelte/i18n.contribution.js +27 -0
  46. package/dist/svelte/index.d.ts +2 -0
  47. package/dist/svelte/index.d.ts.map +1 -1
  48. package/dist/svelte/index.js +2 -0
  49. package/package.json +15 -15
  50. package/dist/chunks/content-corrections-BxfA3tW1.js.map +0 -1
  51. package/dist/chunks/content-reviews-BWrYEQc6.js.map +0 -1
  52. package/dist/chunks/content-versions-OEYQVrUf.js.map +0 -1
@@ -7,10 +7,13 @@ import { Content } from '../content.js';
7
7
  import { ContentQueryCollection, ContentQueryScope } from '../content-query.js';
8
8
  export declare const CONTENT_LIST_WORKFLOW_IDS: readonly ["move-to-trash", "mark-draft", "submit-review", "publish", "archive", "restore", "automated-review", "format-body", "categorize", "optimize"];
9
9
  export type ContentListWorkflowId = (typeof CONTENT_LIST_WORKFLOW_IDS)[number];
10
+ export declare const CONTENT_LIST_LIFECYCLE_ACTION_IDS: readonly ["move-to-trash", "restore", "permanent-delete"];
11
+ export type ContentListLifecycleActionId = (typeof CONTENT_LIST_LIFECYCLE_ACTION_IDS)[number];
12
+ export type ContentListServerActionId = ContentListWorkflowId | ContentListLifecycleActionId;
10
13
  export type ContentListWorkflowExecution = 'foreground' | 'background';
11
14
  export type ContentListWorkflowConfirmation = 'required' | 'none';
12
15
  export interface ContentListWorkflowDescriptor {
13
- id: ContentListWorkflowId;
16
+ id: ContentListServerActionId;
14
17
  label: string;
15
18
  description: string;
16
19
  selectionScopes: Array<'current-page' | 'explicit-ids' | 'all-matching'>;
@@ -34,14 +37,18 @@ export interface ContentListWorkflowDescriptor {
34
37
  };
35
38
  }
36
39
  export declare const CONTENT_LIST_WORKFLOWS: readonly ContentListWorkflowDescriptor[];
40
+ /** The lifecycle-only catalog exposed by the dedicated route/service. */
41
+ export declare const CONTENT_LIST_LIFECYCLE_ACTIONS: readonly ContentListWorkflowDescriptor[];
37
42
  export interface ContentListActionTarget {
38
43
  /** Canonical query sent to the content query endpoint. Required except for explicit IDs. */
39
44
  query?: DataQueryRequest;
40
45
  /** Count visible at selection time; drift fails the preview/apply. */
41
46
  expectedCount: number;
47
+ /** Operator-entered preview count, required only for permanent-delete apply. */
48
+ confirmedCount?: number;
42
49
  }
43
50
  export interface ContentListActionRequest extends DataSurfaceServerActionRequest {
44
- actionId: ContentListWorkflowId;
51
+ actionId: ContentListServerActionId;
45
52
  target: ContentListActionTarget;
46
53
  }
47
54
  export interface ContentListActionCollection extends ContentQueryCollection {
@@ -103,7 +110,7 @@ export interface ContentListActionAdapterOptions {
103
110
  scope?: (run: PrincipalRun) => ContentQueryScope | undefined | Promise<ContentQueryScope | undefined>;
104
111
  /** Server-owned mounted/catalog revision. Defaults to zero for standalone endpoints. */
105
112
  revision?: (run: PrincipalRun, identity: DataSurfaceIdentity) => number | Promise<number>;
106
- authorize?: (workflow: ContentListWorkflowId, run: PrincipalRun) => boolean | Promise<boolean>;
113
+ authorize?: (workflow: ContentListServerActionId, run: PrincipalRun) => boolean | Promise<boolean>;
107
114
  handlers?: ContentListWorkflowHandlers;
108
115
  backgroundQueue?: DataSurfaceBackgroundQueue;
109
116
  descriptor?: DataSurfaceDescriptor;
@@ -1 +1 @@
1
- {"version":3,"file":"content-list-actions.d.ts","sourceRoot":"","sources":["../../src/server/content-list-actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"content-list-actions.d.ts","sourceRoot":"","sources":["../../src/server/content-list-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { DataSurfaceDefinition, DataSurfaceExecutionContext, DataSurfaceSchema } from '@happyvertical/smrt-agents';
2
+ import { ContentQueryCollection, ContentQueryScope } from '../content-query.js';
3
+ export declare const CONTENT_LIST_DATA_SURFACE_ID = "content-list";
4
+ export declare const CONTENT_LIST_DATA_SURFACE_COLLECTION = "contents";
5
+ export interface ContentListDataSurfaceOptions {
6
+ /** Stable catalog id. Defaults to the mounted ContentList surface id. */
7
+ id?: string;
8
+ /** Permission-catalog collection checked by the generic agent tools. */
9
+ collectionName?: string;
10
+ label?: string;
11
+ description?: string;
12
+ metadata?: NonNullable<DataSurfaceDefinition['metadata']>;
13
+ /** Resolve a collection from the live principal context, never model input. */
14
+ collection: ContentQueryCollection | ((context: DataSurfaceExecutionContext) => ContentQueryCollection | Promise<ContentQueryCollection>);
15
+ /** Trusted application narrowing applied in addition to tenant isolation. */
16
+ scope?: ContentQueryScope | ((context: DataSurfaceExecutionContext) => ContentQueryScope | undefined | Promise<ContentQueryScope | undefined>);
17
+ /** Trusted policy override; defaults to the canonical Content query schema. */
18
+ schema?: DataSurfaceSchema;
19
+ }
20
+ /**
21
+ * Build one server-owned ContentList surface for `data.discover`,
22
+ * `data.inspect`, and silent/background `data.query` calls.
23
+ *
24
+ * The returned executor resolves its collection and application scope from the
25
+ * live principal context. The request can only narrow that trusted scope, and
26
+ * every projection/count/facet/page still passes through `executeContentQuery`.
27
+ */
28
+ export declare function createContentListDataSurfaceDefinition(options: ContentListDataSurfaceOptions): Promise<DataSurfaceDefinition>;
29
+ //# sourceMappingURL=content-list-data-surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-list-data-surface.d.ts","sourceRoot":"","sources":["../../src/server/content-list-data-surface.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EAEvB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,4BAA4B,iBAAiB,CAAC;AAC3D,eAAO,MAAM,oCAAoC,aAAa,CAAC;AAE/D,MAAM,WAAW,6BAA6B;IAC5C,yEAAyE;IACzE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,WAAW,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,+EAA+E;IAC/E,UAAU,EACN,sBAAsB,GACtB,CAAC,CACC,OAAO,EAAE,2BAA2B,KACjC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACnE,6EAA6E;IAC7E,KAAK,CAAC,EACF,iBAAiB,GACjB,CAAC,CACC,OAAO,EAAE,2BAA2B,KAElC,iBAAiB,GACjB,SAAS,GACT,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC,CAAC;IAChD,+EAA+E;IAC/E,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAsDD;;;;;;;GAOG;AACH,wBAAsB,sCAAsC,CAC1D,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,qBAAqB,CAAC,CAgDhC"}
@@ -0,0 +1,20 @@
1
+ import { DataSurfaceServerActionContext } from '@happyvertical/smrt-agents/server';
2
+ import { DataSurfaceActionResult } from '@happyvertical/smrt-ui/data';
3
+ import { ContentListActionAdapter } from './content-list-actions.js';
4
+ export interface ContentListLifecycleService {
5
+ invoke(request: unknown, context: DataSurfaceServerActionContext): Promise<DataSurfaceActionResult>;
6
+ }
7
+ export interface ContentListLifecycleRouteOptions {
8
+ adapter: ContentListActionAdapter;
9
+ /** Authenticate and bind the request to its current principal/tenant. */
10
+ context(request: Request): DataSurfaceServerActionContext | Promise<DataSurfaceServerActionContext>;
11
+ }
12
+ /** Create the transport-neutral lifecycle service used by HTTP and agent hosts. */
13
+ export declare function createContentListLifecycleService(adapter: ContentListActionAdapter): ContentListLifecycleService;
14
+ /**
15
+ * Create a native Request/Response handler for `POST /api/v1/contents/lifecycle`.
16
+ * SvelteKit hosts can call it with `event.request`; other runtimes can mount it
17
+ * directly anywhere that implements the standard Fetch API.
18
+ */
19
+ export declare function createContentListLifecycleRoute(options: ContentListLifecycleRouteOptions): (request: Request) => Promise<Response>;
20
+ //# sourceMappingURL=content-list-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-list-lifecycle.d.ts","sourceRoot":"","sources":["../../src/server/content-list-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,wBAAwB,EAG9B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CACJ,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,wBAAwB,CAAC;IAClC,yEAAyE;IACzE,OAAO,CACL,OAAO,EAAE,OAAO,GACf,8BAA8B,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC7E;AA6CD,mFAAmF;AACnF,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wBAAwB,GAChC,2BAA2B,CAgB7B;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAoCzC"}
package/dist/server.d.ts CHANGED
@@ -2,5 +2,7 @@ declare function startServer(): Promise<{
2
2
  shutdown: () => Promise<void>;
3
3
  }>;
4
4
  export * from './server/content-list-actions.js';
5
+ export * from './server/content-list-data-surface.js';
6
+ export * from './server/content-list-lifecycle.js';
5
7
  export { startServer };
6
8
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,wBAAwB,CAAC;AAGhC,iBAAe,WAAW;;GA+BzB;AAOD,cAAc,kCAAkC,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,wBAAwB,CAAC;AAGhC,iBAAe,WAAW;;GA+BzB;AAOD,cAAc,kCAAkC,CAAC;AACjD,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,CAAC"}
package/dist/server.js CHANGED
@@ -1,6 +1,7 @@
1
- import { v as buildContentQuerySchema, w as Content, x as executeContentQuery } from "./chunks/content-query-B4cHfrig.js";
1
+ import { _ as assertContentQuerySchema, t as CONTENT_QUERY_CLASS_NAME, v as buildContentQuerySchema, w as Content, x as executeContentQuery } from "./chunks/content-query-BV41W2Dq.js";
2
2
  import { MAX_DATA_QUERY_PAGE_LIMIT, createDataQueryFingerprint, normalizeDataQueryRequest, startRestServer } from "@happyvertical/smrt-core";
3
3
  import { createHash } from "node:crypto";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
4
5
  import "@happyvertical/smrt-facts";
5
6
  import { PrincipalToolNotAllowedError } from "@happyvertical/smrt-agents";
6
7
  import { createDataSurfaceActionAdapter, isBoundedDataSurfaceJsonValue } from "@happyvertical/smrt-agents/server";
@@ -17,6 +18,11 @@ var CONTENT_LIST_WORKFLOW_IDS = [
17
18
  "categorize",
18
19
  "optimize"
19
20
  ];
21
+ var CONTENT_LIST_LIFECYCLE_ACTION_IDS = [
22
+ "move-to-trash",
23
+ "restore",
24
+ "permanent-delete"
25
+ ];
20
26
  var ALL_SELECTION_SCOPES = [
21
27
  "current-page",
22
28
  "explicit-ids",
@@ -253,6 +259,31 @@ var CONTENT_LIST_WORKFLOWS = Object.freeze([
253
259
  consequences: ["Content fields may be revised or completed."]
254
260
  })
255
261
  ]);
262
+ var PERMANENT_DELETE_ACTION = workflow("permanent-delete", "Delete permanently", {
263
+ description: "Permanently delete content that is already in trash.",
264
+ sensitivity: "sensitive",
265
+ eligibility: ["content is deleted"],
266
+ consequences: ["Content and its owned lifecycle data are irreversibly deleted."],
267
+ permissionRequirements: {
268
+ tool: "content.lifecycle.permanent-delete",
269
+ operations: [CONTENT_READ_OPERATION, {
270
+ id: "contents:delete",
271
+ collection: "contents",
272
+ action: "delete"
273
+ }]
274
+ }
275
+ });
276
+ var CONTENT_LIST_LIFECYCLE_ACTIONS = Object.freeze([
277
+ contentListWorkflow("move-to-trash"),
278
+ contentListWorkflow("restore"),
279
+ PERMANENT_DELETE_ACTION
280
+ ]);
281
+ var CONTENT_LIST_SERVER_ACTIONS = Object.freeze([...CONTENT_LIST_WORKFLOWS, PERMANENT_DELETE_ACTION]);
282
+ function contentListWorkflow(id) {
283
+ const descriptor = CONTENT_LIST_WORKFLOWS.find((entry) => entry.id === id);
284
+ if (!descriptor) throw new Error(`Missing ContentList workflow: ${id}`);
285
+ return descriptor;
286
+ }
256
287
  function workflow(id, label, options) {
257
288
  return {
258
289
  id,
@@ -312,22 +343,22 @@ var ContentListActionError = class extends Error {
312
343
  }
313
344
  reason;
314
345
  };
315
- function isRecord(value) {
346
+ function isRecord$1(value) {
316
347
  return !!value && typeof value === "object" && !Array.isArray(value);
317
348
  }
318
349
  function isPermissionDenied(error) {
319
350
  if (!(error instanceof Error) || error.name !== "OperationPermissionError") return false;
320
351
  const decision = error.decision;
321
- return isRecord(decision) && decision.reason === "permission_denied";
352
+ return isRecord$1(decision) && decision.reason === "permission_denied";
322
353
  }
323
- function isWorkflowId(value) {
324
- return CONTENT_LIST_WORKFLOW_IDS.includes(value);
354
+ function isServerActionId(value) {
355
+ return CONTENT_LIST_SERVER_ACTIONS.some(({ id }) => id === value);
325
356
  }
326
357
  function payloadRecord(value) {
327
- return isRecord(value) ? value : {};
358
+ return isRecord$1(value) ? value : {};
328
359
  }
329
360
  function validPayload(workflowId, payload) {
330
- if (payload !== void 0 && !isRecord(payload)) return false;
361
+ if (payload !== void 0 && !isRecord$1(payload)) return false;
331
362
  const value = payloadRecord(payload);
332
363
  const keys = Object.keys(value);
333
364
  switch (workflowId) {
@@ -348,8 +379,8 @@ function validPayload(workflowId, payload) {
348
379
  }
349
380
  }
350
381
  function actionResult(request, ok, reason) {
351
- const candidate = isRecord(request) ? request : {};
352
- const identityCandidate = isRecord(candidate.identity) ? candidate.identity : {};
382
+ const candidate = isRecord$1(request) ? request : {};
383
+ const identityCandidate = isRecord$1(candidate.identity) ? candidate.identity : {};
353
384
  const identity = typeof identityCandidate.surfaceId === "string" && [
354
385
  "table",
355
386
  "list",
@@ -370,11 +401,13 @@ function actionResult(request, ok, reason) {
370
401
  };
371
402
  }
372
403
  function validateTarget(request) {
373
- if (!isRecord(request) || !isWorkflowId(request.actionId) || !isRecord(request.target) || !isRecord(request.selection)) return "invalid_request";
374
- if (Object.keys(request.target).some((key) => key !== "query" && key !== "expectedCount")) return "invalid_request";
404
+ if (!isRecord$1(request) || !isServerActionId(request.actionId) || !isRecord$1(request.target) || !isRecord$1(request.selection)) return "invalid_request";
405
+ if (Object.keys(request.target).some((key) => key !== "query" && key !== "expectedCount" && key !== "confirmedCount")) return "invalid_request";
375
406
  const expectedCount = request.target.expectedCount;
376
407
  if (typeof expectedCount !== "number" || !Number.isSafeInteger(expectedCount) || expectedCount < 0) return "invalid_request";
377
- if (request.selection.scope !== "explicit-ids" && !isRecord(request.target.query)) return "invalid_request";
408
+ const requiresCountAffirmation = request.actionId === "permanent-delete" && request.phase === "apply";
409
+ if (requiresCountAffirmation && (request.target.confirmedCount !== expectedCount || !Number.isSafeInteger(request.target.confirmedCount)) || !requiresCountAffirmation && request.target.confirmedCount !== void 0) return "confirmation_count_mismatch";
410
+ if (request.selection.scope !== "explicit-ids" && !isRecord$1(request.target.query)) return "invalid_request";
378
411
  if (request.target.query !== void 0 && !isBoundedDataSurfaceJsonValue(request.target.query)) return "invalid_request";
379
412
  }
380
413
  function statusOf(content) {
@@ -399,6 +432,10 @@ async function eligibility(workflowId, content, payload, handlers) {
399
432
  };
400
433
  return { eligible: true };
401
434
  }
435
+ if (workflowId === "permanent-delete") return status === "deleted" ? { eligible: true } : {
436
+ eligible: false,
437
+ reason: "not_deleted"
438
+ };
402
439
  if (status === "deleted") return {
403
440
  eligible: false,
404
441
  reason: "deleted"
@@ -542,6 +579,10 @@ async function applyWorkflow(workflowId, content, expectedUpdatedAt, payload, ru
542
579
  content.status = input.status;
543
580
  await save();
544
581
  return;
582
+ case "permanent-delete":
583
+ await content.withTransaction(async () => void 0);
584
+ await content.delete({ expectedUpdatedAt });
585
+ return;
545
586
  case "automated-review":
546
587
  await content.runReviewAction({
547
588
  expectedUpdatedAt,
@@ -695,7 +736,7 @@ function defaultDescriptor(maxSelectionSize) {
695
736
  ]
696
737
  },
697
738
  controls: [],
698
- actions: CONTENT_LIST_WORKFLOWS.map((entry) => ({
739
+ actions: CONTENT_LIST_SERVER_ACTIONS.map((entry) => ({
699
740
  id: entry.id,
700
741
  label: entry.label,
701
742
  description: entry.description,
@@ -720,6 +761,7 @@ function createContentListActionAdapter(options) {
720
761
  if (descriptor.limits.maxSelectionSize !== maxSelectionSize) throw new Error("ContentList descriptor maxSelectionSize must match the server selection cap");
721
762
  const resolvedByRequest = /* @__PURE__ */ new WeakMap();
722
763
  const contentByRequest = /* @__PURE__ */ new WeakMap();
764
+ const invocationResources = new AsyncLocalStorage();
723
765
  async function loadContent(invocation, rowId) {
724
766
  const key = String(rowId);
725
767
  let byRow = contentByRequest.get(invocation.request);
@@ -732,6 +774,11 @@ function createContentListActionAdapter(options) {
732
774
  pending = (async () => {
733
775
  const content = await (await options.collection(invocation.run)).get({ id: key });
734
776
  if (!content) return null;
777
+ const serialized = content.toJSON();
778
+ invocationResources.getStore()?.set(key, {
779
+ resourceId: String(content.id),
780
+ resourceType: typeof serialized._meta_type === "string" ? serialized._meta_type : content.constructor.name
781
+ });
735
782
  const expected = resolvedByRequest.get(invocation.request)?.rows.find((row) => String(row.id) === key);
736
783
  const revisionValue = (value) => value instanceof Date ? value.toISOString() : String(value ?? "");
737
784
  if (!expected || revisionValue(content.updated_at) !== revisionValue(expected.updated_at)) throw new ContentListActionError("row_revision_drifted");
@@ -741,8 +788,8 @@ function createContentListActionAdapter(options) {
741
788
  }
742
789
  return pending;
743
790
  }
744
- const mapActionError = (error) => error instanceof ContentListActionError ? error.reason : isRecord(error) && error.code === "RUNTIME_REVISION_CONFLICT" ? "row_revision_drifted" : isPermissionDenied(error) || error instanceof PrincipalToolNotAllowedError ? "denied" : void 0;
745
- const definitions = Object.fromEntries(CONTENT_LIST_WORKFLOWS.map((entry) => [entry.id, {
791
+ const mapActionError = (error) => error instanceof ContentListActionError ? error.reason : isRecord$1(error) && error.code === "RUNTIME_REVISION_CONFLICT" ? "row_revision_drifted" : isPermissionDenied(error) || error instanceof PrincipalToolNotAllowedError ? "denied" : void 0;
792
+ const definitions = Object.fromEntries(CONTENT_LIST_SERVER_ACTIONS.map((entry) => [entry.id, {
746
793
  descriptor: {
747
794
  id: entry.id,
748
795
  label: entry.label,
@@ -783,17 +830,43 @@ function createContentListActionAdapter(options) {
783
830
  if (!content) throw new Error("content not found");
784
831
  const expectedUpdatedAt = content.updated_at;
785
832
  if (!(expectedUpdatedAt instanceof Date) && typeof expectedUpdatedAt !== "string") throw new ContentListActionError("row_revision_drifted");
786
- await applyWorkflow(entry.id, content, expectedUpdatedAt, invocation.request.payload, invocation.run, handlers);
787
- return null;
833
+ const resource = invocationResources.getStore()?.get(String(rowId));
834
+ try {
835
+ await applyWorkflow(entry.id, content, expectedUpdatedAt, invocation.request.payload, invocation.run, handlers);
836
+ } catch (error) {
837
+ if (entry.id !== "permanent-delete") throw error;
838
+ if (await (await options.collection(invocation.run)).get({ id: String(rowId) })) throw error;
839
+ }
840
+ return resource ?? null;
788
841
  }
789
842
  }]));
790
843
  const generic = createDataSurfaceActionAdapter({
791
- state: options.state,
844
+ state: {
845
+ putToken: (...args) => options.state.putToken(...args),
846
+ getToken: (...args) => options.state.getToken(...args),
847
+ markTokenConsumed: (...args) => options.state.markTokenConsumed(...args),
848
+ getIdempotency: (...args) => options.state.getIdempotency(...args),
849
+ reserveIdempotency: (...args) => options.state.reserveIdempotency(...args),
850
+ completeIdempotency: (key, ownerToken, result) => {
851
+ if (result.details) result.details = {
852
+ ...result.details,
853
+ auditReference: result.requestId
854
+ };
855
+ return options.state.completeIdempotency(key, ownerToken, result);
856
+ },
857
+ releaseIdempotency: (...args) => options.state.releaseIdempotency(...args)
858
+ },
792
859
  backgroundQueue: options.backgroundQueue,
793
860
  tokenTtlMs: options.tokenTtlMs,
794
861
  runAsPrincipal: options.runAsPrincipal,
795
862
  resolveDeferredPrincipal: options.resolveDeferredPrincipal,
796
- requestFingerprintExtension: (request) => request.target,
863
+ requestFingerprintExtension: (request) => (() => {
864
+ const target = request.target;
865
+ return {
866
+ expectedCount: target.expectedCount,
867
+ ...target.query ? { query: target.query } : {}
868
+ };
869
+ })(),
797
870
  mapError: mapActionError,
798
871
  resolveSurface: async (run) => ({
799
872
  descriptor,
@@ -817,20 +890,41 @@ function createContentListActionAdapter(options) {
817
890
  const invalid = validateTarget(request);
818
891
  if (invalid) return actionResult(request, false, invalid);
819
892
  try {
820
- const result = await generic[phase](request, context);
821
- if (phase !== "preview" || !result.ok) return result;
893
+ const resources = /* @__PURE__ */ new Map();
894
+ const result = await invocationResources.run(resources, () => generic[phase](request, context));
822
895
  const resolved = resolvedByRequest.get(request);
823
- const workflow2 = CONTENT_LIST_WORKFLOWS.find((entry) => entry.id === request.actionId);
896
+ const workflow2 = CONTENT_LIST_SERVER_ACTIONS.find((entry) => entry.id === request.actionId);
897
+ const outcomes = Array.isArray(result.details?.outcomes) ? result.details.outcomes.map((outcome) => {
898
+ if (!isRecord$1(outcome)) return outcome;
899
+ const resource = resources?.get(String(outcome.rowId)) ?? (typeof outcome.resourceId === "string" && typeof outcome.resourceType === "string" ? {
900
+ resourceId: outcome.resourceId,
901
+ resourceType: outcome.resourceType
902
+ } : void 0);
903
+ return resource ? {
904
+ ...outcome,
905
+ ...resource
906
+ } : outcome;
907
+ }) : void 0;
908
+ if (phase !== "preview" || !result.ok) return {
909
+ ...result,
910
+ ...result.details ? { details: {
911
+ ...result.details,
912
+ ...outcomes ? { outcomes } : {},
913
+ auditReference: typeof result.details.auditReference === "string" ? result.details.auditReference : request.requestId
914
+ } } : {}
915
+ };
824
916
  return {
825
917
  ...result,
826
918
  details: {
827
919
  ...result.details ?? {},
920
+ ...outcomes ? { outcomes } : {},
828
921
  resolvedScope: resolved?.scope ?? request.selection.scope,
829
922
  representativeLabels: resolved?.representativeLabels ?? [],
830
- ineligible: Array.isArray(result.details?.outcomes) ? result.details.outcomes.filter((entry) => isRecord(entry) && entry.status === "skipped") : [],
923
+ ineligible: Array.isArray(result.details?.outcomes) ? result.details.outcomes.filter((entry) => isRecord$1(entry) && entry.status === "skipped") : [],
831
924
  consequences: workflow2?.consequences ?? [],
832
925
  sensitivity: workflow2?.sensitivity ?? "public",
833
- execution: workflow2?.execution ?? "foreground"
926
+ execution: workflow2?.execution ?? "foreground",
927
+ auditReference: request.requestId
834
928
  }
835
929
  };
836
930
  } catch (error) {
@@ -845,6 +939,134 @@ function createContentListActionAdapter(options) {
845
939
  };
846
940
  }
847
941
  //#endregion
942
+ //#region src/server/content-list-data-surface.ts
943
+ var CONTENT_LIST_DATA_SURFACE_ID = "content-list";
944
+ var CONTENT_LIST_DATA_SURFACE_COLLECTION = "contents";
945
+ function requiredName(value, fallback, label) {
946
+ const resolved = value ?? fallback;
947
+ if (resolved.trim().length === 0) throw new Error(`${label} must be a non-empty string`);
948
+ return resolved;
949
+ }
950
+ function querySchema(schema) {
951
+ return {
952
+ ...schema,
953
+ fields: schema.fields.filter(({ sensitive, readPermission }) => {
954
+ if (sensitive) return false;
955
+ return !readPermission;
956
+ }).map(({ sensitive: _sensitive, readPermission: _readPermission, metadata: _metadata, ...field }) => field)
957
+ };
958
+ }
959
+ async function resolveCollection(options, context) {
960
+ return typeof options.collection === "function" ? options.collection(context) : options.collection;
961
+ }
962
+ async function resolveScope(options, context) {
963
+ return typeof options.scope === "function" ? options.scope(context) : options.scope;
964
+ }
965
+ async function createContentListDataSurfaceDefinition(options) {
966
+ const executableSchema = querySchema(options.schema ?? await buildContentQuerySchema());
967
+ assertContentQuerySchema(executableSchema);
968
+ return {
969
+ id: requiredName(options.id, CONTENT_LIST_DATA_SURFACE_ID, "ContentList data surface id"),
970
+ collection: requiredName(options.collectionName, CONTENT_LIST_DATA_SURFACE_COLLECTION, "ContentList permission collection"),
971
+ className: CONTENT_QUERY_CLASS_NAME,
972
+ label: options.label ?? "Contents",
973
+ description: options.description ?? "Bounded, tenant-safe content rows, counts, facets, and continuations.",
974
+ metadata: {
975
+ domain: "content",
976
+ adapter: "ContentList",
977
+ views: [
978
+ "grid",
979
+ "detailed",
980
+ "compact"
981
+ ],
982
+ queryModes: [
983
+ "rows",
984
+ "count",
985
+ "facets"
986
+ ],
987
+ ...options.metadata
988
+ },
989
+ schema: executableSchema,
990
+ execute: async (_surface, request, context) => {
991
+ normalizeDataQueryRequest(request, executableSchema);
992
+ return executeContentQuery(await resolveCollection(options, context), request, {
993
+ schema: executableSchema,
994
+ scope: await resolveScope(options, context)
995
+ });
996
+ }
997
+ };
998
+ }
999
+ //#endregion
1000
+ //#region src/server/content-list-lifecycle.ts
1001
+ function isRecord(value) {
1002
+ return !!value && typeof value === "object" && !Array.isArray(value);
1003
+ }
1004
+ function isLifecycleActionId(value) {
1005
+ return CONTENT_LIST_LIFECYCLE_ACTION_IDS.includes(value);
1006
+ }
1007
+ function safeIdentity(value) {
1008
+ if (!isRecord(value)) return {
1009
+ surfaceId: "content-list",
1010
+ kind: "table"
1011
+ };
1012
+ if (typeof value.surfaceId !== "string" || ![
1013
+ "table",
1014
+ "list",
1015
+ "report",
1016
+ "custom"
1017
+ ].includes(String(value.kind))) return {
1018
+ surfaceId: "content-list",
1019
+ kind: "table"
1020
+ };
1021
+ return value;
1022
+ }
1023
+ function rejected(request, reason) {
1024
+ const candidate = isRecord(request) ? request : {};
1025
+ return {
1026
+ version: 1,
1027
+ requestId: typeof candidate.requestId === "string" ? candidate.requestId : "invalid-request",
1028
+ identity: safeIdentity(candidate.identity),
1029
+ actionId: typeof candidate.actionId === "string" ? candidate.actionId : "invalid",
1030
+ phase: candidate.phase === "apply" ? "apply" : "preview",
1031
+ ok: false,
1032
+ reason
1033
+ };
1034
+ }
1035
+ function createContentListLifecycleService(adapter) {
1036
+ return { async invoke(request, context) {
1037
+ if (!isRecord(request)) return rejected(request, "invalid_request");
1038
+ if (!isLifecycleActionId(request.actionId)) return rejected(request, "unsupported");
1039
+ if (request.phase !== "preview" && request.phase !== "apply") return rejected(request, "invalid_request");
1040
+ return adapter[request.phase](request, context);
1041
+ } };
1042
+ }
1043
+ function createContentListLifecycleRoute(options) {
1044
+ const service = createContentListLifecycleService(options.adapter);
1045
+ return async (request) => {
1046
+ if (request.method !== "POST") return Response.json({ error: { message: "Method not allowed." } }, {
1047
+ status: 405,
1048
+ headers: { allow: "POST" }
1049
+ });
1050
+ let input;
1051
+ try {
1052
+ input = await request.json();
1053
+ } catch {
1054
+ return Response.json({ error: { message: "The lifecycle request body must be JSON." } }, { status: 400 });
1055
+ }
1056
+ let context;
1057
+ try {
1058
+ context = await options.context(request);
1059
+ } catch {
1060
+ return Response.json({ error: { message: "Authentication is required." } }, { status: 401 });
1061
+ }
1062
+ try {
1063
+ return Response.json({ result: await service.invoke(input, context) });
1064
+ } catch {
1065
+ return Response.json({ error: { message: "The lifecycle request could not be completed." } }, { status: 500 });
1066
+ }
1067
+ };
1068
+ }
1069
+ //#endregion
848
1070
  //#region src/server.ts
849
1071
  async function startServer() {
850
1072
  console.log("🚀 Starting SMRT Content Server...");
@@ -869,6 +1091,6 @@ async function startServer() {
869
1091
  }
870
1092
  if (import.meta.url === `file://${process.argv[1]}`) startServer().catch(console.error);
871
1093
  //#endregion
872
- export { CONTENT_LIST_WORKFLOWS, CONTENT_LIST_WORKFLOW_IDS, UnsupportedContentListWorkflowStorageError, assertContentListWorkflowStorageSupported, createContentListActionAdapter, startServer };
1094
+ export { CONTENT_LIST_DATA_SURFACE_COLLECTION, CONTENT_LIST_DATA_SURFACE_ID, CONTENT_LIST_LIFECYCLE_ACTIONS, CONTENT_LIST_LIFECYCLE_ACTION_IDS, CONTENT_LIST_WORKFLOWS, CONTENT_LIST_WORKFLOW_IDS, UnsupportedContentListWorkflowStorageError, assertContentListWorkflowStorageSupported, createContentListActionAdapter, createContentListDataSurfaceDefinition, createContentListLifecycleRoute, createContentListLifecycleService, startServer };
873
1095
 
874
1096
  //# sourceMappingURL=server.js.map