@hivefloor/cli 0.1.5 → 0.1.8

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 (48) hide show
  1. package/LICENSE +6 -20
  2. package/README.md +29 -8
  3. package/dist/chunk-2ERPDCOT.js +38 -0
  4. package/dist/chunk-4G362W6G.js +19 -0
  5. package/dist/chunk-5OJUJCE3.js +817 -0
  6. package/dist/{chunk-U6RRUAC2.js → chunk-5XXYQQG6.js} +53 -8
  7. package/dist/chunk-AGIYVFDQ.js +10984 -0
  8. package/dist/{chunk-RYGL6XU4.js → chunk-BLLPDPTL.js} +4 -2
  9. package/dist/{chunk-3N5JYP5O.js → chunk-FPJNGKT5.js} +5 -3
  10. package/dist/chunk-HW3KRNCO.js +201 -0
  11. package/dist/{chunk-4DRHR7LR.js → chunk-HWBUESB4.js} +1158 -196
  12. package/dist/{chunk-C627OKTW.js → chunk-K2IRTZH5.js} +7 -6
  13. package/dist/chunk-KQMPCV57.js +122 -0
  14. package/dist/{chunk-J36OIJBM.js → chunk-L6EFW2SJ.js} +14 -10
  15. package/dist/{chunk-IJRHCDIG.js → chunk-LX5A25O6.js} +4 -2
  16. package/dist/{chunk-MZGGJ6ZS.js → chunk-MYJCU5JL.js} +4 -2
  17. package/dist/{chunk-H6NYMF2D.js → chunk-NMUH5NXN.js} +6 -4
  18. package/dist/{chunk-VX7SCIF2.js → chunk-NRJONTFT.js} +3 -1
  19. package/dist/chunk-QBBKGORP.js +327 -0
  20. package/dist/{chunk-SOXRITAW.js → chunk-QGULSOQ2.js} +3 -0
  21. package/dist/{chunk-6MDJB3BV.js → chunk-QLMLB7RB.js} +17 -9
  22. package/dist/{chunk-TKMIV7BG.js → chunk-QPAFN47B.js} +3 -1
  23. package/dist/chunk-SBOEAOHD.js +48 -0
  24. package/dist/{chunk-IWIDKNWC.js → chunk-TIR4CV3P.js} +21 -17
  25. package/dist/{chunk-6XVIEX75.js → chunk-X2KH6AR4.js} +25 -303
  26. package/dist/chunk-XAXKZ572.js +106 -0
  27. package/dist/{chunk-TPMFQUAW.js → chunk-XPGL7VYE.js} +12 -0
  28. package/dist/{cli-JCBZICR3.js → cli-BFOJWJNG.js} +56 -20
  29. package/dist/connect-ZJ4JXBAJ.js +27 -0
  30. package/dist/control-6GHTZQJV.js +25 -0
  31. package/dist/{disconnect-WQMDCUXT.js → disconnect-3T25NTKX.js} +24 -17
  32. package/dist/{hook-AYJNRGIY.js → hook-TPSHBCWU.js} +277 -17
  33. package/dist/index.js +9 -6
  34. package/dist/{link-ORT4LID6.js → link-EAS5F5PC.js} +14 -11
  35. package/dist/{machine-connect-N52CKQEW.js → machine-connect-KEI4BRWF.js} +23 -17
  36. package/dist/mcp-LVIYR3EN.js +1882 -0
  37. package/dist/orch-KVRL2YA2.js +137 -0
  38. package/dist/{run-ZAZ45MKQ.js → run-JL2OZWK3.js} +1920 -28
  39. package/dist/{status-GOCFNO7K.js → status-QXOOJGGN.js} +14 -11
  40. package/dist/{token-EMM4AJAU.js → token-BFWWQIDA.js} +10 -7
  41. package/dist/{voice-F5MIS3IZ.js → voice-QXHFXRWG.js} +5 -3
  42. package/dist/{where-XFXRTP7E.js → where-CMUORQIO.js} +11 -8
  43. package/package.json +5 -6
  44. package/dist/chunk-JCLWCMEM.js +0 -8
  45. package/dist/chunk-K3NQKI34.js +0 -10
  46. package/dist/chunk-X6B6R32A.js +0 -303
  47. package/dist/connect-2HLVPEOL.js +0 -23
  48. package/dist/mcp-2SF6Y73M.js +0 -118
