@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,70 @@
1
+ /**
2
+ * The Share dialog the knowledge tree's context menu opens.
3
+ *
4
+ * Sharing is a grant, and the grant route already exists: this dialog only chooses
5
+ * WHO receives it. The principal directory behind the picker is the same one the
6
+ * permission table reads, reached through the same `principals` route, so a reader
7
+ * who can grant from either surface picks from one list rather than two that can
8
+ * disagree.
9
+ *
10
+ * The picker is a text field plus a filtered list rather than a `<select>`: a real
11
+ * deployment has hundreds of people, and a closed control makes finding one a
12
+ * scroll. Filtering is local over the directory the Host already returned, so
13
+ * typing costs no round trip and stays responsive while a slow directory is still
14
+ * loading.
15
+ *
16
+ * @module @sparkelf/dsh-knowledge-base/client
17
+ */
18
+ /** One selectable principal, as the Host's directory reports it. */
19
+ export interface SharePrincipal {
20
+ /** Stable id the grant names. */
21
+ id: string;
22
+ /** What a reader recognises it by: a person's name, a role's title. */
23
+ label: string;
24
+ /** Optional second line: department, email, or whatever distinguishes two like-named ids. */
25
+ detail?: string;
26
+ }
27
+ /** The copy this dialog needs, so it renders in the reader's language. */
28
+ export interface ShareDialogCopy {
29
+ title: string;
30
+ intro: string;
31
+ subjectType: string;
32
+ search: string;
33
+ searchPlaceholder: string;
34
+ noMatch: string;
35
+ loading: string;
36
+ empty: string;
37
+ cancel: string;
38
+ confirm: string;
39
+ working: string;
40
+ permission: string;
41
+ actionRead: string;
42
+ actionWrite: string;
43
+ actionManage: string;
44
+ chosen: string;
45
+ failed: string;
46
+ directoryFailed: string;
47
+ kind_user: string;
48
+ kind_role: string;
49
+ kind_department: string;
50
+ kind_group: string;
51
+ }
52
+ /** Props for the share dialog. */
53
+ export interface KnowledgeShareDialogProps {
54
+ /** The path being shared, relative to the knowledge root, or null when closed. */
55
+ relPath: string | null;
56
+ /** Whether that path is a directory; only used to word the intro. */
57
+ isDir: boolean;
58
+ /** Locale-bound copy for this dialog. */
59
+ copy: ShareDialogCopy;
60
+ /** Close the dialog. */
61
+ onClose: () => void;
62
+ /** Called after a grant landed, so the page can refresh its permission view. */
63
+ onShared?: () => void;
64
+ }
65
+ /**
66
+ * The Share dialog.
67
+ * @param props - the target path, the copy, and the callbacks.
68
+ * @returns The modal, or nothing while it is closed.
69
+ */
70
+ export declare function KnowledgeShareDialog(props: KnowledgeShareDialogProps): import("react").JSX.Element | null;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The template library: a card grid in an official dialog, with a maintenance side.
3
+ *
4
+ * A template is a document plus the few facts that describe it -- name, one-line
5
+ * description, category, optional tags. That is the whole model, and it is why the
6
+ * store is a directory of documents next to one JSON index rather than a table: the
7
+ * file IS the template, and the index only says what to call it.
8
+ *
9
+ * Two jobs live here, because they are two readings of the same list:
10
+ *
11
+ * - USING a template. A card's primary action copies the template's document into a
12
+ * directory the reader picks, through the same upload route any new document uses,
13
+ * then opens it. Nothing about a template is special enough to need its own write
14
+ * path.
15
+ * - MAINTAINING the list. Adding a template is "choose a document, fill in the
16
+ * metadata"; editing is the same form with the file already stored; taking one
17
+ * offline removes the record and its document.
18
+ *
19
+ * The empty states are the honest ones: "nothing stored yet" and "could not read the
20
+ * store" are different facts and say so separately, because a reader told the library
21
+ * is empty will believe it.
22
+ *
23
+ * @module @sparkelf/dsh-knowledge-base/client
24
+ */
25
+ /** Props for the template library. */
26
+ export interface KnowledgeTemplatesProps {
27
+ /** Locale-bound copy resolver. */
28
+ t: (key: string) => string;
29
+ /** Close the dialog. */
30
+ onClose: () => void;
31
+ /** The knowledge root, for the "use this template" destination default. */
32
+ mountPoint?: string;
33
+ /** The caller's id, so the destination default prefers their own folder. */
34
+ callerId?: string;
35
+ /** Open a document once it has been created from a template. */
36
+ onOpen?: (relPath: string) => void;
37
+ }
38
+ /**
39
+ * Render the template library.
40
+ * @param props - copy resolver, the knowledge root, and the close handler.
41
+ * @returns The dialog.
42
+ */
43
+ export declare function KnowledgeTemplates(props: KnowledgeTemplatesProps): import("react").JSX.Element;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The Trash surface: what this caller removed, and the way back.
3
+ *
4
+ * ## What a removal is here
5
+ *
6
+ * Removing a document does not delete it. A view is hardlinks into one shared tree,
7
+ * so unlinking the caller's own link would be indistinguishable from a revoked grant
8
+ * and the next sync would put the link back. The removal is therefore recorded as a
9
+ * tombstone that filters this caller's view, and restoring deletes the note. See
10
+ * `src/trash.ts` for the full reasoning.
11
+ *
12
+ * ## Why restore can bring back nothing
13
+ *
14
+ * A grant can be withdrawn while a document sits in the trash. Restoring it then
15
+ * rebuilds the view without that document, which is the correct outcome and one the
16
+ * page has to say out loud -- a Restore button that appears to do nothing reads as a
17
+ * broken page.
18
+ *
19
+ * @module @sparkelf/dsh-knowledge-base/client
20
+ */
21
+ /** Props for the Trash surface. */
22
+ export interface KnowledgeTrashProps {
23
+ /** Locale-bound copy resolver. */
24
+ t: (key: string) => string;
25
+ }
26
+ /** One removed path, as the route reports it. */
27
+ interface TrashEntry {
28
+ /** Path relative to the knowledge root, in view coordinates. */
29
+ relPath: string;
30
+ /** Whether the removed entry was a file or a directory. */
31
+ kind: 'file' | 'directory';
32
+ /** Display name of whoever removed it. */
33
+ removedBy: string;
34
+ /** ISO-8601 instant of removal. */
35
+ removedAt: string;
36
+ /** Where it used to sit. */
37
+ originalPath: string;
38
+ }
39
+ /**
40
+ * Format one removal instant for a row.
41
+ *
42
+ * @param value - ISO-8601 instant from the route.
43
+ * @param locale - BCP-47 tag the browser should format in.
44
+ * @returns the local date and time, or the raw value when it cannot be read.
45
+ */
46
+ export declare function formatRemovedAt(value: string, locale?: string): string;
47
+ /**
48
+ * The last segment of a view path, which is the name a reader recognises.
49
+ *
50
+ * @param relPath - path in view coordinates.
51
+ * @returns that segment, or the whole path when it holds no separator.
52
+ */
53
+ export declare function entryNameOf(relPath: string): string;
54
+ /**
55
+ * Render the Trash surface.
56
+ *
57
+ * @param props - copy resolver.
58
+ * @returns The trash table, its empty state, and a restore action per row.
59
+ */
60
+ export declare function KnowledgeTrash(props: KnowledgeTrashProps): import("react").JSX.Element;
61
+ /** One removed path, re-exported for callers that build their own table. */
62
+ export type { TrashEntry };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Glyphs for the management page's own menu rows.
3
+ *
4
+ * These are the product's own icon components, not hand-drawn paths: the icon set
5
+ * already draws each glyph on the product grid with the product stroke weights
6
+ * (`ICON_REGULAR_STROKE` 1, `ICON_MEDIUM_STROKE` 1.3), and a local SVG with its own
7
+ * stroke reads noticeably heavier beside them. Colour rides `currentColor`, so a
8
+ * row's own text colour drives the glyph and no row needs an icon-specific rule.
9
+ *
10
+ * @module @sparkelf/dsh-knowledge-base/client
11
+ */
12
+ /** One rail section id, matching a selection kind. */
13
+ export type SectionKind = 'home' | 'permissions' | 'indexing' | 'trash' | 'audit' | 'settings';
14
+ /**
15
+ * The glyph matching one rail section.
16
+ *
17
+ * Kept as a map rather than a switch so the menu can render a row per entry and
18
+ * stay a single expression. The document glyph stands for Home because that is
19
+ * what the surface holds, and it is the same mark the left sidebar uses for this
20
+ * plugin, so the entry reads consistently in both rails.
21
+ * @param kind - section id, matching the selection kind.
22
+ * @param size - glyph size.
23
+ * @returns The glyph element.
24
+ */
25
+ export declare function sectionGlyph(kind: SectionKind, size?: number): import("react").JSX.Element;
26
+ /**
27
+ * The brand mark at the rail's top-left.
28
+ *
29
+ * The same glyph the left sidebar shows for this plugin, at the shell's menu-icon
30
+ * size rather than a rail-sized one: this row is a page header, and the sidebar's
31
+ * own larger step belongs to the global rail rather than to a page inside it.
32
+ * @param props - whether the rail is folded, which drops the mark to icon size.
33
+ * @returns The brand glyph.
34
+ */
35
+ export declare function KnowledgeMenuBrand(props: {
36
+ folded: boolean;
37
+ }): import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The pure half of the tree's folder labels: which rows print a name instead of a slug.
3
+ *
4
+ * Kept apart from the rendering module for the reason stated in `permissionRows.ts`:
5
+ * a component module reaches the primitives package, which imports CSS, and a Node test
6
+ * runner cannot load a `.css` file. The label rules are the part worth testing without a
7
+ * DOM, so they live where a plain import can reach them.
8
+ *
9
+ * @module @sparkelf/dsh-knowledge-base/client/departmentFolders
10
+ */
11
+ /** The reader's own organization chain, as the Host reports it. */
12
+ export interface DepartmentPath {
13
+ /** Codes from the organization root down to the caller's department. */
14
+ codes: readonly string[];
15
+ /** Display names, index-aligned with {@link codes}. */
16
+ names: readonly string[];
17
+ }
18
+ /**
19
+ * Tree-relative paths of the caller's own department chain, mapped to their names.
20
+ *
21
+ * The department bucket stores folders by code (`nanning-psb`), because a code is a
22
+ * stable slug: renaming a department cannot move a document. The reader, though, knows
23
+ * their organization by name, so those same rows have to print 「南宁市公安局」 rather
24
+ * than the slug.
25
+ *
26
+ * One entry per LEVEL rather than one for the leaf: the reader walks
27
+ * 「部门」 → 「南宁市公安局」 → 「数字侦察支队」 → 「数据实战大队」, so each of those
28
+ * three rows needs its own name.
29
+ *
30
+ * Only the caller's own chain is translated. A peer department's folder keeps printing
31
+ * its code, because this build has no name for it: the whole organization tree is
32
+ * readable only by an administrator, and deriving a "name" from a slug would put an
33
+ * invented label in front of the reader.
34
+ *
35
+ * A mismatched pair is refused whole rather than zipped to the shorter length: a
36
+ * partially labelled chain would put a correct name on one row and a raw code on the
37
+ * next, which reads as a missing department rather than as a missing translation.
38
+ *
39
+ * @param codes - codes from the organization root down, as DataOps reported them.
40
+ * @param names - display names, index-aligned.
41
+ * @returns The lookup keyed by tree-relative path, or undefined when nothing is usable.
42
+ */
43
+ export declare function departmentPathLabels(codes: readonly string[] | undefined, names: readonly string[] | undefined): ReadonlyMap<string, string> | undefined;
44
+ /**
45
+ * Resolve one tree-relative path to its printed label.
46
+ *
47
+ * Bucket labels are consulted first. The two maps address different rows today
48
+ * (`department` for the bucket, `department/<code>` and deeper for the chain), so the
49
+ * order changes no current label; it states that the audience name of a bucket is the
50
+ * one thing a data value must not override.
51
+ *
52
+ * @param relPath - path relative to the knowledge root.
53
+ * @param bucketLabels - the three audience names, keyed the same way.
54
+ * @param chainLabels - the caller's department chain, from {@link departmentPathLabels}.
55
+ * @returns The label to print, or undefined to print the row's own name.
56
+ */
57
+ export declare function folderLabelOf(relPath: string, bucketLabels: Readonly<Record<string, string>> | undefined, chainLabels: ReadonlyMap<string, string> | undefined): string | undefined;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Whether a deployment has anything the deployment wizard could act on.
3
+ *
4
+ * Its own module rather than a helper inside the settings component because the
5
+ * component imports CSS modules, and a test that wants to CALL this decision cannot
6
+ * load them. Keeping the predicate dependency-free means the rule is exercised
7
+ * directly instead of being matched as text in the file that happens to use it --
8
+ * an assertion on source text cannot notice an inverted branch.
9
+ *
10
+ * @module @sparkelf/dsh-knowledge-base/client
11
+ */
12
+ /**
13
+ * Decide whether to render the deployment wizard.
14
+ *
15
+ * Every step in the plan executes ON A REMOTE HOST: the Host's `deploy.run` route
16
+ * refuses a request without a `hostId` ("Steps mutate a remote host"), and the MinerU
17
+ * steps are shell run there too -- they read the remote `/etc/os-release`, remote
18
+ * `uv`, remote `docker`. So the wizard is not an NFS-only block that a local
19
+ * deployment skips in part; with no SSH host configured it has nothing that can run,
20
+ * and seven disabled buttons are seven dead controls.
21
+ *
22
+ * A configured host is what makes the block meaningful, so that is the primary test.
23
+ * The deployment's own declared mode is the fallback: a `remote` deployment is one
24
+ * that intends to sync, so it keeps the wizard even before a host row exists -- the
25
+ * host list may be empty for a reason the reader can fix, and hiding the wizard would
26
+ * remove the only place that says so.
27
+ *
28
+ * A missing or unrecognised mode counts as `local`: the conservative direction,
29
+ * because local is the shape where the buttons would be a lie.
30
+ * @param hosts - the configured SSH hosts, as `deploy.hosts` reports them.
31
+ * @param storageMode - the deployment's declared mode, as `status` reports it.
32
+ * @returns true when the wizard has a remote target to act on.
33
+ */
34
+ export declare function hasDeployTarget(hosts: readonly unknown[], storageMode: 'local' | 'remote' | undefined): boolean;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Knowledge-base Client plugin.
3
+ *
4
+ * Registers three official DSH surfaces:
5
+ * - `sidebar.panellist` gives the left-sidebar menu entry.
6
+ * - The matching `main` key gives the management page the entry selects. The
7
+ * page replaces the conversation area and carries its own master-detail
8
+ * layout: a menu and the knowledge tree on the left, a content region on the
9
+ * right.
10
+ * - `settings.section` gives the connection and status page.
11
+ *
12
+ * @module @sparkelf/dsh-knowledge-base/client
13
+ */
14
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
15
+ import { type KnowledgeKey } from './locales.ts';
16
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
17
+ interface LocaleNamespaceMap {
18
+ 'settings.knowledgeBase': KnowledgeKey;
19
+ }
20
+ }
21
+ /** Client services required for these contributions. */
22
+ export declare const inject: string[];
23
+ /**
24
+ * Register the knowledge-base navigation entry and Settings section.
25
+ * @param ctx - DSH client context with locale and slot registries.
26
+ */
27
+ export declare function apply(ctx: ClientContext): void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copy for the Share dialog.
3
+ *
4
+ * The context menu's own labels are NOT here: they are `action*` keys in the shared
5
+ * namespace (`locales.ts`), because they are the same sentences the rest of the knowledge
6
+ * surface uses for the same verbs, and two copies of one sentence drift. What stays local
7
+ * is the dialog's copy, which is longer, dialog-specific, and not addressable from the
8
+ * settings namespace -- putting it in `locales.ts` would also mean touching a file several
9
+ * other changes are editing at once.
10
+ *
11
+ * `SHARE_ZH` is typed as the English record, so a key added to one and forgotten in the
12
+ * other fails to compile rather than rendering an English sentence inside a Chinese
13
+ * dialog.
14
+ *
15
+ * @module @sparkelf/dsh-knowledge-base/client
16
+ */
17
+ import type { ShareDialogCopy } from './KnowledgeShareDialog.tsx';
18
+ /**
19
+ * Resolve the share-dialog copy for one locale tag.
20
+ * @param locale - the reader's locale tag, as the page received it.
21
+ * @returns The English or Chinese record.
22
+ */
23
+ export declare function shareCopyFor(locale: string | undefined): ShareDialogCopy;