@deeplake/hivemind 0.7.44 → 0.7.46
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +3116 -208
- package/codex/bundle/capture.js +43 -0
- package/codex/bundle/commands/auth-login.js +43 -0
- package/codex/bundle/graph-pull-worker.js +1185 -0
- package/codex/bundle/pre-tool-use.js +43 -0
- package/codex/bundle/session-start-setup.js +43 -0
- package/codex/bundle/session-start.js +70 -4
- package/codex/bundle/shell/deeplake-shell.js +577 -25
- package/codex/bundle/skillify-worker.js +30 -3
- package/codex/bundle/stop.js +97 -50
- package/cursor/bundle/capture.js +97 -50
- package/cursor/bundle/commands/auth-login.js +43 -0
- package/cursor/bundle/graph-pull-worker.js +1185 -0
- package/cursor/bundle/pre-tool-use.js +43 -0
- package/cursor/bundle/session-end.js +49 -44
- package/cursor/bundle/session-start.js +66 -0
- package/cursor/bundle/shell/deeplake-shell.js +577 -25
- package/cursor/bundle/skillify-worker.js +30 -3
- package/hermes/bundle/capture.js +97 -50
- package/hermes/bundle/commands/auth-login.js +43 -0
- package/hermes/bundle/graph-pull-worker.js +1185 -0
- package/hermes/bundle/pre-tool-use.js +43 -0
- package/hermes/bundle/session-end.js +49 -44
- package/hermes/bundle/session-start.js +66 -0
- package/hermes/bundle/shell/deeplake-shell.js +577 -25
- package/hermes/bundle/skillify-worker.js +30 -3
- package/mcp/bundle/server.js +43 -0
- package/openclaw/dist/chunks/{config-XEK4MJJS.js → config-O5PDJQ7Y.js} +1 -0
- package/openclaw/dist/index.js +47 -2
- package/openclaw/dist/skillify-worker.js +30 -3
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +3 -1
|
@@ -395,9 +395,33 @@ function validateSchema(label, cols) {
|
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
+
var CODEBASE_COLUMNS = Object.freeze([
|
|
399
|
+
// Identity key (matches the PK below)
|
|
400
|
+
{ name: "org_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
401
|
+
{ name: "workspace_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
402
|
+
{ name: "repo_slug", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
403
|
+
{ name: "user_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
404
|
+
{ name: "worktree_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
405
|
+
{ name: "commit_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
406
|
+
// Observation metadata
|
|
407
|
+
{ name: "parent_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
408
|
+
{ name: "branch", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
409
|
+
{ name: "ts", sql: "TIMESTAMP" },
|
|
410
|
+
{ name: "pushed_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
411
|
+
// Snapshot payload
|
|
412
|
+
{ name: "snapshot_sha256", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
413
|
+
{ name: "snapshot_jsonb", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
414
|
+
{ name: "node_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
415
|
+
{ name: "edge_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
416
|
+
// Generator metadata (for drift diagnostics — what hivemind version produced this?)
|
|
417
|
+
{ name: "generator", sql: "TEXT NOT NULL DEFAULT 'hivemind-graph'" },
|
|
418
|
+
{ name: "generator_version", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
419
|
+
{ name: "schema_version", sql: "BIGINT NOT NULL DEFAULT 1" }
|
|
420
|
+
]);
|
|
398
421
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
399
422
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
400
423
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
424
|
+
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
401
425
|
function buildCreateTableSql(tableName, cols) {
|
|
402
426
|
const safe = sqlIdent(tableName);
|
|
403
427
|
const colSql = cols.map((c) => `${c.name} ${c.sql}`).join(", ");
|
|
@@ -693,9 +717,12 @@ function resolveRecordScope(args) {
|
|
|
693
717
|
|
|
694
718
|
// dist/src/skillify/state.js
|
|
695
719
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, writeSync, mkdirSync as mkdirSync2, renameSync as renameSync2, rmdirSync, existsSync as existsSync4, lstatSync, unlinkSync, openSync, closeSync } from "node:fs";
|
|
720
|
+
import { join as join6 } from "node:path";
|
|
721
|
+
|
|
722
|
+
// dist/src/utils/repo-identity.js
|
|
696
723
|
import { execSync } from "node:child_process";
|
|
697
724
|
import { createHash } from "node:crypto";
|
|
698
|
-
import {
|
|
725
|
+
import { basename, resolve } from "node:path";
|
|
699
726
|
|
|
700
727
|
// dist/src/skillify/legacy-migration.js
|
|
701
728
|
import { existsSync as existsSync3, renameSync } from "node:fs";
|
|
@@ -881,7 +908,7 @@ async function query(sql, retries = 4) {
|
|
|
881
908
|
const base = Math.min(3e4, 2e3 * Math.pow(2, attempt));
|
|
882
909
|
const delay = base + Math.floor(Math.random() * 1e3);
|
|
883
910
|
wlog(`fetch failed (${e?.name ?? e?.code ?? e?.message}), retrying in ${delay}ms (attempt ${attempt + 1}/${retries})`);
|
|
884
|
-
await new Promise((
|
|
911
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
885
912
|
continue;
|
|
886
913
|
}
|
|
887
914
|
throw e;
|
|
@@ -897,7 +924,7 @@ async function query(sql, retries = 4) {
|
|
|
897
924
|
const base = Math.min(3e4, 2e3 * Math.pow(2, attempt));
|
|
898
925
|
const delay = base + Math.floor(Math.random() * 1e3);
|
|
899
926
|
wlog(`API ${r.status}, retrying in ${delay}ms (attempt ${attempt + 1}/${retries})`);
|
|
900
|
-
await new Promise((
|
|
927
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
901
928
|
continue;
|
|
902
929
|
}
|
|
903
930
|
throw new Error(`API ${r.status}: ${(await r.text()).slice(0, 200)}`);
|
package/hermes/bundle/capture.js
CHANGED
|
@@ -53,13 +53,13 @@ var init_index_marker_store = __esm({
|
|
|
53
53
|
|
|
54
54
|
// dist/src/utils/stdin.js
|
|
55
55
|
function readStdin() {
|
|
56
|
-
return new Promise((
|
|
56
|
+
return new Promise((resolve3, reject) => {
|
|
57
57
|
let data = "";
|
|
58
58
|
process.stdin.setEncoding("utf-8");
|
|
59
59
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
60
60
|
process.stdin.on("end", () => {
|
|
61
61
|
try {
|
|
62
|
-
|
|
62
|
+
resolve3(JSON.parse(data));
|
|
63
63
|
} catch (err) {
|
|
64
64
|
reject(new Error(`Failed to parse hook input: ${err}`));
|
|
65
65
|
}
|
|
@@ -97,6 +97,7 @@ function loadConfig() {
|
|
|
97
97
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
98
98
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
99
99
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
100
|
+
codebaseTableName: process.env.HIVEMIND_CODEBASE_TABLE ?? "codebase",
|
|
100
101
|
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join(home, ".deeplake", "memory")
|
|
101
102
|
};
|
|
102
103
|
}
|
|
@@ -214,9 +215,33 @@ function validateSchema(label, cols) {
|
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
}
|
|
218
|
+
var CODEBASE_COLUMNS = Object.freeze([
|
|
219
|
+
// Identity key (matches the PK below)
|
|
220
|
+
{ name: "org_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
221
|
+
{ name: "workspace_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
222
|
+
{ name: "repo_slug", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
223
|
+
{ name: "user_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
224
|
+
{ name: "worktree_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
225
|
+
{ name: "commit_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
226
|
+
// Observation metadata
|
|
227
|
+
{ name: "parent_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
228
|
+
{ name: "branch", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
229
|
+
{ name: "ts", sql: "TIMESTAMP" },
|
|
230
|
+
{ name: "pushed_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
231
|
+
// Snapshot payload
|
|
232
|
+
{ name: "snapshot_sha256", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
233
|
+
{ name: "snapshot_jsonb", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
234
|
+
{ name: "node_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
235
|
+
{ name: "edge_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
236
|
+
// Generator metadata (for drift diagnostics — what hivemind version produced this?)
|
|
237
|
+
{ name: "generator", sql: "TEXT NOT NULL DEFAULT 'hivemind-graph'" },
|
|
238
|
+
{ name: "generator_version", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
239
|
+
{ name: "schema_version", sql: "BIGINT NOT NULL DEFAULT 1" }
|
|
240
|
+
]);
|
|
217
241
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
218
242
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
219
243
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
244
|
+
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
220
245
|
function buildCreateTableSql(tableName, cols) {
|
|
221
246
|
const safe = sqlIdent(tableName);
|
|
222
247
|
const colSql = cols.map((c) => `${c.name} ${c.sql}`).join(", ");
|
|
@@ -441,7 +466,7 @@ function getQueryTimeoutMs() {
|
|
|
441
466
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
442
467
|
}
|
|
443
468
|
function sleep2(ms) {
|
|
444
|
-
return new Promise((
|
|
469
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
445
470
|
}
|
|
446
471
|
function isTimeoutError(error) {
|
|
447
472
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -471,7 +496,7 @@ var Semaphore = class {
|
|
|
471
496
|
this.active++;
|
|
472
497
|
return;
|
|
473
498
|
}
|
|
474
|
-
await new Promise((
|
|
499
|
+
await new Promise((resolve3) => this.waiting.push(resolve3));
|
|
475
500
|
}
|
|
476
501
|
release() {
|
|
477
502
|
this.active--;
|
|
@@ -781,6 +806,24 @@ var DeeplakeApi = class {
|
|
|
781
806
|
* This sidesteps the Deeplake UPDATE-coalescing quirk that bit the wiki
|
|
782
807
|
* worker.
|
|
783
808
|
*/
|
|
809
|
+
/**
|
|
810
|
+
* Create the codebase table. One row per (org, workspace, repo, user,
|
|
811
|
+
* worktree, commit) — see CODEBASE_COLUMNS for the schema. Healing
|
|
812
|
+
* + index follow the same pattern as ensureSessionsTable.
|
|
813
|
+
*/
|
|
814
|
+
async ensureCodebaseTable(name) {
|
|
815
|
+
const safe = sqlIdent(name);
|
|
816
|
+
const tables = await this.listTables();
|
|
817
|
+
if (!tables.includes(safe)) {
|
|
818
|
+
log3(`table "${safe}" not found, creating`);
|
|
819
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, CODEBASE_COLUMNS), safe);
|
|
820
|
+
log3(`table "${safe}" created`);
|
|
821
|
+
if (!tables.includes(safe))
|
|
822
|
+
this._tablesCache = [...tables, safe];
|
|
823
|
+
}
|
|
824
|
+
await this.healSchema(safe, CODEBASE_COLUMNS);
|
|
825
|
+
await this.ensureLookupIndex(safe, "codebase_identity", `("org_id", "workspace_id", "repo_slug", "user_id", "worktree_id", "commit_sha")`);
|
|
826
|
+
}
|
|
784
827
|
async ensureSkillsTable(name) {
|
|
785
828
|
const safe = sqlIdent(name);
|
|
786
829
|
const tables = await this.listTables();
|
|
@@ -1056,7 +1099,7 @@ var EmbedClient = class {
|
|
|
1056
1099
|
}
|
|
1057
1100
|
}
|
|
1058
1101
|
connectOnce() {
|
|
1059
|
-
return new Promise((
|
|
1102
|
+
return new Promise((resolve3, reject) => {
|
|
1060
1103
|
const sock = connect(this.socketPath);
|
|
1061
1104
|
const to = setTimeout(() => {
|
|
1062
1105
|
sock.destroy();
|
|
@@ -1064,7 +1107,7 @@ var EmbedClient = class {
|
|
|
1064
1107
|
}, this.timeoutMs);
|
|
1065
1108
|
sock.once("connect", () => {
|
|
1066
1109
|
clearTimeout(to);
|
|
1067
|
-
|
|
1110
|
+
resolve3(sock);
|
|
1068
1111
|
});
|
|
1069
1112
|
sock.once("error", (e) => {
|
|
1070
1113
|
clearTimeout(to);
|
|
@@ -1146,7 +1189,7 @@ var EmbedClient = class {
|
|
|
1146
1189
|
throw new Error("daemon did not become ready within spawnWaitMs");
|
|
1147
1190
|
}
|
|
1148
1191
|
sendAndWait(sock, req) {
|
|
1149
|
-
return new Promise((
|
|
1192
|
+
return new Promise((resolve3, reject) => {
|
|
1150
1193
|
let buf = "";
|
|
1151
1194
|
const to = setTimeout(() => {
|
|
1152
1195
|
sock.destroy();
|
|
@@ -1161,7 +1204,7 @@ var EmbedClient = class {
|
|
|
1161
1204
|
const line = buf.slice(0, nl);
|
|
1162
1205
|
clearTimeout(to);
|
|
1163
1206
|
try {
|
|
1164
|
-
|
|
1207
|
+
resolve3(JSON.parse(line));
|
|
1165
1208
|
} catch (e) {
|
|
1166
1209
|
reject(e);
|
|
1167
1210
|
}
|
|
@@ -1818,9 +1861,54 @@ function spawnSkillifyWorker(opts) {
|
|
|
1818
1861
|
|
|
1819
1862
|
// dist/src/skillify/state.js
|
|
1820
1863
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, writeSync as writeSync3, mkdirSync as mkdirSync10, renameSync as renameSync6, rmdirSync, existsSync as existsSync9, lstatSync as lstatSync2, unlinkSync as unlinkSync5, openSync as openSync4, closeSync as closeSync4 } from "node:fs";
|
|
1864
|
+
import { join as join18 } from "node:path";
|
|
1865
|
+
|
|
1866
|
+
// dist/src/utils/repo-identity.js
|
|
1821
1867
|
import { execSync as execSync2 } from "node:child_process";
|
|
1822
1868
|
import { createHash } from "node:crypto";
|
|
1823
|
-
import {
|
|
1869
|
+
import { basename as basename2, resolve as resolve2 } from "node:path";
|
|
1870
|
+
var DEFAULT_PORTS = {
|
|
1871
|
+
http: "80",
|
|
1872
|
+
https: "443",
|
|
1873
|
+
ssh: "22",
|
|
1874
|
+
git: "9418"
|
|
1875
|
+
};
|
|
1876
|
+
function normalizeGitRemoteUrl(url) {
|
|
1877
|
+
let s = url.trim();
|
|
1878
|
+
const schemeMatch = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
|
|
1879
|
+
const scheme = schemeMatch ? schemeMatch[1].toLowerCase() : null;
|
|
1880
|
+
if (schemeMatch)
|
|
1881
|
+
s = s.slice(schemeMatch[0].length);
|
|
1882
|
+
if (!scheme) {
|
|
1883
|
+
const scp = s.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/);
|
|
1884
|
+
if (scp)
|
|
1885
|
+
s = `${scp[1]}/${scp[2]}`;
|
|
1886
|
+
}
|
|
1887
|
+
s = s.replace(/^[^@/]+@/, "");
|
|
1888
|
+
if (scheme && DEFAULT_PORTS[scheme]) {
|
|
1889
|
+
s = s.replace(new RegExp(`^([^/]+):${DEFAULT_PORTS[scheme]}(/|$)`), "$1$2");
|
|
1890
|
+
}
|
|
1891
|
+
s = s.replace(/\.git\/?$/i, "");
|
|
1892
|
+
s = s.replace(/\/+$/, "");
|
|
1893
|
+
return s.toLowerCase();
|
|
1894
|
+
}
|
|
1895
|
+
function deriveProjectKey(cwd) {
|
|
1896
|
+
const absCwd = resolve2(cwd);
|
|
1897
|
+
const project = basename2(absCwd) || "unknown";
|
|
1898
|
+
let signature = null;
|
|
1899
|
+
try {
|
|
1900
|
+
const raw = execSync2("git config --get remote.origin.url", {
|
|
1901
|
+
cwd: absCwd,
|
|
1902
|
+
encoding: "utf-8",
|
|
1903
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1904
|
+
}).trim();
|
|
1905
|
+
signature = raw ? normalizeGitRemoteUrl(raw) : null;
|
|
1906
|
+
} catch {
|
|
1907
|
+
}
|
|
1908
|
+
const input = signature ?? absCwd;
|
|
1909
|
+
const key = createHash("sha1").update(input).digest("hex").slice(0, 16);
|
|
1910
|
+
return { key, project };
|
|
1911
|
+
}
|
|
1824
1912
|
|
|
1825
1913
|
// dist/src/skillify/legacy-migration.js
|
|
1826
1914
|
import { existsSync as existsSync8, renameSync as renameSync5 } from "node:fs";
|
|
@@ -1875,47 +1963,6 @@ function statePath2(projectKey) {
|
|
|
1875
1963
|
function lockPath3(projectKey) {
|
|
1876
1964
|
return join18(getStateDir(), `${projectKey}.lock`);
|
|
1877
1965
|
}
|
|
1878
|
-
var DEFAULT_PORTS = {
|
|
1879
|
-
http: "80",
|
|
1880
|
-
https: "443",
|
|
1881
|
-
ssh: "22",
|
|
1882
|
-
git: "9418"
|
|
1883
|
-
};
|
|
1884
|
-
function normalizeGitRemoteUrl(url) {
|
|
1885
|
-
let s = url.trim();
|
|
1886
|
-
const schemeMatch = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
|
|
1887
|
-
const scheme = schemeMatch ? schemeMatch[1].toLowerCase() : null;
|
|
1888
|
-
if (schemeMatch)
|
|
1889
|
-
s = s.slice(schemeMatch[0].length);
|
|
1890
|
-
if (!scheme) {
|
|
1891
|
-
const scp = s.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/);
|
|
1892
|
-
if (scp)
|
|
1893
|
-
s = `${scp[1]}/${scp[2]}`;
|
|
1894
|
-
}
|
|
1895
|
-
s = s.replace(/^[^@/]+@/, "");
|
|
1896
|
-
if (scheme && DEFAULT_PORTS[scheme]) {
|
|
1897
|
-
s = s.replace(new RegExp(`^([^/]+):${DEFAULT_PORTS[scheme]}(/|$)`), "$1$2");
|
|
1898
|
-
}
|
|
1899
|
-
s = s.replace(/\.git\/?$/i, "");
|
|
1900
|
-
s = s.replace(/\/+$/, "");
|
|
1901
|
-
return s.toLowerCase();
|
|
1902
|
-
}
|
|
1903
|
-
function deriveProjectKey(cwd) {
|
|
1904
|
-
const project = basename2(cwd) || "unknown";
|
|
1905
|
-
let signature = null;
|
|
1906
|
-
try {
|
|
1907
|
-
const raw = execSync2("git config --get remote.origin.url", {
|
|
1908
|
-
cwd,
|
|
1909
|
-
encoding: "utf-8",
|
|
1910
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
1911
|
-
}).trim();
|
|
1912
|
-
signature = raw ? normalizeGitRemoteUrl(raw) : null;
|
|
1913
|
-
} catch {
|
|
1914
|
-
}
|
|
1915
|
-
const input = signature ?? cwd;
|
|
1916
|
-
const key = createHash("sha1").update(input).digest("hex").slice(0, 16);
|
|
1917
|
-
return { key, project };
|
|
1918
|
-
}
|
|
1919
1966
|
function readState2(projectKey) {
|
|
1920
1967
|
migrateLegacyStateDir();
|
|
1921
1968
|
const p = statePath2(projectKey);
|
|
@@ -384,6 +384,7 @@ function loadConfig() {
|
|
|
384
384
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
385
385
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
386
386
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
387
|
+
codebaseTableName: process.env.HIVEMIND_CODEBASE_TABLE ?? "codebase",
|
|
387
388
|
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join3(home, ".deeplake", "memory")
|
|
388
389
|
};
|
|
389
390
|
}
|
|
@@ -489,9 +490,33 @@ function validateSchema(label, cols) {
|
|
|
489
490
|
}
|
|
490
491
|
}
|
|
491
492
|
}
|
|
493
|
+
var CODEBASE_COLUMNS = Object.freeze([
|
|
494
|
+
// Identity key (matches the PK below)
|
|
495
|
+
{ name: "org_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
496
|
+
{ name: "workspace_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
497
|
+
{ name: "repo_slug", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
498
|
+
{ name: "user_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
499
|
+
{ name: "worktree_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
500
|
+
{ name: "commit_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
501
|
+
// Observation metadata
|
|
502
|
+
{ name: "parent_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
503
|
+
{ name: "branch", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
504
|
+
{ name: "ts", sql: "TIMESTAMP" },
|
|
505
|
+
{ name: "pushed_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
506
|
+
// Snapshot payload
|
|
507
|
+
{ name: "snapshot_sha256", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
508
|
+
{ name: "snapshot_jsonb", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
509
|
+
{ name: "node_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
510
|
+
{ name: "edge_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
511
|
+
// Generator metadata (for drift diagnostics — what hivemind version produced this?)
|
|
512
|
+
{ name: "generator", sql: "TEXT NOT NULL DEFAULT 'hivemind-graph'" },
|
|
513
|
+
{ name: "generator_version", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
514
|
+
{ name: "schema_version", sql: "BIGINT NOT NULL DEFAULT 1" }
|
|
515
|
+
]);
|
|
492
516
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
493
517
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
494
518
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
519
|
+
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
495
520
|
function buildCreateTableSql(tableName, cols) {
|
|
496
521
|
const safe = sqlIdent(tableName);
|
|
497
522
|
const colSql = cols.map((c) => `${c.name} ${c.sql}`).join(", ");
|
|
@@ -1038,6 +1063,24 @@ var DeeplakeApi = class {
|
|
|
1038
1063
|
* This sidesteps the Deeplake UPDATE-coalescing quirk that bit the wiki
|
|
1039
1064
|
* worker.
|
|
1040
1065
|
*/
|
|
1066
|
+
/**
|
|
1067
|
+
* Create the codebase table. One row per (org, workspace, repo, user,
|
|
1068
|
+
* worktree, commit) — see CODEBASE_COLUMNS for the schema. Healing
|
|
1069
|
+
* + index follow the same pattern as ensureSessionsTable.
|
|
1070
|
+
*/
|
|
1071
|
+
async ensureCodebaseTable(name) {
|
|
1072
|
+
const safe = sqlIdent(name);
|
|
1073
|
+
const tables = await this.listTables();
|
|
1074
|
+
if (!tables.includes(safe)) {
|
|
1075
|
+
log3(`table "${safe}" not found, creating`);
|
|
1076
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, CODEBASE_COLUMNS), safe);
|
|
1077
|
+
log3(`table "${safe}" created`);
|
|
1078
|
+
if (!tables.includes(safe))
|
|
1079
|
+
this._tablesCache = [...tables, safe];
|
|
1080
|
+
}
|
|
1081
|
+
await this.healSchema(safe, CODEBASE_COLUMNS);
|
|
1082
|
+
await this.ensureLookupIndex(safe, "codebase_identity", `("org_id", "workspace_id", "repo_slug", "user_id", "worktree_id", "commit_sha")`);
|
|
1083
|
+
}
|
|
1041
1084
|
async ensureSkillsTable(name) {
|
|
1042
1085
|
const safe = sqlIdent(name);
|
|
1043
1086
|
const tables = await this.listTables();
|