@hivefloor/cli 0.1.4 → 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.
- package/LICENSE +6 -20
- package/README.md +31 -9
- package/dist/chunk-2ERPDCOT.js +38 -0
- package/dist/chunk-4G362W6G.js +19 -0
- package/dist/chunk-5OJUJCE3.js +817 -0
- package/dist/chunk-5XXYQQG6.js +274 -0
- package/dist/chunk-AGIYVFDQ.js +10984 -0
- package/dist/{chunk-2BSA7LFD.js → chunk-BLLPDPTL.js} +7 -3
- package/dist/{chunk-R5KDI4WI.js → chunk-FPJNGKT5.js} +9 -3
- package/dist/chunk-HW3KRNCO.js +201 -0
- package/dist/{chunk-ZC2DAKB5.js → chunk-HWBUESB4.js} +1500 -316
- package/dist/{chunk-DNG5CRT3.js → chunk-K2IRTZH5.js} +8 -7
- package/dist/chunk-KQMPCV57.js +122 -0
- package/dist/{chunk-UJ4BQFWV.js → chunk-L6EFW2SJ.js} +53 -31
- package/dist/{chunk-T7TG6WA4.js → chunk-LX5A25O6.js} +4 -2
- package/dist/{chunk-W7DROKC7.js → chunk-MYJCU5JL.js} +89 -13
- package/dist/chunk-NMUH5NXN.js +52 -0
- package/dist/chunk-NRJONTFT.js +67 -0
- package/dist/chunk-QBBKGORP.js +327 -0
- package/dist/chunk-QGULSOQ2.js +142 -0
- package/dist/{chunk-PDXYOREI.js → chunk-QLMLB7RB.js} +110 -31
- package/dist/{chunk-TKMIV7BG.js → chunk-QPAFN47B.js} +3 -1
- package/dist/chunk-SBOEAOHD.js +48 -0
- package/dist/{chunk-SD65CIIY.js → chunk-TIR4CV3P.js} +117 -33
- package/dist/{chunk-QHYZBHXO.js → chunk-X2KH6AR4.js} +195 -251
- package/dist/chunk-XAXKZ572.js +106 -0
- package/dist/{chunk-VNCQFFQO.js → chunk-XPGL7VYE.js} +114 -1
- package/dist/cli-BFOJWJNG.js +279 -0
- package/dist/connect-ZJ4JXBAJ.js +27 -0
- package/dist/control-6GHTZQJV.js +25 -0
- package/dist/{disconnect-MKRHK4CX.js → disconnect-3T25NTKX.js} +55 -34
- package/dist/hook-TPSHBCWU.js +575 -0
- package/dist/index.js +9 -6
- package/dist/{link-HXBMMSG3.js → link-EAS5F5PC.js} +34 -18
- package/dist/{machine-connect-BYHZRRRB.js → machine-connect-KEI4BRWF.js} +30 -24
- package/dist/mcp-LVIYR3EN.js +1882 -0
- package/dist/orch-KVRL2YA2.js +137 -0
- package/dist/{run-336BSU72.js → run-JL2OZWK3.js} +1933 -29
- package/dist/{status-KBBSAADD.js → status-QXOOJGGN.js} +29 -14
- package/dist/token-BFWWQIDA.js +44 -0
- package/dist/voice-QXHFXRWG.js +264 -0
- package/dist/{where-KR7VWSEC.js → where-CMUORQIO.js} +20 -8
- package/package.json +6 -7
- package/dist/chunk-2IMJECYD.js +0 -71
- package/dist/chunk-7KF7IQJN.js +0 -30
- package/dist/chunk-GT3HFFT4.js +0 -132
- package/dist/chunk-JCLWCMEM.js +0 -8
- package/dist/chunk-K3NQKI34.js +0 -10
- package/dist/chunk-O2TC3WSS.js +0 -303
- package/dist/chunk-PY74LT2W.js +0 -41
- package/dist/cli-P3DYE5IR.js +0 -103
- package/dist/connect-ACNM5DQG.js +0 -23
- package/dist/hook-KR2HGVAR.js +0 -301
- package/dist/mcp-N2TMD4GR.js +0 -121
- package/dist/token-JDRLEV5D.js +0 -32
package/dist/chunk-GT3HFFT4.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
CLAUDE_EVENTS,
|
|
4
|
-
CODEX_EVENTS,
|
|
5
|
-
addCreated,
|
|
6
|
-
addHooks,
|
|
7
|
-
editJson,
|
|
8
|
-
enableFeatureHooks,
|
|
9
|
-
forgetCreated,
|
|
10
|
-
removeHooks,
|
|
11
|
-
restoreFeatureHooks,
|
|
12
|
-
wasCreated
|
|
13
|
-
} from "./chunk-QHYZBHXO.js";
|
|
14
|
-
import {
|
|
15
|
-
claudeConfigDirs,
|
|
16
|
-
codexConfigDir,
|
|
17
|
-
profileKeys
|
|
18
|
-
} from "./chunk-UJ4BQFWV.js";
|
|
19
|
-
import {
|
|
20
|
-
atomicWrite,
|
|
21
|
-
backupOnce,
|
|
22
|
-
cliDir,
|
|
23
|
-
cliEntry,
|
|
24
|
-
dropBackupIfSame,
|
|
25
|
-
isDir,
|
|
26
|
-
readText,
|
|
27
|
-
removeFile
|
|
28
|
-
} from "./chunk-VNCQFFQO.js";
|
|
29
|
-
|
|
30
|
-
// src/machine-hooks.ts
|
|
31
|
-
import fs from "fs";
|
|
32
|
-
import path from "path";
|
|
33
|
-
function installCliCopy(srcDir) {
|
|
34
|
-
if (!fs.existsSync(path.join(srcDir, "index.js"))) throw new Error(`cannot find the CLI bundle in ${srcDir}`);
|
|
35
|
-
const dest = cliDir();
|
|
36
|
-
fs.mkdirSync(dest, { recursive: true, mode: 448 });
|
|
37
|
-
for (const f of fs.readdirSync(srcDir)) {
|
|
38
|
-
if (!/\.(?:js|mjs)$/.test(f)) continue;
|
|
39
|
-
const tmp = path.join(dest, `${f}.${process.pid}.tmp`);
|
|
40
|
-
fs.copyFileSync(path.join(srcDir, f), tmp);
|
|
41
|
-
fs.renameSync(tmp, path.join(dest, f));
|
|
42
|
-
}
|
|
43
|
-
fs.writeFileSync(path.join(dest, "package.json"), '{"type":"module"}\n');
|
|
44
|
-
}
|
|
45
|
-
var removeCliCopy = () => fs.rmSync(cliDir(), { recursive: true, force: true });
|
|
46
|
-
function claudeMachineSpecs(node, profile) {
|
|
47
|
-
return CLAUDE_EVENTS.map((event) => ({
|
|
48
|
-
event,
|
|
49
|
-
...event === "Notification" ? { matcher: "permission_prompt|idle_prompt" } : {},
|
|
50
|
-
// Exec form: no shell, no quoting. async: the hook never slows the agent down.
|
|
51
|
-
entry: { type: "command", command: node, args: [cliEntry(), "hook", "claude", event, "--profile", profile], async: true }
|
|
52
|
-
}));
|
|
53
|
-
}
|
|
54
|
-
var q = (s) => `"${s.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
55
|
-
function codexMachineSpecs(node, profile) {
|
|
56
|
-
return CODEX_EVENTS.map((event) => ({ event, entry: { type: "command", command: `${q(node)} ${q(cliEntry())} hook codex ${event} --profile ${profile}` } }));
|
|
57
|
-
}
|
|
58
|
-
function installMachineHooks(node, opts) {
|
|
59
|
-
const res = { claude_dirs: [], lines: [], warnings: [] };
|
|
60
|
-
const dirs = claudeConfigDirs(opts.processDirs).filter(isDir);
|
|
61
|
-
const keys = profileKeys("claude", dirs);
|
|
62
|
-
for (const dir of dirs) {
|
|
63
|
-
const file = path.join(dir, "settings.json");
|
|
64
|
-
try {
|
|
65
|
-
editJson(file, (d) => (addHooks(d, "nested", claudeMachineSpecs(node, keys.get(dir)), "machine"), true));
|
|
66
|
-
res.claude_dirs.push(dir);
|
|
67
|
-
res.lines.push(`Claude Code hooks (${keys.get(dir)}): ${file}`);
|
|
68
|
-
} catch (e) {
|
|
69
|
-
res.warnings.push(e.message);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (opts.codex && isDir(codexConfigDir(opts.env))) {
|
|
73
|
-
const dir = codexConfigDir(opts.env);
|
|
74
|
-
const key = profileKeys("codex", [dir]).get(dir);
|
|
75
|
-
try {
|
|
76
|
-
editJson(path.join(dir, "hooks.json"), (d) => (addHooks(d, "nested", codexMachineSpecs(node, key), "machine"), true));
|
|
77
|
-
editToml(path.join(dir, "config.toml"), (c) => enableFeatureHooks(c));
|
|
78
|
-
res.codex_dir = dir;
|
|
79
|
-
res.lines.push(`Codex hooks (${key}): ${path.join(dir, "hooks.json")}`);
|
|
80
|
-
} catch (e) {
|
|
81
|
-
res.warnings.push(e.message);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return res;
|
|
85
|
-
}
|
|
86
|
-
function editToml(file, fn) {
|
|
87
|
-
const before = readText(file);
|
|
88
|
-
const next = fn(before ?? "");
|
|
89
|
-
if (next === (before ?? "")) return;
|
|
90
|
-
if (before === void 0) addCreated(file);
|
|
91
|
-
else if (!wasCreated(file)) backupOnce(file);
|
|
92
|
-
atomicWrite(file, next);
|
|
93
|
-
}
|
|
94
|
-
function removeMachineHooks(inst) {
|
|
95
|
-
const lines = [];
|
|
96
|
-
for (const dir of inst.claude_dirs) {
|
|
97
|
-
const file = path.join(dir, "settings.json");
|
|
98
|
-
try {
|
|
99
|
-
if (editJson(file, (d) => removeHooks(d, "nested", "machine") > 0, { drop: true })) lines.push(`Claude Code hooks: removed from ${file}`);
|
|
100
|
-
} catch {
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (inst.codex_dir) {
|
|
104
|
-
const file = path.join(inst.codex_dir, "hooks.json");
|
|
105
|
-
try {
|
|
106
|
-
if (editJson(file, (d) => removeHooks(d, "nested", "machine") > 0, { drop: true })) lines.push(`Codex hooks: removed from ${file}`);
|
|
107
|
-
} catch {
|
|
108
|
-
}
|
|
109
|
-
const cfg = path.join(inst.codex_dir, "config.toml");
|
|
110
|
-
const before = readText(cfg);
|
|
111
|
-
if (before !== void 0) {
|
|
112
|
-
const next = restoreFeatureHooks(before);
|
|
113
|
-
if (next !== before) {
|
|
114
|
-
if (wasCreated(cfg) && next.trim() === "") {
|
|
115
|
-
removeFile(cfg);
|
|
116
|
-
forgetCreated(cfg);
|
|
117
|
-
} else {
|
|
118
|
-
atomicWrite(cfg, next);
|
|
119
|
-
dropBackupIfSame(cfg);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return lines;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export {
|
|
128
|
-
installCliCopy,
|
|
129
|
-
removeCliCopy,
|
|
130
|
-
installMachineHooks,
|
|
131
|
-
removeMachineHooks
|
|
132
|
-
};
|
package/dist/chunk-JCLWCMEM.js
DELETED
package/dist/chunk-K3NQKI34.js
DELETED
package/dist/chunk-O2TC3WSS.js
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
configDir,
|
|
4
|
-
readText,
|
|
5
|
-
removeFile,
|
|
6
|
-
serviceLogFile,
|
|
7
|
-
spoolFile
|
|
8
|
-
} from "./chunk-VNCQFFQO.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
|
-
};
|
package/dist/chunk-PY74LT2W.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/api.ts
|
|
4
|
-
var ApiError = class extends Error {
|
|
5
|
-
constructor(status, code, message) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.status = status;
|
|
8
|
-
this.code = code;
|
|
9
|
-
}
|
|
10
|
-
status;
|
|
11
|
-
code;
|
|
12
|
-
};
|
|
13
|
-
async function apiRequest(ctx, host, path, opts = {}) {
|
|
14
|
-
const headers = { accept: "application/json", ...opts.headers };
|
|
15
|
-
if (opts.token) headers.authorization = `Bearer ${opts.token}`;
|
|
16
|
-
if (opts.body !== void 0) headers["content-type"] = "application/json";
|
|
17
|
-
const res = await ctx.fetch(`${host}${path}`, {
|
|
18
|
-
method: opts.method ?? (opts.body !== void 0 ? "POST" : "GET"),
|
|
19
|
-
headers,
|
|
20
|
-
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
|
|
21
|
-
signal: AbortSignal.timeout(opts.timeoutMs ?? 15e3)
|
|
22
|
-
});
|
|
23
|
-
const text = await res.text();
|
|
24
|
-
let json = null;
|
|
25
|
-
try {
|
|
26
|
-
json = text ? JSON.parse(text) : null;
|
|
27
|
-
} catch {
|
|
28
|
-
json = null;
|
|
29
|
-
}
|
|
30
|
-
return { status: res.status, json };
|
|
31
|
-
}
|
|
32
|
-
function errorOf(r) {
|
|
33
|
-
const j = r.json ?? {};
|
|
34
|
-
return new ApiError(r.status, typeof j.error === "string" ? j.error : "error", typeof j.message === "string" ? j.message : `HTTP ${r.status}`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export {
|
|
38
|
-
ApiError,
|
|
39
|
-
apiRequest,
|
|
40
|
-
errorOf
|
|
41
|
-
};
|
package/dist/cli-P3DYE5IR.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
parseArgs
|
|
4
|
-
} from "./chunk-TKMIV7BG.js";
|
|
5
|
-
import {
|
|
6
|
-
VERSION
|
|
7
|
-
} from "./chunk-DNG5CRT3.js";
|
|
8
|
-
import {
|
|
9
|
-
ApiError
|
|
10
|
-
} from "./chunk-PY74LT2W.js";
|
|
11
|
-
import {
|
|
12
|
-
CLI_BIN_NAME,
|
|
13
|
-
CLI_INSTALL_COMMAND,
|
|
14
|
-
cliNpxCommand,
|
|
15
|
-
defaultCtx
|
|
16
|
-
} from "./chunk-ZC2DAKB5.js";
|
|
17
|
-
import "./chunk-K3NQKI34.js";
|
|
18
|
-
|
|
19
|
-
// src/cli.ts
|
|
20
|
-
var HELP = `hivefloor ${VERSION}
|
|
21
|
-
|
|
22
|
-
Usage: ${CLI_BIN_NAME} <command> [options]
|
|
23
|
-
${cliNpxCommand("<command> [options]")} (no install)
|
|
24
|
-
|
|
25
|
-
Commands:
|
|
26
|
-
connect Connect this computer once: every agent on it shows up (Claude profiles, Codex, ...)
|
|
27
|
-
--host URL --name NAME --no-open --no-service --yes
|
|
28
|
-
--agent | --tool claude|codex|cursor|gemini|grok|other connect one agent for one repo (MCP and tasks) instead
|
|
29
|
-
disconnect Remove everything connect added, the machine on the server included (--tool <name> for one agent tool)
|
|
30
|
-
status This machine and its service; the per-repo agent, its projects and live sessions
|
|
31
|
-
where [tool] Which account to run next on (read only; --json for the raw answer)
|
|
32
|
-
service run: the background service (started by your OS; you rarely run it by hand)
|
|
33
|
-
link Link this repo to another project (--project ID | --new NAME [--path PREFIX])
|
|
34
|
-
token Print the stored token for shell use (--reveal to print to a terminal)
|
|
35
|
-
mcp Stdio MCP server that proxies to Hivefloor (for tools without HTTP header support)
|
|
36
|
-
hook <tool> <event>: the hook runner the tools call (reads JSON on stdin)
|
|
37
|
-
help Show this help
|
|
38
|
-
--version Print the version
|
|
39
|
-
|
|
40
|
-
Install once: ${CLI_INSTALL_COMMAND}
|
|
41
|
-
Host: https://hivefloor.worldofz.info, or set HIVEFLOOR_URL.
|
|
42
|
-
`;
|
|
43
|
-
async function run(argv, ctx = defaultCtx()) {
|
|
44
|
-
const [cmd, ...rest] = argv;
|
|
45
|
-
if (cmd === "--version" || cmd === "-v" || cmd === "version") {
|
|
46
|
-
ctx.out(`${VERSION}
|
|
47
|
-
`);
|
|
48
|
-
return 0;
|
|
49
|
-
}
|
|
50
|
-
if (cmd === void 0 || cmd === "help" || cmd === "--help" || cmd === "-h") {
|
|
51
|
-
ctx.out(HELP);
|
|
52
|
-
return 0;
|
|
53
|
-
}
|
|
54
|
-
const p = parseArgs(rest);
|
|
55
|
-
if (p.flags.help) {
|
|
56
|
-
ctx.out(HELP);
|
|
57
|
-
return 0;
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
switch (cmd) {
|
|
61
|
-
case "connect":
|
|
62
|
-
return await (await import("./connect-ACNM5DQG.js")).connect(ctx, p);
|
|
63
|
-
case "disconnect":
|
|
64
|
-
return await (await import("./disconnect-MKRHK4CX.js")).disconnect(ctx, p);
|
|
65
|
-
case "status":
|
|
66
|
-
return await (await import("./status-KBBSAADD.js")).status(ctx, p);
|
|
67
|
-
case "where":
|
|
68
|
-
return await (await import("./where-KR7VWSEC.js")).where(ctx, p);
|
|
69
|
-
case "service":
|
|
70
|
-
if (p.positionals[0] !== "run") {
|
|
71
|
-
ctx.err("hivefloor: usage: hivefloor service run\n");
|
|
72
|
-
return 2;
|
|
73
|
-
}
|
|
74
|
-
return await (await import("./run-336BSU72.js")).runService({ ctx });
|
|
75
|
-
case "link":
|
|
76
|
-
return await (await import("./link-HXBMMSG3.js")).link(ctx, p);
|
|
77
|
-
case "token":
|
|
78
|
-
return await (await import("./token-JDRLEV5D.js")).token(ctx, p);
|
|
79
|
-
case "mcp":
|
|
80
|
-
return await (await import("./mcp-N2TMD4GR.js")).runMcpProxy(ctx, p);
|
|
81
|
-
case "hook": {
|
|
82
|
-
const { runHook, readStdin } = await import("./hook-KR2HGVAR.js");
|
|
83
|
-
await runHook(rest, { env: ctx.env, cwd: ctx.cwd, fetch: ctx.fetch, now: ctx.now, readStdin });
|
|
84
|
-
return 0;
|
|
85
|
-
}
|
|
86
|
-
default:
|
|
87
|
-
ctx.err(`hivefloor: unknown command "${cmd}". Run "hivefloor help".
|
|
88
|
-
`);
|
|
89
|
-
return 2;
|
|
90
|
-
}
|
|
91
|
-
} catch (e) {
|
|
92
|
-
if (e instanceof ApiError) ctx.err(`hivefloor: ${e.message}
|
|
93
|
-
`);
|
|
94
|
-
else ctx.err(`hivefloor: ${e.message}
|
|
95
|
-
`);
|
|
96
|
-
return 1;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export {
|
|
100
|
-
HELP,
|
|
101
|
-
VERSION,
|
|
102
|
-
run
|
|
103
|
-
};
|
package/dist/connect-ACNM5DQG.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
connect,
|
|
4
|
-
connectAgent,
|
|
5
|
-
resolveHost
|
|
6
|
-
} from "./chunk-SD65CIIY.js";
|
|
7
|
-
import "./chunk-R5KDI4WI.js";
|
|
8
|
-
import "./chunk-QHYZBHXO.js";
|
|
9
|
-
import "./chunk-2BSA7LFD.js";
|
|
10
|
-
import "./chunk-2IMJECYD.js";
|
|
11
|
-
import "./chunk-TKMIV7BG.js";
|
|
12
|
-
import "./chunk-PDXYOREI.js";
|
|
13
|
-
import "./chunk-DNG5CRT3.js";
|
|
14
|
-
import "./chunk-T7TG6WA4.js";
|
|
15
|
-
import "./chunk-PY74LT2W.js";
|
|
16
|
-
import "./chunk-VNCQFFQO.js";
|
|
17
|
-
import "./chunk-ZC2DAKB5.js";
|
|
18
|
-
import "./chunk-K3NQKI34.js";
|
|
19
|
-
export {
|
|
20
|
-
connect,
|
|
21
|
-
connectAgent,
|
|
22
|
-
resolveHost
|
|
23
|
-
};
|