@desplega.ai/agent-swarm 1.117.0 → 1.118.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 (105) hide show
  1. package/README.md +1 -0
  2. package/dist/{actions-7bnvhcgs.js → actions-fsdthmby.js} +5 -5
  3. package/dist/{app-976fykvr.js → app-d48rk7pp.js} +3 -3
  4. package/dist/{artifact-0874w6js.js → artifact-x7e6f41t.js} +1 -1
  5. package/dist/{assistant-5drs03t0.js → assistant-nqwh132h.js} +8 -8
  6. package/dist/{boot-reembed-0zhftca3.js → boot-reembed-vztw3kmn.js} +4 -4
  7. package/dist/{boot-reembed-wce58xfv.js → boot-reembed-z229xeg8.js} +3 -3
  8. package/dist/{boot-scrub-logs-vkd2vvxp.js → boot-scrub-logs-yqpj4x5g.js} +2 -2
  9. package/dist/{cli-e0xv4nd4.js → cli-20zj8pm5.js} +10 -7
  10. package/dist/{cli-1987vgjc.js → cli-2xp7h939.js} +3 -3
  11. package/dist/{cli-jkp1gndy.js → cli-48qxfdv4.js} +5 -5
  12. package/dist/{cli-fep22bhf.js → cli-4j0y68we.js} +2 -2
  13. package/dist/{cli-9kk0xa5w.js → cli-4xc1mc5x.js} +1 -1
  14. package/dist/{cli-w5axeg22.js → cli-60z5nrne.js} +1 -1
  15. package/dist/{cli-ndsyqqqk.js → cli-7g2e06cd.js} +2 -2
  16. package/dist/{cli-q0yn57de.js → cli-8j4fe76y.js} +1 -1
  17. package/dist/{cli-kfjs4fjw.js → cli-er0djds9.js} +1 -1
  18. package/dist/{cli-s5q026mr.js → cli-f5qm42kd.js} +702 -110
  19. package/dist/{cli-vwhg6sbn.js → cli-g97ggbfg.js} +2 -2
  20. package/dist/{cli-r06ed00c.js → cli-gwyaqc05.js} +212 -62
  21. package/dist/{cli-yarjrgd5.js → cli-hy7qcdk0.js} +1 -1
  22. package/dist/{cli-z824vphk.js → cli-jzyjzstk.js} +2 -2
  23. package/dist/{cli-m4p6c600.js → cli-k01wm82x.js} +5 -5
  24. package/dist/{cli-5ekf4gcj.js → cli-m3ybbmsm.js} +1 -1
  25. package/dist/{cli-xcp5dmts.js → cli-nh866k5t.js} +1 -1
  26. package/dist/{cli-xm2tyqfe.js → cli-ppwm8c6e.js} +11 -0
  27. package/dist/{cli-f5cx2j92.js → cli-r6yjwx5h.js} +2 -2
  28. package/dist/{cli-rymspw51.js → cli-sqp2bsy0.js} +1 -1
  29. package/dist/{cli-09j7m5v3.js → cli-st3frvaf.js} +4 -4
  30. package/dist/{cli-6058t3w0.js → cli-tzs999rv.js} +1 -1
  31. package/dist/{cli-hmw1vk30.js → cli-xck0rrm4.js} +1 -1
  32. package/dist/{cli-t6n84nqv.js → cli-yqc51axp.js} +5 -4
  33. package/dist/cli.js +10 -10
  34. package/dist/{commands-b3p0fjzd.js → commands-f6n33dnc.js} +2 -2
  35. package/dist/{db-6xw82vz3.js → db-h2rfvs2w.js} +16 -2
  36. package/dist/{handlers-kwrk085v.js → handlers-tr8hkw59.js} +8 -8
  37. package/dist/{hook-e4wdztg5.js → hook-h5337q9c.js} +1 -1
  38. package/dist/{http-x7svk8q5.js → http-6q6znnpp.js} +442 -80
  39. package/dist/{index-aadhkkde.js → index-5mxp943z.js} +10 -10
  40. package/dist/{index-zj38e3q2.js → index-bm63k39y.js} +9 -9
  41. package/dist/{index-35tw5g2v.js → index-qps3frqq.js} +45 -24
  42. package/dist/{index-qb6nfqmy.js → index-sqkw2pk3.js} +8 -8
  43. package/dist/{keepalive-enehyqc8.js → keepalive-zajb254h.js} +4 -4
  44. package/dist/{lead-nmzd0ykq.js → lead-k73hvgv5.js} +18 -18
  45. package/dist/{maintenance-staxb3xt.js → maintenance-8s5pwjje.js} +4 -4
  46. package/dist/{oauth-refresh-sweep-fqczcwxn.js → oauth-refresh-sweep-5qaqbyfx.js} +3 -3
  47. package/dist/{onboard-shmqj6ep.js → onboard-eds531mw.js} +2 -2
  48. package/dist/{otel-impl-726bmdyc.js → otel-impl-93kctmj7.js} +1 -1
  49. package/dist/{pricing-refresh-rzwka8rf.js → pricing-refresh-gn72ypzm.js} +4 -4
  50. package/dist/{rbac-roles-j2k0h8sx.js → rbac-roles-26qs5ckt.js} +2 -2
  51. package/dist/{rbac-roles-chkhakmf.js → rbac-roles-r01mzk0t.js} +3 -3
  52. package/dist/{seed-pricing-vta6a1q3.js → seed-pricing-299zvwxd.js} +3 -3
  53. package/dist/{setup-yv9ctywz.js → setup-fhysh4dg.js} +2 -2
  54. package/dist/{worker-7w6571j0.js → worker-ykxg0ttd.js} +18 -18
  55. package/openapi.json +369 -4
  56. package/package.json +1 -1
  57. package/plugin/skills/pages/SKILL.md +7 -0
  58. package/src/artifact-sdk/browser-sdk.ts +12 -0
  59. package/src/assets/key.ts +115 -0
  60. package/src/be/asset-key-audit.ts +210 -0
  61. package/src/be/asset-key-auth.ts +44 -0
  62. package/src/be/db.ts +721 -152
  63. package/src/be/migrations/115_asset_namespace_keys.sql +400 -0
  64. package/src/be/migrations/116_favorite_principal_scope.sql +38 -0
  65. package/src/be/seed-skills/index.ts +7 -0
  66. package/src/http/all-routes.ts +1 -0
  67. package/src/http/assets.ts +238 -0
  68. package/src/http/favorite-owner.ts +39 -0
  69. package/src/http/favorites.ts +17 -16
  70. package/src/http/index.ts +2 -0
  71. package/src/http/pages.ts +54 -13
  72. package/src/http/schedules.ts +44 -5
  73. package/src/http/stats.ts +3 -3
  74. package/src/http/tasks.ts +25 -1
  75. package/src/http/workflows.ts +52 -6
  76. package/src/scheduler/scheduler.test.ts +1 -0
  77. package/src/scheduler/scheduler.ts +1 -0
  78. package/src/tests/artifact-sdk.test.ts +9 -1
  79. package/src/tests/asset-key-api.test.ts +277 -0
  80. package/src/tests/asset-key-invariants.test.ts +233 -0
  81. package/src/tests/asset-key-mcp.test.ts +168 -0
  82. package/src/tests/asset-key-migration.test.ts +336 -0
  83. package/src/tests/asset-key-normalization.test.ts +68 -0
  84. package/src/tests/favorites.test.ts +37 -0
  85. package/src/tests/pool-affinity.test.ts +3 -1
  86. package/src/tests/script-connections.test.ts +2 -0
  87. package/src/tests/system-default-skills.test.ts +6 -0
  88. package/src/tests/ui-swarm-sdk.test.ts +81 -0
  89. package/src/tests/workflow-workspace.test.ts +2 -0
  90. package/src/tools/create-page.ts +32 -1
  91. package/src/tools/get-tasks.ts +11 -1
  92. package/src/tools/schedules/create-schedule.ts +14 -1
  93. package/src/tools/schedules/list-schedules.ts +8 -0
  94. package/src/tools/schedules/patch-schedule.ts +11 -1
  95. package/src/tools/schedules/update-schedule.ts +11 -1
  96. package/src/tools/send-task.ts +30 -0
  97. package/src/tools/task-action.ts +24 -0
  98. package/src/tools/workflows/create-workflow.ts +19 -1
  99. package/src/tools/workflows/list-workflows.ts +5 -3
  100. package/src/tools/workflows/patch-workflow.ts +7 -2
  101. package/src/tools/workflows/update-workflow.ts +6 -0
  102. package/src/types.ts +64 -2
  103. package/src/workflows/executors/agent-task.ts +4 -1
  104. package/templates/skills/asset-namespaces/config.json +14 -0
  105. package/templates/skills/asset-namespaces/content.md +60 -0
