@agent-native/core 0.114.2 → 0.114.4

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 (132) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +30 -0
  3. package/corpus/core/package.json +2 -1
  4. package/corpus/core/src/a2a/artifact-response.ts +42 -16
  5. package/corpus/core/src/a2a/client.ts +4 -0
  6. package/corpus/core/src/a2a/handlers.ts +133 -2
  7. package/corpus/core/src/a2a/index.ts +1 -0
  8. package/corpus/core/src/a2a/types.ts +14 -0
  9. package/corpus/core/src/db/request-telemetry.ts +32 -8
  10. package/corpus/core/src/integrations/index.ts +6 -0
  11. package/corpus/core/src/integrations/pending-tasks-store.ts +89 -0
  12. package/corpus/core/src/integrations/webhook-handler.ts +17 -7
  13. package/corpus/core/src/scripts/call-agent.ts +54 -10
  14. package/corpus/core/src/server/agent-discovery.ts +22 -0
  15. package/corpus/core/src/settings/store.ts +15 -6
  16. package/corpus/core/src/shared/optional-node-builtins.ts +66 -0
  17. package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  18. package/corpus/core/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  19. package/corpus/core/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  20. package/corpus/core/src/vite/client.ts +5 -0
  21. package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +1 -1
  22. package/corpus/templates/assets/.agents/skills/feature-flags/SKILL.md +1 -1
  23. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -2
  24. package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +1 -1
  25. package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +1 -1
  26. package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  27. package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +1 -1
  28. package/corpus/templates/clips/shared/feature-flags.ts +1 -1
  29. package/corpus/templates/content/.agents/skills/content/SKILL.md +19 -5
  30. package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +1 -1
  31. package/corpus/templates/content/changelog/2026-07-17-slack-created-database-entries-now-record-slack-as-their-sub.md +6 -0
  32. package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +1 -1
  33. package/corpus/templates/design/actions/update-file.ts +10 -1
  34. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +30 -1
  35. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +14 -1
  36. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +547 -50
  37. package/corpus/templates/design/app/components/design/dnd-debug.ts +27 -0
  38. package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +19 -2
  39. package/corpus/templates/design/app/i18n-data.ts +19 -0
  40. package/corpus/templates/design/app/lib/design-save-outbox.ts +46 -2
  41. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +4 -9
  42. package/corpus/templates/design/app/pages/design-editor/history.ts +14 -1
  43. package/corpus/templates/design/changelog/2026-07-17-drawn-shapes-stay-free-positioned-when-dragged.md +6 -0
  44. package/corpus/templates/design/changelog/2026-07-17-shapes-show-a-live-outline-while-you-draw.md +6 -0
  45. package/corpus/templates/design/shared/drag-reflow.ts +375 -0
  46. package/corpus/templates/design/shared/full-app.ts +1 -1
  47. package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +1 -1
  48. package/corpus/templates/forms/.agents/skills/feature-flags/SKILL.md +1 -1
  49. package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +1 -1
  50. package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +1 -1
  51. package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +1 -1
  52. package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +1 -1
  53. package/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +1 -1
  54. package/dist/a2a/artifact-response.d.ts +5 -0
  55. package/dist/a2a/artifact-response.d.ts.map +1 -1
  56. package/dist/a2a/artifact-response.js +20 -5
  57. package/dist/a2a/artifact-response.js.map +1 -1
  58. package/dist/a2a/client.d.ts +3 -1
  59. package/dist/a2a/client.d.ts.map +1 -1
  60. package/dist/a2a/client.js +2 -0
  61. package/dist/a2a/client.js.map +1 -1
  62. package/dist/a2a/handlers.d.ts.map +1 -1
  63. package/dist/a2a/handlers.js +100 -8
  64. package/dist/a2a/handlers.js.map +1 -1
  65. package/dist/a2a/index.d.ts +1 -1
  66. package/dist/a2a/index.d.ts.map +1 -1
  67. package/dist/a2a/index.js.map +1 -1
  68. package/dist/a2a/types.d.ts +12 -0
  69. package/dist/a2a/types.d.ts.map +1 -1
  70. package/dist/a2a/types.js.map +1 -1
  71. package/dist/collab/routes.d.ts +1 -1
  72. package/dist/collab/struct-routes.d.ts +1 -1
  73. package/dist/db/request-telemetry.d.ts.map +1 -1
  74. package/dist/db/request-telemetry.js +24 -6
  75. package/dist/db/request-telemetry.js.map +1 -1
  76. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  77. package/dist/integrations/index.d.ts +1 -0
  78. package/dist/integrations/index.d.ts.map +1 -1
  79. package/dist/integrations/index.js +1 -0
  80. package/dist/integrations/index.js.map +1 -1
  81. package/dist/integrations/pending-tasks-store.d.ts +9 -0
  82. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  83. package/dist/integrations/pending-tasks-store.js +60 -0
  84. package/dist/integrations/pending-tasks-store.js.map +1 -1
  85. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  86. package/dist/integrations/webhook-handler.js +13 -7
  87. package/dist/integrations/webhook-handler.js.map +1 -1
  88. package/dist/notifications/routes.d.ts +2 -2
  89. package/dist/observability/routes.d.ts +3 -3
  90. package/dist/scripts/call-agent.d.ts.map +1 -1
  91. package/dist/scripts/call-agent.js +39 -10
  92. package/dist/scripts/call-agent.js.map +1 -1
  93. package/dist/secrets/routes.d.ts +9 -9
  94. package/dist/server/agent-discovery.d.ts +2 -0
  95. package/dist/server/agent-discovery.d.ts.map +1 -1
  96. package/dist/server/agent-discovery.js +19 -0
  97. package/dist/server/agent-discovery.js.map +1 -1
  98. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  99. package/dist/settings/store.d.ts +1 -1
  100. package/dist/settings/store.d.ts.map +1 -1
  101. package/dist/settings/store.js +14 -6
  102. package/dist/settings/store.js.map +1 -1
  103. package/dist/shared/optional-node-builtins.d.ts +23 -0
  104. package/dist/shared/optional-node-builtins.d.ts.map +1 -0
  105. package/dist/shared/optional-node-builtins.js +35 -0
  106. package/dist/shared/optional-node-builtins.js.map +1 -0
  107. package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  108. package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  109. package/dist/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  110. package/dist/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  111. package/dist/vite/client.d.ts.map +1 -1
  112. package/dist/vite/client.js +2 -0
  113. package/dist/vite/client.js.map +1 -1
  114. package/package.json +2 -1
  115. package/src/a2a/artifact-response.ts +42 -16
  116. package/src/a2a/client.ts +4 -0
  117. package/src/a2a/handlers.ts +133 -2
  118. package/src/a2a/index.ts +1 -0
  119. package/src/a2a/types.ts +14 -0
  120. package/src/db/request-telemetry.ts +32 -8
  121. package/src/integrations/index.ts +6 -0
  122. package/src/integrations/pending-tasks-store.ts +89 -0
  123. package/src/integrations/webhook-handler.ts +17 -7
  124. package/src/scripts/call-agent.ts +54 -10
  125. package/src/server/agent-discovery.ts +22 -0
  126. package/src/settings/store.ts +15 -6
  127. package/src/shared/optional-node-builtins.ts +66 -0
  128. package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  129. package/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  130. package/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  131. package/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  132. package/src/vite/client.ts +5 -0
