@sparkelf/dsh-knowledge-base 0.1.30 → 0.1.31

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/lib/index.js CHANGED
@@ -11798,6 +11798,7 @@ function permissionForKbRoute(method) {
11798
11798
  if (method === "create" || method === "edit" || method === "move" || method === "upload" || method === "rename") return "kb:file:write";
11799
11799
  if (method === "trash" || method === "trash.remove" || method === "trash.restore") return "kb:file:delete";
11800
11800
  if (method === "index" || method === "extract.retry") return "kb:file:extract";
11801
+ if (method === "index.status") return "kb:file:read";
11801
11802
  if (method === "audit.list") return "kb:audit:read";
11802
11803
  if (method === "grants" || method === "grant" || method === "revoke") return "kb:grant:manage";
11803
11804
  if (method === "pending.list" || method === "pending.approve" || method === "pending.reject") return "kb:review:decide";
@@ -13399,6 +13400,32 @@ function apply(ctx, deploymentConfig) {
13399
13400
  });
13400
13401
  }
13401
13402
  case "extract.status": return writeJson(res, 200, extractionQueue.snapshot());
13403
+ case "index.status": {
13404
+ const body = await readJsonBody(req);
13405
+ const relPath = typeof body.path === "string" ? body.path.trim() : "";
13406
+ const docId = Number(body.docId);
13407
+ const db = new DatabaseSync(indexPathFor(config.indexDir));
13408
+ try {
13409
+ let row;
13410
+ if (Number.isInteger(docId) && docId > 0) row = db.prepare("select id, path, scope, mtime from kb_docs where id = ?").get(docId);
13411
+ else if (relPath !== "") {
13412
+ const name = relPath.slice(relPath.lastIndexOf("/") + 1);
13413
+ row = db.prepare("select id, path, scope, mtime from kb_docs where path = ?").get(relPath) ?? db.prepare("select id, path, scope, mtime from kb_docs where path = ? order by mtime desc limit 1").get(name) ?? db.prepare("select id, path, scope, mtime from kb_docs where path like ? order by mtime desc limit 1").get("%/" + relPath) ?? db.prepare("select id, path, scope, mtime from kb_docs where path like ? order by mtime desc limit 1").get("%" + relPath) ?? db.prepare("select id, path, scope, mtime from kb_docs where path like ? order by mtime desc limit 1").get("%/" + name);
13414
+ }
13415
+ if (row === void 0) return writeJson(res, 200, { found: false });
13416
+ const count = db.prepare("select count(*) as n from kb_chunks where doc_id = ?").get(row.id);
13417
+ return writeJson(res, 200, {
13418
+ found: true,
13419
+ docId: row.id,
13420
+ path: row.path,
13421
+ scope: row.scope,
13422
+ chunks: Number(count?.n ?? 0),
13423
+ indexedAt: row.mtime
13424
+ });
13425
+ } finally {
13426
+ db.close();
13427
+ }
13428
+ }
13402
13429
  case "extract.retry": {
13403
13430
  const body = await readJsonBody(req);
13404
13431
  const relPath = String(body.relPath ?? "");
@@ -13413,32 +13440,33 @@ function apply(ctx, deploymentConfig) {
13413
13440
  error: "path escapes the knowledge root",
13414
13441
  refused: [relPath]
13415
13442
  });