@@ -1,40 +1,43 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __hfCreateRequire } from 'node:module';
3
+ const require = __hfCreateRequire(import.meta.url);
2
4
  import {
3
5
  detectRepo
4
- } from "./chunk-RYGL6XU4.js";
6
+ } from "./chunk-BLLPDPTL.js";
5
7
  import {
6
8
  resolveSession
7
- } from "./chunk-H6NYMF2D.js";
9
+ } from "./chunk-NMUH5NXN.js";
8
10
  import {
9
11
  SCHTASKS_TASK,
10
12
  hostKey,
11
13
  readCredentials,
12
14
  windowsServiceStatus
13
- } from "./chunk-6MDJB3BV.js";
15
+ } from "./chunk-QLMLB7RB.js";
14
16
  import {
15
17
  checkUnknownFlags
16
- } from "./chunk-TKMIV7BG.js";
18
+ } from "./chunk-QPAFN47B.js";
17
19
  import {
18
20
  profileKeys
19
- } from "./chunk-J36OIJBM.js";
21
+ } from "./chunk-L6EFW2SJ.js";
20
22
  import {
21
23
  SERVICE_ALIVE_MS,
22
24
  readMachine,
23
25
  readServiceState
24
- } from "./chunk-IJRHCDIG.js";
26
+ } from "./chunk-LX5A25O6.js";
25
27
  import {
26
28
  apiRequest,
27
29
  errorOf
28
- } from "./chunk-VX7SCIF2.js";
29
- import "./chunk-TPMFQUAW.js";
30
+ } from "./chunk-NRJONTFT.js";
31
+ import "./chunk-XAXKZ572.js";
32
+ import "./chunk-XPGL7VYE.js";
30
33
  import {
31
34
  machineName,
32
35
  runCmd
33
- } from "./chunk-SOXRITAW.js";
36
+ } from "./chunk-QGULSOQ2.js";
34
37
  import {
35
38
  cliNpxCommand
36
- } from "./chunk-4DRHR7LR.js";
37
- import "./chunk-K3NQKI34.js";
39
+ } from "./chunk-HWBUESB4.js";
40
+ import "./chunk-2ERPDCOT.js";
38
41
 
39
42
  // src/status.ts
40
43
  var str = (v) => typeof v === "string" ? v : void 0;
@@ -1,17 +1,20 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __hfCreateRequire } from 'node:module';
3
+ const require = __hfCreateRequire(import.meta.url);
2
4
  import {
3
5
  resolveSession
4
- } from "./chunk-H6NYMF2D.js";
5
- import "./chunk-6MDJB3BV.js";
6
+ } from "./chunk-NMUH5NXN.js";
7
+ import "./chunk-QLMLB7RB.js";
6
8
  import {
7
9
  checkUnknownFlags
8
- } from "./chunk-TKMIV7BG.js";
9
- import "./chunk-TPMFQUAW.js";
10
- import "./chunk-SOXRITAW.js";
10
+ } from "./chunk-QPAFN47B.js";
11
+ import "./chunk-XAXKZ572.js";
12
+ import "./chunk-XPGL7VYE.js";
13
+ import "./chunk-QGULSOQ2.js";
11
14
  import {
12
15
  cliNpxCommand
13
- } from "./chunk-4DRHR7LR.js";
14
- import "./chunk-K3NQKI34.js";
16
+ } from "./chunk-HWBUESB4.js";
17
+ import "./chunk-2ERPDCOT.js";
15
18
 
16
19
  // src/token.ts
17
20
  var TOKEN_FLAGS = /* @__PURE__ */ new Set(["reveal", "host", "tool", "help", "h"]);
@@ -1,14 +1,16 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __hfCreateRequire } from 'node:module';
3
+ const require = __hfCreateRequire(import.meta.url);
2
4
  import {
3
5
  checkUnknownFlags,
4
6
  flagStr
5
- } from "./chunk-TKMIV7BG.js";
7
+ } from "./chunk-QPAFN47B.js";
6
8
  import {
7
9
  KOKORO_VOICES,
8
10
  KOKORO_VOICE_ID,
9
11
  voiceFor
10
- } from "./chunk-4DRHR7LR.js";
11
- import "./chunk-K3NQKI34.js";
12
+ } from "./chunk-HWBUESB4.js";
13
+ import "./chunk-2ERPDCOT.js";
12
14
 
