hivecode-mcp 0.14.1 → 0.14.3

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 (72) hide show
  1. package/HIVE_RULES.md +98 -98
  2. package/LICENSE +21 -21
  3. package/README.md +421 -421
  4. package/core.js +91 -91
  5. package/docs/ALWAYS_ON.md +310 -310
  6. package/docs/GITHUB_WORKFLOW.md +394 -394
  7. package/docs/HIVE_RULES.md +41 -41
  8. package/docs/MCP.md +157 -157
  9. package/docs/QUICKSTART.md +266 -266
  10. package/docs/SELF_HOSTING.md +256 -256
  11. package/docs/SLACK_SETUP.md +474 -474
  12. package/docs/TROUBLESHOOTING.md +106 -105
  13. package/hive-activity.js +336 -336
  14. package/hive-authors.js +46 -44
  15. package/hive-await.js +230 -230
  16. package/hive-branch.js +674 -607
  17. package/hive-busy.js +88 -88
  18. package/hive-coord.js +110 -110
  19. package/hive-gate.js +135 -135
  20. package/hive-github.js +3 -1
  21. package/hive-hook-install.js +179 -179
  22. package/hive-instructions.js +74 -74
  23. package/hive-land.js +709 -691
  24. package/hive-listen.js +81 -81
  25. package/hive-mailbox.js +520 -520
  26. package/hive-mcp-http.js +591 -591
  27. package/hive-mcp.js +92 -12
  28. package/hive-mux-proto.js +58 -58
  29. package/hive-mux.js +354 -351
  30. package/hive-notify.js +234 -233
  31. package/hive-obligations.js +247 -247
  32. package/hive-poll-proto.js +50 -50
  33. package/hive-pr-staleness.js +189 -189
  34. package/hive-pr.js +637 -512
  35. package/hive-privacy.js +327 -327
  36. package/hive-receipts.js +233 -233
  37. package/hive-relay-health.js +234 -234
  38. package/hive-repos.js +430 -430
  39. package/hive-room-key.js +210 -210
  40. package/hive-room-mode.js +1761 -1668
  41. package/hive-room-watcher.js +623 -561
  42. package/hive-secrets.js +89 -89
  43. package/hive-session.js +114 -114
  44. package/hive-setup.js +560 -560
  45. package/hive-slack-agent.js +408 -408
  46. package/hive-slack.js +2417 -2367
  47. package/hive-stdio.js +172 -172
  48. package/hive-stop-hook.js +293 -293
  49. package/hive-throttle.js +118 -118
  50. package/hive-time.js +71 -71
  51. package/hive-transport.js +617 -578
  52. package/hive-update.js +58 -58
  53. package/hive-version.js +110 -110
  54. package/hive-webhook.js +55 -54
  55. package/icr-merge.js +58 -58
  56. package/icr.js +856 -851
  57. package/lang-brace.js +305 -305
  58. package/lang-js.js +695 -651
  59. package/lang-json.js +211 -211
  60. package/lang-python.js +588 -588
  61. package/lang-ruby.js +230 -230
  62. package/lang-toml.js +136 -136
  63. package/lang-yaml.js +183 -183
  64. package/limits.js +413 -413
  65. package/package.json +11 -3
  66. package/reconcile.cjs +621 -621
  67. package/slack-app-manifest-agent.json +61 -61
  68. package/slack-app-manifest-inbound.json +36 -36
  69. package/slack-app-manifest.json +27 -27
  70. package/substrate.js +252 -252
  71. package/sync.js +434 -60
  72. package/token.js +201 -201