13416
- if (isAlreadyMarkdown(relPath)) {
13417
- extractionQueue.enqueue(relPath, "");
13443
+ const actualRelPath = await actualRelPathForView(host, config, relPath).catch(() => relPath);
13444
+ if (isAlreadyMarkdown(actualRelPath)) {
13445
+ extractionQueue.enqueue(actualRelPath, "");
13418
13446
  return writeJson(res, 200, {
13419
13447
  outcome: "already-markdown",
13420
- relPath,
13448
+ relPath: actualRelPath,
13421
13449
  message: "this document is already Markdown"
13422
13450
  });
13423
13451
  }
13424
- if (!isExtractable(relPath)) return writeJson(res, 200, {
13452
+ if (!isExtractable(actualRelPath)) return writeJson(res, 200, {
13425
13453
  outcome: "unsupported",
13426
- relPath,
13454
+ relPath: actualRelPath,
13427
13455
  message: "this file type has no extractor"
13428
13456
  });
13429
13457
  const localRoot = localConfig(config);
13430
- const target = join(localRoot.actualRoot, relPath);
13458
+ const target = join(localRoot.actualRoot, actualRelPath);
13431
13459
  const source = await stat(target).catch(() => void 0);
13432
13460
  if (source === void 0 || !source.isFile()) return writeJson(res, 404, { error: "no such file" });
13433
- if (!await canWritePath(host, config, relPath)) return writeJson(res, 403, {
13461
+ if (!await canWritePath(host, config, actualRelPath)) return writeJson(res, 403, {
13434
13462
  error: "write access is required to extract here",
13435
13463
  refused: [relPath]
13436
13464
  });
13437
- const sibling = markdownSiblingOf(relPath);
13465
+ const sibling = markdownSiblingOf(actualRelPath);
13438
13466
  const existing = await stat(join(localRoot.actualRoot, sibling)).catch(() => void 0);
13439
13467
  if (existing !== void 0 && existing.isFile()) return writeJson(res, 200, {
13440
13468
  outcome: "exists",
13441
- relPath,
13469
+ relPath: actualRelPath,
13442
13470
  markdown: sibling
13443
13471
  });
13444
13472
  const settings = await readSettings(viewPathFor({
@@ -13446,13 +13474,13 @@ function apply(ctx, deploymentConfig) {
13446
13474
  viewRoot: localRoot.viewRoot,
13447
13475
  userId: (await fetchCaller(host, config).catch(() => void 0))?.userId ?? ""
13448
13476
  }));
13449
- const accepted = extractionQueue.enqueue(relPath, settings.mineruBaseUrl);
13477
+ const accepted = extractionQueue.enqueue(actualRelPath, settings.mineruBaseUrl);
13450
13478
  if (body.wait === false) return writeJson(res, 202, {
13451
13479
  outcome: "queued",
13452
- relPath,
13480
+ relPath: actualRelPath,
13453
13481
  extraction: accepted
13454
13482
  });
13455
- const settled = await extractionQueue.settled(relPath);
13483
+ const settled = await extractionQueue.settled(actualRelPath);
13456
13484
  const outcome = settled === void 0 ? {
13457
13485
  state: "failed",
13458
13486
  reason: "the extraction task was not recorded"
@@ -138,6 +138,7 @@ export declare const KB_API: {
138
138
  readonly extractStatus: "extract.status";
139
139
  /** Re-run extraction for one document that could not finish. */
140
140
  readonly extractRetry: "extract.retry";
141
+ readonly indexStatus: "index.status";
141
142
  /** Read the caller's pinned paths. */
142
143
  readonly favoritesGet: "favorites.get";
143
144
  readonly favoritesSet: "favorites.set";
@@ -25,6 +25,8 @@ interface HomeRow {
25
25
  location: string;
26
26
  /** Last-modified instant in Unix ms, which is the tree's only timestamp. */
27
27
  mtimeMs?: number;
28
+ /** Host's answer: a `.md` sibling exists beside this non-text document. */
29
+ hasMarkdown?: boolean;
28
30
  }
29
31
  /** Props for the Home surface. */
30
32
  export interface KnowledgeHomeProps {
@@ -60,10 +60,18 @@ export interface KnowledgeProgressPopoverProps {
60
60
  * exists to remove. The page owns the store; this component only draws it.
61
61
  */
62
62
  failures?: readonly FailedExtractionView[];
63
+ /**
64
+ * Keep the persistence/polling work but render no bell or modal.
65
+ *
66
+ * The queue now lives in the Task Center's notifications tab, which reads the same
67
+ * localStorage key; the Knowledge page only needs this component mounted to keep
68
+ * writing observations.
69
+ */
70
+ headless?: boolean;
63
71
  }
64
72
  /**
65
73
  * The notification button and its progress panel.
66
74
  * @param props - the upload batch, whether to watch extraction, and the copy resolver.
67
75
  * @returns The button, plus the panel while it is open.
68
76
  */
69
- export declare function KnowledgeProgressPopover(props: KnowledgeProgressPopoverProps): import("react").JSX.Element;
77
+ export declare function KnowledgeProgressPopover(props: KnowledgeProgressPopoverProps): import("react").JSX.Element | null;
@@ -55,7 +55,6 @@ export declare const en: {
55
55
  readonly renameFailed: "Could not rename: the file may already exist or you may not have write access.";
56
56
  readonly downloadFailed: "Could not download this file.";
57
57
  readonly 'menu.home': "Home";
58
- readonly 'menu.permissions': "Permissions";
59
58
  readonly 'menu.indexing': "Directories & counts";
60
59
  readonly 'menu.trash': "Trash";
61
60
  readonly brand: "Wanxiang Knowledge";
@@ -115,6 +114,24 @@ export declare const en: {
115
114
  readonly homeColOwnerUnset: "Not recorded";
116
115
  readonly homeColCreated: "Created";
117
116
  readonly homeColOpened: "Last opened";
117
+ readonly homeColStatus: "Status";
118
+ readonly homeStatusExtracted: "Extracted";
119
+ readonly homeStatusNotExtracted: "Not extracted";
120
+ readonly homeStatusIndexed: "Indexed";
121
+ readonly homeStatusNotIndexed: "Not indexed";
122
+ readonly statusFileName: "File";
123
+ readonly statusPath: "Path";
124
+ readonly statusType: "Type";
125
+ readonly statusTypeText: "Text";
126
+ readonly statusTypeNonText: "Document";
127
+ readonly statusExtract: "Extraction";
128
+ readonly statusExtractTime: "Extracted at";
129
+ readonly statusMdSize: ".md size";
130
+ readonly statusIndex: "Index";
131
+ readonly statusIndexTime: "Indexed at";
132
+ readonly statusChunks: "Chunks / docId";
133
+ readonly statusFailure: "Failure reason";
134
+ readonly statusClose: "Close";
118
135
  readonly homeEmpty: "Nothing here yet.";
119
136
  readonly trashEmpty: "Trash is empty";
120
137
  readonly trashPending: "Deleting a document is not enabled yet. The knowledge tree is shared, and how long a deletion is kept is still being decided.";
@@ -325,6 +342,10 @@ export declare const en: {
325
342
  readonly auditActionUpload: "Upload";
326
343
  readonly auditActionMove: "Move";
327
344
  readonly auditActionEdit: "Edit";
345
+ readonly auditActionDelete: "Delete";
346
+ readonly auditActionExternalChange: "External change";
347
+ readonly auditActorExternalChange: "External process";
348
+ readonly auditActorSystem: "System";
328
349
  readonly auditOutcomeApplied: "Applied";
329
350
  readonly auditOutcomePending: "Pending review";
330
351
  readonly storageProtocol: "Protocol";
@@ -373,6 +394,7 @@ export declare const en: {
373
394
  readonly progressBadgeMore: "99+";
374
395
  readonly progressOpen: "Upload and extraction progress";
375
396
  readonly progressClose: "Close";
397
+ readonly progressClear: "Clear history";
376
398
  readonly dropRefusedNoCaller: "Cannot place this upload";
377
399
  readonly dropRefusedNoCallerReason: "The host has not reported your account yet, so the personal folder cannot be resolved. Reload and try again.";
378
400
  readonly progressResize: "Drag to resize";
@@ -466,7 +488,14 @@ export declare const en: {
466
488
  readonly refPickerBatchTitle: "Reference {n} items in a chat";
467
489
  readonly refPickerFailed: "Could not insert the reference into that chat.";
468
490
  readonly dropHomeHint: "Drop to upload into your personal folder";
469
- readonly progressTitle: "Progress";
491
+ readonly progressTitle: "Task queue";
492
+ readonly progressQueueTitle: "Tasks";
493
+ readonly progressUploadDone: "Uploaded";
494
+ readonly progressExtractDone: "Extraction done";
495
+ readonly progressStepUploading: "Uploading";
496
+ readonly progressStepUploaded: "Uploaded";
497
+ readonly progressStepExtracting: "Extracting";
498
+ readonly progressStepExtracted: "Extracted";
470
499
  readonly progressRoot: "Root";
471
500
  readonly overviewByRole: "By role";
472
501
  readonly sourceDirect: "Direct";
@@ -496,7 +525,7 @@ export declare const en: {
496
525
  readonly progressExtractGroup: "Extractions";
497
526
  readonly progressUploading: "Uploading {done}/{total}";
498
527
  readonly progressPending: "Queued";
499
- readonly progressExtracting: "Extracting";
528
+ readonly progressExtracting: "Extracting…";
500
529
  readonly progressStepParse: "Parsing document";
501
530
  readonly progressStepChunk: "Chunking text";
502
531
  readonly progressStepIndex: "Writing FTS5 index";
@@ -87,6 +87,10 @@ export interface UploadTaskView {
87
87
  state: 'waiting' | 'uploading' | 'done' | 'failed';
88
88
  /** Why it failed, in the Host's own words. */
89
89
  reason?: string;
90
+ /**
91
+ * When this row was enqueued, ISO-8601. Used to order the unified task queue.
92
+ */
93
+ at?: string;
90
94
  /**
91
95
  * Bytes sent, as 0-100.
92
96
  *
@@ -112,9 +116,12 @@ export interface UploadTaskView {
112
116
  */
113
117
  export declare function pendingCount(uploads: readonly {
114
118
  state: string;
119
+ at?: string;
115
120
  }[], extractions: readonly {
116
121
  state: string;
117
122
  }[]): number;
123
+ /** 上传完成后继续轮询提取任务的窗口。 */
124
+ export declare const UPLOAD_EXTRACTION_GRACE_MS = 30000;
118
125
  /**
119
126
  * How long an optimistic extraction entry may wait for the Host to confirm it.
120
127
  *
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Local persistence for the task queue.
3
+ *
4
+ * Only metadata is stored: a reader who comes back after a reload should still see what
5
+ * they uploaded or extracted, not the document bytes. Records older than the retention
6
+ * window are dropped on load, and the list is capped so a long-lived profile cannot grow
7
+ * without bound.
8
+ *
9
+ * @module @sparkelf/dsh-knowledge-base/client
10
+ */
11
+ /** One task as it is remembered across reloads. */
12
+ export interface PersistedTask {
13
+ /** Stable queue id (`upload:<path>` / `extract:<path>`). */
14
+ id: string;
15
+ /** Display name of the source document. */
16
+ fileName: string;
17
+ /** Which operation the task represents. */
18
+ kind: 'upload' | 'extract';
19
+ /** Last observed lifecycle state. */
20
+ stage: 'uploading' | 'uploaded' | 'extracting' | 'done' | 'failed';
21
+ /** Upload percentage, 0-100, when known. */
22
+ progress?: number;
23
+ /** When the task was first seen, epoch milliseconds. */
24
+ startedAt: number;
25
+ /** When it reached a terminal state, epoch milliseconds. */
26
+ finishedAt?: number;
27
+ /** Failure reason, when the task failed. */
28
+ error?: string;
29
+ }
30
+ /** The localStorage key this plugin owns. */
31
+ export declare const TASK_QUEUE_STORAGE_KEY = "dataops-kb-task-queue-v1";
32
+ /** How long a record is kept. */
33
+ export declare const TASK_QUEUE_RETENTION_MS: number;
34
+ /** Upper bound on records, newest first. */
35
+ export declare const TASK_QUEUE_MAX_RECORDS = 200;
36
+ /**
37
+ * Read the retained queue.
38
+ * @param now - current epoch milliseconds, injectable for tests.
39
+ * @returns Newest-first records inside the retention window.
40
+ */
41
+ export declare function loadTaskQueue(now?: number): PersistedTask[];
42
+ /**
43
+ * Persist the queue, silently degrading when storage is unavailable.
44
+ * @param records - the records to write, already ordered.
45
+ */
46
+ export declare function saveTaskQueue(records: readonly PersistedTask[]): void;
47
+ /**
48
+ * Merge freshly observed rows into the stored history.
49
+ *
50
+ * A new observation wins for the mutable fields (stage/progress/error), while the first
51
+ * `startedAt` and the first terminal `finishedAt` are preserved so a task does not appear
52
+ * to restart on every poll.
53
+ * @param current - stored records.
54
+ * @param incoming - rows observed this render.
55
+ * @param now - current epoch milliseconds.
56
+ * @returns Newest-first merged records, capped.
57
+ */
58
+ export declare function mergeTaskRecords(current: readonly PersistedTask[], incoming: readonly PersistedTask[], now?: number): PersistedTask[];
59
+ /** Remove every stored record. */
60
+ export declare function clearTaskQueue(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkelf/dsh-knowledge-base",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "DataOps-backed knowledge base for DeepSeek Harness: a left-sidebar destination, Settings configuration, and index tooling over a mounted NAS view.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -43,7 +43,7 @@
43
43
  "README.md",
44
44
  "LICENSE",
45
45
  "SKILL.md",
46
- "万相AI使用教程.html",
46
+ "\u4e07\u76f8AI\u4f7f\u7528\u6559\u7a0b.html",
47
47
  "i18n/*.json",
48
48
  "skills/**/SKILL.md",
49
49
  "skills/**/i18n/*.json"
@@ -1,143 +0,0 @@
1
- /**
2
- * The permissions surface: one grant table, read two ways.
3
- *
4
- * A grant says "this principal may do this action to this path". That is the right
5
- * shape to STORE and the wrong shape to AUDIT: an administrator asking "what does
6
- * 张三 have" and "who can see 制度.md" is asking two questions that one
7
- * row-per-grant layout cannot answer without being read line by line.
8
- *
9
- * So the page has one body and two readings of it. The tabs switch which question
10
- * is being asked; both render the same loaded grants, so the two can never
11
- * disagree. No second endpoint exists because there is no second truth.
12
- *
13
- * The tables are the page's own body rather than a summary above one. An earlier
14
- * version stacked both readings as bulleted lists and *also* drew a third,
15
- * row-per-principal table underneath: three renderings of one payload, so the
16
- * reader had to work out which of the three was authoritative before reading any
17
- * of them. Two tabs over one table removes that question.
18
- *
19
- * @module @sparkelf/dsh-knowledge-base/client/KnowledgePermissionOverview
20
- */
21
- import type { GrantView, KnowledgeGrantSubjectType } from '../api.ts';
22
- /** Which reading of the grant table the tabs are showing. */
23
- export type OverviewTab = 'person' | 'role' | 'resource';
24
- /** Copy for the overview, supplied by the caller's locale record. */
25
- export interface OverviewCopy {
26
- tabByPerson: string;
27
- tabByRole: string;
28
- tabByResource: string;
29
- empty: string;
30
- /** Empty state per view, so "nobody is directly granted" is not shown for a role. */
31
- emptyByPerson: string;
32
- emptyByRole: string;
33
- emptyByResource: string;
34
- /** Where a principal's access comes from. */
35
- sourceDirect: string;
36
- /** Format "inherited via role X": `{role}` is replaced by the role code. */
37
- sourceViaRole: (role: string) => string;
38
- /** Shown when the user directory could not be read, so inheritance is unknowable. */
39
- sourceUnavailable: string;
40
- /** Word for a permission set that could not be fully determined. */
41
- actionsUnknown: string;
42
- actionsUnknownHint: string;
43
- /** Column headers unique to the three views. */
44
- colAccount: string;
45
- colSource: string;
46
- /** "{count} member(s)". */
47
- roleMemberCount: (count: number) => string;
48
- /** Pager copy, shared with the audit table's wording. */
49
- pagerPrev: string;
50
- pagerNext: string;
51
- pagerStatus: (page: number, pageCount: number, total: number) => string;
52
- pageSizeLabel: string;
53
- pageSizeOption: (size: number) => string;
54
- pathsHeld: (count: number) => string;
55
- rolesHeld: string;
56
- actionsHeld: string;
57
- noActions: string;
58
- /** Accessible name for the tab strip, for readers who arrive at it by keyboard. */
59
- tabsLabel: string;
60
- /** Stat-card labels: the four numbers the page leads with. */
61
- statPrincipals: string;
62
- statResources: string;
63
- statGrants: string;
64
- statRoles: string;
65
- /** Shared column headers, person reading. */
66
- colPrincipal: string;
67
- colKind: string;
68
- colPermission: string;
69
- colResources: string;
70
- colExpiry: string;
71
- colActions: string;
72
- /** Shared column headers, resource reading. */
73
- colResource: string;
74
- colHolders: string;
75
- colKindOfResource: string;
76
- revoke: string;
77
- revokeBusy: string;
78
- expiryNever: string;
79
- kindFile: string;
80
- kindDirectory: string;
81
- /** Formats "N grants · M paths" under a person's name. */
82
- grantsUnit: (count: number) => string;
83
- resourcesUnit: (count: number) => string;
84
- /**
85
- * Resolves a principal kind and an action to its localized word.
86
- *
87
- * Supplied as callbacks rather than as a keyed map so this component never
88
- * reaches into the locale record itself: a caller with its own wording (a test,
89
- * another surface) can pass its own, and the type checker still enforces that
90
- * every kind and action the table can print has a word.
91
- */
92
- kindLabel: (kind: KnowledgeGrantSubjectType) => string;
93
- actionLabel: (action: string) => string;
94
- }
95
- /** Props the parent panel supplies. */
96
- export interface KnowledgePermissionOverviewProps {
97
- /** The grant table already loaded by the permissions page. */
98
- grants: readonly GrantView[];
99
- /** Display names by `principalType:principalId`. */
100
- labels?: Readonly<Record<string, string>>;
101
- /**
102
- * The DataOps account directory, when the caller could read it.
103
- *
104
- * Absent means the same as an unavailable read: inheritance cannot be attributed, and
105
- * the page says so instead of listing accounts that look like they hold nothing.
106
- */
107
- directory?: {
108
- kind: 'available';
109
- users: ReadonlyArray<{
110
- id: string;
111
- label: string;
112
- username?: string;
113
- roleCodes?: string[];
114
- }>;
115
- } | {
116
- kind: 'unavailable';
117
- reason: string;
118
- };
119
- /** Locale copy. */
120
- copy: OverviewCopy;
121
- /**
122
- * Asks the parent to confirm revoking the grants one row covers.
123
- *
124
- * The confirmation lives in the parent because it is a dialog, and a dialog in
125
- * the middle of a table's row renderer would make the table responsible for
126
- * ownership of the overlay. This component says *what* to revoke; the parent
127
- * decides whether to ask first and then performs it.
128
- */
129
- onRevoke: (grants: GrantView[], label: string) => void;
130
- /** Disables every revoke control while a write is in flight. */
131
- busy?: boolean;
132
- }
133
- /**
134
- * Render the permission overview as stat cards over a three-tab table.
135
- *
136
- * THREE views, not two, because the old pair answered different questions under one
137
- * heading: "by person" listed ROLE grants, so the only rows were 管理员 and 超级管理员
138
- * and a reader concluding "these are the people with access" was reading the page
139
- * correctly and being told something false. A role is not a person.
140
- *
141
- * @param props - grants, labels, directory, role summaries, copy and the revoke hook.
142
- */
143
- export declare function KnowledgePermissionOverview(props: KnowledgePermissionOverviewProps): import("react").JSX.Element;
@@ -1,47 +0,0 @@
1
- /**
2
- * The permissions surface of the management page.
3
- *
4
- * This view reads and writes grants through the DSH Host, which forwards them to
5
- * the DataOps backend. It deliberately holds no policy of its own: the backend's
6
- * authorization resolves the principal, checks the caller's permission keys, and
7
- * enforces what a grant means. The page only presents the result, so a rule
8
- * change lands in one place.
9
- *
10
- * The page leads with its table. A grant list is what an operator opens this
11
- * surface to read, so the data is the body of the page and the two things that
12
- * CHANGE it -- creating a grant, revoking one -- are raised into dialogs. A form
13
- * parked above the table would push the answer below the fold to make room for
14
- * the question.
15
- *
16
- * @module @sparkelf/dsh-knowledge-base/client
17
- */
18
- import { type ReactNode } from 'react';
19
- /** Props for the permissions surface. */
20
- export interface KnowledgePermissionsProps {
21
- /**
22
- * Publishes this page's primary control to the panel header.
23
- *
24
- * The header is the only band at the top of the page, so a page-level action has
25
- * to be handed up rather than drawn in a second title row.
26
- */
27
- onAction?: (action: ReactNode) => void;
28
- /** Locale-bound copy resolver. */
29
- t: (key: string) => string;
30
- /** Mount point the grants are scoped to. */
31
- mountPoint: string;
32
- /** Path the user selected, when the surface opened from a file row. */
33
- initialPath?: string;
34
- /**
35
- * Changes when a row's context menu picks a new path.
36
- *
37
- * The form's path field is seeded from `initialPath` once; without a signal that
38
- * the seed changed, a second right-click would leave the field on the first path.
39
- */
40
- reloadToken?: number;
41
- }
42
- /**
43
- * Render the permission editor.
44
- * @param props - copy resolver and the mount point grants are scoped to.
45
- * @returns The permission surface.
46
- */
47
- export declare function KnowledgePermissions(props: KnowledgePermissionsProps): import("react").JSX.Element;