@agent-native/core 0.90.3 → 0.90.5
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/bin/agent-native.js +25 -3
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +17 -0
- package/corpus/core/bin/agent-native.js +25 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +18 -18
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +8 -2
- package/corpus/core/src/agent/engine/anthropic-engine.ts +11 -1
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +63 -2
- package/corpus/core/src/agent/production-agent.ts +22 -11
- package/corpus/core/src/agent/run-manager.ts +17 -6
- package/corpus/core/src/agent/run-store.ts +16 -11
- package/corpus/core/src/cli/create.ts +35 -0
- package/corpus/core/src/cli/design-connect.ts +263 -1
- package/corpus/core/src/cli/index.ts +84 -7
- package/corpus/core/src/cli/workspacify.ts +34 -0
- package/corpus/core/src/client/KeepTabOpenNotice.tsx +20 -15
- package/corpus/core/src/client/RunStuckBanner.tsx +14 -13
- package/corpus/core/src/client/agent-chat-adapter.ts +28 -17
- package/corpus/core/src/client/history/VersionHistoryPanel.tsx +77 -47
- package/corpus/core/src/client/history/index.ts +3 -0
- package/corpus/core/src/client/history/use-history.ts +28 -0
- package/corpus/core/src/client/index.ts +8 -0
- package/corpus/core/src/client/review/index.ts +5 -0
- package/corpus/core/src/client/review/use-review.ts +40 -2
- package/corpus/core/src/client/use-run-stuck-detection.ts +8 -5
- package/corpus/core/src/history/actions/create-resource-version.ts +11 -8
- package/corpus/core/src/history/index.ts +0 -1
- package/corpus/core/src/history/registry.ts +24 -12
- package/corpus/core/src/history/store.ts +84 -53
- package/corpus/core/src/review/actions/consume-review-feedback.ts +15 -5
- package/corpus/core/src/review/actions/delete-review-comment.ts +15 -3
- package/corpus/core/src/review/actions/resolve-review-thread.ts +12 -5
- package/corpus/core/src/review/index.ts +0 -5
- package/corpus/core/src/review/registry.ts +24 -12
- package/corpus/core/src/review/store.ts +10 -7
- package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
- package/corpus/core/src/server/credential-provider.ts +13 -3
- package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +11 -11
- package/corpus/templates/assets/actions/generate-image.ts +64 -28
- package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +91 -74
- package/corpus/templates/assets/server/lib/generation.ts +29 -4
- package/corpus/templates/assets/server/lib/image-processing.ts +131 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +24 -2
- package/corpus/templates/calendar/AGENTS.md +3 -0
- package/corpus/templates/calendar/actions/create-event.ts +8 -34
- package/corpus/templates/calendar/actions/event-action-helpers.ts +52 -0
- package/corpus/templates/calendar/actions/manage-event-draft.ts +7 -34
- package/corpus/templates/calendar/actions/update-event.ts +10 -23
- package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +47 -0
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +23 -0
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +59 -2
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +40 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +34 -1
- package/corpus/templates/calendar/app/hooks/use-events.ts +6 -0
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/calendar/app/i18n-data.ts +40 -0
- package/corpus/templates/calendar/changelog/2026-07-07-you-can-mark-event-guests-as-optional-while-inviting-them-or.md +6 -0
- package/corpus/templates/calendar/server/handlers/events.ts +1 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/calendar/shared/api.ts +2 -0
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +29 -3
- package/corpus/templates/clips/actions/generate-workflow.ts +19 -8
- package/corpus/templates/clips/actions/get-clips-ai-prefs.ts +36 -0
- package/corpus/templates/clips/actions/lib/clips-ai-prefs.ts +28 -0
- package/corpus/templates/clips/actions/regenerate-chapters.ts +21 -7
- package/corpus/templates/clips/actions/regenerate-summary.ts +26 -8
- package/corpus/templates/clips/actions/regenerate-title.ts +44 -7
- package/corpus/templates/clips/actions/update-clips-ai-prefs.ts +50 -0
- package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +7 -2
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +25 -10
- package/corpus/templates/clips/app/i18n/ar-SA.ts +28 -6
- package/corpus/templates/clips/app/i18n/de-DE.ts +28 -6
- package/corpus/templates/clips/app/i18n/en-US.ts +29 -6
- package/corpus/templates/clips/app/i18n/es-ES.ts +29 -6
- package/corpus/templates/clips/app/i18n/fr-FR.ts +30 -6
- package/corpus/templates/clips/app/i18n/hi-IN.ts +26 -6
- package/corpus/templates/clips/app/i18n/ja-JP.ts +27 -6
- package/corpus/templates/clips/app/i18n/ko-KR.ts +28 -6
- package/corpus/templates/clips/app/i18n/pt-BR.ts +28 -6
- package/corpus/templates/clips/app/i18n/zh-CN.ts +26 -6
- package/corpus/templates/clips/app/i18n/zh-TW.ts +25 -6
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +73 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -2
- package/corpus/templates/clips/changelog/2026-07-07-ai-tools-can-include-the-full-video-not-just-the-transcript-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-clips-desktop-now-surfaces-meetings-and-dictate-directly-in-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-meeting-notes-now-explain-exactly-how-to-start-granola-style.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-meeting-start-alerts-now-include-separate-start-notes-and-jo.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-07-recordings-start-more-predictably-and-newly-saved-clips-refr.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/desktop/src/app.tsx +435 -105
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +27 -21
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -22
- package/corpus/templates/clips/desktop/src/styles.css +167 -2
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -7
- package/corpus/templates/clips/desktop/src-tauri/src/tray_meetings.rs +5 -4
- package/corpus/templates/clips/server/routes/_agent-native/clips/user-prefs.put.ts +16 -8
- package/corpus/templates/clips/shared/clips-ai-prefs.ts +81 -0
- package/corpus/templates/content/AGENTS.md +1 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +73 -8
- package/corpus/templates/content/actions/_database-utils.ts +2 -1
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +20 -1
- package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +663 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +33 -7
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +53 -4
- package/corpus/templates/content/app/components/editor/database/settings.tsx +24 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +70 -1
- package/corpus/templates/content/app/hooks/use-document-properties.ts +63 -5
- package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/content/app/i18n-data.ts +31 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-source-rows-can-be-staged-in-bulk-with-a-reviewable.md +6 -0
- package/corpus/templates/content/changelog/2026-07-07-builder-backed-database-fields-now-edit-like-normal-content-fields.md +6 -0
- package/corpus/templates/content/parity/matrix.md +24 -24
- package/corpus/templates/content/parity/matrix.ts +2 -0
- package/corpus/templates/content/shared/api.ts +59 -4
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +16 -1
- package/corpus/templates/design/actions/add-localhost-screens.ts +1 -0
- package/corpus/templates/design/actions/connect-localhost.ts +26 -3
- package/corpus/templates/design/actions/open-visual-edit.ts +4 -37
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +362 -12
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +89 -14
- package/corpus/templates/design/app/components/design/bridge-security.ts +7 -1
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -1
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +41 -0
- package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-keeps-bridge-access-when-opening-previousl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-now-keeps-the-live-app-connection-authenti.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-uses-live-app-iframes-for-click-to-edit-pr.md +6 -0
- package/dist/agent/durable-background.d.ts +12 -12
- package/dist/agent/durable-background.js +18 -18
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +8 -2
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +11 -1
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +14 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +56 -2
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -11
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +7 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +6 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +15 -10
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +31 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +197 -1
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/index.js +76 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +30 -0
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/KeepTabOpenNotice.d.ts +9 -10
- package/dist/client/KeepTabOpenNotice.d.ts.map +1 -1
- package/dist/client/KeepTabOpenNotice.js +8 -4
- package/dist/client/KeepTabOpenNotice.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +14 -13
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +25 -17
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/history/VersionHistoryPanel.d.ts +1 -1
- package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -1
- package/dist/client/history/VersionHistoryPanel.js +12 -5
- package/dist/client/history/VersionHistoryPanel.js.map +1 -1
- package/dist/client/history/index.d.ts +1 -1
- package/dist/client/history/index.d.ts.map +1 -1
- package/dist/client/history/index.js +1 -1
- package/dist/client/history/index.js.map +1 -1
- package/dist/client/history/use-history.d.ts +12 -0
- package/dist/client/history/use-history.d.ts.map +1 -1
- package/dist/client/history/use-history.js +6 -0
- package/dist/client/history/use-history.js.map +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/review/index.d.ts +1 -1
- package/dist/client/review/index.d.ts.map +1 -1
- package/dist/client/review/index.js +1 -1
- package/dist/client/review/index.js.map +1 -1
- package/dist/client/review/use-review.d.ts +23 -0
- package/dist/client/review/use-review.d.ts.map +1 -1
- package/dist/client/review/use-review.js +8 -0
- package/dist/client/review/use-review.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts +1 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +6 -4
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/history/actions/create-resource-version.js +7 -4
- package/dist/history/actions/create-resource-version.js.map +1 -1
- package/dist/history/index.d.ts +1 -1
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +1 -1
- package/dist/history/index.js.map +1 -1
- package/dist/history/registry.d.ts.map +1 -1
- package/dist/history/registry.js +14 -12
- package/dist/history/registry.js.map +1 -1
- package/dist/history/store.d.ts.map +1 -1
- package/dist/history/store.js +74 -49
- package/dist/history/store.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/review/actions/consume-review-feedback.d.ts +1 -0
- package/dist/review/actions/consume-review-feedback.js +8 -2
- package/dist/review/actions/consume-review-feedback.js.map +1 -1
- package/dist/review/actions/delete-review-comment.d.ts +2 -1
- package/dist/review/actions/delete-review-comment.js +11 -3
- package/dist/review/actions/delete-review-comment.js.map +1 -1
- package/dist/review/actions/resolve-review-thread.d.ts +2 -1
- package/dist/review/actions/resolve-review-thread.js +5 -2
- package/dist/review/actions/resolve-review-thread.js.map +1 -1
- package/dist/review/index.d.ts +1 -1
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +1 -1
- package/dist/review/index.js.map +1 -1
- package/dist/review/registry.d.ts.map +1 -1
- package/dist/review/registry.js +14 -12
- package/dist/review/registry.js.map +1 -1
- package/dist/review/store.d.ts +3 -3
- package/dist/review/store.d.ts.map +1 -1
- package/dist/review/store.js +7 -4
- package/dist/review/store.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +5 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/credential-provider.d.ts +2 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +13 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/package.json +1 -1
|
@@ -999,7 +999,6 @@ async function captureTitleForRecording(params: {
|
|
|
999
999
|
}
|
|
1000
1000
|
|
|
1001
1001
|
const COUNTDOWN_EVENT_TIMEOUT_MS = 5000;
|
|
1002
|
-
const COUNTDOWN_OVERLAY_SETTLE_MS = 120;
|
|
1003
1002
|
|
|
1004
1003
|
function wait(ms: number): Promise<void> {
|
|
1005
1004
|
return new Promise((resolve) => window.setTimeout(resolve, ms));
|
|
@@ -1652,10 +1651,6 @@ async function runRecordingCountdown(wantsScreen: boolean) {
|
|
|
1652
1651
|
console.warn("[clips-recorder] countdown timed out — proceeding");
|
|
1653
1652
|
return;
|
|
1654
1653
|
}
|
|
1655
|
-
// The countdown webview emits before it finishes closing. Give macOS a
|
|
1656
|
-
// brief beat to remove the overlay and any shortcut handling before capture
|
|
1657
|
-
// starts, so the first frame/audio sample is the real recording.
|
|
1658
|
-
await wait(COUNTDOWN_OVERLAY_SETTLE_MS);
|
|
1659
1654
|
}
|
|
1660
1655
|
|
|
1661
1656
|
function showFinalizingFeedback() {
|
|
@@ -1852,29 +1847,35 @@ async function startNativeFullscreenRecording(
|
|
|
1852
1847
|
}).catch((err) => {
|
|
1853
1848
|
console.warn("[clips-recorder] mic warm failed:", err);
|
|
1854
1849
|
});
|
|
1855
|
-
const countdownPromise = runRecordingCountdown(true);
|
|
1856
1850
|
if (localOnly) {
|
|
1851
|
+
const countdownPromise = runRecordingCountdown(true);
|
|
1857
1852
|
id = localFolderName;
|
|
1858
1853
|
await Promise.all([countdownPromise, warmMic(id)]);
|
|
1859
1854
|
} else {
|
|
1860
|
-
const
|
|
1855
|
+
const captureTitlePromise = captureTitleForRecording({
|
|
1861
1856
|
mode: params.mode,
|
|
1862
1857
|
source: params.source,
|
|
1863
1858
|
});
|
|
1864
|
-
|
|
1865
|
-
const recordingPromise =
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1859
|
+
const countdownPromise = runRecordingCountdown(true);
|
|
1860
|
+
const recordingPromise = (async () => {
|
|
1861
|
+
const captureTitle = await captureTitlePromise;
|
|
1862
|
+
console.time("[clips-recorder] createServerRecording duration");
|
|
1863
|
+
try {
|
|
1864
|
+
return await createServerRecording(
|
|
1865
|
+
params.serverUrl,
|
|
1866
|
+
wantsCamera,
|
|
1867
|
+
wantsRecordedAudio,
|
|
1868
|
+
captureTitle,
|
|
1869
|
+
{
|
|
1870
|
+
mimeType: NATIVE_FULLSCREEN_MIME_TYPE,
|
|
1871
|
+
requestStreaming: true,
|
|
1872
|
+
streamingUploadClient: "desktop-native",
|
|
1873
|
+
},
|
|
1874
|
+
);
|
|
1875
|
+
} finally {
|
|
1876
|
+
console.timeEnd("[clips-recorder] createServerRecording duration");
|
|
1877
|
+
}
|
|
1878
|
+
})();
|
|
1878
1879
|
// The recording id usually lands well before the countdown ends — warm
|
|
1879
1880
|
// native capture as soon as it does so setup overlaps the 3-2-1.
|
|
1880
1881
|
const warmAndId = (async () => {
|
|
@@ -1918,6 +1919,11 @@ async function startNativeFullscreenRecording(
|
|
|
1918
1919
|
// Capture is now live — after rebasing the transcript timeline, stamp the
|
|
1919
1920
|
// timer baseline so the toolbar clock lines up with the real start.
|
|
1920
1921
|
startedAt = Date.now();
|
|
1922
|
+
emit("clips:toolbar-enabled", true).catch(() => {});
|
|
1923
|
+
emit("clips:recorder-state", {
|
|
1924
|
+
paused: false,
|
|
1925
|
+
elapsedMs: 0,
|
|
1926
|
+
}).catch(() => {});
|
|
1921
1927
|
localCameraExport?.start(2_000);
|
|
1922
1928
|
} catch (err) {
|
|
1923
1929
|
await localCameraExport?.cancel().catch(() => {});
|
|
@@ -23,9 +23,8 @@ const DEFAULT_AUTO_HIDE_MS = 30_000;
|
|
|
23
23
|
const SNOOZE_MS = 5 * 60_000;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Open a meeting join URL via the Tauri shell plugin.
|
|
27
|
-
*
|
|
28
|
-
* `meetings:start-transcription` event use the same path.
|
|
26
|
+
* Open a meeting join URL via the Tauri shell plugin. Used by the
|
|
27
|
+
* notification's dedicated Join CTA (notes start is a separate action).
|
|
29
28
|
*/
|
|
30
29
|
async function openJoinUrl(url: string | null | undefined): Promise<void> {
|
|
31
30
|
if (!url) return;
|
|
@@ -41,7 +40,7 @@ async function openJoinUrl(url: string | null | undefined): Promise<void> {
|
|
|
41
40
|
* Variants:
|
|
42
41
|
*
|
|
43
42
|
* - Calendar event: solid left bar (green), meeting title, time,
|
|
44
|
-
* "Start notes" + "Snooze 5 min" buttons.
|
|
43
|
+
* "Start notes" + optional "Join" + "Snooze 5 min" buttons.
|
|
45
44
|
* - Ad-hoc call: dashed left bar (slate), "Call detected", app name,
|
|
46
45
|
* same controls.
|
|
47
46
|
*
|
|
@@ -170,11 +169,6 @@ export function MeetingNotification() {
|
|
|
170
169
|
if (!data || pending) return;
|
|
171
170
|
setPending(true);
|
|
172
171
|
setError(null);
|
|
173
|
-
// Open the join URL right away so the user feels the click — the
|
|
174
|
-
// recording action runs in parallel.
|
|
175
|
-
if (data.joinUrl) {
|
|
176
|
-
openJoinUrl(data.joinUrl);
|
|
177
|
-
}
|
|
178
172
|
emit("meetings:start-transcription", {
|
|
179
173
|
meetingId: data.meetingId,
|
|
180
174
|
joinUrl: data.joinUrl,
|
|
@@ -185,25 +179,20 @@ export function MeetingNotification() {
|
|
|
185
179
|
});
|
|
186
180
|
}
|
|
187
181
|
|
|
182
|
+
async function joinMeeting() {
|
|
183
|
+
if (!data?.joinUrl) return;
|
|
184
|
+
await openJoinUrl(data.joinUrl);
|
|
185
|
+
}
|
|
186
|
+
|
|
188
187
|
function snooze() {
|
|
189
188
|
if (!data) return;
|
|
190
189
|
// Hand the snooze to the Rust watcher so the reminder re-fires after the
|
|
191
190
|
// delay even though this overlay window closes right away. A setTimeout
|
|
192
|
-
// here would be torn down with the window and never fire
|
|
193
|
-
// immediately (as before) just re-showed the same banner instantly.
|
|
191
|
+
// here would be torn down with the window and never fire.
|
|
194
192
|
invoke("meetings_snooze", {
|
|
195
193
|
meetingId: data.meetingId,
|
|
196
194
|
minutes: Math.round(SNOOZE_MS / 60_000),
|
|
197
195
|
}).catch(() => {});
|
|
198
|
-
const payload = data;
|
|
199
|
-
// Hide the current banner and re-fire the same payload after the snooze
|
|
200
|
-
// delay. We re-emit through Tauri so the in-app banner overlay window
|
|
201
|
-
// (which is what hosts this React component) can rerender with a fresh
|
|
202
|
-
// auto-hide timer.
|
|
203
|
-
emit("meetings:show-notification", {
|
|
204
|
-
...payload,
|
|
205
|
-
subtitle: `${payload.subtitle} (snoozed)`,
|
|
206
|
-
} as NotificationData).catch(() => {});
|
|
207
196
|
hideNotification();
|
|
208
197
|
}
|
|
209
198
|
|
|
@@ -212,6 +201,7 @@ export function MeetingNotification() {
|
|
|
212
201
|
}
|
|
213
202
|
|
|
214
203
|
const isCalendar = data.type === "calendar";
|
|
204
|
+
const hasJoin = Boolean(data.joinUrl);
|
|
215
205
|
|
|
216
206
|
return (
|
|
217
207
|
<div
|
|
@@ -227,7 +217,9 @@ export function MeetingNotification() {
|
|
|
227
217
|
scheduleAutoHide(DEFAULT_AUTO_HIDE_MS);
|
|
228
218
|
}}
|
|
229
219
|
>
|
|
230
|
-
<div
|
|
220
|
+
<div
|
|
221
|
+
className={`meeting-notification${hasJoin ? " meeting-notification-with-join" : ""}`}
|
|
222
|
+
>
|
|
231
223
|
<div
|
|
232
224
|
className={`meeting-notification-bar ${isCalendar ? "meeting-notification-bar-calendar" : "meeting-notification-bar-adhoc"}`}
|
|
233
225
|
/>
|
|
@@ -243,13 +235,22 @@ export function MeetingNotification() {
|
|
|
243
235
|
</div>
|
|
244
236
|
<div className="meeting-notification-actions">
|
|
245
237
|
<button
|
|
246
|
-
className="meeting-notification-btn"
|
|
238
|
+
className="meeting-notification-btn meeting-notification-btn-primary"
|
|
247
239
|
onClick={takeNotes}
|
|
248
240
|
disabled={pending}
|
|
249
241
|
data-no-drag
|
|
250
242
|
>
|
|
251
243
|
{pending ? "Starting…" : "Start notes"}
|
|
252
244
|
</button>
|
|
245
|
+
{hasJoin ? (
|
|
246
|
+
<button
|
|
247
|
+
className="meeting-notification-btn meeting-notification-btn-secondary"
|
|
248
|
+
onClick={joinMeeting}
|
|
249
|
+
data-no-drag
|
|
250
|
+
>
|
|
251
|
+
Join
|
|
252
|
+
</button>
|
|
253
|
+
) : null}
|
|
253
254
|
<button
|
|
254
255
|
className="meeting-notification-btn meeting-notification-btn-secondary"
|
|
255
256
|
onClick={snooze}
|
|
@@ -1096,7 +1096,7 @@ body[data-clips-route="recording-pill"] #root {
|
|
|
1096
1096
|
|
|
1097
1097
|
.bottom-row {
|
|
1098
1098
|
display: grid;
|
|
1099
|
-
grid-template-columns: repeat(
|
|
1099
|
+
grid-template-columns: repeat(4, 1fr);
|
|
1100
1100
|
gap: 4px;
|
|
1101
1101
|
}
|
|
1102
1102
|
|
|
@@ -1138,6 +1138,145 @@ body[data-clips-route="recording-pill"] #root {
|
|
|
1138
1138
|
font-weight: 500;
|
|
1139
1139
|
}
|
|
1140
1140
|
|
|
1141
|
+
/* ------------------------------------------------------------------------- */
|
|
1142
|
+
/* Popover drill-in views */
|
|
1143
|
+
/* ------------------------------------------------------------------------- */
|
|
1144
|
+
|
|
1145
|
+
.app-popover-view {
|
|
1146
|
+
gap: 0;
|
|
1147
|
+
padding: 0;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
.popover-view {
|
|
1151
|
+
min-height: 260px;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
.popover-view-header {
|
|
1155
|
+
margin-bottom: 2px;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
.popover-view-header-spacer {
|
|
1159
|
+
flex: 1;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
.popover-view-link {
|
|
1163
|
+
font-size: 11px;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.popover-empty-card {
|
|
1167
|
+
display: flex;
|
|
1168
|
+
flex-direction: column;
|
|
1169
|
+
gap: 8px;
|
|
1170
|
+
padding: 12px;
|
|
1171
|
+
border: 1px solid var(--border);
|
|
1172
|
+
border-radius: var(--radius);
|
|
1173
|
+
background: var(--surface);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.popover-empty-card strong {
|
|
1177
|
+
font-size: 13px;
|
|
1178
|
+
color: var(--fg);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
.popover-card-heading {
|
|
1182
|
+
display: flex;
|
|
1183
|
+
align-items: center;
|
|
1184
|
+
gap: 8px;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
.popover-list {
|
|
1188
|
+
display: flex;
|
|
1189
|
+
flex-direction: column;
|
|
1190
|
+
gap: 6px;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
.popover-list-item {
|
|
1194
|
+
display: flex;
|
|
1195
|
+
align-items: center;
|
|
1196
|
+
gap: 9px;
|
|
1197
|
+
padding: 9px;
|
|
1198
|
+
border: 1px solid var(--border);
|
|
1199
|
+
border-radius: var(--radius);
|
|
1200
|
+
background: var(--surface);
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
.popover-list-icon {
|
|
1204
|
+
display: inline-flex;
|
|
1205
|
+
align-items: center;
|
|
1206
|
+
justify-content: center;
|
|
1207
|
+
color: var(--fg-muted);
|
|
1208
|
+
flex-shrink: 0;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
.popover-list-main {
|
|
1212
|
+
flex: 1;
|
|
1213
|
+
min-width: 0;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
.popover-list-title {
|
|
1217
|
+
font-size: 12px;
|
|
1218
|
+
font-weight: 600;
|
|
1219
|
+
color: var(--fg);
|
|
1220
|
+
white-space: nowrap;
|
|
1221
|
+
overflow: hidden;
|
|
1222
|
+
text-overflow: ellipsis;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.popover-list-sub {
|
|
1226
|
+
margin-top: 1px;
|
|
1227
|
+
font-size: 11px;
|
|
1228
|
+
color: var(--fg-subtle);
|
|
1229
|
+
white-space: nowrap;
|
|
1230
|
+
overflow: hidden;
|
|
1231
|
+
text-overflow: ellipsis;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
.popover-list-action {
|
|
1235
|
+
flex-shrink: 0;
|
|
1236
|
+
border: 1px solid var(--border-strong);
|
|
1237
|
+
border-radius: var(--radius-sm);
|
|
1238
|
+
background: var(--bg);
|
|
1239
|
+
color: var(--fg);
|
|
1240
|
+
padding: 6px 8px;
|
|
1241
|
+
font-size: 11px;
|
|
1242
|
+
font-weight: 600;
|
|
1243
|
+
cursor: pointer;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
.popover-list-action:hover {
|
|
1247
|
+
background: var(--surface-hover);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
.popover-list-action-primary {
|
|
1251
|
+
border-color: var(--brand);
|
|
1252
|
+
background: var(--brand);
|
|
1253
|
+
color: var(--bg);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
.popover-list-action-primary:hover {
|
|
1257
|
+
background: var(--brand-hover);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
.popover-kv {
|
|
1261
|
+
display: flex;
|
|
1262
|
+
align-items: center;
|
|
1263
|
+
justify-content: space-between;
|
|
1264
|
+
gap: 12px;
|
|
1265
|
+
padding-top: 6px;
|
|
1266
|
+
border-top: 1px solid var(--border);
|
|
1267
|
+
font-size: 11px;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
.popover-kv span {
|
|
1271
|
+
color: var(--fg-subtle);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
.popover-kv strong {
|
|
1275
|
+
min-width: 0;
|
|
1276
|
+
text-align: right;
|
|
1277
|
+
font-size: 11px;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1141
1280
|
.badge {
|
|
1142
1281
|
position: absolute;
|
|
1143
1282
|
top: -4px;
|
|
@@ -3468,7 +3607,19 @@ body[data-clips-route="recording-pill"] #root {
|
|
|
3468
3607
|
color: white;
|
|
3469
3608
|
pointer-events: auto;
|
|
3470
3609
|
min-width: 280px;
|
|
3471
|
-
max-width:
|
|
3610
|
+
max-width: 400px;
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
.meeting-notification-with-join {
|
|
3614
|
+
flex-wrap: wrap;
|
|
3615
|
+
align-items: flex-start;
|
|
3616
|
+
row-gap: 10px;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
.meeting-notification-with-join .meeting-notification-actions {
|
|
3620
|
+
flex: 1 1 100%;
|
|
3621
|
+
justify-content: flex-end;
|
|
3622
|
+
padding-left: 13px; /* align under content past the bar */
|
|
3472
3623
|
}
|
|
3473
3624
|
|
|
3474
3625
|
.meeting-notification-bar {
|
|
@@ -3536,6 +3687,20 @@ body[data-clips-route="recording-pill"] #root {
|
|
|
3536
3687
|
cursor: progress;
|
|
3537
3688
|
}
|
|
3538
3689
|
|
|
3690
|
+
.meeting-notification-btn-primary {
|
|
3691
|
+
background: #ffffff;
|
|
3692
|
+
color: #111827;
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
.meeting-notification-btn-primary:hover {
|
|
3696
|
+
background: #f3f4f6;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
.meeting-notification-btn-primary:disabled {
|
|
3700
|
+
background: rgba(255, 255, 255, 0.7);
|
|
3701
|
+
color: #374151;
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3539
3704
|
.meeting-notification-actions {
|
|
3540
3705
|
display: inline-flex;
|
|
3541
3706
|
align-items: center;
|
|
@@ -648,7 +648,7 @@ pub async fn native_fullscreen_recording_available() -> Result<bool, String> {
|
|
|
648
648
|
/// the countdown by now; this is just a safety net so a slow/denied mic can't
|
|
649
649
|
/// stall the start.
|
|
650
650
|
#[cfg(target_os = "macos")]
|
|
651
|
-
const MIC_WARM_TIMEOUT_MS: u64 =
|
|
651
|
+
const MIC_WARM_TIMEOUT_MS: u64 = 250;
|
|
652
652
|
|
|
653
653
|
/// Acquire a backend (ScreenCaptureKit, or the screencapture fallback) and
|
|
654
654
|
/// store it as the active session. Shared by the immediate-start command and
|
|
@@ -16,8 +16,8 @@ use crate::util::{
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const MEETING_NOTIFICATION_LABEL: &str = "meeting-notif";
|
|
19
|
-
const NOTIFICATION_W_LOGICAL: u32 =
|
|
20
|
-
const NOTIFICATION_H_LOGICAL: u32 =
|
|
19
|
+
const NOTIFICATION_W_LOGICAL: u32 = 420;
|
|
20
|
+
const NOTIFICATION_H_LOGICAL: u32 = 148;
|
|
21
21
|
const NOTIFICATION_TOP_MARGIN_LOGICAL: u32 = 44;
|
|
22
22
|
const NOTIFICATION_RIGHT_MARGIN_LOGICAL: u32 = 24;
|
|
23
23
|
|
|
@@ -125,11 +125,7 @@ pub async fn notify_meeting_starting(
|
|
|
125
125
|
} else {
|
|
126
126
|
format!("in {} min", (starts_in_secs / 60).max(1))
|
|
127
127
|
};
|
|
128
|
-
let body =
|
|
129
|
-
format!("{} — Start notes", pretty_in)
|
|
130
|
-
} else {
|
|
131
|
-
format!("Starts {}", pretty_in)
|
|
132
|
-
};
|
|
128
|
+
let body = format!("Starts {}", pretty_in);
|
|
133
129
|
dlog!(
|
|
134
130
|
"[clips-tray] notify_meeting_starting id={} title={} body={}",
|
|
135
131
|
meeting_id,
|
|
@@ -25,21 +25,22 @@ pub struct MeetingItem {
|
|
|
25
25
|
|
|
26
26
|
pub const MEETING_ID_PREFIX: &str = "meeting:";
|
|
27
27
|
|
|
28
|
-
/// Build the "
|
|
28
|
+
/// Build the "Start Meeting Notes" submenu populated with up to 3 events. If
|
|
29
29
|
/// the list is empty, returns a submenu containing a single disabled "No
|
|
30
|
-
///
|
|
30
|
+
/// meetings ready" item — keeps the menu structure stable. Selecting a real
|
|
31
|
+
/// meeting starts live notes immediately.
|
|
31
32
|
pub fn build_meetings_section(
|
|
32
33
|
app: &AppHandle,
|
|
33
34
|
upcoming: Vec<MeetingItem>,
|
|
34
35
|
) -> Result<Submenu<Wry>, Box<dyn std::error::Error>> {
|
|
35
36
|
let mut builder: SubmenuBuilder<'_, Wry, AppHandle> =
|
|
36
|
-
SubmenuBuilder::new(app, "
|
|
37
|
+
SubmenuBuilder::new(app, "Start Meeting Notes");
|
|
37
38
|
|
|
38
39
|
if upcoming.is_empty() {
|
|
39
40
|
let placeholder = MenuItem::with_id(
|
|
40
41
|
app,
|
|
41
42
|
"meeting:none",
|
|
42
|
-
"No
|
|
43
|
+
"No meetings ready",
|
|
43
44
|
false,
|
|
44
45
|
None::<&str>,
|
|
45
46
|
)?;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSession } from "@agent-native/core/server";
|
|
2
|
-
import { putUserSetting } from "@agent-native/core/settings";
|
|
2
|
+
import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
|
|
3
3
|
import { defineEventHandler, getHeader, readBody, setResponseStatus } from "h3";
|
|
4
4
|
|
|
5
5
|
const CLIPS_USER_PREFS_KEY = "clips-user-prefs";
|
|
@@ -17,11 +17,19 @@ export default defineEventHandler(async (event) => {
|
|
|
17
17
|
return { error: "Invalid settings payload" };
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
// Merge so partial Settings saves (playback, notifications, …) don't wipe
|
|
21
|
+
// AI-tool prefs written from the recording page popover.
|
|
22
|
+
const existing =
|
|
23
|
+
(await getUserSetting(session.email, CLIPS_USER_PREFS_KEY)) ?? {};
|
|
24
|
+
const next = {
|
|
25
|
+
...(typeof existing === "object" && existing && !Array.isArray(existing)
|
|
26
|
+
? existing
|
|
27
|
+
: {}),
|
|
28
|
+
...(body as Record<string, unknown>),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
await putUserSetting(session.email, CLIPS_USER_PREFS_KEY, next, {
|
|
32
|
+
requestSource: getHeader(event, "x-request-source") || undefined,
|
|
33
|
+
});
|
|
34
|
+
return next;
|
|
27
35
|
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clips user preferences that affect AI video tools.
|
|
3
|
+
*
|
|
4
|
+
* Stored under the shared `clips-user-prefs` user-setting key so Settings and
|
|
5
|
+
* the AI tools popover both read/write the same object.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const CLIPS_USER_PREFS_KEY = "clips-user-prefs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Preferred chat model when Include full video is on. Full-recording video
|
|
12
|
+
* input only works with Gemini (Builder Gemini or Google/Gemini BYOK) —
|
|
13
|
+
* Claude and OpenAI cannot ingest the MP4/WebM.
|
|
14
|
+
*/
|
|
15
|
+
export const CLIPS_FULL_VIDEO_AI_ENGINE = "builder";
|
|
16
|
+
export const CLIPS_FULL_VIDEO_AI_MODEL = "gemini-3-5-flash";
|
|
17
|
+
|
|
18
|
+
export type ClipsAiPrefs = {
|
|
19
|
+
/**
|
|
20
|
+
* When true, Clips AI tools (default title/description, regenerate title/
|
|
21
|
+
* description/chapters, workflows) must watch the full recording — not just
|
|
22
|
+
* the transcript — before writing results. Off by default for cost/latency.
|
|
23
|
+
* Sending the full video requires a Gemini model.
|
|
24
|
+
*/
|
|
25
|
+
includeFullVideoInAi?: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type ClipsUserPrefs = ClipsAiPrefs & {
|
|
29
|
+
defaultPlaybackSpeed?: string;
|
|
30
|
+
emailNotifications?: boolean;
|
|
31
|
+
displayName?: string;
|
|
32
|
+
transcriptCleanupEnabled?: boolean;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function isIncludeFullVideoInAiEnabled(
|
|
36
|
+
prefs: ClipsAiPrefs | Record<string, unknown> | null | undefined,
|
|
37
|
+
): boolean {
|
|
38
|
+
return prefs?.includeFullVideoInAi === true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Extra agent instructions when the user wants AI tools to watch the clip,
|
|
43
|
+
* not just read the audio transcript. Full-video understanding requires Gemini.
|
|
44
|
+
*/
|
|
45
|
+
export function buildFullVideoAiInstructions(recordingId: string): string {
|
|
46
|
+
return (
|
|
47
|
+
`The user enabled "Include full video" for Clips AI. Do NOT rely on the ` +
|
|
48
|
+
`transcript alone — audio is often incomplete for accurate titles, ` +
|
|
49
|
+
`descriptions, chapters, and workflow docs. ` +
|
|
50
|
+
`IMPORTANT: sending / understanding the full recording only works with ` +
|
|
51
|
+
`Gemini (Builder Gemini or a Google Gemini key). Use a Gemini model for ` +
|
|
52
|
+
`this turn — Claude and OpenAI cannot ingest the full video file. ` +
|
|
53
|
+
`Prefer attaching or uploading the recording video itself to Gemini when ` +
|
|
54
|
+
`available. Otherwise use \`get-recording-player-data --recordingId=${recordingId}\` ` +
|
|
55
|
+
`(preferred in-app) or \`create-recording-agent-link --recordingId=${recordingId}\` ` +
|
|
56
|
+
`and fetch that context URL, then sample the timeline via recommendedFrames / ` +
|
|
57
|
+
`the frame API. Combine on-screen UI text, product names, and visual context ` +
|
|
58
|
+
`with any transcript. If the transcript is thin or missing, lean harder on ` +
|
|
59
|
+
`the video.`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function withFullVideoAiInstructions(
|
|
64
|
+
message: string,
|
|
65
|
+
recordingId: string,
|
|
66
|
+
includeFullVideo: boolean,
|
|
67
|
+
): string {
|
|
68
|
+
if (!includeFullVideo) return message;
|
|
69
|
+
return `${message} ${buildFullVideoAiInstructions(recordingId)}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Model selection for sendToAgentChat when Include full video is enabled. */
|
|
73
|
+
export function fullVideoAiModelSelection(): {
|
|
74
|
+
engine: string;
|
|
75
|
+
model: string;
|
|
76
|
+
} {
|
|
77
|
+
return {
|
|
78
|
+
engine: CLIPS_FULL_VIDEO_AI_ENGINE,
|
|
79
|
+
model: CLIPS_FULL_VIDEO_AI_MODEL,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -121,6 +121,7 @@ cd templates/content && pnpm action <name> [args]
|
|
|
121
121
|
| `set-content-database-source-write-mode` | `--databaseId <id>` or `--documentId <id> --liveWritesEnabled true\|false [--allowedWriteModes <json>]` | Enable/disable per-source Builder live writes; enabling is allowed only for `agent-native-blog-article-test` with explicit modes |
|
|
122
122
|
| `stage-builder-revision` | `--databaseId <id>` or `--documentId <id>` | Stage pending local Builder CMS changes as a local-only save-revision record; never calls Builder |
|
|
123
123
|
| `review-content-database-source-change-set` | `--databaseId <id>` or `--documentId <id> --changeSetId <id> --decision approve\|reject [--note]` | Approve or reject a local source change-set review record without provider writes |
|
|
124
|
+
| `stage-builder-source-bulk-update` | `--databaseId <id>` or `--documentId <id> --itemIds <json-array>` or `--documentIds <json-array> --field <json> [--sourceId <id>] [--dryRun true\|false]` | Preview or stage one bounded field update across selected source-backed Builder rows; apply still goes through Builder review/execution |
|
|
124
125
|
| `prepare-builder-source-execution` | `--databaseId <id>` or `--documentId <id> --changeSetId <id> [--pushModeConfirmation autosave\|draft\|publish]` | Prepare a dry-run Builder execution gate for approved field/body changes with request semantics/idempotency key; never calls Builder |
|
|
125
126
|
| `validate-builder-source-execution` | `--databaseId <id>` or `--documentId <id> --changeSetId <id> [--idempotencyKey <key>]` | Validate/replay a prepared Builder execution gate locally as a dry run; never calls Builder |
|
|
126
127
|
| `execute-builder-source-execution` | `--databaseId <id>` or `--documentId <id> --changeSetId <id> [--idempotencyKey <key>] [--pushModeConfirmation autosave\|draft\|publish]` | Execute a guarded live Builder write only when approved, validated, enabled, idempotent, and targeting `agent-native-blog-article-test` |
|