@agent-native/core 0.154.5 → 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 (185) 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/actions/add-comment.ts +2 -1
  87. package/corpus/templates/content/actions/update-comment.ts +1 -1
  88. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +24 -15
  89. package/corpus/templates/design/actions/generate-design.ts +10 -7
  90. package/corpus/templates/design/actions/present-design-variants.ts +35 -6
  91. package/corpus/templates/design/actions/run-design-audit.ts +33 -0
  92. package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-catches-a-screen-that-renders-behind-an.md +6 -0
  93. package/corpus/templates/design/shared/design-review.ts +1 -0
  94. package/corpus/templates/design/shared/html-integrity.ts +66 -0
  95. package/corpus/templates/dispatch/.env.example +5 -0
  96. package/corpus/templates/dispatch/AGENTS.md +24 -19
  97. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  98. package/corpus/templates/dispatch/server/lib/identity-sso.ts +21 -90
  99. package/corpus/templates/dispatch/server/plugins/identity-sso.ts +3 -12
  100. package/corpus/templates/dispatch/shared/feature-flags.ts +4 -0
  101. package/corpus/templates/factory/AGENTS.md +5 -1
  102. package/corpus/templates/factory/README.md +23 -0
  103. package/corpus/templates/factory/actions/view-screen.ts +17 -0
  104. package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +239 -0
  105. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +2 -0
  106. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +130 -7
  107. package/corpus/templates/factory/app/i18n/en-US.ts +20 -0
  108. package/corpus/templates/factory/app/routes/factory.tsx +41 -0
  109. package/corpus/templates/factory/package.json +1 -0
  110. package/corpus/templates/factory/server/factory-graph/contracts.ts +2 -0
  111. package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -0
  112. package/corpus/templates/factory/server/plugins/dispatch-db.ts +1 -0
  113. package/corpus/templates/factory/server/plugins/setup-dispatch.ts +3 -0
  114. package/corpus/templates/mail/app/lib/native-mcp-exclusions.ts +3 -0
  115. package/corpus/templates/mail/vite.config.ts +7 -0
  116. package/corpus/templates/plan/actions/reply-to-plan-comment.ts +7 -2
  117. package/corpus/templates/plan/actions/resolve-plan-comment.ts +2 -2
  118. package/corpus/templates/plan/actions/update-visual-plan.ts +1 -1
  119. package/corpus/templates/plan/app/pages/PlansPage.tsx +29 -20
  120. package/corpus/templates/slides/actions/add-slide-comment.ts +1 -1
  121. package/corpus/templates/slides/actions/update-slide-comment.ts +1 -1
  122. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +9 -6
  123. package/dist/agent/production-agent.js +5 -1
  124. package/dist/agent/thread-data-builder.js +17 -1
  125. package/dist/cli/skills-content/help.js +6 -4
  126. package/dist/cli/skills.js +17 -2
  127. package/dist/cli/workspacify.d.ts +5 -0
  128. package/dist/cli/workspacify.js +65 -8
  129. package/dist/client/AgentPanel.d.ts +5 -0
  130. package/dist/client/AgentPanel.js +20 -4
  131. package/dist/client/AssistantChat.d.ts +21 -0
  132. package/dist/client/AssistantChat.js +66 -68
  133. package/dist/client/active-run-state.d.ts +14 -1
  134. package/dist/client/active-run-state.js +0 -0
  135. package/dist/client/agent-chat-adapter.js +107 -5
  136. package/dist/client/analytics.js +9 -2
  137. package/dist/client/chat/tool-call-display.js +4 -4
  138. package/dist/client/chat-first/apps-rail.js +9 -4
  139. package/dist/client/chat-first/primary-nav.d.ts +2 -1
  140. package/dist/client/chat-first/primary-nav.js +3 -3
  141. package/dist/client/chat-first/types.d.ts +5 -1
  142. package/dist/client/markdown/InlineMarkdown.d.ts +23 -0
  143. package/dist/client/markdown/InlineMarkdown.js +65 -0
  144. package/dist/client/markdown/index.d.ts +1 -0
  145. package/dist/client/markdown/index.js +1 -0
  146. package/dist/client/review/ReviewThreadPanel.js +2 -1
  147. package/dist/client/run-stream-ownership.d.ts +39 -0
  148. package/dist/client/run-stream-ownership.js +65 -0
  149. package/dist/collab/awareness.d.ts +2 -2
  150. package/dist/collab/struct-routes.d.ts +1 -1
  151. package/dist/feature-flags/index.d.ts +1 -1
  152. package/dist/feature-flags/index.js +1 -1
  153. package/dist/feature-flags/store.d.ts +10 -0
  154. package/dist/feature-flags/store.js +112 -1
  155. package/dist/guards/no-env-credentials.js +4 -0
  156. package/dist/index.d.ts +1 -1
  157. package/dist/index.js +1 -1
  158. package/dist/integrations/adapters/slack.js +5 -1
  159. package/dist/localization/default-messages.d.ts +1 -0
  160. package/dist/localization/default-messages.js +1 -0
  161. package/dist/observability/routes.d.ts +6 -6
  162. package/dist/progress/routes.d.ts +1 -1
  163. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  164. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  165. package/dist/resources/agents.js +40 -5
  166. package/dist/resources/handlers.d.ts +1 -1
  167. package/dist/resources/metadata.d.ts +10 -0
  168. package/dist/resources/metadata.js +7 -3
  169. package/dist/review/actions/create-review-comment.js +1 -1
  170. package/dist/review/actions/reply-review-comment.js +1 -1
  171. package/dist/review/actions/resolve-review-thread.js +1 -1
  172. package/dist/secrets/routes.d.ts +3 -3
  173. package/dist/server/action-routes.js +32 -6
  174. package/dist/server/agent-discovery.js +14 -3
  175. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  176. package/dist/server/core-routes-plugin.js +1 -1
  177. package/dist/server/identity-sso-migrations.d.ts +7 -0
  178. package/dist/server/identity-sso-migrations.js +36 -0
  179. package/dist/server/identity-sso-store.d.ts +3 -2
  180. package/dist/server/identity-sso-store.js +8 -3
  181. package/dist/server/realtime-token.d.ts +1 -1
  182. package/dist/server/release-migrations.js +4 -0
  183. package/dist/tracking/providers.js +13 -3
  184. package/dist/workspace-files/tool.js +1 -1
  185. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
