@agent-native/core 0.164.3 → 0.164.11

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 (234) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +36 -47
  3. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +3 -0
  4. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +18 -1
  5. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +256 -38
  6. package/corpus/templates/calendar/app/hooks/use-google-auth.ts +43 -3
  7. package/corpus/templates/calendar/app/i18n-data.ts +120 -0
  8. package/corpus/templates/calendar/app/lib/event-form-utils.ts +113 -0
  9. package/corpus/templates/calendar/server/handlers/google-auth.ts +119 -3
  10. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  11. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  12. package/corpus/templates/calendar/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  13. package/corpus/templates/calendar/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  14. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +1 -1
  15. package/corpus/templates/clips/app/components/player/video-player.tsx +12 -0
  16. package/corpus/templates/clips/app/routes/_app.dictate.tsx +18 -4
  17. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +114 -20
  18. package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -78
  19. package/corpus/templates/clips/changelog/2026-08-19-clips-nightly-builds-are-available-for-trying-the-latest-upd.md +6 -0
  20. package/corpus/templates/clips/changelog/2026-08-19-social-preview-video-frames.md +6 -0
  21. package/corpus/templates/clips/desktop/README.md +19 -4
  22. package/corpus/templates/clips/desktop/src/app.tsx +78 -16
  23. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -2
  24. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -0
  25. package/corpus/templates/clips/server/lib/slack-unfurls.ts +7 -13
  26. package/corpus/templates/clips/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  27. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +41 -3
  28. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  29. package/corpus/templates/clips/server/routes/_agent-native/google/callback.get.ts +22 -1
  30. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +41 -22
  31. package/corpus/templates/clips/shared/share-meta.ts +67 -3
  32. package/corpus/templates/content/actions/list-content-databases.ts +95 -1
  33. package/corpus/templates/content/changelog/2026-08-11-content-mutations-delegated-from-verified-slack-dms-now-use-.md +6 -0
  34. package/corpus/templates/content/shared/api.ts +11 -0
  35. package/corpus/templates/factory/AGENTS.md +1 -1
  36. package/corpus/templates/factory/actions/list-factory-automations.ts +4 -0
  37. package/corpus/templates/factory/actions/start-builder-for-item.ts +19 -17
  38. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +100 -36
  39. package/corpus/templates/factory/app/i18n/en-US.ts +4 -0
  40. package/corpus/templates/factory/app/routes/factory.tsx +209 -46
  41. package/corpus/templates/factory/server/connectors/slack.ts +44 -2
  42. package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -7
  43. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +13 -0
  44. package/corpus/templates/factory/server/triage/slack-client.ts +5 -0
  45. package/corpus/templates/factory/server/triage/slack-poller.ts +72 -4
  46. package/corpus/templates/mail/actions/view-screen.ts +1 -1
  47. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -18
  48. package/corpus/templates/mail/server/handlers/google-auth.ts +125 -24
  49. package/corpus/templates/mail/server/lib/gmail-query.ts +5 -2
  50. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  51. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  52. package/corpus/templates/mail/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  53. package/corpus/templates/mail/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  54. package/corpus/templates/plan/app/pages/PlansPage.tsx +0 -12
  55. package/corpus/templates/plan/changelog/2026-08-19-plan-prompts-now-guide-you-to-connect-ai-before-sending-and-.md +6 -0
  56. package/corpus/templates/slides/actions/approve-deck-access-request.ts +234 -0
  57. package/corpus/templates/slides/actions/get-deck-access-status.ts +35 -2
  58. package/corpus/templates/slides/actions/request-deck-access.ts +263 -64
  59. package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +196 -0
  60. package/corpus/templates/slides/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
  61. package/corpus/templates/slides/app/hooks/use-deck-access.ts +7 -4
  62. package/corpus/templates/slides/app/i18n/en-US.ts +29 -6
  63. package/corpus/templates/slides/app/pages/DeckEditor.tsx +147 -169
  64. package/corpus/templates/slides/app/routes/access-request.approve.tsx +250 -0
  65. package/corpus/templates/slides/server/db/schema.ts +8 -0
  66. package/corpus/templates/slides/server/lib/access-request-email.ts +36 -0
  67. package/corpus/templates/slides/server/lib/emails.ts +26 -0
  68. package/corpus/templates/slides/server/plugins/agent-chat.ts +7 -0
  69. package/corpus/templates/slides/server/plugins/db.ts +50 -0
  70. package/corpus/templates/slides/shared/deck-access.ts +31 -0
  71. package/dist/a2a/artifact-response.d.ts +50 -0
  72. package/dist/a2a/artifact-response.js +266 -39
  73. package/dist/a2a/index.d.ts +2 -0
  74. package/dist/a2a/index.js +1 -0
  75. package/dist/a2a/task-store.d.ts +1 -0
  76. package/dist/a2a/task-store.js +1 -1
  77. package/dist/agent/observational-memory/store.d.ts +1 -0
  78. package/dist/agent/observational-memory/store.js +1 -1
  79. package/dist/agent/run-store.d.ts +1 -0
  80. package/dist/agent/run-store.js +1 -1
  81. package/dist/agent/tool-approval-store.d.ts +1 -0
  82. package/dist/agent/tool-approval-store.js +1 -1
  83. package/dist/application-state/store.d.ts +1 -0
  84. package/dist/application-state/store.js +1 -1
  85. package/dist/browser-sessions/store.d.ts +1 -0
  86. package/dist/browser-sessions/store.js +1 -1
  87. package/dist/checkpoints/store.d.ts +1 -0
  88. package/dist/checkpoints/store.js +1 -1
  89. package/dist/cli/code-agent-schedules.d.ts +11 -0
  90. package/dist/cli/code-agent-schedules.js +44 -5
  91. package/dist/client/AgentPanel.d.ts +5 -1
  92. package/dist/client/AgentPanel.js +2 -2
  93. package/dist/client/AssistantChat.d.ts +5 -1
  94. package/dist/client/AssistantChat.js +40 -6
  95. package/dist/client/EnvironmentBadge.d.ts +7 -13
  96. package/dist/client/EnvironmentBadge.js +43 -92
  97. package/dist/client/agent-chat/index.d.ts +1 -0
  98. package/dist/client/agent-chat/index.js +1 -0
  99. package/dist/client/agent-chat-adapter.js +76 -50
  100. package/dist/client/app-providers.js +4 -4
  101. package/dist/client/chat/message-components.d.ts +4 -0
  102. package/dist/client/chat/message-components.js +28 -1
  103. package/dist/client/chat/run-recovery.js +26 -0
  104. package/dist/client/chat-first/apps-rail.d.ts +1 -0
  105. package/dist/client/chat-first/apps-rail.js +28 -2
  106. package/dist/client/sse-event-processor.js +13 -8
  107. package/dist/client/use-active-agent-chat-run.d.ts +2 -0
  108. package/dist/client/use-active-agent-chat-run.js +22 -0
  109. package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
  110. package/dist/coding-tools/sandbox/executions-store.js +1 -1
  111. package/dist/collab/awareness-store.d.ts +1 -0
  112. package/dist/collab/awareness-store.js +1 -1
  113. package/dist/collab/routes.d.ts +1 -1
  114. package/dist/collab/storage.d.ts +1 -0
  115. package/dist/collab/storage.js +1 -1
  116. package/dist/db/client.js +3 -3
  117. package/dist/db/ddl-guard.js +8 -0
  118. package/dist/db/migration-runtime.d.ts +23 -0
  119. package/dist/db/migration-runtime.js +41 -0
  120. package/dist/db/migrations.d.ts +1 -2
  121. package/dist/db/migrations.js +2 -24
  122. package/dist/email-catalog/log.d.ts +1 -0
  123. package/dist/email-catalog/log.js +1 -1
  124. package/dist/guards/index.d.ts +1 -0
  125. package/dist/guards/index.js +1 -0
  126. package/dist/guards/release-schema-complete.d.ts +22 -0
  127. package/dist/guards/release-schema-complete.js +144 -0
  128. package/dist/integrations/a2a-continuations-store.d.ts +1 -0
  129. package/dist/integrations/a2a-continuations-store.js +1 -1
  130. package/dist/integrations/adapters/slack.js +58 -7
  131. package/dist/integrations/awaiting-input-store.d.ts +1 -0
  132. package/dist/integrations/awaiting-input-store.js +1 -1
  133. package/dist/integrations/config-store.d.ts +1 -0
  134. package/dist/integrations/config-store.js +1 -1
  135. package/dist/integrations/controls-store.d.ts +1 -0
  136. package/dist/integrations/controls-store.js +1 -1
  137. package/dist/integrations/identity-links-store.d.ts +1 -0
  138. package/dist/integrations/identity-links-store.js +1 -1
  139. package/dist/integrations/installations-store.d.ts +1 -0
  140. package/dist/integrations/installations-store.js +1 -1
  141. package/dist/integrations/remote-commands-store.d.ts +1 -0
  142. package/dist/integrations/remote-commands-store.js +1 -1
  143. package/dist/integrations/remote-devices-store.d.ts +1 -0
  144. package/dist/integrations/remote-devices-store.js +1 -1
  145. package/dist/integrations/remote-push-store.d.ts +1 -0
  146. package/dist/integrations/remote-push-store.js +1 -1
  147. package/dist/integrations/remote-run-events-store.d.ts +1 -0
  148. package/dist/integrations/remote-run-events-store.js +1 -1
  149. package/dist/integrations/scope-store.d.ts +1 -0
  150. package/dist/integrations/scope-store.js +1 -1
  151. package/dist/integrations/thread-mapping-store.d.ts +1 -0
  152. package/dist/integrations/thread-mapping-store.js +1 -1
  153. package/dist/integrations/usage-budget-store.d.ts +1 -0
  154. package/dist/integrations/usage-budget-store.js +1 -1
  155. package/dist/jobs/background-automation-runner.js +111 -9
  156. package/dist/jobs/run-history.d.ts +1 -0
  157. package/dist/jobs/run-history.js +1 -1
  158. package/dist/jobs/scheduler-health.d.ts +1 -0
  159. package/dist/jobs/scheduler-health.js +1 -1
  160. package/dist/mcp/approval-store.d.ts +1 -0
  161. package/dist/mcp/approval-store.js +1 -1
  162. package/dist/mcp/connect-store.d.ts +1 -0
  163. package/dist/mcp/connect-store.js +1 -1
  164. package/dist/mcp/oauth-store.d.ts +1 -0
  165. package/dist/mcp/oauth-store.js +1 -1
  166. package/dist/notifications/routes.d.ts +3 -3
  167. package/dist/notifications/store.d.ts +1 -0
  168. package/dist/notifications/store.js +1 -1
  169. package/dist/oauth-tokens/store.d.ts +1 -0
  170. package/dist/oauth-tokens/store.js +1 -1
  171. package/dist/observability/routes.d.ts +3 -3
  172. package/dist/progress/routes.d.ts +1 -1
  173. package/dist/progress/store.d.ts +1 -0
  174. package/dist/progress/store.js +1 -1
  175. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  176. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  177. package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
  178. package/dist/provider-api/corpus-jobs-store.js +1 -1
  179. package/dist/provider-api/custom-registry.d.ts +1 -0
  180. package/dist/provider-api/custom-registry.js +1 -1
  181. package/dist/provider-api/quota-governor.d.ts +1 -0
  182. package/dist/provider-api/quota-governor.js +1 -1
  183. package/dist/provider-api/staged-datasets-store.d.ts +1 -0
  184. package/dist/provider-api/staged-datasets-store.js +1 -1
  185. package/dist/resources/handlers.d.ts +3 -3
  186. package/dist/resources/store.d.ts +1 -0
  187. package/dist/resources/store.js +1 -1
  188. package/dist/scripts/dev/index.js +15 -1
  189. package/dist/search/index.js +3 -0
  190. package/dist/secrets/storage.d.ts +1 -0
  191. package/dist/secrets/storage.js +1 -1
  192. package/dist/server/agent-chat/action-filters-a2a.d.ts +2 -1
  193. package/dist/server/agent-chat/action-filters-a2a.js +10 -2
  194. package/dist/server/agent-chat-plugin.js +71 -20
  195. package/dist/server/agent-teams-run-queue.d.ts +1 -0
  196. package/dist/server/agent-teams-run-queue.js +1 -1
  197. package/dist/server/auth-marketing.js +3 -1
  198. package/dist/server/auth.d.ts +18 -1
  199. package/dist/server/auth.js +370 -154
  200. package/dist/server/embed-session.d.ts +1 -0
  201. package/dist/server/embed-session.js +1 -1
  202. package/dist/server/google-auth-plugin.js +3 -1
  203. package/dist/server/google-oauth.d.ts +10 -0
  204. package/dist/server/google-oauth.js +25 -1
  205. package/dist/server/identity-sso-store.d.ts +1 -0
  206. package/dist/server/identity-sso-store.js +1 -1
  207. package/dist/server/index.d.ts +1 -1
  208. package/dist/server/index.js +1 -1
  209. package/dist/server/onboarding-html.js +200 -31
  210. package/dist/server/poll.d.ts +2 -0
  211. package/dist/server/poll.js +19 -1
  212. package/dist/server/realtime-token.d.ts +1 -1
  213. package/dist/server/release-migrations.js +5 -0
  214. package/dist/server/release-schema.d.ts +46 -0
  215. package/dist/server/release-schema.js +307 -0
  216. package/dist/settings/store.d.ts +1 -0
  217. package/dist/settings/store.js +1 -1
  218. package/dist/shared/environment-lanes.d.ts +28 -0
  219. package/dist/shared/environment-lanes.js +61 -0
  220. package/dist/sharing/actions/share-resource.js +22 -2
  221. package/dist/styles/agent-native.css +17 -15
  222. package/dist/triggers/routes.d.ts +11 -0
  223. package/dist/triggers/routes.js +10 -0
  224. package/dist/usage/alerts-store.d.ts +1 -0
  225. package/dist/usage/alerts-store.js +1 -1
  226. package/dist/usage/store.d.ts +1 -0
  227. package/dist/usage/store.js +1 -1
  228. package/docs/content/drop-in-agent.mdx +4 -4
  229. package/docs/content/faq.mdx +15 -15
  230. package/docs/content/getting-started.mdx +173 -41
  231. package/docs/content/key-concepts.mdx +10 -10
  232. package/docs/content/using-your-agent.mdx +2 -2
  233. package/docs/content/what-is-agent-native.mdx +79 -228
  234. package/package.json +2 -2
