hatchee 0.1.3 → 0.1.4
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/dist/cli.mjs +72 -21
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -11942,7 +11942,12 @@ class Daemon {
|
|
|
11942
11942
|
});
|
|
11943
11943
|
const hooks = createServer((req, res) => {
|
|
11944
11944
|
const url = req.url ?? "";
|
|
11945
|
-
|
|
11945
|
+
const jsonPost = req.method === "POST" && String(req.headers["content-type"] ?? "").includes("application/json");
|
|
11946
|
+
if (url === "/pair") {
|
|
11947
|
+
if (!jsonPost) {
|
|
11948
|
+
res.writeHead(415).end("expected application/json");
|
|
11949
|
+
return;
|
|
11950
|
+
}
|
|
11946
11951
|
try {
|
|
11947
11952
|
res.writeHead(200, { "content-type": "application/json" });
|
|
11948
11953
|
res.end(JSON.stringify(self.pairingPayload()));
|
|
@@ -11952,7 +11957,7 @@ class Daemon {
|
|
|
11952
11957
|
}
|
|
11953
11958
|
return;
|
|
11954
11959
|
}
|
|
11955
|
-
if (
|
|
11960
|
+
if (!jsonPost || url !== "/hook") {
|
|
11956
11961
|
res.writeHead(404).end("not found");
|
|
11957
11962
|
return;
|
|
11958
11963
|
}
|
|
@@ -12140,7 +12145,12 @@ function installHooks(droverBin) {
|
|
|
12140
12145
|
return settingsPath();
|
|
12141
12146
|
}
|
|
12142
12147
|
function isOurs(x) {
|
|
12143
|
-
|
|
12148
|
+
if (typeof x?.command !== "string")
|
|
12149
|
+
return false;
|
|
12150
|
+
const cmd = x.command.trimEnd();
|
|
12151
|
+
if (!/\bhook'?\s*$/.test(cmd))
|
|
12152
|
+
return false;
|
|
12153
|
+
return cmd.includes("hatchee") || cmd.includes("drover") || cmd.includes("daemon/src/cli.ts");
|
|
12144
12154
|
}
|
|
12145
12155
|
function uninstallHooks() {
|
|
12146
12156
|
if (!existsSync2(settingsPath()))
|
|
@@ -12158,12 +12168,22 @@ function uninstallHooks() {
|
|
|
12158
12168
|
function readStdin() {
|
|
12159
12169
|
return new Promise((resolve) => {
|
|
12160
12170
|
let data = "";
|
|
12171
|
+
let done = false;
|
|
12172
|
+
const finish = () => {
|
|
12173
|
+
if (!done) {
|
|
12174
|
+
done = true;
|
|
12175
|
+
resolve(data);
|
|
12176
|
+
}
|
|
12177
|
+
};
|
|
12161
12178
|
process.stdin.setEncoding("utf8");
|
|
12162
12179
|
process.stdin.on("data", (c) => {
|
|
12163
12180
|
data += c;
|
|
12164
12181
|
});
|
|
12165
|
-
process.stdin.on("end",
|
|
12166
|
-
setTimeout(() =>
|
|
12182
|
+
process.stdin.on("end", finish);
|
|
12183
|
+
setTimeout(() => {
|
|
12184
|
+
if (data === "")
|
|
12185
|
+
finish();
|
|
12186
|
+
}, 2000);
|
|
12167
12187
|
});
|
|
12168
12188
|
}
|
|
12169
12189
|
async function runHook(hookPort) {
|
|
@@ -12213,17 +12233,20 @@ var UNIT = join3(HOME, ".config", "systemd", "user", "hatchee.service");
|
|
|
12213
12233
|
function servicePath(node) {
|
|
12214
12234
|
return [
|
|
12215
12235
|
dirname(node),
|
|
12216
|
-
join3(HOME, ".bun/bin"),
|
|
12217
|
-
join3(HOME, ".npm-global/bin"),
|
|
12218
|
-
join3(HOME, ".local/bin"),
|
|
12219
|
-
"/opt/homebrew/bin",
|
|
12220
|
-
"/usr/local/bin",
|
|
12221
12236
|
"/usr/bin",
|
|
12222
12237
|
"/bin",
|
|
12223
12238
|
"/usr/sbin",
|
|
12224
|
-
"/sbin"
|
|
12239
|
+
"/sbin",
|
|
12240
|
+
"/opt/homebrew/bin",
|
|
12241
|
+
"/usr/local/bin",
|
|
12242
|
+
join3(HOME, ".bun/bin"),
|
|
12243
|
+
join3(HOME, ".npm-global/bin"),
|
|
12244
|
+
join3(HOME, ".local/bin")
|
|
12225
12245
|
].join(":");
|
|
12226
12246
|
}
|
|
12247
|
+
function xmlEsc(s) {
|
|
12248
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
12249
|
+
}
|
|
12227
12250
|
function copyStableBin() {
|
|
12228
12251
|
mkdirSync3(BIN_DIR, { recursive: true });
|
|
12229
12252
|
const src = process.argv[1];
|
|
@@ -12233,7 +12256,7 @@ function copyStableBin() {
|
|
|
12233
12256
|
}
|
|
12234
12257
|
}
|
|
12235
12258
|
function plistContent(node, bin) {
|
|
12236
|
-
const args = [node, bin, "up"].map((s) => ` <string>${s}</string>`).join(`
|
|
12259
|
+
const args = [node, bin, "up"].map((s) => ` <string>${xmlEsc(s)}</string>`).join(`
|
|
12237
12260
|
`);
|
|
12238
12261
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
12239
12262
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -12247,10 +12270,10 @@ ${args}
|
|
|
12247
12270
|
<key>RunAtLoad</key><true/>
|
|
12248
12271
|
<key>KeepAlive</key><true/>
|
|
12249
12272
|
<key>ThrottleInterval</key><integer>10</integer>
|
|
12250
|
-
<key>StandardOutPath</key><string>${LOG}</string>
|
|
12251
|
-
<key>StandardErrorPath</key><string>${LOG}</string>
|
|
12273
|
+
<key>StandardOutPath</key><string>${xmlEsc(LOG)}</string>
|
|
12274
|
+
<key>StandardErrorPath</key><string>${xmlEsc(LOG)}</string>
|
|
12252
12275
|
<key>EnvironmentVariables</key>
|
|
12253
|
-
<dict><key>PATH</key><string>${servicePath(node)}</string></dict>
|
|
12276
|
+
<dict><key>PATH</key><string>${xmlEsc(servicePath(node))}</string></dict>
|
|
12254
12277
|
</dict>
|
|
12255
12278
|
</plist>
|
|
12256
12279
|
`;
|
|
@@ -12261,10 +12284,10 @@ Description=Hatchee — watch & approve your coding agents from your phone
|
|
|
12261
12284
|
After=network-online.target
|
|
12262
12285
|
|
|
12263
12286
|
[Service]
|
|
12264
|
-
ExecStart
|
|
12287
|
+
ExecStart="${node}" "${bin}" up
|
|
12265
12288
|
Restart=always
|
|
12266
12289
|
RestartSec=10
|
|
12267
|
-
Environment=PATH=${servicePath(node)}
|
|
12290
|
+
Environment="PATH=${servicePath(node)}"
|
|
12268
12291
|
|
|
12269
12292
|
[Install]
|
|
12270
12293
|
WantedBy=default.target
|
|
@@ -12273,12 +12296,22 @@ WantedBy=default.target
|
|
|
12273
12296
|
function run(cmd, args) {
|
|
12274
12297
|
try {
|
|
12275
12298
|
execFileSync(cmd, args, { stdio: "pipe" });
|
|
12299
|
+
return true;
|
|
12276
12300
|
} catch (e) {
|
|
12277
12301
|
console.log(` · ${cmd} ${args.join(" ")} → ${String(e?.stderr || e?.message || e).trim().slice(0, 200)}`);
|
|
12302
|
+
return false;
|
|
12278
12303
|
}
|
|
12279
12304
|
}
|
|
12280
12305
|
function installService(print = false) {
|
|
12281
12306
|
const node = process.execPath;
|
|
12307
|
+
const src = process.argv[1] ?? "";
|
|
12308
|
+
if (!print && src && !/\.(mjs|cjs|js)$/.test(src)) {
|
|
12309
|
+
console.log(`
|
|
12310
|
+
⚠ running from source (${src}); the service needs the built bundle.`);
|
|
12311
|
+
console.log(` use \`npx hatchee install-service\` for a real install.
|
|
12312
|
+
`);
|
|
12313
|
+
return;
|
|
12314
|
+
}
|
|
12282
12315
|
if (process.platform === "darwin") {
|
|
12283
12316
|
const content = plistContent(node, STABLE_BIN);
|
|
12284
12317
|
if (print) {
|
|
@@ -12296,8 +12329,15 @@ ${content}
|
|
|
12296
12329
|
writeFileSync3(PLIST, content);
|
|
12297
12330
|
const uid = String(process.getuid?.() ?? "");
|
|
12298
12331
|
run("launchctl", ["bootout", `gui/${uid}/${LABEL}`]);
|
|
12299
|
-
run("launchctl", ["bootstrap", `gui/${uid}`, PLIST]);
|
|
12332
|
+
const ok = run("launchctl", ["bootstrap", `gui/${uid}`, PLIST]);
|
|
12300
12333
|
run("launchctl", ["enable", `gui/${uid}/${LABEL}`]);
|
|
12334
|
+
if (!ok) {
|
|
12335
|
+
console.log(`
|
|
12336
|
+
⚠ wrote ${PLIST} but launchctl bootstrap failed (see the message above).`);
|
|
12337
|
+
console.log(` try manually: launchctl bootstrap gui/${uid} ${PLIST}
|
|
12338
|
+
`);
|
|
12339
|
+
return;
|
|
12340
|
+
}
|
|
12301
12341
|
console.log(`
|
|
12302
12342
|
✓ Hatchee will now run in the background (launchd: ${LABEL})`);
|
|
12303
12343
|
console.log(` logs ${LOG}`);
|
|
@@ -12324,8 +12364,15 @@ ${content}
|
|
|
12324
12364
|
mkdirSync3(dirname(UNIT), { recursive: true });
|
|
12325
12365
|
writeFileSync3(UNIT, content);
|
|
12326
12366
|
run("systemctl", ["--user", "daemon-reload"]);
|
|
12327
|
-
run("systemctl", ["--user", "enable", "--now", "hatchee.service"]);
|
|
12367
|
+
const ok = run("systemctl", ["--user", "enable", "--now", "hatchee.service"]);
|
|
12328
12368
|
run("loginctl", ["enable-linger", process.env.USER ?? ""]);
|
|
12369
|
+
if (!ok) {
|
|
12370
|
+
console.log(`
|
|
12371
|
+
⚠ wrote ${UNIT} but \`systemctl --user enable --now\` failed (see above).`);
|
|
12372
|
+
console.log(` is the user systemd bus available? try manually: systemctl --user enable --now hatchee.service
|
|
12373
|
+
`);
|
|
12374
|
+
return;
|
|
12375
|
+
}
|
|
12329
12376
|
console.log(`
|
|
12330
12377
|
✓ Hatchee will now run in the background (systemd --user: hatchee.service)`);
|
|
12331
12378
|
console.log(` logs journalctl --user -u hatchee.service -f`);
|
|
@@ -12361,7 +12408,7 @@ function uninstallService() {
|
|
|
12361
12408
|
}
|
|
12362
12409
|
|
|
12363
12410
|
// src/cli.ts
|
|
12364
|
-
var VERSION2 = "0.1.
|
|
12411
|
+
var VERSION2 = "0.1.4";
|
|
12365
12412
|
var cmd = process.argv[2] ?? "help";
|
|
12366
12413
|
switch (cmd) {
|
|
12367
12414
|
case "up": {
|
|
@@ -12473,7 +12520,11 @@ function banner() {
|
|
|
12473
12520
|
}
|
|
12474
12521
|
async function remotePair(hookPort) {
|
|
12475
12522
|
try {
|
|
12476
|
-
const r = await fetch(`http://127.0.0.1:${hookPort}/pair`, {
|
|
12523
|
+
const r = await fetch(`http://127.0.0.1:${hookPort}/pair`, {
|
|
12524
|
+
method: "POST",
|
|
12525
|
+
headers: { "content-type": "application/json" },
|
|
12526
|
+
signal: AbortSignal.timeout(2500)
|
|
12527
|
+
});
|
|
12477
12528
|
if (!r.ok)
|
|
12478
12529
|
return null;
|
|
12479
12530
|
const info = await r.json();
|
package/package.json
CHANGED