@agent-native/core 0.92.4 → 0.92.6

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 (160) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +19 -0
  3. package/corpus/core/docs/content/template-assets.mdx +139 -0
  4. package/corpus/core/package.json +1 -1
  5. package/corpus/core/src/agent/production-agent.ts +96 -6
  6. package/corpus/core/src/cli/design-connect.ts +43 -16
  7. package/corpus/core/src/cli/skills.ts +52 -16
  8. package/corpus/core/src/client/AssistantChat.tsx +127 -15
  9. package/corpus/core/src/client/chat/tool-call-display.tsx +9 -3
  10. package/corpus/core/src/client/org/TeamPage.tsx +274 -177
  11. package/corpus/core/src/client/settings/DemoModeSection.tsx +6 -6
  12. package/corpus/core/src/client/settings/SettingsPanel.tsx +1 -1
  13. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +49 -1
  14. package/corpus/core/src/demo/actions/toggle-demo-mode.ts +2 -2
  15. package/corpus/core/src/demo/config.ts +3 -3
  16. package/corpus/core/src/demo/redact.ts +720 -0
  17. package/corpus/core/src/extensions/url-safety.ts +13 -1
  18. package/corpus/core/src/localization/default-messages.ts +7 -0
  19. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +7 -0
  20. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +7 -0
  21. package/corpus/core/src/templates/default/app/i18n/en-US.ts +7 -0
  22. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +7 -0
  23. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +7 -0
  24. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +7 -0
  25. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +7 -0
  26. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +7 -0
  27. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +7 -0
  28. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +7 -0
  29. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +7 -0
  30. package/corpus/templates/analytics/AGENTS.md +6 -3
  31. package/corpus/templates/analytics/changelog/2026-07-09-uptime-monitors-use-scheduled-workers-in-production-serverless.md +6 -0
  32. package/corpus/templates/analytics/docs/uptime-monitoring.md +5 -0
  33. package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +14 -2
  34. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +35 -0
  35. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +19 -0
  36. package/corpus/templates/assets/AGENTS.md +13 -0
  37. package/corpus/templates/assets/actions/_generation-preset-settings.ts +73 -0
  38. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +63 -0
  39. package/corpus/templates/assets/actions/create-generation-preset.ts +22 -8
  40. package/corpus/templates/assets/actions/duplicate-library.ts +49 -1
  41. package/corpus/templates/assets/actions/generate-image-batch.ts +14 -1
  42. package/corpus/templates/assets/actions/generate-image.ts +195 -26
  43. package/corpus/templates/assets/actions/import-asset-from-url.ts +323 -0
  44. package/corpus/templates/assets/actions/list-generation-presets.ts +1 -1
  45. package/corpus/templates/assets/actions/rerun-generation-run.ts +37 -0
  46. package/corpus/templates/assets/actions/update-generation-preset.ts +19 -1
  47. package/corpus/templates/assets/app/i18n/ar-SA.ts +1 -0
  48. package/corpus/templates/assets/app/i18n/de-DE.ts +1 -0
  49. package/corpus/templates/assets/app/i18n/es-ES.ts +1 -0
  50. package/corpus/templates/assets/app/i18n/fr-FR.ts +1 -0
  51. package/corpus/templates/assets/app/i18n/hi-IN.ts +1 -0
  52. package/corpus/templates/assets/app/i18n/ja-JP.ts +1 -0
  53. package/corpus/templates/assets/app/i18n/ko-KR.ts +1 -0
  54. package/corpus/templates/assets/app/i18n/pt-BR.ts +1 -0
  55. package/corpus/templates/assets/app/i18n/zh-CN.ts +1 -0
  56. package/corpus/templates/assets/app/i18n/zh-TW.ts +41 -0
  57. package/corpus/templates/assets/app/i18n-data.ts +93 -0
  58. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +66 -11
  59. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +959 -24
  60. package/corpus/templates/assets/changelog/2026-07-07-preset-skeleton-controls-fit-correctly-on-narrower-edit-page.md +6 -0
  61. package/corpus/templates/assets/changelog/2026-07-09-import-reference-images-from-url.md +6 -0
  62. package/corpus/templates/assets/changelog/2026-07-09-preset-reference-board.md +6 -0
  63. package/corpus/templates/assets/server/handlers/assets.ts +7 -27
  64. package/corpus/templates/assets/server/lib/generation.ts +83 -2
  65. package/corpus/templates/assets/server/lib/preset-chat-context.ts +17 -4
  66. package/corpus/templates/assets/server/lib/preset-references.ts +182 -0
  67. package/corpus/templates/assets/server/lib/upload-validation.ts +38 -0
  68. package/corpus/templates/assets/shared/api.ts +20 -0
  69. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +6 -0
  70. package/corpus/templates/calendar/actions/create-event.ts +8 -2
  71. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +22 -7
  72. package/corpus/templates/calendar/changelog/2026-07-09-calendar-events-with-guests-now-automatically-get-a-google-m.md +6 -0
  73. package/corpus/templates/calendar/changelog/2026-07-09-new-events-now-mark-the-creator-rsvp-as-yes.md +6 -0
  74. package/corpus/templates/calendar/server/handlers/events.ts +9 -2
  75. package/corpus/templates/calendar/server/lib/event-video-conferencing.ts +58 -0
  76. package/corpus/templates/calendar/server/lib/google-calendar.ts +1 -0
  77. package/corpus/templates/clips/changelog/2026-07-09-meeting-reminder-popovers-can-now-be-dismissed-with-a-top-le.md +6 -0
  78. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +3 -1
  79. package/corpus/templates/clips/desktop/src/styles.css +13 -9
  80. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +5 -2
  81. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +27 -15
  82. package/corpus/templates/design/actions/connect-localhost.ts +40 -11
  83. package/corpus/templates/design/actions/open-visual-edit.ts +7 -1
  84. package/dist/agent/production-agent.d.ts +34 -1
  85. package/dist/agent/production-agent.d.ts.map +1 -1
  86. package/dist/agent/production-agent.js +58 -5
  87. package/dist/agent/production-agent.js.map +1 -1
  88. package/dist/cli/design-connect.d.ts +5 -1
  89. package/dist/cli/design-connect.d.ts.map +1 -1
  90. package/dist/cli/design-connect.js +37 -16
  91. package/dist/cli/design-connect.js.map +1 -1
  92. package/dist/cli/skills.d.ts.map +1 -1
  93. package/dist/cli/skills.js +52 -16
  94. package/dist/cli/skills.js.map +1 -1
  95. package/dist/client/AssistantChat.d.ts +3 -1
  96. package/dist/client/AssistantChat.d.ts.map +1 -1
  97. package/dist/client/AssistantChat.js +96 -15
  98. package/dist/client/AssistantChat.js.map +1 -1
  99. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  100. package/dist/client/chat/tool-call-display.js +5 -1
  101. package/dist/client/chat/tool-call-display.js.map +1 -1
  102. package/dist/client/org/TeamPage.d.ts.map +1 -1
  103. package/dist/client/org/TeamPage.js +32 -13
  104. package/dist/client/org/TeamPage.js.map +1 -1
  105. package/dist/client/settings/DemoModeSection.d.ts +3 -3
  106. package/dist/client/settings/DemoModeSection.js +4 -4
  107. package/dist/client/settings/DemoModeSection.js.map +1 -1
  108. package/dist/client/settings/SettingsPanel.js +1 -1
  109. package/dist/client/settings/SettingsPanel.js.map +1 -1
  110. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  111. package/dist/client/settings/SettingsTabsPage.js +38 -2
  112. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  113. package/dist/collab/routes.d.ts +1 -1
  114. package/dist/collab/struct-routes.d.ts +1 -1
  115. package/dist/demo/actions/toggle-demo-mode.js +2 -2
  116. package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
  117. package/dist/demo/config.js +3 -3
  118. package/dist/demo/config.js.map +1 -1
  119. package/dist/demo/redact.d.ts +1 -1
  120. package/dist/demo/redact.d.ts.map +1 -1
  121. package/dist/demo/redact.js +0 -0
  122. package/dist/demo/redact.js.map +1 -1
  123. package/dist/extensions/url-safety.d.ts +5 -0
  124. package/dist/extensions/url-safety.d.ts.map +1 -1
  125. package/dist/extensions/url-safety.js +10 -0
  126. package/dist/extensions/url-safety.js.map +1 -1
  127. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  128. package/dist/localization/default-messages.d.ts +7 -0
  129. package/dist/localization/default-messages.d.ts.map +1 -1
  130. package/dist/localization/default-messages.js +7 -0
  131. package/dist/localization/default-messages.js.map +1 -1
  132. package/dist/notifications/routes.d.ts +2 -2
  133. package/dist/observability/routes.d.ts +3 -3
  134. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  135. package/dist/resources/handlers.d.ts +1 -1
  136. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  137. package/dist/templates/default/app/i18n/ar-SA.ts +7 -0
  138. package/dist/templates/default/app/i18n/de-DE.ts +7 -0
  139. package/dist/templates/default/app/i18n/en-US.ts +7 -0
  140. package/dist/templates/default/app/i18n/es-ES.ts +7 -0
  141. package/dist/templates/default/app/i18n/fr-FR.ts +7 -0
  142. package/dist/templates/default/app/i18n/hi-IN.ts +7 -0
  143. package/dist/templates/default/app/i18n/ja-JP.ts +7 -0
  144. package/dist/templates/default/app/i18n/ko-KR.ts +7 -0
  145. package/dist/templates/default/app/i18n/pt-BR.ts +7 -0
  146. package/dist/templates/default/app/i18n/zh-CN.ts +7 -0
  147. package/dist/templates/default/app/i18n/zh-TW.ts +7 -0
  148. package/docs/content/template-assets.mdx +139 -0
  149. package/package.json +1 -1
  150. package/src/templates/default/app/i18n/ar-SA.ts +7 -0
  151. package/src/templates/default/app/i18n/de-DE.ts +7 -0
  152. package/src/templates/default/app/i18n/en-US.ts +7 -0
  153. package/src/templates/default/app/i18n/es-ES.ts +7 -0
  154. package/src/templates/default/app/i18n/fr-FR.ts +7 -0
  155. package/src/templates/default/app/i18n/hi-IN.ts +7 -0
  156. package/src/templates/default/app/i18n/ja-JP.ts +7 -0
  157. package/src/templates/default/app/i18n/ko-KR.ts +7 -0
  158. package/src/templates/default/app/i18n/pt-BR.ts +7 -0
  159. package/src/templates/default/app/i18n/zh-CN.ts +7 -0
  160. package/src/templates/default/app/i18n/zh-TW.ts +7 -0
