oh-my-llmwikimode 1.0.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +494 -0
  3. package/bin/llmwiki.js +1493 -0
  4. package/docs/INSTALLATION.md +228 -0
  5. package/docs/SCOPE_LOCK.md +79 -0
  6. package/docs/STAGE1_GUIDE.md +265 -0
  7. package/docs/STAGE2_AGENT_TEAM_GUIDE.md +141 -0
  8. package/docs/STAGE3_CONVERSATIONAL_GROWTH_GUIDE.md +50 -0
  9. package/docs/TEST_WORKSHEET.md +120 -0
  10. package/docs/github-private-bootstrap.md +53 -0
  11. package/docs/release.md +79 -0
  12. package/docs/stage4-slice1-manual-test.md +259 -0
  13. package/docs/stage4-slice1-user-guide.md +269 -0
  14. package/docs/user-guide-ko.md +452 -0
  15. package/package.json +76 -0
  16. package/scripts/install-llmwiki.ps1 +229 -0
  17. package/src/config.js +74 -0
  18. package/src/curator/browser-data.js +134 -0
  19. package/src/curator/queue.js +324 -0
  20. package/src/curator/schema.js +237 -0
  21. package/src/curator/scoring.js +83 -0
  22. package/src/hooks.js +199 -0
  23. package/src/librarian/schema.js +218 -0
  24. package/src/librarian/weekly-digest.js +478 -0
  25. package/src/security.js +127 -0
  26. package/src/server.js +860 -0
  27. package/src/stage4/graph-reasoning/analyzer.js +255 -0
  28. package/src/stage4/graph-reasoning/browser-data.js +130 -0
  29. package/src/stage4/graph-reasoning/index.js +35 -0
  30. package/src/stage4/graph-reasoning/loader.js +122 -0
  31. package/src/stage4/graph-reasoning/queue.js +154 -0
  32. package/src/stage4/graph-reasoning/schema.js +190 -0
  33. package/src/team/browser-data.js +142 -0
  34. package/src/team/capabilities.js +79 -0
  35. package/src/team/dispatch.js +108 -0
  36. package/src/team/queue.js +290 -0
  37. package/src/team/schema.js +225 -0
  38. package/src/team/shared-memory.js +183 -0
  39. package/src/todo/browser-data.js +71 -0
  40. package/src/todo/queue.js +159 -0
  41. package/src/todo/schema.js +90 -0
  42. package/src/utils/embedding-model.js +111 -0
  43. package/src/wiki/alias-suggestions.js +180 -0
  44. package/src/wiki/browser-data.js +284 -0
  45. package/src/wiki/doctor.js +218 -0
  46. package/src/wiki/entry-normalizer.js +139 -0
  47. package/src/wiki/ingest.js +443 -0
  48. package/src/wiki/lesson-proposal-analyzer.js +463 -0
  49. package/src/wiki/lesson-proposal-manager.js +331 -0
  50. package/src/wiki/lesson-template.js +182 -0
  51. package/src/wiki/lint.js +294 -0
  52. package/src/wiki/notebooklm-adapter.js +264 -0
  53. package/src/wiki/query.js +304 -0
  54. package/src/wiki/raw-manager.js +400 -0
  55. package/src/wiki/search-feedback.js +211 -0
  56. package/src/wiki/semantic-index.js +333 -0
  57. package/src/wiki/semantic-search.js +170 -0
  58. package/src/wiki/source-ledger.js +370 -0
  59. package/src/wiki/store.js +1329 -0
  60. package/src/wiki/usage-events.js +144 -0
