@openviking/dsh-memory-plugin 0.1.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.
@@ -0,0 +1,228 @@
1
+ // GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
2
+ import { readFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join, resolve as resolvePath } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const DEFAULT_OVCLI_CONF_PATH = join(homedir(), ".openviking", "ovcli.conf");
8
+ const DEFAULT_OV_CONF_PATH = join(homedir(), ".openviking", "ov.conf");
9
+ const DEFAULT_BASE_URL = "http://127.0.0.1:1933";
10
+
11
+ function str(val, fallback = "") {
12
+ if (typeof val === "string" && val.trim()) return val.trim();
13
+ return fallback;
14
+ }
15
+
16
+ function normalizePath(value) {
17
+ const raw = str(value, "");
18
+ if (!raw) return "";
19
+ if (raw === "~") return homedir();
20
+ if (raw.startsWith("~/")) return resolvePath(join(homedir(), raw.slice(2)));
21
+ return resolvePath(raw);
22
+ }
23
+
24
+ function tryLoadJson(path) {
25
+ if (!path) return null;
26
+ try {
27
+ return JSON.parse(readFileSync(path, "utf-8"));
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Build the User-Agent every harness plugin sends on OpenViking-bound requests.
35
+ * Shape is `name/semver` so downstream stats layers can parse it as one token.
36
+ */
37
+ export function buildUserAgent(harness, version) {
38
+ return `openviking-memory-${harness}/${str(version, "") || "0.0.0"}`;
39
+ }
40
+
41
+ /**
42
+ * Read a plugin manifest's `version` field. Accepts a path or a URL (so callers
43
+ * can resolve relative to import.meta.url). Returns "" when unreadable so the
44
+ * User-Agent falls back to 0.0.0 instead of throwing inside a short-lived hook.
45
+ */
46
+ export function readManifestVersion(manifest) {
47
+ try {
48
+ return str(JSON.parse(readFileSync(manifest, "utf-8")).version, "");
49
+ } catch {
50
+ return "";
51
+ }
52
+ }
53
+
54
+ function looksLikeOvcli(obj) {
55
+ if (!obj || typeof obj !== "object") return false;
56
+ if (obj.server && typeof obj.server === "object") return false;
57
+ return Boolean(
58
+ typeof obj.url === "string" ||
59
+ typeof obj.api_key === "string" ||
60
+ typeof obj.account === "string" ||
61
+ typeof obj.account_id === "string" ||
62
+ typeof obj.user === "string" ||
63
+ typeof obj.user_id === "string" ||
64
+ typeof obj.actor_peer_id === "string",
65
+ );
66
+ }
67
+
68
+ function hasCredentialFields(obj) {
69
+ if (!obj || typeof obj !== "object") return false;
70
+ return [
71
+ "url",
72
+ "api_key",
73
+ "account",
74
+ "account_id",
75
+ "user",
76
+ "user_id",
77
+ "actor_peer_id",
78
+ "peer_id",
79
+ ].some((key) => typeof obj[key] === "string");
80
+ }
81
+
82
+ export function loadCredentialFiles(env = process.env) {
83
+ const cliPathCandidate = normalizePath(env.OPENVIKING_CLI_CONFIG_FILE) || DEFAULT_OVCLI_CONF_PATH;
84
+ const ovPathCandidate = normalizePath(env.OPENVIKING_CONFIG_FILE) || DEFAULT_OV_CONF_PATH;
85
+ const cliPathEnv = Boolean(str(env.OPENVIKING_CLI_CONFIG_FILE, ""));
86
+ const ovPathEnv = Boolean(str(env.OPENVIKING_CONFIG_FILE, ""));
87
+
88
+ let cliFile = tryLoadJson(cliPathCandidate);
89
+ let cliPath = cliFile ? cliPathCandidate : "";
90
+ let ovFile = tryLoadJson(ovPathCandidate);
91
+ let ovPath = ovFile ? ovPathCandidate : "";
92
+
93
+ // Backward compat: older plugin installs used OPENVIKING_CONFIG_FILE for
94
+ // both ov.conf and ovcli.conf. Preserve that when the file is ovcli-shaped.
95
+ if (ovPathEnv && !cliPathEnv && looksLikeOvcli(ovFile)) {
96
+ cliFile = ovFile;
97
+ cliPath = ovPath;
98
+ ovFile = null;
99
+ ovPath = "";
100
+ }
101
+
102
+ return {
103
+ cliFile: cliFile || {},
104
+ cliPath,
105
+ cliPathCandidate,
106
+ ovFile: ovFile || {},
107
+ ovPath,
108
+ };
109
+ }
110
+
111
+ function sourceMode(env) {
112
+ const raw = str(env.OPENVIKING_CREDENTIAL_SOURCE, str(env.OPENVIKING_CREDENTIALS_SOURCE, "auto"))
113
+ .toLowerCase();
114
+ if (raw === "env" || raw === "environment") return "env";
115
+ if (raw === "cli" || raw === "ovcli" || raw === "file" || raw === "config") return "cli";
116
+ return "auto";
117
+ }
118
+
119
+ function hasEnvCredentialFields(env) {
120
+ return Boolean(
121
+ str(env.OPENVIKING_URL, str(env.OPENVIKING_BASE_URL, "")) ||
122
+ str(env.OPENVIKING_MCP_URL, "") ||
123
+ str(env.OPENVIKING_BEARER_TOKEN, str(env.OPENVIKING_API_KEY, "")) ||
124
+ str(env.OPENVIKING_ACCOUNT, "") ||
125
+ str(env.OPENVIKING_USER, "") ||
126
+ str(env.OPENVIKING_PEER_ID, ""),
127
+ );
128
+ }
129
+
130
+ function deriveBaseUrl({ env, cliFile, ovFile, mode, useCli }) {
131
+ const envUrl = str(env.OPENVIKING_URL, str(env.OPENVIKING_BASE_URL, ""));
132
+ const cliUrl = str(cliFile.url, "");
133
+
134
+ if (mode !== "cli" && envUrl) return envUrl.replace(/\/+$/, "");
135
+ if (useCli && cliUrl) return cliUrl.replace(/\/+$/, "");
136
+ if (mode !== "env" && cliUrl) return cliUrl.replace(/\/+$/, "");
137
+
138
+ const server = ovFile.server || {};
139
+ const ovUrl = str(server.url, "");
140
+ if (ovUrl) return ovUrl.replace(/\/+$/, "");
141
+
142
+ const host = str(server.host, "127.0.0.1").replace("0.0.0.0", "127.0.0.1");
143
+ const port = Number.isFinite(Number(server.port)) ? Math.floor(Number(server.port)) : 1933;
144
+ return `http://${host}:${port}`;
145
+ }
146
+
147
+ export function resolveOpenVikingCredentials(env = process.env) {
148
+ const files = loadCredentialFiles(env);
149
+ const mode = sourceMode(env);
150
+ const envHasCredentials = hasEnvCredentialFields(env);
151
+ const useCli = mode === "cli" ||
152
+ (mode === "auto" && !envHasCredentials && files.cliPath && hasCredentialFields(files.cliFile));
153
+ const cx = files.ovFile.codex || {};
154
+ const server = files.ovFile.server || {};
155
+
156
+ const baseUrl = deriveBaseUrl({ env, ...files, mode, useCli });
157
+
158
+ const apiKey = useCli
159
+ ? str(files.cliFile.api_key, "")
160
+ : (
161
+ str(env.OPENVIKING_BEARER_TOKEN, "") ||
162
+ str(env.OPENVIKING_API_KEY, "") ||
163
+ str(files.cliFile.api_key, "") ||
164
+ str(cx.apiKey, "") ||
165
+ str(server.root_api_key, "")
166
+ );
167
+
168
+ const account = useCli
169
+ ? str(files.cliFile.account, str(files.cliFile.account_id, ""))
170
+ : (
171
+ str(env.OPENVIKING_ACCOUNT, "") ||
172
+ str(files.cliFile.account, str(files.cliFile.account_id, "")) ||
173
+ str(cx.accountId, "")
174
+ );
175
+
176
+ const user = useCli
177
+ ? str(files.cliFile.user, str(files.cliFile.user_id, ""))
178
+ : (
179
+ str(env.OPENVIKING_USER, "") ||
180
+ str(files.cliFile.user, str(files.cliFile.user_id, "")) ||
181
+ str(cx.userId, "")
182
+ );
183
+
184
+ const peerId = useCli
185
+ ? str(files.cliFile.actor_peer_id, str(files.cliFile.peer_id, ""))
186
+ : (
187
+ str(env.OPENVIKING_PEER_ID, "") ||
188
+ str(files.cliFile.actor_peer_id, str(files.cliFile.peer_id, "")) ||
189
+ str(cx.peerId, str(cx.peer_id, ""))
190
+ );
191
+
192
+ const explicitMcpUrl = str(env.OPENVIKING_MCP_URL, "");
193
+ const mcpUrl = (mode !== "cli" && explicitMcpUrl) ? explicitMcpUrl : `${baseUrl.replace(/\/+$/, "")}/mcp`;
194
+
195
+ return {
196
+ ...files,
197
+ credentialSource: useCli ? "ovcli" : ((mode === "env" || envHasCredentials) ? "env" : "auto"),
198
+ baseUrl,
199
+ mcpUrl,
200
+ apiKey,
201
+ account,
202
+ user,
203
+ peerId,
204
+ hasApiKey: Boolean(apiKey),
205
+ };
206
+ }
207
+
208
+ function main() {
209
+ const cmd = process.argv[2] || "";
210
+ if (cmd === "mcp-url") {
211
+ process.stdout.write(resolveOpenVikingCredentials().mcpUrl);
212
+ return;
213
+ }
214
+ if (cmd === "has-api-key") {
215
+ process.stdout.write(resolveOpenVikingCredentials().hasApiKey ? "1" : "0");
216
+ return;
217
+ }
218
+ if (cmd === "has-peer-id") {
219
+ process.stdout.write(resolveOpenVikingCredentials().peerId ? "1" : "0");
220
+ return;
221
+ }
222
+ process.stderr.write("usage: ov-credentials.mjs <mcp-url|has-api-key|has-peer-id>\n");
223
+ process.exitCode = 2;
224
+ }
225
+
226
+ if (process.argv[1] && fileURLToPath(import.meta.url) === resolvePath(process.argv[1])) {
227
+ main();
228
+ }
@@ -0,0 +1,58 @@
1
+ // GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
2
+ /**
3
+ * Shared structured debug logger for OpenViking memory plugin hook scripts.
4
+ *
5
+ * Harness-specific wrappers load config and pass {debug, debugLogPath}. This
6
+ * module stays path-agnostic so it can be vendored into each plugin snapshot.
7
+ */
8
+
9
+ import { appendFileSync, mkdirSync } from "node:fs";
10
+ import { dirname } from "node:path";
11
+
12
+ function ensureDir(filePath) {
13
+ try {
14
+ mkdirSync(dirname(filePath), { recursive: true });
15
+ } catch { /* best effort */ }
16
+ }
17
+
18
+ function writeLine(filePath, obj) {
19
+ try {
20
+ appendFileSync(filePath, JSON.stringify(obj) + "\n");
21
+ } catch { /* best effort */ }
22
+ }
23
+
24
+ function localISO() {
25
+ const d = new Date();
26
+ const off = d.getTimezoneOffset();
27
+ const sign = off <= 0 ? "+" : "-";
28
+ const abs = Math.abs(off);
29
+ const local = new Date(d.getTime() - off * 60000);
30
+ return local.toISOString().replace(
31
+ "Z",
32
+ `${sign}${String(Math.floor(abs / 60)).padStart(2, "0")}:${String(abs % 60).padStart(2, "0")}`,
33
+ );
34
+ }
35
+
36
+ const noop = () => {};
37
+
38
+ export function createLogger(hookName, overrideCfg) {
39
+ const c = overrideCfg || {};
40
+ if (!c.debug) return { log: noop, logError: noop };
41
+
42
+ const logPath = c.debugLogPath;
43
+ if (!logPath) return { log: noop, logError: noop };
44
+ ensureDir(logPath);
45
+
46
+ function log(stage, data) {
47
+ writeLine(logPath, { ts: localISO(), hook: hookName, stage, data });
48
+ }
49
+
50
+ function logError(stage, err) {
51
+ const error = err instanceof Error
52
+ ? { message: err.message, stack: err.stack }
53
+ : String(err);
54
+ writeLine(logPath, { ts: localISO(), hook: hookName, stage, error });
55
+ }
56
+
57
+ return { log, logError };
58
+ }