@geravant/sinain 1.0.18 → 1.0.19
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/index.ts +163 -1257
- package/install.js +2 -1
- package/package.json +4 -2
- package/sinain-knowledge/adapters/generic/adapter.ts +103 -0
- package/sinain-knowledge/adapters/interface.ts +72 -0
- package/sinain-knowledge/adapters/openclaw/adapter.ts +223 -0
- package/sinain-knowledge/curation/engine.ts +493 -0
- package/sinain-knowledge/curation/resilience.ts +336 -0
- package/sinain-knowledge/data/git-store.ts +310 -0
- package/sinain-knowledge/data/schema.ts +89 -0
- package/sinain-knowledge/data/snapshot.ts +226 -0
- package/sinain-knowledge/data/store.ts +488 -0
- package/sinain-knowledge/deploy/cli.ts +214 -0
- package/sinain-knowledge/deploy/manifest.ts +80 -0
- package/sinain-knowledge/protocol/bindings/generic.md +5 -0
- package/sinain-knowledge/protocol/bindings/openclaw.md +5 -0
- package/sinain-knowledge/protocol/heartbeat.md +62 -0
- package/sinain-knowledge/protocol/renderer.ts +56 -0
- package/sinain-knowledge/protocol/skill.md +335 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sinain-knowledge — Shared type definitions
|
|
3
|
+
*
|
|
4
|
+
* All types used across the knowledge system layers.
|
|
5
|
+
* No runtime dependencies — pure type definitions + interfaces.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Logger interface (decoupled from OpenClaw)
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export interface Logger {
|
|
13
|
+
info(msg: string): void;
|
|
14
|
+
warn(msg: string): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Plugin config
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
export type PluginConfig = {
|
|
22
|
+
heartbeatPath?: string;
|
|
23
|
+
skillPath?: string;
|
|
24
|
+
memoryPath?: string;
|
|
25
|
+
modulesPath?: string;
|
|
26
|
+
sessionKey?: string;
|
|
27
|
+
userTimezone?: string;
|
|
28
|
+
snapshotRepoPath?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Module system
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
export type ModuleRegistryEntry = {
|
|
36
|
+
status: "active" | "suspended" | "disabled";
|
|
37
|
+
priority: number;
|
|
38
|
+
activatedAt: string | null;
|
|
39
|
+
lastTriggered: string | null;
|
|
40
|
+
locked: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type ModuleRegistry = {
|
|
44
|
+
version: number;
|
|
45
|
+
modules: Record<string, ModuleRegistryEntry>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Session tracking
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
export type ToolUsageEntry = {
|
|
53
|
+
toolName: string;
|
|
54
|
+
ts: number;
|
|
55
|
+
durationMs?: number;
|
|
56
|
+
error?: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type SessionState = {
|
|
60
|
+
startedAt: number;
|
|
61
|
+
toolUsage: ToolUsageEntry[];
|
|
62
|
+
workspaceDir?: string;
|
|
63
|
+
heartbeatToolCalled?: boolean;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Parent context injection (subagent support)
|
|
68
|
+
// ============================================================================
|
|
69
|
+
|
|
70
|
+
export type ParentContextCache = {
|
|
71
|
+
sessionKey: string;
|
|
72
|
+
capturedAt: number;
|
|
73
|
+
contextText: string;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Script execution abstraction
|
|
78
|
+
// ============================================================================
|
|
79
|
+
|
|
80
|
+
export type ScriptResult = {
|
|
81
|
+
code: number;
|
|
82
|
+
stdout: string;
|
|
83
|
+
stderr: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type ScriptRunner = (
|
|
87
|
+
args: string[],
|
|
88
|
+
opts: { timeoutMs: number; cwd: string },
|
|
89
|
+
) => Promise<ScriptResult>;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sinain-knowledge — Snapshot export/import
|
|
3
|
+
*
|
|
4
|
+
* Serializes the entire knowledge state (playbook, modules, triplestore, logs, config)
|
|
5
|
+
* to a portable JSON format for backup and cross-instance transfer.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "node:fs";
|
|
9
|
+
import { join, dirname } from "node:path";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
|
|
12
|
+
import type { ModuleRegistry } from "./schema.js";
|
|
13
|
+
import type { KnowledgeStore } from "./store.js";
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
export interface KnowledgeSnapshot {
|
|
20
|
+
version: 2;
|
|
21
|
+
integrity: string;
|
|
22
|
+
exportedAt: string;
|
|
23
|
+
exportedFrom: string;
|
|
24
|
+
playbook: {
|
|
25
|
+
base: string;
|
|
26
|
+
effective: string;
|
|
27
|
+
archive: Array<{ ts: string; content: string }>;
|
|
28
|
+
};
|
|
29
|
+
modules: {
|
|
30
|
+
registry: ModuleRegistry | null;
|
|
31
|
+
items: Array<{
|
|
32
|
+
id: string;
|
|
33
|
+
manifest: Record<string, unknown> | null;
|
|
34
|
+
patterns: string;
|
|
35
|
+
guidance: string;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
triplestore: {
|
|
39
|
+
dbBase64: string;
|
|
40
|
+
};
|
|
41
|
+
logs: {
|
|
42
|
+
sessionSummaries: string;
|
|
43
|
+
recentPlaybookLogs: string[];
|
|
44
|
+
recentEvalLogs: string[];
|
|
45
|
+
};
|
|
46
|
+
config: {
|
|
47
|
+
memoryConfig: Record<string, unknown> | null;
|
|
48
|
+
evalConfig: Record<string, unknown> | null;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Helpers
|
|
54
|
+
// ============================================================================
|
|
55
|
+
|
|
56
|
+
function readFileSafe(path: string): string {
|
|
57
|
+
try {
|
|
58
|
+
return readFileSync(path, "utf-8");
|
|
59
|
+
} catch {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function readJsonSafe(path: string): Record<string, unknown> | null {
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function computeIntegrity(snapshot: Omit<KnowledgeSnapshot, "integrity">): string {
|
|
73
|
+
const content = JSON.stringify({ ...snapshot, integrity: "" });
|
|
74
|
+
return createHash("sha256").update(content).digest("hex");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Resolve triplestore path, checking both naming conventions (TS vs Python). */
|
|
78
|
+
export function resolveTriplestorePath(workspaceDir: string): string | null {
|
|
79
|
+
const p1 = join(workspaceDir, "memory", "triples.db");
|
|
80
|
+
if (existsSync(p1)) return p1;
|
|
81
|
+
const p2 = join(workspaceDir, "memory", "triplestore.db");
|
|
82
|
+
if (existsSync(p2)) return p2;
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Export
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
export function exportSnapshot(
|
|
91
|
+
store: KnowledgeStore,
|
|
92
|
+
opts?: { skipTriplestore?: boolean },
|
|
93
|
+
): KnowledgeSnapshot {
|
|
94
|
+
const workspaceDir = store.getWorkspaceDir();
|
|
95
|
+
|
|
96
|
+
// Playbook
|
|
97
|
+
const base = store.readPlaybook() ?? "";
|
|
98
|
+
const effective = store.readEffectivePlaybook() ?? "";
|
|
99
|
+
const archiveDir = join(workspaceDir, "memory", "playbook-archive");
|
|
100
|
+
const archive: Array<{ ts: string; content: string }> = [];
|
|
101
|
+
if (existsSync(archiveDir)) {
|
|
102
|
+
const files = readdirSync(archiveDir).filter((f) => f.endsWith(".md")).sort().reverse().slice(0, 10);
|
|
103
|
+
for (const f of files) {
|
|
104
|
+
archive.push({ ts: f.replace(".md", ""), content: readFileSafe(join(archiveDir, f)) });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Modules
|
|
109
|
+
const registry = store.readModuleRegistry();
|
|
110
|
+
const items: KnowledgeSnapshot["modules"]["items"] = [];
|
|
111
|
+
if (registry) {
|
|
112
|
+
for (const id of Object.keys(registry.modules)) {
|
|
113
|
+
const modDir = join(workspaceDir, "modules", id);
|
|
114
|
+
items.push({
|
|
115
|
+
id,
|
|
116
|
+
manifest: readJsonSafe(join(modDir, "manifest.json")),
|
|
117
|
+
patterns: readFileSafe(join(modDir, "patterns.md")),
|
|
118
|
+
guidance: readFileSafe(join(modDir, "guidance.md")),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Triplestore — skip if caller handles it directly (e.g., git store binary copy)
|
|
124
|
+
let dbBase64 = "";
|
|
125
|
+
if (!opts?.skipTriplestore) {
|
|
126
|
+
const dbPath = resolveTriplestorePath(workspaceDir);
|
|
127
|
+
if (dbPath) {
|
|
128
|
+
try { dbBase64 = readFileSync(dbPath).toString("base64"); } catch {}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Logs
|
|
133
|
+
const sessionSummaries = readFileSafe(join(workspaceDir, "memory", "session-summaries.jsonl"));
|
|
134
|
+
const recentPlaybookLogs: string[] = [];
|
|
135
|
+
const pbLogDir = join(workspaceDir, "memory", "playbook-logs");
|
|
136
|
+
if (existsSync(pbLogDir)) {
|
|
137
|
+
const files = readdirSync(pbLogDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 7);
|
|
138
|
+
for (const f of files) {
|
|
139
|
+
recentPlaybookLogs.push(readFileSafe(join(pbLogDir, f)));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const recentEvalLogs = store.readRecentEvalLogs(20);
|
|
143
|
+
|
|
144
|
+
// Config
|
|
145
|
+
const evalConfig = store.readEvalConfig();
|
|
146
|
+
const memoryConfig = readJsonSafe(join(workspaceDir, "memory", "memory-config.json"));
|
|
147
|
+
|
|
148
|
+
const partial = {
|
|
149
|
+
version: 2 as const,
|
|
150
|
+
exportedAt: new Date().toISOString(),
|
|
151
|
+
exportedFrom: workspaceDir,
|
|
152
|
+
playbook: { base, effective, archive },
|
|
153
|
+
modules: { registry, items },
|
|
154
|
+
triplestore: { dbBase64 },
|
|
155
|
+
logs: { sessionSummaries, recentPlaybookLogs, recentEvalLogs },
|
|
156
|
+
config: { memoryConfig, evalConfig },
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
...partial,
|
|
161
|
+
integrity: computeIntegrity(partial),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Import
|
|
167
|
+
// ============================================================================
|
|
168
|
+
|
|
169
|
+
export function importSnapshot(store: KnowledgeStore, snapshot: KnowledgeSnapshot): void {
|
|
170
|
+
const workspaceDir = store.getWorkspaceDir();
|
|
171
|
+
|
|
172
|
+
// Verify integrity
|
|
173
|
+
const expected = computeIntegrity({ ...snapshot, integrity: "" });
|
|
174
|
+
if (expected !== snapshot.integrity) {
|
|
175
|
+
throw new Error(`Snapshot integrity mismatch: expected ${expected}, got ${snapshot.integrity}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
store.ensureMemoryDirs();
|
|
179
|
+
|
|
180
|
+
// Playbook
|
|
181
|
+
if (snapshot.playbook.base) {
|
|
182
|
+
store.writePlaybook(snapshot.playbook.base);
|
|
183
|
+
}
|
|
184
|
+
if (snapshot.playbook.effective) {
|
|
185
|
+
const effectivePath = join(workspaceDir, "memory", "sinain-playbook-effective.md");
|
|
186
|
+
writeFileSync(effectivePath, snapshot.playbook.effective, "utf-8");
|
|
187
|
+
}
|
|
188
|
+
for (const entry of snapshot.playbook.archive) {
|
|
189
|
+
const archiveDir = join(workspaceDir, "memory", "playbook-archive");
|
|
190
|
+
if (!existsSync(archiveDir)) mkdirSync(archiveDir, { recursive: true });
|
|
191
|
+
writeFileSync(join(archiveDir, `${entry.ts}.md`), entry.content, "utf-8");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Modules
|
|
195
|
+
if (snapshot.modules.registry) {
|
|
196
|
+
const modulesDir = join(workspaceDir, "modules");
|
|
197
|
+
if (!existsSync(modulesDir)) mkdirSync(modulesDir, { recursive: true });
|
|
198
|
+
writeFileSync(join(modulesDir, "module-registry.json"), JSON.stringify(snapshot.modules.registry, null, 2), "utf-8");
|
|
199
|
+
}
|
|
200
|
+
for (const mod of snapshot.modules.items) {
|
|
201
|
+
const modDir = join(workspaceDir, "modules", mod.id);
|
|
202
|
+
if (!existsSync(modDir)) mkdirSync(modDir, { recursive: true });
|
|
203
|
+
if (mod.manifest) writeFileSync(join(modDir, "manifest.json"), JSON.stringify(mod.manifest, null, 2), "utf-8");
|
|
204
|
+
if (mod.patterns) writeFileSync(join(modDir, "patterns.md"), mod.patterns, "utf-8");
|
|
205
|
+
if (mod.guidance) writeFileSync(join(modDir, "guidance.md"), mod.guidance, "utf-8");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Triplestore
|
|
209
|
+
if (snapshot.triplestore.dbBase64) {
|
|
210
|
+
const dbPath = join(workspaceDir, "memory", "triples.db");
|
|
211
|
+
writeFileSync(dbPath, Buffer.from(snapshot.triplestore.dbBase64, "base64"));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Logs
|
|
215
|
+
if (snapshot.logs.sessionSummaries) {
|
|
216
|
+
writeFileSync(join(workspaceDir, "memory", "session-summaries.jsonl"), snapshot.logs.sessionSummaries, "utf-8");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Config
|
|
220
|
+
if (snapshot.config.evalConfig) {
|
|
221
|
+
writeFileSync(join(workspaceDir, "memory", "eval-config.json"), JSON.stringify(snapshot.config.evalConfig, null, 2), "utf-8");
|
|
222
|
+
}
|
|
223
|
+
if (snapshot.config.memoryConfig) {
|
|
224
|
+
writeFileSync(join(workspaceDir, "memory", "memory-config.json"), JSON.stringify(snapshot.config.memoryConfig, null, 2), "utf-8");
|
|
225
|
+
}
|
|
226
|
+
}
|