@deeplake/hivemind 0.7.46 → 0.7.48
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 +17288 -4219
- package/codex/bundle/capture.js +185 -0
- package/codex/bundle/commands/auth-login.js +185 -0
- package/codex/bundle/graph-pull-worker.js +185 -0
- package/codex/bundle/pre-tool-use.js +185 -0
- package/codex/bundle/session-start-setup.js +185 -0
- package/codex/bundle/session-start.js +185 -0
- package/codex/bundle/shell/deeplake-shell.js +451 -3
- package/codex/bundle/skillify-worker.js +64 -0
- package/codex/bundle/stop.js +185 -0
- package/codex/skills/hivemind-goals/SKILL.md +157 -0
- package/cursor/bundle/capture.js +185 -0
- package/cursor/bundle/commands/auth-login.js +185 -0
- package/cursor/bundle/graph-pull-worker.js +185 -0
- package/cursor/bundle/pre-tool-use.js +185 -0
- package/cursor/bundle/session-end.js +16 -0
- package/cursor/bundle/session-start.js +596 -6
- package/cursor/bundle/shell/deeplake-shell.js +451 -3
- package/cursor/bundle/skillify-worker.js +64 -0
- package/hermes/bundle/capture.js +185 -0
- package/hermes/bundle/commands/auth-login.js +185 -0
- package/hermes/bundle/graph-pull-worker.js +185 -0
- package/hermes/bundle/pre-tool-use.js +185 -0
- package/hermes/bundle/session-end.js +16 -0
- package/hermes/bundle/session-start.js +596 -6
- package/hermes/bundle/shell/deeplake-shell.js +451 -3
- package/hermes/bundle/skillify-worker.js +64 -0
- package/mcp/bundle/server.js +185 -0
- package/openclaw/dist/chunks/{config-O5PDJQ7Y.js → config-FH6JYSJW.js} +16 -0
- package/openclaw/dist/index.js +262 -2
- package/openclaw/dist/skillify-worker.js +64 -0
- 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 +2 -1
|
@@ -66792,6 +66792,22 @@ function loadConfig() {
|
|
|
66792
66792
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
66793
66793
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
66794
66794
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
66795
|
+
// Defaults match the table name written into the SQL — keep aligned
|
|
66796
|
+
// with RULES_COLUMNS / TASKS_COLUMNS / TASK_EVENTS_COLUMNS in
|
|
66797
|
+
// deeplake-schema.ts and with the e2e test-org override convention
|
|
66798
|
+
// (memory_test / sessions_test → goals_test, etc.) documented in
|
|
66799
|
+
// CLAUDE.md.
|
|
66800
|
+
rulesTableName: process.env.HIVEMIND_RULES_TABLE ?? "hivemind_rules",
|
|
66801
|
+
tasksTableName: process.env.HIVEMIND_TASKS_TABLE ?? "hivemind_tasks",
|
|
66802
|
+
taskEventsTableName: process.env.HIVEMIND_TASK_EVENTS_TABLE ?? "hivemind_task_events",
|
|
66803
|
+
// Goals + KPIs (refined design — VFS path classifier maps
|
|
66804
|
+
// memory/goal/<user>/<status>/<uuid>.md → hivemind_goals row
|
|
66805
|
+
// memory/kpi/<uuid>/<kpi_id>.md → hivemind_kpis row
|
|
66806
|
+
// See src/shell/deeplake-fs.ts for the translation logic and
|
|
66807
|
+
// GOALS_COLUMNS / KPIS_COLUMNS in deeplake-schema.ts for the
|
|
66808
|
+
// table shape.
|
|
66809
|
+
goalsTableName: process.env.HIVEMIND_GOALS_TABLE ?? "hivemind_goals",
|
|
66810
|
+
kpisTableName: process.env.HIVEMIND_KPIS_TABLE ?? "hivemind_kpis",
|
|
66795
66811
|
codebaseTableName: process.env.HIVEMIND_CODEBASE_TABLE ?? "codebase",
|
|
66796
66812
|
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join4(home, ".deeplake", "memory")
|
|
66797
66813
|
};
|
|
@@ -66893,6 +66909,65 @@ var SKILLS_COLUMNS = Object.freeze([
|
|
|
66893
66909
|
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66894
66910
|
{ name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66895
66911
|
]);
|
|
66912
|
+
var RULES_COLUMNS = Object.freeze([
|
|
66913
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66914
|
+
{ name: "rule_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66915
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66916
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'team'" },
|
|
66917
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
66918
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66919
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
66920
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66921
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
66922
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66923
|
+
]);
|
|
66924
|
+
var TASKS_COLUMNS = Object.freeze([
|
|
66925
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66926
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66927
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66928
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'me'" },
|
|
66929
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
66930
|
+
{ name: "assigned_to", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66931
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66932
|
+
{ name: "kpis", sql: "JSONB" },
|
|
66933
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
66934
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66935
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
66936
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66937
|
+
]);
|
|
66938
|
+
var TASK_EVENTS_COLUMNS = Object.freeze([
|
|
66939
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66940
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66941
|
+
{ name: "task_version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
66942
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66943
|
+
{ name: "value", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
66944
|
+
{ name: "note", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66945
|
+
{ name: "source", sql: "TEXT NOT NULL DEFAULT 'user'" },
|
|
66946
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66947
|
+
{ name: "ts", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66948
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66949
|
+
]);
|
|
66950
|
+
var GOALS_COLUMNS = Object.freeze([
|
|
66951
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66952
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66953
|
+
{ name: "owner", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66954
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'opened'" },
|
|
66955
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66956
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
66957
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66958
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
66959
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66960
|
+
]);
|
|
66961
|
+
var KPIS_COLUMNS = Object.freeze([
|
|
66962
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66963
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66964
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66965
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66966
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
66967
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
66968
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
66969
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
66970
|
+
]);
|
|
66896
66971
|
function validateSchema(label, cols) {
|
|
66897
66972
|
const seen = /* @__PURE__ */ new Set();
|
|
66898
66973
|
for (const col of cols) {
|
|
@@ -66936,6 +67011,11 @@ var CODEBASE_COLUMNS = Object.freeze([
|
|
|
66936
67011
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
66937
67012
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
66938
67013
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
67014
|
+
validateSchema("RULES_COLUMNS", RULES_COLUMNS);
|
|
67015
|
+
validateSchema("TASKS_COLUMNS", TASKS_COLUMNS);
|
|
67016
|
+
validateSchema("TASK_EVENTS_COLUMNS", TASK_EVENTS_COLUMNS);
|
|
67017
|
+
validateSchema("GOALS_COLUMNS", GOALS_COLUMNS);
|
|
67018
|
+
validateSchema("KPIS_COLUMNS", KPIS_COLUMNS);
|
|
66939
67019
|
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
66940
67020
|
function buildCreateTableSql(tableName, cols) {
|
|
66941
67021
|
const safe = sqlIdent(tableName);
|
|
@@ -67532,6 +67612,111 @@ var DeeplakeApi = class {
|
|
|
67532
67612
|
await this.healSchema(safe, SKILLS_COLUMNS);
|
|
67533
67613
|
await this.ensureLookupIndex(safe, "project_key_name", `("project_key", "name")`);
|
|
67534
67614
|
}
|
|
67615
|
+
/**
|
|
67616
|
+
* Create the rules table.
|
|
67617
|
+
*
|
|
67618
|
+
* One row per rule version (same write pattern as skills): edits INSERT
|
|
67619
|
+
* a fresh row with version+1, reads pick latest per rule_id via
|
|
67620
|
+
* `ORDER BY version DESC LIMIT 1`. Sidesteps the Deeplake
|
|
67621
|
+
* UPDATE-coalescing quirk by never UPDATEing.
|
|
67622
|
+
*/
|
|
67623
|
+
async ensureRulesTable(name) {
|
|
67624
|
+
const safe = sqlIdent(name);
|
|
67625
|
+
const tables = await this.listTables();
|
|
67626
|
+
if (!tables.includes(safe)) {
|
|
67627
|
+
log3(`table "${safe}" not found, creating`);
|
|
67628
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, RULES_COLUMNS), safe);
|
|
67629
|
+
log3(`table "${safe}" created`);
|
|
67630
|
+
if (!tables.includes(safe))
|
|
67631
|
+
this._tablesCache = [...tables, safe];
|
|
67632
|
+
}
|
|
67633
|
+
await this.healSchema(safe, RULES_COLUMNS);
|
|
67634
|
+
await this.ensureLookupIndex(safe, "rule_id_version", `("rule_id", "version")`);
|
|
67635
|
+
}
|
|
67636
|
+
/**
|
|
67637
|
+
* Create the tasks table.
|
|
67638
|
+
*
|
|
67639
|
+
* Same write pattern as rules + skills. `kpis` is a nullable JSONB
|
|
67640
|
+
* column with the agent's KPI metadata; KPI current values come from
|
|
67641
|
+
* `task_events` (SUM(value)), not this snapshot.
|
|
67642
|
+
*/
|
|
67643
|
+
async ensureTasksTable(name) {
|
|
67644
|
+
const safe = sqlIdent(name);
|
|
67645
|
+
const tables = await this.listTables();
|
|
67646
|
+
if (!tables.includes(safe)) {
|
|
67647
|
+
log3(`table "${safe}" not found, creating`);
|
|
67648
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, TASKS_COLUMNS), safe);
|
|
67649
|
+
log3(`table "${safe}" created`);
|
|
67650
|
+
if (!tables.includes(safe))
|
|
67651
|
+
this._tablesCache = [...tables, safe];
|
|
67652
|
+
}
|
|
67653
|
+
await this.healSchema(safe, TASKS_COLUMNS);
|
|
67654
|
+
await this.ensureLookupIndex(safe, "task_id_version", `("task_id", "version")`);
|
|
67655
|
+
}
|
|
67656
|
+
/**
|
|
67657
|
+
* Create the task-events table.
|
|
67658
|
+
*
|
|
67659
|
+
* Append-only. Every INSERT is a fresh row; never UPDATE. KPI current
|
|
67660
|
+
* value is `SUM(value) WHERE task_id=? AND kpi_id=?`. Index on
|
|
67661
|
+
* (task_id, kpi_id) is the canonical aggregation key.
|
|
67662
|
+
*/
|
|
67663
|
+
async ensureTaskEventsTable(name) {
|
|
67664
|
+
const safe = sqlIdent(name);
|
|
67665
|
+
const tables = await this.listTables();
|
|
67666
|
+
if (!tables.includes(safe)) {
|
|
67667
|
+
log3(`table "${safe}" not found, creating`);
|
|
67668
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, TASK_EVENTS_COLUMNS), safe);
|
|
67669
|
+
log3(`table "${safe}" created`);
|
|
67670
|
+
if (!tables.includes(safe))
|
|
67671
|
+
this._tablesCache = [...tables, safe];
|
|
67672
|
+
}
|
|
67673
|
+
await this.healSchema(safe, TASK_EVENTS_COLUMNS);
|
|
67674
|
+
await this.ensureLookupIndex(safe, "task_id_kpi_id", `("task_id", "kpi_id")`);
|
|
67675
|
+
}
|
|
67676
|
+
/**
|
|
67677
|
+
* Create the goals table.
|
|
67678
|
+
*
|
|
67679
|
+
* Backed by the VFS path convention memory/goal/<owner>/<status>/<goal_id>.md.
|
|
67680
|
+
* INSERT-only version-bumped: rm and mv operations translate to fresh
|
|
67681
|
+
* v=N+1 rows (status flips for mv → closed; rm is the same soft-close).
|
|
67682
|
+
* The (goal_id, version) index lets the VFS dispatch a cheap latest-row
|
|
67683
|
+
* read on cat / Read of a single goal.
|
|
67684
|
+
*/
|
|
67685
|
+
async ensureGoalsTable(name) {
|
|
67686
|
+
const safe = sqlIdent(name);
|
|
67687
|
+
const tables = await this.listTables();
|
|
67688
|
+
if (!tables.includes(safe)) {
|
|
67689
|
+
log3(`table "${safe}" not found, creating`);
|
|
67690
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, GOALS_COLUMNS), safe);
|
|
67691
|
+
log3(`table "${safe}" created`);
|
|
67692
|
+
if (!tables.includes(safe))
|
|
67693
|
+
this._tablesCache = [...tables, safe];
|
|
67694
|
+
}
|
|
67695
|
+
await this.healSchema(safe, GOALS_COLUMNS);
|
|
67696
|
+
await this.ensureLookupIndex(safe, "goal_id_version", `("goal_id", "version")`);
|
|
67697
|
+
await this.ensureLookupIndex(safe, "owner_status", `("owner", "status")`);
|
|
67698
|
+
}
|
|
67699
|
+
/**
|
|
67700
|
+
* Create the kpis table.
|
|
67701
|
+
*
|
|
67702
|
+
* Backed by memory/kpi/<goal_id>/<kpi_id>.md. KPI rows do NOT carry
|
|
67703
|
+
* owner — ownership derives from the parent goal via logical join on
|
|
67704
|
+
* goal_id. INSERT-only version-bumped. (goal_id, kpi_id) index is the
|
|
67705
|
+
* canonical lookup the VFS uses on Read and Write.
|
|
67706
|
+
*/
|
|
67707
|
+
async ensureKpisTable(name) {
|
|
67708
|
+
const safe = sqlIdent(name);
|
|
67709
|
+
const tables = await this.listTables();
|
|
67710
|
+
if (!tables.includes(safe)) {
|
|
67711
|
+
log3(`table "${safe}" not found, creating`);
|
|
67712
|
+
await this.createTableWithRetry(buildCreateTableSql(safe, KPIS_COLUMNS), safe);
|
|
67713
|
+
log3(`table "${safe}" created`);
|
|
67714
|
+
if (!tables.includes(safe))
|
|
67715
|
+
this._tablesCache = [...tables, safe];
|
|
67716
|
+
}
|
|
67717
|
+
await this.healSchema(safe, KPIS_COLUMNS);
|
|
67718
|
+
await this.ensureLookupIndex(safe, "goal_id_kpi_id", `("goal_id", "kpi_id")`);
|
|
67719
|
+
}
|
|
67535
67720
|
};
|
|
67536
67721
|
|
|
67537
67722
|
// dist/src/shell/deeplake-fs.js
|
|
@@ -68544,6 +68729,82 @@ function buildVirtualIndexContent(summaryRows, sessionRows = [], opts = {}) {
|
|
|
68544
68729
|
return lines.join("\n");
|
|
68545
68730
|
}
|
|
68546
68731
|
|
|
68732
|
+
// dist/src/shell/goal-paths.js
|
|
68733
|
+
var VALID_STATUS = /* @__PURE__ */ new Set(["opened", "in_progress", "closed"]);
|
|
68734
|
+
function segmentsUnderMemory(p22) {
|
|
68735
|
+
let s10 = p22.replace(/\/+$/, "");
|
|
68736
|
+
const memIdx = s10.lastIndexOf("/memory/");
|
|
68737
|
+
if (memIdx >= 0) {
|
|
68738
|
+
s10 = s10.slice(memIdx + "/memory/".length);
|
|
68739
|
+
} else {
|
|
68740
|
+
s10 = s10.replace(/^\/+/, "");
|
|
68741
|
+
if (s10 === "memory")
|
|
68742
|
+
return null;
|
|
68743
|
+
if (s10.startsWith("memory/"))
|
|
68744
|
+
s10 = s10.slice("memory/".length);
|
|
68745
|
+
}
|
|
68746
|
+
if (s10.length === 0)
|
|
68747
|
+
return null;
|
|
68748
|
+
return s10.split("/");
|
|
68749
|
+
}
|
|
68750
|
+
function classifyPath(p22) {
|
|
68751
|
+
const segs = segmentsUnderMemory(p22);
|
|
68752
|
+
if (!segs)
|
|
68753
|
+
return "memory";
|
|
68754
|
+
if (segs[0] === "goal") {
|
|
68755
|
+
if (segs.length === 4 && segs[3].endsWith(".md") && VALID_STATUS.has(segs[2])) {
|
|
68756
|
+
return "goal";
|
|
68757
|
+
}
|
|
68758
|
+
return "memory";
|
|
68759
|
+
}
|
|
68760
|
+
if (segs[0] === "kpi") {
|
|
68761
|
+
if (segs.length === 3 && segs[2].endsWith(".md")) {
|
|
68762
|
+
return "kpi";
|
|
68763
|
+
}
|
|
68764
|
+
return "memory";
|
|
68765
|
+
}
|
|
68766
|
+
return "memory";
|
|
68767
|
+
}
|
|
68768
|
+
function decomposeGoalPath(p22) {
|
|
68769
|
+
const segs = segmentsUnderMemory(p22);
|
|
68770
|
+
if (!segs || segs.length !== 4 || segs[0] !== "goal") {
|
|
68771
|
+
throw new Error(`Not a goal path: ${p22}`);
|
|
68772
|
+
}
|
|
68773
|
+
const status = segs[2];
|
|
68774
|
+
if (!VALID_STATUS.has(status)) {
|
|
68775
|
+
throw new Error(`Invalid goal status in path: ${p22} (got '${status}')`);
|
|
68776
|
+
}
|
|
68777
|
+
const filename = segs[3];
|
|
68778
|
+
if (!filename.endsWith(".md")) {
|
|
68779
|
+
throw new Error(`Goal path must end with .md: ${p22}`);
|
|
68780
|
+
}
|
|
68781
|
+
return {
|
|
68782
|
+
owner: segs[1],
|
|
68783
|
+
status,
|
|
68784
|
+
goal_id: filename.slice(0, -".md".length)
|
|
68785
|
+
};
|
|
68786
|
+
}
|
|
68787
|
+
function decomposeKpiPath(p22) {
|
|
68788
|
+
const segs = segmentsUnderMemory(p22);
|
|
68789
|
+
if (!segs || segs.length !== 3 || segs[0] !== "kpi") {
|
|
68790
|
+
throw new Error(`Not a kpi path: ${p22}`);
|
|
68791
|
+
}
|
|
68792
|
+
const filename = segs[2];
|
|
68793
|
+
if (!filename.endsWith(".md")) {
|
|
68794
|
+
throw new Error(`KPI path must end with .md: ${p22}`);
|
|
68795
|
+
}
|
|
68796
|
+
return {
|
|
68797
|
+
goal_id: segs[1],
|
|
68798
|
+
kpi_id: filename.slice(0, -".md".length)
|
|
68799
|
+
};
|
|
68800
|
+
}
|
|
68801
|
+
function composeGoalPath(parts) {
|
|
68802
|
+
return `/goal/${parts.owner}/${parts.status}/${parts.goal_id}.md`;
|
|
68803
|
+
}
|
|
68804
|
+
function composeKpiPath(parts) {
|
|
68805
|
+
return `/kpi/${parts.goal_id}/${parts.kpi_id}.md`;
|
|
68806
|
+
}
|
|
68807
|
+
|
|
68547
68808
|
// dist/src/graph/vfs-handler.js
|
|
68548
68809
|
import { existsSync as existsSync8, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
68549
68810
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -69061,6 +69322,12 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69061
69322
|
// Paths that live in the sessions table (multi-row, read by concatenation)
|
|
69062
69323
|
sessionPaths = /* @__PURE__ */ new Set();
|
|
69063
69324
|
sessionsTable = null;
|
|
69325
|
+
// Path-routed structured tables. When non-null, the VFS classifies
|
|
69326
|
+
// each path (see ./goal-paths.ts) and dispatches reads/writes to
|
|
69327
|
+
// the right table instead of the generic memory table. Null means
|
|
69328
|
+
// the goal/kpi routing is disabled (test or legacy configurations).
|
|
69329
|
+
goalsTable = null;
|
|
69330
|
+
kpisTable = null;
|
|
69064
69331
|
// Embedding client lazily created on first flush. Lives as long as the process.
|
|
69065
69332
|
embedClient = null;
|
|
69066
69333
|
constructor(client, table, mountPoint) {
|
|
@@ -69071,10 +69338,24 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69071
69338
|
if (mountPoint !== "/")
|
|
69072
69339
|
this.dirs.set("/", /* @__PURE__ */ new Set([mountPoint.slice(1)]));
|
|
69073
69340
|
}
|
|
69074
|
-
static async create(client, table, mount = "/memory", sessionsTable) {
|
|
69341
|
+
static async create(client, table, mount = "/memory", sessionsTable, extra) {
|
|
69075
69342
|
const fs3 = new _DeeplakeFs(client, table, mount);
|
|
69076
69343
|
fs3.sessionsTable = sessionsTable ?? null;
|
|
69344
|
+
fs3.goalsTable = extra?.goalsTable ?? null;
|
|
69345
|
+
fs3.kpisTable = extra?.kpisTable ?? null;
|
|
69077
69346
|
await client.ensureTable();
|
|
69347
|
+
if (fs3.goalsTable) {
|
|
69348
|
+
try {
|
|
69349
|
+
await client.ensureGoalsTable(fs3.goalsTable);
|
|
69350
|
+
} catch {
|
|
69351
|
+
}
|
|
69352
|
+
}
|
|
69353
|
+
if (fs3.kpisTable) {
|
|
69354
|
+
try {
|
|
69355
|
+
await client.ensureKpisTable(fs3.kpisTable);
|
|
69356
|
+
} catch {
|
|
69357
|
+
}
|
|
69358
|
+
}
|
|
69078
69359
|
let sessionSyncOk = true;
|
|
69079
69360
|
const memoryBootstrap = (async () => {
|
|
69080
69361
|
const sql = `SELECT path, size_bytes, mime_type FROM "${table}" ORDER BY path`;
|
|
@@ -69120,7 +69401,61 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69120
69401
|
} catch {
|
|
69121
69402
|
}
|
|
69122
69403
|
})() : Promise.resolve();
|
|
69123
|
-
|
|
69404
|
+
const goalsBootstrap = fs3.goalsTable ? (async () => {
|
|
69405
|
+
try {
|
|
69406
|
+
const goalRows = await client.query(
|
|
69407
|
+
// One row per goal_id (UPDATE-or-INSERT model). Synthesize
|
|
69408
|
+
// the canonical VFS path from owner / status / goal_id.
|
|
69409
|
+
`SELECT goal_id, owner, status, content, created_at FROM "${fs3.goalsTable}" ORDER BY created_at DESC`
|
|
69410
|
+
);
|
|
69411
|
+
for (const row of goalRows) {
|
|
69412
|
+
const owner = String(row["owner"] ?? "");
|
|
69413
|
+
const status = String(row["status"] ?? "");
|
|
69414
|
+
const goal_id = String(row["goal_id"] ?? "");
|
|
69415
|
+
if (!owner || !status || !goal_id)
|
|
69416
|
+
continue;
|
|
69417
|
+
if (status !== "opened" && status !== "in_progress" && status !== "closed")
|
|
69418
|
+
continue;
|
|
69419
|
+
const p22 = composeGoalPath({ owner, status, goal_id });
|
|
69420
|
+
const content = String(row["content"] ?? "");
|
|
69421
|
+
fs3.files.set(p22, Buffer.from(content, "utf-8"));
|
|
69422
|
+
fs3.meta.set(p22, {
|
|
69423
|
+
size: Buffer.byteLength(content, "utf-8"),
|
|
69424
|
+
mime: "text/markdown",
|
|
69425
|
+
mtime: /* @__PURE__ */ new Date()
|
|
69426
|
+
});
|
|
69427
|
+
fs3.addToTree(p22);
|
|
69428
|
+
fs3.flushed.add(p22);
|
|
69429
|
+
}
|
|
69430
|
+
} catch {
|
|
69431
|
+
}
|
|
69432
|
+
})() : Promise.resolve();
|
|
69433
|
+
const kpisBootstrap = fs3.kpisTable ? (async () => {
|
|
69434
|
+
try {
|
|
69435
|
+
const kpiRows = await client.query(
|
|
69436
|
+
// One row per (goal_id, kpi_id) (UPDATE-or-INSERT model).
|
|
69437
|
+
`SELECT goal_id, kpi_id, content, created_at FROM "${fs3.kpisTable}" ORDER BY created_at DESC`
|
|
69438
|
+
);
|
|
69439
|
+
for (const row of kpiRows) {
|
|
69440
|
+
const goal_id = String(row["goal_id"] ?? "");
|
|
69441
|
+
const kpi_id = String(row["kpi_id"] ?? "");
|
|
69442
|
+
if (!goal_id || !kpi_id)
|
|
69443
|
+
continue;
|
|
69444
|
+
const p22 = composeKpiPath({ goal_id, kpi_id });
|
|
69445
|
+
const content = String(row["content"] ?? "");
|
|
69446
|
+
fs3.files.set(p22, Buffer.from(content, "utf-8"));
|
|
69447
|
+
fs3.meta.set(p22, {
|
|
69448
|
+
size: Buffer.byteLength(content, "utf-8"),
|
|
69449
|
+
mime: "text/markdown",
|
|
69450
|
+
mtime: /* @__PURE__ */ new Date()
|
|
69451
|
+
});
|
|
69452
|
+
fs3.addToTree(p22);
|
|
69453
|
+
fs3.flushed.add(p22);
|
|
69454
|
+
}
|
|
69455
|
+
} catch {
|
|
69456
|
+
}
|
|
69457
|
+
})() : Promise.resolve();
|
|
69458
|
+
await Promise.all([memoryBootstrap, sessionsBootstrap, goalsBootstrap, kpisBootstrap]);
|
|
69124
69459
|
return fs3;
|
|
69125
69460
|
}
|
|
69126
69461
|
// ── tree management ───────────────────────────────────────────────────────
|
|
@@ -69189,6 +69524,15 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69189
69524
|
return Promise.all(rows.map((r10) => this.embedClient.embed(r10.contentText, "document")));
|
|
69190
69525
|
}
|
|
69191
69526
|
async upsertRow(r10, embedding) {
|
|
69527
|
+
const kind = classifyPath(r10.path);
|
|
69528
|
+
if (kind === "goal" && this.goalsTable) {
|
|
69529
|
+
await this.upsertGoalRow(r10);
|
|
69530
|
+
return;
|
|
69531
|
+
}
|
|
69532
|
+
if (kind === "kpi" && this.kpisTable) {
|
|
69533
|
+
await this.upsertKpiRow(r10);
|
|
69534
|
+
return;
|
|
69535
|
+
}
|
|
69192
69536
|
const text = sqlStr(r10.contentText);
|
|
69193
69537
|
const p22 = sqlStr(r10.path);
|
|
69194
69538
|
const fname = sqlStr(r10.filename);
|
|
@@ -69212,6 +69556,57 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69212
69556
|
this.flushed.add(r10.path);
|
|
69213
69557
|
}
|
|
69214
69558
|
}
|
|
69559
|
+
/**
|
|
69560
|
+
* UPDATE-or-INSERT for a goal row, keyed by goal_id. One row per
|
|
69561
|
+
* goal forever — status changes, owner reassignments, and text
|
|
69562
|
+
* edits all mutate the same row in place. The version column
|
|
69563
|
+
* stays at 1 (vestigial in the schema; kept so the column is
|
|
69564
|
+
* already there if we ever bring back the audit-trail pattern).
|
|
69565
|
+
*
|
|
69566
|
+
* Trade-off versus the prior INSERT-only-version-bump design:
|
|
69567
|
+
* - Pros: 1 row per goal makes the Deeplake table view obvious,
|
|
69568
|
+
* no row proliferation, simpler bootstrap queries.
|
|
69569
|
+
* - Cons: no audit trail; vulnerable to Deeplake's
|
|
69570
|
+
* UPDATE-coalescing quirk if two writes hit the same row
|
|
69571
|
+
* within microseconds. For the v1 single-user / small-team
|
|
69572
|
+
* workflow the user explicitly chose this trade-off.
|
|
69573
|
+
*/
|
|
69574
|
+
async upsertGoalRow(r10) {
|
|
69575
|
+
if (!this.goalsTable)
|
|
69576
|
+
throw new Error("goalsTable not configured");
|
|
69577
|
+
const parts = decomposeGoalPath(r10.path);
|
|
69578
|
+
const safe = this.goalsTable;
|
|
69579
|
+
const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
69580
|
+
const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' LIMIT 1`);
|
|
69581
|
+
if (existing.length > 0) {
|
|
69582
|
+
await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
|
|
69583
|
+
} else {
|
|
69584
|
+
const id = randomUUID2();
|
|
69585
|
+
await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
|
|
69586
|
+
}
|
|
69587
|
+
this.flushed.add(r10.path);
|
|
69588
|
+
}
|
|
69589
|
+
/**
|
|
69590
|
+
* UPDATE-or-INSERT for a KPI row, keyed by (goal_id, kpi_id).
|
|
69591
|
+
* Same trade-off as upsertGoalRow — one row per KPI forever,
|
|
69592
|
+
* no version proliferation. Progress bumps (Edit on the `current:`
|
|
69593
|
+
* line) and any other content edits mutate the same row in place.
|
|
69594
|
+
*/
|
|
69595
|
+
async upsertKpiRow(r10) {
|
|
69596
|
+
if (!this.kpisTable)
|
|
69597
|
+
throw new Error("kpisTable not configured");
|
|
69598
|
+
const parts = decomposeKpiPath(r10.path);
|
|
69599
|
+
const safe = this.kpisTable;
|
|
69600
|
+
const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
69601
|
+
const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}' LIMIT 1`);
|
|
69602
|
+
if (existing.length > 0) {
|
|
69603
|
+
await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
|
|
69604
|
+
} else {
|
|
69605
|
+
const id = randomUUID2();
|
|
69606
|
+
await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
|
|
69607
|
+
}
|
|
69608
|
+
this.flushed.add(r10.path);
|
|
69609
|
+
}
|
|
69215
69610
|
// ── Virtual index.md generation ────────────────────────────────────────────
|
|
69216
69611
|
async generateVirtualIndex() {
|
|
69217
69612
|
const fetchLimit = INDEX_LIMIT_PER_SECTION + 1;
|
|
@@ -69583,6 +69978,31 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69583
69978
|
return;
|
|
69584
69979
|
throw fsErr("ENOENT", "no such file or directory", p22);
|
|
69585
69980
|
}
|
|
69981
|
+
if (this.goalsTable && classifyPath(p22) === "goal") {
|
|
69982
|
+
const parts = decomposeGoalPath(p22);
|
|
69983
|
+
if (parts.status === "closed") {
|
|
69984
|
+
this.removeFromTree(p22);
|
|
69985
|
+
return;
|
|
69986
|
+
}
|
|
69987
|
+
const closedPath = composeGoalPath({ ...parts, status: "closed" });
|
|
69988
|
+
const contentBuf = this.files.get(p22);
|
|
69989
|
+
const content = contentBuf instanceof Buffer ? contentBuf.toString("utf-8") : "";
|
|
69990
|
+
await this.upsertGoalRow({
|
|
69991
|
+
path: closedPath,
|
|
69992
|
+
filename: basename5(closedPath),
|
|
69993
|
+
contentText: content,
|
|
69994
|
+
mimeType: "text/markdown",
|
|
69995
|
+
sizeBytes: Buffer.byteLength(content, "utf-8"),
|
|
69996
|
+
creationDate: void 0,
|
|
69997
|
+
lastUpdateDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
69998
|
+
});
|
|
69999
|
+
this.files.set(closedPath, contentBuf ?? null);
|
|
70000
|
+
this.meta.set(closedPath, this.meta.get(p22) ?? { size: 0, mime: "text/markdown", mtime: /* @__PURE__ */ new Date() });
|
|
70001
|
+
this.addToTree(closedPath);
|
|
70002
|
+
this.flushed.add(closedPath);
|
|
70003
|
+
this.removeFromTree(p22);
|
|
70004
|
+
return;
|
|
70005
|
+
}
|
|
69586
70006
|
if (this.dirs.has(p22)) {
|
|
69587
70007
|
const children = this.dirs.get(p22) ?? /* @__PURE__ */ new Set();
|
|
69588
70008
|
if (children.size > 0 && !opts?.recursive)
|
|
@@ -69633,6 +70053,32 @@ var DeeplakeFs = class _DeeplakeFs {
|
|
|
69633
70053
|
throw fsErr("EPERM", "session files are read-only", s10);
|
|
69634
70054
|
if (this.sessionPaths.has(d15))
|
|
69635
70055
|
throw fsErr("EPERM", "session files are read-only", d15);
|
|
70056
|
+
if (this.goalsTable && classifyPath(s10) === "goal" && classifyPath(d15) === "goal") {
|
|
70057
|
+
const from = decomposeGoalPath(s10);
|
|
70058
|
+
const to3 = decomposeGoalPath(d15);
|
|
70059
|
+
if (from.goal_id !== to3.goal_id || from.owner !== to3.owner) {
|
|
70060
|
+
throw fsErr("EPERM", "cannot rename goal_id or owner via mv (only status)", d15);
|
|
70061
|
+
}
|
|
70062
|
+
if (!this.files.has(s10))
|
|
70063
|
+
throw fsErr("ENOENT", "no such file or directory", s10);
|
|
70064
|
+
const contentBuf = this.files.get(s10);
|
|
70065
|
+
const content = contentBuf instanceof Buffer ? contentBuf.toString("utf-8") : "";
|
|
70066
|
+
await this.upsertGoalRow({
|
|
70067
|
+
path: d15,
|
|
70068
|
+
filename: basename5(d15),
|
|
70069
|
+
contentText: content,
|
|
70070
|
+
mimeType: "text/markdown",
|
|
70071
|
+
sizeBytes: Buffer.byteLength(content, "utf-8"),
|
|
70072
|
+
creationDate: void 0,
|
|
70073
|
+
lastUpdateDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
70074
|
+
});
|
|
70075
|
+
this.files.set(d15, contentBuf ?? null);
|
|
70076
|
+
this.meta.set(d15, this.meta.get(s10) ?? { size: 0, mime: "text/markdown", mtime: /* @__PURE__ */ new Date() });
|
|
70077
|
+
this.addToTree(d15);
|
|
70078
|
+
this.flushed.add(d15);
|
|
70079
|
+
this.removeFromTree(s10);
|
|
70080
|
+
return;
|
|
70081
|
+
}
|
|
69636
70082
|
await this.cp(src, dest, { recursive: true });
|
|
69637
70083
|
await this.rm(src, { recursive: true, force: true });
|
|
69638
70084
|
}
|
|
@@ -70787,13 +71233,15 @@ async function main() {
|
|
|
70787
71233
|
}
|
|
70788
71234
|
const table = process.env["HIVEMIND_TABLE"] ?? "memory";
|
|
70789
71235
|
const sessionsTable = process.env["HIVEMIND_SESSIONS_TABLE"] ?? "sessions";
|
|
71236
|
+
const goalsTable = process.env["HIVEMIND_GOALS_TABLE"] ?? config.goalsTableName;
|
|
71237
|
+
const kpisTable = process.env["HIVEMIND_KPIS_TABLE"] ?? config.kpisTableName;
|
|
70790
71238
|
const mount = process.env["HIVEMIND_MOUNT"] ?? "/";
|
|
70791
71239
|
const client = new DeeplakeApi(config.token, config.apiUrl, config.orgId, config.workspaceId, table);
|
|
70792
71240
|
if (!isOneShot) {
|
|
70793
71241
|
process.stderr.write(`Connecting to deeplake://${config.workspaceId}/${table} ...
|
|
70794
71242
|
`);
|
|
70795
71243
|
}
|
|
70796
|
-
const fs3 = await DeeplakeFs.create(client, table, mount, sessionsTable);
|
|
71244
|
+
const fs3 = await DeeplakeFs.create(client, table, mount, sessionsTable, { goalsTable, kpisTable });
|
|
70797
71245
|
if (!isOneShot) {
|
|
70798
71246
|
const fileCount = fs3.getAllPaths().filter((p22) => !!p22).length;
|
|
70799
71247
|
process.stderr.write(`Ready. ${fileCount} files loaded.
|
|
@@ -378,6 +378,65 @@ var SKILLS_COLUMNS = Object.freeze([
|
|
|
378
378
|
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
379
379
|
{ name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
380
380
|
]);
|
|
381
|
+
var RULES_COLUMNS = Object.freeze([
|
|
382
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
383
|
+
{ name: "rule_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
384
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
385
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'team'" },
|
|
386
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
387
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
388
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
389
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
390
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
391
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
392
|
+
]);
|
|
393
|
+
var TASKS_COLUMNS = Object.freeze([
|
|
394
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
395
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
396
|
+
{ name: "text", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
397
|
+
{ name: "scope", sql: "TEXT NOT NULL DEFAULT 'me'" },
|
|
398
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'active'" },
|
|
399
|
+
{ name: "assigned_to", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
400
|
+
{ name: "assigned_by", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
401
|
+
{ name: "kpis", sql: "JSONB" },
|
|
402
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
403
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
404
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
405
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
406
|
+
]);
|
|
407
|
+
var TASK_EVENTS_COLUMNS = Object.freeze([
|
|
408
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
409
|
+
{ name: "task_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
410
|
+
{ name: "task_version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
411
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
412
|
+
{ name: "value", sql: "BIGINT NOT NULL DEFAULT 0" },
|
|
413
|
+
{ name: "note", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
414
|
+
{ name: "source", sql: "TEXT NOT NULL DEFAULT 'user'" },
|
|
415
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
416
|
+
{ name: "ts", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
417
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
418
|
+
]);
|
|
419
|
+
var GOALS_COLUMNS = Object.freeze([
|
|
420
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
421
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
422
|
+
{ name: "owner", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
423
|
+
{ name: "status", sql: "TEXT NOT NULL DEFAULT 'opened'" },
|
|
424
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
425
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
426
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
427
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
428
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
429
|
+
]);
|
|
430
|
+
var KPIS_COLUMNS = Object.freeze([
|
|
431
|
+
{ name: "id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
432
|
+
{ name: "goal_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
433
|
+
{ name: "kpi_id", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
434
|
+
{ name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
435
|
+
{ name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
|
|
436
|
+
{ name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
|
|
437
|
+
{ name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
|
|
438
|
+
{ name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
|
|
439
|
+
]);
|
|
381
440
|
function validateSchema(label, cols) {
|
|
382
441
|
const seen = /* @__PURE__ */ new Set();
|
|
383
442
|
for (const col of cols) {
|
|
@@ -421,6 +480,11 @@ var CODEBASE_COLUMNS = Object.freeze([
|
|
|
421
480
|
validateSchema("MEMORY_COLUMNS", MEMORY_COLUMNS);
|
|
422
481
|
validateSchema("SESSIONS_COLUMNS", SESSIONS_COLUMNS);
|
|
423
482
|
validateSchema("SKILLS_COLUMNS", SKILLS_COLUMNS);
|
|
483
|
+
validateSchema("RULES_COLUMNS", RULES_COLUMNS);
|
|
484
|
+
validateSchema("TASKS_COLUMNS", TASKS_COLUMNS);
|
|
485
|
+
validateSchema("TASK_EVENTS_COLUMNS", TASK_EVENTS_COLUMNS);
|
|
486
|
+
validateSchema("GOALS_COLUMNS", GOALS_COLUMNS);
|
|
487
|
+
validateSchema("KPIS_COLUMNS", KPIS_COLUMNS);
|
|
424
488
|
validateSchema("CODEBASE_COLUMNS", CODEBASE_COLUMNS);
|
|
425
489
|
function buildCreateTableSql(tableName, cols) {
|
|
426
490
|
const safe = sqlIdent(tableName);
|