@cmgmyr/hive 1.2.1 → 1.2.2

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <p align="center"><img src="https://raw.githubusercontent.com/cmgmyr/hive/main/docs/assets/logo-card.svg" alt="hive" height="112"></p>
2
2
  <p align="center"><a href="https://www.npmjs.com/package/@cmgmyr/hive"><img src="https://img.shields.io/npm/v/%40cmgmyr%2Fhive?label=npm" alt="npm"></a> <a href="https://github.com/cmgmyr/hive/actions/workflows/ci.yml"><img src="https://github.com/cmgmyr/hive/actions/workflows/ci.yml/badge.svg" alt="CI"></a></p>
3
3
 
4
- Shared, persistent memory and a visible crew of tmux workers for Claude Code and Codex sessions on one project.
4
+ Run a crew of Claude Code and Codex workers from one lead session: visible tmux panes, exact state from hooks, one local SQLite store.
5
5
 
6
6
  - Visible workers: each one is a real tmux pane you can read and type into.
7
7
  - Exact state: workers report it through their own CLI's hooks, so nothing polls.
@@ -1 +1 @@
1
- {"version":"1.2.1","sha":"1d14c85","dirty":false,"build_id":"6d50625e-ceaf-412d-8dcf-6b7a922fceaa"}
1
+ {"version":"1.2.2","sha":"df20075","dirty":false,"build_id":"2f8ecccc-4d22-424a-8c24-c48551ed2441"}
package/dist/cli.js CHANGED
@@ -41,7 +41,7 @@ import { checkoutRoot, createProfile, forkProfile, PROFILE_FILES, ProfileError,
41
41
  import { COMMENT_COUNT_SQL, getTodoDetail, listTodoSummaries, OPEN_BLOCKERS_SQL, TODO_STATUSES, } from "./tools/todos.js";
42
42
  import { createPad, getActivePadByName, listActivePads, overwritePadContent, } from "./tools/pads.js";
43
43
  function usage() {
44
- console.log(`hive — shared memory and coordination for Claude Code sessions
44
+ console.log(`hive — run a crew of Claude Code and Codex workers from one lead session
45
45
 
46
46
  Usage:
47
47
  hive --version version, short sha, and dirty marker for this build
package/dist/help.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export function helpOverview() {
2
- return `HIVE — shared memory and coordination across Claude Code sessions
2
+ return `HIVE — a lead session and a crew of Claude Code and Codex workers, sharing one local store
3
3
 
4
4
  Many workers, one shared memory. Multiple Claude sessions (and humans) share
5
5
  one project-scoped state store: pads, todos, kv, leases.
package/dist/result.js CHANGED
@@ -16,6 +16,23 @@ export function registrationNoticeText(notice) {
16
16
  `project_select.`);
17
17
  }
18
18
  const reportedBuilds = new Set();
19
+ const pendingNotices = new WeakMap();
20
+ function addNotice(result, text, build) {
21
+ result.content.push({ type: "text", text });
22
+ const pending = pendingNotices.get(result) ?? { texts: [] };
23
+ pending.texts.push(text);
24
+ if (build)
25
+ pending.build = build;
26
+ pendingNotices.set(result, pending);
27
+ }
28
+ export function noticeFor(result) {
29
+ return pendingNotices.get(result)?.texts.join("\n");
30
+ }
31
+ export function releaseNotice(result) {
32
+ const build = pendingNotices.get(result)?.build;
33
+ if (build)
34
+ reportedBuilds.delete(build);
35
+ }
19
36
  export async function appendRunningBuildNotice(result, session) {
20
37
  try {
21
38
  const change = runningBuildChange();
@@ -30,8 +47,8 @@ export async function appendRunningBuildNotice(result, session) {
30
47
  }
31
48
  if (reportedBuilds.has(change.disk.build_id))
32
49
  return result;
33
- result.content.push({ type: "text", text: runningBuildNotice(change, session) });
34
50
  reportedBuilds.add(change.disk.build_id);
51
+ addNotice(result, runningBuildNotice(change, session), change.disk.build_id);
35
52
  }
36
53
  catch {
37
54
  }
@@ -52,7 +69,7 @@ export async function run(fn) {
52
69
  }
53
70
  const notice = takeRegistrationNotice();
54
71
  if (notice) {
55
- result.content.push({ type: "text", text: registrationNoticeText(notice) });
72
+ addNotice(result, registrationNoticeText(notice));
56
73
  }
57
74
  return appendRunningBuildNotice(result);
58
75
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { noticeFor, releaseNotice } from "./result.js";
2
3
  function isBuiltSchema(value) {
3
4
  return typeof value === "object" && value !== null && ("_zod" in value || "_def" in value);
4
5
  }
@@ -14,11 +15,15 @@ function strictSchemaFor(toolName, inputSchema) {
14
15
  }
15
16
  // The SDK requires structuredContent whenever outputSchema is declared but never populates it itself,
16
17
  // so this stays scoped to declaring tools rather than attached blanket in src/result.ts's ok().
18
+ // Claude Code shows the model structuredContent and drops content for these tools, so a notice
19
+ // appended to content reaches it only as structuredContent.hive_notice.
17
20
  function withStructuredContent(name, cb) {
18
21
  return async (...args) => {
19
22
  const result = (await cb(...args));
20
- if (result.isError || result.structuredContent)
23
+ if (result.isError)
21
24
  return result;
25
+ if (result.structuredContent)
26
+ return withNotice(result);
22
27
  const first = result.content[0];
23
28
  const text = first?.type === "text" ? first.text : undefined;
24
29
  let parsed;
@@ -30,8 +35,9 @@ function withStructuredContent(name, cb) {
30
35
  }
31
36
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
32
37
  result.structuredContent = parsed;
33
- return result;
38
+ return withNotice(result);
34
39
  }
40
+ releaseNotice(result);
35
41
  return {
36
42
  content: [
37
43
  {
@@ -45,8 +51,23 @@ function withStructuredContent(name, cb) {
45
51
  };
46
52
  };
47
53
  }
54
+ function withNotice(result) {
55
+ const notice = noticeFor(result);
56
+ if (notice && result.structuredContent)
57
+ result.structuredContent = { ...result.structuredContent, hive_notice: notice };
58
+ return result;
59
+ }
60
+ function withNoticeField(outputSchema) {
61
+ return outputSchema === undefined || isBuiltSchema(outputSchema)
62
+ ? outputSchema
63
+ : { ...outputSchema, hive_notice: z.string().optional() };
64
+ }
48
65
  export function enforceStrictInput(server) {
49
66
  const register = server.registerTool.bind(server);
50
- server.registerTool = ((name, config, cb) => register(name, { ...config, inputSchema: strictSchemaFor(name, config.inputSchema) }, (config.outputSchema ? withStructuredContent(name, cb) : cb)));
67
+ server.registerTool = ((name, config, cb) => register(name, {
68
+ ...config,
69
+ inputSchema: strictSchemaFor(name, config.inputSchema),
70
+ outputSchema: withNoticeField(config.outputSchema),
71
+ }, (config.outputSchema ? withStructuredContent(name, cb) : cb)));
51
72
  return server;
52
73
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cmgmyr/hive",
3
- "version": "1.2.1",
4
- "description": "Shared memory and coordination for Claude Code sessions: one lead, many tmux workers, one project-scoped store.",
3
+ "version": "1.2.2",
4
+ "description": "Run a crew of Claude Code and Codex workers from one lead session: visible tmux panes, exact state from hooks, one local SQLite store.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "hive": "dist/cli.js",