@deeplake/hivemind 0.7.67 → 0.7.68
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 +68 -5
- package/codex/bundle/capture.js +3 -0
- package/codex/bundle/stop.js +3 -0
- package/codex/skills/hivemind-goals/SKILL.md +30 -0
- package/cursor/bundle/capture.js +3 -0
- package/cursor/bundle/session-end.js +3 -0
- package/hermes/bundle/capture.js +3 -0
- package/hermes/bundle/session-end.js +3 -0
- package/openclaw/dist/index.js +1 -1
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/openclaw/skills/hivemind-goals/SKILL.md +25 -0
- package/package.json +1 -1
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.68"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "hivemind",
|
|
14
14
|
"description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
|
|
15
|
-
"version": "0.7.
|
|
15
|
+
"version": "0.7.68",
|
|
16
16
|
"source": {
|
|
17
17
|
"source": "git-subdir",
|
|
18
18
|
"url": "https://github.com/activeloopai/hivemind.git",
|
|
19
19
|
"path": "claude-code",
|
|
20
|
-
"sha": "
|
|
20
|
+
"sha": "f0e0e28e1f3687c42c7b46ad1af6379120eab37d"
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/activeloopai/hivemind"
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivemind",
|
|
3
3
|
"description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.68",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Activeloop",
|
|
7
7
|
"url": "https://deeplake.ai"
|
package/bundle/cli.js
CHANGED
|
@@ -10996,6 +10996,30 @@ async function runRulesCommand(args) {
|
|
|
10996
10996
|
// dist/src/commands/goal.js
|
|
10997
10997
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10998
10998
|
var VALID_STATUS = /* @__PURE__ */ new Set(["opened", "in_progress", "closed"]);
|
|
10999
|
+
var VALID_AGENT = /* @__PURE__ */ new Set(["manual", "capture"]);
|
|
11000
|
+
function parseAgentFlag(args) {
|
|
11001
|
+
const rest = [];
|
|
11002
|
+
let agent = "manual";
|
|
11003
|
+
for (let i = 0; i < args.length; i++) {
|
|
11004
|
+
if (args[i] === "--agent") {
|
|
11005
|
+
const val = args[i + 1];
|
|
11006
|
+
if (!val) {
|
|
11007
|
+
process.stderr.write("usage: --agent requires a value (manual|capture)\n");
|
|
11008
|
+
process.exit(1);
|
|
11009
|
+
}
|
|
11010
|
+
agent = val;
|
|
11011
|
+
i++;
|
|
11012
|
+
continue;
|
|
11013
|
+
}
|
|
11014
|
+
rest.push(args[i]);
|
|
11015
|
+
}
|
|
11016
|
+
if (!VALID_AGENT.has(agent)) {
|
|
11017
|
+
process.stderr.write(`invalid --agent: ${agent} (expected manual|capture)
|
|
11018
|
+
`);
|
|
11019
|
+
process.exit(1);
|
|
11020
|
+
}
|
|
11021
|
+
return { agent, rest };
|
|
11022
|
+
}
|
|
10999
11023
|
function loadApiOrDie(table) {
|
|
11000
11024
|
const cfg = loadConfig();
|
|
11001
11025
|
if (!cfg) {
|
|
@@ -11006,7 +11030,7 @@ function loadApiOrDie(table) {
|
|
|
11006
11030
|
const query = (sql) => api.query(sql);
|
|
11007
11031
|
return { api, query, userName: cfg.userName };
|
|
11008
11032
|
}
|
|
11009
|
-
async function goalAdd(text) {
|
|
11033
|
+
async function goalAdd(text, agent = "manual") {
|
|
11010
11034
|
const cfg = loadConfig();
|
|
11011
11035
|
if (!cfg) {
|
|
11012
11036
|
process.stderr.write("hivemind: not logged in.\n");
|
|
@@ -11018,7 +11042,7 @@ async function goalAdd(text) {
|
|
|
11018
11042
|
const safe = sqlIdent(table);
|
|
11019
11043
|
const goalId = randomUUID4();
|
|
11020
11044
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
11021
|
-
await query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(cfg.userName)}', 'opened', E'${sqlStr(text)}', 1, '${sqlStr(ts)}', '
|
|
11045
|
+
await query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(cfg.userName)}', 'opened', E'${sqlStr(text)}', 1, '${sqlStr(ts)}', '${sqlStr(agent)}', '')`);
|
|
11022
11046
|
process.stdout.write(`${goalId}
|
|
11023
11047
|
`);
|
|
11024
11048
|
}
|
|
@@ -11050,6 +11074,33 @@ async function goalList(filter) {
|
|
|
11050
11074
|
process.exit(1);
|
|
11051
11075
|
}
|
|
11052
11076
|
}
|
|
11077
|
+
async function goalGet(goalId) {
|
|
11078
|
+
if (!goalId) {
|
|
11079
|
+
process.stderr.write("usage: hivemind goal get <goal_id>\n");
|
|
11080
|
+
process.exit(1);
|
|
11081
|
+
}
|
|
11082
|
+
const cfg = loadConfig();
|
|
11083
|
+
if (!cfg) {
|
|
11084
|
+
process.stderr.write("not logged in\n");
|
|
11085
|
+
process.exit(1);
|
|
11086
|
+
}
|
|
11087
|
+
const { query } = loadApiOrDie(cfg.goalsTableName);
|
|
11088
|
+
const safe = sqlIdent(cfg.goalsTableName);
|
|
11089
|
+
try {
|
|
11090
|
+
const rows = await query(`SELECT content FROM "${safe}" WHERE goal_id = '${sqlStr(goalId)}' ORDER BY version DESC, created_at DESC LIMIT 1`);
|
|
11091
|
+
if (rows.length === 0) {
|
|
11092
|
+
process.stderr.write(`goal not found: ${goalId}
|
|
11093
|
+
`);
|
|
11094
|
+
process.exit(1);
|
|
11095
|
+
}
|
|
11096
|
+
process.stdout.write(`${String(rows[0].content ?? "")}
|
|
11097
|
+
`);
|
|
11098
|
+
} catch (e) {
|
|
11099
|
+
process.stderr.write(`hivemind goal get: ${e.message}
|
|
11100
|
+
`);
|
|
11101
|
+
process.exit(1);
|
|
11102
|
+
}
|
|
11103
|
+
}
|
|
11053
11104
|
async function goalDone(goalId) {
|
|
11054
11105
|
await goalProgress(goalId, "closed");
|
|
11055
11106
|
}
|
|
@@ -11171,8 +11222,10 @@ var USAGE_GOAL = `
|
|
|
11171
11222
|
hivemind goal \u2014 manage team goals
|
|
11172
11223
|
|
|
11173
11224
|
Usage:
|
|
11174
|
-
hivemind goal add "<text>"
|
|
11225
|
+
hivemind goal add "<text>" [--agent manual|capture]
|
|
11226
|
+
create a goal (status=opened)
|
|
11175
11227
|
hivemind goal list [--all|--mine] list goals (default: --mine)
|
|
11228
|
+
hivemind goal get <goal_id> print a goal's full body (resume context)
|
|
11176
11229
|
hivemind goal done <goal_id> mark goal closed
|
|
11177
11230
|
hivemind goal progress <goal_id> <opened|in_progress|closed>
|
|
11178
11231
|
`.trim();
|
|
@@ -11183,12 +11236,13 @@ async function runGoalCommand(args) {
|
|
|
11183
11236
|
return;
|
|
11184
11237
|
}
|
|
11185
11238
|
if (sub === "add") {
|
|
11186
|
-
const
|
|
11239
|
+
const { agent, rest } = parseAgentFlag(args.slice(1));
|
|
11240
|
+
const text = rest.join(" ").trim();
|
|
11187
11241
|
if (!text) {
|
|
11188
11242
|
process.stderr.write('usage: hivemind goal add "<text>"\n');
|
|
11189
11243
|
process.exit(1);
|
|
11190
11244
|
}
|
|
11191
|
-
await goalAdd(text);
|
|
11245
|
+
await goalAdd(text, agent);
|
|
11192
11246
|
return;
|
|
11193
11247
|
}
|
|
11194
11248
|
if (sub === "list") {
|
|
@@ -11196,6 +11250,15 @@ async function runGoalCommand(args) {
|
|
|
11196
11250
|
await goalList(filter);
|
|
11197
11251
|
return;
|
|
11198
11252
|
}
|
|
11253
|
+
if (sub === "get") {
|
|
11254
|
+
const id = args[1];
|
|
11255
|
+
if (!id) {
|
|
11256
|
+
process.stderr.write("usage: hivemind goal get <goal_id>\n");
|
|
11257
|
+
process.exit(1);
|
|
11258
|
+
}
|
|
11259
|
+
await goalGet(id);
|
|
11260
|
+
return;
|
|
11261
|
+
}
|
|
11199
11262
|
if (sub === "done") {
|
|
11200
11263
|
const id = args[1];
|
|
11201
11264
|
if (!id) {
|
package/codex/bundle/capture.js
CHANGED
|
@@ -1843,6 +1843,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
1843
1843
|
## Open Questions / TODO
|
|
1844
1844
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
1845
1845
|
|
|
1846
|
+
## Next Steps
|
|
1847
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
1848
|
+
|
|
1846
1849
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
1847
1850
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
1848
1851
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
package/codex/bundle/stop.js
CHANGED
|
@@ -1123,6 +1123,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
1123
1123
|
## Open Questions / TODO
|
|
1124
1124
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
1125
1125
|
|
|
1126
|
+
## Next Steps
|
|
1127
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
1128
|
+
|
|
1126
1129
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
1127
1130
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
1128
1131
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
|
@@ -67,6 +67,36 @@ When the user expresses a new goal:
|
|
|
67
67
|
|
|
68
68
|
**Do NOT auto-generate KPIs.** A goal is created with zero KPI files by default. Generate KPIs ONLY when the user explicitly asks you to ("aggiungi KPI per …", "add metrics for this goal", "track these metrics: …"). When the user asks, write each KPI as a separate file at `~/.deeplake/memory/kpi/<goal_id>/<kpi-slug>.md` with the body format documented above.
|
|
69
69
|
|
|
70
|
+
### 1a. Capture a task for later (with resumable context)
|
|
71
|
+
|
|
72
|
+
Use this when the user **parks a tangential task** mid-session — "save this for later", "remind me to …", "don't let me forget …", "let's do X later". The value is NOT the one-liner — it's storing enough **context to resume cold** in a future session without the user re-explaining anything.
|
|
73
|
+
|
|
74
|
+
Write it via the **CLI** so the row is tagged `agent: capture`, which separates parked side-tasks from hand-made goals:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
hivemind goal add --agent capture "Add rate-limiting to the webhook handler
|
|
78
|
+
|
|
79
|
+
Start here: add a per-IP token bucket on the handler entry path
|
|
80
|
+
Files: src/webhook/handler.ts:120-160, src/webhook/limits.ts
|
|
81
|
+
Branch: feat/webhook-hardening
|
|
82
|
+
Run: pnpm test webhook
|
|
83
|
+
Why: bursty clients hammer the endpoint; agreed to defer until the retry-backoff work lands"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- **Line 1 is the label** — short; it's what `goal list` and the SessionStart banner show.
|
|
87
|
+
- Fill `Start here / Files / Branch / Run / Why` from the live conversation. Include only the lines you can fill; `Start here:` (the concrete first action) matters most.
|
|
88
|
+
- Pass the whole package as **one double-quoted argument** (newlines are preserved into the stored body).
|
|
89
|
+
- Confirm to the user: the label + that it'll resume cleanly next session.
|
|
90
|
+
|
|
91
|
+
### 1b. Resume a parked task (automatic context transfer)
|
|
92
|
+
|
|
93
|
+
When the user says "let's work on that task / that goal", "let's start the `<X>` task", or "pick up the parked `<X>`", pull its stored context back into the session and continue — the user should NOT have to re-explain anything.
|
|
94
|
+
|
|
95
|
+
1. **Find it:** `hivemind goal list --mine` and match the user's reference to a `goal_id`. If ambiguous, show the candidates and ask.
|
|
96
|
+
2. **Transfer the context:** `hivemind goal get <goal_id>` prints the full package (`Start here / Files / Branch / Run / Why`). Read it as your working context — `goal list` only shows the first line, so always use `goal get` for the full body.
|
|
97
|
+
3. **Flip to in_progress:** `mv ~/.deeplake/memory/goal/<owner>/opened/<uuid>.md ~/.deeplake/memory/goal/<owner>/in_progress/<uuid>.md`
|
|
98
|
+
4. **Act on it:** open the `Files:`, switch to the `Branch:` if given, and begin from `Start here:`. You are resumed — continue as if the context was never lost.
|
|
99
|
+
|
|
70
100
|
### 2. List goals
|
|
71
101
|
|
|
72
102
|
```bash
|
package/cursor/bundle/capture.js
CHANGED
|
@@ -1843,6 +1843,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
1843
1843
|
## Open Questions / TODO
|
|
1844
1844
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
1845
1845
|
|
|
1846
|
+
## Next Steps
|
|
1847
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
1848
|
+
|
|
1846
1849
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
1847
1850
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
1848
1851
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
|
@@ -268,6 +268,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
268
268
|
## Open Questions / TODO
|
|
269
269
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
270
270
|
|
|
271
|
+
## Next Steps
|
|
272
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
273
|
+
|
|
271
274
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
272
275
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
273
276
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
package/hermes/bundle/capture.js
CHANGED
|
@@ -1842,6 +1842,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
1842
1842
|
## Open Questions / TODO
|
|
1843
1843
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
1844
1844
|
|
|
1845
|
+
## Next Steps
|
|
1846
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
1847
|
+
|
|
1845
1848
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
1846
1849
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
1847
1850
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
|
@@ -266,6 +266,9 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
|
|
|
266
266
|
## Open Questions / TODO
|
|
267
267
|
<Anything unresolved, blocked, or explicitly deferred>
|
|
268
268
|
|
|
269
|
+
## Next Steps
|
|
270
|
+
<The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
|
|
271
|
+
|
|
269
272
|
IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
|
|
270
273
|
PRIVACY: Never include absolute filesystem paths in the summary.
|
|
271
274
|
LENGTH LIMIT: Keep the total summary under 4000 characters.`;
|
package/openclaw/dist/index.js
CHANGED
|
@@ -1799,7 +1799,7 @@ function extractLatestVersion(body) {
|
|
|
1799
1799
|
return typeof v === "string" && v.length > 0 ? v : null;
|
|
1800
1800
|
}
|
|
1801
1801
|
function getInstalledVersion() {
|
|
1802
|
-
return "0.7.
|
|
1802
|
+
return "0.7.68".length > 0 ? "0.7.68" : null;
|
|
1803
1803
|
}
|
|
1804
1804
|
function isNewer(latest, current) {
|
|
1805
1805
|
const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
|
package/openclaw/package.json
CHANGED
|
@@ -23,6 +23,31 @@ OpenClaw exposes purpose-built tools for goals + KPIs. Use them directly — do
|
|
|
23
23
|
3. ONLY if the user asks for KPIs: `hivemind_kpi_add` once per KPI with `goal_id` + `kpi_id` (short slug like `k-prs`) + `target` (positive int) + `unit`.
|
|
24
24
|
4. Confirm to the user with the goal_id and that the goal is team-visible.
|
|
25
25
|
|
|
26
|
+
## Capture a task for later (with resumable context)
|
|
27
|
+
|
|
28
|
+
When the user **parks a tangential task** mid-session — "save this for later", "remind me to …", "don't let me forget …", "let's do X later" — store enough **context to resume cold** later, not just a one-liner. Put the full package in the `text` of `hivemind_goal_add`:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
hivemind_goal_add({ text:
|
|
32
|
+
"Add rate-limiting to the webhook handler\n\n" +
|
|
33
|
+
"Start here: add a per-IP token bucket on the handler entry path\n" +
|
|
34
|
+
"Files: src/webhook/handler.ts:120-160, src/webhook/limits.ts\n" +
|
|
35
|
+
"Branch: feat/webhook-hardening\n" +
|
|
36
|
+
"Run: pnpm test webhook\n" +
|
|
37
|
+
"Why: bursty clients hammer the endpoint; defer until retry-backoff lands" })
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Line 1 is the label. Fill `Start here / Files / Branch / Run / Why` from the conversation; `Start here:` (the concrete first action) matters most. (OpenClaw's `hivemind_goal_add` has no provenance flag, so the row is tagged `manual` — that's fine; the context is what matters.)
|
|
41
|
+
|
|
42
|
+
## Resume a parked task (automatic context transfer)
|
|
43
|
+
|
|
44
|
+
When the user says "let's work on that task / goal" or "pick up the `<X>` task":
|
|
45
|
+
|
|
46
|
+
1. `hivemind_search({ query: "<topic>" })` or `hivemind_index({})` to locate the parked goal, then `hivemind_read({ path: "memory/goal/<owner>/opened/<goal_id>.md" })` to pull the **full** context package back.
|
|
47
|
+
2. Read it as your working context and begin from `Start here:` using the `Files` / `Branch` / `Run` lines — continue as if the context was never lost.
|
|
48
|
+
|
|
49
|
+
(Status-move tools aren't exposed on OpenClaw, so leave the goal where it is and just resume the work.)
|
|
50
|
+
|
|
26
51
|
## What NOT to do
|
|
27
52
|
|
|
28
53
|
- Do NOT write files anywhere under `~/.deeplake/memory/`. OpenClaw's runtime does not route filesystem writes to the Deeplake tables — only the `hivemind_*` tools above do.
|