@powerhousedao/knowledge-note 1.0.0 → 1.0.2

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 (56) hide show
  1. package/dist/editors/health-report-editor/editor.d.ts.map +1 -1
  2. package/dist/editors/health-report-editor/editor.js +100 -17
  3. package/dist/editors/knowledge-note-editor/editor.d.ts.map +1 -1
  4. package/dist/editors/knowledge-note-editor/editor.js +12 -3
  5. package/dist/editors/knowledge-vault/components/DriveExplorer.d.ts.map +1 -1
  6. package/dist/editors/knowledge-vault/components/GettingStarted.js +26 -7
  7. package/dist/editors/knowledge-vault/components/GraphView.d.ts +1 -1
  8. package/dist/editors/knowledge-vault/components/GraphView.d.ts.map +1 -1
  9. package/dist/editors/knowledge-vault/components/GraphView.js +1 -1
  10. package/dist/editors/knowledge-vault/components/HealthDashboard.d.ts.map +1 -1
  11. package/dist/editors/knowledge-vault/components/HealthDashboard.js +16 -4
  12. package/dist/editors/knowledge-vault/hooks/use-drive-init.d.ts.map +1 -1
  13. package/dist/editors/knowledge-vault/hooks/use-drive-init.js +78 -62
  14. package/dist/editors/moc-editor/editor.d.ts.map +1 -1
  15. package/dist/editors/moc-editor/editor.js +13 -4
  16. package/dist/editors/tension-editor/editor.d.ts.map +1 -1
  17. package/dist/editors/tension-editor/editor.js +60 -9
  18. package/dist/package.json +45 -1
  19. package/dist/processors/factory.d.ts.map +1 -1
  20. package/dist/processors/factory.js +4 -1
  21. package/dist/processors/graph-indexer/index.d.ts.map +1 -1
  22. package/dist/processors/graph-indexer/query.d.ts.map +1 -1
  23. package/dist/processors/graph-indexer/query.js +2 -1
  24. package/dist/processors/methodology-indexer/factory.d.ts +4 -0
  25. package/dist/processors/methodology-indexer/factory.d.ts.map +1 -0
  26. package/dist/processors/methodology-indexer/factory.js +23 -0
  27. package/dist/processors/methodology-indexer/index.d.ts +11 -0
  28. package/dist/processors/methodology-indexer/index.d.ts.map +1 -0
  29. package/dist/processors/methodology-indexer/index.js +116 -0
  30. package/dist/processors/methodology-indexer/migrations.d.ts +4 -0
  31. package/dist/processors/methodology-indexer/migrations.d.ts.map +1 -0
  32. package/dist/processors/methodology-indexer/migrations.js +39 -0
  33. package/dist/processors/methodology-indexer/query.d.ts +35 -0
  34. package/dist/processors/methodology-indexer/query.d.ts.map +1 -0
  35. package/dist/processors/methodology-indexer/query.js +114 -0
  36. package/dist/processors/methodology-indexer/schema.d.ts +22 -0
  37. package/dist/processors/methodology-indexer/schema.d.ts.map +1 -0
  38. package/dist/processors/methodology-indexer/schema.js +1 -0
  39. package/dist/style.css +15 -0
  40. package/dist/subgraphs/index.d.ts +1 -0
  41. package/dist/subgraphs/index.d.ts.map +1 -1
  42. package/dist/subgraphs/index.js +1 -0
  43. package/dist/subgraphs/knowledge-graph/subgraph.d.ts.map +1 -1
  44. package/dist/subgraphs/knowledge-graph/subgraph.js +45 -15
  45. package/dist/subgraphs/methodology/index.d.ts +2 -0
  46. package/dist/subgraphs/methodology/index.d.ts.map +1 -0
  47. package/dist/subgraphs/methodology/index.js +1 -0
  48. package/dist/subgraphs/methodology/subgraph.d.ts +47 -0
  49. package/dist/subgraphs/methodology/subgraph.d.ts.map +1 -0
  50. package/dist/subgraphs/methodology/subgraph.js +100 -0
  51. package/dist/tests/processor/graph-indexer.test.js +8 -2
  52. package/dist/tests/unit/knowledge-note-reducers.test.js +4 -1
  53. package/dist/tests/unit/lifecycle-state-machine.test.js +16 -4
  54. package/dist/tests/unit/moc-reducers.test.js +1 -1
  55. package/dist/tests/unit/pipeline-queue-reducers.test.js +10 -2
  56. package/package.json +45 -1
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/health-report-editor/editor.tsx"],"names":[],"mappings":"AAgBA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAiK7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/health-report-editor/editor.tsx"],"names":[],"mappings":"AAcA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAuU7B"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DocumentToolbar } from "@powerhousedao/design-system/connect";
3
- import { useSelectedHealthReportDocument, } from "../../document-models/health-report/v1/hooks.js";
3
+ import { useSelectedHealthReportDocument } from "../../document-models/health-report/v1/hooks.js";
4
4
  import { setSelectedNode, useDocumentsInSelectedDrive, } from "@powerhousedao/reactor-browser";
5
5
  import { TOOLBAR_CLASS } from "../shared/theme-context.js";
6
6
  const STATUS_BADGE = {
@@ -14,26 +14,103 @@ export default function Editor() {
14
14
  const documents = useDocumentsInSelectedDrive();
15
15
  const isEmpty = !state.generatedAt;
16
16
  if (isEmpty) {
17
- return (_jsx("div", { className: "min-h-screen", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text)" }, children: _jsxs("div", { className: "mx-auto max-w-3xl", children: [_jsx(DocumentToolbar, { className: TOOLBAR_CLASS }), _jsx("div", { className: "flex h-64 items-center justify-center rounded-xl m-6", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-sm", style: { color: "var(--bai-text-muted)" }, children: "No health report generated yet" }), _jsx("p", { className: "mt-1 text-xs", style: { color: "var(--bai-text-faint)" }, children: "Run /health in Claude Code to generate a vault health report" })] }) })] }) }));
17
+ return (_jsx("div", { className: "min-h-screen", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text)" }, children: _jsxs("div", { className: "mx-auto max-w-3xl", children: [_jsx(DocumentToolbar, { className: TOOLBAR_CLASS }), _jsx("div", { className: "flex h-64 items-center justify-center rounded-xl m-6", style: {
18
+ backgroundColor: "var(--bai-surface)",
19
+ border: "1px solid var(--bai-border)",
20
+ }, children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-sm", style: { color: "var(--bai-text-muted)" }, children: "No health report generated yet" }), _jsx("p", { className: "mt-1 text-xs", style: { color: "var(--bai-text-faint)" }, children: "Run /health in Claude Code to generate a vault health report" })] }) })] }) }));
18
21
  }
19
22
  const metrics = state.graphMetrics;
20
23
  const checks = state.checks ?? [];
