@agent-native/core 0.114.5 → 0.114.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 +2 -2
- package/corpus/core/CHANGELOG.md +14 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/mcp-config-writers.ts +6 -4
- package/corpus/core/src/cli/mcp.ts +124 -0
- package/corpus/core/src/cli/skills-content/help.ts +4 -3
- package/corpus/core/src/cli/skills-content/index.ts +1 -0
- package/corpus/core/src/cli/skills-content/rewind-skill.ts +52 -0
- package/corpus/core/src/cli/skills.ts +115 -13
- package/corpus/core/src/client/resources/ResourceTree.tsx +11 -5
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +141 -18
- package/corpus/core/src/mcp/screen-memory-stdio.ts +1360 -104
- package/corpus/core/src/mcp-client/index.ts +9 -0
- package/corpus/core/src/mcp-client/screen-memory-local.ts +847 -13
- package/corpus/templates/clips/actions/apply-rewind-extension.ts +195 -0
- package/corpus/templates/clips/actions/delete-agent-recording-if-unpromoted.ts +64 -0
- package/corpus/templates/clips/actions/get-rewind-extension-request.ts +22 -0
- package/corpus/templates/clips/actions/get-screen-memory-status.ts +18 -2
- package/corpus/templates/clips/actions/list-rewind-extension-requests.ts +52 -0
- package/corpus/templates/clips/actions/make-recording-private-for-rewind.ts +55 -0
- package/corpus/templates/clips/actions/query-screen-memory-context.ts +4 -4
- package/corpus/templates/clips/actions/request-rewind-extension.ts +81 -0
- package/corpus/templates/clips/actions/update-rewind-extension-request.ts +47 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +25 -0
- package/corpus/templates/clips/app/components/editor/editor-toolbar.tsx +36 -0
- package/corpus/templates/clips/app/components/editor/rewind-extension-dialog.tsx +338 -0
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +1 -16
- package/corpus/templates/clips/app/components/editor/timeline.tsx +26 -0
- package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +1 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +18 -0
- package/corpus/templates/clips/app/lib/ffmpeg-export.ts +19 -12
- package/corpus/templates/clips/app/lib/rewind-visibility.ts +31 -0
- package/corpus/templates/clips/app/lib/timestamp-mapping.ts +7 -0
- package/corpus/templates/clips/app/lib/upload-file-client.ts +17 -0
- package/corpus/templates/clips/changelog/2026-07-14-rewind-keeps-recent-screen-context-local-and-turns-it-into-clips.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-active-clips-keep-rewind-stable-and-settings-clear.md +12 -0
- package/corpus/templates/clips/changelog/2026-07-17-clicking-the-clips-icon-during-a-recording-now-opens-the-app.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-default-mic-now-uses-the-mac-default-and-transcription-shares-one-capture.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-full-screen-clips-finalize-even-when-screencapturekit-stop-hangs.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-normal-full-screen-clips-no-longer-stop-immediately-after-th.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-rewind-can-hand-one-bounded-private-clip-to-your-agent.md +12 -0
- package/corpus/templates/clips/changelog/2026-07-17-rewind-home-can-copy-a-local-agent-prompt.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-rewind-now-has-a-calm-home-status-focused-first-run-consent-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-rewind-settings-are-smaller-clearer-and-agent-first.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-the-full-clips-interface-stays-available-while-recording.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-18-rewind-organizes-recent-work-into-local-searchable-chapters.md +8 -0
- package/corpus/templates/clips/changelog/2026-07-18-searchable-rewind-chapters.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-19-rewind-backed-recordings-now-start-immediately-after-the-cou.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-opening-zoom-meeting-launches-native-app.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-rewind-can-set-up-your-local-agent-once-so-future-requests-w.md +6 -0
- package/corpus/templates/clips/desktop/package.json +1 -0
- package/corpus/templates/clips/desktop/scripts/sign-macos-local.ts +12 -1
- package/corpus/templates/clips/desktop/src/app.tsx +2478 -223
- package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +21 -1
- package/corpus/templates/clips/desktop/src/components/Switch.tsx +3 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +156 -24
- package/corpus/templates/clips/desktop/src/lib/native-recording-warm.ts +6 -7
- package/corpus/templates/clips/desktop/src/lib/open-meeting-join-url.ts +22 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +1763 -1160
- package/corpus/templates/clips/desktop/src/lib/rewind-agent-prompt.ts +9 -0
- package/corpus/templates/clips/desktop/src/lib/rewind-recording-start.ts +20 -0
- package/corpus/templates/clips/desktop/src/main.tsx +3 -0
- package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +14 -14
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -3
- package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +4 -4
- package/corpus/templates/clips/desktop/src/overlays/preparing.tsx +13 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +27 -2
- package/corpus/templates/clips/desktop/src/shared/config.ts +16 -0
- package/corpus/templates/clips/desktop/src/styles.css +956 -134
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +5 -0
- package/corpus/templates/clips/desktop/src-tauri/build.rs +69 -1
- package/corpus/templates/clips/desktop/src-tauri/src/accessibility.rs +386 -12
- package/corpus/templates/clips/desktop/src-tauri/src/capture_audio_bus.rs +382 -0
- package/corpus/templates/clips/desktop/src-tauri/src/capture_graph.rs +777 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +249 -22
- package/corpus/templates/clips/desktop/src-tauri/src/config.rs +148 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +58 -4
- package/corpus/templates/clips/desktop/src-tauri/src/logfile.rs +13 -1
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +1505 -51
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +124 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1006 -95
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_capture_suspension.rs +165 -0
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_chapters.rs +2434 -0
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +1650 -0
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_egress.rs +643 -0
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_local_ask.rs +803 -0
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_meeting_history.rs +595 -0
- package/corpus/templates/clips/desktop/src-tauri/src/screen_memory.rs +2900 -91
- package/corpus/templates/clips/desktop/src-tauri/src/screen_memory_ocr.rs +360 -0
- package/corpus/templates/clips/desktop/src-tauri/src/screen_memory_transcript.rs +408 -0
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +114 -33
- package/corpus/templates/clips/desktop/src-tauri/src/state.rs +2 -2
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +13 -3
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +7 -13
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +198 -11
- package/corpus/templates/clips/desktop/src-tauri/tauri.alpha.conf.json +17 -0
- package/corpus/templates/clips/shared/meeting-join-url.ts +0 -5
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +9 -1
- package/corpus/templates/content/AGENTS.md +4 -1
- package/corpus/templates/content/actions/_content-spaces.ts +6 -1
- package/corpus/templates/content/actions/_database-row-batch.ts +15 -2
- package/corpus/templates/content/actions/_database-utils.ts +83 -15
- package/corpus/templates/content/actions/add-database-item.ts +3 -0
- package/corpus/templates/content/actions/connect-local-folder-source.ts +2 -1
- package/corpus/templates/content/actions/delete-content-database.ts +12 -9
- package/corpus/templates/content/actions/delete-database-items.ts +3 -2
- package/corpus/templates/content/actions/delete-document.ts +233 -6
- package/corpus/templates/content/actions/duplicate-database-item.ts +1 -0
- package/corpus/templates/content/actions/get-document.ts +4 -1
- package/corpus/templates/content/actions/list-content-databases.ts +1 -0
- package/corpus/templates/content/actions/list-documents.ts +1 -0
- package/corpus/templates/content/actions/list-trashed-content-databases.ts +8 -2
- package/corpus/templates/content/actions/list-trashed-documents.ts +50 -0
- package/corpus/templates/content/actions/permanently-delete-document.ts +28 -0
- package/corpus/templates/content/actions/pull-document.ts +15 -2
- package/corpus/templates/content/actions/restore-content-database.ts +48 -11
- package/corpus/templates/content/actions/restore-document.ts +28 -0
- package/corpus/templates/content/actions/search-documents.ts +2 -1
- package/corpus/templates/content/actions/view-screen.ts +2 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +149 -55
- package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +7 -2
- package/corpus/templates/content/app/components/editor/database/ListView.tsx +7 -2
- package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +3 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +26 -5
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +243 -163
- package/corpus/templates/content/app/components/sidebar/WorkspaceSourceMenu.tsx +154 -0
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +11 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +6 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +57 -0
- package/corpus/templates/content/app/i18n-data.ts +83 -2
- package/corpus/templates/content/app/routes/_app.local-files.tsx +8 -1
- package/corpus/templates/content/changelog/2026-07-19-pages-now-move-to-a-reversible-trash-and-the-organization-pi.md +6 -0
- package/corpus/templates/content/changelog/2026-07-20-trash-actions-now-preserve-independent-archived-pages-enforc.md +6 -0
- package/corpus/templates/content/changelog/2026-07-20-workspace-toggles-now-stay-independently-open-or-closed-and-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-20-workspaces-can-be-added-from-a-blank-workspace-or-a-connecte.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +3 -0
- package/corpus/templates/content/server/db/schema.ts +2 -0
- package/corpus/templates/content/server/lib/public-documents.ts +8 -2
- package/corpus/templates/content/server/plugins/db.ts +52 -0
- package/corpus/templates/content/server/routes/api/document-agent-context.json.get.ts +2 -2
- package/corpus/templates/content/shared/api.ts +10 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/ui/progress.tsx +3 -2
- package/dist/cli/mcp-config-writers.d.ts +2 -2
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +6 -6
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.d.ts +14 -0
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +79 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/skills-content/help.d.ts +1 -1
- package/dist/cli/skills-content/help.d.ts.map +1 -1
- package/dist/cli/skills-content/help.js +4 -3
- package/dist/cli/skills-content/help.js.map +1 -1
- package/dist/cli/skills-content/index.d.ts +1 -0
- package/dist/cli/skills-content/index.d.ts.map +1 -1
- package/dist/cli/skills-content/index.js +1 -0
- package/dist/cli/skills-content/index.js.map +1 -1
- package/dist/cli/skills-content/rewind-skill.d.ts +2 -0
- package/dist/cli/skills-content/rewind-skill.d.ts.map +1 -0
- package/dist/cli/skills-content/rewind-skill.js +53 -0
- package/dist/cli/skills-content/rewind-skill.js.map +1 -0
- package/dist/cli/skills.d.ts +6 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +90 -14
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +3 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +4 -4
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +55 -6
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +365 -0
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp/screen-memory-stdio.js +1014 -91
- package/dist/mcp/screen-memory-stdio.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/screen-memory-local.d.ts +90 -0
- package/dist/mcp-client/screen-memory-local.d.ts.map +1 -1
- package/dist/mcp-client/screen-memory-local.js +590 -12
- package/dist/mcp-client/screen-memory-local.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +4 -4
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +2 -2
- package/src/cli/mcp-config-writers.ts +6 -4
- package/src/cli/mcp.ts +124 -0
- package/src/cli/skills-content/help.ts +4 -3
- package/src/cli/skills-content/index.ts +1 -0
- package/src/cli/skills-content/rewind-skill.ts +52 -0
- package/src/cli/skills.ts +115 -13
- package/src/client/resources/ResourceTree.tsx +11 -5
- package/src/client/resources/ResourcesPanel.tsx +141 -18
- package/src/mcp/screen-memory-stdio.ts +1360 -104
- package/src/mcp-client/index.ts +9 -0
- package/src/mcp-client/screen-memory-local.ts +847 -13
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
|
-
import {
|
|
3
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
|
-
import { getDb
|
|
6
|
+
import { getDb } from "../server/db/index.js";
|
|
7
7
|
import { assertContentDatabaseLifecycleAccess } from "./_content-database-lifecycle.js";
|
|
8
|
+
import { trashDocumentSubtree } from "./delete-document.js";
|
|
8
9
|
|
|
9
10
|
export default defineAction({
|
|
10
11
|
description:
|
|
@@ -17,15 +18,17 @@ export default defineAction({
|
|
|
17
18
|
if (database.systemRole) {
|
|
18
19
|
throw new Error("System Content databases cannot be deleted");
|
|
19
20
|
}
|
|
21
|
+
await assertAccess("document", database.documentId, "admin");
|
|
20
22
|
const db = getDb();
|
|
21
23
|
const deletedAt = database.deletedAt ?? new Date().toISOString();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
await db.transaction((tx) =>
|
|
25
|
+
trashDocumentSubtree(
|
|
26
|
+
tx as unknown as ReturnType<typeof getDb>,
|
|
27
|
+
database.documentId,
|
|
28
|
+
database.ownerEmail,
|
|
29
|
+
deletedAt,
|
|
30
|
+
),
|
|
31
|
+
);
|
|
29
32
|
|
|
30
33
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
31
34
|
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
resolveDatabaseRowsForBatch,
|
|
12
12
|
} from "./_database-row-batch.js";
|
|
13
13
|
import { getContentDatabaseResponse } from "./_database-utils.js";
|
|
14
|
-
import {
|
|
14
|
+
import { trashDocumentSubtree } from "./delete-document.js";
|
|
15
15
|
|
|
16
16
|
export default defineAction({
|
|
17
17
|
description:
|
|
@@ -57,10 +57,11 @@ export default defineAction({
|
|
|
57
57
|
|
|
58
58
|
await db.transaction(async (tx) => {
|
|
59
59
|
for (const row of rows) {
|
|
60
|
-
await
|
|
60
|
+
await trashDocumentSubtree(
|
|
61
61
|
tx as unknown as ReturnType<typeof getDb>,
|
|
62
62
|
row.document.id,
|
|
63
63
|
row.document.ownerEmail,
|
|
64
|
+
now,
|
|
64
65
|
);
|
|
65
66
|
}
|
|
66
67
|
await renumberDatabaseRows(
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
3
|
import { assertAccess } from "@agent-native/core/sharing";
|
|
4
|
-
import { and, eq, inArray } from "drizzle-orm";
|
|
4
|
+
import { and, eq, inArray, isNotNull, isNull, ne, or } from "drizzle-orm";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
|
|
7
7
|
import { getDb, schema } from "../server/db/index.js";
|
|
8
8
|
import { chunks } from "./_batch-utils.js";
|
|
9
9
|
import { assertNotWorkspaceCatalogDocuments } from "./_content-space-catalog-guards.js";
|
|
10
|
+
import { renumberDatabaseRows } from "./_database-row-batch.js";
|
|
10
11
|
|
|
11
12
|
const DELETE_BATCH_SIZE = 90;
|
|
12
13
|
|
|
@@ -155,6 +156,152 @@ async function collectDocumentSubtreeForDelete(
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
export async function trashDocumentSubtree(
|
|
160
|
+
db: ReturnType<typeof getDb>,
|
|
161
|
+
id: string,
|
|
162
|
+
ownerEmail: string,
|
|
163
|
+
trashedAt = new Date().toISOString(),
|
|
164
|
+
): Promise<string[]> {
|
|
165
|
+
const { documentIds } = await collectDocumentSubtreeForDelete(
|
|
166
|
+
db,
|
|
167
|
+
id,
|
|
168
|
+
ownerEmail,
|
|
169
|
+
);
|
|
170
|
+
await assertNotWorkspaceCatalogDocuments(db, documentIds, "deleted");
|
|
171
|
+
|
|
172
|
+
const independentlyTrashedDatabaseDocumentIds = new Set<string>();
|
|
173
|
+
for (const batch of chunks(documentIds, DELETE_BATCH_SIZE)) {
|
|
174
|
+
for (const database of await db
|
|
175
|
+
.select({ documentId: schema.contentDatabases.documentId })
|
|
176
|
+
.from(schema.contentDatabases)
|
|
177
|
+
.where(
|
|
178
|
+
and(
|
|
179
|
+
inArray(schema.contentDatabases.documentId, batch),
|
|
180
|
+
eq(schema.contentDatabases.ownerEmail, ownerEmail),
|
|
181
|
+
isNotNull(schema.contentDatabases.deletedAt),
|
|
182
|
+
),
|
|
183
|
+
)) {
|
|
184
|
+
independentlyTrashedDatabaseDocumentIds.add(database.documentId);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const activeDocumentIds: string[] = [];
|
|
189
|
+
for (const batch of chunks(documentIds, DELETE_BATCH_SIZE)) {
|
|
190
|
+
activeDocumentIds.push(
|
|
191
|
+
...(
|
|
192
|
+
await db
|
|
193
|
+
.select({ id: schema.documents.id })
|
|
194
|
+
.from(schema.documents)
|
|
195
|
+
.where(
|
|
196
|
+
and(
|
|
197
|
+
inArray(schema.documents.id, batch),
|
|
198
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
199
|
+
isNull(schema.documents.trashedAt),
|
|
200
|
+
),
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
.map((document) => document.id)
|
|
204
|
+
.filter(
|
|
205
|
+
(documentId) =>
|
|
206
|
+
!independentlyTrashedDatabaseDocumentIds.has(documentId),
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const batch of chunks(activeDocumentIds, DELETE_BATCH_SIZE)) {
|
|
212
|
+
await db
|
|
213
|
+
.update(schema.documents)
|
|
214
|
+
.set({ trashedAt, trashRootId: id, updatedAt: trashedAt })
|
|
215
|
+
.where(
|
|
216
|
+
and(
|
|
217
|
+
inArray(schema.documents.id, batch),
|
|
218
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
219
|
+
isNull(schema.documents.trashedAt),
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
await db
|
|
223
|
+
.update(schema.contentDatabases)
|
|
224
|
+
.set({ deletedAt: trashedAt, updatedAt: trashedAt })
|
|
225
|
+
.where(
|
|
226
|
+
and(
|
|
227
|
+
inArray(schema.contentDatabases.documentId, batch),
|
|
228
|
+
eq(schema.contentDatabases.ownerEmail, ownerEmail),
|
|
229
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
230
|
+
),
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return activeDocumentIds;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function restoreDocumentSubtree(
|
|
238
|
+
db: ReturnType<typeof getDb>,
|
|
239
|
+
rootId: string,
|
|
240
|
+
ownerEmail: string,
|
|
241
|
+
): Promise<string[]> {
|
|
242
|
+
const documentIds = (
|
|
243
|
+
await db
|
|
244
|
+
.select({ id: schema.documents.id })
|
|
245
|
+
.from(schema.documents)
|
|
246
|
+
.where(
|
|
247
|
+
and(
|
|
248
|
+
eq(schema.documents.trashRootId, rootId),
|
|
249
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
250
|
+
),
|
|
251
|
+
)
|
|
252
|
+
).map((document) => document.id);
|
|
253
|
+
if (documentIds.length === 0) return [];
|
|
254
|
+
|
|
255
|
+
const now = new Date().toISOString();
|
|
256
|
+
for (const batch of chunks(documentIds, DELETE_BATCH_SIZE)) {
|
|
257
|
+
await db
|
|
258
|
+
.update(schema.documents)
|
|
259
|
+
.set({ trashedAt: null, trashRootId: null, updatedAt: now })
|
|
260
|
+
.where(
|
|
261
|
+
and(
|
|
262
|
+
inArray(schema.documents.id, batch),
|
|
263
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
264
|
+
eq(schema.documents.trashRootId, rootId),
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
await db
|
|
268
|
+
.update(schema.contentDatabases)
|
|
269
|
+
.set({ deletedAt: null, updatedAt: now })
|
|
270
|
+
.where(
|
|
271
|
+
and(
|
|
272
|
+
inArray(schema.contentDatabases.documentId, batch),
|
|
273
|
+
eq(schema.contentDatabases.ownerEmail, ownerEmail),
|
|
274
|
+
),
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const databaseIds = [
|
|
279
|
+
...new Set(
|
|
280
|
+
(
|
|
281
|
+
await db
|
|
282
|
+
.select({ databaseId: schema.contentDatabaseItems.databaseId })
|
|
283
|
+
.from(schema.contentDatabaseItems)
|
|
284
|
+
.where(inArray(schema.contentDatabaseItems.documentId, documentIds))
|
|
285
|
+
).map((item) => item.databaseId),
|
|
286
|
+
),
|
|
287
|
+
];
|
|
288
|
+
for (const databaseId of databaseIds) {
|
|
289
|
+
const [database] = await db
|
|
290
|
+
.select()
|
|
291
|
+
.from(schema.contentDatabases)
|
|
292
|
+
.where(
|
|
293
|
+
and(
|
|
294
|
+
eq(schema.contentDatabases.id, databaseId),
|
|
295
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
296
|
+
),
|
|
297
|
+
)
|
|
298
|
+
.limit(1);
|
|
299
|
+
if (database) await renumberDatabaseRows(db, database, now);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return documentIds;
|
|
303
|
+
}
|
|
304
|
+
|
|
158
305
|
async function deleteWhereIn<T>(
|
|
159
306
|
items: T[],
|
|
160
307
|
run: (batch: T[]) => Promise<unknown>,
|
|
@@ -171,6 +318,20 @@ export async function deleteDocumentRecursive(
|
|
|
171
318
|
): Promise<string[]> {
|
|
172
319
|
const { documentIds, ownedDatabaseIds } =
|
|
173
320
|
await collectDocumentSubtreeForDelete(db, id, ownerEmail);
|
|
321
|
+
return deleteCollectedDocuments(
|
|
322
|
+
db,
|
|
323
|
+
documentIds,
|
|
324
|
+
ownedDatabaseIds,
|
|
325
|
+
ownerEmail,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function deleteCollectedDocuments(
|
|
330
|
+
db: ReturnType<typeof getDb>,
|
|
331
|
+
documentIds: string[],
|
|
332
|
+
ownedDatabaseIds: string[],
|
|
333
|
+
ownerEmail: string,
|
|
334
|
+
): Promise<string[]> {
|
|
174
335
|
await assertNotWorkspaceCatalogDocuments(db, documentIds, "deleted");
|
|
175
336
|
|
|
176
337
|
const propertyDefinitionIds: string[] = [];
|
|
@@ -353,8 +514,72 @@ export async function deleteDocumentRecursive(
|
|
|
353
514
|
return documentIds;
|
|
354
515
|
}
|
|
355
516
|
|
|
517
|
+
export async function deleteTrashedDocumentSubtree(
|
|
518
|
+
db: ReturnType<typeof getDb>,
|
|
519
|
+
id: string,
|
|
520
|
+
ownerEmail: string,
|
|
521
|
+
): Promise<string[]> {
|
|
522
|
+
const [root] = await db
|
|
523
|
+
.select({ id: schema.documents.id })
|
|
524
|
+
.from(schema.documents)
|
|
525
|
+
.where(
|
|
526
|
+
and(
|
|
527
|
+
eq(schema.documents.id, id),
|
|
528
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
529
|
+
eq(schema.documents.trashRootId, id),
|
|
530
|
+
isNotNull(schema.documents.trashedAt),
|
|
531
|
+
),
|
|
532
|
+
)
|
|
533
|
+
.limit(1);
|
|
534
|
+
if (!root) {
|
|
535
|
+
throw new Error(
|
|
536
|
+
"Document must be in Trash and be a Trash root before permanent deletion",
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const documentIds = (
|
|
541
|
+
await db
|
|
542
|
+
.select({ id: schema.documents.id })
|
|
543
|
+
.from(schema.documents)
|
|
544
|
+
.where(
|
|
545
|
+
and(
|
|
546
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
547
|
+
eq(schema.documents.trashRootId, id),
|
|
548
|
+
isNotNull(schema.documents.trashedAt),
|
|
549
|
+
),
|
|
550
|
+
)
|
|
551
|
+
).map((document) => document.id);
|
|
552
|
+
const ownedDatabaseIds = await selectOwnedDatabaseIds(
|
|
553
|
+
db,
|
|
554
|
+
documentIds,
|
|
555
|
+
ownerEmail,
|
|
556
|
+
).then((rows) => rows.map((database) => database.id));
|
|
557
|
+
|
|
558
|
+
await db
|
|
559
|
+
.update(schema.documents)
|
|
560
|
+
.set({ parentId: null, updatedAt: new Date().toISOString() })
|
|
561
|
+
.where(
|
|
562
|
+
and(
|
|
563
|
+
eq(schema.documents.ownerEmail, ownerEmail),
|
|
564
|
+
inArray(schema.documents.parentId, documentIds),
|
|
565
|
+
or(
|
|
566
|
+
isNull(schema.documents.trashRootId),
|
|
567
|
+
ne(schema.documents.trashRootId, id),
|
|
568
|
+
),
|
|
569
|
+
),
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
return deleteCollectedDocuments(
|
|
573
|
+
db,
|
|
574
|
+
documentIds,
|
|
575
|
+
ownedDatabaseIds,
|
|
576
|
+
ownerEmail,
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
356
580
|
export default defineAction({
|
|
357
|
-
description:
|
|
581
|
+
description:
|
|
582
|
+
"Move a document and all its children to Trash. Use permanently-delete-document to destroy an item already in Trash.",
|
|
358
583
|
schema: z.object({
|
|
359
584
|
id: z.string().optional().describe("Document ID (required)"),
|
|
360
585
|
databaseDocumentId: z
|
|
@@ -408,10 +633,12 @@ export default defineAction({
|
|
|
408
633
|
if (systemDatabase?.systemRole) {
|
|
409
634
|
throw new Error("System Content database documents cannot be deleted");
|
|
410
635
|
}
|
|
411
|
-
const deleted = await
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
636
|
+
const deleted = await db.transaction((tx) =>
|
|
637
|
+
trashDocumentSubtree(
|
|
638
|
+
tx as unknown as ReturnType<typeof getDb>,
|
|
639
|
+
id,
|
|
640
|
+
existing.ownerEmail as string,
|
|
641
|
+
),
|
|
415
642
|
);
|
|
416
643
|
|
|
417
644
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
@@ -70,7 +70,10 @@ export default defineAction({
|
|
|
70
70
|
statusCode: 404,
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
access.resource.trashedAt ||
|
|
75
|
+
(await isSoftDeletedDatabaseDocument(args.id))
|
|
76
|
+
) {
|
|
74
77
|
throw Object.assign(new Error(`Document "${args.id}" not found`), {
|
|
75
78
|
statusCode: 404,
|
|
76
79
|
});
|
|
@@ -34,6 +34,7 @@ export default defineAction({
|
|
|
34
34
|
deletedAt: schema.contentDatabases.deletedAt,
|
|
35
35
|
documentTitle: schema.documents.title,
|
|
36
36
|
documentParentId: schema.documents.parentId,
|
|
37
|
+
documentTrashRootId: schema.documents.trashRootId,
|
|
37
38
|
})
|
|
38
39
|
.from(schema.contentDatabases)
|
|
39
40
|
.innerJoin(
|
|
@@ -47,6 +48,10 @@ export default defineAction({
|
|
|
47
48
|
.where(
|
|
48
49
|
and(
|
|
49
50
|
isNotNull(schema.contentDatabases.deletedAt),
|
|
51
|
+
or(
|
|
52
|
+
isNull(schema.documents.trashRootId),
|
|
53
|
+
eq(schema.documents.trashRootId, schema.documents.id),
|
|
54
|
+
),
|
|
50
55
|
or(
|
|
51
56
|
and(
|
|
52
57
|
isBlockOwned,
|
|
@@ -82,8 +87,9 @@ export default defineAction({
|
|
|
82
87
|
ownerDocumentId: row.ownerDocumentId,
|
|
83
88
|
deletedAt: row.deletedAt!,
|
|
84
89
|
canPermanentlyDelete:
|
|
85
|
-
row.
|
|
86
|
-
row.
|
|
90
|
+
row.documentTrashRootId === row.documentId &&
|
|
91
|
+
(row.ownerDocumentId === null ||
|
|
92
|
+
row.documentParentId !== row.ownerDocumentId),
|
|
87
93
|
})),
|
|
88
94
|
};
|
|
89
95
|
},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { accessFilter } from "@agent-native/core/sharing";
|
|
3
|
+
import { and, desc, eq, isNotNull, isNull } from "drizzle-orm";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
7
|
+
import type { ListTrashedDocumentsResponse } from "../shared/api.js";
|
|
8
|
+
|
|
9
|
+
export default defineAction({
|
|
10
|
+
description:
|
|
11
|
+
"List trashed page roots the current user can manage. Titles are returned only after document access filtering.",
|
|
12
|
+
schema: z.object({}),
|
|
13
|
+
http: { method: "GET" },
|
|
14
|
+
readOnly: true,
|
|
15
|
+
run: async (): Promise<ListTrashedDocumentsResponse> => {
|
|
16
|
+
const rows = await getDb()
|
|
17
|
+
.select({
|
|
18
|
+
documentId: schema.documents.id,
|
|
19
|
+
title: schema.documents.title,
|
|
20
|
+
trashedAt: schema.documents.trashedAt,
|
|
21
|
+
})
|
|
22
|
+
.from(schema.documents)
|
|
23
|
+
.leftJoin(
|
|
24
|
+
schema.contentDatabases,
|
|
25
|
+
eq(schema.contentDatabases.documentId, schema.documents.id),
|
|
26
|
+
)
|
|
27
|
+
.where(
|
|
28
|
+
and(
|
|
29
|
+
isNotNull(schema.documents.trashedAt),
|
|
30
|
+
eq(schema.documents.trashRootId, schema.documents.id),
|
|
31
|
+
isNull(schema.contentDatabases.id),
|
|
32
|
+
accessFilter(
|
|
33
|
+
schema.documents,
|
|
34
|
+
schema.documentShares,
|
|
35
|
+
undefined,
|
|
36
|
+
"admin",
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
.orderBy(desc(schema.documents.trashedAt));
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
documents: rows.map((row) => ({
|
|
44
|
+
documentId: row.documentId,
|
|
45
|
+
title: row.title.trim() || "Untitled",
|
|
46
|
+
trashedAt: row.trashedAt!,
|
|
47
|
+
})),
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
import { getDb } from "../server/db/index.js";
|
|
7
|
+
import { deleteTrashedDocumentSubtree } from "./delete-document.js";
|
|
8
|
+
|
|
9
|
+
export default defineAction({
|
|
10
|
+
description:
|
|
11
|
+
"Permanently delete a document subtree that is already in Trash. This cannot be undone.",
|
|
12
|
+
schema: z.object({
|
|
13
|
+
id: z.string().describe("Trashed root document ID"),
|
|
14
|
+
}),
|
|
15
|
+
run: async ({ id }) => {
|
|
16
|
+
const access = await assertAccess("document", id, "admin");
|
|
17
|
+
const db = getDb();
|
|
18
|
+
const deleted = await db.transaction((tx) =>
|
|
19
|
+
deleteTrashedDocumentSubtree(
|
|
20
|
+
tx as unknown as ReturnType<typeof getDb>,
|
|
21
|
+
id,
|
|
22
|
+
access.resource.ownerEmail as string,
|
|
23
|
+
),
|
|
24
|
+
);
|
|
25
|
+
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
26
|
+
return { success: true, deleted: deleted.length };
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -4,6 +4,7 @@ import { resolveAccess } from "@agent-native/core/sharing";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import "../server/db/index.js";
|
|
7
|
+
import { isSoftDeletedDatabaseDocument } from "./_database-utils.js";
|
|
7
8
|
import { flushOpenDocumentEditorToSql } from "./_document-flush.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -62,7 +63,13 @@ export default defineAction({
|
|
|
62
63
|
publicAgent: { expose: true, readOnly: true, requiresAuth: true },
|
|
63
64
|
run: async ({ id, format }) => {
|
|
64
65
|
const access = await resolveAccess("document", id);
|
|
65
|
-
if (
|
|
66
|
+
if (
|
|
67
|
+
!access ||
|
|
68
|
+
access.resource.trashedAt ||
|
|
69
|
+
(await isSoftDeletedDatabaseDocument(id))
|
|
70
|
+
) {
|
|
71
|
+
throw new Error(`Document "${id}" not found`);
|
|
72
|
+
}
|
|
66
73
|
|
|
67
74
|
// If a live Yjs collab session is open, the in-memory editor doc is fresher
|
|
68
75
|
// than the SQL column. Ask the open editor to serialize + save, then wait
|
|
@@ -74,7 +81,13 @@ export default defineAction({
|
|
|
74
81
|
|
|
75
82
|
// Re-resolve so we read the now-fresh row (and re-check access).
|
|
76
83
|
const fresh = await resolveAccess("document", id);
|
|
77
|
-
if (
|
|
84
|
+
if (
|
|
85
|
+
!fresh ||
|
|
86
|
+
fresh.resource.trashedAt ||
|
|
87
|
+
(await isSoftDeletedDatabaseDocument(id))
|
|
88
|
+
) {
|
|
89
|
+
throw new Error(`Document "${id}" not found`);
|
|
90
|
+
}
|
|
78
91
|
const doc = fresh.resource;
|
|
79
92
|
const markdown = (doc.content as string) ?? "";
|
|
80
93
|
const content = formatDocumentContent(markdown, format);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
3
|
import { resolveAccess } from "@agent-native/core/sharing";
|
|
4
|
-
import { eq } from "drizzle-orm";
|
|
4
|
+
import { and, eq, isNotNull } from "drizzle-orm";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
|
|
7
7
|
import { getDb, schema } from "../server/db/index.js";
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
assertContentDatabaseLifecycleAccess,
|
|
10
10
|
collectInlineDatabaseOwnerBlockIds,
|
|
11
11
|
} from "./_content-database-lifecycle.js";
|
|
12
|
+
import { restoreDocumentSubtree } from "./delete-document.js";
|
|
12
13
|
import pullDocumentAction from "./pull-document.js";
|
|
13
14
|
|
|
14
15
|
async function shouldClearStaleInlineOwnership(args: {
|
|
@@ -47,16 +48,52 @@ export default defineAction({
|
|
|
47
48
|
ownerBlockId: ownership.database.ownerBlockId,
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
await db
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
await db.transaction(async (tx) => {
|
|
52
|
+
const [backingDocument] = await tx
|
|
53
|
+
.select({
|
|
54
|
+
trashedAt: schema.documents.trashedAt,
|
|
55
|
+
trashRootId: schema.documents.trashRootId,
|
|
56
|
+
})
|
|
57
|
+
.from(schema.documents)
|
|
58
|
+
.where(eq(schema.documents.id, ownership.database.documentId))
|
|
59
|
+
.limit(1);
|
|
60
|
+
if (!backingDocument) {
|
|
61
|
+
throw new Error(`Database "${databaseId}" not found`);
|
|
62
|
+
}
|
|
63
|
+
if (
|
|
64
|
+
backingDocument.trashedAt &&
|
|
65
|
+
backingDocument.trashRootId !== ownership.database.documentId
|
|
66
|
+
) {
|
|
67
|
+
throw new Error("Restore the parent Trash item instead");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const restoredDocumentIds = await restoreDocumentSubtree(
|
|
71
|
+
tx as unknown as ReturnType<typeof getDb>,
|
|
72
|
+
ownership.database.documentId,
|
|
73
|
+
ownership.database.ownerEmail,
|
|
74
|
+
);
|
|
75
|
+
if (
|
|
76
|
+
backingDocument.trashedAt &&
|
|
77
|
+
!restoredDocumentIds.includes(ownership.database.documentId)
|
|
78
|
+
) {
|
|
79
|
+
throw new Error("Database backing page was not restored");
|
|
80
|
+
}
|
|
81
|
+
await tx
|
|
82
|
+
.update(schema.contentDatabases)
|
|
83
|
+
.set({
|
|
84
|
+
deletedAt: null,
|
|
85
|
+
updatedAt: now,
|
|
86
|
+
...(clearInlineOwnership
|
|
87
|
+
? { ownerDocumentId: null, ownerBlockId: null }
|
|
88
|
+
: {}),
|
|
89
|
+
})
|
|
90
|
+
.where(
|
|
91
|
+
and(
|
|
92
|
+
eq(schema.contentDatabases.id, databaseId),
|
|
93
|
+
isNotNull(schema.contentDatabases.deletedAt),
|
|
94
|
+
),
|
|
95
|
+
);
|
|
96
|
+
});
|
|
60
97
|
|
|
61
98
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
62
99
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { writeAppState } from "@agent-native/core/application-state";
|
|
3
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
import { getDb } from "../server/db/index.js";
|
|
7
|
+
import { restoreDocumentSubtree } from "./delete-document.js";
|
|
8
|
+
|
|
9
|
+
export default defineAction({
|
|
10
|
+
description: "Restore a page subtree from Trash.",
|
|
11
|
+
schema: z.object({
|
|
12
|
+
id: z.string().describe("Trashed root document ID"),
|
|
13
|
+
}),
|
|
14
|
+
run: async ({ id }) => {
|
|
15
|
+
const access = await assertAccess("document", id, "admin");
|
|
16
|
+
const restored = await getDb().transaction((tx) =>
|
|
17
|
+
restoreDocumentSubtree(
|
|
18
|
+
tx as unknown as ReturnType<typeof getDb>,
|
|
19
|
+
id,
|
|
20
|
+
access.resource.ownerEmail as string,
|
|
21
|
+
),
|
|
22
|
+
);
|
|
23
|
+
if (restored.length === 0) throw new Error("Document is not in Trash");
|
|
24
|
+
|
|
25
|
+
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
26
|
+
return { success: true, restored: restored.length, documentId: id };
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import { accessFilter } from "@agent-native/core/sharing";
|
|
3
|
-
import { and, sql } from "drizzle-orm";
|
|
3
|
+
import { and, isNull, sql } from "drizzle-orm";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
@@ -74,6 +74,7 @@ export default defineAction({
|
|
|
74
74
|
.where(
|
|
75
75
|
and(
|
|
76
76
|
accessFilter(schema.documents, schema.documentShares),
|
|
77
|
+
isNull(schema.documents.trashedAt),
|
|
77
78
|
documentDiscoveryFilter(),
|
|
78
79
|
sql`(${schema.documents.title} LIKE ${pattern} ESCAPE '\\' OR ${schema.documents.description} LIKE ${pattern} ESCAPE '\\' OR ${schema.documents.content} LIKE ${pattern} ESCAPE '\\')`,
|
|
79
80
|
),
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
readAppStateForCurrentTab,
|
|
5
5
|
} from "@agent-native/core/application-state";
|
|
6
6
|
import { accessFilter, resolveAccess } from "@agent-native/core/sharing";
|
|
7
|
-
import { and, asc, inArray } from "drizzle-orm";
|
|
7
|
+
import { and, asc, inArray, isNull } from "drizzle-orm";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
|
|
10
10
|
import { getDb, schema } from "../server/db/index.js";
|
|
@@ -765,6 +765,7 @@ export default defineAction({
|
|
|
765
765
|
.where(
|
|
766
766
|
and(
|
|
767
767
|
accessFilter(schema.documents, schema.documentShares),
|
|
768
|
+
isNull(schema.documents.trashedAt),
|
|
768
769
|
documentDiscoveryFilter(),
|
|
769
770
|
),
|
|
770
771
|
)
|