13
15
  // src/voice/index.ts
14
16
  import fs2 from "fs";
@@ -1,23 +1,26 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __hfCreateRequire } from 'node:module';
3
+ const require = __hfCreateRequire(import.meta.url);
2
4
  import {
3
5
  resolveSession
4
- } from "./chunk-H6NYMF2D.js";
5
- import "./chunk-6MDJB3BV.js";
6
+ } from "./chunk-NMUH5NXN.js";
7
+ import "./chunk-QLMLB7RB.js";
6
8
  import {
7
9
  checkUnknownFlags
8
- } from "./chunk-TKMIV7BG.js";
10
+ } from "./chunk-QPAFN47B.js";
9
11
  import {
10
12
  apiRequest,
11
13
  errorOf
12
- } from "./chunk-VX7SCIF2.js";
13
- import "./chunk-TPMFQUAW.js";
14
- import "./chunk-SOXRITAW.js";
14
+ } from "./chunk-NRJONTFT.js";
15
+ import "./chunk-XAXKZ572.js";
16
+ import "./chunk-XPGL7VYE.js";
17
+ import "./chunk-QGULSOQ2.js";
15
18
  import {
16
19
  cliNpxCommand,
17
20
  routeProviderFromParam,
18
21
  usageRouteSchema
19
- } from "./chunk-4DRHR7LR.js";
20
- import "./chunk-K3NQKI34.js";
22
+ } from "./chunk-HWBUESB4.js";
23
+ import "./chunk-2ERPDCOT.js";
21
24
 
22
25
  // src/where.ts
23
26
  var WHERE_FLAGS = /* @__PURE__ */ new Set(["json", "host", "tool", "help", "h"]);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hivefloor/cli",
3
- "version": "0.1.5",
4
- "description": "Connect your coding agents (Claude Code, Codex, Cursor, Gemini, Grok) to Hivefloor: live presence, task coordination and usage on one floor.",
3
+ "version": "0.1.8",
4
+ "description": "Connect your coding agents (Claude Code, Codex, Cursor, Gemini, Grok) to HiveFloor: live presence, task coordination and usage on one floor.",
5
5
  "author": {
6
6
  "name": "Zan",
7
7
  "url": "https://github.com/Errr0rr404"
@@ -18,14 +18,13 @@
18
18
  ],
19
19
  "homepage": "https://hivefloor.worldofz.info",
20
20
  "bugs": {
21
- "url": "https://github.com/Errr0rr404/hivefloor/issues"
21
+ "url": "https://github.com/Errr0rr404/hivefloor-cli/issues"
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/Errr0rr404/hivefloor.git",
26
- "directory": "packages/cli"
25
+ "url": "git+https://github.com/Errr0rr404/hivefloor-cli.git"
27
26
  },
28
- "license": "MIT",
27
+ "license": "UNLICENSED",
29
28
  "type": "module",