@@ -26,7 +26,7 @@ import {
26
26
  import {
27
27
  init_package,
28
28
  package_default
29
- } from "./cli-xcp5dmts.js";
29
+ } from "./cli-nh866k5t.js";
30
30
  import {
31
31
  init_secret_scrubber,
32
32
  scrubSecrets
@@ -46,6 +46,81 @@ function parseProviderMeta(rawProvider, rawMeta) {
46
46
  }
47
47
  var init_provider_metadata = () => {};
48
48
 
49
+ // src/assets/key.ts
50
+ function normalizeAssetKey(input) {
51
+ if (typeof input !== "string")
52
+ throw new AssetKeyError("Asset key must be a string");
53
+ if (input.includes("\x00"))
54
+ throw new AssetKeyError("Asset key cannot contain NUL bytes");
55
+ if (input.includes("\\"))
56
+ throw new AssetKeyError("Asset key must use forward slashes");
57
+ const normalized = input.trim().normalize("NFKC").toLowerCase();
58
+ if (!normalized)
59
+ throw new AssetKeyError("Asset key cannot be empty");
60
+ if (normalized.startsWith("/"))
61
+ throw new AssetKeyError("Asset key must be relative");
62
+ const withTrailingSlash = normalized.endsWith("/") ? normalized : `${normalized}/`;
63
+ if (withTrailingSlash.length > ASSET_KEY_MAX_LENGTH) {
64
+ throw new AssetKeyError(`Asset key cannot exceed ${ASSET_KEY_MAX_LENGTH} characters`);
65
+ }
66
+ const segments = withTrailingSlash.slice(0, -1).split("/");
67
+ if (segments.some((segment) => segment === "" || segment === "." || segment === "..")) {
68
+ throw new AssetKeyError("Asset key contains an empty or traversal segment");
69
+ }
70
+ const root = segments[0];
71
+ if (root !== "shared" && root !== "personal") {
72
+ throw new AssetKeyError("Asset key root must be shared or personal");
73
+ }
74
+ if (root === "personal" && !segments[1]) {
75
+ throw new AssetKeyError("Personal asset keys require a canonical user ID");
76
+ }
77
+ return withTrailingSlash;
78
+ }
79
+ function defaultAssetKey(resource, id) {
80
+ if (!id.trim())
81
+ throw new AssetKeyError("Asset key resource ID cannot be empty");
82
+ return normalizeAssetKey(`shared/${resource}:${id}/`);
83
+ }
84
+ function parseAssetKey(input) {
85
+ const key = normalizeAssetKey(input);
86
+ const segments = key.slice(0, -1).split("/");
87
+ if (segments[0] === "personal") {
88
+ return {
89
+ root: "personal",
90
+ key,
91
+ segments,
92
+ userId: segments[1],
93
+ relativeSegments: segments.slice(2)
94
+ };
95
+ }
96
+ return {
97
+ root: "shared",
98
+ key,
99
+ segments,
100
+ relativeSegments: segments.slice(1)
101
+ };
102
+ }
103
+ function isCanonicalAssetKey(input) {
104
+ try {
105
+ return normalizeAssetKey(input) === input;
106
+ } catch {
107
+ return false;
108
+ }
109
+ }
110
+ function canWriteAssetKey(input, trustedUserId) {
111
+ const parsed = parseAssetKey(input);
112
+ return parsed.root === "shared" || !!trustedUserId && parsed.userId === trustedUserId;
113
+ }
114
+ var ASSET_KEY_MAX_LENGTH = 255, AssetKeyError;
115
+ var init_key = __esm(() => {
116
+ AssetKeyError = class AssetKeyError extends Error {
117
+ constructor(message) {
118
+ super(message);
119
+ this.name = "AssetKeyError";
120
+ }
121
+ };
122
+ });
123
+
49
124
  // src/utils/template.ts
50
125
  function interpolate(template, ctx) {
51
126
  const unresolved = [];
@@ -728,9 +803,49 @@ function resolveTaskModelSelection(opts) {
728
803
  function isTerminalTaskStatus(status) {
729
804
  return TERMINAL_TASK_STATUSES.includes(status);
730
805
  }
731
- var ModelTierSchema, MODEL_TIERS, ReasoningEffortSchema, LEGACY_MODEL_TO_TIER, DEFAULT_MODEL_TIER_MAP, AgentTaskStatusSchema, TERMINAL_TASK_STATUSES, InboxMessageStatusSchema, InboxMessageSchema, AgentTaskSourceSchema, ProviderNameSchema, FollowUpConfigSchema, RoutingAffinitySchema, AgentTaskSchema, TaskAttachmentKindSchema, attachmentCommonFields, AttachmentInputSchema, TaskAttachmentSchema, UserSchema, IdentityEventTypeSchema, InboxItemTypeSchema, InboxItemStatusSchema, InboxItemStateSchema, FavoriteItemTypeSchema, UserFavoriteSchema, TaskTemplateKindSchema, TaskTemplateSchema, AgentStatusSchema, AgentSchema, AgentCredStatusLiveTestSchema, AgentLatestModelSchema, AgentBedrockStatusSchema, AgentCredStatusSchema, AgentWithTasksSchema, ChangeSourceSchema, VersionableFieldSchema, ContextVersionSchema, ChannelTypeSchema, ChannelSchema, ChannelMessageSchema, ServiceStatusSchema, ServiceSchema, AgentLogEventTypeSchema, ResumeReasonSchema, AgentLogSchema, SessionLogSchema, SessionCostSourceSchema, SessionCostSchema, EventCategorySchema, EventStatusSchema, EventSourceSchema, EventNameSchema, SwarmEventSchema, ScheduledTaskTargetTypeSchema, ScheduledTaskSchema, SwarmConfigScopeSchema, SwarmConfigSchema, RepoGuidelinesSchema, RepoHooksSchema, SwarmRepoSchema, AgentMemoryScopeSchema, AgentMemorySourceSchema, AgentMemorySchema, ActiveSessionSchema, RetryPolicySchema, ExecutorMetaSchema, ValidationResultSchema, StepValidationConfigSchema, SwarmScriptNodeConfigSchema, WorkflowNodeSchema, WorkflowEdgeSchema, WorkflowDefinitionSchema, WorkflowNodePatchSchema, WorkflowPatchSchema, WebhookVerificationSchema, TriggerConfigSchema, CooldownConfigSchema, InputValueSchema, WorkflowTemplateSchema, WorkflowSnapshotSchema, WorkflowSchema, WorkflowVersionSchema, PageContentTypeSchema, PageAuthModeSchema, PageSnapshotSchema, PageSchema, PageVersionSchema, MetricParamSchema, MetricVariableTypeSchema, MetricFormatSchema, MetricVisualizationSchema, MetricQuerySchema, MetricVariableSchema, MetricVizConfigSchema, MetricWidgetSchema, MetricDefinitionSchema, MetricSnapshotSchema, MetricSchema, MetricVersionSchema, WorkflowRunStatusSchema, WorkflowRunSchema, ScriptRunStatusSchema, TERMINAL_SCRIPT_RUN_STATUSES, ScriptRunKindSchema, ScriptRunSchema, ScriptRunListItemSchema, ScriptRunJournalEntrySchema, WorkflowRunStepStatusSchema, WorkflowRunStepSchema, WaitModeSchema, WaitStateStatusSchema, WaitStateRowSchema, PromptTemplateScopeSchema, PromptTemplateStateSchema, PromptTemplateSchema, PromptTemplateHistorySchema, ScriptScopeSchema, ScriptFsModeSchema, ScriptRecordSchema, ScriptVersionRecordSchema, ScriptApiAuthModeSchema, ScriptApiRecordSchema, SkillTypeSchema, SkillScopeSchema, SkillSchema, AgentSkillSchema, SkillWithInstallInfoSchema, SkillFileSchema, McpServerTransportSchema, McpServerScopeSchema, McpAuthMethodSchema, McpServerSchema, AgentMcpServerSchema, McpServerWithInstallInfoSchema, ContextSnapshotEventTypeSchema, ContextFormulaSchema, ContextSnapshotSchema, BudgetScopeSchema, BudgetSchema, PricingProviderSchema, PricingTokenClassSchema, PricingRowSchema, BudgetRefusalCauseSchema, BudgetRefusalNotificationSchema, BudgetRefusedTriggerSchema, KvValueTypeSchema, KV_NAME_REGEX, KvNamespaceSchema, KvKeySchema, KvEntrySchema;
806
+ var AssetKeySchema, AssetEntityTypeSchema, AssetProviderRefSchema, AssetKeyMappingSchema, AssetSummarySchema, ModelTierSchema, MODEL_TIERS, ReasoningEffortSchema, LEGACY_MODEL_TO_TIER, DEFAULT_MODEL_TIER_MAP, AgentTaskStatusSchema, TERMINAL_TASK_STATUSES, InboxMessageStatusSchema, InboxMessageSchema, AgentTaskSourceSchema, ProviderNameSchema, FollowUpConfigSchema, RoutingAffinitySchema, AgentTaskSchema, TaskAttachmentKindSchema, attachmentCommonFields, AttachmentInputSchema, TaskAttachmentSchema, UserSchema, IdentityEventTypeSchema, InboxItemTypeSchema, InboxItemStatusSchema, InboxItemStateSchema, FavoriteItemTypeSchema, UserFavoriteSchema, TaskTemplateKindSchema, TaskTemplateSchema, AgentStatusSchema, AgentSchema, AgentCredStatusLiveTestSchema, AgentLatestModelSchema, AgentBedrockStatusSchema, AgentCredStatusSchema, AgentWithTasksSchema, ChangeSourceSchema, VersionableFieldSchema, ContextVersionSchema, ChannelTypeSchema, ChannelSchema, ChannelMessageSchema, ServiceStatusSchema, ServiceSchema, AgentLogEventTypeSchema, ResumeReasonSchema, AgentLogSchema, SessionLogSchema, SessionCostSourceSchema, SessionCostSchema, EventCategorySchema, EventStatusSchema, EventSourceSchema, EventNameSchema, SwarmEventSchema, ScheduledTaskTargetTypeSchema, ScheduledTaskSchema, SwarmConfigScopeSchema, SwarmConfigSchema, RepoGuidelinesSchema, RepoHooksSchema, SwarmRepoSchema, AgentMemoryScopeSchema, AgentMemorySourceSchema, AgentMemorySchema, ActiveSessionSchema, RetryPolicySchema, ExecutorMetaSchema, ValidationResultSchema, StepValidationConfigSchema, SwarmScriptNodeConfigSchema, WorkflowNodeSchema, WorkflowEdgeSchema, WorkflowDefinitionSchema, WorkflowNodePatchSchema, WorkflowPatchSchema, WebhookVerificationSchema, TriggerConfigSchema, CooldownConfigSchema, InputValueSchema, WorkflowTemplateSchema, WorkflowSnapshotSchema, WorkflowSchema, WorkflowVersionSchema, PageContentTypeSchema, PageAuthModeSchema, PageSnapshotSchema, PageSchema, PageVersionSchema, MetricParamSchema, MetricVariableTypeSchema, MetricFormatSchema, MetricVisualizationSchema, MetricQuerySchema, MetricVariableSchema, MetricVizConfigSchema, MetricWidgetSchema, MetricDefinitionSchema, MetricSnapshotSchema, MetricSchema, MetricVersionSchema, WorkflowRunStatusSchema, WorkflowRunSchema, ScriptRunStatusSchema, TERMINAL_SCRIPT_RUN_STATUSES, ScriptRunKindSchema, ScriptRunSchema, ScriptRunListItemSchema, ScriptRunJournalEntrySchema, WorkflowRunStepStatusSchema, WorkflowRunStepSchema, WaitModeSchema, WaitStateStatusSchema, WaitStateRowSchema, PromptTemplateScopeSchema, PromptTemplateStateSchema, PromptTemplateSchema, PromptTemplateHistorySchema, ScriptScopeSchema, ScriptFsModeSchema, ScriptRecordSchema, ScriptVersionRecordSchema, ScriptApiAuthModeSchema, ScriptApiRecordSchema, SkillTypeSchema, SkillScopeSchema, SkillSchema, AgentSkillSchema, SkillWithInstallInfoSchema, SkillFileSchema, McpServerTransportSchema, McpServerScopeSchema, McpAuthMethodSchema, McpServerSchema, AgentMcpServerSchema, McpServerWithInstallInfoSchema, ContextSnapshotEventTypeSchema, ContextFormulaSchema, ContextSnapshotSchema, BudgetScopeSchema, BudgetSchema, PricingProviderSchema, PricingTokenClassSchema, PricingRowSchema, BudgetRefusalCauseSchema, BudgetRefusalNotificationSchema, BudgetRefusedTriggerSchema, KvValueTypeSchema, KV_NAME_REGEX, KvNamespaceSchema, KvKeySchema, KvEntrySchema;
732
807
  var init_types = __esm(() => {
733
808
  init_zod();
809
+ init_key();
810
+ AssetKeySchema = string().min(1).max(255).superRefine((value, ctx) => {
811
+ try {
812
+ normalizeAssetKey(value);
813
+ } catch (error) {
814
+ ctx.addIssue({
815
+ code: "custom",
816
+ message: error instanceof Error ? error.message : "Invalid asset namespace key"
817
+ });
818
+ }
819
+ }).describe("Non-unique asset directory namespace (for example shared/ or personal/<user-id>/drafts/). Runtime write boundaries normalize and validate the canonical form.");
820
+ AssetEntityTypeSchema = _enum(["task", "workflow", "schedule", "page", "file"]);
821
+ AssetProviderRefSchema = object({
822
+ providerId: string(),
823
+ orgId: string().optional(),
824
+ driveId: string().optional(),
825
+ providerKey: string()
826
+ });
827
+ AssetKeyMappingSchema = object({
828
+ id: string(),
829
+ providerId: string(),
830
+ providerOrgId: string().optional(),
831
+ providerDriveId: string().optional(),
832
+ providerKey: string(),
833
+ key: AssetKeySchema,
834
+ sourceEntityType: _enum(["task-attachment", "external"]).optional(),
835
+ sourceEntityId: string().optional(),
836
+ createdAt: exports_iso.datetime(),
837
+ updatedAt: exports_iso.datetime(),
838
+ createdBy: string().optional(),
839
+ updatedBy: string().optional()
840
+ });
841
+ AssetSummarySchema = object({
842
+ entityType: AssetEntityTypeSchema,
843
+ id: string(),
844
+ key: AssetKeySchema,
845
+ label: string(),
846
+ updatedAt: string(),
847
+ providerRef: AssetProviderRefSchema.optional()
848
+ });
734
849
  ModelTierSchema = _enum(["smol", "regular", "smart", "ultra"]);
735
850
  MODEL_TIERS = ModelTierSchema.options;
736
851
  ReasoningEffortSchema = _enum(["off", "low", "medium", "high", "xhigh", "max"]);
@@ -849,6 +964,7 @@ var init_types = __esm(() => {
849
964
  });
850
965
  AgentTaskSchema = object({
851
966
  id: uuid(),
967
+ key: AssetKeySchema,
852
968
  agentId: uuid().nullable(),
853
969
  creatorAgentId: uuid().optional(),
854
970
  task: string().min(1),
@@ -1029,7 +1145,7 @@ var init_types = __esm(() => {
1029
1145
  FavoriteItemTypeSchema = _enum(["page", "workflow", "schedule"]);
1030
1146
  UserFavoriteSchema = object({
1031
1147
  id: string(),
1032
- userId: string(),
1148
+ userId: string().optional(),
1033
1149
  itemType: FavoriteItemTypeSchema,
1034
1150
  itemId: string(),
1035
1151
  createdAt: string(),
@@ -1300,6 +1416,7 @@ var init_types = __esm(() => {
1300
1416
  ScheduledTaskTargetTypeSchema = _enum(["agent-task", "workflow", "script"]);
1301
1417
  ScheduledTaskSchema = object({
1302
1418
  id: uuid(),
1419
+ key: AssetKeySchema,
1303
1420
  name: string().min(1).max(100),
1304
1421
  description: string().optional(),
1305
1422
  cronExpression: string().optional(),
@@ -1568,6 +1685,7 @@ var init_types = __esm(() => {
1568
1685
  });
1569
1686
  WorkflowSchema = object({
1570
1687
  id: string().uuid(),
1688
+ key: AssetKeySchema,
1571
1689
  name: string(),
1572
1690
  description: string().optional(),
1573
1691
  enabled: boolean(),
@@ -1606,6 +1724,7 @@ var init_types = __esm(() => {
1606
1724
  });
1607
1725
  PageSchema = object({
1608
1726
  id: string(),
1727
+ key: AssetKeySchema,
1609
1728
  agentId: string(),
1610
1729
  slug: string(),
1611
1730
  title: string(),
@@ -2112,6 +2231,153 @@ var init_request_auth_context = __esm(() => {
2112
2231
  authStorage = new AsyncLocalStorage;
2113
2232
  });
2114
2233
 
2234
+ // src/be/asset-key-audit.ts
2235
+ function auditKeyRow(db, entityType, row) {
2236
+ if (!row.key) {
2237
+ return [
2238
+ {
2239
+ severity: "fatal",
2240
+ code: "missing-key",
2241
+ entityType,
2242
+ entityId: row.id,
2243
+ message: "Asset key is missing or empty."
2244
+ }
2245
+ ];
2246
+ }
2247
+ if (!isCanonicalAssetKey(row.key)) {
2248
+ return [
2249
+ {
2250
+ severity: "fatal",
2251
+ code: "noncanonical-key",
2252
+ entityType,
2253
+ entityId: row.id,
2254
+ message: "Asset key is not in canonical v1 form."
2255
+ }
2256
+ ];
2257
+ }
2258
+ const parsed = parseAssetKey(row.key);
2259
+ if (parsed.root === "personal") {
2260
+ const user = db.prepare("SELECT EXISTS(SELECT 1 FROM users WHERE id = ?) AS present").get(parsed.userId);
2261
+ if (!user?.present) {
2262
+ return [
2263
+ {
2264
+ severity: "warning",
2265
+ code: "unknown-personal-user",
2266
+ entityType,
2267
+ entityId: row.id,
2268
+ message: "Personal namespace references a user that no longer exists."
2269
+ }
2270
+ ];
2271
+ }
2272
+ }
2273
+ return [];
2274
+ }
2275
+ function auditAssetKeys(db) {
2276
+ const issues = [];
2277
+ let checked = 0;
2278
+ for (const table of KEY_TABLES) {
2279
+ const rows = db.prepare(table.sql).all();
2280
+ checked += rows.length;
2281
+ for (const row of rows)
2282
+ issues.push(...auditKeyRow(db, table.entityType, row));
2283
+ }
2284
+ const attachmentMappings = db.prepare(`SELECT
2285
+ a.id AS attachment_id,
2286
+ t."key" AS task_key,
2287
+ m.id AS mapping_id,
2288
+ m."key" AS mapping_key
2289
+ FROM task_attachments a
2290
+ JOIN agent_tasks t ON t.id = a.task_id
2291
+ LEFT JOIN asset_key_mappings m
2292
+ ON m.provider_id = COALESCE(NULLIF(a.provider_id, ''), 'agent-fs')
2293
+ AND m.provider_org_id = COALESCE(a.agent_fs_org_id, '')
2294
+ AND m.provider_drive_id = COALESCE(a.agent_fs_drive_id, '')
2295
+ AND m.provider_key = COALESCE(NULLIF(a.provider_key, ''), a.path)
2296
+ WHERE a.kind = 'agent-fs'
2297
+ AND COALESCE(NULLIF(a.provider_key, ''), a.path) IS NOT NULL`).all();
2298
+ for (const row of attachmentMappings) {
2299
+ if (!row.mapping_id) {
2300
+ issues.push({
2301
+ severity: "warning",
2302
+ code: "missing-provider-mapping",
2303
+ entityType: "file",
2304
+ entityId: row.attachment_id,
2305
+ message: "Agent-fs attachment has no logical namespace mapping."
2306
+ });
2307
+ } else if (row.mapping_key !== row.task_key) {
2308
+ issues.push({
2309
+ severity: "warning",
2310
+ code: "provider-mapping-drift",
2311
+ entityType: "file",
2312
+ entityId: row.mapping_id,
2313
+ message: "Provider mapping namespace differs from its parent task namespace."
2314
+ });
2315
+ }
2316
+ }
2317
+ const sourcedMappings = db.prepare(`SELECT
2318
+ m.id AS mapping_id,
2319
+ m.source_entity_id,
2320
+ a.id AS attachment_id,
2321
+ t."key" AS task_key,
2322
+ m."key" AS mapping_key,
2323
+ CASE WHEN a.id IS NOT NULL
2324
+ AND m.provider_id = COALESCE(NULLIF(a.provider_id, ''), 'agent-fs')
2325
+ AND m.provider_org_id = COALESCE(a.agent_fs_org_id, '')
2326
+ AND m.provider_drive_id = COALESCE(a.agent_fs_drive_id, '')
2327
+ AND m.provider_key = COALESCE(NULLIF(a.provider_key, ''), a.path)
2328
+ THEN 1 ELSE 0 END AS tuple_matches
2329
+ FROM asset_key_mappings m
2330
+ LEFT JOIN task_attachments a ON a.id = m.source_entity_id
2331
+ LEFT JOIN agent_tasks t ON t.id = a.task_id
2332
+ WHERE m.source_entity_type = 'task-attachment'`).all();
2333
+ for (const row of sourcedMappings) {
2334
+ if (!row.attachment_id || row.tuple_matches !== 1 || row.task_key !== row.mapping_key) {
2335
+ issues.push({
2336
+ severity: "warning",
2337
+ code: "provider-mapping-drift",
2338
+ entityType: "file",
2339
+ entityId: row.mapping_id,
2340
+ message: "Provider mapping source or tuple has drifted from its attachment."
2341
+ });
2342
+ }
2343
+ }
2344
+ const fatalCount = issues.filter((issue) => issue.severity === "fatal").length;
2345
+ const warningCount = issues.length - fatalCount;
2346
+ return {
2347
+ ok: issues.length === 0,
2348
+ structuralValid: fatalCount === 0,
2349
+ checked,
2350
+ fatalCount,
2351
+ warningCount,
2352
+ issues
2353
+ };
2354
+ }
2355
+ function enforceAssetKeyStartupAudit(db) {
2356
+ const result = auditAssetKeys(db);
2357
+ if (result.warningCount > 0) {
2358
+ console.warn(`[asset-keys] Startup audit found ${result.warningCount} repairable warning(s)`);
2359
+ }
2360
+ if (result.structuralValid)
2361
+ return result;
2362
+ const message = `[asset-keys] Startup audit found ${result.fatalCount} structurally invalid row(s)`;
2363
+ if (process.env.ASSET_KEY_AUDIT_DISABLE_STARTUP_HARD_FAIL === "true") {
2364
+ console.warn(`${message}; hard-fail temporarily disabled`);
2365
+ return result;
2366
+ }
2367
+ throw new Error(message);
2368
+ }
2369
+ var KEY_TABLES;
2370
+ var init_asset_key_audit = __esm(() => {
2371
+ init_key();
2372
+ KEY_TABLES = [
2373
+ { entityType: "task", sql: 'SELECT id, "key" as key FROM agent_tasks' },
2374
+ { entityType: "workflow", sql: 'SELECT id, "key" as key FROM workflows' },
2375
+ { entityType: "schedule", sql: 'SELECT id, "key" as key FROM scheduled_tasks' },
2376
+ { entityType: "page", sql: 'SELECT id, "key" as key FROM pages' },
2377
+ { entityType: "file", sql: 'SELECT id, "key" as key FROM asset_key_mappings' }
2378
+ ];
2379
+ });
2380
+
2115
2381
  // src/be/crypto/secrets-cipher.ts
2116
2382
  import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2117
2383
  function assertKey(key) {
@@ -3838,6 +4104,7 @@ __export(exports_db, {
3838
4104
  upsertInboxState: () => upsertInboxState,
3839
4105
  upsertChannelActivityCursor: () => upsertChannelActivityCursor,
3840
4106
  upsertBudget: () => upsertBudget,
4107
+ upsertAssetKeyMapping: () => upsertAssetKeyMapping,
3841
4108
  updateWorkflowRunStep: () => updateWorkflowRunStep,
3842
4109
  updateWorkflowRun: () => updateWorkflowRun,
3843
4110
  updateWorkflow: () => updateWorkflow,
@@ -3874,6 +4141,7 @@ __export(exports_db, {
3874
4141
  shouldBlockPolling: () => shouldBlockPolling,
3875
4142
  setUserFavorite: () => setUserFavorite,
3876
4143
  setSlackMessageTracking: () => setSlackMessageTracking,
4144
+ setFavorite: () => setFavorite,
3877
4145
  setBudgetRefusalFollowUpTaskId: () => setBudgetRefusalFollowUpTaskId,
3878
4146
  setApiKeyName: () => setApiKeyName,
3879
4147
  setAgentHarnessProvider: () => setAgentHarnessProvider,
@@ -3904,6 +4172,7 @@ __export(exports_db, {
3904
4172
  normalizeSkillFilePath: () => normalizeSkillFilePath,
3905
4173
  moveTaskToBacklog: () => moveTaskToBacklog,
3906
4174
  moveTaskFromBacklog: () => moveTaskFromBacklog,
4175
+ moveAssetKey: () => moveAssetKey,
3907
4176
  maskSecrets: () => maskSecrets,
3908
4177
  markTasksNotified: () => markTasksNotified,
3909
4178
  markTaskSlackReplySent: () => markTaskSlackReplySent,
@@ -3926,6 +4195,8 @@ __export(exports_db, {
3926
4195
  listMcpServers: () => listMcpServers,
3927
4196
  listKv: () => listKv,
3928
4197
  listInboxState: () => listInboxState,
4198
+ listFavorites: () => listFavorites,
4199
+ listAssetSummaries: () => listAssetSummaries,
3929
4200
  listApprovalRequests: () => listApprovalRequests,
3930
4201
  listAllPages: () => listAllPages,
3931
4202
  listAllMetrics: () => listAllMetrics,
@@ -4093,6 +4364,8 @@ __export(exports_db, {
4093
4364
  getBudgetRefusalNotification: () => getBudgetRefusalNotification,
4094
4365
  getBudget: () => getBudget,
4095
4366
  getAvailableKeyIndices: () => getAvailableKeyIndices,
4367
+ getAssetKeyMappingByProvider: () => getAssetKeyMappingByProvider,
4368
+ getAssetKeyMapping: () => getAssetKeyMapping,
4096
4369
  getApprovalRequestByStepId: () => getApprovalRequestByStepId,
4097
4370
  getApprovalRequestById: () => getApprovalRequestById,
4098
4371
  getAllUsers: () => getAllUsers,
@@ -4219,6 +4492,10 @@ __export(exports_db, {
4219
4492
  KvTypeCollisionError: () => KvTypeCollisionError
4220
4493
  });
4221
4494
  import { Database } from "bun:sqlite";
4495
+ function assetKeyPrefixPattern(input) {
4496
+ const canonical = normalizeAssetKey(input);
4497
+ return `${canonical.replace(/[\\%_]/g, "\\$&")}%`;
4498
+ }
4222
4499
  function emitTaskLifecycleTelemetryAfterCommit(event, props, verify) {
4223
4500
  queueMicrotask(() => {
4224
4501
  if (verify && !verify(getTaskById(props.taskId)))
@@ -4269,6 +4546,7 @@ function initDb(dbPath = "./agent-swarm-db.sqlite") {
4269
4546
  db.run("PRAGMA foreign_keys = ON;");
4270
4547
  loadSqliteVec(db);
4271
4548
  configureDbResolver(resolvePromptTemplate);
4549
+ enforceAssetKeyStartupAudit(db);
4272
4550
  resolveEncryptionKey(dbPath);
4273
4551
  return db;
4274
4552
  }
@@ -4294,81 +4572,25 @@ function initDb(dbPath = "./agent-swarm-db.sqlite") {
4294
4572
  if (needsStatusMigration) {
4295
4573
  console.log("[Migration] Removing restrictive CHECK constraint on agent_tasks.status");
4296
4574
  db.run("PRAGMA foreign_keys=off");
4297
- db.run(`
4298
- CREATE TABLE agent_tasks_new (
4299
- id TEXT PRIMARY KEY,
4300
- agentId TEXT,
4301
- creatorAgentId TEXT,
4302
- task TEXT NOT NULL,
4303
- status TEXT NOT NULL DEFAULT 'pending',
4304
- source TEXT NOT NULL DEFAULT 'mcp' CHECK(source IN ('mcp', 'slack', 'api', 'github', 'agentmail', 'system', 'schedule')),
4305
- taskType TEXT,
4306
- tags TEXT DEFAULT '[]',
4307
- priority INTEGER DEFAULT 50,
4308
- dependsOn TEXT DEFAULT '[]',
4309
- offeredTo TEXT,
4310
- offeredAt TEXT,
4311
- acceptedAt TEXT,
4312
- rejectionReason TEXT,
4313
- slackChannelId TEXT,
4314
- slackThreadTs TEXT,
4315
- slackUserId TEXT,
4316
- createdAt TEXT NOT NULL,
4317
- lastUpdatedAt TEXT NOT NULL,
4318
- finishedAt TEXT,
4319
- failureReason TEXT,
4320
- output TEXT,
4321
- progress TEXT,
4322
- notifiedAt TEXT,
4323
- mentionMessageId TEXT,
4324
- mentionChannelId TEXT,
4325
- githubRepo TEXT,
4326
- githubEventType TEXT,
4327
- githubNumber INTEGER,
4328
- githubCommentId INTEGER,
4329
- githubAuthor TEXT,
4330
- githubUrl TEXT,
4331
- parentTaskId TEXT,
4332
- claudeSessionId TEXT,
4333
- agentmailInboxId TEXT,
4334
- agentmailMessageId TEXT,
4335
- agentmailThreadId TEXT,
4336
- model TEXT,
4337
- scheduleId TEXT
4338
- )
4339
- `);
4340
- db.run(`
4341
- INSERT INTO agent_tasks_new (
4342
- id, agentId, creatorAgentId, task, status, source, taskType, tags,
4343
- priority, dependsOn, offeredTo, offeredAt, acceptedAt, rejectionReason,
4344
- slackChannelId, slackThreadTs, slackUserId, createdAt, lastUpdatedAt,
4345
- finishedAt, failureReason, output, progress, notifiedAt,
4346
- mentionMessageId, mentionChannelId, githubRepo, githubEventType,
4347
- githubNumber, githubCommentId, githubAuthor, githubUrl,
4348
- parentTaskId, claudeSessionId,
4349
- agentmailInboxId, agentmailMessageId, agentmailThreadId,
4350
- model, scheduleId
4351
- )
4352
- SELECT
4353
- id, agentId, creatorAgentId, task, status, source, taskType, tags,
4354
- priority, dependsOn, offeredTo, offeredAt, acceptedAt, rejectionReason,
4355
- slackChannelId, slackThreadTs, slackUserId, createdAt, lastUpdatedAt,
4356
- finishedAt, failureReason, output, progress, notifiedAt,
4357
- mentionMessageId, mentionChannelId, githubRepo, githubEventType,
4358
- githubNumber, githubCommentId, githubAuthor, githubUrl,
4359
- parentTaskId, claudeSessionId,
4360
- agentmailInboxId, agentmailMessageId, agentmailThreadId,
4361
- model, scheduleId
4362
- FROM agent_tasks
4363
- `);
4364
- db.run("DROP TABLE agent_tasks");
4365
- db.run("ALTER TABLE agent_tasks_new RENAME TO agent_tasks");
4366
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_agentId ON agent_tasks(agentId)");
4367
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_status ON agent_tasks(status)");
4368
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_offeredTo ON agent_tasks(offeredTo)");
4369
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_taskType ON agent_tasks(taskType)");
4370
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_agentmailThreadId ON agent_tasks(agentmailThreadId)");
4371
- db.run("CREATE INDEX IF NOT EXISTS idx_agent_tasks_schedule_id ON agent_tasks(scheduleId)");
4575
+ const rebuiltSchemaSql = schemaSql.replace(/^(CREATE TABLE\s+(?:IF NOT EXISTS\s+)?)(?:"agent_tasks"|agent_tasks)/i, "$1agent_tasks_new").replace(/\s+CHECK\s*\(\s*status\s+IN\s*\([^)]*\)\s*\)/i, "");
4576
+ if (rebuiltSchemaSql === schemaSql || !/agent_tasks_new/i.test(rebuiltSchemaSql)) {
4577
+ throw new Error("Could not derive agent_tasks schema without legacy status CHECK");
4578
+ }
4579
+ const columns = db.prepare('PRAGMA table_info("agent_tasks")').all().map((column) => `"${column.name.replaceAll('"', '""')}"`).join(", ");
4580
+ const schemaObjects = db.prepare(`SELECT sql FROM sqlite_master
4581
+ WHERE tbl_name = 'agent_tasks'
4582
+ AND type IN ('index', 'trigger')
4583
+ AND sql IS NOT NULL
4584
+ ORDER BY type, name`).all().map((row) => row.sql);
4585
+ database.transaction(() => {
4586
+ database.run("DROP TABLE IF EXISTS agent_tasks_new");
4587
+ database.run(rebuiltSchemaSql);
4588
+ database.run(`INSERT INTO agent_tasks_new (${columns}) SELECT ${columns} FROM agent_tasks`);
4589
+ database.run("DROP TABLE agent_tasks");
4590
+ database.run("ALTER TABLE agent_tasks_new RENAME TO agent_tasks");
4591
+ for (const sql of schemaObjects)
4592
+ database.run(sql);
4593
+ })();
4372
4594
  db.run("PRAGMA foreign_keys=on");
4373
4595
  console.log("[Migration] Successfully removed CHECK constraint on agent_tasks.status");
4374
4596
  }
@@ -4381,6 +4603,7 @@ function initDb(dbPath = "./agent-swarm-db.sqlite") {
4381
4603
  }
4382
4604
  throw e;
4383
4605
  }
4606
+ enforceAssetKeyStartupAudit(database);
4384
4607
  seedContextVersions();
4385
4608
  configureDbResolver(resolvePromptTemplate);
4386
4609
  seedDefaultTemplates();
@@ -4726,6 +4949,7 @@ function rowToAgentTask(row) {
4726
4949
  }
4727
4950
  return {
4728
4951
  id: row.id,
4952
+ key: row.key,
4729
4953
  agentId: row.agentId,
4730
4954
  creatorAgentId: row.creatorAgentId ?? undefined,
4731
4955
  task: row.task,
@@ -4799,6 +5023,7 @@ function rowToAgentTaskSummary(row) {
4799
5023
  const t = rowToAgentTask(row);
4800
5024
  return {
4801
5025
  id: t.id,
5026
+ key: t.key,
4802
5027
  agentId: t.agentId,
4803
5028
  creatorAgentId: t.creatorAgentId,
4804
5029
  task: previewText(t.task, TASK_PREVIEW_LENGTH),
@@ -4828,7 +5053,7 @@ function rowToAgentTaskSummary(row) {
4828
5053
  function createTask(agentId, task, options) {
4829
5054
  const id = crypto.randomUUID();
4830
5055
  const source2 = options?.source ?? "mcp";
4831
- const row = taskQueries.insert().get(id, agentId, task, "pending", source2, options?.slackChannelId ?? null, options?.slackThreadTs ?? null, options?.slackUserId ?? null, package_default.version);
5056
+ const row = taskQueries.insert().get(id, defaultAssetKey("task", id), agentId, task, "pending", source2, options?.slackChannelId ?? null, options?.slackThreadTs ?? null, options?.slackUserId ?? null, package_default.version);
4832
5057
  if (!row)
4833
5058
  throw new Error("Failed to create task");
4834
5059
  try {
@@ -5057,6 +5282,13 @@ function getAllTasks(filters, opts) {
5057
5282
  conditions.push("scheduleId = ?");
5058
5283
  params.push(filters.scheduleId);
5059
5284
  }
5285
+ if (filters?.key) {
5286
+ conditions.push('"key" = ?');
5287
+ params.push(normalizeAssetKey(filters.key));
5288
+ } else if (filters?.keyPrefix) {
5289
+ conditions.push(`"key" LIKE ? ESCAPE '\\'`);
5290
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
5291
+ }
5060
5292
  if (filters?.source && filters.source.length > 0) {
5061
5293
  const placeholders = filters.source.map(() => "?").join(", ");
5062
5294
  conditions.push(`source IN (${placeholders})`);
@@ -5152,6 +5384,13 @@ function getTasksCount(filters) {
5152
5384
  conditions.push("scheduleId = ?");
5153
5385
  params.push(filters.scheduleId);
5154
5386
  }
5387
+ if (filters?.key) {
5388
+ conditions.push('"key" = ?');
5389
+ params.push(normalizeAssetKey(filters.key));
5390
+ } else if (filters?.keyPrefix) {
5391
+ conditions.push(`"key" LIKE ? ESCAPE '\\'`);
5392
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
5393
+ }
5155
5394
  if (filters?.source && filters.source.length > 0) {
5156
5395
  const placeholders = filters.source.map(() => "?").join(", ");
5157
5396
  conditions.push(`source IN (${placeholders})`);
@@ -5739,6 +5978,28 @@ function stringifyAttachmentCapabilities(value) {
5739
5978
  return value ? JSON.stringify(value) : null;
5740
5979
  }
5741
5980
  function insertTaskAttachment(input) {
5981
+ return getDb().transaction(() => {
5982
+ const attachment = insertTaskAttachmentRow(input);
5983
+ if (attachment.kind === "agent-fs" && attachment.providerId && attachment.providerKey) {
5984
+ const task = getTaskById(input.taskId);
5985
+ if (!task)
5986
+ throw new Error(`Task not found while mapping attachment: ${input.taskId}`);
5987
+ upsertAssetKeyMapping({
5988
+ providerId: attachment.providerId,
5989
+ providerOrgId: attachment.orgId,
5990
+ providerDriveId: attachment.driveId,
5991
+ providerKey: attachment.providerKey,
5992
+ key: task.key,
5993
+ sourceEntityType: "task-attachment",
5994
+ sourceEntityId: attachment.id,
5995
+ createdBy: input.createdBy,
5996
+ updatedBy: input.updatedBy
5997
+ });
5998
+ }
5999
+ return attachment;
6000
+ })();
6001
+ }
6002
+ function insertTaskAttachmentRow(input) {
5742
6003
  const db2 = getDb();
5743
6004
  if (input.sha256) {
5744
6005
  const existing = db2.prepare("SELECT * FROM task_attachments WHERE task_id = ? AND sha256 = ? LIMIT 1").get(input.taskId, input.sha256);
@@ -5784,6 +6045,249 @@ function defaultProviderKey(input) {
5784
6045
  return input.pageId ?? null;
5785
6046
  return null;
5786
6047
  }
6048
+ function rowToAssetKeyMapping(row) {
6049
+ return {
6050
+ id: row.id,
6051
+ providerId: row.provider_id,
6052
+ providerOrgId: row.provider_org_id || undefined,
6053
+ providerDriveId: row.provider_drive_id || undefined,
6054
+ providerKey: row.provider_key,
6055
+ key: row.key,
6056
+ sourceEntityType: row.source_entity_type ?? undefined,
6057
+ sourceEntityId: row.source_entity_id ?? undefined,
6058
+ createdAt: row.created_at,
6059
+ updatedAt: row.updated_at,
6060
+ createdBy: row.created_by ?? undefined,
6061
+ updatedBy: row.updated_by ?? undefined
6062
+ };
6063
+ }
6064
+ function insertAssetKeyHistory(input) {
6065
+ getDb().run(`INSERT INTO asset_key_history
6066
+ (id, entity_type, entity_id, previous_key, new_key, changed_by)
6067
+ VALUES (?, ?, ?, ?, ?, ?)`, [
6068
+ crypto.randomUUID(),
6069
+ input.entityType,
6070
+ input.entityId,
6071
+ input.previousKey ?? null,
6072
+ input.newKey,
6073
+ input.changedBy ?? null
6074
+ ]);
6075
+ }
6076
+ function getAssetKeyMappingByProvider(input) {
6077
+ const row = getDb().prepare(`SELECT * FROM asset_key_mappings
6078
+ WHERE provider_id = ? AND provider_org_id = ?
6079
+ AND provider_drive_id = ? AND provider_key = ?`).get(input.providerId, input.providerOrgId ?? "", input.providerDriveId ?? "", input.providerKey);
6080
+ return row ? rowToAssetKeyMapping(row) : null;
6081
+ }
6082
+ function upsertAssetKeyMapping(input) {
6083
+ if (!input.providerId.trim())
6084
+ throw new Error("providerId is required");
6085
+ if (!input.providerKey.trim())
6086
+ throw new Error("providerKey is required");
6087
+ const now = new Date().toISOString();
6088
+ return getDb().transaction(() => {
6089
+ const existing = getAssetKeyMappingByProvider(input);
6090
+ if (existing) {
6091
+ const key2 = normalizeAssetKey(input.key ?? existing.key);
6092
+ const row2 = getDb().prepare(`UPDATE asset_key_mappings
6093
+ SET "key" = ?, source_entity_type = ?, source_entity_id = ?,
6094
+ updated_at = ?, updated_by = ?
6095
+ WHERE id = ? RETURNING *`).get(key2, input.sourceEntityType ?? existing.sourceEntityType ?? null, input.sourceEntityId ?? existing.sourceEntityId ?? null, now, input.updatedBy ?? input.createdBy ?? existing.updatedBy ?? null, existing.id);
6096
+ if (!row2)
6097
+ throw new Error("Failed to update asset key mapping");
6098
+ if (existing.key !== key2) {
6099
+ insertAssetKeyHistory({
6100
+ entityType: "file",
6101
+ entityId: existing.id,
6102
+ previousKey: existing.key,
6103
+ newKey: key2,
6104
+ changedBy: input.updatedBy ?? input.createdBy
6105
+ });
6106
+ }
6107
+ return rowToAssetKeyMapping(row2);
6108
+ }
6109
+ const id = crypto.randomUUID();
6110
+ const key = normalizeAssetKey(input.key ?? defaultAssetKey(`fs:${input.providerId.trim()}`, id));
6111
+ const row = getDb().prepare(`INSERT INTO asset_key_mappings (
6112
+ id, provider_id, provider_org_id, provider_drive_id, provider_key,
6113
+ "key", source_entity_type, source_entity_id,
6114
+ created_at, updated_at, created_by, updated_by
6115
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, input.providerId.trim(), input.providerOrgId ?? "", input.providerDriveId ?? "", input.providerKey, key, input.sourceEntityType ?? "external", input.sourceEntityId ?? null, now, now, input.createdBy ?? null, input.updatedBy ?? input.createdBy ?? null);
6116
+ if (!row)
6117
+ throw new Error("Failed to create asset key mapping");
6118
+ insertAssetKeyHistory({
6119
+ entityType: "file",
6120
+ entityId: id,
6121
+ newKey: key,
6122
+ changedBy: input.createdBy
6123
+ });
6124
+ return rowToAssetKeyMapping(row);
6125
+ })();
6126
+ }
6127
+ function getAssetKeyMapping(id) {
6128
+ const row = getDb().prepare("SELECT * FROM asset_key_mappings WHERE id = ?").get(id);
6129
+ return row ? rowToAssetKeyMapping(row) : null;
6130
+ }
6131
+ function assetSummaryQueries(types) {
6132
+ const queries = [];
6133
+ if (types.has("task")) {
6134
+ queries.push(`SELECT 'task' AS entityType, id, "key", 'Task ' || substr(id, 1, 8) AS label,
6135
+ lastUpdatedAt AS updatedAt, NULL AS providerId, NULL AS providerOrgId,
6136
+ NULL AS providerDriveId, NULL AS providerKey
6137
+ FROM agent_tasks`);
6138
+ }
6139
+ if (types.has("workflow")) {
6140
+ queries.push(`SELECT 'workflow' AS entityType, id, "key", name AS label,
6141
+ lastUpdatedAt AS updatedAt, NULL AS providerId, NULL AS providerOrgId,
6142
+ NULL AS providerDriveId, NULL AS providerKey
6143
+ FROM workflows`);
6144
+ }
6145
+ if (types.has("schedule")) {
6146
+ queries.push(`SELECT 'schedule' AS entityType, id, "key", name AS label,
6147
+ lastUpdatedAt AS updatedAt, NULL AS providerId, NULL AS providerOrgId,
6148
+ NULL AS providerDriveId, NULL AS providerKey
6149
+ FROM scheduled_tasks`);
6150
+ }
6151
+ if (types.has("page")) {
6152
+ queries.push(`SELECT 'page' AS entityType, id, "key", title AS label,
6153
+ updatedAt, NULL AS providerId, NULL AS providerOrgId,
6154
+ NULL AS providerDriveId, NULL AS providerKey
6155
+ FROM pages`);
6156
+ }
6157
+ if (types.has("file")) {
6158
+ queries.push(`SELECT 'file' AS entityType, id, "key", provider_key AS label,
6159
+ updated_at AS updatedAt, provider_id AS providerId,
6160
+ NULLIF(provider_org_id, '') AS providerOrgId,
6161
+ NULLIF(provider_drive_id, '') AS providerDriveId,
6162
+ provider_key AS providerKey
6163
+ FROM asset_key_mappings`);
6164
+ }
6165
+ return queries;
6166
+ }
6167
+ function listAssetSummaries(filters) {
6168
+ const requestedTypes = new Set(filters?.types?.length ? filters.types : ["task", "workflow", "schedule", "page", "file"]);
6169
+ const queries = assetSummaryQueries(requestedTypes);
6170
+ if (queries.length === 0)
6171
+ return [];
6172
+ const limit = Math.min(Math.max(filters?.limit ?? 500, 1), 1000);
6173
+ const params = [];
6174
+ let query = `SELECT * FROM (${queries.join(" UNION ALL ")})`;
6175
+ if (filters?.keyPrefix) {
6176
+ query += ` WHERE "key" LIKE ? ESCAPE '\\'`;
6177
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
6178
+ }
6179
+ query += ' ORDER BY "key" ASC, updatedAt DESC LIMIT ?';
6180
+ params.push(limit);
6181
+ const rows = getDb().prepare(query).all(...params);
6182
+ return rows.map((row) => ({
6183
+ entityType: row.entityType,
6184
+ id: row.id,
6185
+ key: row.key,
6186
+ label: row.label,
6187
+ updatedAt: row.updatedAt,
6188
+ providerRef: row.providerId && row.providerKey ? {
6189
+ providerId: row.providerId,
6190
+ orgId: row.providerOrgId ?? undefined,
6191
+ driveId: row.providerDriveId ?? undefined,
6192
+ providerKey: row.providerKey
6193
+ } : undefined
6194
+ }));
6195
+ }
6196
+ function currentAssetKey(entityType, id) {
6197
+ switch (entityType) {
6198
+ case "task":
6199
+ return getDb().prepare('SELECT "key" AS key FROM agent_tasks WHERE id = ?').get(id)?.key ?? null;
6200
+ case "workflow":
6201
+ return getDb().prepare('SELECT "key" AS key FROM workflows WHERE id = ?').get(id)?.key ?? null;
6202
+ case "schedule":
6203
+ return getDb().prepare('SELECT "key" AS key FROM scheduled_tasks WHERE id = ?').get(id)?.key ?? null;
6204
+ case "page":
6205
+ return getDb().prepare('SELECT "key" AS key FROM pages WHERE id = ?').get(id)?.key ?? null;
6206
+ case "file":
6207
+ return getAssetKeyMapping(id)?.key ?? null;
6208
+ }
6209
+ }
6210
+ function moveAssetKey(input) {
6211
+ const key = normalizeAssetKey(input.key);
6212
+ const audit = auditAssetKeys(getDb());
6213
+ if (!audit.ok) {
6214
+ throw new Error("Asset namespace moves are blocked until structural errors, unknown personal users, or provider mapping drift are repaired.");
6215
+ }
6216
+ const previousKey = currentAssetKey(input.entityType, input.id);
6217
+ if (!previousKey)
6218
+ return false;
6219
+ if (previousKey === key)
6220
+ return true;
6221
+ if (input.entityType === "file") {
6222
+ const mapping = getAssetKeyMapping(input.id);
6223
+ if (mapping?.sourceEntityType === "task-attachment") {
6224
+ throw new Error("Task attachment namespaces move with their parent task; move the task instead.");
6225
+ }
6226
+ }
6227
+ const now = new Date().toISOString();
6228
+ getDb().transaction(() => {
6229
+ switch (input.entityType) {
6230
+ case "task": {
6231
+ const mappedFiles = getDb().prepare(`SELECT DISTINCT m.id, m."key" AS key
6232
+ FROM asset_key_mappings m
6233
+ JOIN task_attachments a
6234
+ ON m.provider_id = COALESCE(NULLIF(a.provider_id, ''), 'agent-fs')
6235
+ AND m.provider_org_id = COALESCE(a.agent_fs_org_id, '')
6236
+ AND m.provider_drive_id = COALESCE(a.agent_fs_drive_id, '')
6237
+ AND m.provider_key = COALESCE(NULLIF(a.provider_key, ''), a.path)
6238
+ WHERE a.task_id = ?`).all(input.id);
6239
+ getDb().run('UPDATE agent_tasks SET "key" = ?, lastUpdatedAt = ?, updated_by = ? WHERE id = ?', [key, now, input.changedBy ?? null, input.id]);
6240
+ getDb().run(`UPDATE asset_key_mappings
6241
+ SET "key" = ?, updated_at = ?, updated_by = ?
6242
+ WHERE EXISTS (
6243
+ SELECT 1 FROM task_attachments a
6244
+ WHERE a.task_id = ?
6245
+ AND asset_key_mappings.provider_id = COALESCE(NULLIF(a.provider_id, ''), 'agent-fs')
6246
+ AND asset_key_mappings.provider_org_id = COALESCE(a.agent_fs_org_id, '')
6247
+ AND asset_key_mappings.provider_drive_id = COALESCE(a.agent_fs_drive_id, '')
6248
+ AND asset_key_mappings.provider_key = COALESCE(NULLIF(a.provider_key, ''), a.path)
6249
+ )`, [key, now, input.changedBy ?? null, input.id]);
6250
+ for (const mapping of mappedFiles) {
6251
+ if (mapping.key === key)
6252
+ continue;
6253
+ insertAssetKeyHistory({
6254
+ entityType: "file",
6255
+ entityId: mapping.id,
6256
+ previousKey: mapping.key,
6257
+ newKey: key,
6258
+ changedBy: input.changedBy
6259
+ });
6260
+ }
6261
+ break;
6262
+ }
6263
+ case "workflow":
6264
+ getDb().run('UPDATE workflows SET "key" = ?, lastUpdatedAt = ?, updated_by = ? WHERE id = ?', [key, now, input.changedBy ?? null, input.id]);
6265
+ break;
6266
+ case "schedule":
6267
+ getDb().run('UPDATE scheduled_tasks SET "key" = ?, lastUpdatedAt = ?, updated_by = ? WHERE id = ?', [key, now, input.changedBy ?? null, input.id]);
6268
+ break;
6269
+ case "page":
6270
+ getDb().run('UPDATE pages SET "key" = ?, updatedAt = ?, updated_by = ? WHERE id = ?', [
6271
+ key,
6272
+ now,
6273
+ input.changedBy ?? null,
6274
+ input.id
6275
+ ]);
6276
+ break;
6277
+ case "file":
6278
+ getDb().run('UPDATE asset_key_mappings SET "key" = ?, updated_at = ?, updated_by = ? WHERE id = ?', [key, now, input.changedBy ?? null, input.id]);
6279
+ break;
6280
+ }
6281
+ insertAssetKeyHistory({
6282
+ entityType: input.entityType,
6283
+ entityId: input.id,
6284
+ previousKey,
6285
+ newKey: key,
6286
+ changedBy: input.changedBy
6287
+ });
6288
+ })();
6289
+ return true;
6290
+ }
5787
6291
  function deleteTaskAttachment(id) {
5788
6292
  const result = getDb().run("DELETE FROM task_attachments WHERE id = ?", [id]);
5789
6293
  return result.changes > 0;
@@ -5958,6 +6462,9 @@ function createTaskExtended(task, options) {
5958
6462
  if (parent.requestedByUserId && !options.requestedByUserId) {
5959
6463
  options.requestedByUserId = parent.requestedByUserId;
5960
6464
  }
6465
+ if (parent.key && !options.key) {
6466
+ options.key = parent.key;
6467
+ }
5961
6468
  if (parent.contextKey && !options.contextKey) {
5962
6469
  options.contextKey = parent.contextKey;
5963
6470
  }
@@ -6014,8 +6521,9 @@ function createTaskExtended(task, options) {
6014
6521
  }
6015
6522
  }
6016
6523
  const auditUserId = getCurrentRequestUserId() ?? null;
6524
+ const assetKey = normalizeAssetKey(options?.key ?? defaultAssetKey("task", id));
6017
6525
  const row = getDb().prepare(`INSERT INTO agent_tasks (
6018
- id, agentId, creatorAgentId, task, status, source,
6526
+ id, "key", agentId, creatorAgentId, task, status, source,
6019
6527
  taskType, tags, priority, dependsOn, offeredTo, offeredAt,
6020
6528
  slackChannelId, slackThreadTs, slackUserId,
6021
6529
  vcsProvider, vcsRepo, vcsEventType, vcsNumber, vcsCommentId, vcsAuthor, vcsUrl,
@@ -6023,7 +6531,7 @@ function createTaskExtended(task, options) {
6023
6531
  agentmailInboxId, agentmailMessageId, agentmailThreadId,
6024
6532
  mentionMessageId, mentionChannelId, dir, parentTaskId, model, modelTier, effort, scheduleId,
6025
6533
  workflowRunId, workflowRunStepId, outputSchema, followUpConfig, requestedByUserId, contextKey, routingAffinity, swarmVersion, createdAt, lastUpdatedAt, created_by, updated_by
6026
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, options?.agentId ?? null, options?.creatorAgentId ?? null, task, status, options?.source ?? "mcp", options?.taskType ?? null, JSON.stringify(options?.tags ?? []), options?.priority ?? 50, JSON.stringify(options?.dependsOn ?? []), options?.offeredTo ?? null, options?.offeredTo ? now : null, options?.slackChannelId ?? null, options?.slackThreadTs ?? null, options?.slackUserId ?? null, options?.vcsProvider ?? null, options?.vcsRepo ?? null, options?.vcsEventType ?? null, options?.vcsNumber ?? null, options?.vcsCommentId ?? null, options?.vcsAuthor ?? null, options?.vcsUrl ?? null, options?.vcsInstallationId ?? null, options?.vcsNodeId ?? null, options?.agentmailInboxId ?? null, options?.agentmailMessageId ?? null, options?.agentmailThreadId ?? null, options?.mentionMessageId ?? null, options?.mentionChannelId ?? null, options?.dir ?? null, options?.parentTaskId ?? null, options?.model ?? null, options?.modelTier ?? null, options?.effort ?? null, options?.scheduleId ?? null, options?.workflowRunId ?? null, options?.workflowRunStepId ?? null, options?.outputSchema ? JSON.stringify(options.outputSchema) : null, options?.followUpConfig ? JSON.stringify(options.followUpConfig) : null, options?.requestedByUserId ?? null, options?.contextKey ?? null, options?.routingAffinity ? JSON.stringify(options.routingAffinity) : null, package_default.version, now, now, auditUserId, auditUserId);
6534
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, assetKey, options?.agentId ?? null, options?.creatorAgentId ?? null, task, status, options?.source ?? "mcp", options?.taskType ?? null, JSON.stringify(options?.tags ?? []), options?.priority ?? 50, JSON.stringify(options?.dependsOn ?? []), options?.offeredTo ?? null, options?.offeredTo ? now : null, options?.slackChannelId ?? null, options?.slackThreadTs ?? null, options?.slackUserId ?? null, options?.vcsProvider ?? null, options?.vcsRepo ?? null, options?.vcsEventType ?? null, options?.vcsNumber ?? null, options?.vcsCommentId ?? null, options?.vcsAuthor ?? null, options?.vcsUrl ?? null, options?.vcsInstallationId ?? null, options?.vcsNodeId ?? null, options?.agentmailInboxId ?? null, options?.agentmailMessageId ?? null, options?.agentmailThreadId ?? null, options?.mentionMessageId ?? null, options?.mentionChannelId ?? null, options?.dir ?? null, options?.parentTaskId ?? null, options?.model ?? null, options?.modelTier ?? null, options?.effort ?? null, options?.scheduleId ?? null, options?.workflowRunId ?? null, options?.workflowRunStepId ?? null, options?.outputSchema ? JSON.stringify(options.outputSchema) : null, options?.followUpConfig ? JSON.stringify(options.followUpConfig) : null, options?.requestedByUserId ?? null, options?.contextKey ?? null, options?.routingAffinity ? JSON.stringify(options.routingAffinity) : null, package_default.version, now, now, auditUserId, auditUserId);
6027
6535
  if (!row)
6028
6536
  throw new Error("Failed to create task");
6029
6537
  try {
@@ -7052,6 +7560,7 @@ function previewText(text, maxChars) {
7052
7560
  function rowToScheduledTask(row) {
7053
7561
  return {
7054
7562
  id: row.id,
7563
+ key: row.key,
7055
7564
  name: row.name,
7056
7565
  description: row.description ?? undefined,
7057
7566
  cronExpression: row.cronExpression ?? undefined,
@@ -7116,6 +7625,13 @@ function getScheduledTasks(filters, opts) {
7116
7625
  query += " AND scriptName = ?";
7117
7626
  params.push(filters.scriptName);
7118
7627
  }
7628
+ if (filters?.key) {
7629
+ query += ' AND "key" = ?';
7630
+ params.push(normalizeAssetKey(filters.key));
7631
+ } else if (filters?.keyPrefix) {
7632
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
7633
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
7634
+ }
7119
7635
  if (filters?.consecutiveErrorsMin !== undefined) {
7120
7636
  query += " AND consecutiveErrors >= ?";
7121
7637
  params.push(filters.consecutiveErrorsMin);
@@ -7144,12 +7660,12 @@ function createScheduledTask(data) {
7144
7660
  const id = crypto.randomUUID();
7145
7661
  const now = new Date().toISOString();
7146
7662
  const row = getDb().prepare(`INSERT INTO scheduled_tasks (
7147
- id, name, description, cronExpression, intervalMs, taskTemplate,
7663
+ id, "key", name, description, cronExpression, intervalMs, taskTemplate,
7148
7664
  taskType, tags, priority, targetAgentId, enabled, nextRunAt,
7149
7665
  createdByAgentId, timezone, model, modelTier, scheduleType, targetType,
7150
7666
  workflowId, scriptName, scriptArgs, createdAt, lastUpdatedAt,
7151
7667
  created_by, updated_by
7152
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, data.name, data.description ?? null, data.cronExpression ?? null, data.intervalMs ?? null, data.taskTemplate ?? null, data.taskType ?? null, JSON.stringify(data.tags ?? []), data.priority ?? 50, data.targetAgentId ?? null, data.enabled !== false ? 1 : 0, data.nextRunAt ?? null, data.createdByAgentId ?? null, data.timezone ?? "UTC", data.model ?? null, data.modelTier ?? null, data.scheduleType ?? "recurring", data.targetType ?? "agent-task", data.workflowId ?? null, data.scriptName ?? null, data.scriptArgs !== undefined ? JSON.stringify(data.scriptArgs) : "{}", now, now, data.createdBy ?? null, data.createdBy ?? null);
7668
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, normalizeAssetKey(data.key ?? defaultAssetKey("schedule", id)), data.name, data.description ?? null, data.cronExpression ?? null, data.intervalMs ?? null, data.taskTemplate ?? null, data.taskType ?? null, JSON.stringify(data.tags ?? []), data.priority ?? 50, data.targetAgentId ?? null, data.enabled !== false ? 1 : 0, data.nextRunAt ?? null, data.createdByAgentId ?? null, data.timezone ?? "UTC", data.model ?? null, data.modelTier ?? null, data.scheduleType ?? "recurring", data.targetType ?? "agent-task", data.workflowId ?? null, data.scriptName ?? null, data.scriptArgs !== undefined ? JSON.stringify(data.scriptArgs) : "{}", now, now, data.createdBy ?? null, data.createdBy ?? null);
7153
7669
  if (!row)
7154
7670
  throw new Error("Failed to create scheduled task");
7155
7671
  return rowToScheduledTask(row);
@@ -7157,6 +7673,10 @@ function createScheduledTask(data) {
7157
7673
  function updateScheduledTask(id, data) {
7158
7674
  const updates = [];
7159
7675
  const params = [];
7676
+ if (data.key !== undefined) {
7677
+ updates.push('"key" = ?');
7678
+ params.push(normalizeAssetKey(data.key));
7679
+ }
7160
7680
  if (data.name !== undefined) {
7161
7681
  updates.push("name = ?");
7162
7682
  params.push(data.name);
@@ -7737,6 +8257,7 @@ function getRecentFailedCount(hours = 24) {
7737
8257
  function rowToWorkflow(row) {
7738
8258
  return {
7739
8259
  id: row.id,
8260
+ key: row.key,
7740
8261
  name: row.name,
7741
8262
  description: row.description ?? undefined,
7742
8263
  enabled: row.enabled === 1,
@@ -7756,8 +8277,8 @@ function rowToWorkflow(row) {
7756
8277
  }
7757
8278
  function createWorkflow(data) {
7758
8279
  const id = crypto.randomUUID();
7759
- const row = getDb().prepare(`INSERT INTO workflows (id, name, description, definition, triggers, cooldown, input, triggerSchema, dir, vcs_repo, createdByAgentId, created_by, updated_by)
7760
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, data.name, data.description ?? null, JSON.stringify(data.definition), JSON.stringify(data.triggers ?? []), data.cooldown ? JSON.stringify(data.cooldown) : null, data.input ? JSON.stringify(data.input) : null, data.triggerSchema ? JSON.stringify(data.triggerSchema) : null, data.dir ?? null, data.vcsRepo ?? null, data.createdByAgentId ?? null, data.createdBy ?? null, data.createdBy ?? null);
8280
+ const row = getDb().prepare(`INSERT INTO workflows (id, "key", name, description, definition, triggers, cooldown, input, triggerSchema, dir, vcs_repo, createdByAgentId, created_by, updated_by)
8281
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, normalizeAssetKey(data.key ?? defaultAssetKey("workflow", id)), data.name, data.description ?? null, JSON.stringify(data.definition), JSON.stringify(data.triggers ?? []), data.cooldown ? JSON.stringify(data.cooldown) : null, data.input ? JSON.stringify(data.input) : null, data.triggerSchema ? JSON.stringify(data.triggerSchema) : null, data.dir ?? null, data.vcsRepo ?? null, data.createdByAgentId ?? null, data.createdBy ?? null, data.createdBy ?? null);
7761
8282
  if (!row)
7762
8283
  throw new Error("Failed to create workflow");
7763
8284
  return rowToWorkflow(row);
@@ -7776,6 +8297,7 @@ function rowToWorkflowSummary(row) {
7776
8297
  }
7777
8298
  return {
7778
8299
  id: row.id,
8300
+ key: row.key,
7779
8301
  name: row.name,
7780
8302
  description: row.description ?? undefined,
7781
8303
  enabled: row.enabled === 1,
@@ -7794,6 +8316,13 @@ function listWorkflows(filters, opts) {
7794
8316
  query += " AND enabled = ?";
7795
8317
  params.push(filters.enabled ? 1 : 0);
7796
8318
  }
8319
+ if (filters?.key) {
8320
+ query += ' AND "key" = ?';
8321
+ params.push(normalizeAssetKey(filters.key));
8322
+ } else if (filters?.keyPrefix) {
8323
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
8324
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
8325
+ }
7797
8326
  if (filters?.lastRunStatus !== undefined) {
7798
8327
  query += " AND (SELECT status FROM workflow_runs WHERE workflowId = workflows.id ORDER BY startedAt DESC LIMIT 1) = ?";
7799
8328
  params.push(filters.lastRunStatus);
@@ -7821,6 +8350,10 @@ function listWorkflows(filters, opts) {
7821
8350
  function updateWorkflow(id, data) {
7822
8351
  const updates = [];
7823
8352
  const params = [];
8353
+ if (data.key !== undefined) {
8354
+ updates.push('"key" = ?');
8355
+ params.push(normalizeAssetKey(data.key));
8356
+ }
7824
8357
  if (data.name !== undefined) {
7825
8358
  updates.push("name = ?");
7826
8359
  params.push(data.name);
@@ -8131,6 +8664,7 @@ function getWorkflowVersion(workflowId, version) {
8131
8664
  function rowToPage(row) {
8132
8665
  return {
8133
8666
  id: row.id,
8667
+ key: row.key,
8134
8668
  agentId: row.agentId,
8135
8669
  slug: row.slug,
8136
8670
  title: row.title,
@@ -8146,8 +8680,9 @@ function rowToPage(row) {
8146
8680
  };
8147
8681
  }
8148
8682
  function createPage(data) {
8149
- const row = getDb().prepare(`INSERT INTO pages (agentId, slug, title, description, contentType, authMode, passwordHash, body, needsCredentials)
8150
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(data.agentId, data.slug, data.title, data.description ?? null, data.contentType, data.authMode ?? "authed", data.passwordHash ?? null, data.body, data.needsCredentials ? JSON.stringify(data.needsCredentials) : null);
8683
+ const id = crypto.randomUUID().replace(/-/g, "");
8684
+ const row = getDb().prepare(`INSERT INTO pages (id, "key", agentId, slug, title, description, contentType, authMode, passwordHash, body, needsCredentials)
8685
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(id, normalizeAssetKey(data.key ?? defaultAssetKey("page", id)), data.agentId, data.slug, data.title, data.description ?? null, data.contentType, data.authMode ?? "authed", data.passwordHash ?? null, data.body, data.needsCredentials ? JSON.stringify(data.needsCredentials) : null);
8151
8686
  if (!row)
8152
8687
  throw new Error("Failed to create page");
8153
8688
  return rowToPage(row);
@@ -8167,6 +8702,7 @@ function getLatestPageBySlug(slug) {
8167
8702
  function rowToPageSummary(row) {
8168
8703
  return {
8169
8704
  id: row.id,
8705
+ key: row.key,
8170
8706
  agentId: row.agentId,
8171
8707
  slug: row.slug,
8172
8708
  title: row.title,
@@ -8180,24 +8716,68 @@ function rowToPageSummary(row) {
8180
8716
  };
8181
8717
  }
8182
8718
  function listPagesByAgent(agentId, limit = 100, offset = 0, opts) {
8183
- const rows = getDb().prepare("SELECT * FROM pages WHERE agentId = ? ORDER BY updatedAt DESC LIMIT ? OFFSET ?").all(agentId, limit, offset);
8719
+ let query = "SELECT * FROM pages WHERE agentId = ?";
8720
+ const params = [agentId];
8721
+ if (opts?.key) {
8722
+ query += ' AND "key" = ?';
8723
+ params.push(normalizeAssetKey(opts.key));
8724
+ } else if (opts?.keyPrefix) {
8725
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
8726
+ params.push(assetKeyPrefixPattern(opts.keyPrefix));
8727
+ }
8728
+ query += " ORDER BY updatedAt DESC LIMIT ? OFFSET ?";
8729
+ params.push(limit, offset);
8730
+ const rows = getDb().prepare(query).all(...params);
8184
8731
  return opts?.slim ? rows.map(rowToPageSummary) : rows.map(rowToPage);
8185
8732
  }
8186
8733
  function listAllPages(limit = 100, offset = 0, opts) {
8187
- const rows = getDb().prepare("SELECT * FROM pages ORDER BY updatedAt DESC LIMIT ? OFFSET ?").all(limit, offset);
8734
+ let query = "SELECT * FROM pages WHERE 1=1";
8735
+ const params = [];
8736
+ if (opts?.key) {
8737
+ query += ' AND "key" = ?';
8738
+ params.push(normalizeAssetKey(opts.key));
8739
+ } else if (opts?.keyPrefix) {
8740
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
8741
+ params.push(assetKeyPrefixPattern(opts.keyPrefix));
8742
+ }
8743
+ query += " ORDER BY updatedAt DESC LIMIT ? OFFSET ?";
8744
+ params.push(limit, offset);
8745
+ const rows = getDb().prepare(query).all(...params);
8188
8746
  return opts?.slim ? rows.map(rowToPageSummary) : rows.map(rowToPage);
8189
8747
  }
8190
- function countAllPages() {
8191
- const row = getDb().prepare("SELECT COUNT(*) AS count FROM pages").get();
8748
+ function countAllPages(filters) {
8749
+ let query = "SELECT COUNT(*) AS count FROM pages WHERE 1=1";
8750
+ const params = [];
8751
+ if (filters?.key) {
8752
+ query += ' AND "key" = ?';
8753
+ params.push(normalizeAssetKey(filters.key));
8754
+ } else if (filters?.keyPrefix) {
8755
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
8756
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
8757
+ }
8758
+ const row = getDb().prepare(query).get(...params);
8192
8759
  return row?.count ?? 0;
8193
8760
  }
8194
- function countPagesByAgent(agentId) {
8195
- const row = getDb().prepare("SELECT COUNT(*) AS count FROM pages WHERE agentId = ?").get(agentId);
8761
+ function countPagesByAgent(agentId, filters) {
8762
+ let query = "SELECT COUNT(*) AS count FROM pages WHERE agentId = ?";
8763
+ const params = [agentId];
8764
+ if (filters?.key) {
8765
+ query += ' AND "key" = ?';
8766
+ params.push(normalizeAssetKey(filters.key));
8767
+ } else if (filters?.keyPrefix) {
8768
+ query += ` AND "key" LIKE ? ESCAPE '\\'`;
8769
+ params.push(assetKeyPrefixPattern(filters.keyPrefix));
8770
+ }
8771
+ const row = getDb().prepare(query).get(...params);
8196
8772
  return row?.count ?? 0;
8197
8773
  }
8198
8774
  function updatePage(id, data) {
8199
8775
  const updates = [];
8200
8776
  const params = [];
8777
+ if (data.key !== undefined) {
8778
+ updates.push('"key" = ?');
8779
+ params.push(normalizeAssetKey(data.key));
8780
+ }
8201
8781
  if (data.title !== undefined) {
8202
8782
  updates.push("title = ?");
8203
8783
  params.push(data.title);
@@ -9725,7 +10305,7 @@ function upsertInboxState(opts) {
9725
10305
  function rowToUserFavorite(row) {
9726
10306
  return {
9727
10307
  id: row.id,
9728
- userId: row.userId,
10308
+ userId: row.userId ?? undefined,
9729
10309
  itemType: row.itemType,
9730
10310
  itemId: row.itemId,
9731
10311
  createdAt: row.createdAt,
@@ -9734,9 +10314,9 @@ function rowToUserFavorite(row) {
9734
10314
  updatedBy: row.updated_by ?? undefined
9735
10315
  };
9736
10316
  }
9737
- function listUserFavorites(opts) {
9738
- const conditions = ["userId = ?"];
9739
- const params = [opts.userId];
10317
+ function listFavorites(opts) {
10318
+ const conditions = ["favoriteScope = ?"];
10319
+ const params = [opts.favoriteScope];
9740
10320
  if (opts.itemType) {
9741
10321
  conditions.push("itemType = ?");
9742
10322
  params.push(opts.itemType);
@@ -9748,34 +10328,44 @@ function listUserFavorites(opts) {
9748
10328
  const rows = getDb().prepare(`SELECT * FROM user_favorites WHERE ${conditions.join(" AND ")} ORDER BY lastUpdatedAt DESC`).all(...params);
9749
10329
  return rows.map(rowToUserFavorite);
9750
10330
  }
10331
+ function listUserFavorites(opts) {
10332
+ return listFavorites({ ...opts, favoriteScope: `user:${opts.userId}` });
10333
+ }
9751
10334
  function getFavoriteItemIdSet(opts) {
9752
- return new Set(listUserFavorites(opts).map((favorite) => favorite.itemId));
10335
+ return new Set(listFavorites(opts).map((favorite) => favorite.itemId));
9753
10336
  }
9754
- function setUserFavorite(opts) {
10337
+ function setFavorite(opts) {
9755
10338
  if (!opts.favorite) {
9756
- getDb().prepare("DELETE FROM user_favorites WHERE userId = ? AND itemType = ? AND itemId = ?").run(opts.userId, opts.itemType, opts.itemId);
10339
+ getDb().prepare("DELETE FROM user_favorites WHERE favoriteScope = ? AND itemType = ? AND itemId = ?").run(opts.favoriteScope, opts.itemType, opts.itemId);
9757
10340
  return null;
9758
10341
  }
9759
10342
  const now = new Date().toISOString();
9760
- const actor = opts.actorUserId ?? opts.userId;
10343
+ const actor = opts.actorId ?? opts.userId ?? opts.favoriteScope;
9761
10344
  const row = getDb().prepare(`INSERT INTO user_favorites (
9762
- userId, itemType, itemId, createdAt, lastUpdatedAt, created_by, updated_by
10345
+ favoriteScope, userId, itemType, itemId, createdAt, lastUpdatedAt, created_by, updated_by
9763
10346
  )
9764
- VALUES (?, ?, ?, ?, ?, ?, ?)
9765
- ON CONFLICT(userId, itemType, itemId) DO UPDATE SET
10347
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
10348
+ ON CONFLICT(favoriteScope, itemType, itemId) DO UPDATE SET
9766
10349
  lastUpdatedAt = excluded.lastUpdatedAt,
9767
10350
  updated_by = excluded.updated_by
9768
- RETURNING *`).get(opts.userId, opts.itemType, opts.itemId, now, now, actor, actor);
10351
+ RETURNING *`).get(opts.favoriteScope, opts.userId ?? null, opts.itemType, opts.itemId, now, now, actor, actor);
9769
10352
  if (!row)
9770
10353
  throw new Error("Failed to set favorite");
9771
10354
  return rowToUserFavorite(row);
9772
10355
  }
10356
+ function setUserFavorite(opts) {
10357
+ return setFavorite({
10358
+ ...opts,
10359
+ favoriteScope: `user:${opts.userId}`,
10360
+ actorId: opts.actorUserId
10361
+ });
10362
+ }
9773
10363
  function withFavoriteFlags(rows, opts) {
9774
- if (!opts.userId || rows.length === 0) {
10364
+ if (!opts.favoriteScope || rows.length === 0) {
9775
10365
  return rows.map((row) => ({ ...row, favorite: false }));
9776
10366
  }
9777
10367
  const favoriteIds = getFavoriteItemIdSet({
9778
- userId: opts.userId,
10368
+ favoriteScope: opts.favoriteScope,
9779
10369
  itemType: opts.itemType,
9780
10370
  itemIds: rows.map((row) => row.id)
9781
10371
  });
@@ -10490,6 +11080,7 @@ var db = null, sqliteVecAvailable = false, VERSIONABLE_FIELDS, agentQueries, MAX
10490
11080
  var init_db = __esm(() => {
10491
11081
  init_provider_metadata();
10492
11082
  init_package();
11083
+ init_key();
10493
11084
  init_resolver();
10494
11085
  init_slack_routing();
10495
11086
  init_telemetry();
@@ -10497,6 +11088,7 @@ var init_db = __esm(() => {
10497
11088
  init_credentials();
10498
11089
  init_request_auth_context();
10499
11090
  init_secret_scrubber();
11091
+ init_asset_key_audit();
10500
11092
  init_crypto();
10501
11093
  init_date_utils();
10502
11094
  init_runner();
@@ -10521,8 +11113,8 @@ var init_db = __esm(() => {
10521
11113
  delete: () => getDb().prepare("DELETE FROM agents WHERE id = ?")
10522
11114
  };
10523
11115
  taskQueries = {
10524
- insert: () => getDb().prepare(`INSERT INTO agent_tasks (id, agentId, task, status, source, slackChannelId, slackThreadTs, slackUserId, swarmVersion, createdAt, lastUpdatedAt)
10525
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) RETURNING *`),
11116
+ insert: () => getDb().prepare(`INSERT INTO agent_tasks (id, "key", agentId, task, status, source, slackChannelId, slackThreadTs, slackUserId, swarmVersion, createdAt, lastUpdatedAt)
11117
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) RETURNING *`),
10526
11118
  getById: () => getDb().prepare("SELECT * FROM agent_tasks WHERE id = ?"),
10527
11119
  getByAgentId: () => getDb().prepare("SELECT * FROM agent_tasks WHERE agentId = ? ORDER BY createdAt DESC"),
10528
11120
  getByStatus: () => getDb().prepare("SELECT * FROM agent_tasks WHERE status = ? ORDER BY createdAt DESC"),
@@ -10597,4 +11189,4 @@ var init_db = __esm(() => {
10597
11189
  };
10598
11190
  });
10599
11191
 
10600
- export { interpolate, deepInterpolate, init_template, registerTemplate, getTemplateDefinition, getAllTemplateDefinitions, init_registry, configureHttpResolver, resolveTemplate, resolveTemplateAsync, init_resolver, slackContextKey, agentmailContextKey, githubContextKey, gitlabContextKey, linearContextKey, buildJiraContextKey, scheduleContextKey, workflowContextKey, agentContextKey, pageContextKey, init_context_key, checkSlackRoutingCoherence, init_slack_routing, initTelemetry, telemetry, init_telemetry, ModelTierSchema, ReasoningEffortSchema, splitLegacyModelAlias, resolveTaskModelSelection, AgentTaskStatusSchema, isTerminalTaskStatus, AgentTaskSourceSchema, ProviderNameSchema, FollowUpConfigSchema, AgentTaskSchema, AttachmentInputSchema, TaskAttachmentSchema, InboxItemTypeSchema, InboxItemStatusSchema, FavoriteItemTypeSchema, TaskTemplateKindSchema, AgentSchema, AgentLatestModelSchema, AgentCredStatusSchema, ChannelTypeSchema, ChannelSchema, ChannelMessageSchema, ServiceStatusSchema, ServiceSchema, ResumeReasonSchema, AgentLogSchema, EventCategorySchema, EventStatusSchema, EventSourceSchema, EventNameSchema, ScheduledTaskTargetTypeSchema, SwarmConfigScopeSchema, SwarmConfigSchema, RepoGuidelinesSchema, RepoHooksSchema, SwarmRepoSchema, AgentMemoryScopeSchema, AgentMemorySourceSchema, AgentMemorySchema, WorkflowDefinitionSchema, WorkflowNodePatchSchema, WorkflowPatchSchema, TriggerConfigSchema, CooldownConfigSchema, InputValueSchema, PageContentTypeSchema, PageAuthModeSchema, MetricDefinitionSchema, MetricVersionSchema, WorkflowRunStatusSchema, ScriptRunStatusSchema, TERMINAL_SCRIPT_RUN_STATUSES, PromptTemplateScopeSchema, PromptTemplateStateSchema, PromptTemplateSchema, PromptTemplateHistorySchema, ScriptScopeSchema, ScriptFsModeSchema, ScriptApiAuthModeSchema, ContextSnapshotEventTypeSchema, ContextFormulaSchema, BudgetScopeSchema, BudgetSchema, PricingProviderSchema, PricingTokenClassSchema, PricingRowSchema, BudgetRefusalCauseSchema, BudgetRefusalNotificationSchema, KvValueTypeSchema, KvNamespaceSchema, KvKeySchema, KvEntrySchema, init_types, setRequestAuth, getRequestAuth, getCurrentRequestAuth, init_request_auth_context, encryptSecret, decryptSecret, getEncryptionKey, init_crypto, normalizeDate, normalizeDateRequired, init_date_utils, init_session_templates, init_templates, init_templates2 as init_templates1, isReservedConfigKey, reservedKeyError, validateConfigValue, init_swarm_config_guard, onTaskStarted, init_task_lifecycle_events, generateDefaultClaudeMd, generateDefaultSoulMd, generateDefaultIdentityMd, generateDefaultToolsMd, init_defaults, isSqliteVecAvailable, initDb, getDb, closeDb, computeContentHash, createContextVersion, getLatestContextVersion, getContextVersion, getContextVersionHistory, agentQueries, updateAgentCredentialState, createAgent, getAgentById, getAllAgents, getLeadAgent, updateAgentStatus, updateAgentMaxTasks, updateAgentProvider, setAgentHarnessProvider, updateAgentCredStatus, listAgentsWithCredStatusByProvider, getAgentHarnessProviders, updateAgentActivity, MAX_EMPTY_POLLS, incrementEmptyPollCount, resetEmptyPollCount, shouldBlockPolling, deleteAgent, getActiveTaskCount, hasCapacity, getRemainingCapacity, updateAgentStatusFromCapacity, isPoolAffinityEnforcementEnabled, buildRoutingAffinityFromAgent, isAgentEligibleForTask, taskQueries, createTask, getPendingTaskForAgent, assignUnassignedTaskPending, startTask, getTaskById, markTaskSlackReplySent, setSlackMessageTracking, getChildTasks, hasNonTerminalResumeChild, hasNonTerminalRerouteDecisionChild, updateTaskClaudeSessionId, updateTaskVcs, getTasksByAgentId, getAgentCurrentTask, getTasksByStatus, findTaskByVcs, findTaskByGitHub, getAllTasks, getTasksCount, getTaskStats, getCompletedSlackTasks, getRecentlyFinishedWorkerTasks, markTasksNotified, resetTasksNotified, getInProgressSlackTasks, getInProgressTasksByContextKey, findExistingLinearTrackerContextWork, getLatestTaskByContextKey, getAgentWorkingOnThread, getLatestActiveTaskInThread, getMostRecentTaskInThread, findCompletedTaskInThread, findRecentCancelledTaskInThread, completeTask, failTask, cancelTask, supersedeTask, backfillSupersedeTaskResumeTaskId, pauseTask, resumeTask, getPausedTasksForAgent, getOrphanedInProgressTasksForAgent, resetOrphanedInProgressTasksForAgent, getRecentlyCancelledTasksForAgent, deleteTask, updateTaskProgress, insertTaskAttachment, deleteTaskAttachment, replaceTaskAttachment, getTaskAttachments, getAgentWithTasks, getAllAgentsWithTasks, logQueries, createLogEntry, getLogsByAgentId, getLogsByTaskId, getLogsByTaskIdChronological, getLogsByEventType, getAllLogs, findRecentSimilarTasks, createTaskExtended, claimTask, releaseTask, acceptTask, rejectTask, moveTaskToBacklog, moveTaskFromBacklog, releaseStaleReviewingTasks, getOfferedTasksForAgent, claimOfferedTask, getUnassignedTasksCount, getUnassignedTaskIds, getUnassignedTaskIdsForAgent, checkDependencies, getDependentTasks, cascadeFailDependents, updateAgentProfile, updateAgentName, createChannel, getMessageById, getChannelById, getChannelByName, getAllChannels, deleteChannel, postMessage, getChannelMessages, updateReadState, getLastReadAt, getUnreadMessages, getMentionsForAgent, getInboxSummary, claimMentions, releaseMentionProcessing, releaseStaleMentionProcessing, createService, getServiceById, getServiceByAgentAndName, getServicesByAgentId, getAllServices, updateServiceStatus, deleteService, upsertService, deleteServicesByAgentId, sessionLogQueries, createSessionLogs, getSessionLogsByTaskId, getSessionLogsBySession, createSessionCost, getSessionCostsByTaskId, getSessionCostsByAgentId, getAllSessionCosts, getSessionCostsFiltered, getSessionCostSummary, getDashboardCostSummary, createInboxMessage, getInboxMessageById, getUnreadInboxMessages, claimInboxMessages, markInboxMessageRead, markInboxMessageResponded, markInboxMessageDelegated, releaseStaleProcessingInbox, getConcurrentContext, getScheduledTasks, getScheduledTaskById, getScheduledTaskByName, createScheduledTask, updateScheduledTask, deleteScheduledTask, getDueScheduledTasks, autoEncryptLegacyPlaintextSecrets, maskSecrets, getSwarmConfigs, getInjectableGlobalConfigs, getSwarmConfigById, getSwarmConfigLookupById, upsertSwarmConfig, deleteSwarmConfig, deleteSwarmConfigByKey, getResolvedConfig, getSwarmRepos, getSwarmRepoById, getSwarmRepoByName, getSwarmRepoByUrl, createSwarmRepo, updateSwarmRepo, deleteSwarmRepo, getAgentMailInboxMapping, getAgentMailInboxMappingsByAgent, getAllAgentMailInboxMappings, createAgentMailInboxMapping, deleteAgentMailInboxMapping, findTaskByAgentMailThread, insertActiveSession, deleteActiveSession, deleteActiveSessionById, getActiveSessions, heartbeatActiveSession, cleanupStaleSessions, cleanupAgentSessions, updateActiveSessionProviderSessionId, getActiveSessionForTask, reassociateSessionLogs, getStalledInProgressTasks, getStalePinnedResumes, failPendingResumeIfUnclaimed, getIdleWorkersWithCapacity, getUnassignedPoolTasks, getStaleUnassignedAffinityTasks, getRecentFailedTasks, getRecentCompletedCount, getRecentFailedCount, createWorkflow, getWorkflow, listWorkflows, updateWorkflow, deleteWorkflow, getWorkflowsByScheduleId, createWorkflowRun, getWorkflowRun, updateWorkflowRun, listWorkflowRuns, createWorkflowRunStep, getWorkflowRunStep, updateWorkflowRunStep, getWorkflowRunStepsByRunId, getStuckWorkflowRuns, getLastSuccessfulRun, getLastRunStart, getRetryableSteps, getCompletedStepNodeIds, getTaskByWorkflowRunStepId, getStepByIdempotencyKey, getStepCountForNode, getLatestStepForNode, createWorkflowVersion, getWorkflowVersions, getWorkflowVersion, createPage, getPage, getPageBySlug, getLatestPageBySlug, listPagesByAgent, listAllPages, countAllPages, countPagesByAgent, updatePage, deletePage, incrementPageViewCount, createPageVersion, getPageVersions, getPageVersion, createMetric, getMetric, getMetricBySlug, listMetricsByAgent, listAllMetrics, countAllMetrics, countMetricsByAgent, updateMetric, deleteMetric, createMetricVersion, getMetricVersions, getMetricVersion, getPromptTemplates, getPromptTemplateById, upsertPromptTemplate, deletePromptTemplate, resetPromptTemplateToDefault, getPromptTemplateHistory, resolvePromptTemplate, checkoutPromptTemplate, getAllChannelActivityCursors, getChannelActivityCursor, upsertChannelActivityCursor, createApprovalRequest, getApprovalRequestById, resolveApprovalRequest, updateApprovalRequestNotifications, listApprovalRequests, getStuckApprovalRuns, getApprovalRequestByStepId, getExpiredPendingApprovals, createWaitState, getWaitStateById, getWaitStateByStepId, getDueWaitStates, getPendingEventWaitNames, getPendingWaitsByEvent, resolveWaitState, getStuckWaitRuns, SKILL_FILE_LIMITS, normalizeSkillFilePath, createSkill, updateSkill, listSkillFileManifest, getSkillFiles, getSkillFile, upsertSkillFile, upsertSkillFiles, deleteSkillFile, deleteSkill, getSkillById, getSkillByName, listSkills, searchSkills, installSkill, getSystemDefaultSkills, installSystemDefaultSkillsForAgent, uninstallSkill, getAgentSkills, toggleAgentSkill, createMcpServer, updateMcpServer, deleteMcpServer, getMcpServerById, getMcpServerByName, listMcpServers, installMcpServer, uninstallMcpServer, getAgentMcpServers, createContextSnapshot, getContextSnapshotsByTaskId, getContextSnapshotsBySessionId, getContextSummaryByTaskId, getAvailableKeyIndices, recordKeyUsage, markKeyRateLimited, recordKeyRateLimitWindows, setApiKeyName, clearKeyRateLimit, getKeyStatuses, getKeyCostSummary, getUserById, getAllUsers, createUser, updateUser, deleteUser, listInboxState, upsertInboxState, listUserFavorites, getFavoriteItemIdSet, setUserFavorite, withFavoriteFlags, listTaskTemplates, getRootTaskChain, listRecentSessions, countSessions, getBudget, getBudgets, upsertBudget, deleteBudget, getAllPricingRows, getPricingRows, getActivePricingRow, insertPricingRow, deletePricingRow, getDailySpendForAgent, getDailySpendGlobal, getDailySpendForUser, recordBudgetRefusalNotification, getBudgetRefusalNotification, getRecentBudgetRefusalNotifications, hasBudgetRefusalNotificationToday, setBudgetRefusalFollowUpTaskId, getLiveAgentCounts, getInstanceActivity, getSwarmMetrics, hasFirstCompletedTask, getKv, upsertKv, deleteKv, KvTypeCollisionError, incrKv, listKv, countKv, createScriptRun, recordInlineScriptRun, getScriptRun, getScriptRunByIdempotencyKey, listScriptRuns, countScriptRuns, countActiveScriptRuns, updateScriptRun, getRunningScriptRuns, getScriptRunJournalStep, upsertScriptRunJournalStep, listScriptRunJournalSteps, countScriptRunJournalSteps, countScriptRunJournalAgentTaskSteps, exports_db, init_db };
11192
+ export { normalizeAssetKey, parseAssetKey, canWriteAssetKey, init_key, interpolate, deepInterpolate, init_template, registerTemplate, getTemplateDefinition, getAllTemplateDefinitions, init_registry, configureHttpResolver, resolveTemplate, resolveTemplateAsync, init_resolver, slackContextKey, agentmailContextKey, githubContextKey, gitlabContextKey, linearContextKey, buildJiraContextKey, scheduleContextKey, workflowContextKey, agentContextKey, pageContextKey, init_context_key, checkSlackRoutingCoherence, init_slack_routing, initTelemetry, telemetry, init_telemetry, AssetKeySchema, AssetEntityTypeSchema, ModelTierSchema, ReasoningEffortSchema, splitLegacyModelAlias, resolveTaskModelSelection, AgentTaskStatusSchema, isTerminalTaskStatus, AgentTaskSourceSchema, ProviderNameSchema, FollowUpConfigSchema, AgentTaskSchema, AttachmentInputSchema, TaskAttachmentSchema, InboxItemTypeSchema, InboxItemStatusSchema, FavoriteItemTypeSchema, TaskTemplateKindSchema, AgentSchema, AgentLatestModelSchema, AgentCredStatusSchema, ChannelTypeSchema, ChannelSchema, ChannelMessageSchema, ServiceStatusSchema, ServiceSchema, ResumeReasonSchema, AgentLogSchema, EventCategorySchema, EventStatusSchema, EventSourceSchema, EventNameSchema, ScheduledTaskTargetTypeSchema, SwarmConfigScopeSchema, SwarmConfigSchema, RepoGuidelinesSchema, RepoHooksSchema, SwarmRepoSchema, AgentMemoryScopeSchema, AgentMemorySourceSchema, AgentMemorySchema, WorkflowDefinitionSchema, WorkflowNodePatchSchema, WorkflowPatchSchema, TriggerConfigSchema, CooldownConfigSchema, InputValueSchema, PageContentTypeSchema, PageAuthModeSchema, MetricDefinitionSchema, MetricVersionSchema, WorkflowRunStatusSchema, ScriptRunStatusSchema, TERMINAL_SCRIPT_RUN_STATUSES, PromptTemplateScopeSchema, PromptTemplateStateSchema, PromptTemplateSchema, PromptTemplateHistorySchema, ScriptScopeSchema, ScriptFsModeSchema, ScriptApiAuthModeSchema, ContextSnapshotEventTypeSchema, ContextFormulaSchema, BudgetScopeSchema, BudgetSchema, PricingProviderSchema, PricingTokenClassSchema, PricingRowSchema, BudgetRefusalCauseSchema, BudgetRefusalNotificationSchema, KvValueTypeSchema, KvNamespaceSchema, KvKeySchema, KvEntrySchema, init_types, setRequestAuth, getRequestAuth, getCurrentRequestAuth, init_request_auth_context, auditAssetKeys, init_asset_key_audit, encryptSecret, decryptSecret, getEncryptionKey, init_crypto, normalizeDate, normalizeDateRequired, init_date_utils, init_session_templates, init_templates, init_templates2 as init_templates1, isReservedConfigKey, reservedKeyError, validateConfigValue, init_swarm_config_guard, onTaskStarted, init_task_lifecycle_events, generateDefaultClaudeMd, generateDefaultSoulMd, generateDefaultIdentityMd, generateDefaultToolsMd, init_defaults, isSqliteVecAvailable, initDb, getDb, closeDb, computeContentHash, createContextVersion, getLatestContextVersion, getContextVersion, getContextVersionHistory, agentQueries, updateAgentCredentialState, createAgent, getAgentById, getAllAgents, getLeadAgent, updateAgentStatus, updateAgentMaxTasks, updateAgentProvider, setAgentHarnessProvider, updateAgentCredStatus, listAgentsWithCredStatusByProvider, getAgentHarnessProviders, updateAgentActivity, MAX_EMPTY_POLLS, incrementEmptyPollCount, resetEmptyPollCount, shouldBlockPolling, deleteAgent, getActiveTaskCount, hasCapacity, getRemainingCapacity, updateAgentStatusFromCapacity, isPoolAffinityEnforcementEnabled, buildRoutingAffinityFromAgent, isAgentEligibleForTask, taskQueries, createTask, getPendingTaskForAgent, assignUnassignedTaskPending, startTask, getTaskById, markTaskSlackReplySent, setSlackMessageTracking, getChildTasks, hasNonTerminalResumeChild, hasNonTerminalRerouteDecisionChild, updateTaskClaudeSessionId, updateTaskVcs, getTasksByAgentId, getAgentCurrentTask, getTasksByStatus, findTaskByVcs, findTaskByGitHub, getAllTasks, getTasksCount, getTaskStats, getCompletedSlackTasks, getRecentlyFinishedWorkerTasks, markTasksNotified, resetTasksNotified, getInProgressSlackTasks, getInProgressTasksByContextKey, findExistingLinearTrackerContextWork, getLatestTaskByContextKey, getAgentWorkingOnThread, getLatestActiveTaskInThread, getMostRecentTaskInThread, findCompletedTaskInThread, findRecentCancelledTaskInThread, completeTask, failTask, cancelTask, supersedeTask, backfillSupersedeTaskResumeTaskId, pauseTask, resumeTask, getPausedTasksForAgent, getOrphanedInProgressTasksForAgent, resetOrphanedInProgressTasksForAgent, getRecentlyCancelledTasksForAgent, deleteTask, updateTaskProgress, insertTaskAttachment, getAssetKeyMappingByProvider, upsertAssetKeyMapping, getAssetKeyMapping, listAssetSummaries, moveAssetKey, deleteTaskAttachment, replaceTaskAttachment, getTaskAttachments, getAgentWithTasks, getAllAgentsWithTasks, logQueries, createLogEntry, getLogsByAgentId, getLogsByTaskId, getLogsByTaskIdChronological, getLogsByEventType, getAllLogs, findRecentSimilarTasks, createTaskExtended, claimTask, releaseTask, acceptTask, rejectTask, moveTaskToBacklog, moveTaskFromBacklog, releaseStaleReviewingTasks, getOfferedTasksForAgent, claimOfferedTask, getUnassignedTasksCount, getUnassignedTaskIds, getUnassignedTaskIdsForAgent, checkDependencies, getDependentTasks, cascadeFailDependents, updateAgentProfile, updateAgentName, createChannel, getMessageById, getChannelById, getChannelByName, getAllChannels, deleteChannel, postMessage, getChannelMessages, updateReadState, getLastReadAt, getUnreadMessages, getMentionsForAgent, getInboxSummary, claimMentions, releaseMentionProcessing, releaseStaleMentionProcessing, createService, getServiceById, getServiceByAgentAndName, getServicesByAgentId, getAllServices, updateServiceStatus, deleteService, upsertService, deleteServicesByAgentId, sessionLogQueries, createSessionLogs, getSessionLogsByTaskId, getSessionLogsBySession, createSessionCost, getSessionCostsByTaskId, getSessionCostsByAgentId, getAllSessionCosts, getSessionCostsFiltered, getSessionCostSummary, getDashboardCostSummary, createInboxMessage, getInboxMessageById, getUnreadInboxMessages, claimInboxMessages, markInboxMessageRead, markInboxMessageResponded, markInboxMessageDelegated, releaseStaleProcessingInbox, getConcurrentContext, getScheduledTasks, getScheduledTaskById, getScheduledTaskByName, createScheduledTask, updateScheduledTask, deleteScheduledTask, getDueScheduledTasks, autoEncryptLegacyPlaintextSecrets, maskSecrets, getSwarmConfigs, getInjectableGlobalConfigs, getSwarmConfigById, getSwarmConfigLookupById, upsertSwarmConfig, deleteSwarmConfig, deleteSwarmConfigByKey, getResolvedConfig, getSwarmRepos, getSwarmRepoById, getSwarmRepoByName, getSwarmRepoByUrl, createSwarmRepo, updateSwarmRepo, deleteSwarmRepo, getAgentMailInboxMapping, getAgentMailInboxMappingsByAgent, getAllAgentMailInboxMappings, createAgentMailInboxMapping, deleteAgentMailInboxMapping, findTaskByAgentMailThread, insertActiveSession, deleteActiveSession, deleteActiveSessionById, getActiveSessions, heartbeatActiveSession, cleanupStaleSessions, cleanupAgentSessions, updateActiveSessionProviderSessionId, getActiveSessionForTask, reassociateSessionLogs, getStalledInProgressTasks, getStalePinnedResumes, failPendingResumeIfUnclaimed, getIdleWorkersWithCapacity, getUnassignedPoolTasks, getStaleUnassignedAffinityTasks, getRecentFailedTasks, getRecentCompletedCount, getRecentFailedCount, createWorkflow, getWorkflow, listWorkflows, updateWorkflow, deleteWorkflow, getWorkflowsByScheduleId, createWorkflowRun, getWorkflowRun, updateWorkflowRun, listWorkflowRuns, createWorkflowRunStep, getWorkflowRunStep, updateWorkflowRunStep, getWorkflowRunStepsByRunId, getStuckWorkflowRuns, getLastSuccessfulRun, getLastRunStart, getRetryableSteps, getCompletedStepNodeIds, getTaskByWorkflowRunStepId, getStepByIdempotencyKey, getStepCountForNode, getLatestStepForNode, createWorkflowVersion, getWorkflowVersions, getWorkflowVersion, createPage, getPage, getPageBySlug, getLatestPageBySlug, listPagesByAgent, listAllPages, countAllPages, countPagesByAgent, updatePage, deletePage, incrementPageViewCount, createPageVersion, getPageVersions, getPageVersion, createMetric, getMetric, getMetricBySlug, listMetricsByAgent, listAllMetrics, countAllMetrics, countMetricsByAgent, updateMetric, deleteMetric, createMetricVersion, getMetricVersions, getMetricVersion, getPromptTemplates, getPromptTemplateById, upsertPromptTemplate, deletePromptTemplate, resetPromptTemplateToDefault, getPromptTemplateHistory, resolvePromptTemplate, checkoutPromptTemplate, getAllChannelActivityCursors, getChannelActivityCursor, upsertChannelActivityCursor, createApprovalRequest, getApprovalRequestById, resolveApprovalRequest, updateApprovalRequestNotifications, listApprovalRequests, getStuckApprovalRuns, getApprovalRequestByStepId, getExpiredPendingApprovals, createWaitState, getWaitStateById, getWaitStateByStepId, getDueWaitStates, getPendingEventWaitNames, getPendingWaitsByEvent, resolveWaitState, getStuckWaitRuns, SKILL_FILE_LIMITS, normalizeSkillFilePath, createSkill, updateSkill, listSkillFileManifest, getSkillFiles, getSkillFile, upsertSkillFile, upsertSkillFiles, deleteSkillFile, deleteSkill, getSkillById, getSkillByName, listSkills, searchSkills, installSkill, getSystemDefaultSkills, installSystemDefaultSkillsForAgent, uninstallSkill, getAgentSkills, toggleAgentSkill, createMcpServer, updateMcpServer, deleteMcpServer, getMcpServerById, getMcpServerByName, listMcpServers, installMcpServer, uninstallMcpServer, getAgentMcpServers, createContextSnapshot, getContextSnapshotsByTaskId, getContextSnapshotsBySessionId, getContextSummaryByTaskId, getAvailableKeyIndices, recordKeyUsage, markKeyRateLimited, recordKeyRateLimitWindows, setApiKeyName, clearKeyRateLimit, getKeyStatuses, getKeyCostSummary, getUserById, getAllUsers, createUser, updateUser, deleteUser, listInboxState, upsertInboxState, listFavorites, listUserFavorites, getFavoriteItemIdSet, setFavorite, setUserFavorite, withFavoriteFlags, listTaskTemplates, getRootTaskChain, listRecentSessions, countSessions, getBudget, getBudgets, upsertBudget, deleteBudget, getAllPricingRows, getPricingRows, getActivePricingRow, insertPricingRow, deletePricingRow, getDailySpendForAgent, getDailySpendGlobal, getDailySpendForUser, recordBudgetRefusalNotification, getBudgetRefusalNotification, getRecentBudgetRefusalNotifications, hasBudgetRefusalNotificationToday, setBudgetRefusalFollowUpTaskId, getLiveAgentCounts, getInstanceActivity, getSwarmMetrics, hasFirstCompletedTask, getKv, upsertKv, deleteKv, KvTypeCollisionError, incrKv, listKv, countKv, createScriptRun, recordInlineScriptRun, getScriptRun, getScriptRunByIdempotencyKey, listScriptRuns, countScriptRuns, countActiveScriptRuns, updateScriptRun, getRunningScriptRuns, getScriptRunJournalStep, upsertScriptRunJournalStep, listScriptRunJournalSteps, countScriptRunJournalSteps, countScriptRunJournalAgentTaskSteps, exports_db, init_db };