@deeplake/hivemind 0.7.4 → 0.7.9

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.
Files changed (35) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +97 -0
  4. package/bundle/cli.js +820 -20
  5. package/codex/bundle/capture.js +40 -10
  6. package/codex/bundle/commands/auth-login.js +84 -18
  7. package/codex/bundle/pre-tool-use.js +41 -11
  8. package/codex/bundle/session-start-setup.js +40 -10
  9. package/codex/bundle/session-start.js +27 -3
  10. package/codex/bundle/shell/deeplake-shell.js +41 -11
  11. package/codex/bundle/skilify-worker.js +907 -0
  12. package/codex/bundle/stop.js +373 -51
  13. package/cursor/bundle/capture.js +354 -13
  14. package/cursor/bundle/commands/auth-login.js +84 -18
  15. package/cursor/bundle/pre-tool-use.js +40 -10
  16. package/cursor/bundle/session-end.js +303 -6
  17. package/cursor/bundle/session-start.js +68 -14
  18. package/cursor/bundle/shell/deeplake-shell.js +41 -11
  19. package/cursor/bundle/skilify-worker.js +907 -0
  20. package/hermes/bundle/capture.js +354 -13
  21. package/hermes/bundle/commands/auth-login.js +84 -18
  22. package/hermes/bundle/pre-tool-use.js +40 -10
  23. package/hermes/bundle/session-end.js +305 -7
  24. package/hermes/bundle/session-start.js +68 -14
  25. package/hermes/bundle/shell/deeplake-shell.js +41 -11
  26. package/hermes/bundle/skilify-worker.js +907 -0
  27. package/mcp/bundle/server.js +41 -11
  28. package/openclaw/dist/chunks/{config-G23NI5TV.js → config-ZLH6JFJS.js} +1 -0
  29. package/openclaw/dist/index.js +185 -16
  30. package/openclaw/dist/skilify-worker.js +907 -0
  31. package/openclaw/openclaw.plugin.json +1 -1
  32. package/openclaw/package.json +1 -1
  33. package/openclaw/skills/SKILL.md +19 -0
  34. package/package.json +6 -1
  35. package/pi/extension-source/hivemind.ts +130 -1
package/bundle/cli.js CHANGED
@@ -177,6 +177,7 @@ function pluginAlreadyInstalled() {
177
177
  return false;
178
178
  return r.stdout.includes(PLUGIN_KEY);
179
179
  }
