@agent-native/core 0.149.5 → 0.151.0
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/templates/analytics/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +83 -45
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-dashboards-keep-the-selected-tab-when-reopened.md +6 -0
- package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/clips/changelog/2026-08-11-clips-recovers-from-transient-updates-and-avoids-macos-priva.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +32 -176
- package/corpus/templates/clips/desktop/src/lib/updater.ts +52 -37
- package/corpus/templates/clips/desktop/src/styles.css +1 -166
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +2 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +4 -0
- package/corpus/templates/clips/desktop/src-tauri/src/eventkit.rs +28 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +48 -1
- package/corpus/templates/clips/desktop/src-tauri/src/permission_status.rs +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +5 -0
- package/corpus/templates/clips/server/plugins/auth.ts +3 -0
- package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/content/actions/_document-discovery-query.ts +127 -0
- package/corpus/templates/content/actions/list-documents.ts +189 -198
- package/corpus/templates/content/actions/search-documents.ts +95 -24
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +2 -1
- package/corpus/templates/content/app/hooks/use-documents.ts +84 -6
- package/corpus/templates/content/shared/api.ts +10 -0
- package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -1
- package/corpus/templates/design/changelog/2026-08-11-design-agent-prompts-copy-successfully-in-the-desktop-app.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/dispatch/app/global.css +2 -2
- package/corpus/templates/dispatch/changelog/2026-08-10-desktop-workspace-sign-in.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-no-longer-shows-the-generic-chat-starter-among-defa.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-integrations-and-scheduled-work-open-as-first-class-electron-pages.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-sidebar-text-is-slightly-easier-to-read-in-light-and-dark-mo.md +6 -0
- package/corpus/templates/dispatch/server/lib/identity-sso.ts +57 -31
- package/corpus/templates/dispatch/server/plugins/feature-flags.ts +5 -0
- package/corpus/templates/dispatch/server/plugins/identity-sso.ts +82 -33
- package/corpus/templates/dispatch/server/plugins/org-apps-directory.ts +7 -15
- package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +9 -1
- package/corpus/templates/dispatch/shared/feature-flags.ts +15 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/forms/.agents/skills/form-responses/SKILL.md +8 -7
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/forms/app/hooks/use-forms.ts +8 -1
- package/corpus/templates/forms/changelog/2026-08-11-fixed-public-forms-so-conditional-questions-stay-hidden-unti.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +2 -1
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +37 -2
- package/corpus/templates/forms/shared/page-url.ts +54 -0
- package/corpus/templates/forms/shared/types.ts +4 -4
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +5 -0
- package/corpus/templates/slides/actions/add-slide.ts +0 -27
- package/corpus/templates/slides/actions/import-file.ts +28 -9
- package/corpus/templates/slides/actions/view-screen.ts +4 -4
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +8 -1
- package/corpus/templates/slides/app/components/editor/AiEditingMarker.tsx +25 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +43 -48
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +9 -6
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -9
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +2 -0
- package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +0 -26
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +904 -217
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +11 -0
- package/corpus/templates/slides/app/components/editor/inline-edit-session.ts +16 -0
- package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +22 -6
- package/corpus/templates/slides/app/components/editor/style-clipboard.ts +61 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +26 -2
- package/corpus/templates/slides/app/components/ui/context-menu.tsx +1 -0
- package/corpus/templates/slides/app/context/DeckContext.tsx +75 -25
- package/corpus/templates/slides/app/global.css +1 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +6 -1
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -1
- package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +12 -12
- package/corpus/templates/slides/app/lib/slide-agent-context.ts +52 -0
- package/corpus/templates/slides/app/lib/slide-image-replacement.ts +61 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +55 -116
- package/corpus/templates/slides/app/pages/Index.tsx +28 -3
- package/corpus/templates/slides/changelog/2026-08-11-agent-chat-now-follows-the-current-slide-and-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-deck-titles-now-use-slide-content-instead-of-placeholder-filenames.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-history-now-opens-from-the-deck-overflow-menu.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-images-can-be-dropped-directly-onto-slides-and-resized-or-re.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-new-decks-now-transition-directly-to-a-full-page-editor-load.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-selected-slide-layers-can-be-nudged-precisely-with-arrow-key.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-can-copy-and-paste-element-styles-with-cmd-option-c-v.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-shows-one-compact-ai-marker-and-keeps-your-current-sl.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-text-edits-preserve-slide-layout-when-no-changes-are-made.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-the-style-toolbar-now-uses-the-full-available-width.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-undo-and-redo-now-move-one-visible-slide-state-at-a-time.md +6 -0
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -2
- package/corpus/templates/slides/shared/deck-title.ts +56 -0
- package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +5 -0
- package/dist/agent/run-store.js +6 -1
- package/dist/agent/thread-data-builder.js +19 -44
- package/dist/agent/types.d.ts +13 -0
- package/dist/catalog.json +1 -0
- package/dist/cli/create.js +1 -1
- package/dist/client/AssistantChat.js +58 -10
- package/dist/client/FileStorageSetupCard.d.ts +6 -0
- package/dist/client/FileStorageSetupCard.js +18 -0
- package/dist/client/NewWorkspaceAppFlow.js +10 -0
- package/dist/client/agent-chat-adapter.js +87 -11
- package/dist/client/agent-chat.d.ts +1 -1
- package/dist/client/agent-chat.js +8 -3
- package/dist/client/chat/attachment-adapters.js +10 -0
- package/dist/client/chat/message-components.d.ts +4 -1
- package/dist/client/chat/message-components.js +37 -13
- package/dist/client/chat/tool-call-display.js +14 -0
- package/dist/client/chat-first/apps-rail.d.ts +1 -1
- package/dist/client/chat-first/apps-rail.js +6 -6
- package/dist/client/chat-first/copy.js +1 -0
- package/dist/client/chat-first/types.d.ts +1 -0
- package/dist/client/extensions/EmbeddedExtension.js +1 -1
- package/dist/client/extensions/ExtensionViewer.js +1 -1
- package/dist/client/extensions/InlineExtensionFrame.js +1 -1
- package/dist/client/onboarding/FirstRunOnboarding.js +17 -2
- package/dist/client/settings/FileStorageSettingsForm.d.ts +2 -0
- package/dist/client/settings/FileStorageSettingsForm.js +113 -0
- package/dist/client/settings/SettingsPanel.js +2 -1
- package/dist/client/sse-event-processor.js +21 -0
- package/dist/extensions/actions.js +2 -2
- package/dist/extensions/html-shell.js +3 -1
- package/dist/file-upload/pre-upload-attachments.d.ts +15 -10
- package/dist/file-upload/pre-upload-attachments.js +68 -24
- package/dist/file-upload/registry.d.ts +4 -5
- package/dist/file-upload/registry.js +7 -14
- package/dist/file-upload/s3.d.ts +9 -0
- package/dist/file-upload/s3.js +168 -0
- package/dist/file-upload/types.d.ts +3 -3
- package/dist/file-upload/types.js +2 -2
- package/dist/onboarding/app-profile.js +23 -1
- package/dist/onboarding/default-steps.js +69 -0
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/browser-team-tools.js +20 -0
- package/dist/server/agent-chat-plugin.js +12 -3
- package/dist/server/auth.js +45 -21
- package/dist/server/better-auth-instance.d.ts +2 -0
- package/dist/server/better-auth-instance.js +2 -2
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.js +26 -16
- package/dist/server/identity-sso-store.d.ts +3 -0
- package/dist/server/identity-sso-store.js +45 -0
- package/dist/server/identity-sso.d.ts +20 -10
- package/dist/server/identity-sso.js +79 -31
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +24 -1
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -2
- package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +3 -1
- package/docs/content/authentication.mdx +27 -0
- package/docs/content/cross-app-sso.mdx +38 -8
- package/docs/content/extensions.mdx +15 -15
- package/docs/content/file-uploads.mdx +10 -12
- package/docs/content/generative-ui.mdx +6 -1
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +24 -1
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -2
- package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +1 -1
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +3 -1
|
@@ -144,7 +144,7 @@ pub(crate) mod macos {
|
|
|
144
144
|
kAudioObjectPropertyElementMain, kAudioObjectPropertyScopeGlobal, kAudioObjectSystemObject,
|
|
145
145
|
AudioObjectGetPropertyData, AudioObjectID, AudioObjectPropertyAddress,
|
|
146
146
|
};
|
|
147
|
-
use objc2_foundation::{NSArray, NSError, NSLocale, NSString};
|
|
147
|
+
use objc2_foundation::{NSArray, NSBundle, NSError, NSLocale, NSString};
|
|
148
148
|
use objc2_speech::{
|
|
149
149
|
SFSpeechAudioBufferRecognitionRequest, SFSpeechRecognitionResult, SFSpeechRecognitionTask,
|
|
150
150
|
SFSpeechRecognizer, SFSpeechRecognizerAuthorizationStatus,
|
|
@@ -154,6 +154,29 @@ pub(crate) mod macos {
|
|
|
154
154
|
|
|
155
155
|
use screencapturekit::audio_devices::AudioInputDevice;
|
|
156
156
|
|
|
157
|
+
const SPEECH_USAGE_DESCRIPTION_KEY: &str = "NSSpeechRecognitionUsageDescription";
|
|
158
|
+
const SPEECH_USAGE_DESCRIPTION_ERROR: &str =
|
|
159
|
+
"Clips cannot start macOS speech recognition because the app bundle is missing NSSpeechRecognitionUsageDescription.";
|
|
160
|
+
|
|
161
|
+
pub(crate) fn has_speech_usage_description() -> bool {
|
|
162
|
+
let bundle = NSBundle::mainBundle();
|
|
163
|
+
let Some(info) = bundle.infoDictionary() else {
|
|
164
|
+
return false;
|
|
165
|
+
};
|
|
166
|
+
let key = NSString::from_str(SPEECH_USAGE_DESCRIPTION_KEY);
|
|
167
|
+
info.objectForKey(&*key)
|
|
168
|
+
.and_then(|value| value.downcast::<NSString>().ok())
|
|
169
|
+
.is_some_and(|value| !value.is_empty())
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fn ensure_speech_usage_description() -> Result<(), String> {
|
|
173
|
+
if has_speech_usage_description() {
|
|
174
|
+
Ok(())
|
|
175
|
+
} else {
|
|
176
|
+
Err(SPEECH_USAGE_DESCRIPTION_ERROR.into())
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
157
180
|
/// Who owns an in-flight `SpeechSession`. Meetings fall back to this
|
|
158
181
|
/// mic-only engine when whisper fails; a Fn/dictation press must not be
|
|
159
182
|
/// able to silently kill a meeting's live capture (D10). Priority rule:
|
|
@@ -416,6 +439,11 @@ pub(crate) mod macos {
|
|
|
416
439
|
/// system has an answer. The handler itself only sends a value on a
|
|
417
440
|
/// channel; no ObjC interop, no UI work.
|
|
418
441
|
fn ensure_authorized() -> Result<(), String> {
|
|
442
|
+
// macOS aborts the process, rather than returning an error, when
|
|
443
|
+
// Speech.framework is touched without this usage description. This
|
|
444
|
+
// guard keeps `tauri dev` and malformed bundles recoverable.
|
|
445
|
+
ensure_speech_usage_description()?;
|
|
446
|
+
|
|
419
447
|
// Fast path: already known.
|
|
420
448
|
let current = unsafe { SFSpeechRecognizer::authorizationStatus() };
|
|
421
449
|
if current == SFSpeechRecognizerAuthorizationStatus::Authorized {
|
|
@@ -1548,6 +1576,20 @@ pub(crate) mod macos {
|
|
|
1548
1576
|
Ok(())
|
|
1549
1577
|
}
|
|
1550
1578
|
|
|
1579
|
+
pub fn shutdown() {
|
|
1580
|
+
let session = match session_slot().lock() {
|
|
1581
|
+
Ok(mut slot) => slot.take(),
|
|
1582
|
+
Err(poisoned) => poisoned.into_inner().take(),
|
|
1583
|
+
};
|
|
1584
|
+
if let Some(session) = session {
|
|
1585
|
+
session.cancelled.store(true, Ordering::SeqCst);
|
|
1586
|
+
session.stopped.store(true, Ordering::SeqCst);
|
|
1587
|
+
unsafe { session.task.cancel() };
|
|
1588
|
+
stop_engine_and_remove_tap(&session);
|
|
1589
|
+
}
|
|
1590
|
+
clear_warmed_raw_mic_engine();
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1551
1593
|
#[cfg(test)]
|
|
1552
1594
|
mod tests {
|
|
1553
1595
|
use super::{native_speech_voice_processing_mode, MicVoiceProcessingMode, SessionOwner};
|
|
@@ -1569,3 +1611,8 @@ pub(crate) mod macos {
|
|
|
1569
1611
|
}
|
|
1570
1612
|
}
|
|
1571
1613
|
}
|
|
1614
|
+
|
|
1615
|
+
pub fn shutdown() {
|
|
1616
|
+
#[cfg(target_os = "macos")]
|
|
1617
|
+
macos::shutdown();
|
|
1618
|
+
}
|
|
@@ -123,6 +123,11 @@ pub async fn whisper_transcription_stop(app: AppHandle) -> Result<(), String> {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
pub fn shutdown(app: &AppHandle) {
|
|
127
|
+
#[cfg(target_os = "macos")]
|
|
128
|
+
macos::stop(app);
|
|
129
|
+
}
|
|
130
|
+
|
|
126
131
|
#[tauri::command]
|
|
127
132
|
pub async fn whisper_transcription_reset_timeline() -> Result<(), String> {
|
|
128
133
|
#[cfg(target_os = "macos")]
|
|
@@ -5,6 +5,9 @@ import { PRERENDERED_PUBLIC_PAGE_PATHS } from "../../shared/prerendered-public-p
|
|
|
5
5
|
// Clips has public share pages, embeds, and view-event tracking that must
|
|
6
6
|
// reach unauthenticated viewers. Everything else sits behind auth.
|
|
7
7
|
export default createAuthPlugin({
|
|
8
|
+
// Keep the native tray token and the Better Auth cookie useful between
|
|
9
|
+
// infrequent recording sessions without making them permanent.
|
|
10
|
+
maxAge: 60 * 60 * 24 * 90,
|
|
8
11
|
// Clips owns `/_agent-native/google/*` so the same registered Google
|
|
9
12
|
// callback can handle both normal sign-in and the Calendar connect flow.
|
|
10
13
|
mountGoogleOAuthRoutes: false,
|
|
@@ -49,6 +49,34 @@ sendToAgentChat({
|
|
|
49
49
|
});
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Keep user text separate from injected context
|
|
53
|
+
|
|
54
|
+
Treat the visible `message` as the user's request or the shortest clear
|
|
55
|
+
description of an app-initiated operation. Put context the user did not type —
|
|
56
|
+
IDs, URLs, filenames, current selection or screen state, serialized records,
|
|
57
|
+
upload instructions, and bounded source excerpts — in the `context` field.
|
|
58
|
+
`context` is model input carried through the agent turn; it is stripped from
|
|
59
|
+
the rendered user message, so do not concatenate it into `message` with labels,
|
|
60
|
+
blank-line sections, or `<context>` tags yourself.
|
|
61
|
+
|
|
62
|
+
Use the related surface for each kind of supporting input:
|
|
63
|
+
|
|
64
|
+
| Surface | Use for |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `message` | User-authored intent or a concise app action description |
|
|
67
|
+
| `context` | Derived metadata and bounded text needed to carry out that intent |
|
|
68
|
+
| `setAgentChatContextItem` | Context staged for a later user-submitted prompt; keep it keyed so updates replace stale context |
|
|
69
|
+
| `images`, `referenceImagePaths`, attachments | Binary or visual inputs; describe only the handling instructions in `context` |
|
|
70
|
+
|
|
71
|
+
If an app builds a prompt from a form, selection, upload, or editor state, keep
|
|
72
|
+
the visible message short and pass the assembled details as `context`. Preserve
|
|
73
|
+
the user's actual freeform text in `message` when it is the request; do not
|
|
74
|
+
restate it as metadata in `context` unless the agent needs a structured copy.
|
|
75
|
+
|
|
76
|
+
This boundary applies to auto-submitted turns and prefills. A hidden context
|
|
77
|
+
field is not a license to send unbounded records or secrets: cap excerpts,
|
|
78
|
+
prefer stable IDs and URLs, and use an action or resource lookup for full data.
|
|
79
|
+
|
|
52
80
|
**From the UI, in the background:**
|
|
53
81
|
|
|
54
82
|
```ts
|
|
@@ -168,6 +168,11 @@ the useful information remains dense and scannable.
|
|
|
168
168
|
- Do not build custom dropdowns, menus, popovers, modals, or confirmations with manual absolute positioning and click-outside effects.
|
|
169
169
|
- Never use browser dialogs (`window.alert`, `window.confirm`, `window.prompt`). Use `AlertDialog`, `Dialog`, or app-specific confirmation UI.
|
|
170
170
|
- Use Tabler icons for all first-party UI icons. Do not add Lucide, Heroicons, inline SVG icon sets, or emoji icons.
|
|
171
|
+
- Never guess a Tabler icon name. Names like `IconPartyPopper` or `IconConfettiCannon` feel
|
|
172
|
+
plausible but don't exist and crash Vite with a "Named export not found" error. Before importing
|
|
173
|
+
an icon you haven't used elsewhere in this app, confirm it exists by grepping
|
|
174
|
+
`node_modules/@tabler/icons-react/dist/tabler-icons-react.d.ts` (or the package's icon list)
|
|
175
|
+
for the exact name, and pick the closest real match if your first guess isn't there.
|
|
171
176
|
- Keep inline help/info glyphs next to labels at `size-3` (12px) or smaller than the adjacent text. Preserve a larger hit area on the trigger, not the glyph. Use `guard:allow-large-help-icon` only for deliberate heading documentation or menu action exceptions.
|
|
172
177
|
- Use `useActionQuery` and `useActionMutation` from `@agent-native/core/client` for action-backed UI. Standard CRUD should go through actions, not custom `/api/` routes.
|
|
173
178
|
- Keep UI optimistic where possible: update cache and navigation immediately, then reconcile or roll back on mutation result.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { accessFilter } from "@agent-native/core/sharing";
|
|
2
|
+
import {
|
|
3
|
+
and,
|
|
4
|
+
eq,
|
|
5
|
+
exists,
|
|
6
|
+
isNotNull,
|
|
7
|
+
isNull,
|
|
8
|
+
notExists,
|
|
9
|
+
or,
|
|
10
|
+
type SQL,
|
|
11
|
+
} from "drizzle-orm";
|
|
12
|
+
|
|
13
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
14
|
+
import { documentDiscoveryFilter } from "../server/lib/documents.js";
|
|
15
|
+
|
|
16
|
+
export const DOCUMENT_DISCOVERY_MAX_LIMIT = 200;
|
|
17
|
+
export const DOCUMENT_DISCOVERY_DEFAULT_LIMIT = 50;
|
|
18
|
+
|
|
19
|
+
export type DocumentDiscoveryType = "page" | "database";
|
|
20
|
+
|
|
21
|
+
export interface DocumentDiscoveryFilters {
|
|
22
|
+
userEmail: string | null | undefined;
|
|
23
|
+
authorizedOrgIds: string[];
|
|
24
|
+
exactTitle?: string;
|
|
25
|
+
parentId?: string | null;
|
|
26
|
+
spaceId?: string;
|
|
27
|
+
documentType?: DocumentDiscoveryType;
|
|
28
|
+
additional?: SQL;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function documentDiscoveryWhere({
|
|
32
|
+
userEmail,
|
|
33
|
+
authorizedOrgIds,
|
|
34
|
+
exactTitle,
|
|
35
|
+
parentId,
|
|
36
|
+
spaceId,
|
|
37
|
+
documentType,
|
|
38
|
+
additional,
|
|
39
|
+
}: DocumentDiscoveryFilters) {
|
|
40
|
+
const db = getDb();
|
|
41
|
+
const accessContexts = [
|
|
42
|
+
{ userEmail: userEmail ?? undefined },
|
|
43
|
+
...authorizedOrgIds.map((orgId) => ({
|
|
44
|
+
userEmail: userEmail ?? undefined,
|
|
45
|
+
orgId,
|
|
46
|
+
})),
|
|
47
|
+
];
|
|
48
|
+
const activeDatabaseDocument = db
|
|
49
|
+
.select({ id: schema.contentDatabases.id })
|
|
50
|
+
.from(schema.contentDatabases)
|
|
51
|
+
.where(
|
|
52
|
+
and(
|
|
53
|
+
eq(schema.contentDatabases.documentId, schema.documents.id),
|
|
54
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
const deletedDatabaseDocument = db
|
|
58
|
+
.select({ id: schema.contentDatabases.id })
|
|
59
|
+
.from(schema.contentDatabases)
|
|
60
|
+
.where(
|
|
61
|
+
and(
|
|
62
|
+
eq(schema.contentDatabases.documentId, schema.documents.id),
|
|
63
|
+
isNotNull(schema.contentDatabases.deletedAt),
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
const deletedDatabaseMembership = db
|
|
67
|
+
.select({ id: schema.contentDatabaseItems.id })
|
|
68
|
+
.from(schema.contentDatabaseItems)
|
|
69
|
+
.innerJoin(
|
|
70
|
+
schema.contentDatabases,
|
|
71
|
+
eq(schema.contentDatabases.id, schema.contentDatabaseItems.databaseId),
|
|
72
|
+
)
|
|
73
|
+
.where(
|
|
74
|
+
and(
|
|
75
|
+
eq(schema.contentDatabaseItems.documentId, schema.documents.id),
|
|
76
|
+
isNotNull(schema.contentDatabases.deletedAt),
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return and(
|
|
81
|
+
or(
|
|
82
|
+
...accessContexts.map((context) =>
|
|
83
|
+
accessFilter(schema.documents, schema.documentShares, context),
|
|
84
|
+
),
|
|
85
|
+
),
|
|
86
|
+
isNull(schema.documents.trashedAt),
|
|
87
|
+
documentDiscoveryFilter({
|
|
88
|
+
userEmail,
|
|
89
|
+
orgIds: authorizedOrgIds,
|
|
90
|
+
}),
|
|
91
|
+
notExists(deletedDatabaseDocument),
|
|
92
|
+
notExists(deletedDatabaseMembership),
|
|
93
|
+
exactTitle === undefined
|
|
94
|
+
? undefined
|
|
95
|
+
: eq(schema.documents.title, exactTitle),
|
|
96
|
+
parentId === undefined
|
|
97
|
+
? undefined
|
|
98
|
+
: parentId === null
|
|
99
|
+
? isNull(schema.documents.parentId)
|
|
100
|
+
: eq(schema.documents.parentId, parentId),
|
|
101
|
+
spaceId === undefined ? undefined : eq(schema.documents.spaceId, spaceId),
|
|
102
|
+
documentType === "database"
|
|
103
|
+
? exists(activeDatabaseDocument)
|
|
104
|
+
: documentType === "page"
|
|
105
|
+
? notExists(activeDatabaseDocument)
|
|
106
|
+
: undefined,
|
|
107
|
+
additional,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function documentDiscoveryPagination(args: {
|
|
112
|
+
offset: number;
|
|
113
|
+
limit: number;
|
|
114
|
+
totalItems: number;
|
|
115
|
+
returnedItems: number;
|
|
116
|
+
}) {
|
|
117
|
+
const nextOffset = args.offset + args.returnedItems;
|
|
118
|
+
const hasMore = nextOffset < args.totalItems;
|
|
119
|
+
return {
|
|
120
|
+
offset: args.offset,
|
|
121
|
+
limit: args.limit,
|
|
122
|
+
totalItems: args.totalItems,
|
|
123
|
+
returnedItems: args.returnedItems,
|
|
124
|
+
hasMore,
|
|
125
|
+
nextOffset: hasMore ? nextOffset : null,
|
|
126
|
+
};
|
|
127
|
+
}
|