@hiai-gg/docsmint 0.5.2 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/backend/index.js +1 -1
  2. package/dist/frontend/{CategoryDialog-DmlX0Z97.js → CategoryDialog-BYAFjX7E.js} +152 -138
  3. package/dist/frontend/{FolderNode-D3rN3yLV.js → FolderNode-DAAn_T8_.js} +1 -1
  4. package/dist/frontend/SettingsDialog-CyZSOjLE.js +1024 -0
  5. package/dist/frontend/{Sidebar-BnZgNl_8.js → Sidebar-B-zCJT9i.js} +4 -4
  6. package/dist/frontend/app-shell.js +160 -126
  7. package/dist/frontend/components/category-dialog.js +1 -1
  8. package/dist/frontend/components/folder-node.js +1 -1
  9. package/dist/frontend/components/save-as-dialog.js +1 -1
  10. package/dist/frontend/components/settings.js +1 -1
  11. package/dist/frontend/components/sidebar.js +1 -1
  12. package/dist/frontend/dashboard.js +994 -958
  13. package/dist/frontend/folder-refresh.js +1 -1
  14. package/dist/frontend/frontend.css +1 -1
  15. package/dist/frontend/search.js +593 -575
  16. package/dist/frontend/{subfolders-refresh-store.svelte-B2dKVmgz.js → subfolders-refresh-store.svelte-DxP21a1c.js} +1 -0
  17. package/dist/frontend-ssr/app-shell.js +62 -3
  18. package/dist/frontend-ssr/assets/{CategoryDialog-Cnlmr1sz.js → CategoryDialog-BLxVoynx.js} +26 -9
  19. package/dist/frontend-ssr/assets/{FolderNode-CnFVWuQi.js → FolderNode-kmilhDjO.js} +1 -1
  20. package/dist/frontend-ssr/assets/{SettingsDialog-BPdUl6pd.js → SettingsDialog-DVp0OxPO.js} +2 -2
  21. package/dist/frontend-ssr/assets/{Sidebar-DwYZH0Tr.js → Sidebar-CO9LZRPa.js} +4 -4
  22. package/dist/frontend-ssr/assets/{subfolders-refresh-store.svelte-DAh4gT16.js → subfolders-refresh-store.svelte-CXHxQWKh.js} +1 -0
  23. package/dist/frontend-ssr/components/category-dialog.js +1 -1
  24. package/dist/frontend-ssr/components/folder-node.js +1 -1
  25. package/dist/frontend-ssr/components/save-as-dialog.js +1 -1
  26. package/dist/frontend-ssr/components/settings.js +1 -1
  27. package/dist/frontend-ssr/components/sidebar.js +1 -1
  28. package/dist/frontend-ssr/dashboard.js +38 -4
  29. package/dist/frontend-ssr/folder-refresh.js +1 -1
  30. package/dist/frontend-ssr/search.js +52 -33
  31. package/package.json +1 -1
  32. package/packages/cli/src/index.ts +1 -1
  33. package/packages/mcp-server/src/index.ts +1 -1
  34. package/dist/frontend/SettingsDialog-Bd_S2RKW.js +0 -1024
@@ -3,6 +3,7 @@ import * as e from "svelte/internal/client";
3
3
  var t = e.proxy({}), n = e.proxy({}), r = e.proxy({}), i = e.state(0), a = e.state(null), o = e.proxy({}), s = e.state(0);
4
4
  function c() {
5
5
  e.update(s);
6
+ for (let e of Object.keys(n)) t[e] = (t[e] ?? 0) + 1;
6
7
  }
7
8
  function l() {
8
9
  return e.get(s);
@@ -1,8 +1,10 @@
1
1
  import { E as scroll_to_top_aria } from "./assets/messages-BAQzILs4.js";
2
2
  import { t as Icon } from "./assets/Icon-QwirKi9Y.js";
3
- import { n as searchPreferences, r as editorPreferences } from "./assets/SettingsDialog-BPdUl6pd.js";
4
- import { t as Sidebar } from "./assets/Sidebar-DwYZH0Tr.js";
3
+ import { n as searchPreferences, r as editorPreferences } from "./assets/SettingsDialog-DVp0OxPO.js";
4
+ import { t as Sidebar } from "./assets/Sidebar-CO9LZRPa.js";
5
5
  import { o as provideDocsmintRequestAdapter, r as provideDocsmintRouteAdapter } from "./assets/route-context-BPRerEtZ.js";
6
+ import { d as refreshFolders } from "./assets/subfolders-refresh-store.svelte-CXHxQWKh.js";
7
+ import { n as refreshDocs, r as refreshTags } from "./assets/tag-store.svelte-BM1lUI_P.js";
6
8
  import { t as HiaiDocsExtensionProvider } from "./assets/HiaiDocsExtensionProvider-BRKWmcDd.js";
7
9
  import * as $ from "svelte/internal/server";
8
10
  import { getContext, onDestroy, setContext, untrack } from "svelte";
@@ -211,6 +213,54 @@ function ScrollToTop($$renderer, $$props) {
211
213
  });
212
214
  }
213
215
  //#endregion
