@h-rig/memory-plugin 0.0.6-alpha.157 → 0.0.6-alpha.159
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/dist/src/cli.d.ts +1 -3
- package/dist/src/cli.js +417 -19
- package/dist/src/db.js +4 -3
- package/dist/src/embed.js +1 -1
- package/dist/src/embedded-native-assets.d.ts +7 -0
- package/dist/src/embedded-native-assets.js +6 -0
- package/dist/src/index.js +428 -24
- package/dist/src/native-extract.d.ts +2 -0
- package/dist/src/native-extract.js +44 -0
- package/dist/src/native-git.d.ts +28 -0
- package/dist/src/native-git.js +598 -0
- package/dist/src/plugin.d.ts +2 -2
- package/dist/src/plugin.js +428 -24
- package/dist/src/query.d.ts +1 -1
- package/dist/src/query.js +2 -2
- package/dist/src/read.d.ts +1 -1
- package/dist/src/read.js +374 -13
- package/dist/src/service.d.ts +1 -1
- package/dist/src/service.js +417 -19
- package/dist/src/write.d.ts +1 -1
- package/dist/src/write.js +414 -18
- package/package.json +3 -4
package/dist/src/write.js
CHANGED
|
@@ -1,11 +1,407 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// packages/memory-plugin/src/
|
|
3
|
-
import {
|
|
2
|
+
// packages/memory-plugin/src/native-git.ts
|
|
3
|
+
import { chmodSync, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
4
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
5
|
+
import { dirname, isAbsolute, resolve as resolve2 } from "path";
|
|
6
|
+
import { createHash } from "crypto";
|
|
7
|
+
|
|
8
|
+
// packages/memory-plugin/src/native-extract.ts
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "fs";
|
|
10
|
+
import { tmpdir } from "os";
|
|
11
|
+
import { resolve } from "path";
|
|
12
|
+
|
|
13
|
+
// packages/memory-plugin/src/embedded-native-assets.ts
|
|
14
|
+
var embeddedNatives = null;
|
|
15
|
+
|
|
16
|
+
// packages/memory-plugin/src/native-extract.ts
|
|
17
|
+
var sharedNativeOutputDir = resolve(tmpdir(), "rig-native");
|
|
18
|
+
var extractionCache = {};
|
|
19
|
+
function extractEmbeddedNative(name) {
|
|
20
|
+
if (name in extractionCache) {
|
|
21
|
+
return extractionCache[name] ?? null;
|
|
22
|
+
}
|
|
23
|
+
const entry = embeddedNatives?.[name];
|
|
24
|
+
if (!entry) {
|
|
25
|
+
extractionCache[name] = null;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const targetPath = resolve(sharedNativeOutputDir, entry.fileName);
|
|
30
|
+
mkdirSync(sharedNativeOutputDir, { recursive: true });
|
|
31
|
+
const upToDate = existsSync(targetPath) && statSync(targetPath).size === entry.size;
|
|
32
|
+
if (!upToDate) {
|
|
33
|
+
const bytes = readFileSync(entry.filePath);
|
|
34
|
+
const tempPath = `${targetPath}.${process.pid}.${Date.now()}.tmp`;
|
|
35
|
+
writeFileSync(tempPath, bytes, { mode: 493 });
|
|
36
|
+
renameSync(tempPath, targetPath);
|
|
37
|
+
}
|
|
38
|
+
extractionCache[name] = targetPath;
|
|
39
|
+
} catch {
|
|
40
|
+
extractionCache[name] = null;
|
|
41
|
+
}
|
|
42
|
+
return extractionCache[name] ?? null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// packages/memory-plugin/src/native-git.ts
|
|
46
|
+
function isTextTreeCommitUpdate(update) {
|
|
47
|
+
return typeof update.content === "string";
|
|
48
|
+
}
|
|
49
|
+
var sharedGitNativeOutputDir = resolve2(tmpdir2(), "rig-native");
|
|
50
|
+
var sharedGitNativeOutputPath = resolve2(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
51
|
+
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
52
|
+
function temporaryGitBinaryOutputPath(outputPath) {
|
|
53
|
+
const suffix = process.platform === "win32" ? ".exe" : "";
|
|
54
|
+
return resolve2(dirname(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`);
|
|
55
|
+
}
|
|
56
|
+
function publishGitBinary(tempOutputPath, outputPath) {
|
|
57
|
+
try {
|
|
58
|
+
renameSync2(tempOutputPath, outputPath);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (process.platform === "win32" && existsSync2(outputPath)) {
|
|
61
|
+
rmSync(outputPath, { force: true });
|
|
62
|
+
renameSync2(tempOutputPath, outputPath);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function isSharedGitNativeOutputPath(outputPath) {
|
|
69
|
+
return resolve2(outputPath) === sharedGitNativeOutputPath;
|
|
70
|
+
}
|
|
71
|
+
function materializeFromSharedGitBinarySync(outputPath, buildKey) {
|
|
72
|
+
if (isSharedGitNativeOutputPath(outputPath))
|
|
73
|
+
return null;
|
|
74
|
+
const sharedManifest = nativeBuildManifestPath(sharedGitNativeOutputPath);
|
|
75
|
+
if (!existsSync2(sharedGitNativeOutputPath) || !hasMatchingNativeBuildManifestSync(sharedManifest, buildKey) || !binarySupportsTrackerCommandsSync(sharedGitNativeOutputPath)) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
mkdirSync2(dirname(outputPath), { recursive: true });
|
|
79
|
+
copyFileSync(sharedGitNativeOutputPath, outputPath);
|
|
80
|
+
chmodSync(outputPath, 493);
|
|
81
|
+
writeFileSync2(nativeBuildManifestPath(outputPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
82
|
+
`, "utf8");
|
|
83
|
+
return outputPath;
|
|
84
|
+
}
|
|
85
|
+
function runtimeRigGitFileName() {
|
|
86
|
+
return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
|
|
87
|
+
}
|
|
88
|
+
function rigGitSourceCandidates() {
|
|
89
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
90
|
+
const cwd = process.cwd()?.trim() || "";
|
|
91
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
92
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
93
|
+
const moduleRelativeSource = resolve2(import.meta.dir, "../native/rig-git.zig");
|
|
94
|
+
return [...new Set([
|
|
95
|
+
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
96
|
+
moduleRelativeSource,
|
|
97
|
+
projectRoot ? resolve2(projectRoot, "packages/memory-plugin/native/rig-git.zig") : "",
|
|
98
|
+
hostProjectRoot ? resolve2(hostProjectRoot, "packages/memory-plugin/native/rig-git.zig") : "",
|
|
99
|
+
cwd ? resolve2(cwd, "packages/memory-plugin/native/rig-git.zig") : "",
|
|
100
|
+
execDir ? resolve2(execDir, "..", "..", "packages/memory-plugin/native/rig-git.zig") : "",
|
|
101
|
+
execDir ? resolve2(execDir, "..", "native", "rig-git.zig") : ""
|
|
102
|
+
].filter(Boolean))];
|
|
103
|
+
}
|
|
104
|
+
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
105
|
+
const candidates = [];
|
|
106
|
+
let cursor = resolve2(fromDir);
|
|
107
|
+
for (let index = 0;index < 8; index += 1) {
|
|
108
|
+
candidates.push(resolve2(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve2(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve2(cursor, "native", fileName), resolve2(cursor, "native", "bin", fileName));
|
|
109
|
+
const parent = dirname(cursor);
|
|
110
|
+
if (parent === cursor)
|
|
111
|
+
break;
|
|
112
|
+
cursor = parent;
|
|
113
|
+
}
|
|
114
|
+
return candidates;
|
|
115
|
+
}
|
|
116
|
+
function rigGitBinaryCandidates() {
|
|
117
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
118
|
+
const fileName = runtimeRigGitFileName();
|
|
119
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
120
|
+
return [...new Set([
|
|
121
|
+
explicit,
|
|
122
|
+
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
123
|
+
execDir ? resolve2(execDir, fileName) : "",
|
|
124
|
+
execDir ? resolve2(execDir, "..", fileName) : "",
|
|
125
|
+
execDir ? resolve2(execDir, "..", "bin", fileName) : "",
|
|
126
|
+
sharedGitNativeOutputPath
|
|
127
|
+
].filter(Boolean))];
|
|
128
|
+
}
|
|
129
|
+
function resolveGitSourcePath() {
|
|
130
|
+
for (const candidate of rigGitSourceCandidates()) {
|
|
131
|
+
if (candidate && existsSync2(candidate)) {
|
|
132
|
+
return candidate;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
function resolveGitBinaryPath() {
|
|
138
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
for (const candidate of rigGitBinaryCandidates()) {
|
|
142
|
+
if (candidate && existsSync2(candidate)) {
|
|
143
|
+
return candidate;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function preferredGitBinaryOutputPath() {
|
|
149
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
150
|
+
return explicit || sharedGitNativeOutputPath;
|
|
151
|
+
}
|
|
152
|
+
function binarySupportsTrackerCommandsSync(binaryPath) {
|
|
153
|
+
try {
|
|
154
|
+
const probe = Bun.spawnSync([binaryPath, "fetch-ref", "."], {
|
|
155
|
+
stdout: "pipe",
|
|
156
|
+
stderr: "pipe"
|
|
157
|
+
});
|
|
158
|
+
const stdout = probe.stdout.toString().trim();
|
|
159
|
+
const stderr = probe.stderr.toString().trim();
|
|
160
|
+
if (stdout.includes('"error":"unknown command"')) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return probe.exitCode === 2 && stderr.includes(trackerCommandUsageProbe);
|
|
164
|
+
} catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function nativeBuildManifestPath(outputPath) {
|
|
169
|
+
return `${outputPath}.build-manifest.json`;
|
|
170
|
+
}
|
|
171
|
+
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
172
|
+
if (!existsSync2(manifestPath)) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const manifest = JSON.parse(readFileSync2(manifestPath, "utf8"));
|
|
177
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
178
|
+
} catch {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function sha256FileSync(path) {
|
|
183
|
+
return createHash("sha256").update(readFileSync2(path)).digest("hex");
|
|
184
|
+
}
|
|
185
|
+
function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
|
|
186
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
187
|
+
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
188
|
+
}
|
|
189
|
+
const explicitBin = process.env.RIG_NATIVE_GIT_BIN?.trim();
|
|
190
|
+
if (explicitBin && existsSync2(explicitBin)) {
|
|
191
|
+
return explicitBin;
|
|
192
|
+
}
|
|
193
|
+
const embedded = extractEmbeddedNative("rig-git");
|
|
194
|
+
if (embedded) {
|
|
195
|
+
return embedded;
|
|
196
|
+
}
|
|
197
|
+
const sourcePath = resolveGitSourcePath();
|
|
198
|
+
if (!sourcePath) {
|
|
199
|
+
const binaryPath = resolveGitBinaryPath();
|
|
200
|
+
if (binaryPath) {
|
|
201
|
+
return binaryPath;
|
|
202
|
+
}
|
|
203
|
+
throw new Error("rig-git.zig source file not found.");
|
|
204
|
+
}
|
|
205
|
+
const zigBinary = Bun.which("zig");
|
|
206
|
+
if (!zigBinary) {
|
|
207
|
+
throw new Error("zig is required to build native Rig git tools.");
|
|
208
|
+
}
|
|
209
|
+
mkdirSync2(dirname(outputPath), { recursive: true });
|
|
210
|
+
const sourceDigest = sha256FileSync(sourcePath);
|
|
211
|
+
const buildKey = JSON.stringify({
|
|
212
|
+
version: 1,
|
|
213
|
+
zigBinary,
|
|
214
|
+
platform: process.platform,
|
|
215
|
+
arch: process.arch,
|
|
216
|
+
sourcePath,
|
|
217
|
+
sourceDigest
|
|
218
|
+
});
|
|
219
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
220
|
+
const needsBuild = !existsSync2(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
221
|
+
if (!needsBuild) {
|
|
222
|
+
chmodSync(outputPath, 493);
|
|
223
|
+
return outputPath;
|
|
224
|
+
}
|
|
225
|
+
const materialized = materializeFromSharedGitBinarySync(outputPath, buildKey);
|
|
226
|
+
if (materialized)
|
|
227
|
+
return materialized;
|
|
228
|
+
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
229
|
+
const build = Bun.spawnSync([
|
|
230
|
+
zigBinary,
|
|
231
|
+
"build-exe",
|
|
232
|
+
sourcePath,
|
|
233
|
+
"-O",
|
|
234
|
+
"ReleaseFast",
|
|
235
|
+
`-femit-bin=${tempOutputPath}`
|
|
236
|
+
], {
|
|
237
|
+
cwd: dirname(sourcePath),
|
|
238
|
+
stdout: "pipe",
|
|
239
|
+
stderr: "pipe"
|
|
240
|
+
});
|
|
241
|
+
if (build.exitCode !== 0 || !existsSync2(tempOutputPath)) {
|
|
242
|
+
const stderr = build.stderr.toString().trim();
|
|
243
|
+
const stdout = build.stdout.toString().trim();
|
|
244
|
+
const details = [stderr, stdout].filter(Boolean).join(`
|
|
245
|
+
`);
|
|
246
|
+
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
247
|
+
}
|
|
248
|
+
chmodSync(tempOutputPath, 493);
|
|
249
|
+
if (existsSync2(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
250
|
+
rmSync(tempOutputPath, { force: true });
|
|
251
|
+
chmodSync(outputPath, 493);
|
|
252
|
+
return outputPath;
|
|
253
|
+
}
|
|
254
|
+
publishGitBinary(tempOutputPath, outputPath);
|
|
255
|
+
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
256
|
+
rmSync(outputPath, { force: true });
|
|
257
|
+
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
258
|
+
}
|
|
259
|
+
writeFileSync2(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
260
|
+
`, "utf8");
|
|
261
|
+
return outputPath;
|
|
262
|
+
}
|
|
263
|
+
function gitNativeEnv() {
|
|
264
|
+
const env = { ...process.env };
|
|
265
|
+
const token = env.GITHUB_TOKEN?.trim() || env.GH_TOKEN?.trim() || env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
266
|
+
if (token) {
|
|
267
|
+
env.RIG_GITHUB_TOKEN = env.RIG_GITHUB_TOKEN || token;
|
|
268
|
+
env.GITHUB_TOKEN = env.GITHUB_TOKEN || token;
|
|
269
|
+
env.GH_TOKEN = env.GH_TOKEN || token;
|
|
270
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
271
|
+
env.GIT_CONFIG_COUNT = "2";
|
|
272
|
+
env.GIT_CONFIG_KEY_0 = "credential.helper";
|
|
273
|
+
env.GIT_CONFIG_VALUE_0 = "";
|
|
274
|
+
env.GIT_CONFIG_KEY_1 = "credential.helper";
|
|
275
|
+
env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
|
|
276
|
+
}
|
|
277
|
+
return env;
|
|
278
|
+
}
|
|
279
|
+
function runGitNative(command, args) {
|
|
280
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
281
|
+
return { ok: false, error: "rig-git native disabled" };
|
|
282
|
+
}
|
|
283
|
+
const trackerCommand = command === "fetch-ref" || command === "read-blob-at-ref" || command === "write-tree-commit" || command === "push-ref-with-lease";
|
|
284
|
+
let binaryPath = null;
|
|
285
|
+
if (trackerCommand) {
|
|
286
|
+
try {
|
|
287
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
288
|
+
} catch (error) {
|
|
289
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
290
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
291
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
292
|
+
}
|
|
293
|
+
return { ok: false, error: message };
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
297
|
+
binaryPath = explicitBinaryPath && existsSync2(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
298
|
+
if (!binaryPath) {
|
|
299
|
+
try {
|
|
300
|
+
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
301
|
+
} catch (error) {
|
|
302
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
303
|
+
if (message.includes("rig-git.zig source file not found")) {
|
|
304
|
+
return { ok: false, error: "rig-git binary not found" };
|
|
305
|
+
}
|
|
306
|
+
return { ok: false, error: message };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
const proc = Bun.spawnSync([binaryPath, command, ...args], {
|
|
312
|
+
stdout: "pipe",
|
|
313
|
+
stderr: "pipe",
|
|
314
|
+
env: gitNativeEnv()
|
|
315
|
+
});
|
|
316
|
+
if (proc.exitCode !== 0) {
|
|
317
|
+
const stdoutText = proc.stdout.toString().trim();
|
|
318
|
+
if (stdoutText) {
|
|
319
|
+
try {
|
|
320
|
+
const parsed = JSON.parse(stdoutText);
|
|
321
|
+
if (!parsed.ok) {
|
|
322
|
+
return parsed;
|
|
323
|
+
}
|
|
324
|
+
} catch {}
|
|
325
|
+
}
|
|
326
|
+
const errText = proc.stderr.toString().trim() || `exit code ${proc.exitCode}`;
|
|
327
|
+
return { ok: false, error: errText };
|
|
328
|
+
}
|
|
329
|
+
const output = proc.stdout.toString().trim();
|
|
330
|
+
return JSON.parse(output);
|
|
331
|
+
} catch (err) {
|
|
332
|
+
return { ok: false, error: String(err) };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function requireGitNative(command, args) {
|
|
336
|
+
const result = runGitNative(command, args);
|
|
337
|
+
if (result.ok === false) {
|
|
338
|
+
throw new Error(`rig-git ${command} failed: ${result.error}`);
|
|
339
|
+
}
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
function requireGitNativeString(command, args) {
|
|
343
|
+
const result = requireGitNative(command, args);
|
|
344
|
+
if ("value" in result && typeof result.value === "string") {
|
|
345
|
+
return result.value;
|
|
346
|
+
}
|
|
347
|
+
throw new Error(`rig-git ${command} returned an unexpected result payload`);
|
|
348
|
+
}
|
|
349
|
+
function nativeFetchRef(repoPath, remote, branch) {
|
|
350
|
+
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
351
|
+
}
|
|
352
|
+
function nativeReadBlobBytesAtRef(repoPath, ref, path) {
|
|
353
|
+
const requestDir = resolve2(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
354
|
+
mkdirSync2(requestDir, { recursive: true });
|
|
355
|
+
const outputPath = resolve2(requestDir, "blob.bin");
|
|
356
|
+
try {
|
|
357
|
+
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
358
|
+
return readFileSync2(outputPath);
|
|
359
|
+
} finally {
|
|
360
|
+
rmSync(requestDir, { recursive: true, force: true });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function serializeTreeCommitUpdates(updates) {
|
|
364
|
+
return updates.map((update) => {
|
|
365
|
+
if (isTextTreeCommitUpdate(update)) {
|
|
366
|
+
return { path: update.path, kind: "text", content: update.content };
|
|
367
|
+
}
|
|
368
|
+
if (!isAbsolute(update.sourceFilePath)) {
|
|
369
|
+
throw new Error("tree commit binary updates require an absolute sourceFilePath");
|
|
370
|
+
}
|
|
371
|
+
return { path: update.path, kind: "file", sourceFilePath: update.sourceFilePath };
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function buildTreeCommitUpdatesJson(updates) {
|
|
375
|
+
return `${JSON.stringify(serializeTreeCommitUpdates(updates), null, 2)}
|
|
376
|
+
`;
|
|
377
|
+
}
|
|
378
|
+
function nativeWriteTreeCommit(repoPath, baseRef, updates, message) {
|
|
379
|
+
const requestDir = resolve2(sharedGitNativeOutputDir, "requests", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
380
|
+
mkdirSync2(requestDir, { recursive: true });
|
|
381
|
+
const messagePath = resolve2(requestDir, "message.txt");
|
|
382
|
+
const updatesPath = resolve2(requestDir, "updates.json");
|
|
383
|
+
try {
|
|
384
|
+
writeFileSync2(messagePath, message, "utf8");
|
|
385
|
+
writeFileSync2(updatesPath, buildTreeCommitUpdatesJson(updates), "utf8");
|
|
386
|
+
return requireGitNativeString("write-tree-commit", [repoPath, baseRef, messagePath, updatesPath]);
|
|
387
|
+
} finally {
|
|
388
|
+
rmSync(requestDir, { recursive: true, force: true });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function nativePushRefWithLease(repoPath, localOid, remoteRef, expectedOldOid, remote = "origin") {
|
|
392
|
+
return requireGitNativeString("push-ref-with-lease", [
|
|
393
|
+
repoPath,
|
|
394
|
+
localOid,
|
|
395
|
+
remoteRef,
|
|
396
|
+
expectedOldOid,
|
|
397
|
+
remote
|
|
398
|
+
]);
|
|
399
|
+
}
|
|
4
400
|
|
|
5
401
|
// packages/memory-plugin/src/db.ts
|
|
6
402
|
import { Database } from "bun:sqlite";
|
|
7
|
-
import { mkdirSync } from "fs";
|
|
8
|
-
import { dirname } from "path";
|
|
403
|
+
import { mkdirSync as mkdirSync3 } from "fs";
|
|
404
|
+
import { dirname as dirname2 } from "path";
|
|
9
405
|
import {
|
|
10
406
|
NO_MATCH_RETRIEVAL_CANONICAL_KEY
|
|
11
407
|
} from "@rig/contracts";
|
|
@@ -152,11 +548,12 @@ function eventFeedbackOutcome(event) {
|
|
|
152
548
|
}
|
|
153
549
|
function normalizeStatement(statement, args) {
|
|
154
550
|
if (typeof statement === "string") {
|
|
155
|
-
return { sql: statement, args };
|
|
551
|
+
return { sql: statement, ...args !== undefined ? { args } : {} };
|
|
156
552
|
}
|
|
553
|
+
const resolvedArgs = statement.args ?? args;
|
|
157
554
|
return {
|
|
158
555
|
sql: statement.sql,
|
|
159
|
-
args:
|
|
556
|
+
...resolvedArgs !== undefined ? { args: resolvedArgs } : {}
|
|
160
557
|
};
|
|
161
558
|
}
|
|
162
559
|
function normalizeBindings(bindings) {
|
|
@@ -191,7 +588,7 @@ function executeSqlite(sqlite, statement, args) {
|
|
|
191
588
|
const normalized = normalizeStatement(statement, args);
|
|
192
589
|
const bindings = normalizeBindings(normalized.args);
|
|
193
590
|
if (isMutationStatement(normalized.sql)) {
|
|
194
|
-
const result = bindings.length > 0 ? sqlite.run(normalized.sql,
|
|
591
|
+
const result = bindings.length > 0 ? sqlite.run(normalized.sql, bindings) : sqlite.run(normalized.sql);
|
|
195
592
|
return {
|
|
196
593
|
rows: [],
|
|
197
594
|
rowsAffected: Number(result.changes)
|
|
@@ -599,7 +996,7 @@ async function validateEventTargets(executor, event) {
|
|
|
599
996
|
}
|
|
600
997
|
}
|
|
601
998
|
async function openMemoryDb(dbPath) {
|
|
602
|
-
|
|
999
|
+
mkdirSync3(dirname2(dbPath), { recursive: true });
|
|
603
1000
|
const sqlite = new Database(dbPath, { create: true, strict: true });
|
|
604
1001
|
const client = createMemoryDbClient(sqlite);
|
|
605
1002
|
const db = {
|
|
@@ -704,7 +1101,7 @@ async function hasMemoryEvent(db, eventId) {
|
|
|
704
1101
|
}
|
|
705
1102
|
|
|
706
1103
|
// packages/memory-plugin/src/embed.ts
|
|
707
|
-
import { createHash } from "crypto";
|
|
1104
|
+
import { createHash as createHash2 } from "crypto";
|
|
708
1105
|
var DEFAULT_EMBEDDING_API_BASE_URL = "https://api.openai.com/v1";
|
|
709
1106
|
var DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small";
|
|
710
1107
|
var DETERMINISTIC_EMBEDDER_MODE = "deterministic";
|
|
@@ -721,7 +1118,7 @@ function tokenizeForDeterministicEmbedding(text) {
|
|
|
721
1118
|
return tokens.length > 0 ? tokens : [text.toLowerCase()];
|
|
722
1119
|
}
|
|
723
1120
|
function deterministicTokenVector(token) {
|
|
724
|
-
const hash =
|
|
1121
|
+
const hash = createHash2("sha256").update(token).digest();
|
|
725
1122
|
const vector = new Array(DETERMINISTIC_VECTOR_DIMS).fill(0);
|
|
726
1123
|
for (let index = 0;index < 8; index += 1) {
|
|
727
1124
|
const slot = (hash[index] ?? 0) % DETERMINISTIC_VECTOR_DIMS;
|
|
@@ -825,7 +1222,7 @@ function createConfiguredMemoryEmbedder(options = {}) {
|
|
|
825
1222
|
apiKey,
|
|
826
1223
|
model: env.RIG_MEMORY_EMBEDDING_MODEL?.trim() || DEFAULT_EMBEDDING_MODEL,
|
|
827
1224
|
apiBaseUrl: options.apiBaseUrl ?? env.RIG_MEMORY_EMBEDDING_API_BASE_URL?.trim() ?? DEFAULT_EMBEDDING_API_BASE_URL,
|
|
828
|
-
fetchImpl: options.fetchImpl
|
|
1225
|
+
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}
|
|
829
1226
|
});
|
|
830
1227
|
}
|
|
831
1228
|
function warnMissingMemoryEmbedderOnce(warn) {
|
|
@@ -895,18 +1292,17 @@ async function embedChangedMemoryItems(db, event, embedder) {
|
|
|
895
1292
|
}
|
|
896
1293
|
|
|
897
1294
|
// packages/memory-plugin/src/read.ts
|
|
898
|
-
import { mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
899
|
-
import { tmpdir } from "os";
|
|
1295
|
+
import { mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
1296
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
900
1297
|
import { join } from "path";
|
|
901
|
-
import {
|
|
902
|
-
import { resolveMonorepoRoot } from "@rig/runtime/control-plane/native/utils";
|
|
1298
|
+
import { resolveCheckoutRoot as resolveMonorepoRoot } from "@rig/core/checkout-root";
|
|
903
1299
|
var CANONICAL_MEMORY_DB_PATH = "rig/memory/project-memory.db";
|
|
904
1300
|
var DEFAULT_READ_DEPS = {
|
|
905
1301
|
fetchRef: nativeFetchRef,
|
|
906
1302
|
readBlobBytesAtRef: nativeReadBlobBytesAtRef,
|
|
907
1303
|
openMemoryDb,
|
|
908
|
-
makeTempDir: () => mkdtempSync(join(
|
|
909
|
-
removeDir: (path) =>
|
|
1304
|
+
makeTempDir: () => mkdtempSync(join(tmpdir3(), "memory-sync-read-")),
|
|
1305
|
+
removeDir: (path) => rmSync2(path, { recursive: true, force: true })
|
|
910
1306
|
};
|
|
911
1307
|
function isMissingCanonicalMemoryBlobError(error) {
|
|
912
1308
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -944,7 +1340,7 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
|
|
|
944
1340
|
} else {
|
|
945
1341
|
try {
|
|
946
1342
|
const bytes = readDeps.readBlobBytesAtRef(repoPath, baseOid, CANONICAL_MEMORY_DB_PATH);
|
|
947
|
-
|
|
1343
|
+
writeFileSync3(dbPath, bytes);
|
|
948
1344
|
} catch (error) {
|
|
949
1345
|
if (!isMissingCanonicalMemoryBlobError(error)) {
|
|
950
1346
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/memory-plugin",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.159",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "First-party shared-memory capability plugin for Rig.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"module": "./dist/src/index.js",
|
|
30
30
|
"types": "./dist/src/index.d.ts",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.
|
|
33
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
34
|
-
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.157"
|
|
32
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.159",
|
|
33
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.159"
|
|
35
34
|
}
|
|
36
35
|
}
|