21
24
  const recommendations = state.recommendations ?? [];
22
- return (_jsx("div", { className: "min-h-screen", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text)" }, children: _jsxs("div", { className: "mx-auto max-w-4xl", children: [_jsx(DocumentToolbar, { className: TOOLBAR_CLASS }), _jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center gap-4 rounded-xl p-6", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: [_jsx("span", { className: `rounded-full border px-4 py-1.5 text-sm font-bold ${STATUS_BADGE[state.overallStatus ?? "PASS"]}`, children: state.overallStatus }), _jsxs("div", { className: "flex-1", children: [_jsx("h1", { className: "text-xl font-bold", style: { color: "var(--bai-text)" }, children: "Vault Health" }), _jsxs("p", { className: "text-xs", style: { color: "var(--bai-text-muted)" }, children: ["Generated ", new Date(state.generatedAt).toLocaleString(), state.generatedBy && ` by ${state.generatedBy}`, state.mode && ` \u2022 ${state.mode} mode`] })] })] }), metrics && (_jsx("div", { className: "grid grid-cols-4 gap-3", children: [
23
- { label: "Notes", value: metrics.noteCount, color: "var(--bai-accent)" },
24
- { label: "MOCs", value: metrics.mocCount, color: undefined, cls: "text-blue-400" },
25
- { label: "Edges", value: metrics.connectionCount, color: undefined, cls: "text-emerald-400" },
26
- { label: "Density", value: `${(metrics.density * 100).toFixed(1)}%`, color: "var(--bai-text-secondary)" },
27
- { label: "Orphans", value: metrics.orphanCount, color: undefined, cls: metrics.orphanCount > 0 ? "text-amber-400" : "text-emerald-400" },
28
- { label: "Dangling", value: metrics.danglingLinkCount, color: undefined, cls: metrics.danglingLinkCount > 0 ? "text-red-400" : "text-emerald-400" },
29
- { label: "Avg Links", value: metrics.averageLinksPerNote.toFixed(1), color: undefined, cls: metrics.averageLinksPerNote < 2 ? "text-amber-400" : "text-emerald-400" },
30
- { label: "MOC Coverage", value: `${(metrics.mocCoverage * 100).toFixed(0)}%`, color: "var(--bai-text-tertiary)" },
31
- ].map((m) => (_jsxs("div", { className: "rounded-xl p-4", style: { backgroundColor: "var(--bai-surface)", boxShadow: "0 0 0 1px var(--bai-ring)" }, children: [_jsx("p", { className: `text-xl font-bold ${m.cls ?? ""}`, style: m.color ? { color: m.color } : undefined, children: m.value }), _jsx("p", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: m.label })] }, m.label))) })), _jsxs("div", { className: "rounded-xl p-6", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: [_jsxs("h3", { className: "mb-3 text-xs font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: ["Health Checks (", checks.length, ")"] }), checks.length === 0 ? (_jsx("p", { className: "text-sm py-4 text-center", style: { color: "var(--bai-text-faint)" }, children: "No checks recorded" })) : (_jsx("div", { className: "space-y-3", children: checks.map((check) => (_jsxs("div", { className: "rounded-lg px-4 py-3", style: { backgroundColor: "var(--bai-bg)", border: "1px solid var(--bai-border)" }, children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("span", { className: `mt-0.5 shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-bold ${STATUS_BADGE[check.status]}`, children: check.status }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-xs font-medium", style: { color: "var(--bai-text-secondary)" }, children: check.category.replaceAll("_", " ") }), _jsx("p", { className: "mt-0.5 text-xs", style: { color: "var(--bai-text-muted)" }, children: check.message }), check.affectedItems.length > 0 && check.status !== "PASS" && (_jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [check.affectedItems.slice(0, 5).map((item, i) => {
32
- const noteDoc = (documents ?? []).find((d) => (d.header.documentType === "bai/knowledge-note" || d.header.documentType === "bai/source") &&
25
+ return (_jsx("div", { className: "min-h-screen", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text)" }, children: _jsxs("div", { className: "mx-auto max-w-4xl", children: [_jsx(DocumentToolbar, { className: TOOLBAR_CLASS }), _jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center gap-4 rounded-xl p-6", style: {
26
+ backgroundColor: "var(--bai-surface)",
27
+ border: "1px solid var(--bai-border)",
28
+ }, children: [_jsx("span", { className: `rounded-full border px-4 py-1.5 text-sm font-bold ${STATUS_BADGE[state.overallStatus ?? "PASS"]}`, children: state.overallStatus }), _jsxs("div", { className: "flex-1", children: [_jsx("h1", { className: "text-xl font-bold", style: { color: "var(--bai-text)" }, children: "Vault Health" }), _jsxs("p", { className: "text-xs", style: { color: "var(--bai-text-muted)" }, children: ["Generated ", new Date(state.generatedAt).toLocaleString(), state.generatedBy && ` by ${state.generatedBy}`, state.mode && ` \u2022 ${state.mode} mode`] })] })] }), metrics && (_jsx("div", { className: "grid grid-cols-4 gap-3", children: [
29
+ {
30
+ label: "Notes",
31
+ value: metrics.noteCount,
32
+ color: "var(--bai-accent)",
33
+ },
34
+ {
35
+ label: "MOCs",
36
+ value: metrics.mocCount,
37
+ color: undefined,
38
+ cls: "text-blue-400",
39
+ },
40
+ {
41
+ label: "Edges",
42
+ value: metrics.connectionCount,
43
+ color: undefined,
44
+ cls: "text-emerald-400",
45
+ },
46
+ {
47
+ label: "Density",
48
+ value: `${(metrics.density * 100).toFixed(1)}%`,
49
+ color: "var(--bai-text-secondary)",
50
+ },
51
+ {
52
+ label: "Orphans",
53
+ value: metrics.orphanCount,
54
+ color: undefined,
55
+ cls: metrics.orphanCount > 0
56
+ ? "text-amber-400"
57
+ : "text-emerald-400",
58
+ },
59
+ {
60
+ label: "Dangling",
61
+ value: metrics.danglingLinkCount,
62
+ color: undefined,
63
+ cls: metrics.danglingLinkCount > 0
64
+ ? "text-red-400"
65
+ : "text-emerald-400",
66
+ },
67
+ {
68
+ label: "Avg Links",
69
+ value: metrics.averageLinksPerNote.toFixed(1),
70
+ color: undefined,
71
+ cls: metrics.averageLinksPerNote < 2
72
+ ? "text-amber-400"
73
+ : "text-emerald-400",
74
+ },
75
+ {
76
+ label: "MOC Coverage",
77
+ value: `${(metrics.mocCoverage * 100).toFixed(0)}%`,
78
+ color: "var(--bai-text-tertiary)",
79
+ },
80
+ ].map((m) => (_jsxs("div", { className: "rounded-xl p-4", style: {
81
+ backgroundColor: "var(--bai-surface)",
82
+ boxShadow: "0 0 0 1px var(--bai-ring)",
83
+ }, children: [_jsx("p", { className: `text-xl font-bold ${m.cls ?? ""}`, style: m.color ? { color: m.color } : undefined, children: m.value }), _jsx("p", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: m.label })] }, m.label))) })), _jsxs("div", { className: "rounded-xl p-6", style: {
84
+ backgroundColor: "var(--bai-surface)",
85
+ border: "1px solid var(--bai-border)",
86
+ }, children: [_jsxs("h3", { className: "mb-3 text-xs font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: ["Health Checks (", checks.length, ")"] }), checks.length === 0 ? (_jsx("p", { className: "text-sm py-4 text-center", style: { color: "var(--bai-text-faint)" }, children: "No checks recorded" })) : (_jsx("div", { className: "space-y-3", children: checks.map((check) => (_jsxs("div", { className: "rounded-lg px-4 py-3", style: {
87
+ backgroundColor: "var(--bai-bg)",
88
+ border: "1px solid var(--bai-border)",
89
+ }, children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("span", { className: `mt-0.5 shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-bold ${STATUS_BADGE[check.status]}`, children: check.status }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-xs font-medium", style: { color: "var(--bai-text-secondary)" }, children: check.category.replaceAll("_", " ") }), _jsx("p", { className: "mt-0.5 text-xs", style: { color: "var(--bai-text-muted)" }, children: check.message }), check.affectedItems.length > 0 &&
90
+ check.status !== "PASS" && (_jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [check.affectedItems
91
+ .slice(0, 5)
92
+ .map((item, i) => {
93
+ const noteDoc = (documents ?? []).find((d) => (d.header.documentType ===
94
+ "bai/knowledge-note" ||
95
+ d.header.documentType ===
96
+ "bai/source") &&
33
97
  (d.state.global.title === item ||
34
98
  d.header.name === item));
35
- return noteDoc ? (_jsx("button", { type: "button", onClick: () => setSelectedNode(noteDoc.header.id), className: "rounded px-1.5 py-0.5 text-[10px] cursor-pointer", style: { backgroundColor: "var(--bai-hover)", color: "var(--bai-accent)" }, children: item.length > 50 ? item.slice(0, 50) + "\u2026" : item }, i)) : (_jsx("span", { className: "rounded px-1.5 py-0.5 text-[10px]", style: { backgroundColor: "var(--bai-hover)", color: "var(--bai-text-faint)" }, children: item.length > 50 ? item.slice(0, 50) + "\u2026" : item }, i));
36
- }), check.affectedItems.length > 5 && (_jsxs("span", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: ["+", check.affectedItems.length - 5, " more"] }))] }))] })] }), check.status !== "PASS" && (_jsx(CheckGuidance, { category: check.category, affectedItems: check.affectedItems }))] }, check.id))) }))] }), recommendations.length > 0 && (_jsxs("div", { className: "rounded-xl p-6", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: [_jsxs("h3", { className: "mb-3 text-xs font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: ["Recommendations (", recommendations.length, ")"] }), _jsx("ul", { className: "space-y-2", children: recommendations.map((rec, i) => (_jsxs("li", { className: "flex items-start gap-2 text-xs", style: { color: "var(--bai-text-secondary)" }, children: [_jsx("span", { className: "mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: "var(--bai-accent)" } }), rec] }, i))) })] }))] })] }) }));
99
+ return noteDoc ? (_jsx("button", { type: "button", onClick: () => setSelectedNode(noteDoc.header.id), className: "rounded px-1.5 py-0.5 text-[10px] cursor-pointer", style: {
100
+ backgroundColor: "var(--bai-hover)",
101
+ color: "var(--bai-accent)",
102
+ }, children: item.length > 50
103
+ ? item.slice(0, 50) + "\u2026"
104
+ : item }, i)) : (_jsx("span", { className: "rounded px-1.5 py-0.5 text-[10px]", style: {
105
+ backgroundColor: "var(--bai-hover)",
106
+ color: "var(--bai-text-faint)",
107
+ }, children: item.length > 50
108
+ ? item.slice(0, 50) + "\u2026"
109
+ : item }, i));
110
+ }), check.affectedItems.length > 5 && (_jsxs("span", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: ["+", check.affectedItems.length - 5, " more"] }))] }))] })] }), check.status !== "PASS" && (_jsx(CheckGuidance, { category: check.category, affectedItems: check.affectedItems }))] }, check.id))) }))] }), recommendations.length > 0 && (_jsxs("div", { className: "rounded-xl p-6", style: {
111
+ backgroundColor: "var(--bai-surface)",
112
+ border: "1px solid var(--bai-border)",
113
+ }, children: [_jsxs("h3", { className: "mb-3 text-xs font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: ["Recommendations (", recommendations.length, ")"] }), _jsx("ul", { className: "space-y-2", children: recommendations.map((rec, i) => (_jsxs("li", { className: "flex items-start gap-2 text-xs", style: { color: "var(--bai-text-secondary)" }, children: [_jsx("span", { className: "mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: "var(--bai-accent)" } }), rec] }, i))) })] }))] })] }) }));
37
114
  }