216
+ //#region src/lib/hosts/mutation-refresh.ts
217
+ var noImpact = {
218
+ documents: false,
219
+ folders: false,
220
+ tags: false
221
+ };
222
+ function mutationRefreshImpact(input, init) {
223
+ const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
224
+ if (![
225
+ "POST",
226
+ "PUT",
227
+ "PATCH",
228
+ "DELETE"
229
+ ].includes(method)) return noImpact;
230
+ const rawUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
231
+ const pathname = new URL(rawUrl, "http://docsmint.local").pathname;
232
+ if (/\/keys(?:\/|$)/.test(pathname)) return noImpact;
233
+ if (/^\/api\/(?:v1\/)?tags(?:\/|$)/.test(pathname)) return {
234
+ documents: true,
235
+ folders: false,
236
+ tags: true
237
+ };
238
+ if (/^\/api\/(?:v1\/)?documents\/[^/]+\/tags(?:\/|$)/.test(pathname)) return {
239
+ documents: true,
240
+ folders: false,
241
+ tags: true
242
+ };
243
+ if (/^\/api\/(?:v1\/)?(?:folders|categories)(?:\/|$)/.test(pathname)) return {
244
+ documents: true,
245
+ folders: true,
246
+ tags: false
247
+ };
248
+ if (/^\/api\/(?:v1\/)?trash(?:\/|$)/.test(pathname)) return {
249
+ documents: true,
250
+ folders: true,
251
+ tags: false
252
+ };
253
+ if (/^\/api\/(?:v1\/)?(?:documents|import|imports)(?:\/|$)/.test(pathname)) return {
254
+ documents: true,
255
+ folders: true,
256
+ tags: false
257
+ };
258
+ return noImpact;
259
+ }
260
+ function hasMutationRefreshImpact(impact) {
261
+ return impact.documents || impact.folders || impact.tags;
262
+ }
263
+ //#endregion
214
264
  //#region src/lib/hosts/realtime-context.ts
215
265
  var REALTIME_ADAPTER = Symbol("docsmint-realtime-adapter");
216
266
  function provideDocsmintRealtimeAdapter(adapter) {
@@ -232,7 +282,16 @@ function DocsmintAppShellHost($$renderer, $$props) {
232
282
  resolve: (path) => route.resolve(path),
233
283
  navigate: (path, options) => route.navigate?.(path, options)
234
284
  });
235
- provideDocsmintRequestAdapter({ fetch: (...args) => request.fetch(...args) });
285
+ provideDocsmintRequestAdapter({ fetch: async (...args) => {
286
+ const response = await request.fetch(...args);
287
+ const impact = mutationRefreshImpact(args[0], args[1]);
288
+ if (response.ok && hasMutationRefreshImpact(impact)) {
289
+ if (impact.documents) refreshDocs();
290
+ if (impact.folders) refreshFolders();
291
+ if (impact.tags) refreshTags();
292
+ }
293
+ return response;
294
+ } });
236
295
  const realtimeAdapter = untrack(() => realtime);
237
296
  if (realtimeAdapter) provideDocsmintRealtimeAdapter(realtimeAdapter);
238
297
  editorPreferences.init();
@@ -9,6 +9,16 @@ import { t as Label } from "./label-Bj8-TfFN.js";
9
9
  import { a as listApiKeys, n as categoryIdFromScopes, o as revealCategoryApiKey, r as createCategoryApiKey, s as revokeApiKey, t as apiKeyClipboardValue } from "./api-keys-DIbclwj5.js";
10
10
  import { a as Select, i as Select_content, n as Select_trigger, r as Select_item, t as Select_value } from "./select-value-DBhbkNcc.js";
11
11
  import * as $ from "svelte/internal/server";
12
+ //#region src/lib/components/sidebar/category-api-key-flow.ts
13
+ async function issueCategoryKeyAfterSavingAccess(input) {
14
+ if (!input.draft.name.trim()) throw new Error("Name is required");
15
+ if (input.draft.apiMode !== "category") throw new Error("Select Category API access");
16
+ if (!input.draft.apiPermissionRead && !input.draft.apiPermissionEdit && !input.draft.apiPermissionWrite) throw new Error("Select at least one permission");
17
+ const saved = await input.save(input.draft);
18
+ if (!saved || saved.id !== input.categoryId) throw new Error("Failed to save Category API access");
19
+ return input.issue(input.categoryId);
20
+ }
21
+ //#endregion
12
22
  //#region src/lib/components/sidebar/category-dialog-feedback.ts
