@agent-native/core 0.77.4 → 0.77.7
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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +31 -0
- package/corpus/core/package.json +3 -3
- package/corpus/core/src/agent/production-agent.ts +35 -0
- package/corpus/core/src/agent/run-store.ts +2 -0
- package/corpus/core/src/agent/thread-data-builder.ts +21 -2
- package/corpus/core/src/cli/create.ts +35 -1
- package/corpus/core/src/cli/skills.ts +8 -0
- package/corpus/core/src/client/AgentPanel.tsx +57 -25
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -1
- package/corpus/core/src/client/analytics.ts +24 -2
- package/corpus/core/src/client/changelog/Changelog.tsx +22 -10
- package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +405 -35
- package/corpus/core/src/client/use-agent-engine-configured.ts +29 -15
- package/corpus/core/src/client/use-chat-threads.ts +104 -55
- package/corpus/core/src/server/analytics.ts +27 -3
- package/corpus/core/src/sharing/access.ts +35 -13
- package/corpus/core/src/sharing/actions/share-resource.ts +32 -9
- package/corpus/core/src/sharing/actions/unshare-resource.ts +25 -2
- package/corpus/core/src/sharing/registry.ts +9 -0
- package/corpus/core/src/vite/client.ts +3 -0
- package/corpus/templates/analytics/actions/data-source-status.ts +25 -14
- package/corpus/templates/analytics/app/components/layout/NewAnalysisDialog.tsx +2 -2
- package/corpus/templates/analytics/app/lib/data-source-status.ts +47 -6
- package/corpus/templates/analytics/app/lib/data-sources.ts +14 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +24 -5
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +15 -43
- package/corpus/templates/analytics/changelog/2026-06-25-fixed-hubspot-data-source-status-so-private-app-tokens-legac.md +6 -0
- package/corpus/templates/analytics/netlify.toml +1 -0
- package/corpus/templates/analytics/server/lib/credential-keys.ts +3 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +12 -3
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +5 -2
- package/corpus/templates/assets/changelog/2026-06-25-create-now-returns-from-agent-settings-to-the-asset-chat-eve.md +6 -0
- package/corpus/templates/assets/netlify.toml +1 -0
- package/corpus/templates/brain/netlify.toml +1 -0
- package/corpus/templates/calendar/app/i18n-data.ts +12 -0
- package/corpus/templates/calendar/app/lib/clipboard.ts +58 -0
- package/corpus/templates/calendar/app/pages/AvailabilitySettings.tsx +15 -9
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +6 -2
- package/corpus/templates/calendar/changelog/2026-06-25-booking-link-copy-buttons-no-longer-fail-when-clipboard-perm.md +6 -0
- package/corpus/templates/calendar/netlify.toml +1 -0
- package/corpus/templates/chat/netlify.toml +1 -0
- package/corpus/templates/clips/AGENTS.md +9 -7
- package/corpus/templates/clips/actions/add-vocabulary-term.ts +2 -2
- package/corpus/templates/clips/actions/archive-recording.ts +5 -2
- package/corpus/templates/clips/actions/clear-edits.ts +5 -2
- package/corpus/templates/clips/actions/create-folder.ts +7 -2
- package/corpus/templates/clips/actions/delete-folder.ts +7 -4
- package/corpus/templates/clips/actions/delete-recording-permanent.ts +5 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +5 -2
- package/corpus/templates/clips/actions/import-loom-recording.ts +2 -1
- package/corpus/templates/clips/actions/list-notifications.ts +9 -5
- package/corpus/templates/clips/actions/list-organization-state.ts +2 -1
- package/corpus/templates/clips/actions/list-recordings.ts +4 -1
- package/corpus/templates/clips/actions/move-recording.ts +5 -1
- package/corpus/templates/clips/actions/rename-folder.ts +6 -3
- package/corpus/templates/clips/actions/request-transcript.ts +5 -2
- package/corpus/templates/clips/actions/restore-recording.ts +5 -2
- package/corpus/templates/clips/actions/save-browser-diagnostics.ts +21 -8
- package/corpus/templates/clips/actions/set-chapters.ts +5 -2
- package/corpus/templates/clips/actions/set-thumbnail.ts +5 -2
- package/corpus/templates/clips/actions/split-recording.ts +5 -2
- package/corpus/templates/clips/actions/stitch-recordings.ts +6 -2
- package/corpus/templates/clips/actions/trash-recording.ts +5 -2
- package/corpus/templates/clips/actions/undo-edit.ts +5 -2
- package/corpus/templates/clips/actions/view-screen.ts +2 -1
- package/corpus/templates/clips/app/components/library/recording-card.tsx +24 -7
- package/corpus/templates/clips/app/i18n/ar-SA.ts +14 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +14 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +14 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +14 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +14 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +14 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +14 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +14 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +14 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +14 -0
- package/corpus/templates/clips/app/lib/browser-diagnostics-capture.ts +5 -1
- package/corpus/templates/clips/app/root.tsx +2 -2
- package/corpus/templates/clips/app/routes/_app.extensions.$id.tsx +4 -1
- package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +4 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +12 -5
- package/corpus/templates/clips/changelog/2026-06-25-chrome-extension-recordings-now-upload-large-capture-bursts.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-25-console-diagnostics-keep-more-useful-non-secret-details-when.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-25-fixed-owner-recognition-so-clips-created-from-desktop-and-we.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-25-localized-clips-settings-changelog-and-extension-sidebar-lab.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +3 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/background.ts +85 -9
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +55 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +79 -3
- package/corpus/templates/clips/chrome-extension/src/options.ts +10 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +6 -0
- package/corpus/templates/clips/chrome-extension/src/permission.ts +8 -1
- package/corpus/templates/clips/chrome-extension/src/popup.ts +65 -39
- package/corpus/templates/clips/chrome-extension/src/sentry.ts +206 -0
- package/corpus/templates/clips/chrome-extension/vite.config.ts +47 -0
- package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +4 -2
- package/corpus/templates/clips/desktop/src/styles.css +15 -1
- package/corpus/templates/clips/netlify.toml +1 -0
- package/corpus/templates/clips/server/db/index.ts +1 -0
- package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +35 -23
- package/corpus/templates/clips/server/lib/public-agent-context.ts +8 -1
- package/corpus/templates/clips/server/lib/recordings.ts +18 -2
- package/corpus/templates/clips/server/lib/slack-oauth.ts +9 -6
- package/corpus/templates/clips/server/plugins/onboarding-calendar.ts +6 -2
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +2 -2
- package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +5 -2
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +5 -2
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +5 -2
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +5 -2
- package/corpus/templates/clips/shared/browser-diagnostics.ts +14 -4
- package/corpus/templates/content/netlify.toml +1 -0
- package/corpus/templates/design/netlify.toml +1 -0
- package/corpus/templates/dispatch/netlify.toml +1 -0
- package/corpus/templates/forms/netlify.toml +1 -0
- package/corpus/templates/macros/netlify.toml +1 -0
- package/corpus/templates/mail/app/components/email/EmailList.tsx +7 -3
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +4 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +10 -2
- package/corpus/templates/mail/app/hooks/use-compose-state.ts +15 -5
- package/corpus/templates/mail/app/hooks/use-google-auth.ts +47 -9
- package/corpus/templates/mail/changelog/2026-06-25-account-avatars-stay-stable-while-mail-refreshes-google-acco.md +6 -0
- package/corpus/templates/mail/changelog/2026-06-25-mail-background-draft-saves-and-thread-prefetches-no-longer.md +6 -0
- package/corpus/templates/mail/netlify.toml +1 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +8 -0
- package/corpus/templates/plan/netlify.toml +1 -0
- package/corpus/templates/slides/netlify.toml +1 -0
- package/corpus/templates/videos/netlify.toml +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +31 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts +2 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +23 -2
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +28 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills.d.ts +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +8 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +8 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +29 -15
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +4 -4
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +22 -2
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/changelog/Changelog.d.ts +7 -2
- package/dist/client/changelog/Changelog.d.ts.map +1 -1
- package/dist/client/changelog/Changelog.js +9 -7
- package/dist/client/changelog/Changelog.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +339 -11
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +23 -13
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +4 -0
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +49 -4
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/observability/routes.d.ts +7 -7
- package/dist/server/agent-engine-api-key-route.d.ts +2 -2
- package/dist/server/analytics.d.ts +4 -0
- package/dist/server/analytics.d.ts.map +1 -1
- package/dist/server/analytics.js +19 -3
- package/dist/server/analytics.js.map +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +26 -12
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/share-resource.js +20 -9
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/sharing/actions/unshare-resource.js +13 -2
- package/dist/sharing/actions/unshare-resource.js.map +1 -1
- package/dist/sharing/registry.d.ts +9 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +3 -3
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.77.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e5bdcb3: Paginate the All Chats history client so older conversations can be loaded without truncating the history list.
|
|
8
|
+
- e5bdcb3: Drop benign reasonless browser AbortError events from Sentry reporting.
|
|
9
|
+
- e5bdcb3: Repair duplicate persisted chat message ids during thread normalization.
|
|
10
|
+
- e5bdcb3: Ensure hosted template apps can inject Google Analytics from Netlify build-time configuration.
|
|
11
|
+
- e5bdcb3: Normalize email casing when resolving shareable-resource ownership and user shares, and let resources opt into owner access across active-org drift.
|
|
12
|
+
- e5bdcb3: Re-check current LLM connection status before a stale missing-credentials event can keep chat locked after reconnecting Builder, and prevent page chat surfaces from rendering sidebar settings in the main content area.
|
|
13
|
+
- e5bdcb3: Allow browser Sentry initialization to build a DSN from Vite-exposed Sentry client key, project id, and ingest host env vars when runtime config injection is unavailable.
|
|
14
|
+
|
|
15
|
+
## 0.77.6
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 1fab043: Localize shared extension sidebar chrome and changelog labels/dates.
|
|
20
|
+
|
|
21
|
+
## 0.77.5
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 355be37: Add diagnostic-only worker-side progressive setup-stage diagnostics
|
|
26
|
+
(`worker_setup_step`) to localize where a durable background worker hangs between
|
|
27
|
+
`auth_passed` and `claimBackgroundRun`. For the background worker only (gated on
|
|
28
|
+
`isBackgroundWorker`, using the marker's early-available runId), emit the last
|
|
29
|
+
setup stage reached — `db_request_ctx`, `env_config`, `context_all`,
|
|
30
|
+
`action_tool_setup`, `owner_thread`, `prestart` — as the run's `diag_stage`, so a
|
|
31
|
+
worker that stalls leaves a breadcrumb at the stage it stopped in. Best-effort and
|
|
32
|
+
fire-and-forget; no control-flow change.
|
|
33
|
+
|
|
3
34
|
## 0.77.4
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.77.
|
|
3
|
+
"version": "0.77.7",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -211,8 +211,8 @@
|
|
|
211
211
|
"@react-router/dev": "^8.0.1",
|
|
212
212
|
"@react-router/fs-routes": "^8.0.1",
|
|
213
213
|
"@resvg/resvg-js": "^2.6.2",
|
|
214
|
-
"@sentry/browser": "^10.
|
|
215
|
-
"@sentry/node": "^10.
|
|
214
|
+
"@sentry/browser": "^10.61.0",
|
|
215
|
+
"@sentry/node": "^10.61.0",
|
|
216
216
|
"@standard-schema/spec": "^1.1.0",
|
|
217
217
|
"@tanstack/react-table": "^8.21.3",
|
|
218
218
|
"@tiptap/core": "3.27.1",
|
|
@@ -3934,6 +3934,22 @@ export function createProductionAgentHandler(
|
|
|
3934
3934
|
? body[AGENT_CHAT_BACKGROUND_RUN_FIELD]!
|
|
3935
3935
|
: null;
|
|
3936
3936
|
const isBackgroundWorker = backgroundRunMarker !== null;
|
|
3937
|
+
// DIAGNOSTIC-ONLY: progressive per-stage hang localizer for the bg worker.
|
|
3938
|
+
// The worker's runId is available EARLY on the marker (the general `runId`
|
|
3939
|
+
// var resolves much later), so capture it now and emit the LAST setup stage
|
|
3940
|
+
// reached as the run's `diag_stage`. Best-effort, gated on the worker, never
|
|
3941
|
+
// blocks or alters control flow.
|
|
3942
|
+
const bgRunId = isBackgroundWorker
|
|
3943
|
+
? (backgroundRunMarker?.runId as string)
|
|
3944
|
+
: null;
|
|
3945
|
+
const workerStep = (s: string) => {
|
|
3946
|
+
if (bgRunId)
|
|
3947
|
+
void recordRunDiagnostic(
|
|
3948
|
+
bgRunId,
|
|
3949
|
+
RUN_DIAG_STAGE.workerSetupStep,
|
|
3950
|
+
`${s}=${Date.now() - setupT0}ms`,
|
|
3951
|
+
).catch(() => {});
|
|
3952
|
+
};
|
|
3937
3953
|
// Whether this worker is REALLY executing inside a 15-min Netlify
|
|
3938
3954
|
// `-background` function (proven by the runtime function name), not merely a
|
|
3939
3955
|
// `_process-run` re-entry that may have landed on the ~60s synchronous
|
|
@@ -4002,6 +4018,10 @@ export function createProductionAgentHandler(
|
|
|
4002
4018
|
requestAttachments = preparedRequest.attachments;
|
|
4003
4019
|
}
|
|
4004
4020
|
}
|
|
4021
|
+
// DIAGNOSTIC-ONLY: owner/request context prep (resolveAgentOwnerEmail +
|
|
4022
|
+
// prepareRequest) finished. A worker stuck before this points at the
|
|
4023
|
+
// owner/request-context awaits.
|
|
4024
|
+
workerStep("db_request_ctx");
|
|
4005
4025
|
|
|
4006
4026
|
// Pre-upload chat attachments (images AND files/PDFs) through the framework
|
|
4007
4027
|
// file-upload provider (Builder.io by default). The model still sees the
|
|
@@ -4164,6 +4184,10 @@ export function createProductionAgentHandler(
|
|
|
4164
4184
|
}
|
|
4165
4185
|
|
|
4166
4186
|
setupMark("prepDone");
|
|
4187
|
+
// DIAGNOSTIC-ONLY: engine/model/api-key resolution finished. A worker that
|
|
4188
|
+
// reached db_request_ctx but not env_config hung in attachment upload or
|
|
4189
|
+
// engine/model resolution.
|
|
4190
|
+
workerStep("env_config");
|
|
4167
4191
|
// Run all independent pre-send steps in parallel. Each of these hits
|
|
4168
4192
|
// the DB or invokes an action; running them sequentially was the
|
|
4169
4193
|
// single biggest contributor to pre-LLM latency.
|
|
@@ -4418,6 +4442,9 @@ export function createProductionAgentHandler(
|
|
|
4418
4442
|
enrichedMessagePromise,
|
|
4419
4443
|
]);
|
|
4420
4444
|
setupMark("ctxAll");
|
|
4445
|
+
// DIAGNOSTIC-ONLY: all parallel context gathering (system prompt, screen,
|
|
4446
|
+
// files, loop settings, enriched message) resolved.
|
|
4447
|
+
workerStep("context_all");
|
|
4421
4448
|
|
|
4422
4449
|
if (systemPromptError) {
|
|
4423
4450
|
setResponseHeader(event, "Content-Type", "text/event-stream");
|
|
@@ -4446,6 +4473,8 @@ export function createProductionAgentHandler(
|
|
|
4446
4473
|
options.initialToolNames,
|
|
4447
4474
|
);
|
|
4448
4475
|
setupMark("actions");
|
|
4476
|
+
// DIAGNOSTIC-ONLY: action/tool resolution + engine-tool filtering finished.
|
|
4477
|
+
workerStep("action_tool_setup");
|
|
4449
4478
|
const requestSystemPrompt =
|
|
4450
4479
|
requestMode === "plan"
|
|
4451
4480
|
? `${systemPrompt}\n\n${PLAN_MODE_SYSTEM_PROMPT}`
|
|
@@ -4557,6 +4586,9 @@ export function createProductionAgentHandler(
|
|
|
4557
4586
|
}
|
|
4558
4587
|
}
|
|
4559
4588
|
setupMark("depsThread");
|
|
4589
|
+
// DIAGNOSTIC-ONLY: owner/thread resolution + runId/effectiveThreadId +
|
|
4590
|
+
// chained-continuation thread fetch finished.
|
|
4591
|
+
workerStep("owner_thread");
|
|
4560
4592
|
|
|
4561
4593
|
// Persist the user's turn exactly once. The foreground POST does this
|
|
4562
4594
|
// before dispatching; the background worker must NOT repeat it (it re-enters
|
|
@@ -4971,6 +5003,9 @@ export function createProductionAgentHandler(
|
|
|
4971
5003
|
// startRun's callback below — the run row does not exist until startRun
|
|
4972
5004
|
// inserts it, so a pre-startRun write would no-op on the inline path.
|
|
4973
5005
|
setupMark("preStart");
|
|
5006
|
+
// DIAGNOSTIC-ONLY: last stage before startRun fires. A worker that reaches
|
|
5007
|
+
// prestart but never workerStarted is hanging inside startRun itself.
|
|
5008
|
+
workerStep("prestart");
|
|
4974
5009
|
const setupDetail =
|
|
4975
5010
|
Object.entries(setupMarks)
|
|
4976
5011
|
.map(([k, v]) => `${k}=${v}`)
|
|
@@ -540,6 +540,8 @@ export const RUN_DIAG_STAGE = {
|
|
|
540
540
|
workerClaimLost: "worker_claim_lost",
|
|
541
541
|
/** The agent loop started (startRun fired). */
|
|
542
542
|
workerStarted: "worker_started",
|
|
543
|
+
/** Last worker setup stage reached before startRun (progressive hang localizer). */
|
|
544
|
+
workerSetupStep: "worker_setup_step",
|
|
543
545
|
/** Pre-claim setup timing breakdown (diagnostic). */
|
|
544
546
|
setupTimings: "setup_timings",
|
|
545
547
|
/** The worker threw before/while running the loop (message carried in detail). */
|
|
@@ -482,7 +482,26 @@ function normalizeAssistantToolCallIds(message: any): any {
|
|
|
482
482
|
*/
|
|
483
483
|
export function normalizeThreadRepository(repo: any): any {
|
|
484
484
|
const normalized = repo && typeof repo === "object" ? { ...repo } : {};
|
|
485
|
-
const sourceMessages = Array.isArray(repo?.messages)
|
|
485
|
+
const sourceMessages: any[] = Array.isArray(repo?.messages)
|
|
486
|
+
? repo.messages
|
|
487
|
+
: [];
|
|
488
|
+
const firstIndexById = new Map<string, number>();
|
|
489
|
+
const lastEntryById = new Map<string, any>();
|
|
490
|
+
sourceMessages.forEach((entry, index) => {
|
|
491
|
+
const id = messageId(getStoredMessage(entry));
|
|
492
|
+
if (!id) return;
|
|
493
|
+
if (!firstIndexById.has(id)) firstIndexById.set(id, index);
|
|
494
|
+
lastEntryById.set(id, entry);
|
|
495
|
+
});
|
|
496
|
+
const uniqueSourceMessages = sourceMessages
|
|
497
|
+
.filter((entry, index) => {
|
|
498
|
+
const id = messageId(getStoredMessage(entry));
|
|
499
|
+
return id && firstIndexById.get(id) === index;
|
|
500
|
+
})
|
|
501
|
+
.map((entry) => {
|
|
502
|
+
const id = messageId(getStoredMessage(entry));
|
|
503
|
+
return (id && lastEntryById.get(id)) || entry;
|
|
504
|
+
});
|
|
486
505
|
const messages: Array<{
|
|
487
506
|
message: any;
|
|
488
507
|
parentId: string | null;
|
|
@@ -491,7 +510,7 @@ export function normalizeThreadRepository(repo: any): any {
|
|
|
491
510
|
const seenIds = new Set<string>();
|
|
492
511
|
let previousId: string | null = null;
|
|
493
512
|
|
|
494
|
-
for (const entry of
|
|
513
|
+
for (const entry of uniqueSourceMessages) {
|
|
495
514
|
const message = getStoredMessage(entry);
|
|
496
515
|
const id = messageId(message);
|
|
497
516
|
if (!id) continue;
|
|
@@ -27,6 +27,10 @@ const STANDALONE_EXACT_DEPENDENCY_OVERRIDES: Record<string, string> = {
|
|
|
27
27
|
"@react-router/fs-routes": "8.0.1",
|
|
28
28
|
"react-router": "8.0.1",
|
|
29
29
|
};
|
|
30
|
+
const SENTRY_MINIMUM_RELEASE_AGE_EXCLUDES = [
|
|
31
|
+
'"@sentry/browser"',
|
|
32
|
+
'"@sentry/node"',
|
|
33
|
+
];
|
|
30
34
|
const FIRST_PARTY_TARBALL_SYMLINK_EXCLUDES = [
|
|
31
35
|
"*/CLAUDE.md",
|
|
32
36
|
"*/.claude/skills",
|
|
@@ -1054,7 +1058,12 @@ function postProcessStandalone(
|
|
|
1054
1058
|
'"@assistant-ui/tap"': '"^0.5.14"',
|
|
1055
1059
|
};
|
|
1056
1060
|
}
|
|
1057
|
-
|
|
1061
|
+
let updated = mergeWorkspaceYamlSections(existing, sections);
|
|
1062
|
+
updated = mergeWorkspaceYamlListItems(
|
|
1063
|
+
updated,
|
|
1064
|
+
"minimumReleaseAgeExclude",
|
|
1065
|
+
SENTRY_MINIMUM_RELEASE_AGE_EXCLUDES,
|
|
1066
|
+
);
|
|
1058
1067
|
if (updated !== existing) {
|
|
1059
1068
|
fs.writeFileSync(wsPath, updated);
|
|
1060
1069
|
}
|
|
@@ -1366,6 +1375,31 @@ function mergeWorkspaceYamlSections(
|
|
|
1366
1375
|
return result;
|
|
1367
1376
|
}
|
|
1368
1377
|
|
|
1378
|
+
function mergeWorkspaceYamlListItems(
|
|
1379
|
+
yaml: string,
|
|
1380
|
+
section: string,
|
|
1381
|
+
items: string[],
|
|
1382
|
+
): string {
|
|
1383
|
+
let result = yaml;
|
|
1384
|
+
for (const item of items) {
|
|
1385
|
+
const rendered = ` - ${item}`;
|
|
1386
|
+
if (result.includes(rendered)) continue;
|
|
1387
|
+
const sectionHeader = new RegExp(`^${section}:\\s*$`, "m");
|
|
1388
|
+
const match = sectionHeader.exec(result);
|
|
1389
|
+
if (match) {
|
|
1390
|
+
const insertAt = match.index + match[0].length;
|
|
1391
|
+
result =
|
|
1392
|
+
result.slice(0, insertAt) + `\n${rendered}` + result.slice(insertAt);
|
|
1393
|
+
} else {
|
|
1394
|
+
result =
|
|
1395
|
+
result.trimEnd() +
|
|
1396
|
+
(result ? "\n" : "") +
|
|
1397
|
+
`\n${section}:\n${rendered}\n`;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
return result;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1369
1403
|
/**
|
|
1370
1404
|
* Load the pnpm workspace catalog.
|
|
1371
1405
|
* First tries the build-time snapshot at dist/catalog.json (works when
|
|
@@ -795,6 +795,14 @@ or cross either artboard, remove the label and explain the transition with a
|
|
|
795
795
|
nearby annotation instead. Before handoff, inspect the top canvas at default zoom
|
|
796
796
|
and move any frame whose label, connector, or annotation crosses another frame.
|
|
797
797
|
|
|
798
|
+
**Board-unit spacing defaults.** The canvas coordinate system uses approximately 2 board units per screen pixel. \`browser\` frames occupy roughly 700 × 600 board units; \`desktop\` frames roughly 900 × 700 board units. Apply these minimum x/y gaps when placing frames explicitly — any less and frames will touch or overlap:
|
|
799
|
+
|
|
800
|
+
- x-gap between \`browser\` frames: **≥ 1100** (700-unit frame + 400-unit gutter)
|
|
801
|
+
- x-gap between \`desktop\` frames: **≥ 1300** (900-unit frame + 400-unit gutter)
|
|
802
|
+
- y-gap between rows of any surface: **≥ 1400** (includes frame height + section header + buffer)
|
|
803
|
+
|
|
804
|
+
When in doubt, use larger values — the canvas auto-zooms to fit everything.
|
|
805
|
+
|
|
798
806
|
**Canvas annotations are designer notes on the artboard.** When a top canvas is
|
|
799
807
|
present, sprinkle Figma-style notes near the frames they explain: a short
|
|
800
808
|
heading, supporting text, and bullets — plain text layers, never bordered or
|
|
@@ -164,6 +164,12 @@ const CLI_DEFAULT = "claude";
|
|
|
164
164
|
const EXEC_MODE_KEY = "agent-native-exec-mode";
|
|
165
165
|
type ExecMode = "build" | "plan";
|
|
166
166
|
type PanelMode = "chat" | "cli" | "resources" | "settings";
|
|
167
|
+
export function normalizeAgentPanelModeForSurface(
|
|
168
|
+
mode: PanelMode,
|
|
169
|
+
allowSettingsMode: boolean,
|
|
170
|
+
): PanelMode {
|
|
171
|
+
return mode === "settings" && !allowSettingsMode ? "chat" : mode;
|
|
172
|
+
}
|
|
167
173
|
const AGENT_PANEL_FONT_FAMILY =
|
|
168
174
|
'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
|
|
169
175
|
const AGENT_PANEL_ROOT_STYLE = {
|
|
@@ -377,15 +383,11 @@ export function shouldShowAgentPanelChatTabBar(
|
|
|
377
383
|
}
|
|
378
384
|
|
|
379
385
|
export function shouldShowAgentPanelPageNewChatButton(
|
|
380
|
-
|
|
386
|
+
_tabs: MultiTabAssistantChatHeaderProps["tabs"],
|
|
381
387
|
activeTabId: string,
|
|
382
|
-
|
|
388
|
+
_activeTabMessageCount: number,
|
|
383
389
|
) {
|
|
384
|
-
|
|
385
|
-
return (
|
|
386
|
-
Boolean(activeTabId) &&
|
|
387
|
-
(activeTabMessageCount > 0 || activeTab?.status === "running")
|
|
388
|
-
);
|
|
390
|
+
return Boolean(activeTabId);
|
|
389
391
|
}
|
|
390
392
|
|
|
391
393
|
export function shouldShowAgentPanelCliTabBar(cliTabs: string[]) {
|
|
@@ -548,6 +550,8 @@ export interface AgentPanelProps extends Omit<
|
|
|
548
550
|
showTabBar?: boolean;
|
|
549
551
|
/** Show a compact New chat action in page chat when the main header is hidden. */
|
|
550
552
|
showPageNewChatButton?: boolean;
|
|
553
|
+
/** Allow the sidebar settings view to render inside this panel. Default: true. */
|
|
554
|
+
allowSettingsMode?: boolean;
|
|
551
555
|
/** Capability gate for source edits and CLI access. */
|
|
552
556
|
codeAccess?: AgentPanelCodeAccess;
|
|
553
557
|
}
|
|
@@ -666,6 +670,7 @@ function AgentPanelInner({
|
|
|
666
670
|
chatNotice,
|
|
667
671
|
showTabBar = true,
|
|
668
672
|
showPageNewChatButton = false,
|
|
673
|
+
allowSettingsMode = true,
|
|
669
674
|
codeAccess,
|
|
670
675
|
...assistantChatProps
|
|
671
676
|
}: AgentPanelProps) {
|
|
@@ -715,9 +720,9 @@ function AgentPanelInner({
|
|
|
715
720
|
saved === "resources" ||
|
|
716
721
|
saved === "settings"
|
|
717
722
|
)
|
|
718
|
-
return saved;
|
|
723
|
+
return normalizeAgentPanelModeForSurface(saved, allowSettingsMode);
|
|
719
724
|
} catch {}
|
|
720
|
-
return defaultMode;
|
|
725
|
+
return normalizeAgentPanelModeForSurface(defaultMode, allowSettingsMode);
|
|
721
726
|
});
|
|
722
727
|
useEffect(() => {
|
|
723
728
|
try {
|
|
@@ -728,9 +733,18 @@ function AgentPanelInner({
|
|
|
728
733
|
section: string | null;
|
|
729
734
|
requestKey: number;
|
|
730
735
|
}>({ section: null, requestKey: 0 });
|
|
731
|
-
const switchMode = useCallback(
|
|
732
|
-
|
|
733
|
-
|
|
736
|
+
const switchMode = useCallback(
|
|
737
|
+
(m: PanelMode) => {
|
|
738
|
+
startTransition(() =>
|
|
739
|
+
setMode(normalizeAgentPanelModeForSurface(m, allowSettingsMode)),
|
|
740
|
+
);
|
|
741
|
+
},
|
|
742
|
+
[allowSettingsMode],
|
|
743
|
+
);
|
|
744
|
+
useEffect(() => {
|
|
745
|
+
const nextMode = normalizeAgentPanelModeForSurface(mode, allowSettingsMode);
|
|
746
|
+
if (nextMode !== mode) switchMode(nextMode);
|
|
747
|
+
}, [mode, allowSettingsMode, switchMode]);
|
|
734
748
|
const openRunThread = useCallback(
|
|
735
749
|
(threadId: string, run?: AgentRun) => {
|
|
736
750
|
switchMode("chat");
|
|
@@ -794,6 +808,10 @@ function AgentPanelInner({
|
|
|
794
808
|
section: section ?? null,
|
|
795
809
|
requestKey: prev.requestKey + 1,
|
|
796
810
|
}));
|
|
811
|
+
if (!allowSettingsMode) {
|
|
812
|
+
switchMode("chat");
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
797
815
|
switchMode("settings");
|
|
798
816
|
}
|
|
799
817
|
window.addEventListener(
|
|
@@ -805,7 +823,7 @@ function AgentPanelInner({
|
|
|
805
823
|
AGENT_PANEL_OPEN_SETTINGS_EVENT,
|
|
806
824
|
handleOpenSettings,
|
|
807
825
|
);
|
|
808
|
-
}, [switchMode]);
|
|
826
|
+
}, [allowSettingsMode, switchMode]);
|
|
809
827
|
|
|
810
828
|
// CLI terminal tabs (ephemeral — not persisted to SQL)
|
|
811
829
|
const [cliTabs, setCliTabs] = useState<string[]>(["cli-1"]);
|
|
@@ -1151,15 +1169,17 @@ function AgentPanelInner({
|
|
|
1151
1169
|
<DropdownMenuSeparator />
|
|
1152
1170
|
</>
|
|
1153
1171
|
)}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1172
|
+
{allowSettingsMode && (
|
|
1173
|
+
<DropdownMenuItem
|
|
1174
|
+
onSelect={() => switchMode("settings")}
|
|
1175
|
+
className={cn(
|
|
1176
|
+
mode === "settings" ? "font-medium" : "text-muted-foreground",
|
|
1177
|
+
)}
|
|
1178
|
+
>
|
|
1179
|
+
<IconSettings size={14} className="shrink-0" />
|
|
1180
|
+
{t("agentPanel.settings")}
|
|
1181
|
+
</DropdownMenuItem>
|
|
1182
|
+
)}
|
|
1163
1183
|
<DropdownMenuItem onSelect={() => setFeedbackOpen(true)}>
|
|
1164
1184
|
<IconMessageDots size={14} className="shrink-0" />
|
|
1165
1185
|
{t("agentPanel.feedback")}
|
|
@@ -1241,6 +1261,7 @@ function AgentPanelInner({
|
|
|
1241
1261
|
[
|
|
1242
1262
|
activeCliTab,
|
|
1243
1263
|
addCliTab,
|
|
1264
|
+
allowSettingsMode,
|
|
1244
1265
|
availableClis,
|
|
1245
1266
|
canUseCodeTools,
|
|
1246
1267
|
closeAllCliTabs,
|
|
@@ -1287,7 +1308,7 @@ function AgentPanelInner({
|
|
|
1287
1308
|
data-agent-page-new-chat=""
|
|
1288
1309
|
aria-label={t("agentPanel.newChat")}
|
|
1289
1310
|
onClick={() => {
|
|
1290
|
-
addTab();
|
|
1311
|
+
void addTab();
|
|
1291
1312
|
}}
|
|
1292
1313
|
className="pointer-events-auto inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background/95 px-2.5 text-xs font-medium text-foreground shadow-sm backdrop-blur transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
1293
1314
|
>
|
|
@@ -2241,9 +2262,16 @@ export interface AgentChatSurfaceProps extends AgentPanelProps {
|
|
|
2241
2262
|
|
|
2242
2263
|
export function shouldDefaultAgentChatSurfacePageNewChatButton(
|
|
2243
2264
|
mode: AgentChatSurfaceMode | undefined,
|
|
2244
|
-
|
|
2265
|
+
_showTabBar: boolean | undefined,
|
|
2245
2266
|
): boolean {
|
|
2246
|
-
return mode === "page"
|
|
2267
|
+
return mode === "page";
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
export function shouldAllowAgentChatSurfaceSettingsMode(
|
|
2271
|
+
mode: AgentChatSurfaceMode | undefined,
|
|
2272
|
+
allowSettingsMode: boolean | undefined,
|
|
2273
|
+
): boolean {
|
|
2274
|
+
return allowSettingsMode ?? mode !== "page";
|
|
2247
2275
|
}
|
|
2248
2276
|
|
|
2249
2277
|
/**
|
|
@@ -2272,6 +2300,10 @@ export function AgentChatSurface({
|
|
|
2272
2300
|
{...props}
|
|
2273
2301
|
defaultMode={defaultMode}
|
|
2274
2302
|
isFullscreen={isFullscreen ?? pageMode}
|
|
2303
|
+
allowSettingsMode={shouldAllowAgentChatSurfaceSettingsMode(
|
|
2304
|
+
mode,
|
|
2305
|
+
props.allowSettingsMode,
|
|
2306
|
+
)}
|
|
2275
2307
|
showPageNewChatButton={
|
|
2276
2308
|
showPageNewChatButton ?? defaultShowPageNewChatButton
|
|
2277
2309
|
}
|
|
@@ -428,16 +428,24 @@ function HistoryPopover({
|
|
|
428
428
|
openTabIds,
|
|
429
429
|
activeThreadId,
|
|
430
430
|
currentScope,
|
|
431
|
+
hasMoreThreads = false,
|
|
432
|
+
isLoadingMoreThreads = false,
|
|
433
|
+
loadError,
|
|
431
434
|
onSelect,
|
|
432
435
|
onClose,
|
|
436
|
+
onLoadMore,
|
|
433
437
|
onSearch,
|
|
434
438
|
}: {
|
|
435
439
|
threads: ChatThreadSummary[];
|
|
436
440
|
openTabIds: Set<string>;
|
|
437
441
|
activeThreadId: string | null;
|
|
438
442
|
currentScope?: ChatThreadScope | null;
|
|
443
|
+
hasMoreThreads?: boolean;
|
|
444
|
+
isLoadingMoreThreads?: boolean;
|
|
445
|
+
loadError?: string | null;
|
|
439
446
|
onSelect: (id: string) => void;
|
|
440
447
|
onClose: () => void;
|
|
448
|
+
onLoadMore?: () => void;
|
|
441
449
|
onSearch?: (query: string) => Promise<ChatThreadSummary[]>;
|
|
442
450
|
}) {
|
|
443
451
|
const [search, setSearch] = useState("");
|
|
@@ -542,7 +550,11 @@ function HistoryPopover({
|
|
|
542
550
|
/>
|
|
543
551
|
</div>
|
|
544
552
|
<div className="max-h-64 overflow-y-auto py-1">
|
|
545
|
-
{
|
|
553
|
+
{loadError && !search.trim() ? (
|
|
554
|
+
<div className="px-3 py-4 text-xs text-amber-500 text-center">
|
|
555
|
+
{loadError}
|
|
556
|
+
</div>
|
|
557
|
+
) : isSearching ? (
|
|
546
558
|
<div className="px-3 py-4 text-xs text-muted-foreground text-center">
|
|
547
559
|
Searching...
|
|
548
560
|
</div>
|
|
@@ -599,6 +611,16 @@ function HistoryPopover({
|
|
|
599
611
|
),
|
|
600
612
|
)
|
|
601
613
|
)}
|
|
614
|
+
{!search.trim() && hasMoreThreads && (
|
|
615
|
+
<button
|
|
616
|
+
type="button"
|
|
617
|
+
onClick={() => onLoadMore?.()}
|
|
618
|
+
disabled={isLoadingMoreThreads}
|
|
619
|
+
className="mx-1 mt-1 flex w-[calc(100%-0.5rem)] items-center justify-center rounded-md px-3 py-2 text-xs text-muted-foreground hover:bg-accent hover:text-foreground disabled:cursor-default disabled:opacity-60"
|
|
620
|
+
>
|
|
621
|
+
{isLoadingMoreThreads ? "Loading..." : "Load older chats"}
|
|
622
|
+
</button>
|
|
623
|
+
)}
|
|
602
624
|
</div>
|
|
603
625
|
</PopoverContent>
|
|
604
626
|
</Popover>
|
|
@@ -1034,7 +1056,11 @@ export function MultiTabAssistantChat({
|
|
|
1034
1056
|
saveThreadData,
|
|
1035
1057
|
generateTitle,
|
|
1036
1058
|
searchThreads,
|
|
1059
|
+
loadMoreThreads,
|
|
1037
1060
|
refreshThreads,
|
|
1061
|
+
hasMoreThreads,
|
|
1062
|
+
isLoadingMoreThreads,
|
|
1063
|
+
threadsLoadError,
|
|
1038
1064
|
isNewThread,
|
|
1039
1065
|
} = useChatThreads(apiUrl, storageKey, scope, {
|
|
1040
1066
|
restoreActiveThread,
|
|
@@ -2649,8 +2675,12 @@ export function MultiTabAssistantChat({
|
|
|
2649
2675
|
openTabIds={new Set(openTabIds)}
|
|
2650
2676
|
activeThreadId={activeThreadId}
|
|
2651
2677
|
currentScope={scope}
|
|
2678
|
+
hasMoreThreads={hasMoreThreads}
|
|
2679
|
+
isLoadingMoreThreads={isLoadingMoreThreads}
|
|
2680
|
+
loadError={threadsLoadError}
|
|
2652
2681
|
onSelect={openFromHistory}
|
|
2653
2682
|
onClose={() => setShowHistory(false)}
|
|
2683
|
+
onLoadMore={loadMoreThreads}
|
|
2654
2684
|
onSearch={searchThreads}
|
|
2655
2685
|
/>
|
|
2656
2686
|
)}
|
|
@@ -501,9 +501,12 @@ function shouldDropBrowserSentryNoise(event: Sentry.Event): boolean {
|
|
|
501
501
|
.toLowerCase();
|
|
502
502
|
return (
|
|
503
503
|
exceptionValue === "the user aborted a request." ||
|
|
504
|
+
exceptionValue === "signal is aborted without reason" ||
|
|
504
505
|
exceptionValue === "aborterror: the user aborted a request." ||
|
|
506
|
+
exceptionValue === "aborterror: signal is aborted without reason" ||
|
|
505
507
|
(exceptionType === "aborterror" &&
|
|
506
|
-
exceptionValue.includes("the user aborted a request")
|
|
508
|
+
(exceptionValue.includes("the user aborted a request") ||
|
|
509
|
+
exceptionValue.includes("signal is aborted without reason")))
|
|
507
510
|
);
|
|
508
511
|
})
|
|
509
512
|
) {
|
|
@@ -534,12 +537,31 @@ function shouldDropBrowserSentryNoise(event: Sentry.Event): boolean {
|
|
|
534
537
|
);
|
|
535
538
|
}
|
|
536
539
|
|
|
540
|
+
function firstNonEmpty(...values: Array<string | undefined>): string {
|
|
541
|
+
for (const value of values) {
|
|
542
|
+
const trimmed = value?.trim();
|
|
543
|
+
if (trimmed) return trimmed;
|
|
544
|
+
}
|
|
545
|
+
return "";
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function resolveClientSentryDsnFromKeyProject(
|
|
549
|
+
env: Record<string, string | undefined>,
|
|
550
|
+
): string | undefined {
|
|
551
|
+
const key = firstNonEmpty(env.VITE_SENTRY_CLIENT_KEY);
|
|
552
|
+
const projectId = firstNonEmpty(env.VITE_SENTRY_PROJECT_ID);
|
|
553
|
+
const host = firstNonEmpty(env.VITE_SENTRY_INGEST_HOST);
|
|
554
|
+
if (!key || !projectId || !host) return undefined;
|
|
555
|
+
return `https://${key}@${host}/${projectId}`;
|
|
556
|
+
}
|
|
557
|
+
|
|
537
558
|
function getClientSentryDsn(): string | undefined {
|
|
538
559
|
const env = (import.meta.env as Record<string, string | undefined>) ?? {};
|
|
539
560
|
return (
|
|
540
561
|
env.VITE_SENTRY_CLIENT_DSN ||
|
|
541
562
|
env.VITE_SENTRY_DSN ||
|
|
542
|
-
window.__AGENT_NATIVE_CONFIG__?.sentryDsn
|
|
563
|
+
window.__AGENT_NATIVE_CONFIG__?.sentryDsn ||
|
|
564
|
+
resolveClientSentryDsnFromKeyProject(env)
|
|
543
565
|
);
|
|
544
566
|
}
|
|
545
567
|
|