package/core.js CHANGED
@@ -1,91 +1,91 @@
1
- // Shared pure logic, used by the sync clients and the agents — and unit-tested
2
- // in test.js. Keeping these here (instead of copy-pasted) means a fix in one
3
- // place fixes everywhere, and the tests exercise the REAL code.
4
-
5
- import reconcilePkg from './reconcile.cjs'
6
-
7
- export const {
8
- applyDiff,
9
- hasConflictMarkers,
10
- stripConflictMarkers,
11
- merge3,
12
- summarizeChange,
13
- changedRange,
14
- symbolsIn,
15
- icrMerge3,
16
- createReconciler,
17
- reconcile
18
- } = reconcilePkg
19
-
20
- // Optimistic concurrency: is a write based on `expected` still safe to apply?
21
- // Returns the new version on success, or { stale, current } if the region moved.
22
- export function safeBump(versions, region, expected) {
23
- const current = versions.get(region)
24
- if (current !== expected) return { stale: true, current }
25
- versions.set(region, (current ?? 0) + 1)
26
- return { ok: true, version: (current ?? 0) + 1 }
27
- }
28
-
29
- // Lock helpers (pessimistic concurrency). A lock is "alive" only if unexpired.
30
- export function lockHeldByOther(locks, file, me, now) {
31
- const l = locks.get(file)
32
- return l && l.owner !== me && l.exp > now ? l : null
33
- }
34
-
35
- // Deadlock-safe multi-file ordering: always acquire in a stable sorted order so
36
- // two agents can never form a circular wait (A holds 1 wants 2, B holds 2 wants 1).
37
- export function lockOrder(files) {
38
- return [...files].sort()
39
- }
40
-
41
- // Richer negotiation: when a lock holder gets a request, decide how to respond.
42
- // Returns one of:
43
- // grant — no conflict, hand over (after finishing)
44
- // counter — we both touch the same thing; propose taking turns
45
- // deny — the request is destructive while I'm still mid-edit; refuse for now
46
- // `holder` = { intent, done }, `request` = { from, summary }.
47
- export function negotiate(holder, request) {
48
- const h = (holder.intent || '').toLowerCase()
49
- const r = (request.summary || '').toLowerCase()
50
- if (/\b(delete|drop|remove|rewrite|overwrite)\b/.test(r) && !holder.done) {
51
- return { decision: 'deny', reason: 'that change is destructive and I am still mid-edit' }
52
- }
53
- const overlap = sharedWord(h, r)
54
- if (overlap && !holder.done) {
55
- return { decision: 'counter', reason: `we both touch "${overlap}"`, counter: 'let me finish, then it is yours' }
56
- }
57
- return { decision: 'grant', reason: 'no conflict' }
58
- }
59
-
60
- // Smallest shared "significant" word (len > 3) between two intent strings.
61
- function sharedWord(a, b) {
62
- const words = (s) => new Set(s.split(/[^a-z0-9]+/i).filter((w) => w.length > 3))
63
- const wb = words(b)
64
- for (const w of words(a)) if (wb.has(w)) return w
65
- return null
66
- }
67
-
68
- // --- Patch-apply-or-rework (for two writers in the SAME file) ---
69
- // 3-way line merge: given the `base` an agent read, the `mine` it produced, and
70
- // the `current` on the board now, decide what to write.
71
- // - current unchanged -> take mine
72
- // - I changed nothing -> take current
73
- // - changes on disjoint lines -> merge both (no rework)
74
- // - changes overlap the same lines -> { conflict } -> agent must re-do on current
75
- export function mergeEdit(base, mine, current) {
76
- if (current === base) return { ok: true, text: mine }
77
- if (mine === base) return { ok: true, text: current }
78
- if (mine === current) return { ok: true, text: mine }
79
- const b = base.split('\n')
80
- const mr = changedRange(b, mine.split('\n'))
81
- const tr = changedRange(b, current.split('\n'))
82
- if (mr.endBase <= tr.startBase || tr.endBase <= mr.startBase) {
83
- const out = b.slice()
84
- for (const e of [mr, tr].sort((x, y) => y.startBase - x.startBase)) {
85
- out.splice(e.startBase, e.endBase - e.startBase, ...e.newLines)
86
- }
87
- return { ok: true, text: out.join('\n') }
88
- }
89
- return { conflict: true } // same lines changed two ways -> re-reason on `current`
90
- }
91
-
1
+ // Shared pure logic, used by the sync clients and the agents — and unit-tested
2
+ // in test.js. Keeping these here (instead of copy-pasted) means a fix in one
3
+ // place fixes everywhere, and the tests exercise the REAL code.
4
+
5
+ import reconcilePkg from './reconcile.cjs'
6
+
7
+ export const {
8
+ applyDiff,
9
+ hasConflictMarkers,
10
+ stripConflictMarkers,
11
+ merge3,
12
+ summarizeChange,
13
+ changedRange,
14
+ symbolsIn,
15
+ icrMerge3,
16
+ createReconciler,
17
+ reconcile
18
+ } = reconcilePkg
19
+
20
+ // Optimistic concurrency: is a write based on `expected` still safe to apply?
21
+ // Returns the new version on success, or { stale, current } if the region moved.
22
+ export function safeBump(versions, region, expected) {
23
+ const current = versions.get(region)
24
+ if (current !== expected) return { stale: true, current }
25
+ versions.set(region, (current ?? 0) + 1)
26
+ return { ok: true, version: (current ?? 0) + 1 }
27
+ }
28
+
29
+ // Lock helpers (pessimistic concurrency). A lock is "alive" only if unexpired.
30
+ export function lockHeldByOther(locks, file, me, now) {
31
+ const l = locks.get(file)
32
+ return l && l.owner !== me && l.exp > now ? l : null
33
+ }
34
+
35
+ // Deadlock-safe multi-file ordering: always acquire in a stable sorted order so
36
+ // two agents can never form a circular wait (A holds 1 wants 2, B holds 2 wants 1).
37
+ export function lockOrder(files) {
38
+ return [...files].sort()
39
+ }
40
+
41
+ // Richer negotiation: when a lock holder gets a request, decide how to respond.
42
+ // Returns one of:
43
+ // grant — no conflict, hand over (after finishing)
44
+ // counter — we both touch the same thing; propose taking turns
45
+ // deny — the request is destructive while I'm still mid-edit; refuse for now
46
+ // `holder` = { intent, done }, `request` = { from, summary }.
47
+ export function negotiate(holder, request) {
48
+ const h = (holder.intent || '').toLowerCase()
49
+ const r = (request.summary || '').toLowerCase()
50
+ if (/\b(delete|drop|remove|rewrite|overwrite)\b/.test(r) && !holder.done) {
51
+ return { decision: 'deny', reason: 'that change is destructive and I am still mid-edit' }
52
+ }
53
+ const overlap = sharedWord(h, r)
54
+ if (overlap && !holder.done) {
55
+ return { decision: 'counter', reason: `we both touch "${overlap}"`, counter: 'let me finish, then it is yours' }
56
+ }
57
+ return { decision: 'grant', reason: 'no conflict' }
58
+ }
59
+
60
+ // Smallest shared "significant" word (len > 3) between two intent strings.
61
+ function sharedWord(a, b) {
62
+ const words = (s) => new Set(s.split(/[^a-z0-9]+/i).filter((w) => w.length > 3))
63
+ const wb = words(b)
64
+ for (const w of words(a)) if (wb.has(w)) return w
65
+ return null
66
+ }
67
+
68
+ // --- Patch-apply-or-rework (for two writers in the SAME file) ---
69
+ // 3-way line merge: given the `base` an agent read, the `mine` it produced, and
70
+ // the `current` on the board now, decide what to write.
71
+ // - current unchanged -> take mine
72
+ // - I changed nothing -> take current
73
+ // - changes on disjoint lines -> merge both (no rework)
74
+ // - changes overlap the same lines -> { conflict } -> agent must re-do on current
75
+ export function mergeEdit(base, mine, current) {
76
+ if (current === base) return { ok: true, text: mine }
77
+ if (mine === base) return { ok: true, text: current }
78
+ if (mine === current) return { ok: true, text: mine }
79
+ const b = base.split('\n')
80
+ const mr = changedRange(b, mine.split('\n'))
81
+ const tr = changedRange(b, current.split('\n'))
82
+ if (mr.endBase <= tr.startBase || tr.endBase <= mr.startBase) {
83
+ const out = b.slice()
84
+ for (const e of [mr, tr].sort((x, y) => y.startBase - x.startBase)) {
85
+ out.splice(e.startBase, e.endBase - e.startBase, ...e.newLines)
86
+ }
87
+ return { ok: true, text: out.join('\n') }
88
+ }
89
+ return { conflict: true } // same lines changed two ways -> re-reason on `current`
90
+ }
91
+