1
  export { defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
3
3
  export { createFeatureFlagsPlugin } from "./plugin.js";
4
4
  export { createFeatureFlagA2AActionRouteAuth } from "./a2a-action-route.js";
@@ -1,4 +1,4 @@
1
1
  export { defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, } from "./store.js";
3
3
  export { createFeatureFlagsPlugin } from "./plugin.js";
4
4
  export { createFeatureFlagA2AActionRouteAuth } from "./a2a-action-route.js";
@@ -19,6 +19,16 @@ export declare const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
19
19
  export declare function defaultFeatureFlagRules(): FeatureFlagRules;
20
20
  export declare function normalizeFeatureFlagRules(value: unknown): FeatureFlagRules;
21
21
  export declare function getFeatureFlagRules(key: string, scope: Pick<FeatureFlagScope, "orgId">): Promise<FeatureFlagRules>;
22
+ /**
23
+ * Anonymous discovery hint for a rollout that may be scoped to an org.
24
+ *
25
+ * This deliberately answers only whether some active rollout exists. It does
26
+ * not reveal the target email or organization, and callers must still run
27
+ * `evaluateFeatureFlag` with the authenticated scope before granting access.
28
+ * Without this separate hint, an org-only rollout is invisible to Desktop
29
+ * before the user has authenticated and the org can be resolved.
30
+ */
31
+ export declare function hasActiveFeatureFlagRollout(key: string): Promise<boolean>;
22
32
  /**
23
33
  * Atomically derive one flag's scoped rules. An org's first override starts
24
34
  * from the global fallback, then becomes independently CAS-protected.
@@ -1,10 +1,73 @@
1
+ import { getDbExec, isPostgres } from "../db/client.js";
1
2
  import { getOrgSetting, mutateOrgSetting } from "../settings/org-settings.js";
2
3
  import { getSetting, mutateSetting } from "../settings/store.js";
3
4
  import { getFeatureFlagDefinition, } from "./registry.js";
4
5
  export const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
6
+ const FEATURE_FLAG_ROLLOUT_INDEX_PREFIX = "feature-flag-rollout-index:";
5
7
  function settingKey(key) {
6
8
  return `${FEATURE_FLAG_SETTINGS_PREFIX}${key}`;
7
9
  }
10
+ function rolloutIndexKey(key) {
11
+ return `${FEATURE_FLAG_ROLLOUT_INDEX_PREFIX}${key}`;
12
+ }
13
+ function parseStoredRules(value) {
14
+ if (typeof value === "string")
15
+ return normalizeFeatureFlagRules(JSON.parse(value));
16
+ return normalizeFeatureFlagRules(value);
17
+ }
18
+ function hasActiveRollout(rules) {
19
+ return (rules.mode === "on" ||
20
+ (rules.mode === "rules" &&
21
+ (rules.emails.length > 0 ||
22
+ rules.orgIds.length > 0 ||
23
+ rules.percentage > 0)));
24
+ }
25
+ function normalizeFeatureFlagRolloutIndex(value) {
26
+ if (!value || typeof value !== "object")
27
+ return null;
28
+ const raw = value;
29
+ const orgIds = Array.isArray(raw.orgIds)
30
+ ? [
31
+ ...new Set(raw.orgIds.filter((item) => typeof item === "string")),
32
+ ]
33
+ .map((orgId) => orgId.trim())
34
+ .filter(Boolean)
35
+ .sort()
36
+ : [];
37
+ return {
38
+ version: 1,
39
+ global: raw.global === true,
40
+ orgIds,
41
+ };
42
+ }
43
+ function activeFeatureFlagRolloutIndex(index) {
44
+ return index.global || index.orgIds.length > 0;
45
+ }
46
+ async function syncFeatureFlagRolloutIndex(key, scope, rules) {
47
+ const indexKey = rolloutIndexKey(key);
48
+ await mutateSetting(indexKey, async (current) => {
49
+ const next = normalizeFeatureFlagRolloutIndex(current) ?? {
50
+ version: 1,
51
+ global: false,
52
+ orgIds: [],
53
+ };
54
+ if (scope.orgId?.trim()) {
55
+ const orgId = scope.orgId.trim();
56
+ const active = hasActiveRollout(rules);
57
+ const orgIds = active
58
+ ? [...new Set([...next.orgIds, orgId])].sort()
59
+ : next.orgIds.filter((value) => value !== orgId);
60
+ return {
61
+ ...next,
62
+ orgIds,
63
+ };
64
+ }
65
+ return {
66
+ ...next,
67
+ global: hasActiveRollout(rules),
68
+ };
69
+ });
70
+ }
8
71
  export function defaultFeatureFlagRules() {
9
72
  return {
10
73
  version: 1,
@@ -66,6 +129,52 @@ export async function getFeatureFlagRules(key, scope) {
66
129
  ]);
67
130
  return normalizeFeatureFlagRules(orgStored ?? globalStored);
68
131
  }
132
+ /**
133
+ * Anonymous discovery hint for a rollout that may be scoped to an org.
134
+ *
135
+ * This deliberately answers only whether some active rollout exists. It does
136
+ * not reveal the target email or organization, and callers must still run
137
+ * `evaluateFeatureFlag` with the authenticated scope before granting access.
138
+ * Without this separate hint, an org-only rollout is invisible to Desktop
139
+ * before the user has authenticated and the org can be resolved.
140
+ */
141
+ export async function hasActiveFeatureFlagRollout(key) {
142
+ if (!getFeatureFlagDefinition(key))
143
+ return false;
144
+ const indexKey = rolloutIndexKey(key);
145
+ const storedIndex = normalizeFeatureFlagRolloutIndex(await getSetting(indexKey));
146
+ if (storedIndex)
147
+ return activeFeatureFlagRolloutIndex(storedIndex);
148
+ const globalStored = await getSetting(settingKey(key));
149
+ const globalActive = hasActiveRollout(parseStoredRules(globalStored));
150
+ if (globalActive) {
151
+ await mutateSetting(indexKey, async () => ({
152
+ version: 1,
153
+ global: true,
154
+ orgIds: [],
155
+ }));
156
+ return true;
157
+ }
158
+ const table = isPostgres() ? "public.settings" : "settings";
159
+ const { rows } = await getDbExec().execute({
160
+ sql: `SELECT key, value FROM ${table} WHERE key LIKE ?`,
161
+ args: [`o:%:${settingKey(key)}`],
162
+ });
163
+ const orgIds = rows
164
+ .filter((row) => hasActiveRollout(parseStoredRules(row.value)))
165
+ .map((row) => {
166
+ const match = /^o:([^:]+):/.exec(row.key ?? "");
167
+ return match?.[1] ?? null;
168
+ })
169
+ .filter((orgId) => Boolean(orgId))
170
+ .sort();
171
+ await mutateSetting(indexKey, async () => ({
172
+ version: 1,
173
+ global: false,
174
+ orgIds,
175
+ }));
176
+ return orgIds.length > 0;
177
+ }
69
178
  /**
70
179
  * Atomically derive one flag's scoped rules. An org's first override starts
71
180
  * from the global fallback, then becomes independently CAS-protected.
@@ -85,7 +194,9 @@ export async function mutateFeatureFlagRules(key, scope, updater) {
85
194
  const persisted = scope.orgId?.trim()
86
195
  ? await mutateOrgSetting(scope.orgId, settingKey(key), mutate)
87
196
  : await mutateSetting(settingKey(key), mutate);
88
- return normalizeFeatureFlagRules(persisted);
197
+ const normalized = normalizeFeatureFlagRules(persisted);
198
+ await syncFeatureFlagRolloutIndex(key, scope, normalized);
199
+ return normalized;
89
200
  }
90
201
  function rolloutBucket(input) {
91
202
  // FNV-1a is deliberately tiny, deterministic, and independent of runtime.
@@ -55,6 +55,10 @@ const ALLOWLIST_EXACT = new Set([
55
55
  "AWS_LAMBDA_FUNCTION_NAME",
56
56
  "BETTER_AUTH_SECRET",
57
57
  "BETTER_AUTH_URL",
58
+ // Public deployment identity/configuration. These select the app origin and
59
+ // explicitly registered SSO clients; they are not user credentials.
60
+ "APP_URL",
61
+ "IDENTITY_SSO_APP_REGISTRY_JSON",
58
62
  "NOTION_CLIENT_ID",
59
63
  "NOTION_CLIENT_SECRET",
60
64
  "NOTION_STATE_SECRET",
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export { createAgentChatPlugin, defaultAgentChatPlugin, type AgentChatPluginOpti
11
11
  export { createAgentNativeEmbeddedPlugin, mountAgentNativeEmbedded, type AgentNativeEmbeddedPluginOptions, } from "./server/embedded.js";
12
12
  export { BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, type AutomationCapabilities, type BuiltInChannelId, type ChannelCapabilities, type IntegrationAvailability, type IntegrationCatalogEntry, type IntegrationCategory, type IntegrationCredentialRequirement, type IntegrationIconKey, type IntegrationSupportMaturity, } from "./integrations/catalog.js";
13
13
  export { AutomationConnectorError, createAutomationCallbackHandler, createAutomationRuntime, createInvokeAutomationWorkflowAction, type AutomationCallbackAuthentication, type AutomationCallbackInput, type AutomationCallbackResult, type AutomationInboundDefinition, type AutomationInvocation, type AutomationInvocationResult, type AutomationInvocationStatus, type AutomationOutboundDefinition, type AutomationResponseMode, type AutomationRetryPolicy, type AutomationRuntime, type AutomationRuntimeOptions, type AutomationWorkflowCapabilities, type AutomationWorkflowDefinition, type JsonSchema, } from "./automation/index.js";
14
- export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./feature-flags/index.js";
14
+ export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./feature-flags/index.js";
15
15
  export { createServer, createSSEHandler, defineNitroPlugin, autoMountAuth, getSession, type CreateServerOptions, type SSEHandlerOptions, type AuthSession, type AuthOptions, } from "./server/index.js";
16
16
  export { agentChat, type AgentChatCallOptions, type AgentChatResponse, } from "./shared/index.js";
17
17
  export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./shared/embed-auth.js";
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ export { createAgentChatPlugin, defaultAgentChatPlugin, } from "./server/agent-c
16
16
  export { createAgentNativeEmbeddedPlugin, mountAgentNativeEmbedded, } from "./server/embedded.js";
17
17
  export { BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, } from "./integrations/catalog.js";
18
18
  export { AutomationConnectorError, createAutomationCallbackHandler, createAutomationRuntime, createInvokeAutomationWorkflowAction, } from "./automation/index.js";
19
- export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, } from "./feature-flags/index.js";
19
+ export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, } from "./feature-flags/index.js";
20
20
  // Server
21
21
  export { createServer, createSSEHandler, defineNitroPlugin, autoMountAuth, getSession, } from "./server/index.js";
22
22
  // Client
@@ -858,7 +858,11 @@ function markdownToSlackMrkdwn(text) {
858
858
  // pathological "**" sequence that exhibits super-linear backtracking.
859
859
  // Newlines are allowed because `[^*]` excludes only the asterisk
860
860
  // itself, so multi-line bold spans still match.
861
- .replace(/\*\*([^*]{1,5000})\*\*/g, "*$1*"));
861
+ .replace(/\*\*([^*]{1,5000})\*\*/g, "*$1*")
862
+ // Agent output sometimes uses Markdown-style bare Slack user IDs.
863
+ // Leave native `<@...>` mentions untouched while converting the bare
864
+ // user/member forms Slack expects in mrkdwn.
865
+ .replace(/(?<![<\w])@([UW][A-Z0-9]+)(?![A-Z0-9])/g, "<@$1>"));
862
866
  }
