@mainahq/core 1.0.3 → 1.1.1
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.
- package/package.json +1 -1
- package/src/ai/__tests__/delegation.test.ts +55 -1
- package/src/ai/delegation.ts +5 -3
- package/src/context/__tests__/budget.test.ts +29 -6
- package/src/context/__tests__/engine.test.ts +1 -0
- package/src/context/__tests__/selector.test.ts +23 -3
- package/src/context/__tests__/wiki.test.ts +349 -0
- package/src/context/budget.ts +12 -8
- package/src/context/engine.ts +37 -0
- package/src/context/selector.ts +30 -4
- package/src/context/wiki.ts +296 -0
- package/src/db/index.ts +12 -0
- package/src/feedback/__tests__/capture.test.ts +166 -0
- package/src/feedback/__tests__/signals.test.ts +144 -0
- package/src/feedback/__tests__/tmp-capture-1775575256633-lah0etnzlj/feedback.db +0 -0
- package/src/feedback/__tests__/tmp-capture-1775575256640-2xmjme4qraa/feedback.db +0 -0
- package/src/feedback/capture.ts +102 -0
- package/src/feedback/signals.ts +68 -0
- package/src/index.ts +104 -0
- package/src/init/__tests__/init.test.ts +400 -3
- package/src/init/index.ts +368 -12
- package/src/language/__tests__/__fixtures__/detect/composer.lock +1 -0
- package/src/prompts/defaults/index.ts +3 -1
- package/src/prompts/defaults/wiki-compile.md +20 -0
- package/src/prompts/defaults/wiki-query.md +18 -0
- package/src/stats/__tests__/tool-usage.test.ts +133 -0
- package/src/stats/tracker.ts +92 -0
- package/src/verify/__tests__/pipeline.test.ts +11 -8
- package/src/verify/pipeline.ts +13 -1
- package/src/verify/tools/__tests__/wiki-lint.test.ts +784 -0
- package/src/verify/tools/wiki-lint-runner.ts +38 -0
- package/src/verify/tools/wiki-lint.ts +898 -0
- package/src/wiki/__tests__/compiler.test.ts +389 -0
- package/src/wiki/__tests__/extractors/code.test.ts +99 -0
- package/src/wiki/__tests__/extractors/decision.test.ts +323 -0
- package/src/wiki/__tests__/extractors/feature.test.ts +186 -0
- package/src/wiki/__tests__/extractors/workflow.test.ts +131 -0
- package/src/wiki/__tests__/graph.test.ts +344 -0
- package/src/wiki/__tests__/hooks.test.ts +119 -0
- package/src/wiki/__tests__/indexer.test.ts +285 -0
- package/src/wiki/__tests__/linker.test.ts +230 -0
- package/src/wiki/__tests__/louvain.test.ts +229 -0
- package/src/wiki/__tests__/query.test.ts +316 -0
- package/src/wiki/__tests__/schema.test.ts +114 -0
- package/src/wiki/__tests__/signals.test.ts +474 -0
- package/src/wiki/__tests__/state.test.ts +168 -0
- package/src/wiki/__tests__/tracking.test.ts +118 -0
- package/src/wiki/__tests__/types.test.ts +387 -0
- package/src/wiki/compiler.ts +1075 -0
- package/src/wiki/extractors/code.ts +90 -0
- package/src/wiki/extractors/decision.ts +217 -0
- package/src/wiki/extractors/feature.ts +206 -0
- package/src/wiki/extractors/workflow.ts +112 -0
- package/src/wiki/graph.ts +445 -0
- package/src/wiki/hooks.ts +49 -0
- package/src/wiki/indexer.ts +105 -0
- package/src/wiki/linker.ts +117 -0
- package/src/wiki/louvain.ts +190 -0
- package/src/wiki/prompts/compile-architecture.md +59 -0
- package/src/wiki/prompts/compile-decision.md +66 -0
- package/src/wiki/prompts/compile-entity.md +56 -0
- package/src/wiki/prompts/compile-feature.md +60 -0
- package/src/wiki/prompts/compile-module.md +42 -0
- package/src/wiki/prompts/wiki-query.md +25 -0
- package/src/wiki/query.ts +338 -0
- package/src/wiki/schema.ts +111 -0
- package/src/wiki/signals.ts +368 -0
- package/src/wiki/state.ts +89 -0
- package/src/wiki/tracking.ts +30 -0
- package/src/wiki/types.ts +169 -0
- package/src/workflow/context.ts +26 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getFeedbackDb } from "../../db/index";
|
|
5
|
+
import { recordFeedback } from "../collector";
|
|
6
|
+
import { emitAcceptSignal, emitRejectSignal } from "../signals";
|
|
7
|
+
|
|
8
|
+
let tmpDir: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmpDir = join(
|
|
12
|
+
import.meta.dir,
|
|
13
|
+
`tmp-signals-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
14
|
+
);
|
|
15
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
try {
|
|
20
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
21
|
+
} catch {
|
|
22
|
+
/* ignore */
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/** Insert a feedback row and set its workflow_id. */
|
|
27
|
+
function insertFeedback(
|
|
28
|
+
tool: string,
|
|
29
|
+
workflowId: string,
|
|
30
|
+
accepted: boolean,
|
|
31
|
+
): void {
|
|
32
|
+
recordFeedback(tmpDir, {
|
|
33
|
+
promptHash: `${tool}-mcp`,
|
|
34
|
+
task: tool,
|
|
35
|
+
accepted,
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
});
|
|
38
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
39
|
+
if (!dbResult.ok) return;
|
|
40
|
+
const { db } = dbResult.value;
|
|
41
|
+
db.prepare(
|
|
42
|
+
`UPDATE feedback SET workflow_id = ?
|
|
43
|
+
WHERE id = (SELECT id FROM feedback ORDER BY rowid DESC LIMIT 1)`,
|
|
44
|
+
).run(workflowId);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
describe("emitAcceptSignal", () => {
|
|
48
|
+
test("marks recent review/verify entries as accepted", () => {
|
|
49
|
+
insertFeedback("reviewCode", "wf-1", false);
|
|
50
|
+
insertFeedback("verify", "wf-1", false);
|
|
51
|
+
|
|
52
|
+
emitAcceptSignal(tmpDir, "wf-1");
|
|
53
|
+
|
|
54
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
55
|
+
expect(dbResult.ok).toBe(true);
|
|
56
|
+
if (!dbResult.ok) return;
|
|
57
|
+
const { db } = dbResult.value;
|
|
58
|
+
const rows = db
|
|
59
|
+
.query("SELECT command, accepted FROM feedback WHERE workflow_id = ?")
|
|
60
|
+
.all("wf-1") as Array<{ command: string; accepted: number }>;
|
|
61
|
+
for (const row of rows) {
|
|
62
|
+
expect(row.accepted).toBe(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("does not affect entries from a different workflow", () => {
|
|
67
|
+
insertFeedback("reviewCode", "wf-1", false);
|
|
68
|
+
insertFeedback("reviewCode", "wf-2", false);
|
|
69
|
+
|
|
70
|
+
emitAcceptSignal(tmpDir, "wf-1");
|
|
71
|
+
|
|
72
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
73
|
+
if (!dbResult.ok) return;
|
|
74
|
+
const { db } = dbResult.value;
|
|
75
|
+
const wf2 = db
|
|
76
|
+
.query("SELECT accepted FROM feedback WHERE workflow_id = ?")
|
|
77
|
+
.get("wf-2") as { accepted: number } | null;
|
|
78
|
+
expect(wf2?.accepted).toBe(0);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("accepts custom tool list", () => {
|
|
82
|
+
insertFeedback("reviewCode", "wf-1", false);
|
|
83
|
+
insertFeedback("verify", "wf-1", false);
|
|
84
|
+
|
|
85
|
+
emitAcceptSignal(tmpDir, "wf-1", ["reviewCode"]);
|
|
86
|
+
|
|
87
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
88
|
+
if (!dbResult.ok) return;
|
|
89
|
+
const { db } = dbResult.value;
|
|
90
|
+
const review = db
|
|
91
|
+
.query(
|
|
92
|
+
"SELECT accepted FROM feedback WHERE command = ? AND workflow_id = ?",
|
|
93
|
+
)
|
|
94
|
+
.get("reviewCode", "wf-1") as { accepted: number } | null;
|
|
95
|
+
expect(review?.accepted).toBe(1);
|
|
96
|
+
const verify = db
|
|
97
|
+
.query(
|
|
98
|
+
"SELECT accepted FROM feedback WHERE command = ? AND workflow_id = ?",
|
|
99
|
+
)
|
|
100
|
+
.get("verify", "wf-1") as { accepted: number } | null;
|
|
101
|
+
expect(verify?.accepted).toBe(0);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("emitRejectSignal", () => {
|
|
106
|
+
test("marks the most recent entry for a tool+workflow as rejected", () => {
|
|
107
|
+
insertFeedback("reviewCode", "wf-1", true);
|
|
108
|
+
emitRejectSignal(tmpDir, "reviewCode", "wf-1");
|
|
109
|
+
|
|
110
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
111
|
+
if (!dbResult.ok) return;
|
|
112
|
+
const { db } = dbResult.value;
|
|
113
|
+
const row = db
|
|
114
|
+
.query(
|
|
115
|
+
"SELECT accepted FROM feedback WHERE command = ? AND workflow_id = ? ORDER BY created_at DESC LIMIT 1",
|
|
116
|
+
)
|
|
117
|
+
.get("reviewCode", "wf-1") as { accepted: number } | null;
|
|
118
|
+
expect(row?.accepted).toBe(0);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("only rejects the most recent entry, not older ones", () => {
|
|
122
|
+
insertFeedback("reviewCode", "wf-1", true);
|
|
123
|
+
insertFeedback("reviewCode", "wf-1", true);
|
|
124
|
+
emitRejectSignal(tmpDir, "reviewCode", "wf-1");
|
|
125
|
+
|
|
126
|
+
const dbResult = getFeedbackDb(tmpDir);
|
|
127
|
+
if (!dbResult.ok) return;
|
|
128
|
+
const { db } = dbResult.value;
|
|
129
|
+
const rows = db
|
|
130
|
+
.query(
|
|
131
|
+
"SELECT accepted FROM feedback WHERE command = ? AND workflow_id = ? ORDER BY created_at ASC",
|
|
132
|
+
)
|
|
133
|
+
.all("reviewCode", "wf-1") as Array<{ accepted: number }>;
|
|
134
|
+
expect(rows).toHaveLength(2);
|
|
135
|
+
expect(rows[0]?.accepted).toBe(1);
|
|
136
|
+
expect(rows[1]?.accepted).toBe(0);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("does not throw when no matching entries exist", () => {
|
|
140
|
+
expect(() => {
|
|
141
|
+
emitRejectSignal(tmpDir, "reviewCode", "nonexistent");
|
|
142
|
+
}).not.toThrow();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP result capture — connects tool outputs to cache, feedback, and stats.
|
|
3
|
+
* This is the core of the round-trip flywheel.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { hashContent } from "../cache/keys";
|
|
7
|
+
import { createCacheManager } from "../cache/manager";
|
|
8
|
+
import { trackToolUsage } from "../stats/tracker";
|
|
9
|
+
import { recordFeedback } from "./collector";
|
|
10
|
+
import { emitRejectSignal } from "./signals";
|
|
11
|
+
|
|
12
|
+
export interface CaptureInput {
|
|
13
|
+
tool: string;
|
|
14
|
+
input: Record<string, unknown>;
|
|
15
|
+
output: string;
|
|
16
|
+
promptHash?: string;
|
|
17
|
+
durationMs: number;
|
|
18
|
+
mainaDir: string;
|
|
19
|
+
workflowId?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function buildToolCacheKey(
|
|
23
|
+
tool: string,
|
|
24
|
+
input: Record<string, unknown>,
|
|
25
|
+
): string {
|
|
26
|
+
const inputHash = hashContent(JSON.stringify(input));
|
|
27
|
+
return hashContent(`mcp:${tool}:${inputHash}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getCachedResult(
|
|
31
|
+
tool: string,
|
|
32
|
+
input: Record<string, unknown>,
|
|
33
|
+
mainaDir: string,
|
|
34
|
+
): string | null {
|
|
35
|
+
try {
|
|
36
|
+
const cache = createCacheManager(mainaDir);
|
|
37
|
+
const key = buildToolCacheKey(tool, input);
|
|
38
|
+
const entry = cache.get(key);
|
|
39
|
+
if (entry !== null) {
|
|
40
|
+
const inputHash = hashContent(JSON.stringify(input));
|
|
41
|
+
trackToolUsage(mainaDir, {
|
|
42
|
+
tool,
|
|
43
|
+
inputHash,
|
|
44
|
+
durationMs: 0,
|
|
45
|
+
cacheHit: true,
|
|
46
|
+
});
|
|
47
|
+
return entry.value;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function captureResult(input: CaptureInput): void {
|
|
56
|
+
const inputHash = hashContent(JSON.stringify(input.input));
|
|
57
|
+
|
|
58
|
+
// 1. Cache (synchronous — fast SQLite write)
|
|
59
|
+
try {
|
|
60
|
+
const cache = createCacheManager(input.mainaDir);
|
|
61
|
+
const key = buildToolCacheKey(input.tool, input.input);
|
|
62
|
+
cache.set(key, input.output, { ttl: 0 });
|
|
63
|
+
} catch {
|
|
64
|
+
// Cache failure is non-fatal
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2. Reject previous result for same tool+workflow (re-run implies rejection)
|
|
68
|
+
if (input.workflowId) {
|
|
69
|
+
try {
|
|
70
|
+
emitRejectSignal(input.mainaDir, input.tool, input.workflowId);
|
|
71
|
+
} catch {
|
|
72
|
+
// Reject failure is non-fatal
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 3. Feedback (fire-and-forget via microtask)
|
|
77
|
+
queueMicrotask(() => {
|
|
78
|
+
try {
|
|
79
|
+
recordFeedback(input.mainaDir, {
|
|
80
|
+
promptHash: input.promptHash ?? `${input.tool}-mcp`,
|
|
81
|
+
task: input.tool,
|
|
82
|
+
accepted: true,
|
|
83
|
+
timestamp: new Date().toISOString(),
|
|
84
|
+
});
|
|
85
|
+
} catch {
|
|
86
|
+
// Never throw from background feedback
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// 4. Stats (synchronous — fast SQLite write)
|
|
91
|
+
try {
|
|
92
|
+
trackToolUsage(input.mainaDir, {
|
|
93
|
+
tool: input.tool,
|
|
94
|
+
inputHash,
|
|
95
|
+
durationMs: input.durationMs,
|
|
96
|
+
cacheHit: false,
|
|
97
|
+
workflowId: input.workflowId,
|
|
98
|
+
});
|
|
99
|
+
} catch {
|
|
100
|
+
// Stats failure is non-fatal
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implicit accept/reject signals for the RL flywheel.
|
|
3
|
+
* Infers outcomes from downstream user behavior instead of requiring explicit action.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { getFeedbackDb } from "../db/index";
|
|
8
|
+
import { recordWikiUsage } from "../wiki/signals";
|
|
9
|
+
|
|
10
|
+
const DEFAULT_ACCEPT_TOOLS = ["reviewCode", "verify", "checkSlop"];
|
|
11
|
+
|
|
12
|
+
export function emitAcceptSignal(
|
|
13
|
+
mainaDir: string,
|
|
14
|
+
workflowId: string,
|
|
15
|
+
tools?: string[],
|
|
16
|
+
wikiArticles?: string[],
|
|
17
|
+
): void {
|
|
18
|
+
try {
|
|
19
|
+
const dbResult = getFeedbackDb(mainaDir);
|
|
20
|
+
if (!dbResult.ok) return;
|
|
21
|
+
const { db } = dbResult.value;
|
|
22
|
+
const targetTools = tools ?? DEFAULT_ACCEPT_TOOLS;
|
|
23
|
+
const placeholders = targetTools.map(() => "?").join(",");
|
|
24
|
+
db.prepare(
|
|
25
|
+
`UPDATE feedback SET accepted = 1
|
|
26
|
+
WHERE workflow_id = ?
|
|
27
|
+
AND command IN (${placeholders})`,
|
|
28
|
+
).run(workflowId, ...targetTools);
|
|
29
|
+
|
|
30
|
+
// Record wiki effectiveness signal for loaded articles
|
|
31
|
+
if (wikiArticles && wikiArticles.length > 0) {
|
|
32
|
+
const wikiDir = join(mainaDir, "wiki");
|
|
33
|
+
recordWikiUsage(wikiDir, wikiArticles, "accept", true);
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
// Never throw from signals
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function emitRejectSignal(
|
|
41
|
+
mainaDir: string,
|
|
42
|
+
tool: string,
|
|
43
|
+
workflowId: string,
|
|
44
|
+
wikiArticles?: string[],
|
|
45
|
+
): void {
|
|
46
|
+
try {
|
|
47
|
+
const dbResult = getFeedbackDb(mainaDir);
|
|
48
|
+
if (!dbResult.ok) return;
|
|
49
|
+
const { db } = dbResult.value;
|
|
50
|
+
db.prepare(
|
|
51
|
+
`UPDATE feedback SET accepted = 0
|
|
52
|
+
WHERE command = ? AND workflow_id = ?
|
|
53
|
+
AND id = (
|
|
54
|
+
SELECT id FROM feedback
|
|
55
|
+
WHERE command = ? AND workflow_id = ?
|
|
56
|
+
ORDER BY created_at DESC, rowid DESC LIMIT 1
|
|
57
|
+
)`,
|
|
58
|
+
).run(tool, workflowId, tool, workflowId);
|
|
59
|
+
|
|
60
|
+
// Record wiki effectiveness signal for loaded articles
|
|
61
|
+
if (wikiArticles && wikiArticles.length > 0) {
|
|
62
|
+
const wikiDir = join(mainaDir, "wiki");
|
|
63
|
+
recordWikiUsage(wikiDir, wikiArticles, tool, false);
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
// Never throw from signals
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -154,6 +154,12 @@ export type {
|
|
|
154
154
|
TraceDeps,
|
|
155
155
|
} from "./features/traceability";
|
|
156
156
|
export { traceFeature } from "./features/traceability";
|
|
157
|
+
export {
|
|
158
|
+
buildToolCacheKey,
|
|
159
|
+
type CaptureInput,
|
|
160
|
+
captureResult,
|
|
161
|
+
getCachedResult,
|
|
162
|
+
} from "./feedback/capture";
|
|
157
163
|
// Feedback
|
|
158
164
|
export {
|
|
159
165
|
type FeedbackRecord,
|
|
@@ -176,6 +182,7 @@ export {
|
|
|
176
182
|
type RulePreference,
|
|
177
183
|
savePreferences,
|
|
178
184
|
} from "./feedback/preferences";
|
|
185
|
+
export { emitAcceptSignal, emitRejectSignal } from "./feedback/signals";
|
|
179
186
|
export {
|
|
180
187
|
exportEpisodicForCloud,
|
|
181
188
|
exportFeedbackForCloud,
|
|
@@ -287,12 +294,16 @@ export {
|
|
|
287
294
|
getLatest,
|
|
288
295
|
getSkipRate,
|
|
289
296
|
getStats,
|
|
297
|
+
getToolUsageStats,
|
|
290
298
|
getTrends,
|
|
291
299
|
recordSnapshot,
|
|
292
300
|
type SnapshotInput,
|
|
293
301
|
type StatsReport,
|
|
302
|
+
type ToolUsageInput,
|
|
303
|
+
type ToolUsageStats,
|
|
294
304
|
type TrendDirection,
|
|
295
305
|
type TrendsReport,
|
|
306
|
+
trackToolUsage,
|
|
296
307
|
} from "./stats/tracker";
|
|
297
308
|
// Ticket
|
|
298
309
|
export {
|
|
@@ -427,8 +438,101 @@ export {
|
|
|
427
438
|
type ZapOptions,
|
|
428
439
|
type ZapResult,
|
|
429
440
|
} from "./verify/zap";
|
|
441
|
+
// Wiki — Compiler
|
|
442
|
+
export {
|
|
443
|
+
type CompilationResult as WikiCompilationResult,
|
|
444
|
+
type CompileOptions as WikiCompileOptions,
|
|
445
|
+
compile as compileWiki,
|
|
446
|
+
} from "./wiki/compiler";
|
|
447
|
+
export { type CodeEntity, extractCodeEntities } from "./wiki/extractors/code";
|
|
448
|
+
export {
|
|
449
|
+
extractDecisions,
|
|
450
|
+
extractSingleDecision,
|
|
451
|
+
} from "./wiki/extractors/decision";
|
|
452
|
+
export {
|
|
453
|
+
extractFeatures,
|
|
454
|
+
extractSingleFeature,
|
|
455
|
+
} from "./wiki/extractors/feature";
|
|
456
|
+
export { extractWorkflowTrace } from "./wiki/extractors/workflow";
|
|
457
|
+
// Wiki — Graph
|
|
458
|
+
export {
|
|
459
|
+
buildKnowledgeGraph,
|
|
460
|
+
computePageRank,
|
|
461
|
+
type GraphEdge,
|
|
462
|
+
type GraphNode,
|
|
463
|
+
type KnowledgeGraph,
|
|
464
|
+
mapToArticles,
|
|
465
|
+
} from "./wiki/graph";
|
|
466
|
+
// Wiki — Indexer
|
|
467
|
+
export { generateIndex } from "./wiki/indexer";
|
|
468
|
+
// Wiki — Linker
|
|
469
|
+
export { generateLinks, type LinkResult } from "./wiki/linker";
|
|
470
|
+
// Wiki — Louvain
|
|
471
|
+
export {
|
|
472
|
+
detectCommunities,
|
|
473
|
+
type LouvainNode,
|
|
474
|
+
type LouvainResult,
|
|
475
|
+
} from "./wiki/louvain";
|
|
476
|
+
// Wiki — Query
|
|
477
|
+
export {
|
|
478
|
+
queryWiki,
|
|
479
|
+
type WikiQueryOptions,
|
|
480
|
+
type WikiQueryResult,
|
|
481
|
+
} from "./wiki/query";
|
|
482
|
+
export {
|
|
483
|
+
DEFAULT_SCHEMA,
|
|
484
|
+
getArticleMaxLength,
|
|
485
|
+
getLinkSyntax,
|
|
486
|
+
validateArticleStructure,
|
|
487
|
+
type WikiSchema,
|
|
488
|
+
} from "./wiki/schema";
|
|
489
|
+
// Wiki — Signals
|
|
490
|
+
export {
|
|
491
|
+
type ArticleLoadSignal,
|
|
492
|
+
type CompilationPromptSignal,
|
|
493
|
+
calculateEbbinghausScore,
|
|
494
|
+
getPromptEffectiveness,
|
|
495
|
+
getWikiEffectivenessReport,
|
|
496
|
+
recordArticlesLoaded,
|
|
497
|
+
recordWikiUsage,
|
|
498
|
+
type WikiEffectivenessReport,
|
|
499
|
+
type WikiEffectivenessSignal,
|
|
500
|
+
} from "./wiki/signals";
|
|
501
|
+
export {
|
|
502
|
+
createEmptyState,
|
|
503
|
+
getChangedFiles as getWikiChangedFiles,
|
|
504
|
+
hashContent,
|
|
505
|
+
hashFile,
|
|
506
|
+
loadState as loadWikiState,
|
|
507
|
+
saveState as saveWikiState,
|
|
508
|
+
} from "./wiki/state";
|
|
509
|
+
// Wiki — Tracking
|
|
510
|
+
export {
|
|
511
|
+
trackWikiRefsRead,
|
|
512
|
+
trackWikiRefsWritten,
|
|
513
|
+
} from "./wiki/tracking";
|
|
514
|
+
// Wiki
|
|
515
|
+
export type {
|
|
516
|
+
ArticleType,
|
|
517
|
+
DecisionStatus,
|
|
518
|
+
EdgeType,
|
|
519
|
+
ExtractedDecision,
|
|
520
|
+
ExtractedFeature,
|
|
521
|
+
ExtractedWorkflowTrace,
|
|
522
|
+
RLSignal,
|
|
523
|
+
TaskItem,
|
|
524
|
+
WikiArticle,
|
|
525
|
+
WikiLink,
|
|
526
|
+
WikiLintCheck,
|
|
527
|
+
WikiLintFinding,
|
|
528
|
+
WikiLintResult,
|
|
529
|
+
WikiState,
|
|
530
|
+
WorkflowStep as WikiWorkflowStep,
|
|
531
|
+
} from "./wiki/types";
|
|
532
|
+
export { DECAY_HALF_LIVES } from "./wiki/types";
|
|
430
533
|
// Workflow
|
|
431
534
|
export {
|
|
535
|
+
appendWikiRefs,
|
|
432
536
|
appendWorkflowStep,
|
|
433
537
|
loadWorkflowContext,
|
|
434
538
|
resetWorkflowContext,
|