180
+ var PLUGIN_SCOPES = ["user", "project", "local", "managed"];
180
181
  function installClaude() {
181
182
  requireClaudeCli();
182
183
  if (!marketplaceAlreadyAdded()) {
@@ -190,9 +191,15 @@ function installClaude() {
190
191
  if (!inst.ok) {
191
192
  throw new Error(`Failed to install hivemind plugin: ${inst.stderr.slice(0, 200)}`);
192
193
  }
194
+ log(` Claude Code installed via marketplace ${MARKETPLACE_SOURCE}`);
195
+ } else {
196
+ runClaude(["plugin", "marketplace", "update", MARKETPLACE_NAME]);
197
+ for (const scope of PLUGIN_SCOPES) {
198
+ runClaude(["plugin", "update", PLUGIN_KEY, "--scope", scope]);
199
+ }
200
+ log(` Claude Code refreshed via marketplace ${MARKETPLACE_SOURCE}`);
193
201
  }
194
202
  runClaude(["plugin", "enable", PLUGIN_KEY]);
195
- log(` Claude Code installed via marketplace ${MARKETPLACE_SOURCE}`);
196
203
  }
197
204
  function uninstallClaude() {
198
205
  try {
@@ -3345,6 +3352,7 @@ var EXTENSION_PATH = join8(EXTENSIONS_DIR, "hivemind.ts");
3345
3352
  var VERSION_DIR = join8(PI_AGENT_DIR, ".hivemind");
3346
3353
  var WIKI_WORKER_DIR = join8(PI_AGENT_DIR, "hivemind");
3347
3354
  var WIKI_WORKER_PATH = join8(WIKI_WORKER_DIR, "wiki-worker.js");
3355
+ var SKILIFY_WORKER_PATH = join8(WIKI_WORKER_DIR, "skilify-worker.js");
3348
3356
  var HIVEMIND_BLOCK_START = "<!-- BEGIN hivemind-memory -->";
3349
3357
  var HIVEMIND_BLOCK_END = "<!-- END hivemind-memory -->";
3350
3358
  var HIVEMIND_BLOCK_BODY = `${HIVEMIND_BLOCK_START}
@@ -3429,6 +3437,11 @@ function installPi() {
3429
3437
  ensureDir(WIKI_WORKER_DIR);
3430
3438
  copyFileSync2(srcWorker, WIKI_WORKER_PATH);
3431
3439
  }
3440
+ const srcSkilifyWorker = join8(pkgRoot(), "pi", "bundle", "skilify-worker.js");
3441
+ if (existsSync7(srcSkilifyWorker)) {
3442
+ ensureDir(WIKI_WORKER_DIR);
3443
+ copyFileSync2(srcSkilifyWorker, SKILIFY_WORKER_PATH);
3444
+ }
3432
3445
  ensureDir(VERSION_DIR);
3433
3446
  writeVersionStamp(VERSION_DIR, getVersion());
3434
3447
  log(` pi AGENTS.md updated -> ${AGENTS_MD}`);
@@ -3436,6 +3449,9 @@ function installPi() {
3436
3449
  if (existsSync7(WIKI_WORKER_PATH)) {
3437
3450
  log(` pi wiki-worker installed -> ${WIKI_WORKER_PATH}`);
3438
3451
  }
3452
+ if (existsSync7(SKILIFY_WORKER_PATH)) {
3453
+ log(` pi skilify-worker installed -> ${SKILIFY_WORKER_PATH}`);
3454
+ }
3439
3455
  }
3440
3456
  function uninstallPi() {
3441
3457
  if (existsSync7(LEGACY_SKILL_DIR)) {
@@ -3921,6 +3937,7 @@ function loadConfig() {
3921
3937
  apiUrl: process.env.HIVEMIND_API_URL ?? creds?.apiUrl ?? "https://api.deeplake.ai",
3922
3938
  tableName: process.env.HIVEMIND_TABLE ?? "memory",
3923
3939
  sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
3940
+ skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
3924
3941
  memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join12(home, ".deeplake", "memory")
3925
3942
  };
3926
3943
  }
@@ -3945,6 +3962,12 @@ function log2(tag, msg) {
3945
3962
  function sqlStr(value) {
3946
3963
  return value.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/\0/g, "").replace(/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
3947
3964
  }
3965
+ function sqlIdent(name) {
3966
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
3967
+ throw new Error(`Invalid SQL identifier: ${JSON.stringify(name)}`);
3968
+ }
3969
+ return name;
3970
+ }
3948
3971
 
3949
3972
  // dist/src/embeddings/columns.js
3950
3973
  var SUMMARY_EMBEDDING_COL = "summary_embedding";
@@ -4308,7 +4331,7 @@ var DeeplakeApi = class {
4308
4331
  }
4309
4332
  /** Create the memory table if it doesn't already exist. Migrate columns on existing tables. */
4310
4333
  async ensureTable(name) {
4311
- const tbl = name ?? this.tableName;
4334
+ const tbl = sqlIdent(name ?? this.tableName);
4312
4335
  const tables = await this.listTables();
4313
4336
  if (!tables.includes(tbl)) {
4314
4337
  log3(`table "${tbl}" not found, creating`);
@@ -4322,17 +4345,40 @@ var DeeplakeApi = class {
4322
4345
  }
4323
4346
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
4324
4347
  async ensureSessionsTable(name) {
4348
+ const safe = sqlIdent(name);
4325
4349
  const tables = await this.listTables();
4326
- if (!tables.includes(name)) {
4327
- log3(`table "${name}" not found, creating`);
4328
- await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${name}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, name);
4329
- log3(`table "${name}" created`);
4330
- if (!tables.includes(name))
4331
- this._tablesCache = [...tables, name];
4350
+ if (!tables.includes(safe)) {
4351
+ log3(`table "${safe}" not found, creating`);
4352
+ await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
4353
+ log3(`table "${safe}" created`);
4354
+ if (!tables.includes(safe))
4355
+ this._tablesCache = [...tables, safe];
4332
4356
  }
4333
- await this.ensureEmbeddingColumn(name, MESSAGE_EMBEDDING_COL);
4334
- await this.ensureColumn(name, "agent", "TEXT NOT NULL DEFAULT ''");
4335
- await this.ensureLookupIndex(name, "path_creation_date", `("path", "creation_date")`);
4357
+ await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
4358
+ await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
4359
+ await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
4360
+ }
4361
+ /**
4362
+ * Create the skills table.
4363
+ *
4364
+ * One row per skill version. Workers INSERT a fresh row on every KEEP /
4365
+ * MERGE rather than UPDATE-ing in place, so the full version history is
4366
+ * recoverable. Uniqueness in the *current* state is by (project_key, name)
4367
+ * — newer rows shadow older ones at read time (ORDER BY version DESC).
4368
+ * This sidesteps the Deeplake UPDATE-coalescing quirk that bit the wiki
4369
+ * worker.
4370
+ */
4371
+ async ensureSkillsTable(name) {
4372
+ const safe = sqlIdent(name);
4373
+ const tables = await this.listTables();
4374
+ if (!tables.includes(safe)) {
4375
+ log3(`table "${safe}" not found, creating`);
4376
+ await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', project TEXT NOT NULL DEFAULT '', project_key TEXT NOT NULL DEFAULT '', local_path TEXT NOT NULL DEFAULT '', install TEXT NOT NULL DEFAULT 'project', source_sessions TEXT NOT NULL DEFAULT '[]', source_agent TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL DEFAULT 'me', author TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', trigger_text TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '', version BIGINT NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT '', updated_at TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
4377
+ log3(`table "${safe}" created`);
4378
+ if (!tables.includes(safe))
4379
+ this._tablesCache = [...tables, safe];
4380
+ }
4381
+ await this.ensureLookupIndex(safe, "project_key_name", `("project_key", "name")`);
4336
4382
  }
4337
4383
  };
4338
4384
 
@@ -4512,8 +4558,24 @@ async function runAuthCommand(args) {
4512
4558
  console.log(`Org not found: ${target}`);
4513
4559
  process.exit(1);
4514
4560
  }
4561
+ const prevWs = creds.workspaceId ?? "default";
4562
+ const lcPrev = prevWs.toLowerCase();
4563
+ const wsList = await listWorkspaces(creds.token, apiUrl, match.id);
4564
+ const matchedWs = wsList.find((w) => w.id === prevWs || w.name && w.name.toLowerCase() === lcPrev);
4515
4565
  await switchOrg(match.id, match.name);
4516
4566
  console.log(`Switched to org: ${match.name}`);
4567
+ if (!matchedWs) {
4568
+ if (prevWs !== "default") {
4569
+ await switchWorkspace("default");
4570
+ console.log(`Workspace '${prevWs}' is not in org '${match.name}'. Reset workspace to 'default'.`);
4571
+ if (wsList.length > 0) {
4572
+ console.log(`Available workspaces: ${wsList.map((w) => w.name || w.id).join(", ")}`);
4573
+ }
4574
+ }
4575
+ } else if (matchedWs.id !== prevWs) {
4576
+ await switchWorkspace(matchedWs.id);
4577
+ console.log(`Workspace name '${prevWs}' resolved to id '${matchedWs.id}' in org '${match.name}'.`);
4578
+ }
4517
4579
  } else {
4518
4580
  console.log("Usage: org list | org switch <name-or-id>");
4519
4581
  }
@@ -4525,7 +4587,7 @@ async function runAuthCommand(args) {
4525
4587
  process.exit(1);
4526
4588
  }
4527
4589
  const ws = await listWorkspaces(creds.token, apiUrl, creds.orgId);
4528
- ws.forEach((w) => console.log(`${w.id} ${w.name}`));
4590
+ ws.forEach((w) => console.log(w.name || w.id));
4529
4591
  break;
4530
4592
  }
4531
4593
  case "workspace": {
@@ -4533,14 +4595,34 @@ async function runAuthCommand(args) {
4533
4595
  console.log("Not logged in.");
4534
4596
  process.exit(1);
4535
4597
  }
4536
- const wsId = args[1];
4537
- if (!wsId) {
4538
- console.log("Usage: workspace <id>");
4539
- process.exit(1);
4598
+ const sub = args[1];
4599
+ if (sub === "list") {
4600
+ const wsList = await listWorkspaces(creds.token, apiUrl, creds.orgId);
4601
+ wsList.forEach((w) => console.log(w.name || w.id));
4602
+ break;
4540
4603
  }
4541
- await switchWorkspace(wsId);
4542
- console.log(`Switched to workspace: ${wsId}`);
4543
- break;
4604
+ if (sub === "switch") {
4605
+ const target = args[2];
4606
+ if (!target) {
4607
+ console.log("Usage: workspace switch <name-or-id>");
4608
+ process.exit(1);
4609
+ }
4610
+ const wsList = await listWorkspaces(creds.token, apiUrl, creds.orgId);
4611
+ const lcTarget = target.toLowerCase();
4612
+ const match = wsList.find((w) => w.id === target || w.name && w.name.toLowerCase() === lcTarget);
4613
+ if (!match) {
4614
+ console.log(`Workspace not found: ${target}`);
4615
+ if (wsList.length > 0) {
4616
+ console.log(`Available workspaces: ${wsList.map((w) => w.name || w.id).join(", ")}`);
4617
+ }
4618
+ process.exit(1);
4619
+ }
4620
+ await switchWorkspace(match.id);
4621
+ console.log(`Switched to workspace: ${match.name || match.id}`);
4622
+ break;
4623
+ }
4624
+ console.log("Usage: workspace list | workspace switch <name-or-id>");
4625
+ process.exit(1);
4544
4626
  }
4545
4627
  case "invite": {
4546
4628
  if (!creds) {
@@ -4627,6 +4709,699 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
4627
4709
  });
4628
4710
  }
4629
4711
 
4712
+ // dist/src/commands/skilify.js
4713
+ import { readdirSync as readdirSync3, existsSync as existsSync15, readFileSync as readFileSync12, mkdirSync as mkdirSync7, renameSync as renameSync2 } from "node:fs";
4714
+ import { homedir as homedir8 } from "node:os";
4715
+ import { dirname as dirname2, join as join18 } from "node:path";
4716
+
4717
+ // dist/src/skilify/scope-config.js
4718
+ import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
4719
+ import { homedir as homedir5 } from "node:os";
4720
+ import { join as join15 } from "node:path";
4721
+ var STATE_DIR = join15(homedir5(), ".deeplake", "state", "skilify");
4722
+ var CONFIG_PATH2 = join15(STATE_DIR, "config.json");
4723
+ var DEFAULT = { scope: "me", team: [], install: "project" };
4724
+ function loadScopeConfig() {
4725
+ if (!existsSync12(CONFIG_PATH2))
4726
+ return DEFAULT;
4727
+ try {
4728
+ const raw = JSON.parse(readFileSync9(CONFIG_PATH2, "utf-8"));
4729
+ const scope = raw.scope === "team" || raw.scope === "org" ? raw.scope : "me";
4730
+ const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
4731
+ const install = raw.install === "global" ? "global" : "project";
4732
+ return { scope, team, install };
4733
+ } catch {
4734
+ return DEFAULT;
4735
+ }
4736
+ }
4737
+ function saveScopeConfig(cfg) {
4738
+ mkdirSync4(STATE_DIR, { recursive: true });
4739
+ writeFileSync6(CONFIG_PATH2, JSON.stringify(cfg, null, 2));
4740
+ }
4741
+
4742
+ // dist/src/skilify/pull.js
4743
+ import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync6, renameSync } from "node:fs";
4744
+ import { homedir as homedir7 } from "node:os";
4745
+ import { join as join17 } from "node:path";
4746
+
4747
+ // dist/src/skilify/skill-writer.js
4748
+ import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync10, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync7 } from "node:fs";
4749
+ import { homedir as homedir6 } from "node:os";
4750
+ import { join as join16 } from "node:path";
4751
+ function assertValidSkillName(name) {
4752
+ if (typeof name !== "string" || name.length === 0) {
4753
+ throw new Error(`invalid skill name: empty or non-string`);
4754
+ }
4755
+ if (name.length > 100) {
4756
+ throw new Error(`invalid skill name: too long (${name.length} chars)`);
4757
+ }
4758
+ if (name.includes("/") || name.includes("\\") || name.includes("..")) {
4759
+ throw new Error(`invalid skill name: contains path separator or '..': ${name}`);
4760
+ }
4761
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {
4762
+ throw new Error(`invalid skill name: must be kebab-case (lowercase a-z, 0-9, hyphen): ${name}`);
4763
+ }
4764
+ }
4765
+ function parseFrontmatter(text) {
4766
+ if (!text.startsWith("---\n") && !text.startsWith("---\r\n"))
4767
+ return null;
4768
+ const end = text.indexOf("\n---", 4);
4769
+ if (end < 0)
4770
+ return null;
4771
+ const head = text.slice(4, end).trim();
4772
+ const body = text.slice(end + 4).replace(/^\r?\n/, "");
4773
+ const fm = { source_sessions: [] };
4774
+ let mode = "kv";
4775
+ for (const raw of head.split(/\r?\n/)) {
4776
+ if (mode === "sources") {
4777
+ const m2 = raw.match(/^\s+-\s+(.+)$/);
4778
+ if (m2) {
4779
+ fm.source_sessions.push(m2[1].trim());
4780
+ continue;
4781
+ }
4782
+ mode = "kv";
4783
+ }
4784
+ if (raw.startsWith("source_sessions:")) {
4785
+ mode = "sources";
4786
+ continue;
4787
+ }
4788
+ const m = raw.match(/^([a-zA-Z_]+):\s*(.*)$/);
4789
+ if (!m)
4790
+ continue;
4791
+ const [, k, v] = m;
4792
+ let val = v;
4793
+ if (v.startsWith('"') && v.endsWith('"')) {
4794
+ try {
4795
+ val = JSON.parse(v);
4796
+ } catch {
4797
+ }
4798
+ } else if (k === "version") {
4799
+ const n = parseInt(v, 10);
4800
+ if (Number.isFinite(n))
4801
+ val = n;
4802
+ }
4803
+ fm[k] = val;
4804
+ }
4805
+ return { fm, body };
4806
+ }
4807
+
4808
+ // dist/src/skilify/pull.js
4809
+ function esc(s) {
4810
+ return s.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
4811
+ }
4812
+ function buildPullSql(args) {
4813
+ const where = [];
4814
+ if (args.users.length > 0) {
4815
+ const list = args.users.map((u) => `'${esc(u)}'`).join(", ");
4816
+ where.push(`author IN (${list})`);
4817
+ }
4818
+ if (args.skillName) {
4819
+ where.push(`name = '${esc(args.skillName)}'`);
4820
+ }
4821
+ const whereClause = where.length > 0 ? ` WHERE ${where.join(" AND ")}` : "";
4822
+ return `SELECT name, project, project_key, body, version, source_agent, scope, author, description, trigger_text, source_sessions, install, created_at, updated_at FROM "${args.tableName}"${whereClause} ORDER BY project_key ASC, name ASC, version DESC`;
4823
+ }
4824
+ function isMissingTableError(message) {
4825
+ if (!message)
4826
+ return false;
4827
+ return /Table does not exist|relation .* does not exist|no such table/i.test(message);
4828
+ }
4829
+ function resolvePullDestination(install, cwd) {
4830
+ if (install === "global")
4831
+ return join17(homedir7(), ".claude", "skills");
4832
+ if (!cwd)
4833
+ throw new Error("install=project requires a cwd");
4834
+ return join17(cwd, ".claude", "skills");
4835
+ }
4836
+ function selectLatestPerName(rows) {
4837
+ const seen = /* @__PURE__ */ new Set();
4838
+ const out = [];
4839
+ for (const r of rows) {
4840
+ const name = String(r.name ?? "");
4841
+ const projectKey = String(r.project_key ?? "");
4842
+ if (!name)
4843
+ continue;
4844
+ const key = `${projectKey}\0${name}`;
4845
+ if (seen.has(key))
4846
+ continue;
4847
+ seen.add(key);
4848
+ out.push(r);
4849
+ }
4850
+ return out;
4851
+ }
4852
+ function renderSkillFile(row) {
4853
+ const sources = parseSourceSessions(row.source_sessions);
4854
+ const fm = {
4855
+ name: String(row.name ?? ""),
4856
+ description: String(row.description ?? ""),
4857
+ trigger: typeof row.trigger_text === "string" && row.trigger_text.length > 0 ? String(row.trigger_text) : void 0,
4858
+ source_sessions: sources,
4859
+ version: Number(row.version ?? 1),
4860
+ created_by_agent: String(row.source_agent ?? "unknown"),
4861
+ created_at: String(row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()),
4862
+ updated_at: String(row.updated_at ?? (/* @__PURE__ */ new Date()).toISOString())
4863
+ };
4864
+ const body = String(row.body ?? "").trim();
4865
+ return `${renderFrontmatter(fm)}
4866
+
4867
+ ${body}
4868
+ `;
4869
+ }
4870
+ function parseSourceSessions(v) {
4871
+ if (Array.isArray(v))
4872
+ return v.map(String);
4873
+ if (typeof v === "string") {
4874
+ try {
4875
+ const parsed = JSON.parse(v);
4876
+ if (Array.isArray(parsed))
4877
+ return parsed.map(String);
4878
+ } catch {
4879
+ }
4880
+ }
4881
+ return [];
4882
+ }
4883
+ function renderFrontmatter(fm) {
4884
+ const lines = ["---"];
4885
+ lines.push(`name: ${fm.name}`);
4886
+ lines.push(`description: ${JSON.stringify(fm.description)}`);
4887
+ if (fm.trigger)
4888
+ lines.push(`trigger: ${JSON.stringify(fm.trigger)}`);
4889
+ lines.push(`source_sessions:`);
4890
+ for (const s of fm.source_sessions)
4891
+ lines.push(` - ${s}`);
4892
+ lines.push(`version: ${fm.version}`);
4893
+ lines.push(`created_by_agent: ${fm.created_by_agent}`);
4894
+ lines.push(`created_at: ${fm.created_at}`);
4895
+ lines.push(`updated_at: ${fm.updated_at}`);
4896
+ lines.push("---");
4897
+ return lines.join("\n");
4898
+ }
4899
+ function readLocalVersion(path) {
4900
+ if (!existsSync14(path))
4901
+ return null;
4902
+ try {
4903
+ const text = readFileSync11(path, "utf-8");
4904
+ const parsed = parseFrontmatter(text);
4905
+ if (!parsed)
4906
+ return null;
4907
+ const v = parsed.fm.version;
4908
+ return typeof v === "number" ? v : null;
4909
+ } catch {
4910
+ return null;
4911
+ }
4912
+ }
4913
+ function decideAction(args) {
4914
+ const shouldWrite = args.localVersion === null || args.remoteVersion > args.localVersion || args.force;
4915
+ if (!shouldWrite)
4916
+ return "skipped";
4917
+ return args.dryRun ? "dryrun" : "wrote";
4918
+ }
4919
+ async function runPull(opts) {
4920
+ const sql = buildPullSql({
4921
+ tableName: opts.tableName,
4922
+ users: opts.users,
4923
+ skillName: opts.skillName
4924
+ });
4925
+ let rows = [];
4926
+ try {
4927
+ rows = await opts.query(sql);
4928
+ } catch (e) {
4929
+ if (isMissingTableError(e?.message))
4930
+ rows = [];
4931
+ else
4932
+ throw e;
4933
+ }
4934
+ const latest = selectLatestPerName(rows);
4935
+ const root = resolvePullDestination(opts.install, opts.cwd);
4936
+ const summary = { scanned: latest.length, wrote: 0, skipped: 0, dryrun: 0, entries: [] };
4937
+ for (const row of latest) {
4938
+ const name = String(row.name ?? "");
4939
+ if (!name)
4940
+ continue;
4941
+ try {
4942
+ assertValidSkillName(name);
4943
+ } catch (e) {
4944
+ summary.entries.push({
4945
+ name,
4946
+ remoteVersion: Number(row.version ?? 1),
4947
+ localVersion: null,
4948
+ action: "skipped",
4949
+ destination: "(invalid name \u2014 skipped)",
4950
+ author: String(row.author ?? ""),
4951
+ sourceAgent: String(row.source_agent ?? "")
4952
+ });
4953
+ summary.skipped++;
4954
+ continue;
4955
+ }
4956
+ const projectKey = String(row.project_key ?? "");
4957
+ const skillDir = projectKey ? join17(root, projectKey, name) : join17(root, name);
4958
+ const skillFile = join17(skillDir, "SKILL.md");
4959
+ const remoteVersion = Number(row.version ?? 1);
4960
+ const localVersion = readLocalVersion(skillFile);
4961
+ const action = decideAction({
4962
+ remoteVersion,
4963
+ localVersion,
4964
+ force: opts.force ?? false,
4965
+ dryRun: opts.dryRun ?? false
4966
+ });
4967
+ if (action === "wrote") {
4968
+ mkdirSync6(skillDir, { recursive: true });
4969
+ if (existsSync14(skillFile)) {
4970
+ try {
4971
+ renameSync(skillFile, `${skillFile}.bak`);
4972
+ } catch {
4973
+ }
4974
+ }
4975
+ writeFileSync8(skillFile, renderSkillFile(row));
4976
+ }
4977
+ summary.entries.push({
4978
+ name,
4979
+ remoteVersion,
4980
+ localVersion,
4981
+ action,
4982
+ destination: skillFile,
4983
+ author: String(row.author ?? ""),
4984
+ sourceAgent: String(row.source_agent ?? "")
4985
+ });
4986
+ if (action === "wrote")
4987
+ summary.wrote++;
4988
+ else if (action === "dryrun")
4989
+ summary.dryrun++;
4990
+ else
4991
+ summary.skipped++;
4992
+ }
4993
+ return summary;
4994
+ }
4995
+
4996
+ // dist/src/commands/skilify.js
4997
+ var STATE_DIR2 = join18(homedir8(), ".deeplake", "state", "skilify");
4998
+ function showStatus() {
4999
+ const cfg = loadScopeConfig();
5000
+ console.log(`scope: ${cfg.scope}`);
5001
+ console.log(`team: ${cfg.team.length === 0 ? "(empty)" : cfg.team.join(", ")}`);
5002
+ console.log(`install: ${cfg.install} (${cfg.install === "global" ? "~/.claude/skills/" : "<project>/.claude/skills/"})`);
5003
+ if (!existsSync15(STATE_DIR2)) {
5004
+ console.log(`state: (no projects tracked yet)`);
5005
+ return;
5006
+ }
5007
+ const files = readdirSync3(STATE_DIR2).filter((f) => f.endsWith(".json") && f !== "config.json");
5008
+ if (files.length === 0) {
5009
+ console.log(`state: (no projects tracked yet)`);
5010
+ return;
5011
+ }
5012
+ console.log(`state: ${files.length} project(s) tracked`);
5013
+ for (const f of files) {
5014
+ try {
5015
+ const s = JSON.parse(readFileSync12(join18(STATE_DIR2, f), "utf-8"));
5016
+ const skills = s.skillsGenerated.length === 0 ? "none" : s.skillsGenerated.join(", ");
5017
+ console.log(` - ${s.project} (counter=${s.counter}, last=${s.lastDate ?? "never"}, skills=${skills})`);
5018
+ } catch {
5019
+ }
5020
+ }
5021
+ }
5022
+ function setScope(scope) {
5023
+ if (scope !== "me" && scope !== "team" && scope !== "org") {
5024
+ console.error(`Invalid scope '${scope}'. Use one of: me, team, org`);
5025
+ process.exit(1);
5026
+ }
5027
+ const cfg = loadScopeConfig();
5028
+ saveScopeConfig({ ...cfg, scope });
5029
+ console.log(`Scope set to '${scope}'.`);
5030
+ if (scope === "team" && cfg.team.length === 0) {
5031
+ console.log(`Note: team list is empty. Use 'hivemind skilify team add <username>' to populate it.`);
5032
+ }
5033
+ }
5034
+ function setInstall(loc) {
5035
+ if (loc !== "project" && loc !== "global") {
5036
+ console.error(`Invalid install location '${loc}'. Use one of: project, global`);
5037
+ process.exit(1);
5038
+ }
5039
+ const cfg = loadScopeConfig();
5040
+ saveScopeConfig({ ...cfg, install: loc });
5041
+ const path = loc === "global" ? join18(homedir8(), ".claude", "skills") : "<cwd>/.claude/skills";
5042
+ console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
5043
+ }
5044
+ function promoteSkill(name, cwd) {
5045
+ if (!name) {
5046
+ console.error("Usage: hivemind skilify promote <skill-name>");
5047
+ process.exit(1);
5048
+ }
5049
+ const projectPath = join18(cwd, ".claude", "skills", name);
5050
+ const globalPath = join18(homedir8(), ".claude", "skills", name);
5051
+ if (!existsSync15(join18(projectPath, "SKILL.md"))) {
5052
+ console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
5053
+ process.exit(1);
5054
+ }
5055
+ if (existsSync15(join18(globalPath, "SKILL.md"))) {
5056
+ console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
5057
+ process.exit(1);
5058
+ }
5059
+ mkdirSync7(dirname2(globalPath), { recursive: true });
5060
+ renameSync2(projectPath, globalPath);
5061
+ console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
5062
+ }
5063
+ function teamAdd(name) {
5064
+ if (!name) {
5065
+ console.error("Usage: hivemind skilify team add <username>");
5066
+ process.exit(1);
5067
+ }
5068
+ const cfg = loadScopeConfig();
5069
+ if (cfg.team.includes(name)) {
5070
+ console.log(`'${name}' is already in the team list.`);
5071
+ return;
5072
+ }
5073
+ const next = [...cfg.team, name].sort();
5074
+ saveScopeConfig({ ...cfg, team: next });
5075
+ console.log(`Added '${name}' to team. Team is now: ${next.join(", ")}`);
5076
+ }
5077
+ function teamRemove(name) {
5078
+ if (!name) {
5079
+ console.error("Usage: hivemind skilify team remove <username>");
5080
+ process.exit(1);
5081
+ }
5082
+ const cfg = loadScopeConfig();
5083
+ if (!cfg.team.includes(name)) {
5084
+ console.log(`'${name}' is not in the team list.`);
5085
+ return;
5086
+ }
5087
+ const next = cfg.team.filter((n) => n !== name);
5088
+ saveScopeConfig({ ...cfg, team: next });
5089
+ console.log(`Removed '${name}' from team. Team is now: ${next.length === 0 ? "(empty)" : next.join(", ")}`);
5090
+ }
5091
+ function teamList() {
5092
+ const cfg = loadScopeConfig();
5093
+ if (cfg.team.length === 0) {
5094
+ console.log(`(team list is empty)`);
5095
+ return;
5096
+ }
5097
+ for (const n of cfg.team)
5098
+ console.log(n);
5099
+ }
5100
+ function usage() {
5101
+ console.log("Usage:");
5102
+ console.log(" hivemind skilify show current scope, team, install, and per-project state");
5103
+ console.log(" hivemind skilify scope <me|team|org> set the mining scope");
5104
+ console.log(" hivemind skilify install <project|global> set where new skills are written");
5105
+ console.log(" hivemind skilify promote <skill-name> move a project skill to the global location");
5106
+ console.log(" hivemind skilify team add <username> add a username to the team list");
5107
+ console.log(" hivemind skilify team remove <username> remove a username from the team list");
5108
+ console.log(" hivemind skilify team list list current team members");
5109
+ console.log(" hivemind skilify pull [skill-name] [opts] fetch skills from Deeplake to local FS");
5110
+ console.log(" Options for pull:");
5111
+ console.log(" --to <project|global> destination (default: global)");
5112
+ console.log(" --user <name> only skills authored by this user");
5113
+ console.log(" --users <a,b,c> only skills authored by these users");
5114
+ console.log(" --all-users all authors (default \u2014 equivalent to no filter)");
5115
+ console.log(" --dry-run show what would be written, don't touch disk");
5116
+ console.log(" --force overwrite even when local version >= remote");
5117
+ console.log(" hivemind skilify status show per-project state");
5118
+ }
5119
+ function takeFlagValue(args, flag) {
5120
+ const idx = args.indexOf(flag);
5121
+ if (idx < 0)
5122
+ return null;
5123
+ const value = args[idx + 1];
5124
+ if (value === void 0 || value.startsWith("--")) {
5125
+ console.error(`${flag} requires a value`);
5126
+ process.exit(1);
5127
+ }
5128
+ args.splice(idx, 2);
5129
+ return value;
5130
+ }
5131
+ function takeBooleanFlag(args, flag) {
5132
+ const idx = args.indexOf(flag);
5133
+ if (idx < 0)
5134
+ return false;
5135
+ args.splice(idx, 1);
5136
+ return true;
5137
+ }
5138
+ async function pullSkills(args) {
5139
+ const work = [...args];
5140
+ const toRaw = takeFlagValue(work, "--to") ?? "global";
5141
+ const userOne = takeFlagValue(work, "--user");
5142
+ const usersMany = takeFlagValue(work, "--users");
5143
+ const allUsers = takeBooleanFlag(work, "--all-users");
5144
+ const dryRun = takeBooleanFlag(work, "--dry-run");
5145
+ const force = takeBooleanFlag(work, "--force");
5146
+ const skillName = work[0];
5147
+ if (toRaw !== "project" && toRaw !== "global") {
5148
+ console.error(`Invalid --to '${toRaw}'. Use 'project' or 'global'.`);
5149
+ process.exit(1);
5150
+ }
5151
+ let users = [];
5152
+ if (allUsers)
5153
+ users = [];
5154
+ else if (userOne)
5155
+ users = [userOne];
5156
+ else if (usersMany)
5157
+ users = usersMany.split(",").map((s) => s.trim()).filter(Boolean);
5158
+ const config = loadConfig();
5159
+ if (!config) {
5160
+ console.error("Not logged in. Run: hivemind login");
5161
+ process.exit(1);
5162
+ }
5163
+ const api = new DeeplakeApi(config.token, config.apiUrl, config.orgId, config.workspaceId, config.skillsTableName);
5164
+ const query = (sql) => api.query(sql);
5165
+ let summary;
5166
+ try {
5167
+ summary = await runPull({
5168
+ query,
5169
+ tableName: config.skillsTableName,
5170
+ install: toRaw,
5171
+ cwd: toRaw === "project" ? process.cwd() : void 0,
5172
+ users,
5173
+ skillName,
5174
+ dryRun,
5175
+ force
5176
+ });
5177
+ } catch (e) {
5178
+ console.error(`pull failed: ${e?.message ?? e}`);
5179
+ process.exit(1);
5180
+ }
5181
+ const dest = toRaw === "global" ? join18(homedir8(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
5182
+ const filterDesc = users.length === 0 ? "all users" : users.join(", ");
5183
+ console.log(`Destination: ${dest}`);
5184
+ console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
5185
+ console.log(`Scanned ${summary.scanned} remote skill(s).`);
5186
+ for (const e of summary.entries) {
5187
+ const tag = e.action === "wrote" ? "\u2713 wrote" : e.action === "dryrun" ? "\u2192 would write" : "\xB7 skipped";
5188
+ const ver = e.localVersion === null ? `v${e.remoteVersion} (new)` : `v${e.localVersion} \u2192 v${e.remoteVersion}`;
5189
+ console.log(` ${tag.padEnd(15)} ${e.name.padEnd(40)} ${ver.padEnd(20)} (${e.author}/${e.sourceAgent})`);
5190
+ }
5191
+ console.log(`Result: ${summary.wrote} written, ${summary.dryrun} dry-run, ${summary.skipped} skipped.`);
5192
+ }
5193
+ function runSkilifyCommand(args) {
5194
+ const sub = args[0];
5195
+ if (!sub || sub === "status") {
5196
+ showStatus();
5197
+ return;
5198
+ }
5199
+ if (sub === "scope") {
5200
+ setScope(args[1] ?? "");
5201
+ return;
5202
+ }
5203
+ if (sub === "install") {
5204
+ setInstall(args[1] ?? "");
5205
+ return;
5206
+ }
5207
+ if (sub === "promote") {
5208
+ promoteSkill(args[1] ?? "", process.cwd());
5209
+ return;
5210
+ }
5211
+ if (sub === "pull") {
5212
+ pullSkills(args.slice(1)).catch((e) => {
5213
+ console.error(`pull error: ${e?.message ?? e}`);
5214
+ process.exit(1);
5215
+ });
5216
+ return;
5217
+ }
5218
+ if (sub === "team") {
5219
+ const action = args[1];
5220
+ if (action === "add") {
5221
+ teamAdd(args[2] ?? "");
5222
+ return;
5223
+ }
5224
+ if (action === "remove") {
5225
+ teamRemove(args[2] ?? "");
5226
+ return;
5227
+ }
5228
+ if (action === "list") {
5229
+ teamList();
5230
+ return;
5231
+ }
5232
+ console.error("Usage: hivemind skilify team <add|remove|list> [name]");
5233
+ process.exit(1);
5234
+ }
5235
+ if (sub === "--help" || sub === "-h" || sub === "help") {
5236
+ usage();
5237
+ return;
5238
+ }
5239
+ console.error(`Unknown skilify subcommand: ${sub}`);
5240
+ usage();
5241
+ process.exit(1);
5242
+ }
5243
+ if (process.argv[1] && process.argv[1].endsWith("skilify.js")) {
5244
+ runSkilifyCommand(process.argv.slice(2));
5245
+ }
5246
+
5247
+ // dist/src/cli/update.js
5248
+ import { execFileSync as execFileSync4 } from "node:child_process";
5249
+ import { existsSync as existsSync16, readFileSync as readFileSync14, realpathSync } from "node:fs";
5250
+ import { dirname as dirname4, sep } from "node:path";
5251
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
5252
+
5253
+ // dist/src/utils/version-check.js
5254
+ import { readFileSync as readFileSync13 } from "node:fs";
5255
+ import { dirname as dirname3, join as join19 } from "node:path";
5256
+ function isNewer(latest, current) {
5257
+ const parse = (v) => v.split(".").map(Number);
5258
+ const [la, lb, lc] = parse(latest);
5259
+ const [ca, cb, cc] = parse(current);
5260
+ return la > ca || la === ca && lb > cb || la === ca && lb === cb && lc > cc;
5261
+ }
5262
+
5263
+ // dist/src/cli/update.js
5264
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@deeplake/hivemind/latest";
5265
+ var PKG_NAME = "@deeplake/hivemind";
5266
+ function detectInstallKind(argv1) {
5267
+ const realArgv1 = (() => {
5268
+ try {
5269
+ return realpathSync(argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url));
5270
+ } catch {
5271
+ return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
5272
+ }
5273
+ })();
5274
+ let dir = dirname4(realArgv1);
5275
+ let installDir = null;
5276
+ for (let i = 0; i < 10; i++) {
5277
+ const pkgPath = `${dir}${sep}package.json`;
5278
+ try {
5279
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
5280
+ if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
5281
+ installDir = dir;
5282
+ break;
5283
+ }
5284
+ } catch {
5285
+ }
5286
+ const parent = dirname4(dir);
5287
+ if (parent === dir)
5288
+ break;
5289
+ dir = parent;
5290
+ }
5291
+ installDir ??= dirname4(realArgv1);
5292
+ if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
5293
+ return { kind: "npx", installDir };
5294
+ }
5295
+ if (realArgv1.includes(`${sep}node_modules${sep}@deeplake${sep}hivemind`) || realArgv1.includes(`${sep}node_modules${sep}hivemind`)) {
5296
+ return { kind: "npm-global", installDir };
5297
+ }
5298
+ let gitDir = installDir;
5299
+ for (let i = 0; i < 6; i++) {
5300
+ if (existsSync16(`${gitDir}${sep}.git`)) {
5301
+ return { kind: "local-dev", installDir };
5302
+ }
5303
+ const parent = dirname4(gitDir);
5304
+ if (parent === gitDir)
5305
+ break;
5306
+ gitDir = parent;
5307
+ }
5308
+ return { kind: "unknown", installDir };
5309
+ }
5310
+ async function getLatestNpmVersion(timeoutMs = 5e3) {
5311
+ try {
5312
+ const res = await fetch(NPM_REGISTRY_URL, { signal: AbortSignal.timeout(timeoutMs) });
5313
+ if (!res.ok)
5314
+ return null;
5315
+ const meta = await res.json();
5316
+ return meta.version ?? null;
5317
+ } catch {
5318
+ return null;
5319
+ }
5320
+ }
5321
+ var defaultSpawn = (cmd, args) => {
5322
+ execFileSync4(cmd, args, { stdio: "inherit" });
5323
+ };
5324
+ async function runUpdate(opts = {}) {
5325
+ const current = opts.currentVersionOverride ?? getVersion();
5326
+ const latest = opts.latestVersionOverride !== void 0 ? opts.latestVersionOverride : await getLatestNpmVersion();
5327
+ if (!latest) {
5328
+ warn(`Could not reach npm registry to check for updates.`);
5329
+ warn(`Current version: ${current}`);
5330
+ return 1;
5331
+ }
5332
+ if (!isNewer(latest, current)) {
5333
+ log(`hivemind ${current} is up to date (npm latest: ${latest}).`);
5334
+ return 0;
5335
+ }
5336
+ log(`Update available: ${current} \u2192 ${latest}`);
5337
+ const detected = opts.installKindOverride ?? detectInstallKind();
5338
+ const spawn = opts.spawn ?? defaultSpawn;
5339
+ switch (detected.kind) {
5340
+ case "npm-global": {
5341
+ if (opts.dryRun) {
5342
+ log(`(dry-run) Would run: npm install -g ${PKG_NAME}@latest`);
5343
+ log(`(dry-run) Would re-run: hivemind install --skip-auth`);
5344
+ return 0;
5345
+ }
5346
+ log(`Upgrading via npm\u2026`);
5347
+ try {
5348
+ spawn("npm", ["install", "-g", `${PKG_NAME}@latest`]);
5349
+ } catch (e) {
5350
+ warn(`npm install failed: ${e.message}`);
5351
+ warn(`Try running it manually: npm install -g ${PKG_NAME}@latest`);
5352
+ return 1;
5353
+ }
5354
+ log(``);
5355
+ log(`Refreshing agent bundles\u2026`);
5356
+ try {
5357
+ spawn("hivemind", ["install", "--skip-auth"]);
5358
+ } catch (e) {
5359
+ warn(`Agent refresh failed: ${e.message}`);
5360
+ warn(`Run manually: hivemind install`);
5361
+ return 1;
5362
+ }
5363
+ log(``);
5364
+ log(`Updated to ${latest}.`);
5365
+ return 0;
5366
+ }
5367
+ case "npx": {
5368
+ if (opts.dryRun) {
5369
+ log(`(dry-run) Would print npx-pin instructions (no persistent install to upgrade).`);
5370
+ return 0;
5371
+ }
5372
+ log(`You ran hivemind via npx, which does not have a persistent global install.`);
5373
+ log(`To use the new version, re-run with the explicit version pin:`);
5374
+ log(``);
5375
+ log(` npx ${PKG_NAME}@${latest} install`);
5376
+ log(``);
5377
+ log(`Or install globally so future updates are one command:`);
5378
+ log(``);
5379
+ log(` npm install -g ${PKG_NAME}@latest`);
5380
+ return 0;
5381
+ }
5382
+ case "local-dev": {
5383
+ if (opts.dryRun) {
5384
+ log(`(dry-run) Would refuse: running from a local dev checkout (${detected.installDir}).`);
5385
+ return 0;
5386
+ }
5387
+ warn(`hivemind is running from a local development checkout (${detected.installDir}).`);
5388
+ warn(`Update via your dev workflow (git pull + npm install + npm run build),`);
5389
+ warn(`not via 'hivemind update'.`);
5390
+ return 1;
5391
+ }
5392
+ case "unknown":
5393
+ default: {
5394
+ if (opts.dryRun) {
5395
+ log(`(dry-run) Would refuse: install kind unknown (${detected.installDir}).`);
5396
+ return 0;
5397
+ }
5398
+ warn(`Could not determine how hivemind was installed (path: ${detected.installDir}).`);
5399
+ warn(`Update manually: npm install -g ${PKG_NAME}@latest`);
5400
+ return 1;
5401
+ }
5402
+ }
5403
+ }
5404
+
4630
5405
  // dist/src/cli/index.js
4631
5406
  var AUTH_SUBCOMMANDS = /* @__PURE__ */ new Set([
4632
5407
  "whoami",
@@ -4662,6 +5437,9 @@ Usage:
4662
5437
 
4663
5438
  hivemind login Run device-flow login (open browser).
4664
5439
  hivemind status Show which assistants are wired up.
5440
+ hivemind update [--dry-run]
5441
+ Check npm for a newer @deeplake/hivemind, upgrade the CLI, and refresh
5442
+ every detected agent bundle. Single command for all agents.
4665
5443
 
4666
5444
  Semantic search (embeddings):
4667
5445
  hivemind embeddings install Download @huggingface/transformers
@@ -4675,13 +5453,27 @@ Semantic search (embeddings):
4675
5453
  Add --with-embeddings to "hivemind install" (or "hivemind <agent> install")
4676
5454
  to run "embeddings install" automatically after installing the agent(s).
4677
5455
 
5456
+ Skill management (mine + share reusable Claude skills across the org):
5457
+ hivemind skilify Show scope, team, install, and per-project state.
5458
+ hivemind skilify pull [skill-name] Sync skills from the org table to local FS.
5459
+ Options: --user <email>, --users a,b,c,
5460
+ --all-users, --to <project|global>,
5461
+ --dry-run, --force.
5462
+ hivemind skilify scope <me|team|org> Set the sharing scope for newly mined skills.
5463
+ hivemind skilify install <project|global> Set where new skills are written.
5464
+ hivemind skilify promote <name> Move a project skill to the global location.
5465
+ hivemind skilify team add <username> Add a username to the team list.
5466
+ hivemind skilify team remove <username> Remove a username from the team list.
5467
+ hivemind skilify team list List current team members.
5468
+
4678
5469
  Account / org / workspace:
4679
5470
  hivemind whoami Show current user, org, workspace.
4680
5471
  hivemind logout Remove credentials.
4681
5472
  hivemind org list List organizations.
4682
5473
  hivemind org switch <name-or-id> Switch active organization.
4683
5474
  hivemind workspaces List workspaces in current org.
4684
- hivemind workspace <id> Switch active workspace.
5475
+ hivemind workspace list List workspaces (alias of 'workspaces').
5476
+ hivemind workspace switch <name-or-id> Switch active workspace.
4685
5477
  hivemind members List org members.
4686
5478
  hivemind invite <email> <ADMIN|WRITE|READ> Invite a teammate.
4687
5479
  hivemind remove <user-id> Remove a member.
@@ -4819,6 +5611,14 @@ async function main() {
4819
5611
  runStatus();
4820
5612
  return;
4821
5613
  }
5614
+ if (cmd === "update") {
5615
+ const code = await runUpdate({ dryRun: hasFlag(args.slice(1), "--dry-run") });
5616
+ process.exit(code);
5617
+ }
5618
+ if (cmd === "skilify") {
5619
+ runSkilifyCommand(args.slice(1));
5620
+ return;
5621
+ }
4822
5622
  if (cmd === "embeddings") {
4823
5623
  const sub = args[1];
4824
5624
  if (sub === "install" || sub === "enable") {