863
867
  /**
864
868
  * Optionally set Slack's native Agent status indicator (the small "is
@@ -315,6 +315,7 @@ declare const messages: {
315
315
  openApp: string;
316
316
  notDispatchOrWorkspaceApp: string;
317
317
  agentsDescription: string;
318
+ simpleAgentsDescription: string;
318
319
  mcpAccessUpdated: string;
319
320
  selectAppForMcp: string;
320
321
  mcpUrlCopied: string;
@@ -321,6 +321,7 @@ const messages = {
321
321
  openApp: "Open app",
322
322
  notDispatchOrWorkspaceApp: " a Dispatch tab or a workspace app in this workspace.",
323
323
  agentsDescription: "Dispatch can delegate to the built-in app suite over A2A by default. Add extra agents here only if you want to route work to apps outside that built-in set.",
324
+ simpleAgentsDescription: "Create reusable agents in minutes, or import a setup you already made in Claude or another agent tool.",
324
325
  mcpAccessUpdated: "Agent integration access updated",
325
326
  selectAppForMcp: "Select at least one app, or expose all apps.",
326
327
  mcpUrlCopied: "Agent integration URL copied",
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- ok?: undefined;
45
- error?: undefined;
46
44
  summary: import("./types.js").TraceSummary;
47
45
  spans: import("./types.js").TraceSpan[];
48
46
  id?: undefined;
49
- } | {
50
- ok?: undefined;
51
47
  error?: undefined;
48
+ ok?: undefined;
49
+ } | {
52
50
  summary?: undefined;
53
51
  spans?: undefined;
54
52
  id: string;
55
- } | {
53
+ error?: undefined;
56
54
  ok?: undefined;
55
+ } | {
57
56
  summary?: undefined;
58
57
  spans?: undefined;
59
58
  id?: undefined;
60
59
  error: any;
60
+ ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;
@@ -75,9 +75,11 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- deleted?: undefined;
79
78
  id?: undefined;
80
79
  provider?: undefined;
80
+ deleted?: undefined;
81
+ found?: undefined;
82
+ message?: undefined;
81
83
  providers: {
82
84
  id: string;
83
85
  label: string;
@@ -88,46 +90,44 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
88
90
  updatedAt: number;
89
91
  }[];
90
92
  count: number;
91
- found?: undefined;
92
93
  registered?: undefined;
93
94
  label?: undefined;
94
- message?: undefined;
95
95
  } | {
96
- deleted?: undefined;
97
96
  id?: undefined;
97
+ deleted?: undefined;
98
+ message?: undefined;
98
99
  providers?: undefined;
99
100
  count?: undefined;
100
101
  found: boolean;
101
102
  provider: import("../custom-registry.js").CustomProviderConfig;
102
103
  registered?: undefined;
103
104
  label?: undefined;
104
- message?: undefined;
105
105
  } | {
106
- deleted?: undefined;
107
106
  provider?: undefined;
107
+ deleted?: undefined;
108
+ message?: undefined;
108
109
  providers?: undefined;
109
110
  count?: undefined;
110
111
  found: boolean;
111
112
  id: string;
112
113
  registered?: undefined;
113
114
  label?: undefined;
114
- message?: undefined;
115
115
  } | {
116
116
  provider?: undefined;
117
+ found?: undefined;
118
+ message?: undefined;
117
119
  providers?: undefined;
118
120
  count?: undefined;
119
- found?: undefined;
120
121
  deleted: boolean;
121
122
  id: string;
122
123
  registered?: undefined;
123
124
  label?: undefined;
124
- message?: undefined;
125
125
  } | {
126
- deleted?: undefined;
127
126
  provider?: undefined;
127
+ deleted?: undefined;
128
+ found?: undefined;
128
129
  providers?: undefined;
129
130
  count?: undefined;
130
- found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -311,9 +311,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
311
311
  notes?: string | undefined;
312
312
  scope?: "org" | "user" | undefined;
313
313
  }, {
314
- message?: undefined;
315
314
  id?: undefined;
316
- deleted?: undefined;
315
+ found?: undefined;
317
316
  providers: {
318
317
  id: string;
319
318
  label: string;
@@ -325,45 +324,46 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
325
324
  }[];
326
325
  count: number;
327
326
  provider?: undefined;
328
- found?: undefined;
327
+ deleted?: undefined;
329
328
  registered?: undefined;
330
329
  label?: undefined;
331
- } | {
332
330
  message?: undefined;
333
- count?: undefined;
331
+ } | {
334
332
  id?: undefined;
335
- deleted?: undefined;
336
333
  providers?: undefined;
334
+ count?: undefined;
337
335
  found: boolean;
338
336
  provider: import("../custom-registry.js").CustomProviderConfig;
337
+ deleted?: undefined;
339
338
  registered?: undefined;
340
339
  label?: undefined;
341
- } | {
342
340
  message?: undefined;
343
- count?: undefined;
344
- deleted?: undefined;
341
+ } | {
345
342
  providers?: undefined;
343
+ count?: undefined;
346
344
  provider?: undefined;
347
345
  found: boolean;
348
346
  id: string;
347
+ deleted?: undefined;
349
348
  registered?: undefined;
350
349
  label?: undefined;
351
- } | {
352
350
  message?: undefined;
353
- count?: undefined;
351
+ } | {
352
+ found?: undefined;
354
353
  providers?: undefined;
354
+ count?: undefined;
355
355
  provider?: undefined;
356
- found?: undefined;
357
356
  deleted: boolean;
358
357
  id: string;
359
358
  registered?: undefined;
360
359
  label?: undefined;
360
+ message?: undefined;
361
361
  } | {
362
- count?: undefined;
363
- deleted?: undefined;
362
+ found?: undefined;
364
363
  providers?: undefined;
364
+ count?: undefined;
365
365
  provider?: undefined;
366
- found?: undefined;
366
+ deleted?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
369
369
  label: string;
@@ -1,5 +1,35 @@
1
- import { parseCustomAgentProfile, } from "./metadata.js";
1
+ import { getResourceKind, parseCustomAgentProfile, } from "./metadata.js";
2
2
  import { resourceGet, resourceGetByPath, resourceListAccessible, SHARED_OWNER, } from "./store.js";
3
+ function metadataFields(metadata) {
4
+ if (!metadata)
5
+ return {};
6
+ try {
7
+ const parsed = JSON.parse(metadata);
8
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
9
+ ? parsed
10
+ : null;
11
+ // coercion-ok: malformed resource metadata is absent, not a valid profile field
12
+ }
13
+ catch (_error) {
14
+ return null;
15
+ }
16
+ }
17
+ async function enrichAgentProfile(owner, profile, accessibleResources) {
18
+ const root = profile.path.replace(/\.md$/i, "");
19
+ const resources = accessibleResources ?? (await resourceListAccessible(owner, `${root}/`));
20
+ const workspace = resources.map((resource) => {
21
+ const metadata = metadataFields(resource.metadata) ?? {};
22
+ return {
23
+ path: resource.path,
24
+ kind: getResourceKind(resource.path),
25
+ name: typeof metadata.name === "string" ? metadata.name : undefined,
26
+ description: typeof metadata.description === "string"
27
+ ? metadata.description
28
+ : undefined,
29
+ };
30
+ });
31
+ return { ...profile, workspace: { root, resources: workspace } };
32
+ }
3
33
  export async function listAccessibleCustomAgents(owner) {
4
34
  const resources = await resourceListAccessible(owner, "agents/");
5
35
  const profiles = await Promise.all(resources
@@ -8,9 +38,14 @@ export async function listAccessibleCustomAgents(owner) {
8
38
  const full = await resourceGet(resource.id);
9
39
  if (!full)
10
40
  return null;
11
- return parseCustomAgentProfile(full.content, resource.path);
41
+ const profile = parseCustomAgentProfile(full.content, resource.path);
42
+ return profile;
43
+ }));
44
+ const validProfiles = profiles.filter((profile) => !!profile);
45
+ return Promise.all(validProfiles.map((profile) => {
46
+ const root = `${profile.path.replace(/\.md$/i, "")}/`;
47
+ return enrichAgentProfile(owner, profile, resources.filter((resource) => resource.path.startsWith(root)));
12
48
  }));
13
- return profiles.filter((profile) => !!profile);
14
49
  }
15
50
  export async function findAccessibleCustomAgent(owner, identifier) {
16
51
  const trimmed = identifier.trim();
@@ -26,13 +61,13 @@ export async function findAccessibleCustomAgent(owner, identifier) {
26
61
  if (personal) {
27
62
  const profile = parseCustomAgentProfile(personal.content, personal.path);
28
63
  if (profile)
29
- return profile;
64
+ return enrichAgentProfile(owner, profile);
30
65
  }
31
66
  const shared = await resourceGetByPath(SHARED_OWNER, path);
32
67
  if (shared) {
33
68
  const profile = parseCustomAgentProfile(shared.content, shared.path);
34
69
  if (profile)
35
- return profile;
70
+ return enrichAgentProfile(owner, profile);
36
71
  }
37
72
  }
38
73
  const lower = trimmed.toLowerCase();
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
48
48
  }>;
49
49
  /** DELETE /_agent-native/resources/:id — delete a resource */