@@ -10,6 +10,8 @@ import { invokeAgentAction } from "../a2a/invoke.js";
10
10
  import type {
11
11
  A2AApprovedAction,
12
12
  A2ACorrelationMetadata,
13
+ A2ASourceContext,
14
+ A2ASourceContextReference,
13
15
  Task,
14
16
  } from "../a2a/types.js";
15
17
  import {
@@ -100,26 +102,65 @@ function getIntegrationCallTimeoutMs(): number | undefined {
100
102
  return DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS;
101
103
  }
102
104
 
103
- function integrationSourceContextHint(): string {
105
+ interface IntegrationSourceContext {
106
+ reference: A2ASourceContextReference;
107
+ hint: A2ASourceContext;
108
+ }
109
+
110
+ function integrationSourceContext(): IntegrationSourceContext | undefined {
104
111
  const integration = getIntegrationRequestContext();
105
112
  const incoming = integration?.incoming;
106
- if (incoming?.platform !== "slack" || !incoming.sourceUrl) return "";
113
+ if (
114
+ !integration ||
115
+ incoming?.platform !== "slack" ||
116
+ !incoming.sourceUrl ||
117
+ !integration.taskId
118
+ ) {
119
+ return undefined;
120
+ }
121
+
122
+ const rawSourceUrl = incoming.sourceUrl;
123
+ if (rawSourceUrl !== rawSourceUrl.trim()) return undefined;
107
124
 
108
125
  try {
109
- const sourceUrl = new URL(incoming.sourceUrl);
126
+ const sourceUrl = new URL(rawSourceUrl);
110
127
  const isSlackHost =
111
128
  sourceUrl.hostname === "slack.com" ||
112
129
  sourceUrl.hostname.endsWith(".slack.com");
113
- if (sourceUrl.protocol !== "https:" || !isSlackHost) return "";
114
- return (
115
- `\n\n[Source Slack thread: ${sourceUrl.toString()} ` +
116
- "Preserve this exact URL as request provenance when creating an intake record or other artifact.]"
117
- );
130
+ if (
131
+ sourceUrl.protocol !== "https:" ||
132
+ !isSlackHost ||
133
+ sourceUrl.username ||
134
+ sourceUrl.password ||
135
+ sourceUrl.port
136
+ ) {
137
+ return undefined;
138
+ }
139
+ return {
140
+ reference: {
141
+ platform: "slack",
142
+ integrationTaskId: integration.taskId,
143
+ },
144
+ hint: {
145
+ platform: "slack",
146
+ sourceUrl: rawSourceUrl,
147
+ },
148
+ };
118
149
  } catch {
119
- return "";
150
+ return undefined;
120
151
  }
121
152
  }
122
153
 
154
+ function integrationSourceContextHint(
155
+ sourceContext: IntegrationSourceContext | undefined,
156
+ ): string {
157
+ if (!sourceContext) return "";
158
+ return (
159
+ `\n\n[Source Slack thread: ${sourceContext.hint.sourceUrl} ` +
160
+ "Compatibility hint only; this text is not authoritative. Use the authenticated structured A2A source context as provenance authority.]"
161
+ );
162
+ }
163
+
123
164
  function formatDownstreamLlmCredentialFailure(
124
165
  agentName: string,
125
166
  value: unknown,
@@ -253,9 +294,10 @@ export async function run(
253
294
  // in handlers.ts) still emits fully-qualified URLs. This is belt-and-
254
295
  // suspenders with the receiver hint — but it works against any current
255
296
  // deployment, no redeploy required.
297
+ const sourceContext = integrationSourceContext();
256
298
  const messageWithHint = taskId
257
299
  ? ""
258
- : `${message}${integrationSourceContextHint()}\n\n` +
300
+ : `${message}${integrationSourceContextHint(sourceContext)}\n\n` +
259
301
  `[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +
260
302
  `If you create or reference a deck/document/design/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +
261
303
  `Use only artifact IDs and URL paths returned by successful actions — never invent slugs, IDs, or hosts. ` +
@@ -432,6 +474,7 @@ export async function run(
432
474
  orgDomain: callerOrgDomain,
433
475
  orgSecret: callerOrgSecret,
434
476
  approvedActions,
477
+ ...(sourceContext ? { sourceContext: sourceContext.reference } : {}),
435
478
  contextId: context.threadId,
436
479
  correlation,
437
480
  idempotencyKey,
@@ -526,6 +569,7 @@ export async function run(
526
569
  orgDomain: domain,
527
570
  orgSecret,
528
571
  approvedActions,
572
+ ...(sourceContext ? { sourceContext: sourceContext.reference } : {}),
529
573
  contextId: context?.threadId,
530
574
  correlation,
531
575
  idempotencyKey,
@@ -689,6 +689,28 @@ async function discoverWorkspaceAgents(
689
689
  .filter((agent): agent is DiscoveredAgent => !!agent);
690
690
  }
691
691
 
692
+ /** Resolve only the Dispatch app designated by the receiver's own manifest. */
693
+ export function findWorkspaceDispatchAgent(): DiscoveredAgent | undefined {
694
+ const app = loadWorkspaceAppsManifest()?.find(
695
+ (candidate) => candidate.isDispatch === true,
696
+ );
697
+ if (!app) return undefined;
698
+
699
+ const builtin = BUILTIN_AGENTS.find((agent) => agent.id === "dispatch");
700
+ const url = workspaceAppUrl(app, builtin?.url);
701
+ if (!url) return undefined;
702
+ return {
703
+ id: app.id,
704
+ name: app.name,
705
+ description:
706
+ app.description ||
707
+ builtin?.description ||
708
+ `Workspace app mounted at ${app.path}`,
709
+ url,
710
+ color: builtin?.color || "#6B7280",
711
+ };
712
+ }
713
+
692
714
  /**
693
715
  * Like `getBuiltinAgents`, but always returns the production URL — never the
694
716
  * env-resolved devUrl. Used by the resource seeder so that a one-time seed
@@ -1,9 +1,10 @@
1
- import { EventEmitter } from "events";
1
+ import type { EventEmitter } from "node:events";
2
2
 
3
3
  import { getDbExec, isPostgres, intType } from "../db/client.js";
4
4
  import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
5
5
  import { widenIntColumnsToBigInt } from "../db/widen-columns.js";
6
6
  import { getRequestContext } from "../server/request-context.js";
7
+ import { createEventEmitter } from "../shared/optional-node-builtins.js";
7
8
 
8
9
  let _initPromise: Promise<void> | undefined;
9
10
 
@@ -29,12 +30,20 @@ function requestSettingsCache(): Map<string, string | null> | null {
29
30
  return cache;
30
31
  }
31
32
 
32
- const _emitter = new EventEmitter();
33
+ // Created lazily so this module can be evaluated in the browser dev graph
34
+ // without a top-level `new EventEmitter()` tripping Vite's externalized
35
+ // `node:events` stub. The emitter drives server-side SSE fan-out only.
36
+ let _emitter: EventEmitter | undefined;
33
37
 
34
- export function getSettingsEmitter(): EventEmitter {
38
+ function settingsEmitter(): EventEmitter {
39
+ if (!_emitter) _emitter = createEventEmitter();
35
40
  return _emitter;
36
41
  }
37
42
 
43
+ export function getSettingsEmitter(): EventEmitter {
44
+ return settingsEmitter();
45
+ }
46
+
38
47
  function settingsTable(): string {
39
48
  return isPostgres() ? "public.settings" : "settings";
40
49
  }
@@ -174,7 +183,7 @@ export async function mutateSetting(
174
183
  });
175
184
  if (result.rowsAffected === 0) continue;
176
185
  requestSettingsCache()?.set(key, nextRaw);
177
- _emitter.emit("settings", {
186
+ settingsEmitter().emit("settings", {
178
187
  source: "settings",
179
188
  type: "change",
180
189
  key,
@@ -200,7 +209,7 @@ export async function putSetting(
200
209
  args: [key, JSON.stringify(value), Date.now()],
201
210
  });
202
211
  requestSettingsCache()?.set(key, JSON.stringify(value));
203
- _emitter.emit("settings", {
212
+ settingsEmitter().emit("settings", {
204
213
  source: "settings",
205
214
  type: "change",
206
215
  key,
@@ -221,7 +230,7 @@ export async function deleteSetting(
221
230
  });
222
231
  requestSettingsCache()?.set(key, null);
223
232
  if (result.rowsAffected > 0) {
224
- _emitter.emit("settings", {
233
+ settingsEmitter().emit("settings", {
225
234
  source: "settings",
226
235
  type: "delete",
227
236
  key,
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Browser-safe accessors for optional Node builtins.
3
+ *
4
+ * `node:async_hooks` and `node:events` are server-only, but the modules that
5
+ * use them (db telemetry, settings/resource emitters) can land in the browser
6
+ * dev graph before tree-shaking runs. A static `import { X } from "node:..."`
7
+ * resolves to Vite's externalized stub and throws the instant the value is
8
+ * touched at module load. We read the builtin through `process.getBuiltinModule`
9
+ * instead — the same guard `server/request-context.ts` uses — so there is no
10
+ * static `node:` import to evaluate in the browser, and callers fall back to a
11
+ * no-op on non-Node runtimes (browser, or Node without getBuiltinModule).
12
+ */
13
+ import type { AsyncLocalStorage } from "node:async_hooks";
14
+ import type { EventEmitter } from "node:events";
15
+
16
+ type BuiltinProcess = {
17
+ versions?: { node?: string };
18
+ getBuiltinModule?: (name: string) => unknown;
19
+ };
20
+
21
+ function nodeBuiltin<T>(name: string): T | undefined {
22
+ const proc =
23
+ typeof process === "undefined" ? undefined : (process as BuiltinProcess);
24
+ if (
25
+ typeof window !== "undefined" ||
26
+ !proc ||
27
+ !proc.versions?.node ||
28
+ typeof proc.getBuiltinModule !== "function"
29
+ ) {
30
+ return undefined;
31
+ }
32
+ return proc.getBuiltinModule(name) as T | undefined;
33
+ }
34
+
35
+ export type AsyncLocalStorageCtor = new <T>() => AsyncLocalStorage<T>;
36
+
37
+ export function getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined {
38
+ return nodeBuiltin<{ AsyncLocalStorage: AsyncLocalStorageCtor }>(
39
+ "node:async_hooks",
40
+ )?.AsyncLocalStorage;
41
+ }
42
+
43
+ type EventEmitterCtor = new () => EventEmitter;
44
+
45
+ /**
46
+ * Returns a real Node EventEmitter on Node, or a no-op emitter elsewhere. The
47
+ * emitters that use this drive server-side SSE fan-out; nothing subscribes in
48
+ * the browser, so the no-op fallback is inert rather than wrong.
49
+ */
50
+ export function createEventEmitter(): EventEmitter {
51
+ const Ctor = nodeBuiltin<{ EventEmitter: EventEmitterCtor }>(
52
+ "node:events",
53
+ )?.EventEmitter;
54
+ if (Ctor) return new Ctor();
55
+ const noop = {
56
+ on: () => noop,
57
+ off: () => noop,
58
+ once: () => noop,
59
+ addListener: () => noop,
60
+ removeListener: () => noop,
61
+ removeAllListeners: () => noop,
62
+ setMaxListeners: () => noop,
63
+ emit: () => false,
64
+ };
65
+ return noop as unknown as EventEmitter;
66
+ }
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -805,6 +805,7 @@ const CORE_CLIENT_SUBPATHS = [
805
805
  "@agent-native/core/client/components/RemoteSelectionRings",
806
806
  "@agent-native/core/client/visual-style-controls",
807
807
  "@agent-native/core/client/feature-flags",
808
+ "@agent-native/core/feature-flags/registry",
808
809
  "@agent-native/core/client/hooks",
809
810
  "@agent-native/core/client/host",
810
811
  "@agent-native/core/client/i18n",
@@ -1158,6 +1159,10 @@ function getCoreSourceAliases(
1158
1159
  coreSrc,
1159
1160
  "client/feature-flags/index.ts",
1160
1161
  ),
1162
+ "@agent-native/core/feature-flags/registry": path.join(
1163
+ coreSrc,
1164
+ "feature-flags/registry.ts",
1165
+ ),
1161
1166
  "@agent-native/core/client/hooks": path.join(
1162
1167
  coreSrc,
1163
1168
  "client/hooks/index.ts",