@@ -1,9 +1,19 @@
1
1
  import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { readDeployCredentialEnv } from "../server/credential-provider.js";
3
+ function a2aSecret() {
4
+ return readDeployCredentialEnv("A2A_SECRET");
5
+ }
6
+ function a2aSecrets() {
7
+ const secret = a2aSecret();
8
+ return secret ? [secret] : [];
9
+ }
2
10
  const ARTIFACT_IDENTITY_WRITE_TOOLS = new Set([
3
11
  "save-monitor",
4
12
  "create-form",
5
13
  "submit-content-database-form",
6
14
  "add-database-item",
15
+ "upsert-database-item-by-key",
16
+ "mutate-content-database-block",
7
17
  "create-document",
8
18
  "update-document",
9
19
  "set-document-property",
@@ -44,50 +54,79 @@ const ARTIFACT_RESOURCE_TYPES = new Set([
44
54
  "monitor",
45
55
  "form",
46
56
  ]);
47
- function persistedArtifactIdentitiesFromMarker(result, secrets = process.env.A2A_SECRET
48
- ? [process.env.A2A_SECRET]
49
- : []) {
57
+ function persistedArtifactLedgerFromMarker(result, secrets = a2aSecrets(), expectedDelegatedTaskId) {
50
58
  if (secrets.length === 0)
51
- return [];
52
- const match = result.match(/<!--\s*agent-native:persisted-artifacts=([A-Za-z0-9_-]+)\.([a-f0-9]{64})\s*-->/);
53
- if (!match)
54
- return [];
55
- try {
56
- const payload = match[1];
57
- const supplied = Buffer.from(match[2], "hex");
58
- const verified = secrets.some((secret) => {
59
- const expected = createHmac("sha256", secret).update(payload).digest();
60
- return (supplied.length === expected.length &&
61
- timingSafeEqual(supplied, expected));
62
- });
63
- if (!verified) {
64
- return [];
59
+ return null;
60
+ const matches = result.matchAll(/<!--\s*agent-native:persisted-artifacts=([A-Za-z0-9_-]+)\.([a-f0-9]{64})\s*-->/g);
61
+ for (const match of matches) {
62
+ try {
63
+ const payload = match[1];
64
+ const supplied = Buffer.from(match[2], "hex");
65
+ const verified = secrets.some((secret) => {
66
+ const expected = createHmac("sha256", secret).update(payload).digest();
67
+ return (supplied.length === expected.length &&
68
+ timingSafeEqual(supplied, expected));
69
+ });
70
+ if (!verified)
71
+ continue;
72
+ const parsed = JSON.parse(Buffer.from(payload, "base64url").toString());
73
+ if (Array.isArray(parsed)) {
74
+ return { version: 1, identities: parsed, mutationReceipts: [] };
75
+ }
76
+ const ledger = asRecord(parsed);
77
+ if (!ledger || ledger.version !== 1)
78
+ continue;
79
+ const parsedLedger = {
80
+ version: 1,
81
+ identities: Array.isArray(ledger.identities) ? ledger.identities : [],
82
+ mutationReceipts: Array.isArray(ledger.mutationReceipts)
83
+ ? ledger.mutationReceipts
84
+ : [],
85
+ ...(typeof ledger.delegatedTaskId === "string"
86
+ ? { delegatedTaskId: ledger.delegatedTaskId }
87
+ : {}),
88
+ };
89
+ if (expectedDelegatedTaskId &&
90
+ parsedLedger.delegatedTaskId !== expectedDelegatedTaskId) {
91
+ continue;
92
+ }
93
+ return parsedLedger;
94
+ }
95
+ catch {
96
+ // coercion-ok: malformed signed-marker payloads are untrusted absence, never a successful receipt ledger
97
+ continue;
65
98
  }
66
- const parsed = JSON.parse(Buffer.from(payload, "base64url").toString());
67
- if (!Array.isArray(parsed))
68
- return [];
69
- return parsed
70
- .slice(0, 12)
71
- .filter((identity) => {
72
- const item = asRecord(identity);
73
- return (!!item &&
74
- ARTIFACT_RESOURCE_TYPES.has(item.resourceType) &&
75
- typeof item.id === "string" &&
76
- typeof item.sourceAction === "string");
77
- });
78
- }
79
- catch {
80
- return [];
81
99
  }
100
+ return null;
82
101
  }
83
- function withPersistedArtifactMarker(text, toolResults, secret = process.env.A2A_SECRET) {
84
- const verificationSecrets = [secret, process.env.A2A_SECRET].filter((value, index, values) => !!value && values.indexOf(value) === index);
102
+ function persistedArtifactIdentitiesFromMarker(result, secrets = a2aSecrets()) {
103
+ return (persistedArtifactLedgerFromMarker(result, secrets)?.identities ?? [])
104
+ .slice(0, 12)
105
+ .filter((identity) => {
106
+ const item = asRecord(identity);
107
+ return (!!item &&
108
+ ARTIFACT_RESOURCE_TYPES.has(item.resourceType) &&
109
+ typeof item.id === "string" &&
110
+ typeof item.sourceAction === "string");
111
+ });
112
+ }
113
+ function withPersistedArtifactMarker(text, toolResults, secret = a2aSecret(), delegatedTaskId) {
114
+ const verificationSecrets = [secret, a2aSecret()].filter((value, index, values) => !!value && values.indexOf(value) === index);
85
115
  const identities = extractA2AArtifactIdentities(toolResults, {
86
116
  persistedArtifactSecrets: verificationSecrets,
87
117
  }).slice(0, 12);
88
- if (identities.length === 0 || !secret)
118
+ const mutationReceipts = extractA2APersistedMutationReceipts(toolResults, {
119
+ persistedArtifactSecrets: secret ? [secret] : [],
120
+ expectedDelegatedTaskId: delegatedTaskId,
121
+ }).slice(0, 12);
122
+ if ((identities.length === 0 && mutationReceipts.length === 0) || !secret)
89
123
  return text;
90
- const payload = Buffer.from(JSON.stringify(identities)).toString("base64url");
124
+ const payload = Buffer.from(JSON.stringify({
125
+ version: 1,
126
+ identities,
127
+ mutationReceipts,
128
+ ...(delegatedTaskId ? { delegatedTaskId } : {}),
129
+ })).toString("base64url");
91
130
  const signature = createHmac("sha256", secret).update(payload).digest("hex");
92
131
  const marker = `<!-- ${PERSISTED_ARTIFACT_MARKER}${payload}.${signature} -->`;
93
132
  return text ? `${text}\n\n${marker}` : marker;
@@ -474,6 +513,22 @@ function collectArtifacts(results) {
474
513
  documents.set(artifact.id, artifact);
475
514
  continue;
476
515
  }
516
+ if (toolResult.tool === "upsert-database-item-by-key" ||
517
+ toolResult.tool === "mutate-content-database-block") {
518
+ const receipt = asRecord(parsed.receipt);
519
+ const receiptRow = asRecord(receipt?.row);
520
+ const receiptTarget = asRecord(receipt?.target);
521
+ const rowLink = asRecord(receipt?.rowLink);
522
+ const rowDocumentId = stringValue(receiptRow?.documentId) ??
523
+ stringValue(receiptTarget?.rowDocumentId);
524
+ if (rowDocumentId) {
525
+ documents.set(rowDocumentId, {
526
+ id: rowDocumentId,
527
+ url: stringValue(receiptRow?.urlPath) ?? stringValue(rowLink?.urlPath),
528
+ });
529
+ }
530
+ continue;
531
+ }
477
532
  if (toolResult.tool === "create-document" ||
478
533
  toolResult.tool === "update-document") {
479
534
  if (parsed.conflict === true)
@@ -772,6 +827,175 @@ export function extractA2AArtifactIdentities(results, options = {}) {
772
827
  }
773
828
  return [...identities.values()];
774
829
  }
830
+ function boundedStrings(value) {
831
+ if (!Array.isArray(value))
832
+ return undefined;
833
+ return value
834
+ .map(stringValue)
835
+ .filter((item) => !!item)
836
+ .slice(0, 50);
837
+ }
838
+ function parsePersistedMutationReceipt(value, sourceAction) {
839
+ const receipt = asRecord(value);
840
+ const target = asRecord(receipt?.target);
841
+ const authorityScope = asRecord(target?.authorityScope);
842
+ const row = asRecord(receipt?.row);
843
+ const rowLink = asRecord(receipt?.rowLink);
844
+ const idempotency = asRecord(receipt?.idempotency);
845
+ const revisions = asRecord(receipt?.revisions);
846
+ const rowRevisions = asRecord(revisions?.row);
847
+ const fieldRevisions = asRecord(revisions?.field);
848
+ const affected = asRecord(receipt?.affected);
849
+ const readback = asRecord(receipt?.readback);
850
+ const authorityScopeKind = stringValue(authorityScope?.kind) ??
851
+ stringValue(target?.authorityScopeKind);
852
+ const idempotencyResult = stringValue(idempotency?.result);
853
+ const rowDocumentId = stringValue(row?.documentId) ?? stringValue(target?.rowDocumentId);
854
+ const urlPath = stringValue(row?.urlPath) ?? stringValue(rowLink?.urlPath);
855
+ const receiptId = stringValue(receipt?.receiptId);
856
+ const operation = stringValue(receipt?.operation);
857
+ const outcome = stringValue(receipt?.outcome);
858
+ const authorityScopeId = stringValue(authorityScope?.id) ?? stringValue(target?.authorityScopeId);
859
+ const spaceId = stringValue(target?.spaceId);
860
+ const databaseId = stringValue(target?.databaseId);
861
+ const databaseDocumentId = stringValue(target?.databaseDocumentId);
862
+ const idempotencyKey = stringValue(idempotency?.key);
863
+ const payloadDigest = stringValue(idempotency?.payloadDigest);
864
+ if (!receipt ||
865
+ !target ||
866
+ (authorityScopeKind !== "personal" &&
867
+ authorityScopeKind !== "organization") ||
868
+ (idempotencyResult !== "applied" && idempotencyResult !== "replayed") ||
869
+ (readback?.verified !== true && receipt.readbackVerified !== true) ||
870
+ !receiptId ||
871
+ !operation ||
872
+ !outcome ||
873
+ !authorityScopeId ||
874
+ !spaceId ||
875
+ !databaseId ||
876
+ !databaseDocumentId ||
877
+ !idempotencyKey ||
878
+ !payloadDigest ||
879
+ !rowDocumentId ||
880
+ !urlPath) {
881
+ return null;
882
+ }
883
+ const propertyIds = boundedStrings(affected?.propertyIds);
884
+ const blockIds = boundedStrings(affected?.blockIds);
885
+ const deletedBlockIds = boundedStrings(affected?.deletedBlockIds);
886
+ const order = boundedStrings(affected?.order);
887
+ const compactAffected = {
888
+ ...(typeof affected?.title === "boolean" ? { title: affected.title } : {}),
889
+ ...(propertyIds ? { propertyIds } : {}),
890
+ ...(blockIds ? { blockIds } : {}),
891
+ ...(deletedBlockIds ? { deletedBlockIds } : {}),
892
+ ...(order ? { order } : {}),
893
+ };
894
+ const itemId = stringValue(row?.itemId) ?? stringValue(target.itemId);
895
+ const targetItemId = stringValue(target.itemId);
896
+ const targetRowDocumentId = stringValue(target.rowDocumentId);
897
+ const targetPropertyId = stringValue(target.propertyId);
898
+ const after = stringValue(revisions?.after);
899
+ const rowBefore = stringValue(rowRevisions?.before) ?? stringValue(revisions?.rowBefore);
900
+ const rowAfter = stringValue(rowRevisions?.after) ?? stringValue(revisions?.rowAfter);
901
+ return {
902
+ receiptId,
903
+ sourceAction,
904
+ operation,
905
+ outcome,
906
+ target: {
907
+ authorityScopeKind,
908
+ authorityScopeId,
909
+ spaceId,
910
+ databaseId,
911
+ databaseDocumentId,
912
+ ...(targetItemId ? { itemId: targetItemId } : {}),
913
+ ...(targetRowDocumentId ? { rowDocumentId: targetRowDocumentId } : {}),
914
+ ...(targetPropertyId ? { propertyId: targetPropertyId } : {}),
915
+ },
916
+ row: {
917
+ ...(itemId ? { itemId } : {}),
918
+ documentId: rowDocumentId,
919
+ urlPath,
920
+ },
921
+ idempotency: {
922
+ key: idempotencyKey,
923
+ result: idempotencyResult,
924
+ payloadDigest,
925
+ },
926
+ revisions: {
927
+ ...(revisions?.before === null || typeof revisions?.before === "string"
928
+ ? { before: revisions.before }
929
+ : {}),
930
+ ...(after ? { after } : {}),
931
+ ...(rowBefore ? { rowBefore } : {}),
932
+ ...(rowAfter ? { rowAfter } : {}),
933
+ ...(typeof (fieldRevisions?.before ?? revisions?.fieldBefore) === "number"
934
+ ? {
935
+ fieldBefore: (fieldRevisions?.before ??
936
+ revisions?.fieldBefore),
937
+ }
938
+ : {}),
939
+ ...(typeof (fieldRevisions?.after ?? revisions?.fieldAfter) === "number"
940
+ ? {
941
+ fieldAfter: (fieldRevisions?.after ??
942
+ revisions?.fieldAfter),
943
+ }
944
+ : {}),
945
+ },
946
+ ...(Object.keys(compactAffected).length > 0
947
+ ? { affected: compactAffected }
948
+ : {}),
949
+ readbackVerified: true,
950
+ };
951
+ }
952
+ /**
953
+ * Extract bounded, read-back-verified mutation receipts. Nested agent results
954
+ * are accepted only through the signed persisted ledger.
955
+ */
956
+ export function extractA2APersistedMutationReceipts(results, options = {}) {
957
+ const receipts = new Map();
958
+ for (const result of results) {
959
+ if (result.isError === true || result.completedSideEffect === false)
960
+ continue;
961
+ if (result.tool === "call-agent") {
962
+ const nested = persistedArtifactLedgerFromMarker(result.result, options.persistedArtifactSecrets, options.expectedDelegatedTaskId);
963
+ for (const receipt of nested?.mutationReceipts ?? []) {
964
+ const parsed = parsePersistedMutationReceipt(receipt, "call-agent");
965
+ if (parsed)
966
+ receipts.set(parsed.receiptId, parsed);
967
+ }
968
+ continue;
969
+ }
970
+ if (result.tool !== "upsert-database-item-by-key" &&
971
+ result.tool !== "mutate-content-database-block") {
972
+ continue;
973
+ }
974
+ const parsedResult = parseToolResultJson(result.result);
975
+ const receipt = parsePersistedMutationReceipt(parsedResult?.receipt, result.tool);
976
+ if (receipt)
977
+ receipts.set(receipt.receiptId, receipt);
978
+ }
979
+ return [...receipts.values()].slice(0, 12);
980
+ }
981
+ export function appendA2APersistedMutationReceipts(text, toolResults, options = {}) {
982
+ const receiptSecret = options.persistedArtifactSecret ?? a2aSecret();
983
+ const receipts = extractA2APersistedMutationReceipts(toolResults, {
984
+ persistedArtifactSecrets: receiptSecret ? [receiptSecret] : [],
985
+ expectedDelegatedTaskId: options.delegatedTaskId,
986
+ }).filter((receipt) => !text.includes(receipt.receiptId));
987
+ if (receipts.length === 0)
988
+ return text;
989
+ const lines = receipts.map((receipt) => {
990
+ const url = artifactUrl(options.baseUrl, receipt.row.urlPath);
991
+ const item = receipt.row.itemId ? `; item ID: ${receipt.row.itemId}` : "";
992
+ return (`- ${receipt.receiptId}: ${receipt.outcome} via ${receipt.sourceAction}; ` +
993
+ `row ${url} (document ID: ${receipt.row.documentId}${item}); ` +
994
+ `idempotency: ${receipt.idempotency.result}`);
995
+ });
996
+ const section = ["Mutation receipts:", ...lines].join("\n");
997
+ return text.trim() ? `${text.trim()}\n\n${section}` : section;
998
+ }
775
999
  function parseDownstreamArtifactBlock(result) {
776
1000
  const artifacts = [];
777
1001
  for (const line of downstreamArtifactLines(result)) {
@@ -1076,9 +1300,12 @@ function formatUnverifiedArtifactMessage(refs, documents, decks, dashboards, ana
1076
1300
  export function guardA2AArtifactResponse(responseText, toolResults, options = {}) {
1077
1301
  const baseUrl = normalizeBaseUrl(options.baseUrl);
1078
1302
  const includeReferencedArtifacts = options.includeReferencedArtifacts ?? false;
1079
- const finalize = (value) => options.includePersistedArtifactMarker
1080
- ? withPersistedArtifactMarker(value, toolResults, options.persistedArtifactSecret ?? process.env.A2A_SECRET)
1081
- : value;
1303
+ const finalize = (value) => {
1304
+ const withReceipts = appendA2APersistedMutationReceipts(value, toolResults, options);
1305
+ return options.includePersistedArtifactMarker
1306
+ ? withPersistedArtifactMarker(withReceipts, toolResults, options.persistedArtifactSecret ?? a2aSecret(), options.delegatedTaskId)
1307
+ : withReceipts;
1308
+ };
1082
1309
  const { documents, decks, dashboards, analyses, images, designShells, generatedDesigns, monitors, forms, } = collectArtifacts(toolResults);
1083
1310
  const generatedDesignIds = new Set(generatedDesigns.map((design) => design.id));
1084
1311
  const incompleteShells = designShells.filter((shell) => !generatedDesignIds.has(shell.id));
@@ -9,3 +9,5 @@ export type { A2ACallerAuth } from "./caller-auth.js";
9
9
  export { AgentInvocationError, buildAgentInvocationPrompt, invokeAgent, invokeAgentAction, looksLikeAgentUrl, resolveAgentInvocationTarget, } from "./invoke.js";
10
10
  export type { A2AConfig, A2AHandler, A2AHandlerContext, A2AHandlerResult, A2ASourceContext, AgentCard, AgentSkill, AgentCapabilities, Task, TaskState, TaskStatus, Message, Part, TextPart, FilePart, DataPart, Artifact, JsonRpcRequest, JsonRpcResponse, A2ACorrelationMetadata, A2AReadOnlyActionInvocation, A2AReadOnlyActionResult, A2AAgentActivityPhase, A2AAgentActivitySnapshot, A2AAgentActivityState, A2AAgentActivityToolCall, A2AAgentActivityToolStatus, } from "./types.js";
11
11
  export type { AgentInvocationErrorCode, AgentActionInvocationResult, AgentInvocationResult, AgentInvocationRuntime, InvokeAgentActionOptions, InvokeAgentOptions, ResolveAgentInvocationTargetOptions, ResolvedAgentInvocationTarget, } from "./invoke.js";
12
+ export { extractA2APersistedMutationReceipts, stripA2APersistedArtifactMarkers, } from "./artifact-response.js";
13
+ export type { A2APersistedMutationReceipt } from "./artifact-response.js";
package/dist/a2a/index.js CHANGED
@@ -7,3 +7,4 @@ export { A2AClient, callAction, callAgent, signA2AToken } from "./client.js";
7
7
  export { canonicalA2AAudience } from "./audience.js";
8
8
  export { resolveA2ACallerAuth } from "./caller-auth.js";
9
9
  export { AgentInvocationError, buildAgentInvocationPrompt, invokeAgent, invokeAgentAction, looksLikeAgentUrl, resolveAgentInvocationTarget, } from "./invoke.js";
10
+ export { extractA2APersistedMutationReceipts, stripA2APersistedArtifactMarkers, } from "./artifact-response.js";
@@ -1,6 +1,7 @@
1
1
  import type { Task, Message, TaskState, Artifact } from "./types.js";
2
2
  export declare const MAX_A2A_IDEMPOTENCY_KEY_CHARS = 128;
3
3
  export declare const A2A_PERSONAL_OWNER_SCOPE = "__personal__";
4
+ export declare function ensureTable(): Promise<void>;
4
5
  export interface A2AApprovalRecord {
5
6
  id: string;
6
7
  taskId: string;
@@ -5,7 +5,7 @@ let _initPromise;
5
5
  export const MAX_A2A_IDEMPOTENCY_KEY_CHARS = 128;
6
6
  const A2A_IDEMPOTENCY_INDEX = "idx_a2a_tasks_owner_scope_idempotency";
7
7
  export const A2A_PERSONAL_OWNER_SCOPE = "__personal__";
8
- async function ensureTable() {
8
+ export async function ensureTable() {
9
9
  if (!_initPromise) {
10
10
  _initPromise = (async () => {
11
11
  const client = getDbExec();
@@ -12,6 +12,7 @@
12
12
  * runtime even before the migration plugin is registered.
13
13
  */
14
14
  import type { ObservationalMemoryEntry, ObservationalMemoryOwner, ObservationalMemoryTier } from "./types.js";
15
+ export declare function ensureTable(): Promise<void>;
15
16
  /** Reset the cached ensureTable promise — test-only seam. */
16
17
  export declare function __resetObservationalMemoryTableCache(): void;
17
18
  export interface InsertObservationalMemoryInput extends ObservationalMemoryOwner {
@@ -14,7 +14,7 @@
14
14
  import { getDbExec, isPostgres } from "../../db/client.js";
15
15
  import { ensureTableExists, ensureIndexExists } from "../../db/ddl-guard.js";
16
16
  let tableReady = null;
17
- async function ensureTable() {
17
+ export async function ensureTable() {
18
18
  if (tableReady)
19
19
  return tableReady;
20
20
  tableReady = (async () => {
@@ -217,6 +217,7 @@ export declare const IN_FLIGHT_RUN_STALE_GRACE_MS: number;
217
217
  * is reaped like any other stale run.
218
218
  */
219
219
  export declare const IN_FLIGHT_GRACE_MAX_LIVENESS_GAP_MS = 120000;
220
+ export declare function ensureRunTables(): Promise<void>;
220
221
  /**
221
222
  * Persist a zombie tool-call completion to the ledger. Called by the detached
222
223
  * promise continuation after `Promise.race` abandons it. Best-effort — never
@@ -294,7 +294,7 @@ export const IN_FLIGHT_RUN_STALE_GRACE_MS = 14.5 * 60_000; // 870_000
294
294
  * is reaped like any other stale run.
295
295
  */
296
296
  export const IN_FLIGHT_GRACE_MAX_LIVENESS_GAP_MS = 120_000;
297
- async function ensureRunTables() {
297
+ export async function ensureRunTables() {
298
298
  if (!_initPromise) {
299
299
  _initPromise = (async () => {
300
300
  const client = getDbExec();
@@ -1,3 +1,4 @@
1
+ export declare function ensureAgentToolApprovalTable(): Promise<void>;
1
2
  export interface AgentToolApprovalBinding {
2
3
  ownerEmail: string;
3
4
  orgId?: string | null;
@@ -11,7 +11,7 @@ import { AGENT_TOOL_APPROVAL_INDEX_SQL, AGENT_TOOL_APPROVAL_LOGICAL_INDEX_SQL, A
11
11
  const APPROVAL_TTL_MS = 60 * 60_000;
12
12
  const APPROVAL_CLEANUP_AGE_MS = 24 * 60 * 60_000;
13
13
  let initPromise;
14
- async function ensureAgentToolApprovalTable() {
14
+ export async function ensureAgentToolApprovalTable() {
15
15
  if (!initPromise) {
16
16
  initPromise = (async () => {
17
17
  const createSql = AGENT_TOOL_APPROVAL_TABLE_SQL[isPostgres() ? "postgres" : "sqlite"];
@@ -1,4 +1,5 @@
1
1
  import type { StoreWriteOptions } from "../settings/store.js";
2
+ export declare function ensureTable(): Promise<void>;
2
3
  export declare function appStateGet(sessionId: string, key: string): Promise<Record<string, unknown> | null>;
3
4
  /**
4
5
  * Read several application-state keys for one session in a single SQL query,
@@ -11,7 +11,7 @@ const MAX_HOSTED_APP_STATE_VALUE_BYTES = 1024 * 1024;
11
11
  function escapeLike(s) {
12
12
  return s.replace(/[!%_]/g, (match) => `!${match}`);
13
13
  }
14
- async function ensureTable() {
14
+ export async function ensureTable() {
15
15
  if (!_initPromise) {
16
16
  _initPromise = (async () => {
17
17
  const client = getDbExec();
@@ -2,6 +2,7 @@ import type { AgentNativeBrowserSessionRecord, AgentNativeBrowserSessionRequest,
2
2
  export declare const DEFAULT_BROWSER_SESSION_TTL_MS = 45000;
3
3
  export declare const DEFAULT_BROWSER_SESSION_REQUEST_TIMEOUT_MS = 30000;
4
4
  export declare const DEFAULT_BROWSER_SESSION_REQUEST_POLL_MS = 250;
5
+ export declare function ensureTables(): Promise<void>;
5
6
  export declare function registerBrowserSession(ownerEmailInput: string, input: RegisterAgentNativeBrowserSessionInput): Promise<AgentNativeBrowserSessionRecord>;
6
7
  export declare function listBrowserSessions(ownerEmailInput: string, options?: {
7
8
  includeExpired?: boolean;
@@ -13,7 +13,7 @@ function nowMs() {
13
13
  function sleep(ms) {
14
14
  return new Promise((resolve) => setTimeout(resolve, ms));
15
15
  }
16
- async function ensureTables() {
16
+ export async function ensureTables() {
17
17
  if (!initPromise) {
18
18
  initPromise = (async () => {
19
19
  const client = getDbExec();
@@ -1,3 +1,4 @@
1
+ export declare function ensureCheckpointTable(): Promise<void>;
1
2
  export declare function insertCheckpoint(id: string, threadId: string, runId: string | null, commitSha: string, message: string): Promise<void>;
2
3
  export declare function getCheckpointsByThread(threadId: string): Promise<Array<{
3
4
  id: string;
@@ -1,7 +1,7 @@
1
1
  import { getDbExec, intType, isPostgres } from "../db/client.js";
2
2
  import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
3
3
  let _initPromise;
4
- async function ensureCheckpointTable() {
4
+ export async function ensureCheckpointTable() {
5
5
  if (!_initPromise) {
6
6
  _initPromise = (async () => {
7
7
  const client = getDbExec();
@@ -52,3 +52,14 @@ export declare function deleteCodeAgentSchedule(scheduleId: string): boolean;
52
52
  export declare function markCodeAgentScheduleRun(scheduleId: string, patch: CodeAgentScheduleRunPatch): CodeAgentScheduleRecord | null;
53
53
  export declare function isCodeAgentScheduleDue(schedule: CodeAgentScheduleRecord, now?: Date): boolean;
54
54
  export declare function nextCodeAgentScheduleRunAt(schedule: CodeAgentScheduleRecord, now?: Date): string;
55
+ /**
56
+ * A schedules file that exists but cannot be understood. Every mutation
57
+ * rewrites the whole file, so treating this as an empty list would delete every
58
+ * stored schedule; callers must fail instead.
59
+ */
60
+ export declare class CodeAgentSchedulesUnreadableError extends Error {
61
+ readonly filePath: string;
62
+ constructor(filePath: string, detail: string, options?: {
63
+ cause?: unknown;
64
+ });
65
+ }
@@ -136,16 +136,55 @@ export function nextCodeAgentScheduleRunAt(schedule, now = new Date()) {
136
136
  next += intervalMs;
137
137
  return new Date(next).toISOString();
138
138
  }
139
+ /**
140
+ * A schedules file that exists but cannot be understood. Every mutation
141
+ * rewrites the whole file, so treating this as an empty list would delete every
142
+ * stored schedule; callers must fail instead.
143
+ */
144
+ export class CodeAgentSchedulesUnreadableError extends Error {
145
+ filePath;
146
+ constructor(filePath, detail, options) {
147
+ super(`Code agent schedules at ${filePath} could not be read (${detail}). ` +
148
+ `Refusing to continue so the existing schedules are not overwritten. ` +
149
+ `Repair or remove the file, then retry.`, options);
150
+ this.name = "CodeAgentSchedulesUnreadableError";
151
+ this.filePath = filePath;
152
+ }
153
+ }
139
154
  function readScheduleFile() {
155
+ const filePath = codeAgentSchedulesPath();
156
+ let contents;
140
157
  try {
141
- const raw = JSON.parse(fs.readFileSync(codeAgentSchedulesPath(), "utf8"));
142
- if (!Array.isArray(raw))
158
+ contents = fs.readFileSync(filePath, "utf8");
159
+ }
160
+ catch (error) {
161
+ // Only a genuinely absent file is an empty schedule list. A permission
162
+ // error or transient I/O failure is unknown, not empty.
163
+ if (error?.code === "ENOENT")
143
164
  return [];
144
- return raw.filter(isScheduleRecord);
165
+ throw new CodeAgentSchedulesUnreadableError(filePath, "read failed", {
166
+ cause: error,
167
+ });
168
+ }
169
+ let parsed;
170
+ try {
171
+ parsed = JSON.parse(contents);
172
+ }
173
+ catch (error) {
174
+ throw new CodeAgentSchedulesUnreadableError(filePath, "invalid JSON", {
175
+ cause: error,
176
+ });
177
+ }
178
+ if (!Array.isArray(parsed)) {
179
+ throw new CodeAgentSchedulesUnreadableError(filePath, `expected an array, found ${parsed === null ? "null" : typeof parsed}`);
145
180
  }
146
- catch {
147
- return [];
181
+ const records = parsed.filter(isScheduleRecord);
182
+ if (records.length !== parsed.length) {
183
+ // Dropping the entries we cannot parse and writing the rest back is the
184
+ // same data loss by a quieter route — a newer schemaVersion included.
185
+ throw new CodeAgentSchedulesUnreadableError(filePath, `${parsed.length - records.length} of ${parsed.length} entries are not valid schedule records`);
148
186
  }
187
+ return records;
149
188
  }
150
189
  function writeScheduleFile(records) {
151
190
  const filePath = codeAgentSchedulesPath();
@@ -223,6 +223,10 @@ export interface AgentSidebarProps {
223
223
  apiUrl?: string;
224
224
  /** Runtime surface identity used for server-side chat capabilities. */
225
225
  agentChatSurface?: AgentChatSurfaceKind;
226
+ /** Whether the desktop host is currently showing its unauthenticated identity gate. */
227
+ desktopIdentityUnauthenticated?: AssistantChatProps["desktopIdentityUnauthenticated"];
228
+ /** Whether the desktop host has just established its authenticated identity session. */
229
+ desktopIdentityAuthenticated?: AssistantChatProps["desktopIdentityAuthenticated"];
226
230
  /** Show the chat thread tab row. Default: true. */
227
231
  showTabBar?: MultiTabAssistantChatProps["showTabBar"];
228
232
  /** Keep inline app-opening results inside the current app chat. */
@@ -250,7 +254,7 @@ export interface AgentSidebarProps {
250
254
  * Wraps app content with a toggleable agent sidebar.
251
255
  * Use AgentToggleButton in your header to open/close it.
252
256
  */
253
- export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, availableModels, modelListLoading, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
257
+ export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, availableModels, modelListLoading, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, desktopIdentityUnauthenticated, desktopIdentityAuthenticated, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
254
258
  /**
255
259
  * Focus the agent chat composer input.
256
260
  * Opens the sidebar if closed, then focuses the text input.
@@ -1418,7 +1418,7 @@ export function AgentChatSurface({ mode = "panel", className, defaultMode = "cha
1418
1418
  * Wraps app content with a toggleable agent sidebar.
1419
1419
  * Use AgentToggleButton in your header to open/close it.
1420
1420
  */
1421
- export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, availableModels, modelListLoading, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1421
+ export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, availableModels, modelListLoading, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, desktopIdentityUnauthenticated, desktopIdentityAuthenticated, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1422
1422
  const staticHostedHarnessEnabled = isHostedHarnessConfigured(injectedAgentNativeConfig().harness);
1423
1423
  const hostedHarnessQuery = useActionQuery("get-hosted-harness-config", undefined, { enabled: staticHostedHarnessEnabled });
1424
1424
  const hostedHarnessStatus = hostedHarnessQuery.data;
@@ -2059,7 +2059,7 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
2059
2059
  ? "desktop"
2060
2060
  : undefined, "data-agent-sidebar-layout": panelLayout, "data-agent-sidebar-position": effectivePosition, "data-agent-native-hosted-harness-ui": hostedHarnessUi ? "desktop" : undefined, "data-agent-sidebar-state": panelOpen ? "open" : "closed", "data-agent-sidebar-per-app-chat": isPerAppChatSidebar ? "true" : undefined, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, "data-agent-sidebar-chat-handoff": chatViewTransitionHandoff ? "true" : undefined, style: chatViewTransition
2061
2061
  ? getAgentChatViewTransitionStyle(panelStyle)
2062
- : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, availableAgents: effectiveAvailableAgents, availableModels: availableModels, modelListLoading: modelListLoading, selectedAgent: effectiveSelectedAgent, onAgentChange: effectiveOnAgentChange, hostedHarness: hostedHarnessEnabled, onConnectLocalRuntime: onConnectLocalRuntime, runtime: runtime, adapterReloadKey: adapterReloadKey, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, showTabBar: effectiveShowTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: effectivePosition, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
2062
+ : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, availableAgents: effectiveAvailableAgents, availableModels: availableModels, modelListLoading: modelListLoading, selectedAgent: effectiveSelectedAgent, onAgentChange: effectiveOnAgentChange, hostedHarness: hostedHarnessEnabled, onConnectLocalRuntime: onConnectLocalRuntime, runtime: runtime, adapterReloadKey: adapterReloadKey, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, desktopIdentityUnauthenticated: desktopIdentityUnauthenticated, desktopIdentityAuthenticated: desktopIdentityAuthenticated, showTabBar: effectiveShowTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: effectivePosition, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
2063
2063
  const drawerPlaceholder = wideDrawerEnabled && !presentationMode && panelOpen ? (_jsx("div", { "aria-hidden": "true", className: "agent-sidebar-drawer-placeholder shrink-0", "data-agent-sidebar-placeholder": "true", style: { width: drawerPlaceholderWidth + 1 } })) : null;
2064
2064
  return (_jsx(AgentSidebarOnboardingContext.Provider, { value: true, children: _jsxs(RealtimeVoiceModeProvider, { browserTabId: browserTabId, children: [showFirstRunOnboarding && (_jsx(Suspense, { fallback: null, children: _jsx(FirstRunOnboarding, {}) })), _jsxs("div", { className: "agent-sidebar-shell flex min-w-0 flex-1 h-screen overflow-hidden", "data-agent-sidebar-position": effectivePosition, "data-agent-native-hosted-harness-ui": hostedHarnessUi ? "desktop" : undefined, "data-agent-native-hosted-chat": isPerAppChatHosted ? "true" : undefined, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, children: [isMobile &&
2065
2065
  !isPerAppChatHosted &&
@@ -14,7 +14,7 @@ import { type ContentPart } from "./sse-event-processor.js";
14
14
  import type { ChatThreadScope, ChatThreadSnapshot } from "./use-chat-threads.js";
15
15
  export { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, assistantUiRecoverableRenderErrorKind, isAssistantUiRecoverableRenderError, isAssistantUiStaleIndexError, } from "./assistant-ui-recovery.js";
16
16
  export { displayableUserMessageText } from "./chat/message-components.js";
17
- export declare function shouldSuppressUnauthenticatedDesktopThreadRestore(surface: AgentChatSurfaceKind, status: number): boolean;
17
+ export declare function shouldSuppressUnauthenticatedDesktopThreadRestore(surface: AgentChatSurfaceKind, status: number, desktopIdentityUnauthenticated?: boolean): boolean;
18
18
  type AssistantUiMessageResourceShape = {
19
19
  id: string;
20
20
  content: readonly unknown[];
@@ -278,6 +278,10 @@ export interface AssistantChatProps {
278
278
  * dev filesystem/bash code-editing tools out of in-product sidebars.
279
279
  */
280
280
  agentChatSurface?: AgentChatSurfaceKind;
281
+ /** Whether the desktop host is currently showing its unauthenticated identity gate. */
282
+ desktopIdentityUnauthenticated?: boolean;
283
+ /** Whether the desktop host has just established its authenticated identity session. */
284
+ desktopIdentityAuthenticated?: boolean;
281
285
  /** Route completed first-party open_app calls through the host app pane. */
282
286
  suppressInlineOpenApp?: boolean;
283
287
  /** Placeholder text for empty state */