30
29
  "bin": {
31
30
  "hivefloor": "dist/index.js"
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/hookclock.ts
4
- var HARD_EXIT_MS = 4e3;
5
-
6
- export {
7
- HARD_EXIT_MS
8
- };
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
7
-
8
- export {
9
- __export
10
- };
@@ -1,303 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- configDir,
4
- readText,
5
- removeFile,
6
- serviceLogFile,
7
- spoolFile
8
- } from "./chunk-TPMFQUAW.js";
9
-
10
- // src/spool.ts
11
- import fs from "fs";
12
- import path from "path";
13
- var SPOOL_MAX_BYTES = 1024 * 1024;
14
- var LOCK_STALE_MS = 1e4;
15
- var CLAIM_STALE_MS = 6e4;
16
- var LOCK_WAIT_MS = 250;
17
- var CAP_SLACK = 64 * 1024;
18
- var counter = 0;
19
- var uniq = () => `${Date.now()}-${process.pid}-${counter++}`;
20
- function parseSpool(text) {
21
- const out = [];
22
- for (const line of text.split("\n")) {
23
- if (!line.trim()) continue;
24
- try {
25
- out.push(JSON.parse(line));
26
- } catch {
27
- }
28
- }
29
- return out;
30
- }
31
- function capped(events, maxBytes = SPOOL_MAX_BYTES) {
32
- const lines = events.map((e) => JSON.stringify(e));
33
- let total = lines.reduce((n, l) => n + Buffer.byteLength(l) + 1, 0);
34
- let start = 0;
35
- while (total > maxBytes && start < lines.length) {
36
- total -= Buffer.byteLength(lines[start]) + 1;
37
- start += 1;
38
- }
39
- return { events: events.slice(start), dropped: start };
40
- }
41
- function droppedEvents(file = spoolFile()) {
42
- try {
43
- return Number(fs.readFileSync(`${file}.dropped`, "utf8").trim()) || 0;
44
- } catch {
45
- return 0;
46
- }
47
- }
48
- function noteDropped(spool, dropped) {
49
- if (dropped <= 0) return;
50
- try {
51
- fs.writeFileSync(`${spool}.dropped`, String(droppedEvents(spool) + dropped), { mode: 384 });
52
- } catch {
53
- }
54
- try {
55
- fs.appendFileSync(serviceLogFile(), `${(/* @__PURE__ */ new Date()).toISOString()} spool full: dropped ${dropped} event(s), the cap is ${SPOOL_MAX_BYTES} bytes
56
- `, { mode: 384 });
57
- } catch {
58
- }
59
- }
60
- function pause(ms) {
61
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
62
- }
63
- var lockPath = (file) => `${file}.lock`;
64
- function acquireLock(file) {
65
- const lp = lockPath(file);
66
- const deadline = Date.now() + LOCK_WAIT_MS;
67
- for (; ; ) {
68
- try {
69
- fs.closeSync(fs.openSync(lp, "wx", 384));
70
- return true;
71
- } catch (e) {
72
- if (e.code !== "EEXIST") return false;
73
- }
74
- try {
75
- if (Date.now() - fs.statSync(lp).mtimeMs > LOCK_STALE_MS) {
76
- fs.rmSync(lp, { force: true });
77
- continue;
78
- }
79
- } catch {
80
- continue;
81
- }
82
- if (Date.now() >= deadline) return false;
83
- pause(5);
84
- }
85
- }
86
- function releaseLock(file) {
87
- removeFile(lockPath(file));
88
- }
89
- var claimPath = (file) => `${file}.claim-${uniq()}`;
90
- var pendingPath = (file) => `${file}.pending-${uniq()}`;
91
- function sideFiles(dir, file, kind) {
92
- const prefix = `${path.basename(file)}.${kind}-`;
93
- let names;
94
- try {
95
- names = fs.readdirSync(dir);
96
- } catch {
97
- return [];
98
- }
99
- return names.filter((n) => n.startsWith(prefix)).sort().map((n) => path.join(dir, n));
100
- }
101
- function owner(file) {
102
- const m = /\.(?:claim|pending)-(\d+)-(\d+)-\d+$/.exec(path.basename(file));
103
- if (!m) return void 0;
104
- return { ts: Number(m[1]), pid: Number(m[2]) };
105
- }
106
- function alive(pid) {
107
- if (pid === process.pid) return true;
108
- try {
109
- process.kill(pid, 0);
110
- return true;
111
- } catch (e) {
112
- return e.code === "EPERM";
113
- }
114
- }
115
- function abandoned(file) {
116
- const o = owner(file);
117
- if (!o) return false;
118
- if (!alive(o.pid)) return true;
119
- return Date.now() - o.ts > CLAIM_STALE_MS;
120
- }
121
- function writeEvents(file, events) {
122
- const tmp = `${file}.tmp-${process.pid}-${counter++}`;
123
- try {
124
- fs.writeFileSync(tmp, events.map((e) => JSON.stringify(e)).join("\n") + (events.length ? "\n" : ""), { mode: 384 });
125
- fs.renameSync(tmp, file);
126
- } catch (e) {
127
- removeFile(tmp);
128
- throw e;
129
- }
130
- }
131
- function writeSpool(file, events, maxBytes = SPOOL_MAX_BYTES) {
132
- const { events: kept, dropped } = capped(events, maxBytes);
133
- if (dropped > 0) noteDropped(file, dropped);
134
- writeEvents(file, kept);
135
- }
136
- function recover(file) {
137
- const dir = path.dirname(file);
138
- const stale = [...sideFiles(dir, file, "claim").filter(abandoned), ...sideFiles(dir, file, "pending")].sort();
139
- if (stale.length === 0) return;
140
- const events = [];
141
- for (const f of stale) events.push(...parseSpool(readText(f) ?? ""));
142
- if (events.length > 0) {
143
- const existing = parseSpool(readText(file) ?? "");
144
- writeSpool(file, [...events, ...existing]);
145
- }
146
- for (const f of stale) removeFile(f);
147
- }
148
- function takeSpool(file = spoolFile()) {
149
- fs.mkdirSync(configDir(), { recursive: true, mode: 448 });
150
- if (!acquireLock(file)) return void 0;
151
- try {
152
- recover(file);
153
- const claim = claimPath(file);
154
- try {
155
- fs.renameSync(file, claim);
156
- } catch {
157
- return void 0;
158
- }
159
- let events;
160
- try {
161
- events = parseSpool(fs.readFileSync(claim, "utf8"));
162
- } catch {
163
- return void 0;
164
- }
165
- if (events.length === 0) {
166
- removeFile(claim);
167
- return void 0;
168
- }
169
- return { spool: file, file: claim, events };
170
- } finally {
171
- releaseLock(file);
172
- }
173
- }
174
- function releaseSpool(claim, keep, spool = spoolFile()) {
175
- if (keep.length === 0) {
176
- if (claim) removeFile(claim.file);
177
- return;
178
- }
179
- const target = claim?.spool ?? spool;
180
- try {
181
- returnToSpool(keep, target);
182
- } catch {
183
- if (claim) {
184
- try {
185
- writeEvents(claim.file, keep);
186
- } catch {
187
- }
188
- return;
189
- }
190
- try {
191
- writeEvents(pendingPath(target), keep);
192
- } catch {
193
- }
194
- return;
195
- }
196
- if (claim) removeFile(claim.file);
197
- }
198
- function returnToSpool(events, file = spoolFile()) {
199
- if (events.length === 0) return;
200
- fs.mkdirSync(configDir(), { recursive: true, mode: 448 });
201
- if (!acquireLock(file)) {
202
- writeEvents(pendingPath(file), events);
203
- return;
204
- }
205
- try {
206
- const existing = parseSpool(readText(file) ?? "");
207
- writeSpool(file, [...events, ...existing]);
208
- } finally {
209
- releaseLock(file);
210
- }
211
- }
212
- function appendToSpool(event, file = spoolFile()) {
213
- fs.mkdirSync(configDir(), { recursive: true, mode: 448 });
214
- const line = JSON.stringify(event) + "\n";
215
- if (!acquireLock(file)) {
216
- fs.appendFileSync(file, line, { mode: 384 });
217
- return;
218
- }
219
- try {
220
- fs.appendFileSync(file, line, { mode: 384 });
221
- let size = 0;
222
- try {
223
- size = fs.statSync(file).size;
224
- } catch {
225
- size = 0;
226
- }
227
- if (size > SPOOL_MAX_BYTES) writeSpool(file, parseSpool(readText(file) ?? ""), SPOOL_MAX_BYTES - CAP_SLACK);
228
- } finally {
229
- releaseLock(file);
230
- }
231
- }
232
-
233
- // src/nudge.ts
234
- import fs2 from "fs";
235
- import path2 from "path";
236
- var STASH_TTL_MS = 24 * 36e5;
237
- var nudgeStashFile = () => path2.join(configDir(), "nudges.jsonl");
238
- var CONTEXT_EVENTS = {
239
- claude: ["UserPromptSubmit", "SessionStart", "PreToolUse", "PostToolUse"],
240
- codex: ["UserPromptSubmit", "SessionStart"]
241
- };
242
- function contextEventName(tool, native) {
243
- return CONTEXT_EVENTS[tool]?.find((e) => e.toLowerCase() === native.toLowerCase()) ?? null;
244
- }
245
- var isNudge = (v) => typeof v === "object" && v !== null && typeof v.session_id === "string" && typeof v.text === "string";
246
- function nudgesOf(json) {
247
- const list = typeof json === "object" && json !== null ? json.nudges : void 0;
248
- return Array.isArray(list) ? list.filter(isNudge) : [];
249
- }
250
- function contextOutput(hookEventName, texts) {
251
- return JSON.stringify({ hookSpecificOutput: { hookEventName, additionalContext: texts.join("\n\n") } });
252
- }
253
- function stashNudges(nudges, nowMs, file = nudgeStashFile()) {
254
- if (nudges.length === 0) return;
255
- try {
256
- fs2.mkdirSync(path2.dirname(file), { recursive: true, mode: 448 });
257
- fs2.appendFileSync(file, nudges.map((n) => `${JSON.stringify({ ...n, at: nowMs })}
258
- `).join(""), { mode: 384 });
259
- } catch {
260
- }
261
- }
262
- function takeStashed(sessionId, nowMs, file = nudgeStashFile()) {
263
- if (!fs2.existsSync(file)) return [];
264
- const claim = `${file}.${process.pid}-${nowMs}`;
265
- try {
266
- fs2.renameSync(file, claim);
267
- } catch {
268
- return [];
269
- }
270
- const mine = [];
271
- const rest = [];
272
- try {
273
- for (const line of fs2.readFileSync(claim, "utf8").split("\n")) {
274
- if (!line.trim()) continue;
275
- try {
276
- const n = JSON.parse(line);
277
- if (!isNudge(n) || nowMs - (n.at ?? 0) > STASH_TTL_MS) continue;
278
- if (n.session_id === sessionId) mine.push(n.text);
279
- else rest.push(line);
280
- } catch {
281
- }
282
- }
283
- if (rest.length > 0) fs2.appendFileSync(file, `${rest.join("\n")}
284
- `, { mode: 384 });
285
- } catch {
286
- }
287
- try {
288
- fs2.rmSync(claim, { force: true });
289
- } catch {
290
- }
291
- return mine;
292
- }
293
-
294
- export {
295
- takeSpool,
296
- releaseSpool,
297
- appendToSpool,
298
- contextEventName,
299
- nudgesOf,
300
- contextOutput,
301
- stashNudges,
302
- takeStashed
303
- };
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- connect,
4
- connectAgent,
5
- resolveHost
6
- } from "./chunk-IWIDKNWC.js";
7
- import "./chunk-3N5JYP5O.js";
8
- import "./chunk-6XVIEX75.js";
9
- import "./chunk-RYGL6XU4.js";
10
- import "./chunk-6MDJB3BV.js";
11
- import "./chunk-TKMIV7BG.js";
12
- import "./chunk-C627OKTW.js";
13
- import "./chunk-IJRHCDIG.js";
14
- import "./chunk-VX7SCIF2.js";
15
- import "./chunk-TPMFQUAW.js";
16
- import "./chunk-SOXRITAW.js";
17
- import "./chunk-4DRHR7LR.js";
18
- import "./chunk-K3NQKI34.js";
19
- export {
20
- connect,
21
- connectAgent,
22
- resolveHost
23
- };
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- detectRepo
4
- } from "./chunk-RYGL6XU4.js";
5
- import {
6
- resolveSession
7
- } from "./chunk-H6NYMF2D.js";
8
- import "./chunk-6MDJB3BV.js";
9
- import {
10
- checkUnknownFlags,
11
- flagStr
12
- } from "./chunk-TKMIV7BG.js";
13
- import {
14
- toolFromEnv
15
- } from "./chunk-TPMFQUAW.js";
16
- import {
17
- assertTokenTransport,
18
- sameOrigin
19
- } from "./chunk-SOXRITAW.js";
20
- import {
21
- cliNpxCommand
22
- } from "./chunk-4DRHR7LR.js";
23
- import "./chunk-K3NQKI34.js";
24
-
25
- // src/mcp.ts
26
- import os from "os";
27
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
28
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
29
- async function contextHeaders(ctx, token, toolName) {
30
- const h = { Authorization: `Bearer ${token}`, "X-HF-Tool": ctx.env.HIVEFLOOR_TOOL || toolFromEnv(ctx.env) || toolName, "X-HF-Machine": os.hostname().split(".")[0] ?? "machine" };
31
- const session = ctx.env.HIVEFLOOR_SESSION || ctx.env.CLAUDE_SESSION_ID || ctx.env.GROK_SESSION_ID || ctx.env.CODEX_SESSION_ID;
32
- if (session) h["X-HF-Session"] = session;
33
- const model = ctx.env.HIVEFLOOR_MODEL || ctx.env.ANTHROPIC_MODEL;
34
- if (model) h["X-HF-Model"] = model;
35
- const repo = await detectRepo(ctx.cwd);
36
- if (repo) {
37
- h["X-HF-Repo"] = repo.remote;
38
- if (repo.branch) h["X-HF-Branch"] = repo.branch;
39
- if (repo.path) h["X-HF-Path"] = repo.path;
40
- }
41
- return h;
42
- }
43
- var isRequest = (m) => "method" in m && "id" in m;
44
- function mcpTargetUrl(flagUrl, host) {
45
- try {
46
- return assertTokenTransport(flagUrl ?? `${host}/mcp`);
47
- } catch (e) {
48
- if (flagUrl && e.message === "not a URL") throw new Error("--url is not a URL");
49
- throw e;
50
- }
51
- }
52
- var MCP_FLAGS = /* @__PURE__ */ new Set(["url", "host", "tool", "help", "h"]);
53
- async function runMcpProxy(ctx, p, io = { stdin: process.stdin, stdout: process.stdout }) {
54
- const unknown = checkUnknownFlags(p, MCP_FLAGS);
55
- if (unknown) {
56
- ctx.err(`hivefloor: unknown flag "--${unknown}". Run "hivefloor help".
57
- `);
58
- return 2;
59
- }
60
- const s = await resolveSession(ctx, p);
61
- if (!s) {
62
- ctx.err(`hivefloor: not connected. Run: ${cliNpxCommand("connect")}
63
- `);
64
- return 1;
65
- }
66
- let url;
67
- try {
68
- url = mcpTargetUrl(flagStr(p, "url"), s.host);
69
- } catch (e) {
70
- ctx.err(`hivefloor mcp: ${e.message}
71
- `);
72
- return 1;
73
- }
74
- if (!sameOrigin(url.origin, s.host)) {
75
- ctx.err(`hivefloor mcp: refusing to send the token of ${s.host} to ${url.origin}; --url must be the same host
76
- `);
77
- return 1;
78
- }
79
- const headers = await contextHeaders(ctx, s.token, s.tool);
80
- const upstream = new StreamableHTTPClientTransport(url, { requestInit: { headers } });
81
- const downstream = new StdioServerTransport(io.stdin, io.stdout);
82
- return await new Promise((resolve) => {
83
- let closing = false;
84
- const finish = (code) => {
85
- if (closing) return;
86
- closing = true;
87
- void Promise.allSettled([upstream.close(), downstream.close()]).then(() => resolve(code));
88
- };
89
- downstream.onmessage = (msg) => {
90
- upstream.send(msg).catch((e) => {
91
- if (isRequest(msg)) void downstream.send({ jsonrpc: "2.0", id: msg.id, error: { code: -32e3, message: `Hivefloor is not reachable: ${e.message}` } });
92
- });
93
- };
94
- upstream.onmessage = (msg) => {
95
- const result = msg.result;
96
- if (result && typeof result.protocolVersion === "string") upstream.setProtocolVersion?.(result.protocolVersion);
97
- void downstream.send(msg);
98
- };
99
- upstream.onerror = (e) => ctx.err(`hivefloor mcp: ${e.message}
100
- `);
101
- downstream.onerror = (e) => ctx.err(`hivefloor mcp: ${e.message}
102
- `);
103
- downstream.onclose = () => finish(0);
104
- io.stdin.once("end", () => finish(0));
105
- io.stdin.once("close", () => finish(0));
106
- upstream.onclose = () => finish(0);
107
- upstream.start().then(() => downstream.start()).catch((e) => {
108
- ctx.err(`hivefloor mcp: ${e.message}
109
- `);
110
- finish(1);
111
- });
112
- });
113
- }
114
- export {
115
- contextHeaders,
116
- mcpTargetUrl,
117
- runMcpProxy
118
- };