@agent-native/core 0.114.5 → 0.114.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +8 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/resources/ResourceTree.tsx +11 -5
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +141 -18
- package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +1 -2
- package/corpus/templates/clips/changelog/2026-07-20-opening-zoom-meeting-launches-native-app.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +7 -11
- package/corpus/templates/clips/desktop/src/lib/open-meeting-join-url.ts +22 -0
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -3
- 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/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/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.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/client/resources/ResourceTree.tsx +11 -5
- package/src/client/resources/ResourcesPanel.tsx +141 -18
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.114.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6d96437: Add clear creation actions to empty resource views and improve collaboration usage feedback.
|
|
8
|
+
- Updated dependencies [6d96437]
|
|
9
|
+
- @agent-native/toolkit@0.8.1
|
|
10
|
+
|
|
3
11
|
## 0.114.5
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.114.
|
|
3
|
+
"version": "0.114.6",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -120,6 +120,8 @@ export interface ResourceTreeProps {
|
|
|
120
120
|
headingHint?: React.ReactNode;
|
|
121
121
|
/** Scope-specific action shown beside the section heading. */
|
|
122
122
|
sectionAction?: React.ReactNode;
|
|
123
|
+
/** Scope-specific action shown beneath an empty collection message. */
|
|
124
|
+
emptyStateAction?: React.ReactNode;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
interface CreatingState {
|
|
@@ -638,6 +640,7 @@ export function ResourceTree({
|
|
|
638
640
|
readOnly = false,
|
|
639
641
|
headingHint,
|
|
640
642
|
sectionAction,
|
|
643
|
+
emptyStateAction,
|
|
641
644
|
}: ResourceTreeProps) {
|
|
642
645
|
const [expanded, setExpanded] = useState<Set<string>>(() => new Set());
|
|
643
646
|
const [creating, setCreating] = useState<CreatingState | null>(null);
|
|
@@ -848,11 +851,14 @@ export function ResourceTree({
|
|
|
848
851
|
{isEmpty && !creating && !isLoading && (
|
|
849
852
|
<div className="flex items-start gap-2 border-y border-border/60 px-2 py-4">
|
|
850
853
|
<IconFile className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
|
|
851
|
-
<
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
854
|
+
<div className="flex flex-col items-start gap-2">
|
|
855
|
+
<p className="text-xs text-muted-foreground">
|
|
856
|
+
{variant === "collection"
|
|
857
|
+
? "No resources in this collection yet"
|
|
858
|
+
: "No files yet"}
|
|
859
|
+
</p>
|
|
860
|
+
{emptyStateAction}
|
|
861
|
+
</div>
|
|
856
862
|
</div>
|
|
857
863
|
)}
|
|
858
864
|
</div>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button } from "@agent-native/toolkit/ui/button";
|
|
1
2
|
import {
|
|
2
3
|
IconPlus,
|
|
3
4
|
IconUpload,
|
|
@@ -82,6 +83,42 @@ import {
|
|
|
82
83
|
const WORKSPACE_DOCS_URL = "https://agent-native.com/docs/workspace";
|
|
83
84
|
const LOCAL_WORKSPACE_RESOURCE_METADATA_SOURCE = "local-workspace-resource";
|
|
84
85
|
|
|
86
|
+
const EMPTY_RESOURCE_ACTION_LABELS: Record<ResourceView, string> = {
|
|
87
|
+
files: "Add file",
|
|
88
|
+
instructions: "Add instructions",
|
|
89
|
+
agents: "Add agent",
|
|
90
|
+
memory: "Add memory",
|
|
91
|
+
skills: "Add skill",
|
|
92
|
+
learnings: "Add learning",
|
|
93
|
+
"remote-agents": "Add remote agent",
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const EMPTY_RESOURCE_SEEDS: Partial<
|
|
97
|
+
Record<ResourceView, { path: string; content: string; mimeType?: string }>
|
|
98
|
+
> = {
|
|
99
|
+
instructions: {
|
|
100
|
+
path: "AGENTS.md",
|
|
101
|
+
content: "# Agent Instructions\n\n",
|
|
102
|
+
mimeType: "text/markdown",
|
|
103
|
+
},
|
|
104
|
+
memory: {
|
|
105
|
+
path: "memory/MEMORY.md",
|
|
106
|
+
content: "# Memory\n\n",
|
|
107
|
+
mimeType: "text/markdown",
|
|
108
|
+
},
|
|
109
|
+
learnings: {
|
|
110
|
+
path: "LEARNINGS.md",
|
|
111
|
+
content: "# Learnings\n\n",
|
|
112
|
+
mimeType: "text/markdown",
|
|
113
|
+
},
|
|
114
|
+
"remote-agents": {
|
|
115
|
+
path: "remote-agents/new-agent.json",
|
|
116
|
+
content:
|
|
117
|
+
'{\n "id": "new-agent",\n "name": "New agent",\n "description": "",\n "url": "",\n "color": "#6B7280"\n}\n',
|
|
118
|
+
mimeType: "application/json",
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
85
122
|
export type ResourceView =
|
|
86
123
|
| "files"
|
|
87
124
|
| "instructions"
|
|
@@ -228,6 +265,9 @@ function CreateMenu({
|
|
|
228
265
|
onCreated,
|
|
229
266
|
showToast,
|
|
230
267
|
mcpIntegrations,
|
|
268
|
+
triggerVariant = "icon",
|
|
269
|
+
triggerLabel,
|
|
270
|
+
initialView = "menu",
|
|
231
271
|
}: {
|
|
232
272
|
scope: ResourceScope;
|
|
233
273
|
resourceFilter?: ResourceView;
|
|
@@ -257,6 +297,9 @@ function CreateMenu({
|
|
|
257
297
|
message: string,
|
|
258
298
|
opts?: { resourceId?: string; durationMs?: number },
|
|
259
299
|
) => void;
|
|
300
|
+
triggerVariant?: "icon" | "outline";
|
|
301
|
+
triggerLabel?: string;
|
|
302
|
+
initialView?: CreateMenuView;
|
|
260
303
|
}) {
|
|
261
304
|
const t = useT();
|
|
262
305
|
const [open, setOpen] = useState(false);
|
|
@@ -313,7 +356,7 @@ function CreateMenu({
|
|
|
313
356
|
|
|
314
357
|
useEffect(() => {
|
|
315
358
|
if (open) {
|
|
316
|
-
setView(
|
|
359
|
+
setView(initialView);
|
|
317
360
|
setValue("");
|
|
318
361
|
setAgentName("");
|
|
319
362
|
setAgentDescription("");
|
|
@@ -326,7 +369,7 @@ function CreateMenu({
|
|
|
326
369
|
setSkillUploadFileName("");
|
|
327
370
|
setSkillFlyoutOpen(false);
|
|
328
371
|
}
|
|
329
|
-
}, [open]);
|
|
372
|
+
}, [initialView, open]);
|
|
330
373
|
|
|
331
374
|
useEffect(() => {
|
|
332
375
|
if (view !== "menu" && view !== "agent-form") {
|
|
@@ -642,22 +685,36 @@ The result should be a reusable agent profile, not a one-off task response.`,
|
|
|
642
685
|
e.target.value = "";
|
|
643
686
|
}}
|
|
644
687
|
/>
|
|
645
|
-
|
|
646
|
-
<
|
|
647
|
-
<
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
688
|
+
{triggerVariant === "outline" ? (
|
|
689
|
+
<PopoverTrigger asChild>
|
|
690
|
+
<Button
|
|
691
|
+
type="button"
|
|
692
|
+
variant="outline"
|
|
693
|
+
size="sm"
|
|
694
|
+
className="h-7 gap-1.5 px-2.5 text-xs"
|
|
695
|
+
>
|
|
696
|
+
<IconPlus className="size-3.5" />
|
|
697
|
+
{triggerLabel ?? "Add resource"}
|
|
698
|
+
</Button>
|
|
699
|
+
</PopoverTrigger>
|
|
700
|
+
) : (
|
|
701
|
+
<Tooltip>
|
|
702
|
+
<TooltipTrigger asChild>
|
|
703
|
+
<PopoverTrigger asChild>
|
|
704
|
+
<button
|
|
705
|
+
type="button"
|
|
706
|
+
className={cn(
|
|
707
|
+
"flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50",
|
|
708
|
+
open && "bg-accent/50 text-foreground",
|
|
709
|
+
)}
|
|
710
|
+
>
|
|
711
|
+
<IconPlus className="h-3.5 w-3.5" />
|
|
712
|
+
</button>
|
|
713
|
+
</PopoverTrigger>
|
|
714
|
+
</TooltipTrigger>
|
|
715
|
+
<TooltipContent>Create new...</TooltipContent>
|
|
716
|
+
</Tooltip>
|
|
717
|
+
)}
|
|
661
718
|
<PopoverContent
|
|
662
719
|
align="end"
|
|
663
720
|
sideOffset={6}
|
|
@@ -1522,6 +1579,70 @@ export function ResourcesPanel({
|
|
|
1522
1579
|
);
|
|
1523
1580
|
};
|
|
1524
1581
|
|
|
1582
|
+
const renderEmptyStateAction = (targetScope: ResourceScope) => {
|
|
1583
|
+
if (targetScope === "shared" && !canEditOrg) return null;
|
|
1584
|
+
|
|
1585
|
+
const label = resourceFilter
|
|
1586
|
+
? EMPTY_RESOURCE_ACTION_LABELS[resourceFilter]
|
|
1587
|
+
: "Add resource";
|
|
1588
|
+
|
|
1589
|
+
if (
|
|
1590
|
+
!resourceFilter ||
|
|
1591
|
+
resourceFilter === "files" ||
|
|
1592
|
+
resourceFilter === "agents" ||
|
|
1593
|
+
resourceFilter === "skills"
|
|
1594
|
+
) {
|
|
1595
|
+
return (
|
|
1596
|
+
<CreateMenu
|
|
1597
|
+
scope={targetScope}
|
|
1598
|
+
resourceFilter={resourceFilter}
|
|
1599
|
+
onCreateFile={(name) => handleCreateFromToolbar(targetScope, name)}
|
|
1600
|
+
onCreateResource={(path, content, mimeType, opts) =>
|
|
1601
|
+
handleCreateResourceFromToolbar(
|
|
1602
|
+
targetScope,
|
|
1603
|
+
path,
|
|
1604
|
+
content,
|
|
1605
|
+
mimeType,
|
|
1606
|
+
opts,
|
|
1607
|
+
)
|
|
1608
|
+
}
|
|
1609
|
+
onCreateMcpServer={handleCreateMcpServer}
|
|
1610
|
+
canCreateOrgMcp={canCreateOrgMcp}
|
|
1611
|
+
hasOrg={hasOrgForMcp}
|
|
1612
|
+
showToast={showToast}
|
|
1613
|
+
mcpIntegrations={mcpIntegrations}
|
|
1614
|
+
triggerVariant="outline"
|
|
1615
|
+
triggerLabel={label}
|
|
1616
|
+
initialView={resourceFilter === "files" ? "file" : "menu"}
|
|
1617
|
+
/>
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
const seed = EMPTY_RESOURCE_SEEDS[resourceFilter];
|
|
1622
|
+
if (!seed) return null;
|
|
1623
|
+
|
|
1624
|
+
return (
|
|
1625
|
+
<Button
|
|
1626
|
+
type="button"
|
|
1627
|
+
variant="outline"
|
|
1628
|
+
size="sm"
|
|
1629
|
+
className="h-7 gap-1.5 px-2.5 text-xs"
|
|
1630
|
+
disabled={createResource.isPending}
|
|
1631
|
+
onClick={() =>
|
|
1632
|
+
handleCreateResourceFromToolbar(
|
|
1633
|
+
targetScope,
|
|
1634
|
+
seed.path,
|
|
1635
|
+
seed.content,
|
|
1636
|
+
seed.mimeType,
|
|
1637
|
+
)
|
|
1638
|
+
}
|
|
1639
|
+
>
|
|
1640
|
+
<IconPlus className="size-3.5" />
|
|
1641
|
+
{label}
|
|
1642
|
+
</Button>
|
|
1643
|
+
);
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1525
1646
|
return (
|
|
1526
1647
|
<div
|
|
1527
1648
|
className={cn(
|
|
@@ -1881,6 +2002,7 @@ export function ResourcesPanel({
|
|
|
1881
2002
|
title="Personal"
|
|
1882
2003
|
titleTooltip="Files visible only to you"
|
|
1883
2004
|
sectionAction={renderScopeCreateMenu("personal")}
|
|
2005
|
+
emptyStateAction={renderEmptyStateAction("personal")}
|
|
1884
2006
|
/>
|
|
1885
2007
|
)}
|
|
1886
2008
|
{showSharedTree && (
|
|
@@ -1915,6 +2037,7 @@ export function ResourcesPanel({
|
|
|
1915
2037
|
readOnly={!canEditOrg}
|
|
1916
2038
|
headingHint={!canEditOrg ? "Read only" : undefined}
|
|
1917
2039
|
sectionAction={renderScopeCreateMenu("shared")}
|
|
2040
|
+
emptyStateAction={renderEmptyStateAction("shared")}
|
|
1918
2041
|
/>
|
|
1919
2042
|
)}
|
|
1920
2043
|
</div>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
-
import { resolveNativeMeetingJoinUrl } from "@shared/meeting-join-url";
|
|
3
2
|
import {
|
|
4
3
|
IconCheck,
|
|
5
4
|
IconClock,
|
|
@@ -285,7 +284,7 @@ export function UpcomingMeetingCard({
|
|
|
285
284
|
<div className="flex items-center gap-1.5">
|
|
286
285
|
{meeting.joinUrl && (
|
|
287
286
|
<a
|
|
288
|
-
href={
|
|
287
|
+
href={meeting.joinUrl}
|
|
289
288
|
target="_blank"
|
|
290
289
|
rel="noopener noreferrer"
|
|
291
290
|
onClick={(e) => e.stopPropagation()}
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
getCameraStreamWithFallback,
|
|
56
56
|
isMediaConstraintFailure,
|
|
57
57
|
} from "./lib/media-capture-constraints";
|
|
58
|
-
import {
|
|
58
|
+
import { openMeetingJoinUrl } from "./lib/open-meeting-join-url";
|
|
59
59
|
import {
|
|
60
60
|
DESKTOP_CAPTURE_PERMISSION_MESSAGE,
|
|
61
61
|
isHardCapturePermissionError,
|
|
@@ -1030,11 +1030,9 @@ export function App() {
|
|
|
1030
1030
|
listen<{ joinUrl?: string | null }>("meetings:open-join-url", (ev) => {
|
|
1031
1031
|
const url = ev.payload?.joinUrl;
|
|
1032
1032
|
if (!url) return;
|
|
1033
|
-
|
|
1034
|
-
.
|
|
1035
|
-
|
|
1036
|
-
console.error("[clips-popover] open join url failed:", err);
|
|
1037
|
-
});
|
|
1033
|
+
openMeetingJoinUrl(url).catch((err) => {
|
|
1034
|
+
console.error("[clips-popover] open join url failed:", err);
|
|
1035
|
+
});
|
|
1038
1036
|
})
|
|
1039
1037
|
.then((u) => {
|
|
1040
1038
|
unlisten = u;
|
|
@@ -1162,11 +1160,9 @@ export function App() {
|
|
|
1162
1160
|
const startMeetingNotesAndJoin = useCallback(
|
|
1163
1161
|
(meeting: PopoverMeeting) => {
|
|
1164
1162
|
if (meeting.joinUrl) {
|
|
1165
|
-
|
|
1166
|
-
(err)
|
|
1167
|
-
|
|
1168
|
-
},
|
|
1169
|
-
);
|
|
1163
|
+
openMeetingJoinUrl(meeting.joinUrl).catch((err) => {
|
|
1164
|
+
console.error("[clips-popover] open meeting join url failed:", err);
|
|
1165
|
+
});
|
|
1170
1166
|
}
|
|
1171
1167
|
startMeetingNotes(meeting);
|
|
1172
1168
|
hidePopover();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { open as openExternal } from "@tauri-apps/plugin-shell";
|
|
2
|
+
|
|
3
|
+
import { resolveDesktopMeetingJoinUrl } from "./meeting-join-url";
|
|
4
|
+
|
|
5
|
+
type OpenExternal = (url: string) => Promise<void>;
|
|
6
|
+
|
|
7
|
+
export async function openMeetingJoinUrl(
|
|
8
|
+
joinUrl: string,
|
|
9
|
+
open: OpenExternal = openExternal,
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
const nativeJoinUrl = resolveDesktopMeetingJoinUrl(joinUrl);
|
|
12
|
+
if (nativeJoinUrl === joinUrl) {
|
|
13
|
+
await open(joinUrl);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
await open(nativeJoinUrl);
|
|
19
|
+
} catch {
|
|
20
|
+
await open(joinUrl);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -9,16 +9,15 @@ import { invoke } from "@tauri-apps/api/core";
|
|
|
9
9
|
import { LogicalSize } from "@tauri-apps/api/dpi";
|
|
10
10
|
import { emit, listen } from "@tauri-apps/api/event";
|
|
11
11
|
import { getCurrentWindow } from "@tauri-apps/api/window";
|
|
12
|
-
import { open as openExternal } from "@tauri-apps/plugin-shell";
|
|
13
12
|
import { useEffect, useRef, useState } from "react";
|
|
14
13
|
|
|
15
|
-
import { resolveDesktopMeetingJoinUrl } from "../lib/meeting-join-url";
|
|
16
14
|
import {
|
|
17
15
|
detectMeetingJoinProvider,
|
|
18
16
|
joinProviderLabel,
|
|
19
17
|
meetingNotificationAutoHideMs,
|
|
20
18
|
type MeetingJoinProvider,
|
|
21
19
|
} from "../lib/meeting-notification-timing";
|
|
20
|
+
import { openMeetingJoinUrl } from "../lib/open-meeting-join-url";
|
|
22
21
|
|
|
23
22
|
interface NotificationData {
|
|
24
23
|
type: "calendar" | "adhoc";
|
|
@@ -51,7 +50,7 @@ const NOTIFICATION_MENU_HEIGHT = 224;
|
|
|
51
50
|
async function openJoinUrl(url: string | null | undefined): Promise<void> {
|
|
52
51
|
if (!url) return;
|
|
53
52
|
try {
|
|
54
|
-
await
|
|
53
|
+
await openMeetingJoinUrl(url);
|
|
55
54
|
} catch (err) {
|
|
56
55
|
console.error("[clips-tray] openJoinUrl failed:", err);
|
|
57
56
|
}
|
|
@@ -5,11 +5,6 @@ function isZoomMeetingHost(hostname: string): boolean {
|
|
|
5
5
|
return hostname === "zoom.us" || hostname.endsWith(".zoom.us");
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Prefer Zoom's native URI when an HTTPS calendar link carries a meeting id.
|
|
10
|
-
* Other providers and URL shapes retain their original URL as the safe
|
|
11
|
-
* fallback.
|
|
12
|
-
*/
|
|
13
8
|
export function resolveNativeMeetingJoinUrl(joinUrl: string): string {
|
|
14
9
|
try {
|
|
15
10
|
const url = new URL(joinUrl);
|
|
@@ -82,12 +82,20 @@ pnpm action update-document --id abc123 --description "Stable guidance for what
|
|
|
82
82
|
|
|
83
83
|
### delete-document
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
Move a document and all its children to Trash. IDs, bodies, hierarchy, and
|
|
86
|
+
database membership remain intact so the subtree can be restored.
|
|
86
87
|
|
|
87
88
|
```bash
|
|
88
89
|
pnpm action delete-document --id abc123
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
Restore the root subtree, or permanently delete it only after it is in Trash:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pnpm action restore-document --id abc123
|
|
96
|
+
pnpm action permanently-delete-document --id abc123
|
|
97
|
+
```
|
|
98
|
+
|
|
91
99
|
## Comments
|
|
92
100
|
|
|
93
101
|
Comments are Notion/Google-Docs-style **inline comments**. Selecting text and commenting leaves the passage **highlighted inline** via a ProseMirror decoration overlay — nothing is written into the markdown body, so the document round-trips unchanged. Each thread stores the quoted text plus surrounding context (`anchorPrefix`/`anchorSuffix`) and an approximate `anchorStartOffset`, so the highlight follows the text as the document is edited, disambiguates repeated text, and degrades gracefully (the thread stays in the sidebar) when its text is deleted.
|
|
@@ -146,6 +146,9 @@ cd templates/content && pnpm action <name> [args]
|
|
|
146
146
|
| `get-content-database` | `--databaseId <id>` or `--documentId <id>` | Get a database with its description, property/option schema guidance, item pages, and computed ancestry context |
|
|
147
147
|
| `list-trashed-content-databases` | | List soft-deleted databases visible in the sidebar Trash surface |
|
|
148
148
|
| `restore-content-database` | `--databaseId <id>` | Restore a soft-deleted database from the sidebar Trash surface |
|
|
149
|
+
| `list-trashed-documents` | | List access-filtered page roots visible in the sidebar Trash surface |
|
|
150
|
+
| `restore-document` | `--id <id>` | Restore a page and the subtree moved to Trash with it |
|
|
151
|
+
| `permanently-delete-document` | `--id <id>` | Permanently destroy a document subtree already in Trash |
|
|
149
152
|
| `get-content-database-source` | `--databaseId <id>` or `--documentId <id>` | Inspect local/no-source or source-backed status, mappings, row identity, freshness, and change sets |
|
|
150
153
|
| `attach-content-database-source` | `--databaseId <id>` or `--documentId <id> [--sourceType mock-local\|builder-cms\|local-table\|notion-database] [--sourceName] [--sourceTable] [--relationshipMode items\|details] [--join <json>]` | Attach a source binding; use `items` to add more Builder rows and `details` to match a read-only local/Notion source onto existing rows |
|
|
151
154
|
| `list-notion-database-sources` | `[--query <text>] [--limit <1-100>]` | List Notion data sources visible through the current user's OAuth connection; returns IDs/names only, never tokens |
|
|
@@ -175,7 +178,7 @@ cd templates/content && pnpm action <name> [args]
|
|
|
175
178
|
| `reorder-document-property` | `--documentId <id> --propertyId <propertyId> --targetPropertyId <id> [--position before\|after]` | Reorder a property definition within its database (used to reorder Blocks fields on the page) |
|
|
176
179
|
| `set-document-discoverability` | `--id <id> --hideFromSearch true\|false [--includeChildren true\|false]` | Hide/show an org-accessible document in Organization/search while keeping link access |
|
|
177
180
|
| `move-document` | `--id <id> [--parentId] [--position]` | Move or reorder a document in the page tree |
|
|
178
|
-
| `delete-document` | `--id <id>` |
|
|
181
|
+
| `delete-document` | `--id <id>` | Move a document and its recursive children to Trash |
|
|
179
182
|
|
|
180
183
|
Database views follow Notion-style tab labels. When creating or duplicating
|
|
181
184
|
views in `viewConfig`, use unique default names (`Table 2`, `SEO copy 2`, etc.)
|
|
@@ -806,7 +806,11 @@ async function provisionOwnedContentSpace(
|
|
|
806
806
|
export async function provisionSourceBackedContentSpace(
|
|
807
807
|
db: Db,
|
|
808
808
|
userEmail: string,
|
|
809
|
-
input: {
|
|
809
|
+
input: {
|
|
810
|
+
connectionId: string;
|
|
811
|
+
name: string;
|
|
812
|
+
propertyValues?: Record<string, unknown>;
|
|
813
|
+
},
|
|
810
814
|
) {
|
|
811
815
|
const connectionId = input.connectionId.trim();
|
|
812
816
|
if (!connectionId) throw new Error("Local folder connection ID is required");
|
|
@@ -814,6 +818,7 @@ export async function provisionSourceBackedContentSpace(
|
|
|
814
818
|
spaceId: sourceBackedContentSpaceId(userEmail, connectionId),
|
|
815
819
|
name: input.name.trim() || "Local folder",
|
|
816
820
|
kind: "source_backed",
|
|
821
|
+
propertyValues: input.propertyValues,
|
|
817
822
|
});
|
|
818
823
|
}
|
|
819
824
|
|
|
@@ -151,6 +151,7 @@ export async function resolveDatabaseRowsForBatch(
|
|
|
151
151
|
eq(schema.contentDatabaseItems.databaseId, database.id),
|
|
152
152
|
rowPredicates.length === 1 ? rowPredicates[0] : or(...rowPredicates),
|
|
153
153
|
isNull(schema.contentDatabases.deletedAt),
|
|
154
|
+
isNull(schema.documents.trashedAt),
|
|
154
155
|
),
|
|
155
156
|
)
|
|
156
157
|
.orderBy(asc(schema.contentDatabaseItems.position));
|
|
@@ -185,9 +186,21 @@ export async function renumberDatabaseRows(
|
|
|
185
186
|
now: string,
|
|
186
187
|
) {
|
|
187
188
|
const rows = await db
|
|
188
|
-
.select(
|
|
189
|
+
.select({
|
|
190
|
+
id: schema.contentDatabaseItems.id,
|
|
191
|
+
documentId: schema.contentDatabaseItems.documentId,
|
|
192
|
+
})
|
|
189
193
|
.from(schema.contentDatabaseItems)
|
|
190
|
-
.
|
|
194
|
+
.innerJoin(
|
|
195
|
+
schema.documents,
|
|
196
|
+
eq(schema.documents.id, schema.contentDatabaseItems.documentId),
|
|
197
|
+
)
|
|
198
|
+
.where(
|
|
199
|
+
and(
|
|
200
|
+
eq(schema.contentDatabaseItems.databaseId, database.id),
|
|
201
|
+
isNull(schema.documents.trashedAt),
|
|
202
|
+
),
|
|
203
|
+
)
|
|
191
204
|
.orderBy(asc(schema.contentDatabaseItems.position));
|
|
192
205
|
if (rows.length === 0) return;
|
|
193
206
|
|