feat(web): redesign Knowledge as an editable wiki
Replaces the read-only stats dashboard with a three-pane wiki: a navigator tree (group by folder/type/tag/entity), a reader/editor with bare-slug auto-linking and revision history + diff, and a context rail for backlinks and related notes. Adds a Cleanup mode for the drift tools (duplicates, tag manager, orphans, trash) and a Cmd+K quick-open. Also: - Adds a real landing view (hero count, KPI row, Nomos-share meter, recently-updated, busiest tags) in place of the old "Select a note" empty state, and extends the design pass across the tree/reader/rail (kind icons instead of repeated text badges, accent-bar selection, constrained prose measure). - Guards every note-selection path behind a confirm when there's an unsaved edit in progress, so switching notes can no longer silently discard a draft. - Extracts the markdown-rendering CSS duplicated across ChatThread, EntityDetailContent, and the new WikiReader into a shared .markdown-body class in app.css, with ChatThread keeping only its decorative deltas. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
50
web/src/lib/components/knowledge/kinds.ts
Normal file
50
web/src/lib/components/knowledge/kinds.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// Per-kind presentation, shared by the tree, the overview, and anywhere else
|
||||
// a note's kind needs to be shown at a glance.
|
||||
//
|
||||
// Kind is encoded by **icon shape**, not colour. Three categories would be a
|
||||
// categorical palette, and at the 12px mark size the tree uses, colour alone
|
||||
// is the least reliable channel there is — it fails for colour-vision
|
||||
// deficiency, and small low-chroma marks on a dark surface are hard for
|
||||
// anyone to tell apart. Distinct silhouettes are legible at any size, in any
|
||||
// theme, for every reader. Colour is left to carry state (selection, the
|
||||
// agent badge), where it isn't the only thing distinguishing two items.
|
||||
//
|
||||
// It also fixes a plain redundancy: the tree previously stamped a literal
|
||||
// "document" text badge on every row, which in a folder of 20 documents is
|
||||
// 20 repetitions of the same word and no information at all.
|
||||
import FileTextIcon from '@lucide/svelte/icons/file-text'
|
||||
import MicroscopeIcon from '@lucide/svelte/icons/microscope'
|
||||
import ListChecksIcon from '@lucide/svelte/icons/list-checks'
|
||||
import type { Component } from 'svelte'
|
||||
|
||||
export type NoteKind = 'document' | 'investigation' | 'runbook'
|
||||
|
||||
export interface KindMeta {
|
||||
icon: Component
|
||||
label: string
|
||||
/** Plural, for counts and section headings. */
|
||||
plural: string
|
||||
}
|
||||
|
||||
const FALLBACK: KindMeta = { icon: FileTextIcon, label: 'note', plural: 'notes' }
|
||||
|
||||
const KIND_META: Record<NoteKind, KindMeta> = {
|
||||
document: { icon: FileTextIcon, label: 'document', plural: 'documents' },
|
||||
investigation: { icon: MicroscopeIcon, label: 'investigation', plural: 'investigations' },
|
||||
runbook: { icon: ListChecksIcon, label: 'runbook', plural: 'runbooks' }
|
||||
}
|
||||
|
||||
// Tolerates an unknown kind rather than throwing — `kind` comes from the
|
||||
// entity's type column, which the ontology could grow a fourth value for
|
||||
// without this file knowing.
|
||||
export function kindMeta(kind: string): KindMeta {
|
||||
return KIND_META[kind as NoteKind] ?? FALLBACK
|
||||
}
|
||||
|
||||
// True for notes last written by the agent rather than a human. Two spellings
|
||||
// exist in the live data: 'nomos-agent' (written via the MCP upsert_knowledge
|
||||
// tool) and 'agent:mcp' (the actor label the HTTP API records when the same
|
||||
// agent calls in over REST with the MCP bearer token).
|
||||
export function isAgentAuthored(editedBy: string): boolean {
|
||||
return editedBy === 'nomos-agent' || editedBy === 'agent:mcp'
|
||||
}
|
||||
Reference in New Issue
Block a user