38
115
  const GUIDANCE = {
39
116
  ORPHAN_DETECTION: {
@@ -77,9 +154,15 @@ const GUIDANCE = {
77
154
  icon: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z",
78
155
  },
79
156
  };
80
- function CheckGuidance({ category, affectedItems }) {
157
+ function CheckGuidance({ category, affectedItems, }) {
81
158
  const guidance = GUIDANCE[category];
82
159
  if (!guidance)
83
160
  return null;
84
- return (_jsx("div", { className: "mt-3 rounded-lg px-4 py-3", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("svg", { className: "mt-0.5 h-4 w-4 shrink-0", style: { color: "var(--bai-accent)" }, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: guidance.icon }) }), _jsxs("div", { className: "flex-1 space-y-2", children: [_jsxs("div", { children: [_jsx("p", { className: "text-[10px] font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: "How to fix" }), _jsx("p", { className: "mt-0.5 text-xs leading-relaxed", style: { color: "var(--bai-text-secondary)" }, children: guidance.manual })] }), _jsxs("div", { className: "flex items-center gap-2 rounded-md px-3 py-2", style: { backgroundColor: "var(--bai-bg)", border: "1px solid var(--bai-border)" }, children: [_jsx("span", { className: "text-[10px] font-semibold", style: { color: "var(--bai-text-muted)" }, children: "AI Agent:" }), _jsx("code", { className: "text-[11px] font-mono", style: { color: "var(--bai-accent)" }, children: guidance.agent }), _jsx("span", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: "in Claude Code" })] })] })] }) }));
161
+ return (_jsx("div", { className: "mt-3 rounded-lg px-4 py-3", style: {
162
+ backgroundColor: "var(--bai-surface)",
163
+ border: "1px solid var(--bai-border)",
164
+ }, children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("svg", { className: "mt-0.5 h-4 w-4 shrink-0", style: { color: "var(--bai-accent)" }, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: guidance.icon }) }), _jsxs("div", { className: "flex-1 space-y-2", children: [_jsxs("div", { children: [_jsx("p", { className: "text-[10px] font-semibold uppercase tracking-wider", style: { color: "var(--bai-text-muted)" }, children: "How to fix" }), _jsx("p", { className: "mt-0.5 text-xs leading-relaxed", style: { color: "var(--bai-text-secondary)" }, children: guidance.manual })] }), _jsxs("div", { className: "flex items-center gap-2 rounded-md px-3 py-2", style: {
165
+ backgroundColor: "var(--bai-bg)",
166
+ border: "1px solid var(--bai-border)",
167
+ }, children: [_jsx("span", { className: "text-[10px] font-semibold", style: { color: "var(--bai-text-muted)" }, children: "AI Agent:" }), _jsx("code", { className: "text-[11px] font-mono", style: { color: "var(--bai-accent)" }, children: guidance.agent }), _jsx("span", { className: "text-[10px]", style: { color: "var(--bai-text-faint)" }, children: "in Claude Code" })] })] })] }) }));
85
168
  }
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/knowledge-note-editor/editor.tsx"],"names":[],"mappings":"AAgCA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAgX7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/knowledge-note-editor/editor.tsx"],"names":[],"mappings":"AAgCA,MAAM,CAAC,OAAO,UAAU,MAAM,4CA2X7B"}
@@ -64,10 +64,19 @@ export default function Editor() {
64
64
  actor,
65
65
  timestamp: ts,
66
66
  comment,
67
- })), onApprove: (id, actor, ts, comment) => dispatch(actions.approveNote({ id, actor, timestamp: ts, comment })), onReject: (id, actor, ts, comment) => dispatch(actions.rejectNote({ id, actor, timestamp: ts, comment })), onArchive: (id, actor, ts, comment) => dispatch(actions.archiveNote({ id, actor, timestamp: ts, comment })), onRestore: (id, actor, ts, comment) => dispatch(actions.restoreNote({ id, actor, timestamp: ts, comment })) }), _jsx("input", { type: "text", defaultValue: state.title ?? "", placeholder: "Untitled Note", onBlur: (e) => handleSetTitle(e.target.value.trim()), onKeyDown: (e) => {
68
- if (e.key === "Enter")
67
+ })), onApprove: (id, actor, ts, comment) => dispatch(actions.approveNote({ id, actor, timestamp: ts, comment })), onReject: (id, actor, ts, comment) => dispatch(actions.rejectNote({ id, actor, timestamp: ts, comment })), onArchive: (id, actor, ts, comment) => dispatch(actions.archiveNote({ id, actor, timestamp: ts, comment })), onRestore: (id, actor, ts, comment) => dispatch(actions.restoreNote({ id, actor, timestamp: ts, comment })) }), _jsx("textarea", { defaultValue: state.title ?? "", placeholder: "Untitled Note", onBlur: (e) => handleSetTitle(e.target.value.trim()), onKeyDown: (e) => {
68
+ if (e.key === "Enter" && !e.shiftKey)
69
69
  e.currentTarget.blur();
70
- }, className: "w-full border-0 bg-transparent text-2xl font-bold outline-none", style: { color: "var(--bai-text)" } })] }), _jsx("textarea", { defaultValue: state.description ?? "", placeholder: "Brief description (max 200 chars)...", maxLength: 200, rows: 2, onBlur: (e) => handleSetDescription(e.target.value.trim()), className: "w-full resize-none rounded-lg px-3 py-2 text-sm outline-none placeholder:opacity-50 focus:border-[#cba6f7]/50", style: {
70
+ }, onInput: (e) => {
71
+ const el = e.currentTarget;
72
+ el.style.height = "auto";
73
+ el.style.height = `${el.scrollHeight}px`;
74
+ }, ref: (el) => {
75
+ if (el) {
76
+ el.style.height = "auto";
77
+ el.style.height = `${el.scrollHeight}px`;
78
+ }
79
+ }, rows: 1, className: "w-full resize-y border-0 bg-transparent text-2xl font-bold leading-snug outline-none", style: { color: "var(--bai-text)", overflow: "hidden" } })] }), _jsx("textarea", { defaultValue: state.description ?? "", placeholder: "Brief description (max 200 chars)...", maxLength: 200, rows: 2, onBlur: (e) => handleSetDescription(e.target.value.trim()), className: "w-full resize-none rounded-lg px-3 py-2 text-sm outline-none placeholder:opacity-50 focus:border-[#cba6f7]/50", style: {
71
80
  backgroundColor: "var(--bai-bg)",
72
81
  color: "var(--bai-text-secondary)",
73
82
  border: "1px solid var(--bai-border)",
@@ -1 +1 @@
1
- {"version":3,"file":"DriveExplorer.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/DriveExplorer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA+BlD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW,2CAiUtD"}
1
+ {"version":3,"file":"DriveExplorer.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/DriveExplorer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA+BlD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW,2CA+UtD"}
@@ -14,16 +14,29 @@ function GettingStartedModal({ onClose }) {
14
14
  { id: "graph", label: "Graph & Links" },
15
15
  { id: "plugin", label: "AI Agent" },
16
16
  ];
17
- return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 bg-black/60", onClick: onClose }), _jsxs("div", { className: "relative z-10 flex h-[80vh] w-[720px] max-w-[90vw] flex-col rounded-2xl shadow-2xl", style: { backgroundColor: "var(--bai-surface)", border: "1px solid var(--bai-border)" }, children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4", style: { borderBottom: "1px solid var(--bai-border)" }, children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-bold", style: { color: "var(--bai-text)" }, children: "Getting Started" }), _jsx("p", { className: "text-xs", style: { color: "var(--bai-text-muted)" }, children: "Learn how to use the Knowledge Vault" })] }), _jsx("button", { type: "button", onClick: onClose, className: "rounded-lg p-2 transition-colors", style: { color: "var(--bai-text-muted)" }, children: _jsx("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [_jsx("div", { className: "w-44 shrink-0 py-3", style: { borderRight: "1px solid var(--bai-border)" }, children: sections.map((s) => (_jsx("button", { type: "button", onClick: () => setActiveSection(s.id), className: "flex w-full px-4 py-2 text-left text-xs transition-colors", style: {
18
- backgroundColor: activeSection === s.id ? "var(--bai-accent-soft)" : "transparent",
19
- color: activeSection === s.id ? "var(--bai-accent)" : "var(--bai-text-tertiary)",
17
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 bg-black/60", onClick: onClose }), _jsxs("div", { className: "relative z-10 flex h-[80vh] w-[720px] max-w-[90vw] flex-col rounded-2xl shadow-2xl", style: {
18
+ backgroundColor: "var(--bai-surface)",
19
+ border: "1px solid var(--bai-border)",
20
+ }, children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4", style: { borderBottom: "1px solid var(--bai-border)" }, children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-bold", style: { color: "var(--bai-text)" }, children: "Getting Started" }), _jsx("p", { className: "text-xs", style: { color: "var(--bai-text-muted)" }, children: "Learn how to use the Knowledge Vault" })] }), _jsx("button", { type: "button", onClick: onClose, className: "rounded-lg p-2 transition-colors", style: { color: "var(--bai-text-muted)" }, children: _jsx("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [_jsx("div", { className: "w-44 shrink-0 py-3", style: { borderRight: "1px solid var(--bai-border)" }, children: sections.map((s) => (_jsx("button", { type: "button", onClick: () => setActiveSection(s.id), className: "flex w-full px-4 py-2 text-left text-xs transition-colors", style: {
21
+ backgroundColor: activeSection === s.id
22
+ ? "var(--bai-accent-soft)"
23
+ : "transparent",
24
+ color: activeSection === s.id
25
+ ? "var(--bai-accent)"
26
+ : "var(--bai-text-tertiary)",
20
27
  fontWeight: activeSection === s.id ? 500 : 400,
21
28
  }, children: s.label }, s.id))) }), _jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-5", children: [activeSection === "overview" && _jsx(OverviewSection, {}), activeSection === "sources" && _jsx(SourcesSection, {}), activeSection === "notes" && _jsx(NotesSection, {}), activeSection === "pipeline" && _jsx(PipelineSection, {}), activeSection === "graph" && _jsx(GraphSection, {}), activeSection === "plugin" && _jsx(PluginSection, {})] })] })] })] }));
22
29
  }
