@sparkelf/dsh-knowledge-base 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/SKILL.md +147 -0
  3. package/cordis.patch.yml +5 -0
  4. package/i18n/zh.json +10 -0
  5. package/lib/client.js +15976 -0
  6. package/lib/client.js.map +1 -0
  7. package/lib/index.js +5724 -0
  8. package/lib/types/api.d.ts +574 -0
  9. package/lib/types/client/KnowledgeAudit.d.ts +39 -0
  10. package/lib/types/client/KnowledgeContextMenu.d.ts +96 -0
  11. package/lib/types/client/KnowledgeCreateDialog.d.ts +134 -0
  12. package/lib/types/client/KnowledgeFileTree.d.ts +88 -0
  13. package/lib/types/client/KnowledgeHome.d.ts +79 -0
  14. package/lib/types/client/KnowledgeIndexing.d.ts +60 -0
  15. package/lib/types/client/KnowledgeListing.d.ts +160 -0
  16. package/lib/types/client/KnowledgeLoading.d.ts +41 -0
  17. package/lib/types/client/KnowledgeMenuIcon.d.ts +27 -0
  18. package/lib/types/client/KnowledgePanel.d.ts +58 -0
  19. package/lib/types/client/KnowledgePermissionOverview.d.ts +99 -0
  20. package/lib/types/client/KnowledgePermissions.d.ts +47 -0
  21. package/lib/types/client/KnowledgeReferencePicker.d.ts +65 -0
  22. package/lib/types/client/KnowledgeSearch.d.ts +83 -0
  23. package/lib/types/client/KnowledgeSectionHeader.d.ts +71 -0
  24. package/lib/types/client/KnowledgeSelectionBar.d.ts +45 -0
  25. package/lib/types/client/KnowledgeSettings.d.ts +96 -0
  26. package/lib/types/client/KnowledgeSettingsSection.d.ts +21 -0
  27. package/lib/types/client/KnowledgeShareDialog.d.ts +70 -0
  28. package/lib/types/client/KnowledgeTemplates.d.ts +43 -0
  29. package/lib/types/client/KnowledgeTrash.d.ts +62 -0
  30. package/lib/types/client/MenuGlyphs.d.ts +37 -0
  31. package/lib/types/client/departmentFolders.d.ts +57 -0
  32. package/lib/types/client/deployTarget.d.ts +34 -0
  33. package/lib/types/client/index.d.ts +27 -0
  34. package/lib/types/client/knowledgeMenuCopy.d.ts +23 -0
  35. package/lib/types/client/locales.d.ts +438 -0
  36. package/lib/types/client/openInSidebar.d.ts +62 -0
  37. package/lib/types/client/ownerLabel.d.ts +39 -0
  38. package/lib/types/client/permissionRows.d.ts +94 -0
  39. package/lib/types/client/roleSummary.d.ts +47 -0
  40. package/lib/types/client/saveAudit.d.ts +87 -0
  41. package/lib/types/client/useFavorites.d.ts +49 -0
  42. package/lib/types/client/usePinnedPaths.d.ts +39 -0
  43. package/lib/types/client/useTreeState.d.ts +46 -0
  44. package/lib/types/client/useViewMode.d.ts +39 -0
  45. package/lib/types/deploy.d.ts +209 -0
  46. package/lib/types/extract.d.ts +144 -0
  47. package/lib/types/index.d.ts +846 -0
  48. package/lib/types/permissions.d.ts +237 -0
  49. package/lib/types/protocol.d.ts +229 -0
  50. package/lib/types/remote.d.ts +105 -0
  51. package/lib/types/trash.d.ts +142 -0
  52. package/lib/types/viewMetadata.d.ts +20 -0
  53. package/lib/types/views.d.ts +923 -0
  54. package/package.json +109 -4
  55. package/skills/kb-organize/SKILL.md +365 -0
  56. package/skills/kb-organize/i18n/zh.json +10 -0
  57. package/README.md +0 -3
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The glyph the left sidebar renders for the knowledge-base entry.
3
+ *
4
+ * `sidebar.panellist` is a list of icon buttons, so this component receives only a
5
+ * size and never renders a surface. The page the entry selects is a separate
6
+ * component registered against the `main` key.
7
+ *
8
+ * The glyph is the product's own icon component rather than a local path: the rail
9
+ * sits directly beside the other panel icons, and a hand-drawn stroke read visibly
10
+ * heavier than its neighbours. Using the product icon keeps the rail uniform and
11
+ * lets the size the sidebar passes through unchanged.
12
+ *
13
+ * @module @sparkelf/dsh-knowledge-base/client
14
+ */
15
+ /** Props the sidebar list passes to one entry. */
16
+ export interface KnowledgeMenuIconProps {
17
+ /** Glyph edge length in pixels, chosen by the sidebar for its current width. */
18
+ size?: number;
19
+ /** Whether this entry is the selected panel. */
20
+ active?: boolean;
21
+ }
22
+ /**
23
+ * Render the knowledge-base glyph.
24
+ * @param props - sidebar-supplied glyph size.
25
+ * @returns The product icon sized for the sidebar rail.
26
+ */
27
+ export declare function KnowledgeMenuIcon(props: KnowledgeMenuIconProps): import("react").JSX.Element;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The knowledge-base management page.
3
+ *
4
+ * Selected by the left-sidebar entry and rendered into the `main` slot, so it
5
+ * replaces the conversation area. The page carries its own master-detail layout:
6
+ * the rail holds a menu above the knowledge tree, and the content region shows
7
+ * whichever surface the rail selected (a file preview, permissions, or indexing).
8
+ *
9
+ * The tree is this package's own listing rather than the file component from
10
+ * `dsh-better-sidebar`. That component renders icon and name only and builds its
11
+ * context menu internally, so it has nowhere to show whether a row is readable and
12
+ * nowhere to add a grant entry, while the actions its menu does offer (rename,
13
+ * delete, upload) edit a shared curated store rather than deciding who may see a
14
+ * document. The one thing worth keeping from it is the `@`-reference action, reused
15
+ * through its own helper so both trees insert the same reference.
16
+ *
17
+ * @module @sparkelf/dsh-knowledge-base/client
18
+ */
19
+ /**
20
+ * The session binding the page scopes its file tree with.
21
+ *
22
+ * It is a subscribable observable rather than a plain value because the session it
23
+ * names appears only after a Workspace is chosen, which regularly happens after
24
+ * this page has already mounted.
25
+ */
26
+ export interface SessionSource {
27
+ /** Current binding; `key` is the session id, absent before a session exists. */
28
+ getSnapshot: () => {
29
+ key?: unknown;
30
+ };
31
+ /** Subscribe to changes; returns the unsubscribe function. */
32
+ subscribe: (listener: () => void) => () => void;
33
+ }
34
+ /** Values the `main` slot injects into the page. */
35
+ export interface KnowledgePanelInjected {
36
+ /** Locale-bound copy for this package's namespace. */
37
+ t: (key: string) => string;
38
+ /** Locale tag the slot bound for this namespace, so dates match the reader. */
39
+ locale?: string;
40
+ /** Source of the session the file tree resolves its scope from. */
41
+ sessionSource: SessionSource;
42
+ /**
43
+ * The client context, needed by the borrowed tree's `@` helper.
44
+ *
45
+ * That helper resolves the workspace root and the conversation input service
46
+ * itself, so it needs the context rather than the values it reads from it.
47
+ */
48
+ ctx: unknown;
49
+ }
50
+ /** Props the page receives. */
51
+ export interface KnowledgePanelProps extends Partial<KnowledgePanelInjected> {
52
+ }
53
+ /**
54
+ * Render the knowledge-base management page.
55
+ * @param props - injected locale copy and the current session id.
56
+ * @returns The master-detail page.
57
+ */
58
+ export declare function KnowledgePanel(props: KnowledgePanelProps): import("react").JSX.Element;
@@ -0,0 +1,99 @@
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
+ import { type RoleSummary } from './roleSummary.ts';
23
+ /** Which reading of the grant table the tabs are showing. */
24
+ export type OverviewTab = 'person' | 'resource';
25
+ /** Copy for the overview, supplied by the caller's locale record. */
26
+ export interface OverviewCopy {
27
+ tabByPerson: string;
28
+ tabByResource: string;
29
+ empty: string;
30
+ pathsHeld: (count: number) => string;
31
+ rolesHeld: string;
32
+ actionsHeld: string;
33
+ builtInRoles: string;
34
+ noActions: string;
35
+ /** Accessible name for the tab strip, for readers who arrive at it by keyboard. */
36
+ tabsLabel: string;
37
+ /** Stat-card labels: the four numbers the page leads with. */
38
+ statPrincipals: string;
39
+ statResources: string;
40
+ statGrants: string;
41
+ statRoles: string;
42
+ /** Shared column headers, person reading. */
43
+ colPrincipal: string;
44
+ colKind: string;
45
+ colPermission: string;
46
+ colResources: string;
47
+ colExpiry: string;
48
+ colActions: string;
49
+ /** Shared column headers, resource reading. */
50
+ colResource: string;
51
+ colHolders: string;
52
+ colKindOfResource: string;
53
+ revoke: string;
54
+ revokeBusy: string;
55
+ expiryNever: string;
56
+ kindFile: string;
57
+ kindDirectory: string;
58
+ /** Formats "N grants · M paths" under a person's name. */
59
+ grantsUnit: (count: number) => string;
60
+ resourcesUnit: (count: number) => string;
61
+ /**
62
+ * Resolves a principal kind and an action to its localized word.
63
+ *
64
+ * Supplied as callbacks rather than as a keyed map so this component never
65
+ * reaches into the locale record itself: a caller with its own wording (a test,
66
+ * another surface) can pass its own, and the type checker still enforces that
67
+ * every kind and action the table can print has a word.
68
+ */
69
+ kindLabel: (kind: KnowledgeGrantSubjectType) => string;
70
+ actionLabel: (action: string) => string;
71
+ }
72
+ /** Props the parent panel supplies. */
73
+ export interface KnowledgePermissionOverviewProps {
74
+ /** The grant table already loaded by the permissions page. */
75
+ grants: readonly GrantView[];
76
+ /** Display names by `principalType:principalId`. */
77
+ labels?: Readonly<Record<string, string>>;
78
+ /** Built-in role summaries, so the person view can explain what a role means. */
79
+ roles?: readonly RoleSummary[];
80
+ /** Locale copy. */
81
+ copy: OverviewCopy;
82
+ /**
83
+ * Asks the parent to confirm revoking the grants one row covers.
84
+ *
85
+ * The confirmation lives in the parent because it is a dialog, and a dialog in
86
+ * the middle of a table's row renderer would make the table responsible for
87
+ * ownership of the overlay. This component says *what* to revoke; the parent
88
+ * decides whether to ask first and then performs it.
89
+ */
90
+ onRevoke: (grants: GrantView[], label: string) => void;
91
+ /** Disables every revoke control while a write is in flight. */
92
+ busy?: boolean;
93
+ }
94
+ /**
95
+ * Render the permission overview as stat cards over a two-tab table.
96
+ *
97
+ * @param props - grants, labels, role summaries, locale copy and the revoke hook.
98
+ */
99
+ export declare function KnowledgePermissionOverview(props: KnowledgePermissionOverviewProps): import("react").JSX.Element;
@@ -0,0 +1,47 @@
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;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The `@`-mention picker: choose which conversation a knowledge file goes into.
3
+ *
4
+ * The explorer row's `@` button used to answer `if (sessionId === undefined) return`
5
+ * -- a page with no conversation open simply dropped the click, so the button looked
6
+ * broken. But "no conversation open" is exactly the state this page is in most of the
7
+ * time: it is a management surface, not a chat. The reference still has to land
8
+ * somewhere, so the click now asks where.
9
+ *
10
+ * Two things are deliberately borrowed rather than invented:
11
+ *
12
+ * The insertion itself is `referenceInChat`, the same contract the sidebar explorer
13
+ * and the viewer's selection popup call. That function owns the whole policy this
14
+ * dialog must not re-derive: which workspace root the mention is relative to, the
15
+ * chip spelling for files versus folders, the quoted form for paths with spaces, and
16
+ * the "degrade to a logged no-op" behaviour when a service is missing. Building a
17
+ * second insertion path here would be the one way to make the two surfaces disagree.
18
+ *
19
+ * The session list and the navigation are the host's own services, resolved lazily
20
+ * through `ctx.get` rather than injected: this dialog is mounted whether or not the
21
+ * user has ever opened a conversation, and a page that cannot see `uiSession` must
22
+ * still render (it would show an empty list, not crash).
23
+ *
24
+ * @module @sparkelf/dsh-knowledge-base/client
25
+ */
26
+ /** Props for the picker. */
27
+ export interface KnowledgeReferencePickerProps {
28
+ /** Whether the dialog is showing. */
29
+ open: boolean;
30
+ /** Close without referencing anything. */
31
+ onClose: () => void;
32
+ /** Absolute path of the entry the `@` button was pressed on. */
33
+ path: string;
34
+ /** Whether that entry is a directory (a folder mention rather than a file chip). */
35
+ isDir: boolean;
36
+ /** The client context; both the draft insert and the service lookups need it. */
37
+ ctx: unknown;
38
+ /** Locale-bound copy for this package's namespace. */
39
+ t: (key: string) => string;
40
+ /** Locale tag, so a session's timestamp reads in the reader's language. */
41
+ locale?: string;
42
+ /**
43
+ * The conversation the host currently has selected, read at call time.
44
+ *
45
+ * The New Session flow creates a conversation asynchronously and does not return
46
+ * its id, so the only way to name it afterwards is to ask the page's own session
47
+ * binding -- the same observable the file tree is scoped by. Reading it lazily
48
+ * rather than as a prop is what makes it current by the time the draft is ready.
49
+ */
50
+ selectedSessionId?: () => string | undefined;
51
+ /**
52
+ * Called once a reference was actually inserted, with the session that received it.
53
+ *
54
+ * The dialog closes itself either way; this exists so the page can report which
55
+ * conversation the file went to, which is the only feedback a reader gets when the
56
+ * target tab is not the one they were looking at.
57
+ */
58
+ onReferenced?: (sessionId: string) => void;
59
+ }
60
+ /**
61
+ * The `@`-mention session picker.
62
+ * @param props - the entry to reference and the dialog's state.
63
+ * @returns The dialog, or null while closed.
64
+ */
65
+ export declare function KnowledgeReferencePicker(props: KnowledgeReferencePickerProps): import("react").JSX.Element;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The knowledge base's search: find a document, then open it.
3
+ *
4
+ * The field itself lives in the page's rail, not here, because it is navigation:
5
+ * a reader reaches "find a document" the same way they reach the permission or
6
+ * indexing section, and a menu row labelled "Search" asked them to click through
7
+ * to a box before they could type. `useKnowledgeSearch` owns the one piece of
8
+ * state both halves need, so the rail's field and this result list cannot
9
+ * disagree about which term produced which hits.
10
+ *
11
+ * This replaces an earlier summary of mount state, which answered a question the
12
+ * operator had not asked: the mount path, the file count, and a sync timestamp are
13
+ * facts about the deployment, while the reason to open this page is to locate a
14
+ * document.
15
+ *
16
+ * @module @sparkelf/dsh-knowledge-base/client
17
+ */
18
+ /** One result row, as the Host returns it. */
19
+ interface SearchHit {
20
+ /** Path relative to the mount point. */
21
+ relPath: string;
22
+ /** File name alone. */
23
+ name: string;
24
+ /** Whether the term matched the file body rather than only its name. */
25
+ inContent: boolean;
26
+ /** Matching line, when the term was found inside the file. */
27
+ line?: string;
28
+ /** 1-based line number of {@link line}. */
29
+ lineNumber?: number;
30
+ /** Last-modified instant in Unix ms, when the Host could stat the file. */
31
+ mtimeMs?: number;
32
+ }
33
+ /** What {@link useKnowledgeSearch} hands back to the rail and the result list. */
34
+ export interface KnowledgeSearchState {
35
+ /** Current term, owned here so the field and the results read one value. */
36
+ term: string;
37
+ /** Replace the term. */
38
+ setTerm: (value: string) => void;
39
+ /** Hits for the settled term, empty while idle. */
40
+ hits: SearchHit[];
41
+ /** Which surface the result list should draw. */
42
+ status: 'idle' | 'searching' | 'done' | 'error';
43
+ /** Index of the keyboard-highlighted row. */
44
+ active: number;
45
+ /** Highlight a row, so pointer movement and the arrow keys agree. */
46
+ setActive: (index: number) => void;
47
+ /** Arrow-key handling for the rail's field. */
48
+ onKeyDown: (event: {
49
+ key: string;
50
+ preventDefault: () => void;
51
+ }) => void;
52
+ }
53
+ /**
54
+ * Own the search term, its debounced request, and the highlighted row.
55
+ *
56
+ * Extracted rather than left inside the result component because the field it is
57
+ * driven by now sits in the rail: a hook keeps one owner for the term while the
58
+ * input and the list render in different regions of the page.
59
+ *
60
+ * @param mountPoint - the mount to search; empty while the page is still loading.
61
+ * @returns The term, its hits, and the keyboard handler for the field.
62
+ */
63
+ export declare function useKnowledgeSearch(mountPoint: string): KnowledgeSearchState;
64
+ /** Props for the result list. */
65
+ export interface KnowledgeSearchProps {
66
+ /** Locale-bound copy resolver. */
67
+ t: (key: string) => string;
68
+ /** Term and hits, owned by {@link useKnowledgeSearch}. */
69
+ search: KnowledgeSearchState;
70
+ /** Called with the chosen path so the page can show its preview. */
71
+ onOpen: (path: string) => void;
72
+ /** Locale tag, used to render dates and relative spans in the reader's language. */
73
+ locale?: string;
74
+ /** Shown while no term is entered, so the surface is useful before searching. */
75
+ idle?: React.ReactNode;
76
+ }
77
+ /**
78
+ * Render the results for the rail's search field.
79
+ * @param props - copy resolver, the search state, and the open callback.
80
+ * @returns The result list, or the idle content when nothing is typed.
81
+ */
82
+ export declare function KnowledgeSearch(props: KnowledgeSearchProps): import("react").JSX.Element;
83
+ export {};
@@ -0,0 +1,71 @@
1
+ /**
2
+ * The rail's section bands: a name with an optional trailing glyph cluster.
3
+ *
4
+ * Copied from the shell's own browser header,
5
+ * `ui-workspace/src/client/rows/WorkspaceBrowser.module.css` (`.sectionHeader` /
6
+ * `.sectionLabel` + `.iconButton`). That band is the one a reader compares this
7
+ * page against, because it is what the right sidebar shows for 工作区 in the same
8
+ * window. The metrics were also measured live on the running shell on 2026-10-17
9
+ * and agree with the stylesheet exactly: a 36px row, `gap: 4px`,
10
+ * `padding-left: 4px`, a label at 14px/20px, and 28x28 buttons on an 8px radius.
11
+ *
12
+ * Two details are the stylesheet's own and easy to get wrong:
13
+ *
14
+ * - The label is *not* bold. `--dsw-font-s-14` is 14px/22px, while this band's
15
+ * line-height is an explicit 20px, so the shorthand is paired with the measured
16
+ * line-height rather than allowed to win.
17
+ * - The name inherits the band's ink, which the stylesheet sets to
18
+ * `--dsw-alias-label-tertiary`; the buttons carry
19
+ * `--dsw-alias-label-secondary` of their own. Measured live, the name is
20
+ * `#adb2b8` and the buttons `#cfd3d6`, which is that same split.
21
+ *
22
+ * The band is a plain `div` with a name span and a button cluster rather than a
23
+ * heading element: it labels a region that already carries its own landmark, and
24
+ * a second heading level here would put an unlabelled h3 in the heading outline.
25
+ *
26
+ * @module @sparkelf/dsh-knowledge-base/client
27
+ */
28
+ import type { ReactNode } from 'react';
29
+ /** Props for one section band. */
30
+ export interface KnowledgeSectionHeaderProps {
31
+ /** Localized section name, rendered at the measured 14px/20px. */
32
+ name: ReactNode;
33
+ /**
34
+ * The trailing controls.
35
+ *
36
+ * Optional because the pinned band's only control is the fold toggle, while
37
+ * the tree band carries three; a band with none renders the name alone.
38
+ */
39
+ actions?: ReactNode;
40
+ /** Extra class for the band, so a caller can add its own spacing. */
41
+ className?: string;
42
+ }
43
+ /**
44
+ * Render one section band.
45
+ * @param props - the name, its trailing controls, and optional placement.
46
+ * @returns The band.
47
+ */
48
+ export declare function KnowledgeSectionHeader(props: KnowledgeSectionHeaderProps): import("react").JSX.Element;
49
+ /** Props for one 28px glyph button in a band's cluster. */
50
+ export interface KnowledgeIconButtonProps {
51
+ /** Localized accessible name; also the tooltip, as the shell's own buttons do. */
52
+ label: string;
53
+ /** The glyph, sized by the caller to the band's 16px step. */
54
+ children: ReactNode;
55
+ /** Invoked on activation. */
56
+ onClick: () => void;
57
+ /** Whether the control refuses activation. */
58
+ disabled?: boolean;
59
+ /** Whether the control's action is currently engaged, so it can report `aria-pressed`. */
60
+ pressed?: boolean;
61
+ }
62
+ /**
63
+ * Render one glyph button.
64
+ *
65
+ * A native button with the band's own class rather than the `Button` primitive:
66
+ * that primitive is the product's labelled action at a 36px control height, while
67
+ * this is the 28x28 icon control the band is specified around.
68
+ * @param props - the accessible name, glyph, and activation handler.
69
+ * @returns The button.
70
+ */
71
+ export declare function KnowledgeIconButton(props: KnowledgeIconButtonProps): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The batch action bar that closes a multi-select session in the tree.
3
+ *
4
+ * Copied from the explorer's own `explorerSelectionBar` (`FileTree.tsx:2238`,
5
+ * `sidebar.module.css:932`): the same `role="toolbar"`, the same sticky bottom
6
+ * position, the same 28px minimum height, the same `bg-layer-2` fill and 4px
7
+ * radius, and the same split between a shrinking count on the left and the
8
+ * actions on the right. It is a copy rather than a second design because a reader
9
+ * sees that bar in this window's right sidebar, and the two are the same gesture.
10
+ *
11
+ * The actions are deliberately only the two this build can actually perform.
12
+ * Delete is absent because the trash has no decided retention or ownership
13
+ * semantics, and a destructive button wired to an undecided policy is worse than
14
+ * no button: the explorer's own bar carries delete, so its absence here is a
15
+ * decision rather than an oversight.
16
+ *
17
+ * @module @sparkelf/dsh-knowledge-base/client
18
+ */
19
+ /** Props for the batch bar. */
20
+ export interface KnowledgeSelectionBarProps {
21
+ /** Locale-bound copy resolver. */
22
+ t: (key: string, params?: Record<string, string | number>) => string;
23
+ /** How many rows are selected, for the count and the label. */
24
+ count: number;
25
+ /** Move every selected path into one folder the reader picks. */
26
+ onMove: () => void;
27
+ /** Pin every selected path. */
28
+ onPin: () => void;
29
+ /** Drop the selection. */
30
+ onClear: () => void;
31
+ /**
32
+ * Whether a batch write is in flight, so the actions can be held.
33
+ *
34
+ * A second click while the first is still moving would send the same paths twice,
35
+ * and the second would be refused as a missing source -- an error the reader
36
+ * would read as the feature being broken.
37
+ */
38
+ busy?: boolean;
39
+ }
40
+ /**
41
+ * Render the batch bar for the current selection.
42
+ * @param props - the count, the three actions, and the busy flag.
43
+ * @returns The toolbar.
44
+ */
45
+ export declare function KnowledgeSelectionBar(props: KnowledgeSelectionBarProps): import("react").JSX.Element;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * TODO: this page is unreachable from the real entry, and needs a decision.
3
+ *
4
+ * Verified by driving the deployed product on 2026-10-21, not by reading the code:
5
+ * entering 知识库 and clicking 「设置」 in its own rail opens the DSH GLOBAL settings
6
+ * dialog (left nav: 通用设置/模型/内置插件/Agent 预设/DataOps/备份/知识库/插件市场/
7
+ * 侧边卡片), never this component. The rail row sets `selection.kind = 'settings'`,
8
+ * which `KnowledgePanel.tsx` renders as this surface, but the click that a reader can
9
+ * actually reach is the shell's own settings entry, so nothing in the real UI leads
10
+ * here. The review switch below therefore has no user-facing effect today.
11
+ *
12
+ * Deliberately NOT deleted: removing this file, the `rendered.kind === 'settings'`
13
+ * branch in `KnowledgePanel.tsx` and the `menu.settings` rail row is a cross-file
14
+ * structural change, and the choice between "delete the page" and "give it a real
15
+ * entry point" is a product decision rather than a cleanup. Left as-is with this note
16
+ * so the next change starts from the measured fact instead of re-deriving it.
17
+ *
18
+ * What WAS moved: the MinerU service address. It lived here for one round and was
19
+ * invisible to readers for exactly this reason; it now renders in
20
+ * `KnowledgeSettingsSection.tsx` (DSH global settings → 知识库), which is reachable.
21
+ */
22
+ /**
23
+ * The settings surface of the management page.
24
+ *
25
+ * This page is now only the review switch: a DECISION about whether other people's
26
+ * contributions take effect immediately, so it is a control and it needs write
27
+ * access. The queue that decision governs and the trail of what it settled both
28
+ * moved to the Audit page, which is the surface an operator opens to get through
29
+ * work; parking a worklist under a configuration switch made them scroll past the
30
+ * setting to reach today's arrivals, and left two duplicate entry points pointing
31
+ * at the same two tables.
32
+ *
33
+ * The switch ships OFF. That is the product decision, not a default that drifted: an
34
+ * operator who never opens this page keeps the behaviour they had, and turning review
35
+ * on is a deliberate act with a visible consequence.
36
+ *
37
+ * @module @sparkelf/dsh-knowledge-base/client
38
+ */
39
+ /** This knowledge base's review settings, as the Host reports them. */
40
+ export interface KnowledgeSettingsView {
41
+ /** Whether a write must be reviewed before it counts as published. */
42
+ reviewRequired: boolean;
43
+ /**
44
+ * MinerU's full base address, or `''` to derive it from the configured port.
45
+ *
46
+ * Absent from an older Host's answer, which reads as `''`: the field then shows
47
+ * "derived" rather than a value the Host never sent.
48
+ */
49
+ mineruBaseUrl?: string;
50
+ }
51
+ /** One recorded change, as the Host reports it. */
52
+ export interface KnowledgeAuditEntryView {
53
+ /** ISO timestamp of the action. */
54
+ at: string;
55
+ /** DataOps user id that performed it: the identity the trail is checked against. */
56
+ actor: string;
57
+ /**
58
+ * That user's display name, when the entry carries one.
59
+ *
60
+ * Absent on entries written before it was recorded; the column falls back to the
61
+ * id so an old line still identifies its actor.
62
+ */
63
+ actorLabel?: string;
64
+ /** What they did. Mirrors the Host's own action union. */
65
+ action: 'create' | 'upload' | 'move' | 'approve' | 'reject' | 'edit';
66
+ /** The path the action concerned. */
67
+ relPath: string;
68
+ /** For a move, the destination path. */
69
+ toRelPath?: string;
70
+ /** Whether it took effect immediately or was parked for review or refused. */
71
+ outcome: 'applied' | 'pending' | 'rejected';
72
+ }
73
+ /** Props for the settings surface. */
74
+ export interface KnowledgeSettingsProps {
75
+ /** Locale-bound copy for this package's namespace. */
76
+ t: (key: string) => string;
77
+ }
78
+ /** One submission waiting for review, as the Host reports it. */
79
+ export interface PendingWriteView {
80
+ /** The parking name a decision is made against. */
81
+ name: string;
82
+ /** Who submitted it. */
83
+ userId: string;
84
+ /** The path it wants to occupy. */
85
+ relPath: string;
86
+ /** When it was submitted. */
87
+ at: string;
88
+ /** Size of the submitted bytes. */
89
+ bytes: number;
90
+ }
91
+ /**
92
+ * Render the review switch and the audit trail.
93
+ * @param props - copy resolver.
94
+ * @returns The settings surface.
95
+ */
96
+ export declare function KnowledgeSettings(props: KnowledgeSettingsProps): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { en } from './locales.ts';
3
+ /** Values injected by the DSH Settings slot. */
4
+ export interface KnowledgeSettingsInjected {
5
+ /** Translate one knowledge-base message key. */
6
+ t: (key: keyof typeof en) => string;
7
+ }
8
+ /** Props accepted by the injected Settings section. */
9
+ export type KnowledgeSettingsProps = Partial<InjectFace<KnowledgeSettingsInjected>>;
10
+ /**
11
+ * Render the knowledge-base connection, resolved paths, status, the read-only
12
+ * authorization summary, and the deployment wizard.
13
+ *
14
+ * Authorization itself is deliberately absent: DataOps owns grants, and this
15
+ * panel only reports what the backend says (AGENTS.md "Managed DataOps
16
+ * Authorization" forbids replicating that policy in a plugin).
17
+ *
18
+ * @param props - Settings slot injection values.
19
+ * @returns The localized Settings section, or nothing before injection.
20
+ */
21
+ export declare function KnowledgeSettingsSection(props: KnowledgeSettingsProps): import("react").JSX.Element | null;