@zonease/happy 0.6.37 → 0.6.39
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/{types-DYCJXXdA.mjs → api-CIZKyfSn.mjs} +136 -1725
- package/dist/{types-BrTorNAy.cjs → api-CwOCQeLH.cjs} +317 -1961
- package/dist/auth-0VnlXT9f.mjs +181 -0
- package/dist/auth-BE8dD20T.mjs +270 -0
- package/dist/auth-BIleVCw0.cjs +274 -0
- package/dist/auth-Cas9DR3b.cjs +183 -0
- package/dist/browser-Cc08m7of.cjs +22 -0
- package/dist/browser-Dll5hxOV.mjs +20 -0
- package/dist/claudeLocal-CPT3zcIU.mjs +344 -0
- package/dist/claudeLocal-WkgLbl1a.cjs +352 -0
- package/dist/codex/happyMcpStdioBridge.cjs +4 -1
- package/dist/codex/happyMcpStdioBridge.mjs +4 -1
- package/dist/common-BdNgghUJ.mjs +75 -0
- package/dist/common-CZvSRU4p.cjs +83 -0
- package/dist/{config-D_g6ohaV.cjs → config-Draa-5XC.cjs} +21 -34
- package/dist/{config-DPn-cbpz.mjs → config-rTT4qTU5.mjs} +7 -20
- package/dist/connect-BfC1tYP_.mjs +679 -0
- package/dist/connect-CJZ73syK.cjs +681 -0
- package/dist/{constants-B4x1K7by.cjs → constants-E_UWYTo3.cjs} +2 -2
- package/dist/{constants-BO9OAFOT.mjs → constants-pmXZGibX.mjs} +1 -1
- package/dist/controlClient-CM_QcJnB.mjs +159 -0
- package/dist/controlClient-DZMIsKsT.cjs +168 -0
- package/dist/deviceExec-CU1R9CRb.cjs +84 -0
- package/dist/deviceExec-D93AOVV4.mjs +81 -0
- package/dist/diagnose-B3D1a_v0.cjs +60 -0
- package/dist/diagnose-CuRKXxt1.mjs +58 -0
- package/dist/doctor-C08m5Z9f.cjs +78 -0
- package/dist/doctor-Cya9YSA0.cjs +214 -0
- package/dist/doctor-DZYB6IVc.mjs +211 -0
- package/dist/doctor-ON7pN5G5.mjs +74 -0
- package/dist/downloadImage-DfSFLb-h.mjs +887 -0
- package/dist/downloadImage-MQMrUUxS.cjs +897 -0
- package/dist/enroll-BxlbVftP.cjs +115 -0
- package/dist/enroll-C52x8oly.mjs +113 -0
- package/dist/evidence-Ccd9iYcj.mjs +127 -0
- package/dist/evidence-CjWBG5rX.cjs +129 -0
- package/dist/formatImageMessage-B4lSxlk2.mjs +43 -0
- package/dist/formatImageMessage-DbyG8c2j.cjs +46 -0
- package/dist/github-DKcyF1zp.mjs +57 -0
- package/dist/github-h9GhJJ_C.cjs +59 -0
- package/dist/index-CDTNgfUf.cjs +578 -0
- package/dist/index-CPKdvi7J.mjs +554 -0
- package/dist/index.cjs +812 -40
- package/dist/index.mjs +813 -40
- package/dist/install-BokHRgFW.cjs +98 -0
- package/dist/install-C_cp8b2-.cjs +96 -0
- package/dist/install-DAeCn8ae.mjs +94 -0
- package/dist/install-oRAjVLjP.mjs +95 -0
- package/dist/lib.cjs +18 -12
- package/dist/lib.d.cts +16 -16
- package/dist/lib.d.mts +16 -16
- package/dist/lib.mjs +13 -7
- package/dist/{loadableToolOutput-lQH8Kb_w.mjs → loadableToolOutput-Cuygmd4K.mjs} +4 -2
- package/dist/{loadableToolOutput-CasonFIt.cjs → loadableToolOutput-DDCJjywt.cjs} +63 -61
- package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
- package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
- package/dist/persistence-BFjvtUad.mjs +944 -0
- package/dist/persistence-JLUn_Nou.cjs +996 -0
- package/dist/projectPath-BTBIMB57.mjs +10 -0
- package/dist/projectPath-ChLhdOyt.cjs +13 -0
- package/dist/prompt-BTWDZZO0.cjs +25 -0
- package/dist/prompt-BsAZsPbo.mjs +22 -0
- package/dist/release-BMEzNONE.mjs +168 -0
- package/dist/release-EhOJeAZe.cjs +171 -0
- package/dist/run-BDn2aE3Q.cjs +2152 -0
- package/dist/run-DBZqN6Kn.mjs +2128 -0
- package/dist/runClaude-DNHvERX0.mjs +3763 -0
- package/dist/runClaude-uaKxPZPm.cjs +3766 -0
- package/dist/{runCodex-BTt3fxG4.cjs → runCodex-82UrZLme.cjs} +169 -153
- package/dist/{runCodex-BXCB5trB.mjs → runCodex-C-RTM0wA.mjs} +36 -20
- package/dist/{runGemini-37HHbp9n.mjs → runGemini-Bm6-4Xm2.mjs} +34 -17
- package/dist/{runGemini-C-0nSFBv.cjs → runGemini-CXMr4Jwb.cjs} +212 -195
- package/dist/{runOneShot-CXhbFJ2j.cjs → runOneShot-1B6RMYT7.cjs} +31 -55
- package/dist/{runOneShot-USX8QPfE.mjs → runOneShot-ioARRHrx.mjs} +14 -38
- package/dist/{serve-DZAq-_1F.cjs → serve-BtdAhkIE.cjs} +35 -58
- package/dist/{serve-BRedJPzL.mjs → serve-CwibwU6N.mjs} +12 -35
- package/dist/session-2sU4Bu1R.mjs +108 -0
- package/dist/session-D--F87zL.cjs +110 -0
- package/dist/sessionKeyCache-4Tp8pJ3N.cjs +36 -0
- package/dist/sessionKeyCache-D2BwO91C.mjs +33 -0
- package/dist/sessionList-BCSw3qYt.mjs +51 -0
- package/dist/sessionList-ICJsjNtJ.cjs +54 -0
- package/dist/sessionSummary-Bkz52BPh.cjs +393 -0
- package/dist/sessionSummary-lHGBWQSb.mjs +387 -0
- package/dist/spawnHappyCLI-CoORX0YW.mjs +66 -0
- package/dist/spawnHappyCLI-D_V-AAoP.cjs +70 -0
- package/dist/ssh-BTOlhhxi.cjs +333 -0
- package/dist/ssh-DL_AkRAD.mjs +328 -0
- package/dist/systemdScope-BeOtAkhk.mjs +25 -0
- package/dist/systemdScope-DW3-UoKB.cjs +29 -0
- package/dist/task-CQzrHRZe.mjs +165 -0
- package/dist/task-CSpaC9HX.cjs +167 -0
- package/dist/time-Bj2HRkKH.cjs +33 -0
- package/dist/time-DgsBLJA_.mjs +29 -0
- package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
- package/dist/trimIdent-BAjmv_TG.mjs +20 -0
- package/dist/types-BoJh4Qfv.mjs +57 -0
- package/dist/types-DWeB7aqh.cjs +59 -0
- package/dist/uninstall-BiKyRAb1.cjs +77 -0
- package/dist/uninstall-nFMFGUVM.mjs +75 -0
- package/dist/update-BcqRHXf2.mjs +109 -0
- package/dist/update-Dw8pgsAT.cjs +111 -0
- package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
- package/dist/workflowCommon-Bl568-rt.cjs +62 -0
- package/dist/workflowReports-BEWuQesA.cjs +113 -0
- package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
- package/package.json +1 -1
- package/dist/index-BlkHOkB3.cjs +0 -11312
- package/dist/index-DJ2VpGiR.mjs +0 -11272
- package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
- package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var child_process = require('child_process');
|
|
5
|
+
var os = require('os');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var logger = require('./persistence-JLUn_Nou.cjs');
|
|
8
|
+
var trimIdent = require('./trimIdent-4gvk9Wk6.cjs');
|
|
9
|
+
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
10
|
+
|
|
11
|
+
const PLIST_LABEL = "com.happy-cli.daemon";
|
|
12
|
+
const PLIST_DIR = path.join(os.homedir(), "Library", "LaunchAgents");
|
|
13
|
+
const PLIST_FILE = path.join(PLIST_DIR, `${PLIST_LABEL}.plist`);
|
|
14
|
+
const LOG_DIR = path.join(os.homedir(), ".happy");
|
|
15
|
+
function plistEnvironment() {
|
|
16
|
+
const entries = [["HAPPY_DAEMON_SUPERVISED", "1"]];
|
|
17
|
+
if (process.env.HAPPY_SERVER_URL) entries.push(["HAPPY_SERVER_URL", process.env.HAPPY_SERVER_URL]);
|
|
18
|
+
if (process.env.HAPPY_HOME_DIR) entries.push(["HAPPY_HOME_DIR", process.env.HAPPY_HOME_DIR]);
|
|
19
|
+
if (process.env.HAPPY_WEBAPP_URL) entries.push(["HAPPY_WEBAPP_URL", process.env.HAPPY_WEBAPP_URL]);
|
|
20
|
+
return entries.map(([key, value]) => `
|
|
21
|
+
<key>${key}</key>
|
|
22
|
+
<string>${value}</string>`).join("");
|
|
23
|
+
}
|
|
24
|
+
async function install() {
|
|
25
|
+
const plistEnvironmentEntries = plistEnvironment();
|
|
26
|
+
const runtime = process.execPath;
|
|
27
|
+
const entrypoint = path.join(projectPath.projectPath(), "dist", "index.mjs");
|
|
28
|
+
if (!fs.existsSync(PLIST_DIR)) {
|
|
29
|
+
fs.mkdirSync(PLIST_DIR, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
if (!fs.existsSync(LOG_DIR)) {
|
|
32
|
+
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
if (fs.existsSync(PLIST_FILE)) {
|
|
35
|
+
logger.logger.info("Daemon plist already exists. Unloading first...");
|
|
36
|
+
try {
|
|
37
|
+
child_process.execSync(`launchctl unload ${PLIST_FILE}`, { stdio: "ignore" });
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const plistContent = trimIdent.trimIdent(`
|
|
42
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
43
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
44
|
+
<plist version="1.0">
|
|
45
|
+
<dict>
|
|
46
|
+
<key>Label</key>
|
|
47
|
+
<string>${PLIST_LABEL}</string>
|
|
48
|
+
|
|
49
|
+
<key>ProgramArguments</key>
|
|
50
|
+
<array>
|
|
51
|
+
<string>${runtime}</string>
|
|
52
|
+
<string>--no-warnings</string>
|
|
53
|
+
<string>--no-deprecation</string>
|
|
54
|
+
<string>${entrypoint}</string>
|
|
55
|
+
<string>daemon</string>
|
|
56
|
+
<string>start-sync</string>
|
|
57
|
+
</array>
|
|
58
|
+
|
|
59
|
+
<key>EnvironmentVariables</key>
|
|
60
|
+
<dict>${plistEnvironmentEntries}
|
|
61
|
+
</dict>
|
|
62
|
+
|
|
63
|
+
<key>RunAtLoad</key>
|
|
64
|
+
<true/>
|
|
65
|
+
|
|
66
|
+
<key>KeepAlive</key>
|
|
67
|
+
<dict>
|
|
68
|
+
<key>SuccessfulExit</key>
|
|
69
|
+
<false/>
|
|
70
|
+
</dict>
|
|
71
|
+
|
|
72
|
+
<key>ThrottleInterval</key>
|
|
73
|
+
<integer>30</integer>
|
|
74
|
+
|
|
75
|
+
<key>StandardOutPath</key>
|
|
76
|
+
<string>${path.join(LOG_DIR, "daemon.log")}</string>
|
|
77
|
+
|
|
78
|
+
<key>StandardErrorPath</key>
|
|
79
|
+
<string>${path.join(LOG_DIR, "daemon.err")}</string>
|
|
80
|
+
|
|
81
|
+
<key>WorkingDirectory</key>
|
|
82
|
+
<string>/tmp</string>
|
|
83
|
+
</dict>
|
|
84
|
+
</plist>
|
|
85
|
+
`);
|
|
86
|
+
fs.writeFileSync(PLIST_FILE, plistContent);
|
|
87
|
+
logger.logger.info(`Created LaunchAgent plist at ${PLIST_FILE}`);
|
|
88
|
+
try {
|
|
89
|
+
child_process.execSync(`launchctl load ${PLIST_FILE}`, { stdio: "pipe" });
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw new Error(`Failed to load LaunchAgent. You can try manually: launchctl load ${PLIST_FILE}`);
|
|
92
|
+
}
|
|
93
|
+
logger.logger.info("Daemon enabled and started. It will auto-start on login.");
|
|
94
|
+
logger.logger.info("To disable: happy daemon disable");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
exports.PLIST_LABEL = PLIST_LABEL;
|
|
98
|
+
exports.install = install;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var logger = require('./persistence-JLUn_Nou.cjs');
|
|
4
|
+
var install$2 = require('./install-BokHRgFW.cjs');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var child_process = require('child_process');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
var os = require('os');
|
|
9
|
+
var trimIdent = require('./trimIdent-4gvk9Wk6.cjs');
|
|
10
|
+
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
11
|
+
var systemdScope = require('./systemdScope-DW3-UoKB.cjs');
|
|
12
|
+
require('node:fs/promises');
|
|
13
|
+
require('node:fs');
|
|
14
|
+
require('node:os');
|
|
15
|
+
require('node:path');
|
|
16
|
+
require('zod');
|
|
17
|
+
require('node:crypto');
|
|
18
|
+
require('tweetnacl');
|
|
19
|
+
require('chalk');
|
|
20
|
+
require('url');
|
|
21
|
+
|
|
22
|
+
function environmentLines() {
|
|
23
|
+
const lines = ["Environment=HAPPY_DAEMON_SUPERVISED=1"];
|
|
24
|
+
if (process.env.HAPPY_SERVER_URL) lines.push(`Environment=HAPPY_SERVER_URL=${process.env.HAPPY_SERVER_URL}`);
|
|
25
|
+
if (process.env.HAPPY_HOME_DIR) lines.push(`Environment=HAPPY_HOME_DIR=${process.env.HAPPY_HOME_DIR}`);
|
|
26
|
+
if (process.env.HAPPY_WEBAPP_URL) lines.push(`Environment=HAPPY_WEBAPP_URL=${process.env.HAPPY_WEBAPP_URL}`);
|
|
27
|
+
return lines.length ? "\n " + lines.join("\n ") : "";
|
|
28
|
+
}
|
|
29
|
+
async function install$1() {
|
|
30
|
+
const daemonEnvironmentLines = environmentLines();
|
|
31
|
+
const runtime = process.execPath;
|
|
32
|
+
const entrypoint = path.join(projectPath.projectPath(), "dist", "index.mjs");
|
|
33
|
+
if (!fs.existsSync(entrypoint)) {
|
|
34
|
+
throw new Error(`Entrypoint not found: ${entrypoint}. Please build the project first.`);
|
|
35
|
+
}
|
|
36
|
+
const homedir = os.homedir();
|
|
37
|
+
const scope = systemdScope.systemdScopeFor(systemdScope.isRootUser());
|
|
38
|
+
const servicePath = scope.unitPath;
|
|
39
|
+
const serviceContent = trimIdent.trimIdent(`
|
|
40
|
+
[Unit]
|
|
41
|
+
Description=Happy AI CLI Daemon
|
|
42
|
+
After=network-online.target
|
|
43
|
+
Wants=network-online.target
|
|
44
|
+
|
|
45
|
+
[Service]
|
|
46
|
+
Type=simple
|
|
47
|
+
ExecStart=${runtime} --no-warnings --no-deprecation ${entrypoint} daemon start-sync
|
|
48
|
+
Restart=on-failure
|
|
49
|
+
RestartSec=30
|
|
50
|
+
Environment=HOME=${homedir}${daemonEnvironmentLines}
|
|
51
|
+
|
|
52
|
+
[Install]
|
|
53
|
+
WantedBy=${scope.wantedBy}
|
|
54
|
+
`);
|
|
55
|
+
fs.mkdirSync(path.dirname(servicePath), { recursive: true });
|
|
56
|
+
fs.writeFileSync(servicePath, serviceContent + "\n");
|
|
57
|
+
logger.logger.info(`Created systemd ${scope.system ? "system" : "user"} service at ${servicePath}`);
|
|
58
|
+
try {
|
|
59
|
+
child_process.execSync(`systemctl ${scope.systemctlFlag} daemon-reload`.trim(), { stdio: "pipe" });
|
|
60
|
+
child_process.execSync(`systemctl ${scope.systemctlFlag} enable --now ${systemdScope.SERVICE_NAME}`.trim(), { stdio: "pipe" });
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
63
|
+
throw new Error(
|
|
64
|
+
scope.system ? `Failed to enable the systemd service: ${detail}` : `Failed to enable the systemd user service: ${detail}
|
|
65
|
+
A user service needs a systemd user session (systemctl --user status must work).
|
|
66
|
+
On a server, install it as root instead so it runs without a logged-in session: sudo happy daemon install`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (!scope.system) {
|
|
70
|
+
try {
|
|
71
|
+
child_process.execSync(`loginctl enable-linger ${os.userInfo().username}`, { stdio: "pipe" });
|
|
72
|
+
} catch {
|
|
73
|
+
logger.logger.info("Could not enable lingering \u2014 the daemon may stop when you log out. Fix with: sudo loginctl enable-linger $USER");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
logger.logger.info(scope.system ? "Daemon enabled and started. It will auto-start on boot." : "Daemon enabled and started. It will auto-start on login.");
|
|
77
|
+
logger.logger.info("To disable: happy daemon disable");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function install() {
|
|
81
|
+
const credentials = await logger.readCredentials();
|
|
82
|
+
if (!credentials) {
|
|
83
|
+
throw new Error('Not authenticated. Please run "happy auth login" first.');
|
|
84
|
+
}
|
|
85
|
+
if (process.platform === "darwin") {
|
|
86
|
+
logger.logger.info("Setting up daemon auto-start for macOS...");
|
|
87
|
+
await install$2.install();
|
|
88
|
+
} else if (process.platform === "linux") {
|
|
89
|
+
logger.logger.info("Setting up daemon auto-start for Linux...");
|
|
90
|
+
await install$1();
|
|
91
|
+
} else {
|
|
92
|
+
throw new Error(`Unsupported platform: ${process.platform}. Only macOS and Linux are supported.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
exports.install = install;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { l as logger, r as readCredentials } from './persistence-BFjvtUad.mjs';
|
|
2
|
+
import { i as install$2 } from './install-oRAjVLjP.mjs';
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
import { t as trimIdent } from './trimIdent-BAjmv_TG.mjs';
|
|
8
|
+
import { p as projectPath } from './projectPath-BTBIMB57.mjs';
|
|
9
|
+
import { s as systemdScopeFor, i as isRootUser, S as SERVICE_NAME } from './systemdScope-BeOtAkhk.mjs';
|
|
10
|
+
import 'node:fs/promises';
|
|
11
|
+
import 'node:fs';
|
|
12
|
+
import 'node:os';
|
|
13
|
+
import 'node:path';
|
|
14
|
+
import 'zod';
|
|
15
|
+
import 'node:crypto';
|
|
16
|
+
import 'tweetnacl';
|
|
17
|
+
import 'chalk';
|
|
18
|
+
import 'url';
|
|
19
|
+
|
|
20
|
+
function environmentLines() {
|
|
21
|
+
const lines = ["Environment=HAPPY_DAEMON_SUPERVISED=1"];
|
|
22
|
+
if (process.env.HAPPY_SERVER_URL) lines.push(`Environment=HAPPY_SERVER_URL=${process.env.HAPPY_SERVER_URL}`);
|
|
23
|
+
if (process.env.HAPPY_HOME_DIR) lines.push(`Environment=HAPPY_HOME_DIR=${process.env.HAPPY_HOME_DIR}`);
|
|
24
|
+
if (process.env.HAPPY_WEBAPP_URL) lines.push(`Environment=HAPPY_WEBAPP_URL=${process.env.HAPPY_WEBAPP_URL}`);
|
|
25
|
+
return lines.length ? "\n " + lines.join("\n ") : "";
|
|
26
|
+
}
|
|
27
|
+
async function install$1() {
|
|
28
|
+
const daemonEnvironmentLines = environmentLines();
|
|
29
|
+
const runtime = process.execPath;
|
|
30
|
+
const entrypoint = path.join(projectPath(), "dist", "index.mjs");
|
|
31
|
+
if (!existsSync(entrypoint)) {
|
|
32
|
+
throw new Error(`Entrypoint not found: ${entrypoint}. Please build the project first.`);
|
|
33
|
+
}
|
|
34
|
+
const homedir = os.homedir();
|
|
35
|
+
const scope = systemdScopeFor(isRootUser());
|
|
36
|
+
const servicePath = scope.unitPath;
|
|
37
|
+
const serviceContent = trimIdent(`
|
|
38
|
+
[Unit]
|
|
39
|
+
Description=Happy AI CLI Daemon
|
|
40
|
+
After=network-online.target
|
|
41
|
+
Wants=network-online.target
|
|
42
|
+
|
|
43
|
+
[Service]
|
|
44
|
+
Type=simple
|
|
45
|
+
ExecStart=${runtime} --no-warnings --no-deprecation ${entrypoint} daemon start-sync
|
|
46
|
+
Restart=on-failure
|
|
47
|
+
RestartSec=30
|
|
48
|
+
Environment=HOME=${homedir}${daemonEnvironmentLines}
|
|
49
|
+
|
|
50
|
+
[Install]
|
|
51
|
+
WantedBy=${scope.wantedBy}
|
|
52
|
+
`);
|
|
53
|
+
mkdirSync(path.dirname(servicePath), { recursive: true });
|
|
54
|
+
writeFileSync(servicePath, serviceContent + "\n");
|
|
55
|
+
logger.info(`Created systemd ${scope.system ? "system" : "user"} service at ${servicePath}`);
|
|
56
|
+
try {
|
|
57
|
+
execSync(`systemctl ${scope.systemctlFlag} daemon-reload`.trim(), { stdio: "pipe" });
|
|
58
|
+
execSync(`systemctl ${scope.systemctlFlag} enable --now ${SERVICE_NAME}`.trim(), { stdio: "pipe" });
|
|
59
|
+
} catch (error) {
|
|
60
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
61
|
+
throw new Error(
|
|
62
|
+
scope.system ? `Failed to enable the systemd service: ${detail}` : `Failed to enable the systemd user service: ${detail}
|
|
63
|
+
A user service needs a systemd user session (systemctl --user status must work).
|
|
64
|
+
On a server, install it as root instead so it runs without a logged-in session: sudo happy daemon install`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
if (!scope.system) {
|
|
68
|
+
try {
|
|
69
|
+
execSync(`loginctl enable-linger ${os.userInfo().username}`, { stdio: "pipe" });
|
|
70
|
+
} catch {
|
|
71
|
+
logger.info("Could not enable lingering \u2014 the daemon may stop when you log out. Fix with: sudo loginctl enable-linger $USER");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
logger.info(scope.system ? "Daemon enabled and started. It will auto-start on boot." : "Daemon enabled and started. It will auto-start on login.");
|
|
75
|
+
logger.info("To disable: happy daemon disable");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function install() {
|
|
79
|
+
const credentials = await readCredentials();
|
|
80
|
+
if (!credentials) {
|
|
81
|
+
throw new Error('Not authenticated. Please run "happy auth login" first.');
|
|
82
|
+
}
|
|
83
|
+
if (process.platform === "darwin") {
|
|
84
|
+
logger.info("Setting up daemon auto-start for macOS...");
|
|
85
|
+
await install$2();
|
|
86
|
+
} else if (process.platform === "linux") {
|
|
87
|
+
logger.info("Setting up daemon auto-start for Linux...");
|
|
88
|
+
await install$1();
|
|
89
|
+
} else {
|
|
90
|
+
throw new Error(`Unsupported platform: ${process.platform}. Only macOS and Linux are supported.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { install };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { l as logger } from './persistence-BFjvtUad.mjs';
|
|
6
|
+
import { t as trimIdent } from './trimIdent-BAjmv_TG.mjs';
|
|
7
|
+
import { p as projectPath } from './projectPath-BTBIMB57.mjs';
|
|
8
|
+
|
|
9
|
+
const PLIST_LABEL = "com.happy-cli.daemon";
|
|
10
|
+
const PLIST_DIR = join(os.homedir(), "Library", "LaunchAgents");
|
|
11
|
+
const PLIST_FILE = join(PLIST_DIR, `${PLIST_LABEL}.plist`);
|
|
12
|
+
const LOG_DIR = join(os.homedir(), ".happy");
|
|
13
|
+
function plistEnvironment() {
|
|
14
|
+
const entries = [["HAPPY_DAEMON_SUPERVISED", "1"]];
|
|
15
|
+
if (process.env.HAPPY_SERVER_URL) entries.push(["HAPPY_SERVER_URL", process.env.HAPPY_SERVER_URL]);
|
|
16
|
+
if (process.env.HAPPY_HOME_DIR) entries.push(["HAPPY_HOME_DIR", process.env.HAPPY_HOME_DIR]);
|
|
17
|
+
if (process.env.HAPPY_WEBAPP_URL) entries.push(["HAPPY_WEBAPP_URL", process.env.HAPPY_WEBAPP_URL]);
|
|
18
|
+
return entries.map(([key, value]) => `
|
|
19
|
+
<key>${key}</key>
|
|
20
|
+
<string>${value}</string>`).join("");
|
|
21
|
+
}
|
|
22
|
+
async function install() {
|
|
23
|
+
const plistEnvironmentEntries = plistEnvironment();
|
|
24
|
+
const runtime = process.execPath;
|
|
25
|
+
const entrypoint = join(projectPath(), "dist", "index.mjs");
|
|
26
|
+
if (!existsSync(PLIST_DIR)) {
|
|
27
|
+
mkdirSync(PLIST_DIR, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
if (!existsSync(LOG_DIR)) {
|
|
30
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
if (existsSync(PLIST_FILE)) {
|
|
33
|
+
logger.info("Daemon plist already exists. Unloading first...");
|
|
34
|
+
try {
|
|
35
|
+
execSync(`launchctl unload ${PLIST_FILE}`, { stdio: "ignore" });
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const plistContent = trimIdent(`
|
|
40
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
41
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
42
|
+
<plist version="1.0">
|
|
43
|
+
<dict>
|
|
44
|
+
<key>Label</key>
|
|
45
|
+
<string>${PLIST_LABEL}</string>
|
|
46
|
+
|
|
47
|
+
<key>ProgramArguments</key>
|
|
48
|
+
<array>
|
|
49
|
+
<string>${runtime}</string>
|
|
50
|
+
<string>--no-warnings</string>
|
|
51
|
+
<string>--no-deprecation</string>
|
|
52
|
+
<string>${entrypoint}</string>
|
|
53
|
+
<string>daemon</string>
|
|
54
|
+
<string>start-sync</string>
|
|
55
|
+
</array>
|
|
56
|
+
|
|
57
|
+
<key>EnvironmentVariables</key>
|
|
58
|
+
<dict>${plistEnvironmentEntries}
|
|
59
|
+
</dict>
|
|
60
|
+
|
|
61
|
+
<key>RunAtLoad</key>
|
|
62
|
+
<true/>
|
|
63
|
+
|
|
64
|
+
<key>KeepAlive</key>
|
|
65
|
+
<dict>
|
|
66
|
+
<key>SuccessfulExit</key>
|
|
67
|
+
<false/>
|
|
68
|
+
</dict>
|
|
69
|
+
|
|
70
|
+
<key>ThrottleInterval</key>
|
|
71
|
+
<integer>30</integer>
|
|
72
|
+
|
|
73
|
+
<key>StandardOutPath</key>
|
|
74
|
+
<string>${join(LOG_DIR, "daemon.log")}</string>
|
|
75
|
+
|
|
76
|
+
<key>StandardErrorPath</key>
|
|
77
|
+
<string>${join(LOG_DIR, "daemon.err")}</string>
|
|
78
|
+
|
|
79
|
+
<key>WorkingDirectory</key>
|
|
80
|
+
<string>/tmp</string>
|
|
81
|
+
</dict>
|
|
82
|
+
</plist>
|
|
83
|
+
`);
|
|
84
|
+
writeFileSync(PLIST_FILE, plistContent);
|
|
85
|
+
logger.info(`Created LaunchAgent plist at ${PLIST_FILE}`);
|
|
86
|
+
try {
|
|
87
|
+
execSync(`launchctl load ${PLIST_FILE}`, { stdio: "pipe" });
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw new Error(`Failed to load LaunchAgent. You can try manually: launchctl load ${PLIST_FILE}`);
|
|
90
|
+
}
|
|
91
|
+
logger.info("Daemon enabled and started. It will auto-start on login.");
|
|
92
|
+
logger.info("To disable: happy daemon disable");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { PLIST_LABEL as P, install as i };
|
package/dist/lib.cjs
CHANGED
|
@@ -1,37 +1,43 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var api = require('./api-CwOCQeLH.cjs');
|
|
4
|
+
var logger = require('./persistence-JLUn_Nou.cjs');
|
|
5
|
+
var types = require('./types-DWeB7aqh.cjs');
|
|
4
6
|
require('axios');
|
|
5
|
-
require('chalk');
|
|
6
|
-
require('fs');
|
|
7
|
-
require('node:fs');
|
|
8
|
-
require('node:os');
|
|
9
|
-
require('node:path');
|
|
10
7
|
require('node:events');
|
|
11
8
|
require('socket.io-client');
|
|
12
9
|
require('zod');
|
|
10
|
+
require('./index-CDTNgfUf.cjs');
|
|
13
11
|
require('@paralleldrive/cuid2');
|
|
12
|
+
require('./time-Bj2HRkKH.cjs');
|
|
14
13
|
require('node:crypto');
|
|
15
|
-
require('
|
|
14
|
+
require('node:fs');
|
|
15
|
+
require('node:path');
|
|
16
16
|
require('node:child_process');
|
|
17
17
|
require('node:fs/promises');
|
|
18
|
+
require('node:os');
|
|
18
19
|
require('node:util');
|
|
19
20
|
require('child_process');
|
|
20
21
|
require('util');
|
|
21
22
|
require('fs/promises');
|
|
22
23
|
require('path');
|
|
24
|
+
require('./projectPath-ChLhdOyt.cjs');
|
|
23
25
|
require('url');
|
|
24
26
|
require('node:module');
|
|
25
27
|
require('ws');
|
|
26
28
|
require('crypto');
|
|
29
|
+
require('tweetnacl');
|
|
27
30
|
require('@stablelib/base64');
|
|
28
31
|
require('node:readline');
|
|
29
32
|
require('expo-server-sdk');
|
|
33
|
+
require('./sessionKeyCache-4Tp8pJ3N.cjs');
|
|
34
|
+
require('chalk');
|
|
35
|
+
require('fs');
|
|
30
36
|
|
|
31
37
|
|
|
32
38
|
|
|
33
|
-
exports.ApiClient =
|
|
34
|
-
exports.ApiSessionClient =
|
|
35
|
-
exports.
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
39
|
+
exports.ApiClient = api.ApiClient;
|
|
40
|
+
exports.ApiSessionClient = api.ApiSessionClient;
|
|
41
|
+
exports.configuration = logger.configuration;
|
|
42
|
+
exports.logger = logger.logger;
|
|
43
|
+
exports.RawJSONLinesSchema = types.RawJSONLinesSchema;
|
package/dist/lib.d.cts
CHANGED
|
@@ -321,53 +321,53 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
321
321
|
createdAt: z.ZodNumber;
|
|
322
322
|
updatedAt: z.ZodNumber;
|
|
323
323
|
}, "strip", z.ZodTypeAny, {
|
|
324
|
+
id: string;
|
|
325
|
+
seq: number;
|
|
324
326
|
content: {
|
|
325
327
|
c: string;
|
|
326
328
|
t: "encrypted";
|
|
327
329
|
};
|
|
328
|
-
id: string;
|
|
329
|
-
seq: number;
|
|
330
330
|
createdAt: number;
|
|
331
331
|
updatedAt: number;
|
|
332
332
|
localId?: string | null | undefined;
|
|
333
333
|
}, {
|
|
334
|
+
id: string;
|
|
335
|
+
seq: number;
|
|
334
336
|
content: {
|
|
335
337
|
c: string;
|
|
336
338
|
t: "encrypted";
|
|
337
339
|
};
|
|
338
|
-
id: string;
|
|
339
|
-
seq: number;
|
|
340
340
|
createdAt: number;
|
|
341
341
|
updatedAt: number;
|
|
342
342
|
localId?: string | null | undefined;
|
|
343
343
|
}>;
|
|
344
344
|
}, "strip", z.ZodTypeAny, {
|
|
345
|
+
t: "new-message";
|
|
345
346
|
message: {
|
|
347
|
+
id: string;
|
|
348
|
+
seq: number;
|
|
346
349
|
content: {
|
|
347
350
|
c: string;
|
|
348
351
|
t: "encrypted";
|
|
349
352
|
};
|
|
350
|
-
id: string;
|
|
351
|
-
seq: number;
|
|
352
353
|
createdAt: number;
|
|
353
354
|
updatedAt: number;
|
|
354
355
|
localId?: string | null | undefined;
|
|
355
356
|
};
|
|
356
|
-
t: "new-message";
|
|
357
357
|
sid: string;
|
|
358
358
|
}, {
|
|
359
|
+
t: "new-message";
|
|
359
360
|
message: {
|
|
361
|
+
id: string;
|
|
362
|
+
seq: number;
|
|
360
363
|
content: {
|
|
361
364
|
c: string;
|
|
362
365
|
t: "encrypted";
|
|
363
366
|
};
|
|
364
|
-
id: string;
|
|
365
|
-
seq: number;
|
|
366
367
|
createdAt: number;
|
|
367
368
|
updatedAt: number;
|
|
368
369
|
localId?: string | null | undefined;
|
|
369
370
|
};
|
|
370
|
-
t: "new-message";
|
|
371
371
|
sid: string;
|
|
372
372
|
}>, z.ZodObject<{
|
|
373
373
|
t: z.ZodLiteral<"update-session">;
|
|
@@ -472,18 +472,18 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
472
472
|
seq: number;
|
|
473
473
|
createdAt: number;
|
|
474
474
|
body: {
|
|
475
|
+
t: "new-message";
|
|
475
476
|
message: {
|
|
477
|
+
id: string;
|
|
478
|
+
seq: number;
|
|
476
479
|
content: {
|
|
477
480
|
c: string;
|
|
478
481
|
t: "encrypted";
|
|
479
482
|
};
|
|
480
|
-
id: string;
|
|
481
|
-
seq: number;
|
|
482
483
|
createdAt: number;
|
|
483
484
|
updatedAt: number;
|
|
484
485
|
localId?: string | null | undefined;
|
|
485
486
|
};
|
|
486
|
-
t: "new-message";
|
|
487
487
|
sid: string;
|
|
488
488
|
} | {
|
|
489
489
|
t: "update-session";
|
|
@@ -515,18 +515,18 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
515
515
|
seq: number;
|
|
516
516
|
createdAt: number;
|
|
517
517
|
body: {
|
|
518
|
+
t: "new-message";
|
|
518
519
|
message: {
|
|
520
|
+
id: string;
|
|
521
|
+
seq: number;
|
|
519
522
|
content: {
|
|
520
523
|
c: string;
|
|
521
524
|
t: "encrypted";
|
|
522
525
|
};
|
|
523
|
-
id: string;
|
|
524
|
-
seq: number;
|
|
525
526
|
createdAt: number;
|
|
526
527
|
updatedAt: number;
|
|
527
528
|
localId?: string | null | undefined;
|
|
528
529
|
};
|
|
529
|
-
t: "new-message";
|
|
530
530
|
sid: string;
|
|
531
531
|
} | {
|
|
532
532
|
t: "update-session";
|
package/dist/lib.d.mts
CHANGED
|
@@ -321,53 +321,53 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
321
321
|
createdAt: z.ZodNumber;
|
|
322
322
|
updatedAt: z.ZodNumber;
|
|
323
323
|
}, "strip", z.ZodTypeAny, {
|
|
324
|
+
id: string;
|
|
325
|
+
seq: number;
|
|
324
326
|
content: {
|
|
325
327
|
c: string;
|
|
326
328
|
t: "encrypted";
|
|
327
329
|
};
|
|
328
|
-
id: string;
|
|
329
|
-
seq: number;
|
|
330
330
|
createdAt: number;
|
|
331
331
|
updatedAt: number;
|
|
332
332
|
localId?: string | null | undefined;
|
|
333
333
|
}, {
|
|
334
|
+
id: string;
|
|
335
|
+
seq: number;
|
|
334
336
|
content: {
|
|
335
337
|
c: string;
|
|
336
338
|
t: "encrypted";
|
|
337
339
|
};
|
|
338
|
-
id: string;
|
|
339
|
-
seq: number;
|
|
340
340
|
createdAt: number;
|
|
341
341
|
updatedAt: number;
|
|
342
342
|
localId?: string | null | undefined;
|
|
343
343
|
}>;
|
|
344
344
|
}, "strip", z.ZodTypeAny, {
|
|
345
|
+
t: "new-message";
|
|
345
346
|
message: {
|
|
347
|
+
id: string;
|
|
348
|
+
seq: number;
|
|
346
349
|
content: {
|
|
347
350
|
c: string;
|
|
348
351
|
t: "encrypted";
|
|
349
352
|
};
|
|
350
|
-
id: string;
|
|
351
|
-
seq: number;
|
|
352
353
|
createdAt: number;
|
|
353
354
|
updatedAt: number;
|
|
354
355
|
localId?: string | null | undefined;
|
|
355
356
|
};
|
|
356
|
-
t: "new-message";
|
|
357
357
|
sid: string;
|
|
358
358
|
}, {
|
|
359
|
+
t: "new-message";
|
|
359
360
|
message: {
|
|
361
|
+
id: string;
|
|
362
|
+
seq: number;
|
|
360
363
|
content: {
|
|
361
364
|
c: string;
|
|
362
365
|
t: "encrypted";
|
|
363
366
|
};
|
|
364
|
-
id: string;
|
|
365
|
-
seq: number;
|
|
366
367
|
createdAt: number;
|
|
367
368
|
updatedAt: number;
|
|
368
369
|
localId?: string | null | undefined;
|
|
369
370
|
};
|
|
370
|
-
t: "new-message";
|
|
371
371
|
sid: string;
|
|
372
372
|
}>, z.ZodObject<{
|
|
373
373
|
t: z.ZodLiteral<"update-session">;
|
|
@@ -472,18 +472,18 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
472
472
|
seq: number;
|
|
473
473
|
createdAt: number;
|
|
474
474
|
body: {
|
|
475
|
+
t: "new-message";
|
|
475
476
|
message: {
|
|
477
|
+
id: string;
|
|
478
|
+
seq: number;
|
|
476
479
|
content: {
|
|
477
480
|
c: string;
|
|
478
481
|
t: "encrypted";
|
|
479
482
|
};
|
|
480
|
-
id: string;
|
|
481
|
-
seq: number;
|
|
482
483
|
createdAt: number;
|
|
483
484
|
updatedAt: number;
|
|
484
485
|
localId?: string | null | undefined;
|
|
485
486
|
};
|
|
486
|
-
t: "new-message";
|
|
487
487
|
sid: string;
|
|
488
488
|
} | {
|
|
489
489
|
t: "update-session";
|
|
@@ -515,18 +515,18 @@ declare const CoreUpdateContainerSchema: z.ZodObject<{
|
|
|
515
515
|
seq: number;
|
|
516
516
|
createdAt: number;
|
|
517
517
|
body: {
|
|
518
|
+
t: "new-message";
|
|
518
519
|
message: {
|
|
520
|
+
id: string;
|
|
521
|
+
seq: number;
|
|
519
522
|
content: {
|
|
520
523
|
c: string;
|
|
521
524
|
t: "encrypted";
|
|
522
525
|
};
|
|
523
|
-
id: string;
|
|
524
|
-
seq: number;
|
|
525
526
|
createdAt: number;
|
|
526
527
|
updatedAt: number;
|
|
527
528
|
localId?: string | null | undefined;
|
|
528
529
|
};
|
|
529
|
-
t: "new-message";
|
|
530
530
|
sid: string;
|
|
531
531
|
} | {
|
|
532
532
|
t: "update-session";
|