@agent-native/core 0.154.4 → 0.155.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 (207) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/account-health/SKILL.md +76 -0
  3. package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +3 -0
  4. package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +2 -1
  5. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +6 -5
  6. package/corpus/templates/analytics/AGENTS.md +3 -0
  7. package/corpus/templates/analytics/actions/account-deep-dive.ts +3 -2
  8. package/corpus/templates/analytics/actions/bigquery.ts +1 -1
  9. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -1
  10. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +1 -0
  11. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyCombobox.tsx +12 -4
  12. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyValueCombobox.tsx +5 -2
  13. package/corpus/templates/analytics/app/pages/adhoc/explorer/property-label.ts +32 -0
  14. package/corpus/templates/analytics/changelog/2026-08-13-account-health-readouts-verify-customer-scope-and-contract-metrics.md +7 -0
  15. package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +43 -17
  16. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +17 -0
  17. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -0
  18. package/corpus/templates/calendar/AGENTS.md +2 -0
  19. package/corpus/templates/calendar/DEVELOPING.md +4 -4
  20. package/corpus/templates/calendar/actions/get-settings.ts +4 -11
  21. package/corpus/templates/calendar/actions/update-availability.ts +15 -4
  22. package/corpus/templates/calendar/actions/update-settings.ts +15 -4
  23. package/corpus/templates/calendar/app/components/booking/DatePicker.tsx +9 -3
  24. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +21 -19
  25. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +9 -6
  26. package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +25 -3
  27. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +10 -3
  28. package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +9 -9
  29. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -3
  30. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +10 -4
  31. package/corpus/templates/calendar/app/i18n-data.ts +30 -0
  32. package/corpus/templates/calendar/app/lib/availability-schedule.ts +53 -0
  33. package/corpus/templates/calendar/app/lib/event-form-utils.ts +5 -0
  34. package/corpus/templates/calendar/app/pages/AvailabilitySettings.tsx +90 -28
  35. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +135 -61
  36. package/corpus/templates/calendar/app/pages/BookingPage.tsx +2 -0
  37. package/corpus/templates/calendar/app/pages/CalendarView.tsx +30 -15
  38. package/corpus/templates/calendar/app/pages/Settings.tsx +60 -1
  39. package/corpus/templates/calendar/changelog/2026-08-13-find-a-time-now-closes-from-a-clear-header-action.md +6 -0
  40. package/corpus/templates/calendar/server/handlers/bookings.ts +2 -1
  41. package/corpus/templates/calendar/server/handlers/settings.ts +12 -16
  42. package/corpus/templates/calendar/shared/api.ts +1 -0
  43. package/corpus/templates/calendar/shared/availability-schedule.ts +64 -0
  44. package/corpus/templates/calendar/shared/calendar-week.ts +21 -0
  45. package/corpus/templates/calendar/shared/settings.ts +44 -0
  46. package/corpus/templates/clips/AGENTS.md +2 -0
  47. package/corpus/templates/clips/actions/add-comment.ts +5 -2
  48. package/corpus/templates/clips/actions/finalize-recording.ts +31 -1
  49. package/corpus/templates/clips/actions/get-recording-player-data.ts +9 -0
  50. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +21 -1
  51. package/corpus/templates/clips/actions/reply-to-comment.ts +5 -2
  52. package/corpus/templates/clips/actions/update-comment.ts +9 -2
  53. package/corpus/templates/clips/app/components/library/search-bar.tsx +26 -13
  54. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +135 -3
  55. package/corpus/templates/clips/app/components/player/comments-panel.tsx +5 -99
  56. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +7 -3
  57. package/corpus/templates/clips/app/components/player/video-player.tsx +84 -24
  58. package/corpus/templates/clips/app/components/workspace/notifications-list.tsx +11 -3
  59. package/corpus/templates/clips/app/i18n/en-US.ts +12 -0
  60. package/corpus/templates/clips/app/lib/public-meeting.ts +11 -3
  61. package/corpus/templates/clips/app/lib/search-focus.ts +15 -0
  62. package/corpus/templates/clips/app/root.tsx +2 -1
  63. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +94 -26
  64. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +24 -7
  65. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +8 -4
  66. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +14 -7
  67. package/corpus/templates/clips/app/routes/share.$shareId.tsx +8 -4
  68. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +72 -26
  69. package/corpus/templates/clips/changelog/2026-08-13-inline-markdown-comments.md +6 -0
  70. package/corpus/templates/clips/changelog/2026-08-13-private-meeting-agent-links.md +6 -0
  71. package/corpus/templates/clips/desktop/src/app.tsx +116 -19
  72. package/corpus/templates/clips/desktop/src/lib/recorder.ts +13 -29
  73. package/corpus/templates/clips/desktop/src/lib/recording-request.ts +39 -0
  74. package/corpus/templates/clips/desktop/src/lib/settings-navigation.ts +11 -0
  75. package/corpus/templates/clips/desktop/src/lib/whisper-model-picker.ts +7 -0
  76. package/corpus/templates/clips/desktop/src/styles.css +117 -0
  77. package/corpus/templates/clips/server/db/index.ts +10 -0
  78. package/corpus/templates/clips/server/db/schema.ts +1 -0
  79. package/corpus/templates/clips/server/lib/recordings.ts +3 -1
  80. package/corpus/templates/clips/server/lib/seekable-media-state.ts +90 -0
  81. package/corpus/templates/clips/server/plugins/db.ts +5 -0
  82. package/corpus/templates/clips/server/routes/api/public-meeting.get.ts +37 -4
  83. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +16 -5
  84. package/corpus/templates/clips/shared/clips-ai-prefs.ts +3 -0
  85. package/corpus/templates/clips/shared/meeting-agent-access.ts +5 -0
  86. package/corpus/templates/content/.agents/skills/content/SKILL.md +2 -2
  87. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +20 -4
  88. package/corpus/templates/content/actions/_database-row-mutation.ts +1490 -0
  89. package/corpus/templates/content/actions/_database-utils.ts +44 -0
  90. package/corpus/templates/content/actions/_property-utils.ts +4 -1
  91. package/corpus/templates/content/actions/add-comment.ts +2 -1
  92. package/corpus/templates/content/actions/add-database-item.ts +62 -240
  93. package/corpus/templates/content/actions/configure-document-property.ts +165 -1
  94. package/corpus/templates/content/actions/delete-document-property.ts +18 -0
  95. package/corpus/templates/content/actions/set-document-property.ts +78 -1
  96. package/corpus/templates/content/actions/update-comment.ts +1 -1
  97. package/corpus/templates/content/actions/update-database-item.ts +62 -0
  98. package/corpus/templates/content/actions/upsert-database-item-by-key.ts +43 -796
  99. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +24 -15
  100. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +10 -8
  101. package/corpus/templates/content/app/hooks/use-content-database.ts +33 -32
  102. package/corpus/templates/content/changelog/2026-08-10-database-row-actions-now-validate-exact-schemas-and-safe-ret.md +6 -0
  103. package/corpus/templates/content/parity/matrix.md +1 -1
  104. package/corpus/templates/content/parity/matrix.ts +2 -0
  105. package/corpus/templates/content/server/db/schema.ts +39 -3
  106. package/corpus/templates/content/server/plugins/db.ts +30 -0
  107. package/corpus/templates/content/shared/api.ts +75 -2
  108. package/corpus/templates/design/actions/generate-design.ts +10 -7
  109. package/corpus/templates/design/actions/present-design-variants.ts +35 -6
  110. package/corpus/templates/design/actions/run-design-audit.ts +33 -0
  111. package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-catches-a-screen-that-renders-behind-an.md +6 -0
  112. package/corpus/templates/design/shared/design-review.ts +1 -0
  113. package/corpus/templates/design/shared/html-integrity.ts +66 -0
  114. package/corpus/templates/dispatch/.env.example +5 -0
  115. package/corpus/templates/dispatch/AGENTS.md +24 -19
  116. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  117. package/corpus/templates/dispatch/server/lib/identity-sso.ts +21 -90
  118. package/corpus/templates/dispatch/server/plugins/identity-sso.ts +3 -12
  119. package/corpus/templates/dispatch/shared/feature-flags.ts +4 -0
  120. package/corpus/templates/factory/AGENTS.md +5 -1
  121. package/corpus/templates/factory/README.md +23 -0
  122. package/corpus/templates/factory/actions/view-screen.ts +17 -0
  123. package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +239 -0
  124. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +2 -0
  125. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +130 -7
  126. package/corpus/templates/factory/app/i18n/en-US.ts +20 -0
  127. package/corpus/templates/factory/app/routes/factory.tsx +41 -0
  128. package/corpus/templates/factory/package.json +1 -0
  129. package/corpus/templates/factory/server/factory-graph/contracts.ts +2 -0
  130. package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -0
  131. package/corpus/templates/factory/server/plugins/dispatch-db.ts +1 -0
  132. package/corpus/templates/factory/server/plugins/setup-dispatch.ts +3 -0
  133. package/corpus/templates/mail/app/lib/native-mcp-exclusions.ts +3 -0
  134. package/corpus/templates/mail/vite.config.ts +7 -0
  135. package/corpus/templates/plan/actions/reply-to-plan-comment.ts +7 -2
  136. package/corpus/templates/plan/actions/resolve-plan-comment.ts +2 -2
  137. package/corpus/templates/plan/actions/update-visual-plan.ts +1 -1
  138. package/corpus/templates/plan/app/pages/PlansPage.tsx +29 -20
  139. package/corpus/templates/slides/actions/add-slide-comment.ts +1 -1
  140. package/corpus/templates/slides/actions/update-slide-comment.ts +1 -1
  141. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +9 -6
  142. package/dist/action.d.ts +22 -0
  143. package/dist/action.js +27 -0
  144. package/dist/agent/production-agent.js +5 -1
  145. package/dist/agent/thread-data-builder.js +17 -1
  146. package/dist/cli/skills-content/help.js +6 -4
  147. package/dist/cli/skills.js +17 -2
  148. package/dist/cli/workspacify.d.ts +5 -0
  149. package/dist/cli/workspacify.js +65 -8
  150. package/dist/client/AgentPanel.d.ts +5 -0
  151. package/dist/client/AgentPanel.js +20 -4
  152. package/dist/client/AssistantChat.d.ts +21 -0
  153. package/dist/client/AssistantChat.js +66 -68
  154. package/dist/client/active-run-state.d.ts +14 -1
  155. package/dist/client/active-run-state.js +0 -0
  156. package/dist/client/agent-chat-adapter.js +107 -5
  157. package/dist/client/analytics.js +9 -2
  158. package/dist/client/chat/tool-call-display.js +4 -4
  159. package/dist/client/chat-first/apps-rail.js +9 -4
  160. package/dist/client/chat-first/primary-nav.d.ts +2 -1
  161. package/dist/client/chat-first/primary-nav.js +3 -3
  162. package/dist/client/chat-first/types.d.ts +5 -1
  163. package/dist/client/markdown/InlineMarkdown.d.ts +23 -0
  164. package/dist/client/markdown/InlineMarkdown.js +65 -0
  165. package/dist/client/markdown/index.d.ts +1 -0
  166. package/dist/client/markdown/index.js +1 -0
  167. package/dist/client/review/ReviewThreadPanel.js +2 -1
  168. package/dist/client/run-stream-ownership.d.ts +39 -0
  169. package/dist/client/run-stream-ownership.js +65 -0
  170. package/dist/collab/routes.d.ts +1 -1
  171. package/dist/collab/struct-routes.d.ts +1 -1
  172. package/dist/feature-flags/index.d.ts +1 -1
  173. package/dist/feature-flags/index.js +1 -1
  174. package/dist/feature-flags/store.d.ts +10 -0
  175. package/dist/feature-flags/store.js +112 -1
  176. package/dist/guards/no-env-credentials.js +4 -0
  177. package/dist/index.browser.d.ts +1 -1
  178. package/dist/index.browser.js +1 -1
  179. package/dist/index.d.ts +2 -2
  180. package/dist/index.js +2 -2
  181. package/dist/integrations/adapters/slack.js +5 -1
  182. package/dist/localization/default-messages.d.ts +1 -0
  183. package/dist/localization/default-messages.js +1 -0
  184. package/dist/notifications/routes.d.ts +1 -1
  185. package/dist/observability/routes.d.ts +1 -1
  186. package/dist/progress/routes.d.ts +1 -1
  187. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  188. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  189. package/dist/resources/agents.js +40 -5
  190. package/dist/resources/handlers.d.ts +1 -1
  191. package/dist/resources/metadata.d.ts +10 -0
  192. package/dist/resources/metadata.js +7 -3
  193. package/dist/review/actions/create-review-comment.js +1 -1
  194. package/dist/review/actions/reply-review-comment.js +1 -1
  195. package/dist/review/actions/resolve-review-thread.js +1 -1
  196. package/dist/server/action-routes.js +42 -8
  197. package/dist/server/agent-discovery.js +14 -3
  198. package/dist/server/core-routes-plugin.js +1 -1
  199. package/dist/server/identity-sso-migrations.d.ts +7 -0
  200. package/dist/server/identity-sso-migrations.js +36 -0
  201. package/dist/server/identity-sso-store.d.ts +3 -2
  202. package/dist/server/identity-sso-store.js +8 -3
  203. package/dist/server/realtime-token.d.ts +1 -1
  204. package/dist/server/release-migrations.js +4 -0
  205. package/dist/tracking/providers.js +13 -3
  206. package/dist/workspace-files/tool.js +1 -1
  207. package/package.json +3 -2