@@ -0,0 +1,144 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import crypto from "node:crypto";
4
+
5
+ /**
6
+ * B1 Agent School — Usage Event Contract
7
+ *
8
+ * Append-only usage events under .system/usage/{YYYY-MM-DD}.jsonl
9
+ * Schema: {version, ts, event, entry_path, source, query_hash, actor, review_required}
10
+ */
11
+
12
+ export const USAGE_EVENT_VERSION = 1;
13
+ export const USAGE_EVENT_DIR = ".system/usage";
14
+
15
+ export const USAGE_EVENTS = {
16
+ LESSON_VIEWED: "lesson_viewed",
17
+ LESSON_REFERENCED: "lesson_referenced",
18
+ SEARCH_RESULT_USED: "search_result_used",
19
+ };
20
+
21
+ function formatDateKey(date) {
22
+ const d = new Date(date);
23
+ const year = d.getUTCFullYear();
24
+ const month = String(d.getUTCMonth() + 1).padStart(2, "0");
25
+ const day = String(d.getUTCDate()).padStart(2, "0");
26
+ return `${year}-${month}-${day}`;
27
+ }
28
+
29
+ function getUsageFilePath(wikiRoot, date) {
30
+ const dateKey = formatDateKey(date);
31
+ return path.join(wikiRoot, USAGE_EVENT_DIR, `${dateKey}.jsonl`);
32
+ }
33
+
34
+ function ensureUsageDir(wikiRoot) {
35
+ const dir = path.join(wikiRoot, USAGE_EVENT_DIR);
36
+ fs.mkdirSync(dir, { recursive: true });
37
+ return dir;
38
+ }
39
+
40
+ function hashQuery(query) {
41
+ if (!query) return "";
42
+ return crypto.createHash("sha256").update(String(query)).digest("hex");
43
+ }
44
+
45
+ /**
46
+ * Append a usage event.
47
+ *
48
+ * @param {string} wikiRoot
49
+ * @param {Object} event
50
+ * @param {string} event.event - One of USAGE_EVENTS values
51
+ * @param {string} event.entry_path - Path to the entry (e.g., editorial/lessons/...)
52
+ * @param {string} [event.source="manual"] - Source: wiki_search, wiki_query, cli, manual
53
+ * @param {string} [event.query] - Original query text (will be hashed, never stored raw)
54
+ * @param {string} [event.actor="local"] - Actor identifier
55
+ * @param {Object} [options]
56
+ * @param {Date} [options.now] - Injected timestamp for determinism in tests
57
+ * @returns {{success: boolean, path?: string, error?: string}}
58
+ */
59
+ export function appendUsageEvent(wikiRoot, event, options = {}) {
60
+ try {
61
+ ensureUsageDir(wikiRoot);
62
+
63
+ const eventType = String(event.event || "").trim();
64
+ if (!Object.values(USAGE_EVENTS).includes(eventType)) {
65
+ return { success: false, error: `Invalid event type: ${eventType}` };
66
+ }
67
+
68
+ const entryPath = String(event.entry_path || "").trim();
69
+ if (!entryPath) {
70
+ return { success: false, error: "entry_path is required" };
71
+ }
72
+
73
+ const now = options.now ? new Date(options.now) : new Date();
74
+ const record = {
75
+ version: USAGE_EVENT_VERSION,
76
+ ts: now.toISOString(),
77
+ event: eventType,
78
+ entry_path: entryPath,
79
+ source: String(event.source || "manual").trim(),
80
+ query_hash: hashQuery(event.query),
81
+ actor: String(event.actor || "local").trim(),
82
+ review_required: true,
83
+ };
84
+
85
+ const filePath = getUsageFilePath(wikiRoot, now);
86
+ const line = JSON.stringify(record);
87
+ fs.appendFileSync(filePath, `${line}\n`, { encoding: "utf-8" });
88
+
89
+ return { success: true, path: filePath, record };
90
+ } catch (error) {
91
+ return { success: false, error: error.message };
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Read usage events for a specific date.
97
+ *
98
+ * @param {string} wikiRoot
99
+ * @param {string|Date} [date] - Defaults to today
100
+ * @returns {{success: boolean, events?: Array, error?: string}}
101
+ */
102
+ export function readUsageEvents(wikiRoot, date) {
103
+ try {
104
+ const targetDate = date ? new Date(date) : new Date();
105
+ const filePath = getUsageFilePath(wikiRoot, targetDate);
106
+
107
+ if (!fs.existsSync(filePath)) {
108
+ return { success: true, events: [] };
109
+ }
110
+
111
+ const lines = fs
112
+ .readFileSync(filePath, "utf-8")
113
+ .split(/\r?\n/)
114
+ .filter(Boolean);
115
+
116
+ const events = [];
117
+ for (const line of lines) {
118
+ try {
119
+ events.push(JSON.parse(line));
120
+ } catch {
121
+ // Skip malformed lines
122
+ }
123
+ }
124
+
125
+ return { success: true, events };
126
+ } catch (error) {
127
+ return { success: false, error: error.message };
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Get all usage event file paths.
133
+ *
134
+ * @param {string} wikiRoot
135
+ * @returns {string[]}
136
+ */
137
+ export function listUsageEventFiles(wikiRoot) {
138
+ const dir = path.join(wikiRoot, USAGE_EVENT_DIR);
139
+ if (!fs.existsSync(dir)) return [];
140
+ return fs
141
+ .readdirSync(dir)
142
+ .filter((f) => f.endsWith(".jsonl"))
143
+ .sort();
144
+ }