@happyvertical/smrt-content 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.
Files changed (144) hide show
  1. package/agents/content-list.md +61 -5
  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-D1bLBzMT.js +4092 -0
  5. package/dist/chunks/{content-query-4w62u5_0.js.map → content-query-D1bLBzMT.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-Di3vcTgb.js → content-versions-B0OUI1ut.js} +6 -3
  9. package/dist/chunks/content-versions-B0OUI1ut.js.map +1 -0
  10. package/dist/chunks/{contents-BV8RoP_R.js → contents-CRG2Snrb.js} +2 -2
  11. package/dist/chunks/{contents-BV8RoP_R.js.map → contents-CRG2Snrb.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 +33 -6
  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-lifecycle.d.ts +20 -0
  20. package/dist/server/content-list-lifecycle.d.ts.map +1 -0
  21. package/dist/server.d.ts +1 -0
  22. package/dist/server.d.ts.map +1 -1
  23. package/dist/server.js +189 -25
  24. package/dist/server.js.map +1 -1
  25. package/dist/smrt-knowledge.json +17 -5
  26. package/dist/svelte/components/ContentAgentChat.svelte +10 -0
  27. package/dist/svelte/components/ContentAgentChat.svelte.d.ts +10 -0
  28. package/dist/svelte/components/ContentAgentChat.svelte.d.ts.map +1 -1
  29. package/dist/svelte/components/ContentBodyEditor.svelte +9 -0
  30. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts +9 -0
  31. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts.map +1 -1
  32. package/dist/svelte/components/ContentBodyRenderer.svelte +3 -0
  33. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts +3 -0
  34. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts.map +1 -1
  35. package/dist/svelte/components/ContentClaimAuditTool.svelte +3 -0
  36. package/dist/svelte/components/ContentClaimAuditTool.svelte.d.ts +3 -0
  37. package/dist/svelte/components/ContentClaimAuditTool.svelte.d.ts.map +1 -1
  38. package/dist/svelte/components/ContentContributionForm.svelte +7 -0
  39. package/dist/svelte/components/ContentContributionForm.svelte.d.ts +7 -0
  40. package/dist/svelte/components/ContentContributionForm.svelte.d.ts.map +1 -1
  41. package/dist/svelte/components/ContentContributionInbox.svelte +8 -0
  42. package/dist/svelte/components/ContentContributionInbox.svelte.d.ts +8 -0
  43. package/dist/svelte/components/ContentContributionInbox.svelte.d.ts.map +1 -1
  44. package/dist/svelte/components/ContentContributionPortal.svelte +5 -0
  45. package/dist/svelte/components/ContentContributionPortal.svelte.d.ts +5 -0
  46. package/dist/svelte/components/ContentContributionPortal.svelte.d.ts.map +1 -1
  47. package/dist/svelte/components/ContentContributionTypeManager.svelte +3 -0
  48. package/dist/svelte/components/ContentContributionTypeManager.svelte.d.ts +3 -0
  49. package/dist/svelte/components/ContentContributionTypeManager.svelte.d.ts.map +1 -1
  50. package/dist/svelte/components/ContentContributorManager.svelte +3 -0
  51. package/dist/svelte/components/ContentContributorManager.svelte.d.ts +3 -0
  52. package/dist/svelte/components/ContentContributorManager.svelte.d.ts.map +1 -1
  53. package/dist/svelte/components/ContentCorrectionsTool.svelte +4 -0
  54. package/dist/svelte/components/ContentCorrectionsTool.svelte.d.ts +4 -0
  55. package/dist/svelte/components/ContentCorrectionsTool.svelte.d.ts.map +1 -1
  56. package/dist/svelte/components/ContentEditor.svelte +16 -0
  57. package/dist/svelte/components/ContentEditor.svelte.d.ts +16 -0
  58. package/dist/svelte/components/ContentEditor.svelte.d.ts.map +1 -1
  59. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte +4 -0
  60. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte.d.ts +4 -0
  61. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte.d.ts.map +1 -1
  62. package/dist/svelte/components/ContentGovernanceManager.svelte +3 -0
  63. package/dist/svelte/components/ContentGovernanceManager.svelte.d.ts +3 -0
  64. package/dist/svelte/components/ContentGovernanceManager.svelte.d.ts.map +1 -1
  65. package/dist/svelte/components/ContentGovernancePanel.svelte +16 -0
  66. package/dist/svelte/components/ContentGovernancePanel.svelte.d.ts +16 -0
  67. package/dist/svelte/components/ContentGovernancePanel.svelte.d.ts.map +1 -1
  68. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte +3 -0
  69. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte.d.ts +3 -0
  70. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte.d.ts.map +1 -1
  71. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte +4 -0
  72. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte.d.ts +4 -0
  73. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte.d.ts.map +1 -1
  74. package/dist/svelte/components/ContentGovernanceTool.svelte +5 -0
  75. package/dist/svelte/components/ContentGovernanceTool.svelte.d.ts +5 -0
  76. package/dist/svelte/components/ContentGovernanceTool.svelte.d.ts.map +1 -1
  77. package/dist/svelte/components/ContentImageBrowser.svelte +10 -0
  78. package/dist/svelte/components/ContentImageBrowser.svelte.d.ts +10 -0
  79. package/dist/svelte/components/ContentImageBrowser.svelte.d.ts.map +1 -1
  80. package/dist/svelte/components/ContentImageChooser.svelte +4 -0
  81. package/dist/svelte/components/ContentImageChooser.svelte.d.ts +4 -0
  82. package/dist/svelte/components/ContentImageChooser.svelte.d.ts.map +1 -1
  83. package/dist/svelte/components/ContentList.svelte +201 -22
  84. package/dist/svelte/components/ContentList.svelte.d.ts +13 -0
  85. package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -1
  86. package/dist/svelte/components/ContentListLifecyclePanel.svelte +341 -0
  87. package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts +17 -0
  88. package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts.map +1 -0
  89. package/dist/svelte/components/ContentMetadataFields.svelte +2 -0
  90. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts +2 -0
  91. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts.map +1 -1
  92. package/dist/svelte/components/ContentReferencesPanel.svelte +3 -0
  93. package/dist/svelte/components/ContentReferencesPanel.svelte.d.ts +3 -0
  94. package/dist/svelte/components/ContentReferencesPanel.svelte.d.ts.map +1 -1
  95. package/dist/svelte/components/ContentReviewStatusTray.svelte +5 -0
  96. package/dist/svelte/components/ContentReviewStatusTray.svelte.d.ts +5 -0
  97. package/dist/svelte/components/ContentReviewStatusTray.svelte.d.ts.map +1 -1
  98. package/dist/svelte/components/ContentStatusFields.svelte +2 -0
  99. package/dist/svelte/components/ContentStatusFields.svelte.d.ts +2 -0
  100. package/dist/svelte/components/ContentStatusFields.svelte.d.ts.map +1 -1
  101. package/dist/svelte/components/ContentTitleField.svelte +4 -0
  102. package/dist/svelte/components/ContentTitleField.svelte.d.ts +4 -0
  103. package/dist/svelte/components/ContentTitleField.svelte.d.ts.map +1 -1
  104. package/dist/svelte/components/ContentTransparencyReport.svelte +3 -0
  105. package/dist/svelte/components/ContentTransparencyReport.svelte.d.ts +3 -0
  106. package/dist/svelte/components/ContentTransparencyReport.svelte.d.ts.map +1 -1
  107. package/dist/svelte/components/ContentTransparencyTool.svelte +3 -0
  108. package/dist/svelte/components/ContentTransparencyTool.svelte.d.ts +3 -0
  109. package/dist/svelte/components/ContentTransparencyTool.svelte.d.ts.map +1 -1
  110. package/dist/svelte/components/ContentVersionsTool.svelte +3 -0
  111. package/dist/svelte/components/ContentVersionsTool.svelte.d.ts +3 -0
  112. package/dist/svelte/components/ContentVersionsTool.svelte.d.ts.map +1 -1
  113. package/dist/svelte/components/GovernedContentEditor.svelte +20 -0
  114. package/dist/svelte/components/GovernedContentEditor.svelte.d.ts +20 -0
  115. package/dist/svelte/components/GovernedContentEditor.svelte.d.ts.map +1 -1
  116. package/dist/svelte/content-list-lifecycle.d.ts +132 -0
  117. package/dist/svelte/content-list-lifecycle.d.ts.map +1 -0
  118. package/dist/svelte/content-list-lifecycle.js +439 -0
  119. package/dist/svelte/i18n.contribution.d.ts +27 -0
  120. package/dist/svelte/i18n.contribution.d.ts.map +1 -1
  121. package/dist/svelte/i18n.contribution.js +27 -0
  122. package/dist/svelte/index.d.ts +1 -0
  123. package/dist/svelte/index.d.ts.map +1 -1
  124. package/dist/svelte/index.js +1 -0
  125. package/dist/svelte/routes/ContentContributionsRoute.svelte +4 -0
  126. package/dist/svelte/routes/ContentContributionsRoute.svelte.d.ts +4 -0
  127. package/dist/svelte/routes/ContentContributionsRoute.svelte.d.ts.map +1 -1
  128. package/dist/svelte/routes/ContentFactsRoute.svelte +5 -0
  129. package/dist/svelte/routes/ContentFactsRoute.svelte.d.ts +5 -0
  130. package/dist/svelte/routes/ContentFactsRoute.svelte.d.ts.map +1 -1
  131. package/dist/svelte/routes/ContentGovernanceRoute.svelte +4 -0
  132. package/dist/svelte/routes/ContentGovernanceRoute.svelte.d.ts +4 -0
  133. package/dist/svelte/routes/ContentGovernanceRoute.svelte.d.ts.map +1 -1
  134. package/dist/svelte/routes/ContentWorkspaceRoute.svelte +5 -0
  135. package/dist/svelte/routes/ContentWorkspaceRoute.svelte.d.ts +5 -0
  136. package/dist/svelte/routes/ContentWorkspaceRoute.svelte.d.ts.map +1 -1
  137. package/dist/svelte/routes/PublishedArticleRoute.svelte +3 -0
  138. package/dist/svelte/routes/PublishedArticleRoute.svelte.d.ts +3 -0
  139. package/dist/svelte/routes/PublishedArticleRoute.svelte.d.ts.map +1 -1
  140. package/package.json +16 -15
  141. package/dist/chunks/content-corrections-BxfA3tW1.js.map +0 -1
  142. package/dist/chunks/content-query-4w62u5_0.js +0 -4092
  143. package/dist/chunks/content-reviews-BWrYEQc6.js.map +0 -1
  144. package/dist/chunks/content-versions-Di3vcTgb.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-content",
5
- "packageVersion": "0.43.10",
5
+ "packageVersion": "0.44.1",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-content:ContentAsset": {
8
8
  "name": "contentasset",
@@ -1610,7 +1610,10 @@
1610
1610
  "promotedContentId": {
1611
1611
  "type": "foreignKey",
1612
1612
  "required": false,
1613
- "related": "Content"
1613
+ "related": "Content",
1614
+ "_meta": {
1615
+ "nullable": true
1616
+ }
1614
1617
  },
1615
1618
  "revisionCount": {
1616
1619
  "type": "integer",
@@ -5751,7 +5754,13 @@
5751
5754
  "delete": {
5752
5755
  "name": "delete",
5753
5756
  "async": true,
5754
- "parameters": [],
5757
+ "parameters": [
5758
+ {
5759
+ "name": "options",
5760
+ "type": "SmrtDeleteOptions",
5761
+ "optional": true
5762
+ }
5763
+ ],
5755
5764
  "returnType": "Promise<void>",
5756
5765
  "isStatic": false,
5757
5766
  "isPublic": true
@@ -7475,7 +7484,13 @@
7475
7484
  "delete": {
7476
7485
  "name": "delete",
7477
7486
  "async": true,
7478
- "parameters": [],
7487
+ "parameters": [
7488
+ {
7489
+ "name": "options",
7490
+ "type": "SmrtDeleteOptions",
7491
+ "optional": true
7492
+ }
7493
+ ],
7479
7494
  "returnType": "Promise<void>",
7480
7495
  "isStatic": false,
7481
7496
  "isPublic": true
@@ -9228,7 +9243,13 @@
9228
9243
  "delete": {
9229
9244
  "name": "delete",
9230
9245
  "async": true,
9231
- "parameters": [],
9246
+ "parameters": [
9247
+ {
9248
+ "name": "options",
9249
+ "type": "SmrtDeleteOptions",
9250
+ "optional": true
9251
+ }
9252
+ ],
9232
9253
  "returnType": "Promise<void>",
9233
9254
  "isStatic": false,
9234
9255
  "isPublic": true
@@ -11418,7 +11439,13 @@
11418
11439
  "delete": {
11419
11440
  "name": "delete",
11420
11441
  "async": true,
11421
- "parameters": [],
11442
+ "parameters": [
11443
+ {
11444
+ "name": "options",
11445
+ "type": "SmrtDeleteOptions",
11446
+ "optional": true
11447
+ }
11448
+ ],
11422
11449
  "returnType": "Promise<void>",
11423
11450
  "isStatic": false,
11424
11451
  "isPublic": true
@@ -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,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,6 @@ 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-lifecycle.js';
5
6
  export { startServer };
6
7
  //# 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,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-4w62u5_0.js";
1
+ import { v as buildContentQuerySchema, w as Content, x as executeContentQuery } from "./chunks/content-query-D1bLBzMT.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,76 @@ function createContentListActionAdapter(options) {
845
939
  };
846
940
  }
847
941
  //#endregion
942
+ //#region src/server/content-list-lifecycle.ts
943
+ function isRecord(value) {
944
+ return !!value && typeof value === "object" && !Array.isArray(value);
945
+ }
946
+ function isLifecycleActionId(value) {
947
+ return CONTENT_LIST_LIFECYCLE_ACTION_IDS.includes(value);
948
+ }
949
+ function safeIdentity(value) {
950
+ if (!isRecord(value)) return {
951
+ surfaceId: "content-list",
952
+ kind: "table"
953
+ };
954
+ if (typeof value.surfaceId !== "string" || ![
955
+ "table",
956
+ "list",
957
+ "report",
958
+ "custom"
959
+ ].includes(String(value.kind))) return {
960
+ surfaceId: "content-list",
961
+ kind: "table"
962
+ };
963
+ return value;
964
+ }
965
+ function rejected(request, reason) {
966
+ const candidate = isRecord(request) ? request : {};
967
+ return {
968
+ version: 1,
969
+ requestId: typeof candidate.requestId === "string" ? candidate.requestId : "invalid-request",
970
+ identity: safeIdentity(candidate.identity),
971
+ actionId: typeof candidate.actionId === "string" ? candidate.actionId : "invalid",
972
+ phase: candidate.phase === "apply" ? "apply" : "preview",
973
+ ok: false,
974
+ reason
975
+ };
976
+ }
977
+ function createContentListLifecycleService(adapter) {
978
+ return { async invoke(request, context) {
979
+ if (!isRecord(request)) return rejected(request, "invalid_request");
980
+ if (!isLifecycleActionId(request.actionId)) return rejected(request, "unsupported");
981
+ if (request.phase !== "preview" && request.phase !== "apply") return rejected(request, "invalid_request");
982
+ return adapter[request.phase](request, context);
983
+ } };
984
+ }
985
+ function createContentListLifecycleRoute(options) {
986
+ const service = createContentListLifecycleService(options.adapter);
987
+ return async (request) => {
988
+ if (request.method !== "POST") return Response.json({ error: { message: "Method not allowed." } }, {
989
+ status: 405,
990
+ headers: { allow: "POST" }
991
+ });
992
+ let input;
993
+ try {
994
+ input = await request.json();
995
+ } catch {
996
+ return Response.json({ error: { message: "The lifecycle request body must be JSON." } }, { status: 400 });
997
+ }
998
+ let context;
999
+ try {
1000
+ context = await options.context(request);
1001
+ } catch {
1002
+ return Response.json({ error: { message: "Authentication is required." } }, { status: 401 });
1003
+ }
1004
+ try {
1005
+ return Response.json({ result: await service.invoke(input, context) });
1006
+ } catch {
1007
+ return Response.json({ error: { message: "The lifecycle request could not be completed." } }, { status: 500 });
1008
+ }
1009
+ };
1010
+ }
1011
+ //#endregion
848
1012
  //#region src/server.ts
849
1013
  async function startServer() {
850
1014
  console.log("🚀 Starting SMRT Content Server...");
@@ -869,6 +1033,6 @@ async function startServer() {
869
1033
  }
870
1034
  if (import.meta.url === `file://${process.argv[1]}`) startServer().catch(console.error);
871
1035
  //#endregion
872
- export { CONTENT_LIST_WORKFLOWS, CONTENT_LIST_WORKFLOW_IDS, UnsupportedContentListWorkflowStorageError, assertContentListWorkflowStorageSupported, createContentListActionAdapter, startServer };
1036
+ export { CONTENT_LIST_LIFECYCLE_ACTIONS, CONTENT_LIST_LIFECYCLE_ACTION_IDS, CONTENT_LIST_WORKFLOWS, CONTENT_LIST_WORKFLOW_IDS, UnsupportedContentListWorkflowStorageError, assertContentListWorkflowStorageSupported, createContentListActionAdapter, createContentListLifecycleRoute, createContentListLifecycleService, startServer };
873
1037
 
874
1038
  //# sourceMappingURL=server.js.map