@@ -34,6 +34,7 @@ export type DesignHtmlIntegrityIssue =
34
34
  | "runtime-missing"
35
35
  | "runtime-alpine-missing"
36
36
  | "runtime-cloak-missing"
37
+ | "runtime-overlay-unhidden"
37
38
  | "url-backed-screen-replaced";
38
39
 
39
40
  /**
@@ -153,6 +154,14 @@ export function describeDesignHtmlIntegrityIssue(
153
154
  `but no script source contains Alpine.js. The element will remain ` +
154
155
  `hidden forever; load Alpine.js before relying on x-cloak.`
155
156
  );
157
+ case "runtime-overlay-unhidden":
158
+ return (
159
+ `<${detail.tag ?? "element"}> at ${at} covers the whole frame and is ` +
160
+ `shown by Alpine (${detail.attribute ?? "x-show"}), but nothing hides ` +
161
+ `it before Alpine starts. It paints over the design on first render. ` +
162
+ `Add x-cloak plus [x-cloak] { display: none !important; }, or an ` +
163
+ `inline style="display:none".`
164
+ );
156
165
  case "runtime-cloak-missing":
157
166
  return (
158
167
  `the document uses x-cloak on <${detail.tag ?? "element"}> at ${at}, ` +
@@ -1175,6 +1184,53 @@ function collectInteractiveRuntimeIssues(
1175
1184
  ];
1176
1185
  }
1177
1186
 
1187
+ /**
1188
+ * Covers the frame when it is taken out of flow AND stretched to every edge.
1189
+ * `fixed` alone is a toolbar; `inset-0` alone is a normal filled parent.
1190
+ */
1191
+ function coversViewport(className: string): boolean {
1192
+ const classes = new Set(className.split(/\s+/));
1193
+ const positioned = classes.has("fixed") || classes.has("absolute");
1194
+ const fullBleed =
1195
+ classes.has("inset-0") ||
1196
+ (classes.has("w-screen") && classes.has("h-screen"));
1197
+ return positioned && fullBleed;
1198
+ }
1199
+
1200
+ /**
1201
+ * The shape the `x-cloak` checks above cannot see. An overlay toggled by
1202
+ * `x-show` with no `x-cloak` at all paints over the design until Alpine
1203
+ * evaluates the expression — the same symptom, minus the attribute that makes
1204
+ * it detectable. Advisory rather than blocking: with Alpine healthy this is one
1205
+ * frame, and a genuinely broken runtime is already caught above.
1206
+ *
1207
+ * `<template x-if>` is deliberately not checked: template content is inert
1208
+ * until Alpine clones it, so it cannot paint early.
1209
+ */
1210
+ function collectOverlayAdvisory(
1211
+ parsed: ParsedDocument,
1212
+ locate: Locator,
1213
+ ): DesignHtmlIntegrityIssueDetail[] {
1214
+ for (const element of parsed.elements) {
1215
+ const names = new Set(
1216
+ element.attrs.map((attribute) => attribute.name.toLowerCase()),
1217
+ );
1218
+ if (names.has("x-cloak") || !names.has("x-show")) continue;
1219
+ if (!coversViewport(attributeOf(element, "class") ?? "")) continue;
1220
+ if (INLINE_PRE_HIDE.test(attributeOf(element, "style") ?? "")) continue;
1221
+
1222
+ return [
1223
+ {
1224
+ issue: "runtime-overlay-unhidden",
1225
+ ...locate(locationOf(element)?.startOffset ?? 0),
1226
+ tag: element.tagName,
1227
+ attribute: "x-show",
1228
+ },
1229
+ ];
1230
+ }
1231
+ return [];
1232
+ }
1233
+
1178
1234
  /**
1179
1235
  * Reported, never enforced: legitimate fragments and token-only screens carry no
1180
1236
  * runtime of their own, so blocking here would reject valid work.
@@ -1182,6 +1238,16 @@ function collectInteractiveRuntimeIssues(
1182
1238
  function collectAdvisoryIssues(
1183
1239
  parsed: ParsedDocument,
1184
1240
  locate: Locator,
1241
+ ): DesignHtmlIntegrityIssueDetail[] {
1242
+ return [
1243
+ ...collectOverlayAdvisory(parsed, locate),
1244
+ ...collectTailwindRuntimeAdvisory(parsed, locate),
1245
+ ];
1246
+ }
1247
+
1248
+ function collectTailwindRuntimeAdvisory(
1249
+ parsed: ParsedDocument,
1250
+ locate: Locator,
1185
1251
  ): DesignHtmlIntegrityIssueDetail[] {
1186
1252
  // Only documents that actually depend on utility classes can be broken by a
1187
1253
  // missing runtime. A screen styled entirely through its own CSS needs no
@@ -43,6 +43,11 @@
43
43
  # App URL (used for webhook callback construction)
44
44
  # APP_URL=https://your-app.example.com
45
45
 
46
+ # Optional exact registry for custom workspace apps that opt into Desktop SSO.
47
+ # Each entry must declare appId, clientId, an exact HTTPS origin, callbackPath
48
+ # "/_agent-native/identity/callback", and the "identity-sso" capability.
49
+ # IDENTITY_SSO_APP_REGISTRY_JSON=
50
+
46
51
  # Builder-backed app creation in production
47
52
  # DISPATCH_BUILDER_PROJECT_ID= # Default Builder project for new app branches
48
53
  # BUILDER_PUBLIC_KEY= # Builder space/public key
@@ -13,10 +13,9 @@ Read the relevant skill before deeper work:
13
13
 
14
14
  ## Core Rules
15
15
 
16
- - Store large file/blob payloads in configured file/blob storage, not SQL: no
17
- base64, `data:` URLs, images, video/audio, PDFs, ZIPs, screenshots,
18
- thumbnails, or replay chunks in app tables, `application_state`, `settings`,
19
- or `resources`; persist URLs, ids, or handles instead.
16
+ - Store large file/blob payloads in configured file/blob storage, not SQL:
17
+ persist URLs, ids, or handles instead of base64, media, documents, archives,
18
+ screenshots, thumbnails, or replay chunks.
20
19
  - Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
21
20
  - Treat Dispatch as workspace infrastructure. Prefer actions over raw SQL for
22
21
  vault, integrations, resource grants, messaging, routing, and approvals.
@@ -32,13 +31,22 @@ Read the relevant skill before deeper work:
32
31
  values or silently widen app access while doing this.
33
32
  - Use `view-screen` when the current integration, resource, approval, route, or
34
33
  setup item is unclear.
35
- - Dispatch keeps its primary navigation focused on Overview, Chat, Apps, and
36
- the workspace app rail. Workspace management and operator tools live under
37
- the top-level `/admin` control plane, which uses grouped navigation for
38
- `/admin/operations`, `/admin/metrics`, `/admin/integrations`, `/admin/vault`,
39
- `/admin/automations`, `/admin/approvals`, `/admin/destinations`,
40
- `/admin/agents`, `/admin/workspace`, `/admin/messaging`, `/admin/identities`,
41
- `/admin/audit`, `/admin/dreams`, and `/admin/thread-debug`.
34
+ - Use `import-agent` to normalize safe Claude Markdown or JSON into an
35
+ `agents/<slug>.md` profile; it skips credentials, hooks, shell, and local env.
36
+ - Use `import-agent-pack` for a Claude Project/Cowork-style folder. It keeps the
37
+ runnable profile at `agents/<slug>.md` and stores text references, context,
38
+ and agent-owned skills below `agents/<slug>/`. Use `list-agent-pack` to
39
+ inspect the files and the shared agent pack UI to edit them.
40
+ - Use `connect-external-agent` for public HTTP/A2A metadata; authenticate through
41
+ the normal connection flow.
42
+ - Dispatch's primary nav is Overview, Chat, Apps, Agents, and the app rail.
43
+ `/agents` creates/imports reusable profiles, opens per-agent chat, and can
44
+ hand a profile off to app creation; `/admin/agents` manages technical MCP/A2A
45
+ connections; other workspace/operator tools live under `/admin`.
46
+ - Agent profiles and agentic apps are also managed from Factory's top-level
47
+ Agents tab. Factory embeds the same agent actions and pack editor and reads
48
+ mounted app metadata through the shared Dispatch database; it does not create
49
+ a second agent registry.
42
50
  - Keep approval and routing behavior explicit. Never silently widen access to
43
51
  secrets, apps, integrations, or workspace resources.
44
52
  - Curated workspace templates are private app sources. Use
@@ -65,15 +73,12 @@ Read the relevant skill before deeper work:
65
73
  preserve the returned per-source health instead of treating an unavailable
66
74
  source as zero failures.
67
75
  - For a Slack-linked issue, call `read-slack-thread-context` with the exact
68
- permalink before diagnosing it. It resolves child links to the parent thread,
69
- preserves attachments and related URLs, and reports whether pagination is
70
- complete. Never treat an unreadable Slack thread as an empty one.
76
+ permalink before diagnosing it; preserve its pagination and readability
77
+ status instead of treating an unreadable thread as empty.
71
78
  - For usage investigations, use `list-dispatch-usage-metrics` with the smallest
72
- useful scope (`me` or `workspace`), lookback, and optional `userEmail` filter.
73
- Treat prompt attribution as evidence with gaps: `not-captured` and
74
- `unavailable` are not zero usage or a reason to guess. Use `view-screen` on
75
- `/admin/metrics` to keep the agent's analysis aligned with the visible scope
76
- and selected user.
79
+ useful scope and lookback. Treat `not-captured` and `unavailable` attribution
80
+ as gaps, not zero usage; use `view-screen` on `/admin/metrics` to align with
81
+ the visible scope and selected user.
77
82
 
78
83
  ## Application State
79
84
 
@@ -327,6 +327,8 @@ const enUS = {
327
327
  },
328
328
  pages: {
329
329
  adminDescription: "Workspace controls and operations",
330
+ simpleAgentsDescription:
331
+ "Create reusable agents in minutes, or import a setup you already made in Claude or another agent tool.",
330
332
  adminNavigation: "Admin navigation",
331
333
  adminWelcome: "Workspace control plane",
332
334
  adminChooseArea:
@@ -1209,6 +1211,8 @@ export const messagesByLocale = {
1209
1211
  pages: {
1210
1212
  ...chatFirstPageTranslations["zh-CN"],
1211
1213
  adminDescription: "工作区控制与运营",
1214
+ simpleAgentsDescription:
1215
+ "几分钟内创建可复用的代理,或导入你已在 Claude 或其他代理工具中创建的设置。",
1212
1216
  adminNavigation: "管理导航",
1213
1217
  adminWelcome: "工作区控制中心",
1214
1218
  adminChooseArea: "在一个地方管理应用、连接、自动化和运营工具。",
@@ -1623,6 +1627,8 @@ export const messagesByLocale = {
1623
1627
  pages: {
1624
1628
  ...chatFirstPageTranslations["es-ES"],
1625
1629
  adminDescription: "Controles y operaciones del espacio de trabajo",
1630
+ simpleAgentsDescription:
1631
+ "Crea agentes reutilizables en minutos o importa una configuración que ya hayas creado en Claude u otra herramienta de agentes.",
1626
1632
  adminNavigation: "Navegación de administración",
1627
1633
  adminWelcome: "Panel de control del espacio de trabajo",
1628
1634
  adminChooseArea:
@@ -2048,6 +2054,8 @@ export const messagesByLocale = {
2048
2054
  pages: {
2049
2055
  ...chatFirstPageTranslations["fr-FR"],
2050
2056
  adminDescription: "Contrôles et opérations de l’espace de travail",
2057
+ simpleAgentsDescription:
2058
+ "Créez des agents réutilisables en quelques minutes ou importez une configuration déjà créée dans Claude ou un autre outil d’agents.",
2051
2059
  adminNavigation: "Navigation d’administration",
2052
2060
  adminWelcome: "Centre de contrôle de l’espace de travail",
2053
2061
  adminChooseArea:
@@ -2463,6 +2471,8 @@ export const messagesByLocale = {
2463
2471
  pages: {
2464
2472
  ...chatFirstPageTranslations["de-DE"],
2465
2473
  adminDescription: "Arbeitsbereichssteuerung und -betrieb",
2474
+ simpleAgentsDescription:
2475
+ "Erstelle in wenigen Minuten wiederverwendbare Agents oder importiere eine Konfiguration, die du bereits in Claude oder einem anderen Agent-Tool erstellt hast.",
2466
2476
  adminNavigation: "Administrationsnavigation",
2467
2477
  adminWelcome: "Arbeitsbereichsleitstelle",
2468
2478
  adminChooseArea:
@@ -2873,6 +2883,8 @@ export const messagesByLocale = {
2873
2883
  pages: {
2874
2884
  ...chatFirstPageTranslations["ja-JP"],
2875
2885
  adminDescription: "ワークスペースの管理と運用",
2886
+ simpleAgentsDescription:
2887
+ "数分で再利用可能なエージェントを作成するか、Claude などのエージェントツールで作成済みの設定をインポートします。",
2876
2888
  adminNavigation: "管理ナビゲーション",
2877
2889
  adminWelcome: "ワークスペースのコントロールプレーン",
2878
2890
  adminChooseArea:
@@ -3277,6 +3289,8 @@ export const messagesByLocale = {
3277
3289
  pages: {
3278
3290
  ...chatFirstPageTranslations["ko-KR"],
3279
3291
  adminDescription: "워크스페이스 제어 및 운영",
3292
+ simpleAgentsDescription:
3293
+ "몇 분 만에 재사용 가능한 에이전트를 만들거나 Claude 또는 다른 에이전트 도구에서 만든 설정을 가져오세요.",
3280
3294
  adminNavigation: "관리 탐색",
3281
3295
  adminWelcome: "워크스페이스 제어 센터",
3282
3296
  adminChooseArea:
@@ -3691,6 +3705,8 @@ export const messagesByLocale = {
3691
3705
  pages: {
3692
3706
  ...chatFirstPageTranslations["pt-BR"],
3693
3707
  adminDescription: "Controles e operações do espaço de trabalho",
3708
+ simpleAgentsDescription:
3709
+ "Crie agentes reutilizáveis em minutos ou importe uma configuração que você já criou no Claude ou em outra ferramenta de agentes.",
3694
3710
  adminNavigation: "Navegação de administração",
3695
3711
  adminWelcome: "Central de controle do espaço de trabalho",
3696
3712
  adminChooseArea:
@@ -4096,6 +4112,8 @@ export const messagesByLocale = {
4096
4112
  pages: {
4097
4113
  ...chatFirstPageTranslations["hi-IN"],
4098
4114
  adminDescription: "वर्कस्पेस नियंत्रण और संचालन",
4115
+ simpleAgentsDescription:
4116
+ "कुछ ही मिनटों में दोबारा इस्तेमाल किए जा सकने वाले एजेंट बनाएं, या Claude या किसी अन्य एजेंट टूल में पहले से बनाई गई सेटअप इंपोर्ट करें।",
4099
4117
  adminNavigation: "व्यवस्थापक नेविगेशन",
4100
4118
  adminWelcome: "वर्कस्पेस नियंत्रण केंद्र",
4101
4119
  adminChooseArea:
@@ -4529,6 +4547,8 @@ export const messagesByLocale = {
4529
4547
  pages: {
4530
4548
  ...chatFirstPageTranslations["ar-SA"],
4531
4549
  adminDescription: "عناصر التحكم في مساحة العمل وعملياتها",
4550
+ simpleAgentsDescription:
4551
+ "أنشئ وكلاء قابلين لإعادة الاستخدام خلال دقائق، أو استورد إعدادًا أنشأته بالفعل في Claude أو أداة وكلاء أخرى.",
4532
4552
  adminNavigation: "تنقل الإدارة",
4533
4553
  adminWelcome: "مركز التحكم في مساحة العمل",
4534
4554
  adminChooseArea:
@@ -14,7 +14,15 @@
14
14
 
15
15
  import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
16
16
 
17
- import { getDbExec, intType } from "@agent-native/core/db";
17
+ import {
18
+ getDbExec,
19
+ intType,
20
+ isProductionServerlessFunctionRuntime,
21
+ } from "@agent-native/core/db";
22
+ import {
23
+ CANONICAL_WORKSPACE_SSO_APP_ORIGINS,
24
+ parseWorkspaceSsoAppRegistrations,
25
+ } from "@agent-native/dispatch/shared/workspace-sso";
18
26
 
19
27
  const CONTROL_CHARS = /[\u0000-\u001f\u007f]/;
20
28
  const APP_ID = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
@@ -62,22 +70,7 @@ export function normalizeIdentityAuthority(raw: unknown): string | null {
62
70
 
63
71
  /** Exact first-party app origins. Never replace this with a suffix check. */