13
23
  function categoryDialogErrorMessage(error, fallback) {
14
24
  if (typeof error === "object" && error !== null && "status" in error && error.status === 409) return "A category with this name already exists.";
@@ -47,10 +57,22 @@ function CategoryDialog($$renderer, $$props) {
47
57
  categoryKeys = (await listApiKeys(request.fetch)).keys.filter((key) => categoryIdFromScopes(key.scopes) === categoryId);
48
58
  }
49
59
  async function issueCategoryKey() {
50
- if (!category?.id) return;
60
+ if (!category?.id || !onSave) return;
51
61
  keyBusy = true;
62
+ error = null;
52
63
  try {
53
- const issued = await createCategoryApiKey(category.id, void 0, request.fetch);
64
+ const issued = await issueCategoryKeyAfterSavingAccess({
65
+ categoryId: category.id,
66
+ draft: {
67
+ name: trimmedName(),
68
+ apiMode: normalizeApiMode(apiMode),
69
+ apiPermissionRead,
70
+ apiPermissionEdit,
71
+ apiPermissionWrite
72
+ },
73
+ save: async (payload) => onSave(payload),
74
+ issue: async (categoryId) => createCategoryApiKey(categoryId, void 0, request.fetch)
75
+ });
54
76
  issuedKeys = {
55
77
  ...issuedKeys,
56
78
  [issued.id]: issued.key
@@ -462,23 +484,18 @@ function CategoryDialog($$renderer, $$props) {
462
484
  },
463
485
  $$slots: { default: true }
464
486
  });
465
- $$renderer.push(`<!----><p class="text-xs text-muted-foreground">Keys inherit the saved permissions above.</p></div> `);
487
+ $$renderer.push(`<!----><p class="text-xs text-muted-foreground">The current permissions are saved before the key is issued.</p></div> `);
466
488
  Button($$renderer, {
467
489
  type: "button",
468
490
  size: "sm",
469
491
  onclick: issueCategoryKey,
470
- disabled: busy || keyBusy || category.apiMode !== "category",
492
+ disabled: busy || keyBusy || !trimmedName() || !hasAnyPermission(),
471
493
  children: ($$renderer) => {
472
494
  $$renderer.push(`<!---->Create key`);
473
495
  },
474
496
  $$slots: { default: true }
475
497
  });
476
498
  $$renderer.push(`<!----></div> `);
477
- if (category.apiMode !== "category") {
478
- $$renderer.push("<!--[0-->");
479
- $$renderer.push(`<p class="text-xs text-muted-foreground">Save Category API access first, then reopen settings to issue a key.</p>`);
480
- } else $$renderer.push("<!--[-1-->");
481
- $$renderer.push(`<!--]--> `);
482
499
  if (latestIssuedKey()) {
483
500
  $$renderer.push("<!--[0-->");
484
501
  $$renderer.push(`<div class="rounded-lg border border-primary/30 bg-primary/10 p-3 text-primary"><p class="text-xs font-medium">Copy now — this raw key is shown once.</p> <code class="mt-1 block break-all rounded bg-background/80 p-2 text-xs text-foreground">${$.escape(latestIssuedKey())}</code> `);
@@ -5,7 +5,7 @@ import { a as Dropdown_menu, i as Dropdown_menu_content, o as Ellipsis_vertical,
5
5
  import { a as getDocsmintRequestAdapter, n as navigateDocsmintRoute, t as getDocsmintRouteAdapter } from "./route-context-BPRerEtZ.js";
6
6
  import { t as cn } from "./utils-DvZnctjz.js";
7
7
  import "./dndzone-DMvTO_Jz.js";
8
- import "./subfolders-refresh-store.svelte-DAh4gT16.js";
8
+ import "./subfolders-refresh-store.svelte-CXHxQWKh.js";
9
9
  import * as $ from "svelte/internal/server";
10
10
  import { page } from "$app/state";
11
11
  import "svelte/animate";
@@ -840,7 +840,7 @@ function SettingsDialog($$renderer, $$props) {
840
840
  });
841
841
  $$renderer.push(`<!----> <p class="text-xs text-muted-foreground">${$.escape(settings_email_change_warning())}</p> `);
842
842
  $$renderer.push("<!--[-1-->");
843
- $$renderer.push(`<!--]--></div> <div class="flex items-center justify-between gap-4 rounded-md border p-3"><span><span class="block text-sm font-medium">GraphRAG search</span> <span class="block text-xs text-muted-foreground">Use graph expansion for related documents. Disable it for faster standard RAG search.</span></span> <button type="button" role="switch"${$.attr_class("preference-switch svelte-1eaqpj", void 0, { "enabled": searchPreferences.graphSearchEnabled })}${$.attr("aria-checked", searchPreferences.graphSearchEnabled)} aria-label="Use GraphRAG search"><span class="svelte-1eaqpj"></span></button></div> <!--[-->`);
843
+ $$renderer.push(`<!--]--></div> <details class="profile-advanced border-t pt-4 svelte-1eaqpj"><summary class="flex cursor-pointer items-center justify-between gap-3 rounded-md px-1 py-2 svelte-1eaqpj"><span><span class="block text-sm font-medium">Advanced</span> <span class="block text-xs text-muted-foreground">Search and additional profile controls</span></span> <span class="profile-advanced-chevron svelte-1eaqpj" aria-hidden="true">⌄</span></summary> <div class="mt-3 space-y-3"><div class="flex items-center justify-between gap-4 rounded-md border p-3"><span><span class="block text-sm font-medium">GraphRAG search</span> <span class="block text-xs text-muted-foreground">Use graph expansion for related documents. Disable it for faster standard RAG search.</span></span> <button type="button" role="switch"${$.attr_class("preference-switch svelte-1eaqpj", void 0, { "enabled": searchPreferences.graphSearchEnabled })}${$.attr("aria-checked", searchPreferences.graphSearchEnabled)} aria-label="Use GraphRAG search"><span class="svelte-1eaqpj"></span></button></div> <!--[-->`);
844
844
  const each_array_1 = $.ensure_array_like(profileActions());
845
845
  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
846
846
  const ProfileAction = each_array_1[$$index_1].component;
@@ -853,7 +853,7 @@ function SettingsDialog($$renderer, $$props) {
853
853
  $$renderer.push("<!--]-->");
854
854
  }
855
855
  }
856
- $$renderer.push(`<!--]--> `);
856
+ $$renderer.push(`<!--]--></div></details> `);
857
857
  $$renderer.push("<!--[-1-->");
858
858
  $$renderer.push(`<!--]--> `);
859
859
  Button($$renderer, {
@@ -6,7 +6,7 @@ import { t as Chevron_right } from "./chevron-right-DKD7WXjz.js";
6
6
  import { t as Clock } from "./clock-CzsE58TH.js";
7
7
  import { t as Copy } from "./copy-DkkCPkBL.js";
8
8
  import { t as Folder } from "./folder-DYIE-XPP.js";
9
- import { t as SettingsDialog } from "./SettingsDialog-BPdUl6pd.js";
9
+ import { t as SettingsDialog } from "./SettingsDialog-DVp0OxPO.js";
10
10
  import { n as Search, t as Tag } from "./tag-BmiVU_Ej.js";
11
11
  import { a as Dropdown_menu, i as Dropdown_menu_content, o as Ellipsis_vertical, r as Dropdown_menu_item, t as Dropdown_menu_trigger } from "./dropdown-menu-Dn_vQq9b.js";
12
12
  import { t as Loader_circle } from "./loader-circle-CIEWGyfP.js";
@@ -24,10 +24,10 @@ import { c as updateDocument, r as deleteDocument, s as listDocuments, t as clea
24
24
  import { c as updateFolder, r as deleteFolder, s as listFolders, t as createFolder } from "./folders-BX30gHv6.js";
25
25
  import { t as DeleteDialog } from "./DeleteDialog-DG9Lm38J.js";
26
26
  import { t as ShareDialog } from "./ShareDialog-BZd28sg-.js";
27
- import { t as CategoryDialog } from "./CategoryDialog-Cnlmr1sz.js";
27
+ import { t as CategoryDialog } from "./CategoryDialog-BLxVoynx.js";
28
28
  import { n as createDocumentPlacementWriter, t as createDocumentDropCoordinator } from "./document-drop-coordinator-CEaYACsC.js";
29
- import { a as getFolderFromRegistry, c as getPendingDocumentPlacement, d as refreshFolders, f as registerDocument, n as bumpSubfoldersRefresh, p as registerFolder, r as getDocumentFromRegistry, t as acknowledgeDocumentPlacement, u as publishDocumentPlacement } from "./subfolders-refresh-store.svelte-DAh4gT16.js";
30
- import { t as FolderNode } from "./FolderNode-CnFVWuQi.js";
29
+ import { a as getFolderFromRegistry, c as getPendingDocumentPlacement, d as refreshFolders, f as registerDocument, n as bumpSubfoldersRefresh, p as registerFolder, r as getDocumentFromRegistry, t as acknowledgeDocumentPlacement, u as publishDocumentPlacement } from "./subfolders-refresh-store.svelte-CXHxQWKh.js";
30
+ import { t as FolderNode } from "./FolderNode-kmilhDjO.js";
31
31
  import { i as setSelectedTag, n as refreshDocs, r as refreshTags, t as getSelectedTag } from "./tag-store.svelte-BM1lUI_P.js";
32
32
  import { t as ConfirmDialog } from "./ConfirmDialog-BhAelejz.js";
33
33
  import { i as deleteTag, o as listTags } from "./tags-BQsI_6OW.js";
@@ -9,6 +9,7 @@ var pendingDocumentPlacements = {};
9
9
  var globalFolderRefreshNonce = 0;
10
10
  function refreshFolders() {
11
11
  globalFolderRefreshNonce++;
12
+ for (const folderId of Object.keys(foldersRegistry)) refreshNonces[folderId] = (refreshNonces[folderId] ?? 0) + 1;
12
13
  }
13
14
  function getGlobalFolderRefreshNonce() {
14
15
  return globalFolderRefreshNonce;
@@ -1,2 +1,2 @@
1
- import { t as CategoryDialog } from "../assets/CategoryDialog-Cnlmr1sz.js";
1
+ import { t as CategoryDialog } from "../assets/CategoryDialog-BLxVoynx.js";
2
2
  export { CategoryDialog };
@@ -1,2 +1,2 @@
1
- import { t as FolderNode } from "../assets/FolderNode-CnFVWuQi.js";
1
+ import { t as FolderNode } from "../assets/FolderNode-kmilhDjO.js";
2
2
  export { FolderNode };
@@ -7,7 +7,7 @@ import { a as Dialog, i as Dialog_description, n as Dialog_header, o as Button,
7
7
  import { t as Label } from "../assets/label-Bj8-TfFN.js";
8
8
  import "../assets/categories-av9xjeg5.js";
9
9
  import { a as Select, i as Select_content, n as Select_trigger, r as Select_item, t as Select_value } from "../assets/select-value-DBhbkNcc.js";
10
- import { d as refreshFolders } from "../assets/subfolders-refresh-store.svelte-DAh4gT16.js";
10
+ import { d as refreshFolders } from "../assets/subfolders-refresh-store.svelte-CXHxQWKh.js";
11
11
  import * as $ from "svelte/internal/server";
12
12
  //#region src/lib/components/SaveAsDialog.svelte
13
13
  function SaveAsDialog($$renderer, $$props) {
@@ -1,2 +1,2 @@
1
- import { t as SettingsDialog } from "../assets/SettingsDialog-BPdUl6pd.js";
1
+ import { t as SettingsDialog } from "../assets/SettingsDialog-DVp0OxPO.js";
2
2
  export { SettingsDialog };
@@ -1,2 +1,2 @@
1
- import { t as Sidebar } from "../assets/Sidebar-DwYZH0Tr.js";
1
+ import { t as Sidebar } from "../assets/Sidebar-CO9LZRPa.js";
2
2
  export { Sidebar };
@@ -1,4 +1,4 @@
1
- import { Cr as doc_open, Dr as doc_share, Fr as dashboard_page_title, Ir as dashboard_new_document, Lr as dashboard_subtitle, Rr as dashboard_title, Sr as doc_duplicate, Tr as doc_updated, _n as action_cancel, _r as folders_rename, _t as folder_page_title, a as import_progress_error, bt as editor_more_options, c as import_progress_queued, cr as folders_subfolders, d as import_progress_title, f as sidebar_uncategorized, fn as action_back, gn as action_delete, gr as folders_delete, gt as share_copied, hr as folders_delete_title, i as import_progress_summary, k as dashboard_import, l as import_progress_uploading, lr as folders_document, mr as folders_delete_description, n as import_progress_empty, o as import_progress_done, or as folders_move, pn as action_close, r as import_progress_close, s as import_progress_processing, sr as folders_subfolder, u as import_progress_total, un as action_loading, ur as folders_documents, vn as action_save, vr as folders_empty_description, wr as doc_open_menu, xr as doc_move_to_folder, yr as folders_empty, yt as action_copy_content, zr as nav_documents } from "./assets/messages-BAQzILs4.js";
1
+ import { Cr as doc_open, Dr as doc_share, Fr as dashboard_page_title, Ir as dashboard_new_document, Lr as dashboard_subtitle, Pr as doc_title_placeholder, Rr as dashboard_title, Sr as doc_duplicate, Tr as doc_updated, _n as action_cancel, _r as folders_rename, _t as folder_page_title, a as import_progress_error, bt as editor_more_options, c as import_progress_queued, cr as folders_subfolders, d as import_progress_title, f as sidebar_uncategorized, fn as action_back, gn as action_delete, gr as folders_delete, gt as share_copied, hr as folders_delete_title, i as import_progress_summary, k as dashboard_import, l as import_progress_uploading, lr as folders_document, mr as folders_delete_description, n as import_progress_empty, o as import_progress_done, or as folders_move, pn as action_close, r as import_progress_close, s as import_progress_processing, sr as folders_subfolder, u as import_progress_total, un as action_loading, ur as folders_documents, vn as action_save, vr as folders_empty_description, wr as doc_open_menu, xr as doc_move_to_folder, yr as folders_empty, yt as action_copy_content, zr as nav_documents } from "./assets/messages-BAQzILs4.js";
2
2
  import { t as Icon } from "./assets/Icon-QwirKi9Y.js";
3
3
  import { i as Folder_kanban, n as Badge, r as X, t as DatePicker } from "./assets/DatePicker-D84cJ-Eq.js";
4
4
  import { i as Check, n as Plus, r as File_text, t as FolderDialog } from "./assets/confirm-dialog-XuyaL8sr.js";
@@ -25,7 +25,7 @@ import { c as updateDocument, i as getDocument } from "./assets/documents-CZ-wQo
25
25
  import { c as updateFolder, i as duplicateDocument } from "./assets/folders-BX30gHv6.js";
26
26
  import { t as copyToClipboard } from "./assets/clipboard-CXOaoz2W.js";
27
27
  import { t as ShareDialog } from "./assets/ShareDialog-BZd28sg-.js";
28
- import { d as refreshFolders, n as bumpSubfoldersRefresh } from "./assets/subfolders-refresh-store.svelte-DAh4gT16.js";
28
+ import { d as refreshFolders, n as bumpSubfoldersRefresh } from "./assets/subfolders-refresh-store.svelte-CXHxQWKh.js";
29
29
  import { n as refreshDocs } from "./assets/tag-store.svelte-BM1lUI_P.js";
30
30
  import { t as ConfirmDialog } from "./assets/ConfirmDialog-BhAelejz.js";
31
31
  import * as $ from "svelte/internal/server";
@@ -1787,6 +1787,10 @@ function HiaiDocsDashboardHost($$renderer, $$props) {
1787
1787
  let showDeleteFolderDialog = false;
1788
1788
  let deleteFolderTargetId = null;
1789
1789
  let deleteFolderBusy = false;
1790
+ let showDeleteDocumentDialog = false;
1791
+ let deleteDocumentTargetId = null;
1792
+ let deleteDocumentTargetTitle = "";
1793
+ let deleteDocumentBusy = false;
1790
1794
  let showShareDialog = false;
1791
1795
  let shareTarget = null;
1792
1796
  let importOpen = false;
@@ -1874,14 +1878,26 @@ function HiaiDocsDashboardHost($$renderer, $$props) {
1874
1878
  deleteFolderBusy = false;
1875
1879
  }
1876
1880
  }
1877
- async function handleDeleteDocument(id) {
1878
- if (!confirm(`${action_delete()}?`)) return;
1881
+ function handleDeleteDocument(id) {
1882
+ const document = filteredDocuments().find((candidate) => candidate.id === id);
1883
+ deleteDocumentTargetId = id;
1884
+ deleteDocumentTargetTitle = document?.title || doc_title_placeholder();
1885
+ showDeleteDocumentDialog = true;
1886
+ }
1887
+ async function confirmDeleteDocument() {
1888
+ const id = deleteDocumentTargetId;
1889
+ if (!id || deleteDocumentBusy) return;
1890
+ deleteDocumentBusy = true;
1879
1891
  try {
1880
1892
  await apiFetch(`/api/documents/${id}`, { method: "DELETE" }, request.fetch);
1893
+ showDeleteDocumentDialog = false;
1894
+ deleteDocumentTargetId = null;
1881
1895
  await invalidateAll();
1882
1896
  refreshDocs();
1883
1897
  } catch (e) {
1884
1898
  console.error("Failed to delete document", e);
1899
+ } finally {
1900
+ deleteDocumentBusy = false;
1885
1901
  }
1886
1902
  }
1887
1903
  async function handleDuplicateDocument(id) {
@@ -2676,6 +2692,24 @@ function HiaiDocsDashboardHost($$renderer, $$props) {
2676
2692
  }
2677
2693
  });
2678
2694
  $$renderer.push(`<!----> `);
2695
+ ConfirmDialog($$renderer, {
2696
+ title: "Move to Trash?",
2697
+ description: `“${deleteDocumentTargetTitle}” will be moved to Trash and can be restored later.`,
2698
+ confirmLabel: "Move to Trash",
2699
+ cancelLabel: action_cancel(),
2700
+ variant: "destructive",
2701
+ busy: deleteDocumentBusy,
2702
+ onConfirm: confirmDeleteDocument,
2703
+ onCancel: () => showDeleteDocumentDialog = false,
2704
+ get open() {
2705
+ return showDeleteDocumentDialog;
2706
+ },
2707
+ set open($$value) {
2708
+ showDeleteDocumentDialog = $$value;
2709
+ $$settled = false;
2710
+ }
2711
+ });
2712
+ $$renderer.push(`<!----> `);
2679
2713
  if (shareTarget) {
2680
2714
  $$renderer.push("<!--[0-->");
2681
2715
  ShareDialog($$renderer, {
@@ -1,2 +1,2 @@
1
- import { a as getFolderFromRegistry, c as getPendingDocumentPlacement, d as refreshFolders, f as registerDocument, i as getDocumentPlacementNonce, l as getSubfoldersRefresh, m as supersedePendingDocumentPlacement, n as bumpSubfoldersRefresh, o as getGlobalFolderRefreshNonce, p as registerFolder, r as getDocumentFromRegistry, s as getLatestDocumentPlacement, t as acknowledgeDocumentPlacement, u as publishDocumentPlacement } from "./assets/subfolders-refresh-store.svelte-DAh4gT16.js";
1
+ import { a as getFolderFromRegistry, c as getPendingDocumentPlacement, d as refreshFolders, f as registerDocument, i as getDocumentPlacementNonce, l as getSubfoldersRefresh, m as supersedePendingDocumentPlacement, n as bumpSubfoldersRefresh, o as getGlobalFolderRefreshNonce, p as registerFolder, r as getDocumentFromRegistry, s as getLatestDocumentPlacement, t as acknowledgeDocumentPlacement, u as publishDocumentPlacement } from "./assets/subfolders-refresh-store.svelte-CXHxQWKh.js";
2
2
  export { acknowledgeDocumentPlacement, bumpSubfoldersRefresh, getDocumentFromRegistry, getDocumentPlacementNonce, getFolderFromRegistry, getGlobalFolderRefreshNonce, getLatestDocumentPlacement, getPendingDocumentPlacement, getSubfoldersRefresh, publishDocumentPlacement, refreshFolders, registerDocument, registerFolder, supersedePendingDocumentPlacement };
@@ -95,6 +95,24 @@ function Sliders_horizontal($$renderer, $$props) {
95
95
  ]));
96
96
  }
97
97
  //#endregion
98
+ //#region src/lib/hosts/search-folder-options.ts
99
+ function effectiveCategoryId(folder, byId) {
100
+ const seen = /* @__PURE__ */ new Set();
101
+ let current = folder;
102
+ while (current && !seen.has(current.id)) {
103
+ seen.add(current.id);
104
+ if (current.categoryId) return current.categoryId;
105
+ current = current.parentId ? byId.get(current.parentId) : void 0;
106
+ }
107
+ return null;
108
+ }
109
+ /** Folder names visible under the currently selected search category. */
110
+ function folderNamesForSearchCategory(fallbackNames, folders, categoryId) {
111
+ if (!categoryId) return [...fallbackNames];
112
+ const byId = new Map(folders.map((folder) => [folder.id, folder]));
113
+ return [...new Set(folders.filter((folder) => effectiveCategoryId(folder, byId) === categoryId).map((folder) => folder.name))];
114
+ }
115
+ //#endregion
98
116
  //#region src/lib/hosts/HiaiDocsSearchHost.svelte
99
117
  function HiaiDocsSearchHost($$renderer, $$props) {
100
118
  $$renderer.component(($$renderer) => {
@@ -132,6 +150,7 @@ function HiaiDocsSearchHost($$renderer, $$props) {
132
150
  if (!queryLower()) return [];
133
151
  return allCategories.filter((c) => c.name.toLowerCase().includes(queryLower()));
134
152
  });
153
+ const visibleFolderNames = $.derived(() => folderNamesForSearchCategory(folders, allFolders, activeCategoryId));
135
154
  $.derived(() => matchingDocs().length > 0 || matchingFolders().length > 0 || matchingCategories().length > 0);
136
155
  function buildUrl(overrides) {
137
156
  const params = new URLSearchParams();
@@ -170,22 +189,22 @@ function HiaiDocsSearchHost($$renderer, $$props) {
170
189
  $$renderer.push(`<!----> ${$.escape(search_clear_all_filters())}</button>`);
171
190
  } else $$renderer.push("<!--[-1-->");
172
191
  $$renderer.push(`<!--]--> `);
173
- if (folders.length > 0) {
192
+ if (categories.length > 0) {
174
193
  $$renderer.push("<!--[0-->");
175
194
  $$renderer.push(`<div><button type="button" class="mb-2 flex w-full items-center justify-between text-xs font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground"><span class="flex items-center gap-1.5">`);
176
- Folder($$renderer, { class: "size-3.5" });
177
- $$renderer.push(`<!----> ${$.escape(search_folders())}</span> `);
195
+ Folder_kanban($$renderer, { class: "size-3.5" });
196
+ $$renderer.push(`<!----> ${$.escape(categories_title())}</span> `);
178
197
  $$renderer.push("<!--[0-->");
179
198
  Chevron_down($$renderer, { class: "size-3" });
180
199
  $$renderer.push(`<!--]--></button> `);
181
200
  {
182
201
  $$renderer.push("<!--[0-->");
183
202
  $$renderer.push(`<div class="space-y-0.5"><!--[-->`);
184
- const each_array = $.ensure_array_like(folders);
203
+ const each_array = $.ensure_array_like(categories);
185
204
  for (let $$index_4 = 0, $$length = each_array.length; $$index_4 < $$length; $$index_4++) {
186
- let folder = each_array[$$index_4];
187
- $$renderer.push(`<button${$.attr_class(`flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-sm transition-colors ${activeFolder === folder ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`)}><span class="truncate">${$.escape(folder)}</span> `);
188
- if (activeFolder === folder) {
205
+ let category = each_array[$$index_4];
206
+ $$renderer.push(`<button${$.attr_class(`flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-sm transition-colors ${activeCategoryId === category.id ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`)}><span class="truncate">${$.escape(category.name)}</span> `);
207
+ if (activeCategoryId === category.id) {
189
208
  $$renderer.push("<!--[0-->");
190
209
  X($$renderer, { class: "size-3 shrink-0" });
191
210
  } else $$renderer.push("<!--[-1-->");
@@ -196,40 +215,22 @@ function HiaiDocsSearchHost($$renderer, $$props) {
196
215
  $$renderer.push(`<!--]--></div>`);
197
216
  } else $$renderer.push("<!--[-1-->");
198
217
  $$renderer.push(`<!--]--> `);
199
- if (tags.length > 0) {
200
- $$renderer.push("<!--[0-->");
201
- $$renderer.push(`<div><h4 class="mb-2 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground">`);
202
- Tag($$renderer, { class: "size-3.5" });
203
- $$renderer.push(`<!----> ${$.escape(search_tags())}</h4> <div class="flex flex-wrap gap-1.5"><!--[-->`);
204
- const each_array_1 = $.ensure_array_like(tags);
205
- for (let $$index_5 = 0, $$length = each_array_1.length; $$index_5 < $$length; $$index_5++) {
206
- let tag = each_array_1[$$index_5];
207
- $$renderer.push(`<button${$.attr_class(`inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium transition-colors ${activeTags.includes(tag.name) ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground hover:bg-secondary/80"}`)}>`);
208
- if (tag.color) {
209
- $$renderer.push("<!--[0-->");
210
- $$renderer.push(`<span class="mr-1.5 inline-block size-2 rounded-full"${$.attr_style(`background-color: ${$.stringify(tag.color)}`)}></span>`);
211
- } else $$renderer.push("<!--[-1-->");
212
- $$renderer.push(`<!--]--> ${$.escape(tag.name)}</button>`);
213
- }
214
- $$renderer.push(`<!--]--></div></div>`);
215
- } else $$renderer.push("<!--[-1-->");
216
- $$renderer.push(`<!--]--> `);
217
- if (categories.length > 0) {
218
+ if (visibleFolderNames().length > 0) {
218
219
  $$renderer.push("<!--[0-->");
219
220
  $$renderer.push(`<div><button type="button" class="mb-2 flex w-full items-center justify-between text-xs font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground"><span class="flex items-center gap-1.5">`);
220
- Folder_kanban($$renderer, { class: "size-3.5" });
221
- $$renderer.push(`<!----> ${$.escape(categories_title())}</span> `);
221
+ Folder($$renderer, { class: "size-3.5" });
222
+ $$renderer.push(`<!----> ${$.escape(search_folders())}</span> `);
222
223
  $$renderer.push("<!--[0-->");
223
224
  Chevron_down($$renderer, { class: "size-3" });
224
225
  $$renderer.push(`<!--]--></button> `);
225
226
  {
226
227
  $$renderer.push("<!--[0-->");
227
228
  $$renderer.push(`<div class="space-y-0.5"><!--[-->`);
228
- const each_array_2 = $.ensure_array_like(categories);
229
- for (let $$index_6 = 0, $$length = each_array_2.length; $$index_6 < $$length; $$index_6++) {
230
- let category = each_array_2[$$index_6];
231
- $$renderer.push(`<button${$.attr_class(`flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-sm transition-colors ${activeCategoryId === category.id ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`)}><span class="truncate">${$.escape(category.name)}</span> `);
232
- if (activeCategoryId === category.id) {
229
+ const each_array_1 = $.ensure_array_like(visibleFolderNames());
230
+ for (let $$index_5 = 0, $$length = each_array_1.length; $$index_5 < $$length; $$index_5++) {
231
+ let folder = each_array_1[$$index_5];
232
+ $$renderer.push(`<button${$.attr_class(`flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-sm transition-colors ${activeFolder === folder ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`)}><span class="truncate">${$.escape(folder)}</span> `);
233
+ if (activeFolder === folder) {
233
234
  $$renderer.push("<!--[0-->");
234
235
  X($$renderer, { class: "size-3 shrink-0" });
235
236
  } else $$renderer.push("<!--[-1-->");
@@ -239,6 +240,24 @@ function HiaiDocsSearchHost($$renderer, $$props) {
239
240
  }
240
241
  $$renderer.push(`<!--]--></div>`);
241
242
  } else $$renderer.push("<!--[-1-->");
243
+ $$renderer.push(`<!--]--> `);
244
+ if (tags.length > 0) {
245
+ $$renderer.push("<!--[0-->");
246
+ $$renderer.push(`<div><h4 class="mb-2 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground">`);
247
+ Tag($$renderer, { class: "size-3.5" });
248
+ $$renderer.push(`<!----> ${$.escape(search_tags())}</h4> <div class="flex flex-wrap gap-1.5"><!--[-->`);
249
+ const each_array_2 = $.ensure_array_like(tags);
250
+ for (let $$index_6 = 0, $$length = each_array_2.length; $$index_6 < $$length; $$index_6++) {
251
+ let tag = each_array_2[$$index_6];
252
+ $$renderer.push(`<button${$.attr_class(`inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium transition-colors ${activeTags.includes(tag.name) ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground hover:bg-secondary/80"}`)}>`);
253
+ if (tag.color) {
254
+ $$renderer.push("<!--[0-->");
255
+ $$renderer.push(`<span class="mr-1.5 inline-block size-2 rounded-full"${$.attr_style(`background-color: ${$.stringify(tag.color)}`)}></span>`);
256
+ } else $$renderer.push("<!--[-1-->");
257
+ $$renderer.push(`<!--]--> ${$.escape(tag.name)}</button>`);
258
+ }
259
+ $$renderer.push(`<!--]--></div></div>`);
260
+ } else $$renderer.push("<!--[-1-->");
242
261
  $$renderer.push(`<!--]--> <div><h4 class="mb-2 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground">`);
243
262
  Calendar($$renderer, { class: "size-3.5" });
244
263
  $$renderer.push(`<!----> ${$.escape(search_date_range())}</h4> <div class="space-y-2"><div><label for="dateFrom" class="text-xs text-muted-foreground">${$.escape(search_date_from())}</label> <div class="mt-0.5">`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hiai-gg/docsmint",
3
- "version": "0.5.2",
3
+ "version": "0.5.5",
4
4
  "type": "module",
5
5
  "browser": {
6
6
  "./dist/backend-launcher.js": false,
@@ -24,7 +24,7 @@ import { registerSearch } from "./commands/search.js";
24
24
  import { registerSnapshot } from "./commands/snapshot.js";
25
25
  import { registerUpdate } from "./commands/update.js";
26
26
 
27
- const VERSION = "0.5.2";
27
+ const VERSION = "0.5.5";
28
28
 
29
29
  const program = new Command();
30
30
  program
@@ -35,7 +35,7 @@ interface McpToolResult {
35
35
 
36
36
  const server = new McpServer({
37
37
  name: "hiai-docs",
38
- version: "0.5.2",
38
+ version: "0.5.5",
39
39
  });
40
40
 
41
41
  /**