diff --git a/openclaw/skills/SKILL.md b/openclaw/skills/SKILL.md index 188ac6f3..5dc467f1 100644 --- a/openclaw/skills/SKILL.md +++ b/openclaw/skills/SKILL.md @@ -23,6 +23,16 @@ The plugin automatically: - **Recalls** relevant memories before each agent turn via keyword search - All data stored as structured rows — searchable, persistent, shared +## Commands + +- `/hivemind_login` — sign in +- `/hivemind_capture` — toggle capture on/off +- `/hivemind_whoami` — show current org and workspace +- `/hivemind_orgs` — list organizations +- `/hivemind_switch_org ` — switch organization +- `/hivemind_workspaces` — list workspaces +- `/hivemind_switch_workspace ` — switch workspace + ## Sharing memory Multiple agents share memory when users are in the same Deeplake organization. diff --git a/openclaw/src/index.ts b/openclaw/src/index.ts index 3fdbe51c..469bc264 100644 --- a/openclaw/src/index.ts +++ b/openclaw/src/index.ts @@ -5,7 +5,7 @@ import { join } from "node:path"; // Shared core imports import { loadConfig } from "../../src/config.js"; -import { loadCredentials, saveCredentials, requestDeviceCode, pollForToken, listOrgs } from "../../src/commands/auth.js"; +import { loadCredentials, saveCredentials, requestDeviceCode, pollForToken, listOrgs, switchOrg, listWorkspaces, switchWorkspace } from "../../src/commands/auth.js"; import { DeeplakeApi } from "../../src/deeplake-api.js"; import { sqlStr, sqlLike } from "../../src/utils/sql.js"; @@ -183,6 +183,78 @@ export default definePluginEntry({ return { text: captureEnabled ? "✅ Capture enabled — conversations will be stored to Hivemind." : "⏸️ Capture paused — conversations will NOT be stored until you run /hivemind_capture again." }; }, }); + + pluginApi.registerCommand({ + name: "hivemind_whoami", + description: "Show current Hivemind org and workspace", + handler: async () => { + const creds = loadCredentials(); + if (!creds?.token) return { text: "Not logged in. Run /hivemind_login" }; + return { text: `Org: ${creds.orgName ?? creds.orgId}\nWorkspace: ${creds.workspaceId ?? "default"}` }; + }, + }); + + pluginApi.registerCommand({ + name: "hivemind_orgs", + description: "List available organizations", + handler: async () => { + const creds = loadCredentials(); + if (!creds?.token) return { text: "Not logged in. Run /hivemind_login" }; + const orgs = await listOrgs(creds.token, creds.apiUrl); + if (!orgs.length) return { text: "No organizations found." }; + const lines = orgs.map(o => `${o.id === creds.orgId ? "→ " : " "}${o.name}`); + return { text: lines.join("\n") }; + }, + }); + + pluginApi.registerCommand({ + name: "hivemind_switch_org", + description: "Switch to a different organization", + acceptsArgs: true, + handler: async (ctx: CommandContext) => { + const creds = loadCredentials(); + if (!creds?.token) return { text: "Not logged in. Run /hivemind_login" }; + const target = ctx.args?.trim(); + if (!target) return { text: "Usage: /hivemind_switch_org " }; + const orgs = await listOrgs(creds.token, creds.apiUrl); + const match = orgs.find(o => o.id === target || o.name.toLowerCase() === target.toLowerCase()); + if (!match) return { text: `Org not found: ${target}` }; + await switchOrg(match.id, match.name); + api = null; + return { text: `Switched to org: ${match.name}` }; + }, + }); + + pluginApi.registerCommand({ + name: "hivemind_workspaces", + description: "List available workspaces", + handler: async () => { + const creds = loadCredentials(); + if (!creds?.token) return { text: "Not logged in. Run /hivemind_login" }; + const ws = await listWorkspaces(creds.token, creds.apiUrl, creds.orgId); + if (!ws.length) return { text: "No workspaces found." }; + const lines = ws.map(w => `${w.id === (creds.workspaceId ?? "default") ? "→ " : " "}${w.name}`); + return { text: lines.join("\n") }; + }, + }); + + pluginApi.registerCommand({ + name: "hivemind_switch_workspace", + description: "Switch to a different workspace", + acceptsArgs: true, + handler: async (ctx: CommandContext) => { + const creds = loadCredentials(); + if (!creds?.token) return { text: "Not logged in. Run /hivemind_login" }; + const target = ctx.args?.trim(); + if (!target) return { text: "Usage: /hivemind_switch_workspace " }; + const ws = await listWorkspaces(creds.token, creds.apiUrl, creds.orgId); + const match = ws.find(w => w.id === target || w.name.toLowerCase() === target.toLowerCase()); + if (!match) return { text: `Workspace not found: ${target}` }; + await switchWorkspace(match.id); + api = null; + return { text: `Switched to workspace: ${match.name}` }; + }, + }); } const config = (pluginApi.pluginConfig ?? {}) as PluginConfig;