50
50
  export declare function handleDeleteResource(event: any): Promise<{
51
- ok?: undefined;
52
51
  error: string;
52
+ ok?: undefined;
53
53
  } | {
54
54
  error?: undefined;
55
55
  ok: boolean;
@@ -11,6 +11,12 @@ export interface SkillMetadata {
11
11
  name: string;
12
12
  description?: string;
13
13
  }
14
+ export interface AgentWorkspaceResource {
15
+ path: string;
16
+ kind: ResourceKind;
17
+ name?: string;
18
+ description?: string;
19
+ }
14
20
  export interface CustomAgentProfile {
15
21
  id: string;
16
22
  path: string;
@@ -21,6 +27,10 @@ export interface CustomAgentProfile {
21
27
  color?: string;
22
28
  delegateDefault?: boolean;
23
29
  instructions: string;
30
+ workspace?: {
31
+ root: string;
32
+ resources: AgentWorkspaceResource[];
33
+ };
24
34
  }
25
35
  export interface RemoteAgentManifest {
26
36
  id: string;
@@ -81,15 +81,19 @@ export function frontmatterFieldsToObject(frontmatter) {
81
81
  return Object.fromEntries(frontmatter?.fields.map((f) => [f.key, f.value]) ?? []);
82
82
  }
83
83
  export function isSkillPath(path) {
84
- if (!path.startsWith("skills/") || !path.endsWith(".md"))
84
+ const prefix = path.startsWith("skills/")
85
+ ? "skills/"
86
+ : path.match(/^agents\/[^/]+\/skills\//)?.[0];
87
+ if (!prefix || !path.endsWith(".md"))
85
88
  return false;
86
- const relative = path.replace(/^skills\//, "");
89
+ const relative = path.slice(prefix.length);
87
90
  return (relative.endsWith("/SKILL.md") ||
88
91
  (relative.endsWith(".md") && !relative.includes("/")));
89
92
  }
90
93
  export function getSkillNameFromPath(path) {
91
94
  const relative = path
92
95
  .replace(/^\.agents\/skills\//, "")
96
+ .replace(/^agents\/[^/]+\/skills\//, "")
93
97
  .replace(/^skills\//, "");
94
98
  if (relative.endsWith("/SKILL.md")) {
95
99
  return (relative
@@ -103,7 +107,7 @@ export function isJobPath(path) {
103
107
  return path.startsWith("jobs/") && path.endsWith(".md");
104
108
  }
105
109
  export function isCustomAgentPath(path) {
106
- return path.startsWith("agents/") && path.endsWith(".md");
110
+ return /^agents\/[^/]+\.md$/.test(path);
107
111
  }
108
112
  export function isRemoteAgentPath(path) {
109
113
  return (path.endsWith(".json") &&
@@ -32,7 +32,7 @@ const schema = z.object({
32
32
  metadata: z.record(z.string(), z.unknown()).optional(),
33
33
  });
34
34
  export default defineAction({
35
- description: "Create an inline comment, annotation, or review thread for a resource.",
35
+ description: "Create an inline comment, annotation, or review thread for a resource. Body text supports inline Markdown without headings.",
36
36
  schema,
37
37
  run: async (args, ctx) => {
38
38
  const actionCtx = ctx;
@@ -21,7 +21,7 @@ const schema = z.object({
21
21
  metadata: z.record(z.string(), z.unknown()).optional(),
22
22
  });
23
23
  export default defineAction({
24
- description: "Reply to an existing review comment thread.",
24
+ description: "Reply to an existing review comment thread with inline Markdown text without headings.",
25
25
  schema,
26
26
  run: async (args, ctx) => {
27
27
  const actionCtx = ctx;
@@ -10,7 +10,7 @@ const schema = z.object({
10
10
  resolutionNote: z.string().trim().min(1).max(2_000).optional(),
11
11
  });
12
12
  export default defineAction({
13
- description: "Resolve an inline comment or review thread.",
13
+ description: "Resolve an inline comment or review thread. An optional resolution note supports inline Markdown without headings.",
14
14
  schema,
15
15
  run: async (args, ctx) => {
16
16
  const actionCtx = ctx;
@@ -34,16 +34,16 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
34
34
  /** POST /_agent-native/secrets/:key — write a secret. */
35
35
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
36
36
  error: string;
37
- ok?: undefined;
38
37
  status?: undefined;
38
+ ok?: undefined;
39
39
  } | {
40
40
  ok: boolean;
41
41
  status: string;
42
42
  error?: undefined;
43
43
  } | {
44
- ok?: undefined;
45
44
  error: string;
46
45
  removed?: undefined;
46
+ ok?: undefined;
47
47
  } | {
48
48
  ok: boolean;
49
49
  removed: boolean;
@@ -54,9 +54,9 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
54
54
  * or the current stored value without changing anything.
55
55
  */
56
56
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
57
- ok?: undefined;
58
57
  error: string;
59
58
  note?: undefined;
59
+ ok?: undefined;
60
60
  } | {
61
61
  ok: boolean;
62
62
  note?: undefined;