64
72
  export const CANONICAL_IDENTITY_SSO_APP_ORIGINS = {
65
- analytics: "https://analytics.agent-native.com",
66
- assets: "https://assets.agent-native.com",
67
- brain: "https://brain.agent-native.com",
68
- calendar: "https://calendar.agent-native.com",
69
- chat: "https://chat.agent-native.com",
70
- clips: "https://clips.agent-native.com",
71
- content: "https://content.agent-native.com",
72
- crm: "https://crm.agent-native.com",
73
- design: "https://design.agent-native.com",
74
- dispatch: "https://dispatch.agent-native.com",
75
- forms: "https://forms.agent-native.com",
76
- macros: "https://macros.agent-native.com",
77
- mail: "https://mail.agent-native.com",
78
- plan: "https://plan.agent-native.com",
79
- slides: "https://slides.agent-native.com",
80
- tasks: "https://tasks.agent-native.com",
73
+ ...CANONICAL_WORKSPACE_SSO_APP_ORIGINS,
81
74
  } as const;
82
75
 
83
76
  export const DEFAULT_ALLOWED_ORIGINS: readonly string[] = Object.values(
@@ -102,82 +95,17 @@ function canonicalRegistrations(): IdentitySsoAppRegistration[] {
102
95
  );
103
96
  }