23
30
  const H = ({ children }) => (_jsx("h3", { className: "mb-3 text-sm font-semibold", style: { color: "var(--bai-text)" }, children: children }));
24
31
  const P = ({ children }) => (_jsx("p", { className: "mb-4 text-xs leading-relaxed", style: { color: "var(--bai-text-tertiary)" }, children: children }));
25
- const Step = ({ n, title, children, }) => (_jsxs("div", { className: "mb-4 flex gap-3", children: [_jsx("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-bold", style: { backgroundColor: "var(--bai-accent-soft)", color: "var(--bai-accent)" }, children: n }), _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium", style: { color: "var(--bai-text)" }, children: title }), _jsx("p", { className: "mt-0.5 text-xs", style: { color: "var(--bai-text-muted)" }, children: children })] })] }));
26
- const Tip = ({ children }) => (_jsx("div", { className: "mb-4 rounded-lg px-4 py-3", style: { border: "1px solid var(--bai-accent-soft)", backgroundColor: "var(--bai-accent-soft)" }, children: _jsx("p", { className: "text-xs", style: { color: "var(--bai-accent)", opacity: 0.8 }, children: children }) }));
32
+ const Step = ({ n, title, children, }) => (_jsxs("div", { className: "mb-4 flex gap-3", children: [_jsx("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-bold", style: {
33
+ backgroundColor: "var(--bai-accent-soft)",
34
+ color: "var(--bai-accent)",
35
+ }, children: n }), _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium", style: { color: "var(--bai-text)" }, children: title }), _jsx("p", { className: "mt-0.5 text-xs", style: { color: "var(--bai-text-muted)" }, children: children })] })] }));
36
+ const Tip = ({ children }) => (_jsx("div", { className: "mb-4 rounded-lg px-4 py-3", style: {
37
+ border: "1px solid var(--bai-accent-soft)",
38
+ backgroundColor: "var(--bai-accent-soft)",
39
+ }, children: _jsx("p", { className: "text-xs", style: { color: "var(--bai-accent)", opacity: 0.8 }, children: children }) }));
27
40
  function OverviewSection() {
28
41
  return (_jsxs("div", { children: [_jsx(H, { children: "What is the Knowledge Vault?" }), _jsx(P, { children: "A structured knowledge management system where raw content (articles, notes, transcripts) is processed into atomic claims, connected into a knowledge graph, and maintained over time." }), _jsx(H, { children: "The Navigation Tabs" }), _jsx("div", { className: "space-y-2 mb-4", children: [
29
42
  {
@@ -62,7 +75,10 @@ function SourcesSection() {
62
75
  "WEB_PAGE",
63
76
  "BOOK_CHAPTER",
64
77
  "MANUAL_ENTRY",
65
- ].map((t) => (_jsx("span", { className: "rounded px-2 py-1 text-[10px]", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text-tertiary)" }, children: t }, t))) }), _jsx(H, { children: "Source Lifecycle" }), _jsx(P, { children: "INBOX (new) \u2192 EXTRACTING (queued for AI) \u2192 EXTRACTED (claims created) \u2192 ARCHIVED (done)" }), _jsx(Tip, { children: "You can edit a source after creating it. Click \"Edit\" in the source viewer. Saving resets the status to INBOX so it can be re-processed with the updated content." }), _jsx(H, { children: "Deleting Sources" }), _jsx(P, { children: "In the Sources tab, hover over a source and click the trash icon. A confirmation dialog will appear before deletion." })] }));
78
+ ].map((t) => (_jsx("span", { className: "rounded px-2 py-1 text-[10px]", style: {
79
+ backgroundColor: "var(--bai-bg)",
80
+ color: "var(--bai-text-tertiary)",
81
+ }, children: t }, t))) }), _jsx(H, { children: "Source Lifecycle" }), _jsx(P, { children: "INBOX (new) \u2192 EXTRACTING (queued for AI) \u2192 EXTRACTED (claims created) \u2192 ARCHIVED (done)" }), _jsx(Tip, { children: "You can edit a source after creating it. Click \"Edit\" in the source viewer. Saving resets the status to INBOX so it can be re-processed with the updated content." }), _jsx(H, { children: "Deleting Sources" }), _jsx(P, { children: "In the Sources tab, hover over a source and click the trash icon. A confirmation dialog will appear before deletion." })] }));
66
82
  }
67
83
  function NotesSection() {
68
84
  return (_jsxs("div", { children: [_jsx(H, { children: "Knowledge Notes" }), _jsx(P, { children: "Each note is an atomic claim \u2014 one idea, one point. Notes have declarative titles that read as complete sentences." }), _jsx(H, { children: "Note Structure" }), _jsx("div", { className: "space-y-1 mb-4", children: [
@@ -153,7 +169,10 @@ function GraphSection() {
153
169
  ].map((item) => (_jsxs("div", { className: "flex gap-2 rounded px-3 py-1.5", style: { backgroundColor: "var(--bai-bg)" }, children: [_jsx("span", { className: "shrink-0 text-[10px] font-medium w-20", style: { color: "var(--bai-text-secondary)" }, children: item.metric }), _jsx("span", { className: "text-[10px]", style: { color: "var(--bai-text-muted)" }, children: item.desc })] }, item.metric))) }), _jsx(Tip, { children: "The graph auto-syncs when notes change. If you add a link in the note editor, the graph view updates on the next tab switch." })] }));
154
170
  }
155
171
  function PluginSection() {
156
- return (_jsxs("div", { children: [_jsx(H, { children: "AI Agent (Claude Plugin)" }), _jsx(P, { children: "The powerhouse-knowledge plugin connects Claude Code to your vault. The AI agent can extract claims, find connections, verify quality, and analyze the graph." }), _jsx(H, { children: "Setup \u2014 Local" }), _jsx(Step, { n: 1, title: "Start the reactor locally", children: "Run ph vetra --watch in your project directory. MCP is served at http://localhost:4001/mcp" }), _jsx(Step, { n: 2, title: "Open Claude Code with the plugin", children: "claude --plugin-dir ~/path/to/powerhouse-knowledge" }), _jsx(Step, { n: 3, title: "Run /setup", children: "This imports the Ars Contexta methodology (249 research claims) if not already present." }), _jsx(H, { children: "Setup \u2014 Remote Vault" }), _jsx(P, { children: "You can also connect to any remote Switchboard instance instead of running locally. Edit .mcp.json in the plugin directory to point to the remote reactor:" }), _jsxs("div", { className: "mb-4 rounded-lg px-4 py-3 font-mono text-[11px]", style: { backgroundColor: "var(--bai-bg)", color: "var(--bai-text-secondary)" }, children: [_jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `{` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` "mcpServers": { "reactor-mcp": {` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` "url": "` }), _jsx("span", { className: "text-emerald-400", children: "https://your-switchboard.example.com/mcp" }), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `"` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` }}` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `}` })] }), _jsx(Tip, { children: "No local reactor needed when connecting remotely. The plugin talks to the remote Switchboard via MCP over HTTPS. All skills work the same way \u2014 the only difference is the endpoint URL." }), _jsx(H, { children: "Key Commands" }), _jsx("div", { className: "space-y-1 mb-4", children: [
172
+ return (_jsxs("div", { children: [_jsx(H, { children: "AI Agent (Claude Plugin)" }), _jsx(P, { children: "The powerhouse-knowledge plugin connects Claude Code to your vault. The AI agent can extract claims, find connections, verify quality, and analyze the graph." }), _jsx(H, { children: "Setup \u2014 Local" }), _jsx(Step, { n: 1, title: "Start the reactor locally", children: "Run ph vetra --watch in your project directory. MCP is served at http://localhost:4001/mcp" }), _jsx(Step, { n: 2, title: "Open Claude Code with the plugin", children: "claude --plugin-dir ~/path/to/powerhouse-knowledge" }), _jsx(Step, { n: 3, title: "Run /setup", children: "This imports the Ars Contexta methodology (249 research claims) if not already present." }), _jsx(H, { children: "Setup \u2014 Remote Vault" }), _jsx(P, { children: "You can also connect to any remote Switchboard instance instead of running locally. Edit .mcp.json in the plugin directory to point to the remote reactor:" }), _jsxs("div", { className: "mb-4 rounded-lg px-4 py-3 font-mono text-[11px]", style: {
173
+ backgroundColor: "var(--bai-bg)",
174
+ color: "var(--bai-text-secondary)",
175
+ }, children: [_jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `{` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` "mcpServers": { "reactor-mcp": {` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` "url": "` }), _jsx("span", { className: "text-emerald-400", children: "https://your-switchboard.example.com/mcp" }), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `"` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: ` }}` }), _jsx("br", {}), _jsx("span", { style: { color: "var(--bai-text-muted)" }, children: `}` })] }), _jsx(Tip, { children: "No local reactor needed when connecting remotely. The plugin talks to the remote Switchboard via MCP over HTTPS. All skills work the same way \u2014 the only difference is the endpoint URL." }), _jsx(H, { children: "Key Commands" }), _jsx("div", { className: "space-y-1 mb-4", children: [
157
176
  { cmd: "/seed", desc: "Ingest source material for processing" },
158
177
  { cmd: "/extract", desc: "Extract atomic claims from a source" },
159
178
  { cmd: "/connect", desc: "Find and create links between notes" },
@@ -36,6 +36,6 @@ type GraphViewProps = {
36
36
  mocs?: MocInfo[];
37
37
  tensions?: TensionInfo[];
38
38
  };
39
- export declare function GraphView({ notes, graphState, mocs, tensions }: GraphViewProps): import("react/jsx-runtime").JSX.Element;
39
+ export declare function GraphView({ notes, graphState, mocs, tensions, }: GraphViewProps): import("react/jsx-runtime").JSX.Element;
40
40
  export {};
41
41
  //# sourceMappingURL=GraphView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/GraphView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAUzE,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,EAAE,CAAC;IACJ,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,EAAE,CAAC;IACJ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,IAAI,CAAC;AAET,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzD,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B,CAAC;AAwXF,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAupB9E"}
1
+ {"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/GraphView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAUzE,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,EAAE,CAAC;IACJ,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,EAAE,CAAC;IACJ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,IAAI,CAAC;AAET,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzD,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B,CAAC;AA0XF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,UAAU,EACV,IAAI,EACJ,QAAQ,GACT,EAAE,cAAc,2CAupBhB"}
@@ -328,7 +328,7 @@ function getLayoutOptions() {
328
328
  /* ------------------------------------------------------------------ */
329
329
  /* Component */
330
330
  /* ------------------------------------------------------------------ */
331
- export function GraphView({ notes, graphState, mocs, tensions }) {
331
+ export function GraphView({ notes, graphState, mocs, tensions, }) {
332
332
  const containerRef = useRef(null);
333
333
  const cyRef = useRef(null);
334
334
  const [selectedDetail, setSelectedDetail] = useState(null);
@@ -1 +1 @@
1
- {"version":3,"file":"HealthDashboard.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/HealthDashboard.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,4CA+iB9B"}
1
+ {"version":3,"file":"HealthDashboard.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/components/HealthDashboard.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,4CA8kB9B"}
@@ -191,7 +191,14 @@ export function HealthDashboard() {
191
191
  border: "1px solid var(--bai-border)",
192
192
  }, children: [_jsx("span", { className: `rounded-full border px-4 py-1.5 text-sm font-bold ${STATUS_BADGE[agentReport?.overallStatus ?? health.overallStatus]}`, children: agentReport?.overallStatus ?? health.overallStatus }), _jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-lg font-bold", style: { color: "var(--bai-text)" }, children: "Vault Health" }), _jsx("p", { className: "text-xs", style: { color: "var(--bai-text-muted)" }, children: agentReport
193
193
  ? `Agent report from ${new Date(agentReport.generatedAt).toLocaleString()} by ${agentReport.generatedBy}`
194
- : "Live metrics \u2014 run /health in Claude Code for a full agent report" })] }), _jsx("span", { className: "rounded-full border px-3 py-1 text-[10px] font-medium", style: { borderColor: "var(--bai-border)", color: "var(--bai-text-muted)" }, children: agentReport ? "Agent" : "Live" })] }), agentReport?.recommendations && agentReport.recommendations.length > 0 && (_jsxs("div", { className: "rounded-xl p-4", style: { backgroundColor: "var(--bai-accent-soft)", border: "1px solid var(--bai-border)" }, children: [_jsx("h3", { className: "mb-2 text-xs font-semibold", style: { color: "var(--bai-accent)" }, children: "Agent Recommendations" }), _jsx("ul", { className: "space-y-1", children: agentReport.recommendations.map((rec, i) => (_jsxs("li", { className: "flex items-start gap-2 text-xs", style: { color: "var(--bai-text-secondary)" }, children: [_jsx("span", { className: "mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: "var(--bai-accent)" } }), rec] }, i))) })] })), _jsx("div", { className: "grid grid-cols-4 gap-3", children: [
194
+ : "Live metrics \u2014 run /health in Claude Code for a full agent report" })] }), _jsx("span", { className: "rounded-full border px-3 py-1 text-[10px] font-medium", style: {
195
+ borderColor: "var(--bai-border)",
196
+ color: "var(--bai-text-muted)",
197
+ }, children: agentReport ? "Agent" : "Live" })] }), agentReport?.recommendations &&
198
+ agentReport.recommendations.length > 0 && (_jsxs("div", { className: "rounded-xl p-4", style: {
199
+ backgroundColor: "var(--bai-accent-soft)",
200
+ border: "1px solid var(--bai-border)",
201
+ }, children: [_jsx("h3", { className: "mb-2 text-xs font-semibold", style: { color: "var(--bai-accent)" }, children: "Agent Recommendations" }), _jsx("ul", { className: "space-y-1", children: agentReport.recommendations.map((rec, i) => (_jsxs("li", { className: "flex items-start gap-2 text-xs", style: { color: "var(--bai-text-secondary)" }, children: [_jsx("span", { className: "mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: "var(--bai-accent)" } }), rec] }, i))) })] })), _jsx("div", { className: "grid grid-cols-4 gap-3", children: [
195
202
  {
196
203
  label: "Notes",
197
204
  value: agentReport?.graphMetrics?.noteCount ?? health.noteCount,
@@ -225,13 +232,18 @@ export function HealthDashboard() {
225
232
  {
226
233
  label: "Orphans",
227
234
  value: agentReport?.graphMetrics?.orphanCount ?? health.orphanCount,
228
- colorClass: (agentReport?.graphMetrics?.orphanCount ?? health.orphanCount) > 0 ? "text-amber-400" : "text-emerald-400",
235
+ colorClass: (agentReport?.graphMetrics?.orphanCount ?? health.orphanCount) >
236
+ 0
237
+ ? "text-amber-400"
238
+ : "text-emerald-400",
229
239
  colorStyle: undefined,
230
240
  },
231
241
  {
232
242
  label: "Avg Links",
233
- value: (agentReport?.graphMetrics?.averageLinksPerNote ?? health.avgLinksPerNote).toFixed(1),
234
- colorClass: (agentReport?.graphMetrics?.averageLinksPerNote ?? health.avgLinksPerNote) < 2
243
+ value: (agentReport?.graphMetrics?.averageLinksPerNote ??
244
+ health.avgLinksPerNote).toFixed(1),
245
+ colorClass: (agentReport?.graphMetrics?.averageLinksPerNote ??
246
+ health.avgLinksPerNote) < 2
235
247
  ? "text-amber-400"
236
248
  : "text-emerald-400",
237
249
  colorStyle: undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"use-drive-init.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/hooks/use-drive-init.ts"],"names":[],"mappings":"AAoEA,wBAAgB,YAAY,SAsB3B;AAgHD;;;GAGG;AACH,wBAAgB,YAAY,wBAI3B"}
1
+ {"version":3,"file":"use-drive-init.d.ts","sourceRoot":"","sources":["../../../../editors/knowledge-vault/hooks/use-drive-init.ts"],"names":[],"mappings":"AA+DA,wBAAgB,YAAY,SAsB3B;AAsGD;;;GAGG;AACH,wBAAgB,YAAY,wBAI3B"}
@@ -1,19 +1,40 @@
1
- import { useEffect, useRef } from "react";
1
+ import { useEffect } from "react";
2
2
  import { useSelectedDrive, useNodesInSelectedDrive, addDocument, addFolder, } from "@powerhousedao/reactor-browser";
3
- const FOLDER_TREE = [
4
- {
5
- name: "knowledge",
6
- children: [{ name: "notes" }, { name: "inbox" }, { name: "insights" }],
7
- },
3
+ /**
4
+ * Drive folder structure matching Ars Contexta layout:
5
+ *
6
+ * /knowledge/ <- notes, MOCs, knowledge graph
7
+ * /knowledge/notes/ <- knowledge notes
8
+ * /knowledge/inbox/ <- unprocessed captures
9
+ * /knowledge/insights/ <- synthesized insights
10
+ * /sources/ <- archived source material
11
+ * /ops/ <- operational coordination
12
+ * /ops/sessions/ <- session transcripts
13
+ * /ops/health/ <- health reports
14
+ * /ops/queue/ <- pipeline queue singleton
15
+ * /self/ <- system identity & config
16
+ * /self/methodology/ <- methodology notes
17
+ * /research/ <- bundled research claims
18
+ *
19
+ * Pattern: follows contributor-billing's proven approach —
20
+ * module-level tracking Set per drive prevents duplicates,
21
+ * sequential creation with delays for sync compatibility.
22
+ */
23
+ // ─── Module-level state (survives re-renders, prevents duplicates) ───
24
+ const initStartedForDrives = new Set();
25
+ // Flat list of folders to create (order matters — parents first)
26
+ const FOLDERS = [
27
+ { name: "knowledge" },
28
+ { name: "notes", parentPath: "knowledge" },
29
+ { name: "inbox", parentPath: "knowledge" },
30
+ { name: "insights", parentPath: "knowledge" },
8
31
  { name: "sources" },
9
- {
10
- name: "ops",
11
- children: [{ name: "sessions" }, { name: "health" }, { name: "queue" }],
12
- },
13
- {
14
- name: "self",
15
- children: [{ name: "methodology" }],
16
- },
32
+ { name: "ops" },
33
+ { name: "sessions", parentPath: "ops" },
34
+ { name: "health", parentPath: "ops" },
35
+ { name: "queue", parentPath: "ops" },
36
+ { name: "self" },
37
+ { name: "methodology", parentPath: "self" },
17
38
  { name: "research" },
18
39
  ];
19
40
  const SINGLETONS = [
@@ -22,44 +43,61 @@ const SINGLETONS = [
22
43
  type: "bai/pipeline-queue",
23
44
  folderPath: "ops/queue",
24
45
  },
25
- {
26
- name: "HealthReport",
27
- type: "bai/health-report",
28
- folderPath: "ops/health",
29
- },
46
+ { name: "HealthReport", type: "bai/health-report", folderPath: "ops/health" },
30
47
  { name: "KnowledgeGraph", type: "bai/knowledge-graph", folderPath: "self" },
31
48
  { name: "VaultConfig", type: "bai/vault-config", folderPath: "self" },
32
49
  ];
33
50
  export function useDriveInit() {
34
- // Use the drive ID (UUID), never the slug
35
51
  const [selectedDrive] = useSelectedDrive();
36
52
  const driveId = selectedDrive?.header.id;
37
53
  const nodes = useNodesInSelectedDrive();
38
- const initAttempted = useRef(false);
39
54
  useEffect(() => {
40
- if (!driveId || initAttempted.current)
55
+ if (!driveId || nodes === undefined)
56
+ return;
57
+ if (initStartedForDrives.has(driveId))
41
58
  return;
42
- if (nodes === undefined)
43
- return; // still loading
44
- // Check if the root "knowledge" folder exists (our init marker)
59
+ // Check if already initialized (knowledge folder exists)
45
60
  const hasKnowledgeFolder = (nodes ?? []).some((n) => n.kind === "folder" && n.name === "knowledge" && n.parentFolder == null);
46
- if (hasKnowledgeFolder)
47
- return; // already initialized
48
- initAttempted.current = true;
49
- initDrive(driveId, nodes ?? []);
61
+ if (hasKnowledgeFolder) {
62
+ initStartedForDrives.add(driveId);
63
+ return;
64
+ }
65
+ initStartedForDrives.add(driveId);
66
+ void initDrive(driveId, nodes ?? []);
50
67
  }, [driveId, nodes]);
51
68
  }
69
+ // ─── Single sequential init: folders then singletons ───
52
70
  async function initDrive(driveId, existingNodes) {
53
71
  try {
54
- console.log(`[VaultInit] Initializing drive ${driveId}...`);
55
- // Build map of existing folders: path -> id
56
- const existingFolderIds = buildExistingFolderMap(existingNodes);
57
- const folderIds = new Map(existingFolderIds);
58
- // Create folder tree recursively
59
- await createFolderTree(driveId, FOLDER_TREE, undefined, "", folderIds);
60
- // Wait a beat for the reactor to process folder creation
61
- await new Promise((resolve) => setTimeout(resolve, 1000));
62
- // Create singleton documents in their folders
72
+ // Phase 1: Create folders
73
+ console.log(`[VaultInit] Creating folders for drive ${driveId}...`);
74
+ const existingFolderMap = buildExistingFolderMap(existingNodes);
75
+ const folderIds = new Map(existingFolderMap);
76
+ for (const folder of FOLDERS) {
77
+ const path = folder.parentPath
78
+ ? `${folder.parentPath}/${folder.name}`
79
+ : folder.name;
80
+ if (folderIds.has(path)) {
81
+ continue;
82
+ }
83
+ const parentId = folder.parentPath
84
+ ? folderIds.get(folder.parentPath)
85
+ : undefined;
86
+ try {
87
+ const result = await addFolder(driveId, folder.name, parentId);
88
+ folderIds.set(path, result.id);
89
+ console.log(`[VaultInit] Created folder: /${path}/`);
90
+ await new Promise((r) => setTimeout(r, 500));
91
+ }
92
+ catch (err) {
93
+ console.error(`[VaultInit] Failed to create folder /${path}/:`, err);
94
+ }
95
+ }
96
+ console.log("[VaultInit] Folders complete");
97
+ // Wait for reactor to process all folder operations
98
+ await new Promise((r) => setTimeout(r, 1500));
99
+ // Phase 2: Create singletons
100
+ console.log(`[VaultInit] Creating singletons...`);
63
101
  const existingTypes = new Set(existingNodes
64
102
  .filter((n) => n.kind === "file")
65
103
  .map((n) => n.documentType));
@@ -70,11 +108,9 @@ async function initDrive(driveId, existingNodes) {
70
108
  }
71
109
  const parentFolderId = folderIds.get(singleton.folderPath);
72
110
  try {
73
- // addDocument uses the drive UUID internally
74
111
  await addDocument(driveId, singleton.name, singleton.type, parentFolderId);
75
112
  console.log(`[VaultInit] Created ${singleton.name} in /${singleton.folderPath}/`);
76
- // Small delay between document creations to avoid revision conflicts
77
- await new Promise((resolve) => setTimeout(resolve, 500));
113
+ await new Promise((r) => setTimeout(r, 1000));
78
114
  }
79
115
  catch (err) {
80
116
  console.error(`[VaultInit] Failed to create ${singleton.name}:`, err);
@@ -86,27 +122,7 @@ async function initDrive(driveId, existingNodes) {
86
122
  console.error("[VaultInit] Drive initialization failed:", err);
87
123
  }
88
124
  }
89
- async function createFolderTree(driveId, defs, parentFolderId, pathPrefix, folderIds) {
90
- for (const def of defs) {
91
- const path = pathPrefix ? `${pathPrefix}/${def.name}` : def.name;
92
- if (!folderIds.has(path)) {
93
- try {
94
- const result = await addFolder(driveId, def.name, parentFolderId);
95
- folderIds.set(path, result.id);
96
- console.log(`[VaultInit] Created folder: /${path}/`);
97
- // Small delay to avoid revision conflicts
98
- await new Promise((resolve) => setTimeout(resolve, 200));
99
- }
100
- catch (err) {
101
- console.error(`[VaultInit] Failed to create folder /${path}/:`, err);
102
- continue;
103
- }
104
- }
105
- if (def.children) {
106
- await createFolderTree(driveId, def.children, folderIds.get(path), path, folderIds);
107
- }
108
- }
109
- }
125
+ // ─── Helpers ───
110
126
  function buildExistingFolderMap(nodes) {
111
127
  const map = new Map();
112
128
  const folders = nodes.filter((n) => n.kind === "folder");
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/moc-editor/editor.tsx"],"names":[],"mappings":"AAmBA,MAAM,CAAC,OAAO,UAAU,MAAM,4CAmV7B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/moc-editor/editor.tsx"],"names":[],"mappings":"AAuBA,MAAM,CAAC,OAAO,UAAU,MAAM,4CA6X7B"}