@@ -674,9 +674,34 @@ function toolCallFingerprintFromContentPart(part: unknown): string | null {
674
674
  return `${name}\u0000${argsText}`;
675
675
  }
676
676
 
677
+ function toolCallNameFromContentPart(part: unknown): string | null {
678
+ if (!part || typeof part !== "object") return null;
679
+ const candidate = part as { type?: unknown; toolName?: unknown };
680
+ if (candidate.type !== "tool-call") return null;
681
+ return typeof candidate.toolName === "string" && candidate.toolName
682
+ ? candidate.toolName
683
+ : null;
684
+ }
685
+
686
+ function toolCallIdsRepresentSameLocalCall(
687
+ renderedId: string,
688
+ reconnectId: string,
689
+ ): boolean {
690
+ return renderedId === reconnectId || renderedId.endsWith(`:${reconnectId}`);
691
+ }
692
+
677
693
  function collectRenderedToolCallStates(messages: readonly unknown[]): {
678
694
  byId: Map<string, { rank: number }>;
679
695
  latestAssistantByFingerprint: Map<string, { rank: number }>;
696
+ latestAssistantByName: Map<
697
+ string,
698
+ {
699
+ rank: number;
700
+ ids: Set<string>;
701
+ pendingIds: Set<string>;
702
+ pendingRank: number;
703
+ }
704
+ >;
680
705
  } {
681
706
  const byId = new Map<string, { rank: number }>();
682
707
  for (const message of messages) {
@@ -695,22 +720,50 @@ function collectRenderedToolCallStates(messages: readonly unknown[]): {
695
720
  }
696
721
 
697
722
  const latestAssistantByFingerprint = new Map<string, { rank: number }>();
723
+ const latestAssistantByName = new Map<
724
+ string,
725
+ {
726
+ rank: number;
727
+ ids: Set<string>;
728
+ pendingIds: Set<string>;
729
+ pendingRank: number;
730
+ }
731
+ >();
698
732
  const latestEntry = messages.at(-1);
699
733
  const latestMessage = getRepoMessage(latestEntry as any);
700
734
  const latestContent = latestMessage?.content;
701
735
  if (latestMessage?.role === "assistant" && Array.isArray(latestContent)) {
702
736
  for (const part of latestContent) {
703
- const fingerprint = toolCallFingerprintFromContentPart(part);
704
- if (!fingerprint) continue;
705
737
  const rank = toolCallProgressRank(part);
706
- const existing = latestAssistantByFingerprint.get(fingerprint);
707
- latestAssistantByFingerprint.set(fingerprint, {
708
- rank: Math.max(existing?.rank ?? 0, rank),
709
- });
738
+ const fingerprint = toolCallFingerprintFromContentPart(part);
739
+ if (fingerprint) {
740
+ const existing = latestAssistantByFingerprint.get(fingerprint);
741
+ latestAssistantByFingerprint.set(fingerprint, {
742
+ rank: Math.max(existing?.rank ?? 0, rank),
743
+ });
744
+ }
745
+ const name = toolCallNameFromContentPart(part);
746
+ if (name) {
747
+ const existing = latestAssistantByName.get(name);
748
+ const id = toolCallIdFromContentPart(part);
749
+ const ids = new Set(existing?.ids);
750
+ const pendingIds = new Set(existing?.pendingIds);
751
+ if (id) ids.add(id);
752
+ if (id && rank < 4) pendingIds.add(id);
753
+ latestAssistantByName.set(name, {
754
+ rank: Math.max(existing?.rank ?? 0, rank),
755
+ ids,
756
+ pendingIds,
757
+ pendingRank:
758
+ rank < 4
759
+ ? Math.max(existing?.pendingRank ?? 0, rank)
760
+ : (existing?.pendingRank ?? 0),
761
+ });
762
+ }
710
763
  }
711
764
  }
712
765
 
713
- return { byId, latestAssistantByFingerprint };
766
+ return { byId, latestAssistantByFingerprint, latestAssistantByName };
714
767
  }
715
768
 
716
769
  function assistantTextFromContent(content: unknown): string {
@@ -798,29 +851,37 @@ function trimReconnectTextAlreadyRendered(
798
851
  export function dedupeReconnectContentAgainstMessages(
799
852
  content: ContentPart[],
800
853
  messages: readonly unknown[],
854
+ options?: { suppressToolRepeats?: boolean },
801
855
  ): ContentPart[] {
802
856
  if (content.length === 0) return content;
803
857
  const snapshotDeduped = dedupePendingToolCallReplaysWithinContent(content);
804
858
  let changed = snapshotDeduped !== content;
805
859
  if (messages.length === 0) return changed ? snapshotDeduped : content;
806
- const { byId, latestAssistantByFingerprint } =
860
+ const { byId, latestAssistantByFingerprint, latestAssistantByName } =
807
861
  collectRenderedToolCallStates(messages);
808
862
  const renderedAssistantText = latestRenderedAssistantText(messages);
809
863
  if (
810
864
  byId.size === 0 &&
811
865
  latestAssistantByFingerprint.size === 0 &&
866
+ latestAssistantByName.size === 0 &&
812
867
  !renderedAssistantText
813
868
  ) {
814
869
  return changed ? snapshotDeduped : content;
815
870
  }
816
871
 
817
872
  const filtered =
818
- byId.size > 0 || latestAssistantByFingerprint.size > 0
873
+ byId.size > 0 ||
874
+ latestAssistantByFingerprint.size > 0 ||
875
+ latestAssistantByName.size > 0
819
876
  ? snapshotDeduped.filter((part) => {
820
877
  const reconnectRank = toolCallProgressRank(part);
821
878
  const id = toolCallIdFromContentPart(part);
822
879
  const existing = id ? byId.get(id) : undefined;
823
880
  if (existing) {
881
+ if (options?.suppressToolRepeats) {
882
+ changed = true;
883
+ return false;
884
+ }
824
885
  // Keep reconnect copies that are strictly ahead of the rendered
825
886
  // message (e.g. completed overlay vs lagging pending thread data).
826
887
  // Same-or-behind ranks are duplicates and should stay hidden.
@@ -842,14 +903,60 @@ export function dedupeReconnectContentAgainstMessages(
842
903
  : undefined;
843
904
  const isCompletedRepeat =
844
905
  reconnectRank >= 4 && latestByFingerprint?.rank === 4;
906
+ const keepCompletedRepeat =
907
+ isCompletedRepeat && !options?.suppressToolRepeats;
908
+ if (latestByFingerprint && options?.suppressToolRepeats) {
909
+ changed = true;
910
+ return false;
911
+ }
845
912
  if (
846
913
  latestByFingerprint &&
847
- !isCompletedRepeat &&
914
+ !keepCompletedRepeat &&
848
915
  reconnectRank <= latestByFingerprint.rank
849
916
  ) {
850
917
  changed = true;
851
918
  return false;
852
919
  }
920
+ // Activity / arg-less fallback. A reconnect spinner (activity===true)
921
+ // or a pending tool whose args have not materialized yet has no
922
+ // fingerprint, and its reader-local id (`tc_N`) never matches the
923
+ // server-scoped id (`${runId}:tc_N`) rendered in the message, so it
924
+ // slips past BOTH checks above and paints a second card beside the
925
+ // live one ("one spinning, one static"). Suppress it only when the
926
+ // latest assistant message renders the same tool that is ITSELF still
927
+ // pending (rank < 4) at an equal-or-greater rank: a spinner alongside
928
+ // a live pending card is the same in-flight call seen by two readers.
929
+ // If the rendered same-name tool is already completed, a fresh spinner
930
+ // is more likely a genuinely repeated call, so it must stay visible
931
+ // (an empty-args fingerprint would over-match — see the completed
932
+ // repeat cases below).
933
+ if (!fingerprint) {
934
+ const name = toolCallNameFromContentPart(part);
935
+ const latestByName = name
936
+ ? latestAssistantByName.get(name)
937
+ : undefined;
938
+ const matchesRenderedLocalId =
939
+ id && latestByName
940
+ ? Array.from(latestByName.ids).some((renderedId) =>
941
+ toolCallIdsRepresentSameLocalCall(renderedId, id),
942
+ )
943
+ : false;
944
+ const matchesRenderedPendingLocalId =
945
+ id && latestByName
946
+ ? Array.from(latestByName.pendingIds).some((renderedId) =>
947
+ toolCallIdsRepresentSameLocalCall(renderedId, id),
948
+ )
949
+ : false;
950
+ if (
951
+ latestByName &&
952
+ matchesRenderedLocalId &&
953
+ matchesRenderedPendingLocalId &&
954
+ reconnectRank <= latestByName.pendingRank
955
+ ) {
956
+ changed = true;
957
+ return false;
958
+ }
959
+ }
853
960
  return true;
854
961
  })
855
962
  : snapshotDeduped;
@@ -3328,8 +3435,9 @@ const AssistantChatInner = forwardRef<
3328
3435
  return;
3329
3436
  }
3330
3437
  const stillNeeded =
3331
- dedupeReconnectContentAgainstMessages(reconnectContent, messages).length >
3332
- 0;
3438
+ dedupeReconnectContentAgainstMessages(reconnectContent, messages, {
3439
+ suppressToolRepeats: true,
3440
+ }).length > 0;
3333
3441
  if (!stillNeeded) {
3334
3442
  setReconnectContent([]);
3335
3443
  setAdapterHandoffPending(false);
@@ -3888,9 +3996,13 @@ const AssistantChatInner = forwardRef<
3888
3996
  ],
3889
3997
  );
3890
3998
 
3891
- const visibleReconnectContent = useMemo(
3892
- () => dedupeReconnectContentAgainstMessages(reconnectContent, messages),
3893
- [messages, reconnectContent],
3999
+ // Do not memoize this on `messages` identity. assistant-ui can update the
4000
+ // live assistant message content in place while streaming, and the reconnect
4001
+ // overlay must hide as soon as that live message has caught up.
4002
+ const visibleReconnectContent = dedupeReconnectContentAgainstMessages(
4003
+ reconnectContent,
4004
+ messages,
4005
+ { suppressToolRepeats: adapterHandoffPending },
3894
4006
  );
3895
4007
  const chatScrollResetKey = `${tabId ?? ""}:${threadId ?? ""}`;
3896
4008
 
@@ -157,6 +157,12 @@ function inferToolTextLanguage(
157
157
  ): string {
158
158
  const keyName = (key ?? "").toLowerCase();
159
159
  const tool = (toolName ?? "").toLowerCase();
160
+ if (
161
+ keyName === "code" &&
162
+ (tool.includes("run-code") || tool.includes("run_code"))
163
+ ) {
164
+ return "javascript";
165
+ }
160
166
  if (
161
167
  keyName === "sql" ||
162
168
  keyName.endsWith("sql") ||
@@ -352,7 +358,7 @@ function ToolOutputPopover({
352
358
  side="bottom"
353
359
  sideOffset={6}
354
360
  collisionPadding={12}
355
- className="flex w-[min(calc(100vw-2rem),760px)] flex-col gap-0 overflow-hidden p-0"
361
+ className="flex max-h-[min(calc(100vh-2rem),var(--radix-popover-content-available-height,75vh))] w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,760px),760px)] flex-col gap-0 overflow-hidden p-0"
356
362
  >
357
363
  <div className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3">
358
364
  <div className="truncate text-sm font-medium">{title}</div>
@@ -365,11 +371,11 @@ function ToolOutputPopover({
365
371
  {copied ? "Copied" : "Copy"}
366
372
  </button>
367
373
  </div>
368
- <div className="p-3">
374
+ <div className="min-h-0 flex-1 overflow-hidden p-3">
369
375
  <SimpleCodeViewer
370
376
  text={payload.text}
371
377
  lang={payload.lang}
372
- maxHeightClass="max-h-[75vh]"
378
+ maxHeightClass="max-h-[min(70vh,calc(var(--radix-popover-content-available-height,75vh)-4.5rem))]"
373
379
  />
374
380
  </div>
375
381
  </PopoverContent>