104
97
 
105
- function exactOrigin(raw: unknown): string | null {
106
- if (typeof raw !== "string" || !raw || CONTROL_CHARS.test(raw)) return null;
107
- try {
108
- const url = new URL(raw);
109
- if (
110
- url.protocol !== "https:" &&
111
- !(url.protocol === "http:" && LOCALHOST_HOSTS.has(url.hostname))
112
- ) {
113
- return null;
114
- }
115
- if (
116
- url.username ||
117
- url.password ||
118
- url.pathname !== "/" ||
119
- url.search ||
120
- url.hash
121
- ) {
122
- return null;
123
- }
124
- return url.origin;
125
- } catch (error) {
126
- void error;
127
- return null;
128
- }
129
- }
130
-
131
98
  function parseCustomRegistrations(
132
99
  env: NodeJS.ProcessEnv,
133
100
  ): IdentitySsoAppRegistration[] {
134
- const raw = env.IDENTITY_SSO_APP_REGISTRY_JSON?.trim();
135
- if (!raw) return [];
136
- let value: unknown;
137
- try {
138
- value = JSON.parse(raw);
139
- } catch (error) {
140
- void error;
141
- return [];
142
- }
143
- if (!Array.isArray(value)) return [];
144
-
145
- const registrations: IdentitySsoAppRegistration[] = [];
146
- const seen = new Set<string>();
147
- for (const entry of value) {
148
- if (!entry || typeof entry !== "object") continue;
149
- const candidate = entry as Record<string, unknown>;
150
- const appId = candidate.appId;
151
- const clientId = candidate.clientId;
152
- const origin = exactOrigin(candidate.origin);
153
- const callbackPath = candidate.callbackPath;
154
- const capabilities = candidate.capabilities;
155
- if (
156
- typeof appId !== "string" ||
157
- !APP_ID.test(appId) ||
158
- typeof clientId !== "string" ||
159
- !CLIENT_ID.test(clientId) ||
160
- !origin ||
161
- callbackPath !== IDENTITY_SSO_CALLBACK_PATH ||
162
- !Array.isArray(capabilities) ||
163
- !capabilities.includes("identity-sso") ||
164
- seen.has(appId) ||
165
- Object.prototype.hasOwnProperty.call(
166
- CANONICAL_IDENTITY_SSO_APP_ORIGINS,
167
- appId,
168
- )
169
- ) {
170
- continue;
171
- }
172
- seen.add(appId);
173
- registrations.push({
174
- appId,
175
- clientId,
176
- origin,
177
- callbackPath: IDENTITY_SSO_CALLBACK_PATH,
178
- });
179
- }
180
- return registrations;
101
+ return parseWorkspaceSsoAppRegistrations(
102
+ env.IDENTITY_SSO_APP_REGISTRY_JSON,
103
+ ).map((registration) => ({
104
+ appId: registration.appId,
105
+ clientId: registration.clientId,
106
+ origin: registration.origin,
107
+ callbackPath: IDENTITY_SSO_CALLBACK_PATH,
108
+ }));
181
109
  }
