@deeplake/hivemind 0.7.45 → 0.7.47
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/README.md +64 -0
- package/bundle/cli.js +22702 -7775
- package/codex/bundle/capture.js +228 -0
- package/codex/bundle/commands/auth-login.js +228 -0
- package/codex/bundle/graph-pull-worker.js +1370 -0
- package/codex/bundle/pre-tool-use.js +228 -0
- package/codex/bundle/session-start-setup.js +228 -0
- package/codex/bundle/session-start.js +255 -4
- package/codex/bundle/shell/deeplake-shell.js +1028 -28
- package/codex/bundle/skillify-worker.js +94 -3
- package/codex/bundle/stop.js +282 -50
- package/codex/skills/hivemind-goals/SKILL.md +157 -0
- package/cursor/bundle/capture.js +282 -50
- package/cursor/bundle/commands/auth-login.js +228 -0
- package/cursor/bundle/graph-pull-worker.js +1370 -0
- package/cursor/bundle/pre-tool-use.js +228 -0
- package/cursor/bundle/session-end.js +65 -44
- package/cursor/bundle/session-start.js +662 -6
- package/cursor/bundle/shell/deeplake-shell.js +1028 -28
- package/cursor/bundle/skillify-worker.js +94 -3
- package/hermes/bundle/capture.js +282 -50
- package/hermes/bundle/commands/auth-login.js +228 -0
- package/hermes/bundle/graph-pull-worker.js +1370 -0
- package/hermes/bundle/pre-tool-use.js +228 -0
- package/hermes/bundle/session-end.js +65 -44
- package/hermes/bundle/session-start.js +662 -6
- package/hermes/bundle/shell/deeplake-shell.js +1028 -28
- package/hermes/bundle/skillify-worker.js +94 -3
- package/mcp/bundle/server.js +228 -0
- package/openclaw/dist/chunks/config-FH6JYSJW.js +53 -0
- package/openclaw/dist/index.js +307 -2
- package/openclaw/dist/skillify-worker.js +94 -3
- package/openclaw/openclaw.plugin.json +4 -2
- package/openclaw/package.json +1 -1
- package/openclaw/skills/hivemind-goals/SKILL.md +30 -0
- package/package.json +4 -1
- package/openclaw/dist/chunks/config-XEK4MJJS.js +0 -36
|
@@ -97,6 +97,23 @@ 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
|
+
// Defaults match the table name written into the SQL — keep aligned
|
|
101
|
+
// with RULES_COLUMNS / TASKS_COLUMNS / TASK_EVENTS_COLUMNS in
|
|
102
|
+
// deeplake-schema.ts and with the e2e test-org override convention
|
|
103
|
+
// (memory_test / sessions_test → goals_test, etc.) documented in
|
|
104
|
+
// CLAUDE.md.
|
|
105
|
+
rulesTableName: process.env.HIVEMIND_RULES_TABLE ?? "hivemind_rules",
|
|
106
|
+
tasksTableName: process.env.HIVEMIND_TASKS_TABLE ?? "hivemind_tasks",
|
|
107
|
+
taskEventsTableName: process.env.HIVEMIND_TASK_EVENTS_TABLE ?? "hivemind_task_events",
|
|
108
|
+
// Goals + KPIs (refined design — VFS path classifier maps
|
|
109
|
+
// memory/goal/<user>/<status>/<uuid>.md → hivemind_goals row
|
|
110
|
+
// memory/kpi/<uuid>/<kpi_id>.md → hivemind_kpis row
|
|
111
|
+
// See src/shell/deeplake-fs.ts for the translation logic and
|
|
112
|
+
// GOALS_COLUMNS / KPIS_COLUMNS in deeplake-schema.ts for the
|
|
113
|
+
// table shape.
|
|
114
|
+
goalsTableName: process.env.HIVEMIND_GOALS_TABLE ?? "hivemind_goals",
|
|
115
|
+
kpisTableName: process.env.HIVEMIND_KPIS_TABLE ?? "hivemind_kpis",
|
|
116
|
+
codebaseTableName: process.env.HIVEMIND_CODEBASE_TABLE ?? "codebase",
|
|
100
117
|
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join(home, ".deeplake", "memory")
|
|
101
118
|
};
|
|
102
119
|
}
|
|
@@ -197,6 +214,65 @@ var SKILLS_COLUMNS = Object.freeze([
|
|
|
197
214
|
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
198
215
|
{ name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
199
216
|
]);
|
|
217
|
+
var RULES_COLUMNS = Object.freeze([
|
|
218
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
219
|
+
{ name: "rule_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
220
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
221
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'team'" },
|
|
222
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
223
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
224
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
225
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
226
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
227
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
228
|
+
]);
|
|
229
|
+
var TASKS_COLUMNS = Object.freeze([
|
|
230
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
231
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
232
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
233
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'me'" },
|
|
234
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
235
|
+
{ name: "assigned_to", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
236
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
237
|
+
{ name: "kpis", sql: "JSONB" },
|
|
238
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
239
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
240
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
241
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
242
|
+
]);
|
|
243
|
+
var TASK_EVENTS_COLUMNS = Object.freeze([
|
|
244
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
245
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
246
|
+
{ name: "task_version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
247
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
248
|
+
{ name: "value", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
249
|
+
{ name: "note", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
250
|
+
{ name: "source", sql: "TEXT NOT NULL DEFAULT 'user'" },
|
|
251
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
252
|
+
{ name: "ts", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
253
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
254
|
+
]);
|
|
255
|
+
var GOALS_COLUMNS = Object.freeze([
|
|
256
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
257
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
258
|
+
{ name: "owner", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
259
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'opened'" },
|
|
260
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
261
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
262
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
263
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
264
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
265
|
+
]);
|
|
266
|
+
var KPIS_COLUMNS = Object.freeze([
|
|
267
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
268
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
269
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
270
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
271
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
272
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
273
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
274
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
275
|
+
]);
|
|
200
276
|
function validateSchema(label, cols) {
|
|
201
277
|
const seen = /* @__PURE__ */ new Set();
|
|
202
278
|
for (const col of cols) {
|
|
@@ -214,9 +290,38 @@ function validateSchema(label, cols) {
|
|
|
214
290
|
}
|
|
215
291
|
}
|
|
216
292
|
}
|
|
293
|
+
var CODEBASE_COLUMNS = Object.freeze([
|
|
294
|
+
// Identity key (matches the PK below)
|
|
295
|
+
{ name: "org_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
296
|
+
{ name: "workspace_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
297
|
+
{ name: "repo_slug", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
298
|
+
{ name: "user_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
299
|
+
{ name: "worktree_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
300
|
+
{ name: "commit_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
301
|
+
// Observation metadata
|
|
302
|
+
{ name: "parent_sha", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
303
|
+
{ name: "branch", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
304
|
+
{ name: "ts", sql: "TIMESTAMP" },
|
|
305
|
+
{ name: "pushed_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
306
|
+
// Snapshot payload
|
|
307
|
+
{ name: "snapshot_sha256", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
308
|
+
{ name: "snapshot_jsonb", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
309
|
+
{ name: "node_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
310
|
+
{ name: "edge_count", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
311
|
+
// Generator metadata (for drift diagnostics — what hivemind version produced this?)
|
|
312
|
+
{ name: "generator", sql: "TEXT NOT NULL DEFAULT 'hivemind-graph'" },
|
|
313
|
+
{ name: "generator_version", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
314
|
+
{ name: "schema_version", sql: "BIGINT NOT NULL DEFAULT 1" }
|
|
315
|
+
]);
|
|
217
316
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
218
317
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
219
318
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
319
|
+
validateSchema("RULES_COLUMNS", RULES_COLUMNS);
|
|
320
|
+
validateSchema("TASKS_COLUMNS", TASKS_COLUMNS);
|
|
321
|
+
validateSchema("TASK_EVENTS_COLUMNS", TASK_EVENTS_COLUMNS);
|
|
322
|
+
validateSchema("GOALS_COLUMNS", GOALS_COLUMNS);
|
|
323
|
+
validateSchema("KPIS_COLUMNS", KPIS_COLUMNS);
|
|
324
|
+
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
220
325
|
function buildCreateTableSql(tableName, cols) {
|
|
221
326
|
const safe = sqlIdent(tableName);
|
|
222
327
|
const colSql = cols.map((c) => `${c.name} ${c.sql}`).join(", ");
|
|
@@ -781,6 +886,24 @@ var DeeplakeApi = class {
|
|
|
781
886
|
* This sidesteps the Deeplake UPDATE-coalescing quirk that bit the wiki
|
|
782
887
|
* worker.
|
|
783
888
|
*/
|
|
889
|
+
/**
|
|
890
|
+
* Create the codebase table. One row per (org, workspace, repo, user,
|
|
891
|
+
* worktree, commit) — see CODEBASE_COLUMNS for the schema. Healing
|
|
892
|
+
* + index follow the same pattern as ensureSessionsTable.
|
|
893
|
+
*/
|
|
894
|
+
async ensureCodebaseTable(name) {
|
|
895
|
+
const safe = sqlIdent(name);
|
|
896
|
+
const tables = await this.listTables();
|
|
897
|
+
if (!tables.includes(safe)) {
|
|
898
|
+
log3(`table "${safe}" not found, creating`);
|
|
899
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, CODEBASE_COLUMNS), safe);
|
|
900
|
+
log3(`table "${safe}" created`);
|
|
901
|
+
if (!tables.includes(safe))
|
|
902
|
+
this._tablesCache = [...tables, safe];
|
|
903
|
+
}
|
|
904
|
+
await this.healSchema(safe, CODEBASE_COLUMNS);
|
|
905
|
+
await this.ensureLookupIndex(safe, "codebase_identity", `("org_id", "workspace_id", "repo_slug", "user_id", "worktree_id", "commit_sha")`);
|
|
906
|
+
}
|
|
784
907
|
async ensureSkillsTable(name) {
|
|
785
908
|
const safe = sqlIdent(name);
|
|
786
909
|
const tables = await this.listTables();
|
|
@@ -794,6 +917,111 @@ var DeeplakeApi = class {
|
|
|
794
917
|
await this.healSchema(safe, SKILLS_COLUMNS);
|
|
795
918
|
await this.ensureLookupIndex(safe, "project_key_name", `("project_key", "name")`);
|
|
796
919
|
}
|
|
920
|
+
/**
|
|
921
|
+
* Create the rules table.
|
|
922
|
+
*
|
|
923
|
+
* One row per rule version (same write pattern as skills): edits INSERT
|
|
924
|
+
* a fresh row with version+1, reads pick latest per rule_id via
|
|
925
|
+
* `ORDER BY version DESC LIMIT 1`. Sidesteps the Deeplake
|
|
926
|
+
* UPDATE-coalescing quirk by never UPDATEing.
|
|
927
|
+
*/
|
|
928
|
+
async ensureRulesTable(name) {
|
|
929
|
+
const safe = sqlIdent(name);
|
|
930
|
+
const tables = await this.listTables();
|
|
931
|
+
if (!tables.includes(safe)) {
|
|
932
|
+
log3(`table "${safe}" not found, creating`);
|
|
933
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, RULES_COLUMNS), safe);
|
|
934
|
+
log3(`table "${safe}" created`);
|
|
935
|
+
if (!tables.includes(safe))
|
|
936
|
+
this._tablesCache = [...tables, safe];
|
|
937
|
+
}
|
|
938
|
+
await this.healSchema(safe, RULES_COLUMNS);
|
|
939
|
+
await this.ensureLookupIndex(safe, "rule_id_version", `("rule_id", "version")`);
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Create the tasks table.
|
|
943
|
+
*
|
|
944
|
+
* Same write pattern as rules + skills. `kpis` is a nullable JSONB
|
|
945
|
+
* column with the agent's KPI metadata; KPI current values come from
|
|
946
|
+
* `task_events` (SUM(value)), not this snapshot.
|
|
947
|
+
*/
|
|
948
|
+
async ensureTasksTable(name) {
|
|
949
|
+
const safe = sqlIdent(name);
|
|
950
|
+
const tables = await this.listTables();
|
|
951
|
+
if (!tables.includes(safe)) {
|
|
952
|
+
log3(`table "${safe}" not found, creating`);
|
|
953
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, TASKS_COLUMNS), safe);
|
|
954
|
+
log3(`table "${safe}" created`);
|
|
955
|
+
if (!tables.includes(safe))
|
|
956
|
+
this._tablesCache = [...tables, safe];
|
|
957
|
+
}
|
|
958
|
+
await this.healSchema(safe, TASKS_COLUMNS);
|
|
959
|
+
await this.ensureLookupIndex(safe, "task_id_version", `("task_id", "version")`);
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Create the task-events table.
|
|
963
|
+
*
|
|
964
|
+
* Append-only. Every INSERT is a fresh row; never UPDATE. KPI current
|
|
965
|
+
* value is `SUM(value) WHERE task_id=? AND kpi_id=?`. Index on
|
|
966
|
+
* (task_id, kpi_id) is the canonical aggregation key.
|
|
967
|
+
*/
|
|
968
|
+
async ensureTaskEventsTable(name) {
|
|
969
|
+
const safe = sqlIdent(name);
|
|
970
|
+
const tables = await this.listTables();
|
|
971
|
+
if (!tables.includes(safe)) {
|
|
972
|
+
log3(`table "${safe}" not found, creating`);
|
|
973
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, TASK_EVENTS_COLUMNS), safe);
|
|
974
|
+
log3(`table "${safe}" created`);
|
|
975
|
+
if (!tables.includes(safe))
|
|
976
|
+
this._tablesCache = [...tables, safe];
|
|
977
|
+
}
|
|
978
|
+
await this.healSchema(safe, TASK_EVENTS_COLUMNS);
|
|
979
|
+
await this.ensureLookupIndex(safe, "task_id_kpi_id", `("task_id", "kpi_id")`);
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Create the goals table.
|
|
983
|
+
*
|
|
984
|
+
* Backed by the VFS path convention memory/goal/<owner>/<status>/<goal_id>.md.
|
|
985
|
+
* INSERT-only version-bumped: rm and mv operations translate to fresh
|
|
986
|
+
* v=N+1 rows (status flips for mv → closed; rm is the same soft-close).
|
|
987
|
+
* The (goal_id, version) index lets the VFS dispatch a cheap latest-row
|
|
988
|
+
* read on cat / Read of a single goal.
|
|
989
|
+
*/
|
|
990
|
+
async ensureGoalsTable(name) {
|
|
991
|
+
const safe = sqlIdent(name);
|
|
992
|
+
const tables = await this.listTables();
|
|
993
|
+
if (!tables.includes(safe)) {
|
|
994
|
+
log3(`table "${safe}" not found, creating`);
|
|
995
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, GOALS_COLUMNS), safe);
|
|
996
|
+
log3(`table "${safe}" created`);
|
|
997
|
+
if (!tables.includes(safe))
|
|
998
|
+
this._tablesCache = [...tables, safe];
|
|
999
|
+
}
|
|
1000
|
+
await this.healSchema(safe, GOALS_COLUMNS);
|
|
1001
|
+
await this.ensureLookupIndex(safe, "goal_id_version", `("goal_id", "version")`);
|
|
1002
|
+
await this.ensureLookupIndex(safe, "owner_status", `("owner", "status")`);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Create the kpis table.
|
|
1006
|
+
*
|
|
1007
|
+
* Backed by memory/kpi/<goal_id>/<kpi_id>.md. KPI rows do NOT carry
|
|
1008
|
+
* owner — ownership derives from the parent goal via logical join on
|
|
1009
|
+
* goal_id. INSERT-only version-bumped. (goal_id, kpi_id) index is the
|
|
1010
|
+
* canonical lookup the VFS uses on Read and Write.
|
|
1011
|
+
*/
|
|
1012
|
+
async ensureKpisTable(name) {
|
|
1013
|
+
const safe = sqlIdent(name);
|
|
1014
|
+
const tables = await this.listTables();
|
|
1015
|
+
if (!tables.includes(safe)) {
|
|
1016
|
+
log3(`table "${safe}" not found, creating`);
|
|
1017
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, KPIS_COLUMNS), safe);
|
|
1018
|
+
log3(`table "${safe}" created`);
|
|
1019
|
+
if (!tables.includes(safe))
|
|
1020
|
+
this._tablesCache = [...tables, safe];
|
|
1021
|
+
}
|
|
1022
|
+
await this.healSchema(safe, KPIS_COLUMNS);
|
|
1023
|
+
await this.ensureLookupIndex(safe, "goal_id_kpi_id", `("goal_id", "kpi_id")`);
|
|
1024
|
+
}
|
|
797
1025
|
};
|
|
798
1026
|
|
|
799
1027
|
// dist/src/shell/grep-core.js
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
// dist/src/utils/stdin.js
|
|
4
4
|
function readStdin() {
|
|
5
|
-
return new Promise((
|
|
5
|
+
return new Promise((resolve2, reject) => {
|
|
6
6
|
let data = "";
|
|
7
7
|
process.stdin.setEncoding("utf-8");
|
|
8
8
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
9
9
|
process.stdin.on("end", () => {
|
|
10
10
|
try {
|
|
11
|
-
|
|
11
|
+
resolve2(JSON.parse(data));
|
|
12
12
|
} catch (err) {
|
|
13
13
|
reject(new Error(`Failed to parse hook input: ${err}`));
|
|
14
14
|
}
|
|
@@ -64,6 +64,23 @@ function loadConfig() {
|
|
|
64
64
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
65
65
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
66
66
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
67
|
+
// Defaults match the table name written into the SQL — keep aligned
|
|
68
|
+
// with RULES_COLUMNS / TASKS_COLUMNS / TASK_EVENTS_COLUMNS in
|
|
69
|
+
// deeplake-schema.ts and with the e2e test-org override convention
|
|
70
|
+
// (memory_test / sessions_test → goals_test, etc.) documented in
|
|
71
|
+
// CLAUDE.md.
|
|
72
|
+
rulesTableName: process.env.HIVEMIND_RULES_TABLE ?? "hivemind_rules",
|
|
73
|
+
tasksTableName: process.env.HIVEMIND_TASKS_TABLE ?? "hivemind_tasks",
|
|
74
|
+
taskEventsTableName: process.env.HIVEMIND_TASK_EVENTS_TABLE ?? "hivemind_task_events",
|
|
75
|
+
// Goals + KPIs (refined design — VFS path classifier maps
|
|
76
|
+
// memory/goal/<user>/<status>/<uuid>.md → hivemind_goals row
|
|
77
|
+
// memory/kpi/<uuid>/<kpi_id>.md → hivemind_kpis row
|
|
78
|
+
// See src/shell/deeplake-fs.ts for the translation logic and
|
|
79
|
+
// GOALS_COLUMNS / KPIS_COLUMNS in deeplake-schema.ts for the
|
|
80
|
+
// table shape.
|
|
81
|
+
goalsTableName: process.env.HIVEMIND_GOALS_TABLE ?? "hivemind_goals",
|
|
82
|
+
kpisTableName: process.env.HIVEMIND_KPIS_TABLE ?? "hivemind_kpis",
|
|
83
|
+
codebaseTableName: process.env.HIVEMIND_CODEBASE_TABLE ?? "codebase",
|
|
67
84
|
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join2(home, ".deeplake", "memory")
|
|
68
85
|
};
|
|
69
86
|
}
|
|
@@ -407,9 +424,54 @@ function spawnSkillifyWorker(opts) {
|
|
|
407
424
|
|
|
408
425
|
// dist/src/skillify/state.js
|
|
409
426
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, writeSync as writeSync2, mkdirSync as mkdirSync5, renameSync as renameSync3, rmdirSync, existsSync as existsSync5, lstatSync, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
|
|
427
|
+
import { join as join11 } from "node:path";
|
|
428
|
+
|
|
429
|
+
// dist/src/utils/repo-identity.js
|
|
410
430
|
import { execSync as execSync2 } from "node:child_process";
|
|
411
431
|
import { createHash } from "node:crypto";
|
|
412
|
-
import {
|
|
432
|
+
import { basename, resolve } from "node:path";
|
|
433
|
+
var DEFAULT_PORTS = {
|
|
434
|
+
http: "80",
|
|
435
|
+
https: "443",
|
|
436
|
+
ssh: "22",
|
|
437
|
+
git: "9418"
|
|
438
|
+
};
|
|
439
|
+
function normalizeGitRemoteUrl(url) {
|
|
440
|
+
let s = url.trim();
|
|
441
|
+
const schemeMatch = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
|
|
442
|
+
const scheme = schemeMatch ? schemeMatch[1].toLowerCase() : null;
|
|
443
|
+
if (schemeMatch)
|
|
444
|
+
s = s.slice(schemeMatch[0].length);
|
|
445
|
+
if (!scheme) {
|
|
446
|
+
const scp = s.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/);
|
|
447
|
+
if (scp)
|
|
448
|
+
s = `${scp[1]}/${scp[2]}`;
|
|
449
|
+
}
|
|
450
|
+
s = s.replace(/^[^@/]+@/, "");
|
|
451
|
+
if (scheme && DEFAULT_PORTS[scheme]) {
|
|
452
|
+
s = s.replace(new RegExp(`^([^/]+):${DEFAULT_PORTS[scheme]}(/|$)`), "$1$2");
|
|
453
|
+
}
|
|
454
|
+
s = s.replace(/\.git\/?$/i, "");
|
|
455
|
+
s = s.replace(/\/+$/, "");
|
|
456
|
+
return s.toLowerCase();
|
|
457
|
+
}
|
|
458
|
+
function deriveProjectKey(cwd) {
|
|
459
|
+
const absCwd = resolve(cwd);
|
|
460
|
+
const project = basename(absCwd) || "unknown";
|
|
461
|
+
let signature = null;
|
|
462
|
+
try {
|
|
463
|
+
const raw = execSync2("git config --get remote.origin.url", {
|
|
464
|
+
cwd: absCwd,
|
|
465
|
+
encoding: "utf-8",
|
|
466
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
467
|
+
}).trim();
|
|
468
|
+
signature = raw ? normalizeGitRemoteUrl(raw) : null;
|
|
469
|
+
} catch {
|
|
470
|
+
}
|
|
471
|
+
const input = signature ?? absCwd;
|
|
472
|
+
const key = createHash("sha1").update(input).digest("hex").slice(0, 16);
|
|
473
|
+
return { key, project };
|
|
474
|
+
}
|
|
413
475
|
|
|
414
476
|
// dist/src/skillify/legacy-migration.js
|
|
415
477
|
import { existsSync as existsSync4, renameSync as renameSync2 } from "node:fs";
|
|
@@ -464,47 +526,6 @@ function statePath(projectKey) {
|
|
|
464
526
|
function lockPath2(projectKey) {
|
|
465
527
|
return join11(getStateDir(), `${projectKey}.lock`);
|
|
466
528
|
}
|
|
467
|
-
var DEFAULT_PORTS = {
|
|
468
|
-
http: "80",
|
|
469
|
-
https: "443",
|
|
470
|
-
ssh: "22",
|
|
471
|
-
git: "9418"
|
|
472
|
-
};
|
|
473
|
-
function normalizeGitRemoteUrl(url) {
|
|
474
|
-
let s = url.trim();
|
|
475
|
-
const schemeMatch = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
|
|
476
|
-
const scheme = schemeMatch ? schemeMatch[1].toLowerCase() : null;
|
|
477
|
-
if (schemeMatch)
|
|
478
|
-
s = s.slice(schemeMatch[0].length);
|
|
479
|
-
if (!scheme) {
|
|
480
|
-
const scp = s.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/);
|
|
481
|
-
if (scp)
|
|
482
|
-
s = `${scp[1]}/${scp[2]}`;
|
|
483
|
-
}
|
|
484
|
-
s = s.replace(/^[^@/]+@/, "");
|
|
485
|
-
if (scheme && DEFAULT_PORTS[scheme]) {
|
|
486
|
-
s = s.replace(new RegExp(`^([^/]+):${DEFAULT_PORTS[scheme]}(/|$)`), "$1$2");
|
|
487
|
-
}
|
|
488
|
-
s = s.replace(/\.git\/?$/i, "");
|
|
489
|
-
s = s.replace(/\/+$/, "");
|
|
490
|
-
return s.toLowerCase();
|
|
491
|
-
}
|
|
492
|
-
function deriveProjectKey(cwd) {
|
|
493
|
-
const project = basename(cwd) || "unknown";
|
|
494
|
-
let signature = null;
|
|
495
|
-
try {
|
|
496
|
-
const raw = execSync2("git config --get remote.origin.url", {
|
|
497
|
-
cwd,
|
|
498
|
-
encoding: "utf-8",
|
|
499
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
500
|
-
}).trim();
|
|
501
|
-
signature = raw ? normalizeGitRemoteUrl(raw) : null;
|
|
502
|
-
} catch {
|
|
503
|
-
}
|
|
504
|
-
const input = signature ?? cwd;
|
|
505
|
-
const key = createHash("sha1").update(input).digest("hex").slice(0, 16);
|
|
506
|
-
return { key, project };
|
|
507
|
-
}
|
|
508
529
|
function readState(projectKey) {
|
|
509
530
|
migrateLegacyStateDir();
|
|
510
531
|
const p = statePath(projectKey);
|