182
110
 
183
111
  /**
@@ -390,6 +318,9 @@ function buildCodeTableSql(): string {
390
318
  }
391
319
 
392
320
  async function ensureCodeTable(): Promise<void> {
321
+ // The Dispatch release migration owns this table in production serverless
322
+ // deployments. Do not turn a missing release migration into request-time DDL.
323
+ if (isProductionServerlessFunctionRuntime()) return;
393
324
  if (!codeTableInitPromise) {
394
325
  codeTableInitPromise = getDbExec()
395
326
  .execute(buildCodeTableSql())
@@ -17,9 +17,8 @@
17
17
 
18
18
  import { signA2AToken } from "@agent-native/core/a2a";
19
19
  import {
20
- getFeatureFlagRules,
20
+ hasActiveFeatureFlagRollout,
21
21
  isFeatureFlagEnabled,
22
- normalizeFeatureFlagRules,
23
22
  } from "@agent-native/core/feature-flags";
24
23
  import { getOrgDomain } from "@agent-native/core/org";
25
24
  import { getH3App, getSession } from "@agent-native/core/server";
@@ -103,16 +102,8 @@ async function resolveOrgDomain(
103
102
  }
104
103
 
105
104
  export async function canAttemptWorkspaceSso(): Promise<boolean> {
106
- const stored = await getFeatureFlagRules(
107
- DESKTOP_WORKSPACE_SSO_FLAG.key,
108
- {},
109
- ).catch(() => null);
110
- if (!stored) return false;
111
- const rules = normalizeFeatureFlagRules(stored);
112
- if (rules.mode === "off") return false;
113
- if (rules.mode === "on") return true;
114
- return (
115
- rules.emails.length > 0 || rules.orgIds.length > 0 || rules.percentage > 0
105
+ return hasActiveFeatureFlagRollout(DESKTOP_WORKSPACE_SSO_FLAG.key).catch(
106
+ () => false,
116
107
  );
117
108
  }
118
109
 
@@ -2,6 +2,9 @@ import {
2
2
  defineFeatureFlag,
3
3
  defineFeatureFlags,
4
4
  } from "@agent-native/core/feature-flags";
5
+ import { DISPATCH_WORKSPACE_SSO_FLAG } from "@agent-native/dispatch/shared/feature-flags";
6
+
7
+ export { DISPATCH_WORKSPACE_SSO_FLAG };
5
8
 
6
9
  export const DESKTOP_WORKSPACE_SSO_FLAG = defineFeatureFlag({
7
10
  key: "desktop.workspace-sso",
@@ -12,4 +15,5 @@ export const DESKTOP_WORKSPACE_SSO_FLAG = defineFeatureFlag({
12
15
 
13
16
  export const DISPATCH_FEATURE_FLAGS = defineFeatureFlags([
14
17
  DESKTOP_WORKSPACE_SSO_FLAG,
18
+ DISPATCH_WORKSPACE_SSO_FLAG,
15
19
  ]);
@@ -37,7 +37,7 @@ decisions, feedback, agent runs, and provider audit records.
37
37
 
38
38
  - `navigation.view`: `factory` when the workspace is open.
39
39
  - `navigation.factoryId`: selected Factory id when present.
40
- - `navigation.factoryTab`: `map` | `inbox` | `rules` | `automations` | `audit` | `settings`.
40
+ - `navigation.factoryTab`: `map` | `inbox` | `rules` | `automations` | `agents` | `audit` | `settings`.
41
41
  - `navigation.factoryAuditRunId`: selected automation run in the audit view when present.
42
42
  - `navigation.factoryNodeId` / `navigation.factoryEdgeId`: selected graph item.
43
43
  - A selected graph node or edge is part of `navigation` context. Read
@@ -68,6 +68,10 @@ decisions, feedback, agent runs, and provider audit records.
68
68
  | `save-factory-graph` | Create or version a complete visual graph; never starts provider work. |
69
69
  | `list-factory-comments` / `add-factory-comment` | Read or attach comments to a canvas, node, or edge. |
70
70
  | `provider-api-catalog` / `provider-api-docs` / `provider-api-request` | Discover and use connected provider APIs with shared workspace credentials; never request raw keys. |
71
+ | `list-workspace-apps` / `update-workspace-app-metadata` | Inventory and edit mounted agentic apps in the shared workspace. |
72
+ | `list-workspace-resources` / `create-workspace-resource` / `update-workspace-resource` | Manage shared resource records used by agents and apps. |
73
+ | `import-agent` / `import-agent-pack` / `list-agent-pack` | Import a simple profile or a Claude/Cowork-style folder-backed agent pack. |
74
+ | `start-workspace-app-creation` | Promote an agent and all of its pack resource ids into an app-creation handoff. |
71
75
 
72
76
  Rules start in shadow mode; hard guards always apply. Organization automations
73
77
  execute stored prompts, and every external mutation needs a durable run,
@@ -74,6 +74,29 @@ signed callback secret belong in Dispatch workspace credentials and are
74
74
  resolved at runtime. The app remains observe-only until a human explicitly
75
75
  approves a Factory item.
76
76
 
77
+ ## Agents and agentic apps
78
+
79
+ Factory's top-level Agents tab is a shared workspace surface, not a second
80
+ registry. It reads mounted agentic apps and their editable Dispatch metadata,
81
+ then embeds Dispatch's reusable-agent manager for create, chat, import, and
82
+ folder-backed pack editing. A simple agent's profile lives at
83
+ `agents/<slug>.md`; its optional context, references, and private skills live
84
+ under `agents/<slug>/`. Use the folder import to bring in a Claude Project,
85
+ Cowork-style folder, or another text-based agent setup. The importer strips
86
+ credentials, hooks, shell commands, and local environment settings, and All-app
87
+ imports remain subject to Dispatch approval policy.
88
+
89
+ When editing a factory flow, an agent step can bind to either a shared reusable
90
+ agent or a ready mounted agentic app from the same workspace database. The map
91
+ stores the selected target type and id, while the graph remains a reviewable
92
+ blueprint and does not silently change runtime routing.
93
+
94
+ Use **Build app** on an agent row when the agent needs a full workspace face.
95
+ The handoff carries the profile and every pack resource id into app creation;
96
+ the original agent remains reusable after the app is created. Mounted apps and
97
+ simple agents continue to use the same Dispatch actions, SQL resources, grants,
98
+ and application-state navigation.
99
+
77
100
  ## Development
78
101
 
79
102
  ```bash
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { defineAction } from "@agent-native/core/action";
11
11
  import { readAppState } from "@agent-native/core/application-state";
12
+ import { dispatchActions } from "@agent-native/dispatch/actions";
12
13
  import { z } from "zod";
13
14
 
14
15
  import {
@@ -22,6 +23,12 @@ import {
22
23
  workspaceMemberIdentityFromContext,
23
24
  } from "../server/lib/require-workspace-member.js";
24
25
 
26
+ async function runDispatchAction(name: string, args: Record<string, unknown>) {
27
+ const action = dispatchActions[name];
28
+ if (!action) throw new Error(`Dispatch action not found: ${name}`);
29
+ return action.run(args);
30
+ }
31
+
25
32
  export default defineAction({
26
33
  description:
27
34
  "See what the user is currently looking at on screen. Returns the current navigation state for chat or Factory. Always call this first when the visible selection matters.",
@@ -63,6 +70,16 @@ export default defineAction({
63
70
  selectedNode: graph.nodes.find((node) => node.id === selectedNodeId),
64
71
  selectedEdge: graph.edges.find((edge) => edge.id === selectedEdgeId),
65
72
  };
73
+
74
+ if (state.factoryTab === "agents") {
75
+ const [apps, agents] = await Promise.all([
76
+ runDispatchAction("list-workspace-apps", {
77
+ includeAgentCards: false,
78
+ }),
79
+ runDispatchAction("list-workspace-resources", { kind: "agent" }),
80
+ ]);
81
+ screen.factoryAgents = { apps, agents };
82
+ }
66
83
  }
67
84
 
68
85
  if (Object.keys(screen).length === 0) {