zenflo 0.11.8 → 0.11.10
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/{index-BSKmq2tY.mjs → index-BW7_WZAp.mjs} +554 -79
- package/dist/{index-DXM6ppoL.cjs → index-CIEIMabk.cjs} +552 -76
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/runCCR-COQ_d0t_.cjs +103 -0
- package/dist/runCCR-CQVvjom9.mjs +101 -0
- package/dist/{runCodex-C5pAgp-V.cjs → runCodex-CWrjFTDA.cjs} +2 -2
- package/dist/{runCodex-DoQNB2J-.mjs → runCodex-zJRwP8WW.mjs} +2 -2
- package/dist/status-4hHpWyGc.mjs +104 -0
- package/dist/status-CXWZdbyc.cjs +101 -0
- package/dist/status-DChMScEv.cjs +106 -0
- package/dist/status-DT-lQ5z3.mjs +99 -0
- package/dist/status-EIRGrJzv.mjs +92 -0
- package/dist/status-a3Xws-4m.cjs +94 -0
- package/dist/{types-uaIx8ab0.cjs → types-CVUeTsiC.cjs} +2 -2
- package/dist/{types-qQzfAnur.mjs → types-Kg2WtK0J.mjs} +2 -2
- package/package.json +1 -1
- package/scripts/ccr_launcher.cjs +309 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import os$1, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes } from 'node:crypto';
|
|
4
|
-
import { l as logger, p as projectPath,
|
|
4
|
+
import { l as logger, p as projectPath, e as backoff, f as delay, R as RawJSONLinesSchema, g as AsyncLock, c as configuration, r as readDaemonState, h as clearDaemonState, d as packageJson, b as readSettings, i as readCredentials, j as encodeBase64, u as updateSettings, k as encodeBase64Url, m as decodeBase64, w as writeCredentialsLegacy, n as writeCredentialsDataKey, o as acquireDaemonLock, q as writeDaemonState, A as ApiClient, s as releaseDaemonLock, t as clearCredentials, v as clearMachineId, x as getLatestDaemonLog } from './types-Kg2WtK0J.mjs';
|
|
5
5
|
import { spawn, execSync, execFileSync } from 'node:child_process';
|
|
6
6
|
import { resolve, join } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -18,8 +18,8 @@ import tweetnacl from 'tweetnacl';
|
|
|
18
18
|
import 'expo-server-sdk';
|
|
19
19
|
import { createHash, randomBytes as randomBytes$1 } from 'crypto';
|
|
20
20
|
import { spawn as spawn$1, execSync as execSync$1, exec } from 'child_process';
|
|
21
|
-
import { readFileSync as readFileSync$1, existsSync as existsSync$1,
|
|
22
|
-
import { join as join$1 } from 'path';
|
|
21
|
+
import { readFileSync as readFileSync$1, existsSync as existsSync$1, mkdirSync as mkdirSync$1, copyFileSync, writeFileSync, unlinkSync } from 'fs';
|
|
22
|
+
import path, { join as join$1 } from 'path';
|
|
23
23
|
import psList from 'ps-list';
|
|
24
24
|
import spawn$2 from 'cross-spawn';
|
|
25
25
|
import os from 'os';
|
|
@@ -32,6 +32,7 @@ import { validatorCompiler, serializerCompiler } from 'fastify-type-provider-zod
|
|
|
32
32
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
33
33
|
import { createServer } from 'node:http';
|
|
34
34
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
35
|
+
import { fileURLToPath as fileURLToPath$1 } from 'url';
|
|
35
36
|
import { createServer as createServer$1 } from 'http';
|
|
36
37
|
import { promisify } from 'util';
|
|
37
38
|
|
|
@@ -843,15 +844,15 @@ const RemoteModeDisplay = ({ messageBuffer, logPath, onExit, onSwitchToLocal })
|
|
|
843
844
|
const getMessageColor = (type) => {
|
|
844
845
|
switch (type) {
|
|
845
846
|
case "user":
|
|
846
|
-
return "
|
|
847
|
+
return "magentaBright";
|
|
847
848
|
case "assistant":
|
|
848
|
-
return "
|
|
849
|
+
return "cyanBright";
|
|
849
850
|
case "system":
|
|
850
|
-
return "
|
|
851
|
+
return "blueBright";
|
|
851
852
|
case "tool":
|
|
852
|
-
return "
|
|
853
|
+
return "yellowBright";
|
|
853
854
|
case "result":
|
|
854
|
-
return "
|
|
855
|
+
return "greenBright";
|
|
855
856
|
case "status":
|
|
856
857
|
return "gray";
|
|
857
858
|
default:
|
|
@@ -870,18 +871,28 @@ const RemoteModeDisplay = ({ messageBuffer, logPath, onExit, onSwitchToLocal })
|
|
|
870
871
|
return chunks.join("\n");
|
|
871
872
|
}).join("\n");
|
|
872
873
|
};
|
|
873
|
-
|
|
874
|
+
const banner = [
|
|
875
|
+
"\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557",
|
|
876
|
+
"\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551",
|
|
877
|
+
"\u2551 \u255A\u2550\u2550\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2551",
|
|
878
|
+
"\u2551 \u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2551",
|
|
879
|
+
"\u2551 \u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2551",
|
|
880
|
+
"\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2551",
|
|
881
|
+
"\u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u2551",
|
|
882
|
+
"\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
|
|
883
|
+
];
|
|
884
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: terminalWidth, height: terminalHeight }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, banner.map((line, i) => /* @__PURE__ */ React.createElement(Text, { key: i, color: "cyan", bold: true }, line))), /* @__PURE__ */ React.createElement(
|
|
874
885
|
Box,
|
|
875
886
|
{
|
|
876
887
|
flexDirection: "column",
|
|
877
888
|
width: terminalWidth,
|
|
878
|
-
height: terminalHeight -
|
|
889
|
+
height: terminalHeight - 14,
|
|
879
890
|
borderStyle: "round",
|
|
880
|
-
borderColor: "
|
|
891
|
+
borderColor: "magenta",
|
|
881
892
|
paddingX: 1,
|
|
882
893
|
overflow: "hidden"
|
|
883
894
|
},
|
|
884
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "
|
|
895
|
+
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "magenta", bold: true }, "\u{1F4E1} Remote Mode - Live Session"), /* @__PURE__ */ React.createElement(Text, { color: "magenta", dimColor: true }, "\u2500".repeat(Math.min(terminalWidth - 4, 60)))),
|
|
885
896
|
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", height: terminalHeight - 10, overflow: "hidden" }, messages.length === 0 ? /* @__PURE__ */ React.createElement(Text, { color: "gray", dimColor: true }, "Waiting for messages...") : (
|
|
886
897
|
// Show only the last messages that fit in the available space
|
|
887
898
|
messages.slice(-Math.max(1, terminalHeight - 10)).map((msg) => /* @__PURE__ */ React.createElement(Box, { key: msg.id, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: getMessageColor(msg.type), dimColor: true }, formatMessage(msg))))
|
|
@@ -890,14 +901,14 @@ const RemoteModeDisplay = ({ messageBuffer, logPath, onExit, onSwitchToLocal })
|
|
|
890
901
|
Box,
|
|
891
902
|
{
|
|
892
903
|
width: terminalWidth,
|
|
893
|
-
borderStyle: "
|
|
894
|
-
borderColor: actionInProgress ? "gray" : confirmationMode === "exit" ? "red" : confirmationMode === "switch" ? "yellow" : "
|
|
904
|
+
borderStyle: "double",
|
|
905
|
+
borderColor: actionInProgress ? "gray" : confirmationMode === "exit" ? "red" : confirmationMode === "switch" ? "yellow" : "cyan",
|
|
895
906
|
paddingX: 2,
|
|
896
907
|
justifyContent: "center",
|
|
897
908
|
alignItems: "center",
|
|
898
909
|
flexDirection: "column"
|
|
899
910
|
},
|
|
900
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center" }, actionInProgress === "exiting" ? /* @__PURE__ */ React.createElement(Text, { color: "gray", bold: true }, "Exiting...") : actionInProgress === "switching" ? /* @__PURE__ */ React.createElement(Text, { color: "
|
|
911
|
+
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "center" }, actionInProgress === "exiting" ? /* @__PURE__ */ React.createElement(Text, { color: "gray", bold: true }, "\u26A1 Exiting remote session...") : actionInProgress === "switching" ? /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, "\u{1F504} Switching to local mode...") : confirmationMode === "exit" ? /* @__PURE__ */ React.createElement(Text, { color: "red", bold: true }, "\u26A0\uFE0F Press Ctrl-C again to exit completely") : confirmationMode === "switch" ? /* @__PURE__ */ React.createElement(Text, { color: "yellow", bold: true }, "\u23F8\uFE0F Press SPACE again to switch to local mode") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, "\u{1F680} Press SPACE to switch to local \u2022 Ctrl-C to exit")), process.env.DEBUG && logPath && /* @__PURE__ */ React.createElement(Text, { color: "gray", dimColor: true }, "Debug logs: ", logPath))
|
|
901
912
|
));
|
|
902
913
|
};
|
|
903
914
|
|
|
@@ -998,10 +1009,10 @@ class AbortError extends Error {
|
|
|
998
1009
|
}
|
|
999
1010
|
}
|
|
1000
1011
|
|
|
1001
|
-
const __filename$
|
|
1002
|
-
const __dirname$
|
|
1012
|
+
const __filename$2 = fileURLToPath(import.meta.url);
|
|
1013
|
+
const __dirname$2 = join(__filename$2, "..");
|
|
1003
1014
|
function getDefaultClaudeCodePath() {
|
|
1004
|
-
return join(__dirname$
|
|
1015
|
+
return join(__dirname$2, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
1005
1016
|
}
|
|
1006
1017
|
function logDebug(message) {
|
|
1007
1018
|
if (process.env.DEBUG) {
|
|
@@ -3880,8 +3891,8 @@ function selectAuthenticationMethod() {
|
|
|
3880
3891
|
async function doMobileAuth(keypair) {
|
|
3881
3892
|
console.clear();
|
|
3882
3893
|
console.log("\nMobile Authentication\n");
|
|
3883
|
-
console.log("Scan this QR code with your
|
|
3884
|
-
const authUrl = "
|
|
3894
|
+
console.log("Scan this QR code with your ZenFlo mobile app:\n");
|
|
3895
|
+
const authUrl = "zenflo://terminal?" + encodeBase64Url(keypair.publicKey);
|
|
3885
3896
|
displayQRCode(authUrl);
|
|
3886
3897
|
console.log("\nOr manually enter this URL:");
|
|
3887
3898
|
console.log(authUrl);
|
|
@@ -4780,7 +4791,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4780
4791
|
// Initialize lifecycle state
|
|
4781
4792
|
lifecycleState: "running",
|
|
4782
4793
|
lifecycleStateSince: Date.now(),
|
|
4783
|
-
flavor: "claude"
|
|
4794
|
+
flavor: options.flavor || "claude"
|
|
4784
4795
|
};
|
|
4785
4796
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
4786
4797
|
logger.debug(`Session created: ${response.id}`);
|
|
@@ -5017,16 +5028,120 @@ async function runClaude(credentials, options = {}) {
|
|
|
5017
5028
|
process.exit(0);
|
|
5018
5029
|
}
|
|
5019
5030
|
|
|
5020
|
-
const
|
|
5021
|
-
const
|
|
5022
|
-
|
|
5031
|
+
const __filename$1 = fileURLToPath$1(import.meta.url);
|
|
5032
|
+
const __dirname$1 = path.dirname(__filename$1);
|
|
5033
|
+
const PLIST_LABEL$1 = "com.zenflo.daemon";
|
|
5034
|
+
const LAUNCH_AGENTS_DIR$1 = path.join(os.homedir(), "Library", "LaunchAgents");
|
|
5035
|
+
const PLIST_FILE$1 = path.join(LAUNCH_AGENTS_DIR$1, `${PLIST_LABEL$1}.plist`);
|
|
5036
|
+
const APP_BUNDLE_DIR = path.join(os.homedir(), "Library", "Application Support", "ZenFlo");
|
|
5037
|
+
const APP_BUNDLE_PATH = path.join(APP_BUNDLE_DIR, "ZenFlo Daemon.app");
|
|
5038
|
+
async function install$3() {
|
|
5023
5039
|
try {
|
|
5040
|
+
console.log(chalk.cyan("\u{1F4E6} Installing ZenFlo daemon as LaunchAgent...\n"));
|
|
5024
5041
|
if (existsSync$1(PLIST_FILE$1)) {
|
|
5025
|
-
|
|
5026
|
-
|
|
5042
|
+
console.log(chalk.yellow("\u26A0\uFE0F LaunchAgent already installed. Uninstalling first...\n"));
|
|
5043
|
+
try {
|
|
5044
|
+
execSync$1(`launchctl unload "${PLIST_FILE$1}"`, { stdio: "pipe" });
|
|
5045
|
+
} catch (error) {
|
|
5046
|
+
}
|
|
5047
|
+
}
|
|
5048
|
+
if (!existsSync$1(LAUNCH_AGENTS_DIR$1)) {
|
|
5049
|
+
mkdirSync$1(LAUNCH_AGENTS_DIR$1, { recursive: true });
|
|
5050
|
+
}
|
|
5051
|
+
let zenfloBinaryPath;
|
|
5052
|
+
try {
|
|
5053
|
+
zenfloBinaryPath = execSync$1("which zenflo", { encoding: "utf-8" }).trim();
|
|
5054
|
+
} catch (error) {
|
|
5055
|
+
throw new Error("Could not find zenflo binary in PATH. Is ZenFlo installed?");
|
|
5056
|
+
}
|
|
5057
|
+
console.log(chalk.cyan("Creating app bundle with ZenFlo icon..."));
|
|
5058
|
+
const contentsDir = path.join(APP_BUNDLE_PATH, "Contents");
|
|
5059
|
+
const macosDir = path.join(contentsDir, "MacOS");
|
|
5060
|
+
const resourcesDir = path.join(contentsDir, "Resources");
|
|
5061
|
+
mkdirSync$1(macosDir, { recursive: true });
|
|
5062
|
+
mkdirSync$1(resourcesDir, { recursive: true });
|
|
5063
|
+
const possibleIconPaths = [
|
|
5064
|
+
// PRIMARY: Icon Exports directory (user's actual branding)
|
|
5065
|
+
"/Users/quinnmay/developer/zenflo/Icon Exports/ZenFlo.icns",
|
|
5066
|
+
path.join(process.cwd(), "Icon Exports", "ZenFlo.icns"),
|
|
5067
|
+
path.join(__dirname$1, "..", "..", "..", "Icon Exports", "ZenFlo.icns"),
|
|
5068
|
+
// Fallback: Tauri icons (old location)
|
|
5069
|
+
"/Users/quinnmay/developer/zenflo/mobile/src-tauri/icons/icon.icns",
|
|
5070
|
+
"/Users/quinnmay/developer/zenflo/webapp/src-tauri/icons/icon.icns",
|
|
5071
|
+
path.join(process.cwd(), "mobile", "src-tauri", "icons", "icon.icns"),
|
|
5072
|
+
path.join(process.cwd(), "webapp", "src-tauri", "icons", "icon.icns"),
|
|
5073
|
+
path.join(__dirname$1, "..", "..", "..", "mobile", "src-tauri", "icons", "icon.icns"),
|
|
5074
|
+
path.join(__dirname$1, "..", "..", "..", "webapp", "src-tauri", "icons", "icon.icns")
|
|
5075
|
+
];
|
|
5076
|
+
let iconCopied = false;
|
|
5077
|
+
for (const iconPath of possibleIconPaths) {
|
|
5078
|
+
if (existsSync$1(iconPath)) {
|
|
5079
|
+
copyFileSync(iconPath, path.join(resourcesDir, "AppIcon.icns"));
|
|
5080
|
+
console.log(chalk.green("\u2705 Copied ZenFlo icon"));
|
|
5081
|
+
console.log(chalk.dim(` Source: ${iconPath}`));
|
|
5082
|
+
iconCopied = true;
|
|
5083
|
+
break;
|
|
5084
|
+
}
|
|
5027
5085
|
}
|
|
5028
|
-
|
|
5029
|
-
|
|
5086
|
+
if (!iconCopied) {
|
|
5087
|
+
console.log(chalk.yellow("\u26A0\uFE0F Could not find icon.icns (will use default icon)"));
|
|
5088
|
+
}
|
|
5089
|
+
try {
|
|
5090
|
+
execSync$1(`touch "${APP_BUNDLE_PATH}"`);
|
|
5091
|
+
execSync$1("killall Dock 2>/dev/null || true", { stdio: "pipe" });
|
|
5092
|
+
execSync$1("killall Finder 2>/dev/null || true", { stdio: "pipe" });
|
|
5093
|
+
console.log(chalk.green("\u2705 Refreshed icon cache\n"));
|
|
5094
|
+
} catch (error) {
|
|
5095
|
+
console.log(chalk.dim(" (Icon cache refresh skipped)\n"));
|
|
5096
|
+
}
|
|
5097
|
+
const infoPlistContent = trimIdent(`
|
|
5098
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
5099
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
5100
|
+
<plist version="1.0">
|
|
5101
|
+
<dict>
|
|
5102
|
+
<key>CFBundleExecutable</key>
|
|
5103
|
+
<string>zenflo-daemon</string>
|
|
5104
|
+
<key>CFBundleIconFile</key>
|
|
5105
|
+
<string>AppIcon.icns</string>
|
|
5106
|
+
<key>CFBundleIdentifier</key>
|
|
5107
|
+
<string>com.zenflo.daemon</string>
|
|
5108
|
+
<key>CFBundleName</key>
|
|
5109
|
+
<string>ZenFlo Daemon</string>
|
|
5110
|
+
<key>CFBundlePackageType</key>
|
|
5111
|
+
<string>APPL</string>
|
|
5112
|
+
<key>CFBundleShortVersionString</key>
|
|
5113
|
+
<string>1.0.0</string>
|
|
5114
|
+
<key>LSBackgroundOnly</key>
|
|
5115
|
+
<true/>
|
|
5116
|
+
<key>LSUIElement</key>
|
|
5117
|
+
<true/>
|
|
5118
|
+
</dict>
|
|
5119
|
+
</plist>
|
|
5120
|
+
`);
|
|
5121
|
+
writeFileSync(path.join(contentsDir, "Info.plist"), infoPlistContent);
|
|
5122
|
+
console.log(chalk.green("\u2705 Created app bundle Info.plist"));
|
|
5123
|
+
let nodePath;
|
|
5124
|
+
let zenfloScriptPath;
|
|
5125
|
+
try {
|
|
5126
|
+
nodePath = execSync$1("which node", { encoding: "utf-8" }).trim();
|
|
5127
|
+
} catch (error) {
|
|
5128
|
+
throw new Error("Could not find node binary in PATH. Is Node.js installed?");
|
|
5129
|
+
}
|
|
5130
|
+
try {
|
|
5131
|
+
const symlinkTarget = execSync$1(`readlink "${zenfloBinaryPath}"`, { encoding: "utf-8" }).trim();
|
|
5132
|
+
const symlinkDir = path.dirname(zenfloBinaryPath);
|
|
5133
|
+
zenfloScriptPath = path.resolve(symlinkDir, symlinkTarget);
|
|
5134
|
+
} catch (error) {
|
|
5135
|
+
zenfloScriptPath = zenfloBinaryPath;
|
|
5136
|
+
}
|
|
5137
|
+
const wrapperScript = trimIdent(`
|
|
5138
|
+
#!/bin/bash
|
|
5139
|
+
# Use absolute paths to avoid issues when launched from / by LaunchAgent
|
|
5140
|
+
exec "${nodePath}" "${zenfloScriptPath}" daemon start-sync
|
|
5141
|
+
`);
|
|
5142
|
+
const wrapperPath = path.join(macosDir, "zenflo-daemon");
|
|
5143
|
+
writeFileSync(wrapperPath, wrapperScript, { mode: 493 });
|
|
5144
|
+
console.log(chalk.green("\u2705 Created launcher script\n"));
|
|
5030
5145
|
const plistContent = trimIdent(`
|
|
5031
5146
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
5032
5147
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -5034,92 +5149,411 @@ async function install$1() {
|
|
|
5034
5149
|
<dict>
|
|
5035
5150
|
<key>Label</key>
|
|
5036
5151
|
<string>${PLIST_LABEL$1}</string>
|
|
5037
|
-
|
|
5152
|
+
|
|
5038
5153
|
<key>ProgramArguments</key>
|
|
5039
5154
|
<array>
|
|
5040
|
-
<string
|
|
5041
|
-
<string
|
|
5042
|
-
<string
|
|
5155
|
+
<string>/usr/bin/open</string>
|
|
5156
|
+
<string>-a</string>
|
|
5157
|
+
<string>${APP_BUNDLE_PATH}</string>
|
|
5158
|
+
<string>--background</string>
|
|
5043
5159
|
</array>
|
|
5044
|
-
|
|
5045
|
-
<key>EnvironmentVariables</key>
|
|
5046
|
-
<dict>
|
|
5047
|
-
<key>ZENFLO_DAEMON_MODE</key>
|
|
5048
|
-
<string>true</string>
|
|
5049
|
-
</dict>
|
|
5050
|
-
|
|
5160
|
+
|
|
5051
5161
|
<key>RunAtLoad</key>
|
|
5052
5162
|
<true/>
|
|
5053
|
-
|
|
5163
|
+
|
|
5054
5164
|
<key>KeepAlive</key>
|
|
5055
|
-
<
|
|
5056
|
-
|
|
5165
|
+
<dict>
|
|
5166
|
+
<key>SuccessfulExit</key>
|
|
5167
|
+
<false/>
|
|
5168
|
+
</dict>
|
|
5169
|
+
|
|
5057
5170
|
<key>StandardErrorPath</key>
|
|
5058
|
-
<string>${
|
|
5059
|
-
|
|
5171
|
+
<string>${configuration.zenfloHomeDir}/daemon.err</string>
|
|
5172
|
+
|
|
5060
5173
|
<key>StandardOutPath</key>
|
|
5061
|
-
<string>${
|
|
5062
|
-
|
|
5174
|
+
<string>${configuration.zenfloHomeDir}/daemon.log</string>
|
|
5175
|
+
|
|
5063
5176
|
<key>WorkingDirectory</key>
|
|
5064
|
-
<string
|
|
5177
|
+
<string>${os.homedir()}</string>
|
|
5178
|
+
|
|
5179
|
+
<key>ProcessType</key>
|
|
5180
|
+
<string>Background</string>
|
|
5181
|
+
|
|
5182
|
+
<key>ThrottleInterval</key>
|
|
5183
|
+
<integer>10</integer>
|
|
5065
5184
|
</dict>
|
|
5066
5185
|
</plist>
|
|
5067
5186
|
`);
|
|
5068
|
-
writeFileSync(PLIST_FILE$1, plistContent);
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5187
|
+
writeFileSync(PLIST_FILE$1, plistContent, { mode: 420 });
|
|
5188
|
+
console.log(chalk.green("\u2705 Created LaunchAgent plist"));
|
|
5189
|
+
console.log(chalk.dim(` ${PLIST_FILE$1}
|
|
5190
|
+
`));
|
|
5191
|
+
try {
|
|
5192
|
+
execSync$1(`launchctl load "${PLIST_FILE$1}"`, { stdio: "pipe" });
|
|
5193
|
+
console.log(chalk.green("\u2705 LaunchAgent loaded successfully\n"));
|
|
5194
|
+
} catch (error) {
|
|
5195
|
+
throw new Error(`Failed to load LaunchAgent: ${error instanceof Error ? error.message : error}`);
|
|
5196
|
+
}
|
|
5197
|
+
console.log(chalk.green.bold("\u{1F389} Installation complete!\n"));
|
|
5198
|
+
console.log(chalk.cyan("The daemon will now:"));
|
|
5199
|
+
console.log(chalk.dim(" \u2022 Start automatically when you log in"));
|
|
5200
|
+
console.log(chalk.dim(" \u2022 Run in the background 24/7"));
|
|
5201
|
+
console.log(chalk.dim(" \u2022 Restart automatically if it crashes"));
|
|
5202
|
+
console.log(chalk.dim(" \u2022 Display with ZenFlo branding in Activity Monitor\n"));
|
|
5203
|
+
console.log(chalk.cyan("Next steps:"));
|
|
5204
|
+
console.log(chalk.dim(" \u2022 Check status: ") + chalk.white("zenflo daemon status"));
|
|
5205
|
+
console.log(chalk.dim(" \u2022 View logs: ") + chalk.white(`tail -f ${configuration.zenfloHomeDir}/daemon.log`));
|
|
5206
|
+
console.log(chalk.dim(" \u2022 Uninstall: ") + chalk.white("zenflo daemon uninstall\n"));
|
|
5207
|
+
console.log(chalk.yellow("\u{1F4A1} Tip: To grant Full Disk Access:"));
|
|
5208
|
+
console.log(chalk.dim(" 1. Open System Settings \u2192 Privacy & Security \u2192 Full Disk Access"));
|
|
5209
|
+
console.log(chalk.dim(" 2. Click the + button"));
|
|
5210
|
+
console.log(chalk.dim(" 3. Navigate to: ") + chalk.white(zenfloBinaryPath));
|
|
5211
|
+
console.log(chalk.dim(" 4. Enable the toggle\n"));
|
|
5074
5212
|
} catch (error) {
|
|
5213
|
+
console.error(chalk.red("\u274C Installation failed:"), error instanceof Error ? error.message : error);
|
|
5075
5214
|
logger.debug("Failed to install daemon:", error);
|
|
5076
5215
|
throw error;
|
|
5077
5216
|
}
|
|
5078
5217
|
}
|
|
5079
5218
|
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5219
|
+
const TASK_NAME$1 = "ZenFlo Daemon";
|
|
5220
|
+
async function install$2() {
|
|
5221
|
+
try {
|
|
5222
|
+
console.log(chalk.cyan("\u{1F4E6} Installing ZenFlo daemon as Windows Task Scheduler task...\n"));
|
|
5223
|
+
try {
|
|
5224
|
+
execSync$1(`schtasks /Query /TN "${TASK_NAME$1}"`, { stdio: "pipe" });
|
|
5225
|
+
console.log(chalk.yellow("\u26A0\uFE0F Task already installed. Uninstalling first...\n"));
|
|
5226
|
+
try {
|
|
5227
|
+
execSync$1(`schtasks /Delete /TN "${TASK_NAME$1}" /F`, { stdio: "pipe" });
|
|
5228
|
+
} catch (error) {
|
|
5229
|
+
}
|
|
5230
|
+
} catch (error) {
|
|
5231
|
+
}
|
|
5232
|
+
let zenfloBinaryPath;
|
|
5233
|
+
try {
|
|
5234
|
+
zenfloBinaryPath = execSync$1("where zenflo", { encoding: "utf-8" }).trim().split("\n")[0];
|
|
5235
|
+
} catch (error) {
|
|
5236
|
+
throw new Error("Could not find zenflo binary in PATH. Is ZenFlo installed?");
|
|
5237
|
+
}
|
|
5238
|
+
let nodePath;
|
|
5239
|
+
try {
|
|
5240
|
+
nodePath = execSync$1("where node", { encoding: "utf-8" }).trim().split("\n")[0];
|
|
5241
|
+
} catch (error) {
|
|
5242
|
+
throw new Error("Could not find node.exe in PATH. Is Node.js installed?");
|
|
5243
|
+
}
|
|
5244
|
+
const xmlPath = path.join(configuration.zenfloHomeDir, "daemon-task.xml");
|
|
5245
|
+
const xmlContent = trimIdent(`
|
|
5246
|
+
<?xml version="1.0" encoding="UTF-16"?>
|
|
5247
|
+
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
5248
|
+
<RegistrationInfo>
|
|
5249
|
+
<Date>2025-01-01T00:00:00</Date>
|
|
5250
|
+
<Author>${os.userInfo().username}</Author>
|
|
5251
|
+
<Description>ZenFlo AI coding assistant daemon service</Description>
|
|
5252
|
+
</RegistrationInfo>
|
|
5253
|
+
<Triggers>
|
|
5254
|
+
<LogonTrigger>
|
|
5255
|
+
<Enabled>true</Enabled>
|
|
5256
|
+
<UserId>${os.userInfo().username}</UserId>
|
|
5257
|
+
</LogonTrigger>
|
|
5258
|
+
</Triggers>
|
|
5259
|
+
<Principals>
|
|
5260
|
+
<Principal id="Author">
|
|
5261
|
+
<UserId>${os.userInfo().username}</UserId>
|
|
5262
|
+
<LogonType>InteractiveToken</LogonType>
|
|
5263
|
+
<RunLevel>LeastPrivilege</RunLevel>
|
|
5264
|
+
</Principal>
|
|
5265
|
+
</Principals>
|
|
5266
|
+
<Settings>
|
|
5267
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
5268
|
+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
5269
|
+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
5270
|
+
<AllowHardTerminate>true</AllowHardTerminate>
|
|
5271
|
+
<StartWhenAvailable>true</StartWhenAvailable>
|
|
5272
|
+
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
|
5273
|
+
<IdleSettings>
|
|
5274
|
+
<StopOnIdleEnd>false</StopOnIdleEnd>
|
|
5275
|
+
<RestartOnIdle>false</RestartOnIdle>
|
|
5276
|
+
</IdleSettings>
|
|
5277
|
+
<AllowStartOnDemand>true</AllowStartOnDemand>
|
|
5278
|
+
<Enabled>true</Enabled>
|
|
5279
|
+
<Hidden>false</Hidden>
|
|
5280
|
+
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
5281
|
+
<WakeToRun>false</WakeToRun>
|
|
5282
|
+
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
5283
|
+
<Priority>7</Priority>
|
|
5284
|
+
<RestartOnFailure>
|
|
5285
|
+
<Interval>PT1M</Interval>
|
|
5286
|
+
<Count>3</Count>
|
|
5287
|
+
</RestartOnFailure>
|
|
5288
|
+
</Settings>
|
|
5289
|
+
<Actions Context="Author">
|
|
5290
|
+
<Exec>
|
|
5291
|
+
<Command>"${nodePath}"</Command>
|
|
5292
|
+
<Arguments>"${zenfloBinaryPath}" daemon start-sync</Arguments>
|
|
5293
|
+
<WorkingDirectory>${os.homedir()}</WorkingDirectory>
|
|
5294
|
+
</Exec>
|
|
5295
|
+
</Actions>
|
|
5296
|
+
</Task>
|
|
5297
|
+
`);
|
|
5298
|
+
writeFileSync(xmlPath, xmlContent, { encoding: "utf-16le" });
|
|
5299
|
+
console.log(chalk.green("\u2705 Created task definition XML"));
|
|
5300
|
+
console.log(chalk.dim(` ${xmlPath}
|
|
5301
|
+
`));
|
|
5302
|
+
try {
|
|
5303
|
+
execSync$1(`schtasks /Create /XML "${xmlPath}" /TN "${TASK_NAME$1}"`, { stdio: "pipe" });
|
|
5304
|
+
console.log(chalk.green("\u2705 Task created successfully\n"));
|
|
5305
|
+
} catch (error) {
|
|
5306
|
+
throw new Error(`Failed to create scheduled task: ${error instanceof Error ? error.message : error}`);
|
|
5307
|
+
}
|
|
5308
|
+
try {
|
|
5309
|
+
execSync$1(`schtasks /Run /TN "${TASK_NAME$1}"`, { stdio: "pipe" });
|
|
5310
|
+
console.log(chalk.green("\u2705 Task started successfully\n"));
|
|
5311
|
+
} catch (error) {
|
|
5312
|
+
console.log(chalk.yellow("\u26A0\uFE0F Could not start task immediately (will start at next login)\n"));
|
|
5313
|
+
}
|
|
5314
|
+
console.log(chalk.green.bold("\u{1F389} Installation complete!\n"));
|
|
5315
|
+
console.log(chalk.cyan("The daemon will now:"));
|
|
5316
|
+
console.log(chalk.dim(" \u2022 Start automatically when you log in"));
|
|
5317
|
+
console.log(chalk.dim(" \u2022 Run in the background 24/7"));
|
|
5318
|
+
console.log(chalk.dim(" \u2022 Restart automatically if it crashes (up to 3 times)\n"));
|
|
5319
|
+
console.log(chalk.cyan("Next steps:"));
|
|
5320
|
+
console.log(chalk.dim(" \u2022 Check status: ") + chalk.white("zenflo daemon status"));
|
|
5321
|
+
console.log(chalk.dim(" \u2022 View logs: ") + chalk.white(`type ${configuration.zenfloHomeDir}\\daemon.log`));
|
|
5322
|
+
console.log(chalk.dim(" \u2022 Uninstall: ") + chalk.white("zenflo daemon uninstall\n"));
|
|
5323
|
+
console.log(chalk.yellow("\u{1F4A1} Tip: View task in Task Scheduler:"));
|
|
5324
|
+
console.log(chalk.dim(" 1. Press Win+R and type: taskschd.msc"));
|
|
5325
|
+
console.log(chalk.dim(' 2. Find "ZenFlo Daemon" in Task Scheduler Library'));
|
|
5326
|
+
console.log(chalk.dim(" 3. View history, logs, and configuration\n"));
|
|
5327
|
+
} catch (error) {
|
|
5328
|
+
console.error(chalk.red("\u274C Installation failed:"), error instanceof Error ? error.message : error);
|
|
5329
|
+
logger.debug("Failed to install daemon:", error);
|
|
5330
|
+
throw error;
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
|
|
5334
|
+
const SERVICE_NAME$1 = "zenflo-daemon";
|
|
5335
|
+
const SYSTEMD_USER_DIR$1 = path.join(os.homedir(), ".config", "systemd", "user");
|
|
5336
|
+
const SERVICE_FILE$1 = path.join(SYSTEMD_USER_DIR$1, `${SERVICE_NAME$1}.service`);
|
|
5337
|
+
async function install$1() {
|
|
5338
|
+
try {
|
|
5339
|
+
console.log(chalk.cyan("\u{1F4E6} Installing ZenFlo daemon as systemd user service...\n"));
|
|
5340
|
+
if (existsSync$1(SERVICE_FILE$1)) {
|
|
5341
|
+
console.log(chalk.yellow("\u26A0\uFE0F Service already installed. Uninstalling first...\n"));
|
|
5342
|
+
try {
|
|
5343
|
+
execSync$1(`systemctl --user stop ${SERVICE_NAME$1}`, { stdio: "pipe" });
|
|
5344
|
+
execSync$1(`systemctl --user disable ${SERVICE_NAME$1}`, { stdio: "pipe" });
|
|
5345
|
+
} catch (error) {
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
if (!existsSync$1(SYSTEMD_USER_DIR$1)) {
|
|
5349
|
+
mkdirSync$1(SYSTEMD_USER_DIR$1, { recursive: true });
|
|
5350
|
+
}
|
|
5351
|
+
let zenfloBinaryPath;
|
|
5352
|
+
try {
|
|
5353
|
+
zenfloBinaryPath = execSync$1("which zenflo", { encoding: "utf-8" }).trim();
|
|
5354
|
+
} catch (error) {
|
|
5355
|
+
throw new Error("Could not find zenflo binary in PATH. Is ZenFlo installed?");
|
|
5356
|
+
}
|
|
5357
|
+
const serviceContent = trimIdent(`
|
|
5358
|
+
[Unit]
|
|
5359
|
+
Description=ZenFlo AI Coding Assistant Daemon
|
|
5360
|
+
After=network.target
|
|
5361
|
+
|
|
5362
|
+
[Service]
|
|
5363
|
+
Type=simple
|
|
5364
|
+
ExecStart=${zenfloBinaryPath} daemon start-sync
|
|
5365
|
+
Restart=on-failure
|
|
5366
|
+
RestartSec=10
|
|
5367
|
+
StandardOutput=append:${configuration.zenfloHomeDir}/daemon.log
|
|
5368
|
+
StandardError=append:${configuration.zenfloHomeDir}/daemon.err
|
|
5369
|
+
WorkingDirectory=${os.homedir()}
|
|
5370
|
+
|
|
5371
|
+
[Install]
|
|
5372
|
+
WantedBy=default.target
|
|
5373
|
+
`);
|
|
5374
|
+
writeFileSync(SERVICE_FILE$1, serviceContent, { mode: 420 });
|
|
5375
|
+
console.log(chalk.green("\u2705 Created systemd service file"));
|
|
5376
|
+
console.log(chalk.dim(` ${SERVICE_FILE$1}
|
|
5377
|
+
`));
|
|
5378
|
+
try {
|
|
5379
|
+
execSync$1("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
5380
|
+
console.log(chalk.green("\u2705 Reloaded systemd configuration"));
|
|
5381
|
+
} catch (error) {
|
|
5382
|
+
throw new Error(`Failed to reload systemd: ${error instanceof Error ? error.message : error}`);
|
|
5383
|
+
}
|
|
5384
|
+
try {
|
|
5385
|
+
execSync$1(`systemctl --user enable ${SERVICE_NAME$1}`, { stdio: "pipe" });
|
|
5386
|
+
console.log(chalk.green("\u2705 Service enabled (auto-start at login)"));
|
|
5387
|
+
} catch (error) {
|
|
5388
|
+
throw new Error(`Failed to enable service: ${error instanceof Error ? error.message : error}`);
|
|
5389
|
+
}
|
|
5390
|
+
try {
|
|
5391
|
+
execSync$1(`systemctl --user start ${SERVICE_NAME$1}`, { stdio: "pipe" });
|
|
5392
|
+
console.log(chalk.green("\u2705 Service started successfully\n"));
|
|
5393
|
+
} catch (error) {
|
|
5394
|
+
throw new Error(`Failed to start service: ${error instanceof Error ? error.message : error}`);
|
|
5395
|
+
}
|
|
5396
|
+
console.log(chalk.green.bold("\u{1F389} Installation complete!\n"));
|
|
5397
|
+
console.log(chalk.cyan("The daemon will now:"));
|
|
5398
|
+
console.log(chalk.dim(" \u2022 Start automatically when you log in"));
|
|
5399
|
+
console.log(chalk.dim(" \u2022 Run in the background 24/7"));
|
|
5400
|
+
console.log(chalk.dim(" \u2022 Restart automatically if it crashes\n"));
|
|
5401
|
+
console.log(chalk.cyan("Next steps:"));
|
|
5402
|
+
console.log(chalk.dim(" \u2022 Check status: ") + chalk.white("zenflo daemon status"));
|
|
5403
|
+
console.log(chalk.dim(" \u2022 View logs: ") + chalk.white(`tail -f ${configuration.zenfloHomeDir}/daemon.log`));
|
|
5404
|
+
console.log(chalk.dim(" \u2022 Uninstall: ") + chalk.white("zenflo daemon uninstall\n"));
|
|
5405
|
+
console.log(chalk.yellow("\u{1F4A1} Tip: systemd commands:"));
|
|
5406
|
+
console.log(chalk.dim(" \u2022 Check status: ") + chalk.white(`systemctl --user status ${SERVICE_NAME$1}`));
|
|
5407
|
+
console.log(chalk.dim(" \u2022 View logs: ") + chalk.white(`journalctl --user -u ${SERVICE_NAME$1} -f`));
|
|
5408
|
+
console.log(chalk.dim(" \u2022 Restart: ") + chalk.white(`systemctl --user restart ${SERVICE_NAME$1}
|
|
5409
|
+
`));
|
|
5410
|
+
} catch (error) {
|
|
5411
|
+
console.error(chalk.red("\u274C Installation failed:"), error instanceof Error ? error.message : error);
|
|
5412
|
+
logger.debug("Failed to install daemon:", error);
|
|
5413
|
+
throw error;
|
|
5083
5414
|
}
|
|
5084
|
-
|
|
5085
|
-
|
|
5415
|
+
}
|
|
5416
|
+
|
|
5417
|
+
async function install() {
|
|
5418
|
+
switch (process.platform) {
|
|
5419
|
+
case "darwin":
|
|
5420
|
+
await install$3();
|
|
5421
|
+
break;
|
|
5422
|
+
case "win32":
|
|
5423
|
+
await install$2();
|
|
5424
|
+
break;
|
|
5425
|
+
case "linux":
|
|
5426
|
+
await install$1();
|
|
5427
|
+
break;
|
|
5428
|
+
default:
|
|
5429
|
+
throw new Error(`Daemon installation is not supported on platform: ${process.platform}`);
|
|
5086
5430
|
}
|
|
5087
|
-
logger.info("Installing ZenFlo CLI daemon for macOS...");
|
|
5088
|
-
await install$1();
|
|
5089
5431
|
}
|
|
5090
5432
|
|
|
5091
|
-
const PLIST_LABEL = "com.
|
|
5092
|
-
const
|
|
5093
|
-
|
|
5433
|
+
const PLIST_LABEL = "com.zenflo.daemon";
|
|
5434
|
+
const LAUNCH_AGENTS_DIR = path.join(os.homedir(), "Library", "LaunchAgents");
|
|
5435
|
+
const PLIST_FILE = path.join(LAUNCH_AGENTS_DIR, `${PLIST_LABEL}.plist`);
|
|
5436
|
+
async function uninstall$3() {
|
|
5094
5437
|
try {
|
|
5438
|
+
console.log(chalk.cyan("\u{1F5D1}\uFE0F Uninstalling ZenFlo daemon LaunchAgent...\n"));
|
|
5095
5439
|
if (!existsSync$1(PLIST_FILE)) {
|
|
5096
|
-
|
|
5440
|
+
console.log(chalk.yellow("\u26A0\uFE0F LaunchAgent not found. Nothing to uninstall."));
|
|
5441
|
+
console.log(chalk.dim(` Expected location: ${PLIST_FILE}
|
|
5442
|
+
`));
|
|
5097
5443
|
return;
|
|
5098
5444
|
}
|
|
5099
5445
|
try {
|
|
5100
|
-
execSync$1(`launchctl unload ${PLIST_FILE}`, { stdio: "
|
|
5101
|
-
|
|
5446
|
+
execSync$1(`launchctl unload "${PLIST_FILE}"`, { stdio: "pipe" });
|
|
5447
|
+
console.log(chalk.green("\u2705 LaunchAgent unloaded"));
|
|
5102
5448
|
} catch (error) {
|
|
5103
|
-
|
|
5449
|
+
console.log(chalk.dim(" (LaunchAgent was not loaded)\n"));
|
|
5104
5450
|
}
|
|
5105
5451
|
unlinkSync(PLIST_FILE);
|
|
5106
|
-
|
|
5107
|
-
|
|
5452
|
+
console.log(chalk.green("\u2705 Removed LaunchAgent plist\n"));
|
|
5453
|
+
console.log(chalk.green.bold("\u{1F389} Uninstallation complete!\n"));
|
|
5454
|
+
console.log(chalk.cyan("The daemon will no longer:"));
|
|
5455
|
+
console.log(chalk.dim(" \u2022 Start automatically at login"));
|
|
5456
|
+
console.log(chalk.dim(" \u2022 Run in the background\n"));
|
|
5457
|
+
console.log(chalk.cyan("Note: ") + chalk.dim("Auto-start will still work when you run ") + chalk.white("zenflo\n"));
|
|
5108
5458
|
} catch (error) {
|
|
5459
|
+
console.error(chalk.red("\u274C Uninstallation failed:"), error instanceof Error ? error.message : error);
|
|
5109
5460
|
logger.debug("Failed to uninstall daemon:", error);
|
|
5110
5461
|
throw error;
|
|
5111
5462
|
}
|
|
5112
5463
|
}
|
|
5113
5464
|
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5465
|
+
const TASK_NAME = "ZenFlo Daemon";
|
|
5466
|
+
async function uninstall$2() {
|
|
5467
|
+
try {
|
|
5468
|
+
console.log(chalk.cyan("\u{1F5D1}\uFE0F Uninstalling ZenFlo daemon scheduled task...\n"));
|
|
5469
|
+
try {
|
|
5470
|
+
execSync$1(`schtasks /Query /TN "${TASK_NAME}"`, { stdio: "pipe" });
|
|
5471
|
+
} catch (error) {
|
|
5472
|
+
console.log(chalk.yellow("\u26A0\uFE0F Scheduled task not found. Nothing to uninstall.\n"));
|
|
5473
|
+
return;
|
|
5474
|
+
}
|
|
5475
|
+
try {
|
|
5476
|
+
execSync$1(`schtasks /End /TN "${TASK_NAME}"`, { stdio: "pipe" });
|
|
5477
|
+
console.log(chalk.green("\u2705 Task stopped"));
|
|
5478
|
+
} catch (error) {
|
|
5479
|
+
console.log(chalk.dim(" (Task was not running)\n"));
|
|
5480
|
+
}
|
|
5481
|
+
try {
|
|
5482
|
+
execSync$1(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: "pipe" });
|
|
5483
|
+
console.log(chalk.green("\u2705 Scheduled task removed\n"));
|
|
5484
|
+
} catch (error) {
|
|
5485
|
+
throw new Error(`Failed to delete scheduled task: ${error instanceof Error ? error.message : error}`);
|
|
5486
|
+
}
|
|
5487
|
+
console.log(chalk.green.bold("\u{1F389} Uninstallation complete!\n"));
|
|
5488
|
+
console.log(chalk.cyan("The daemon will no longer:"));
|
|
5489
|
+
console.log(chalk.dim(" \u2022 Start automatically at login"));
|
|
5490
|
+
console.log(chalk.dim(" \u2022 Run in the background\n"));
|
|
5491
|
+
console.log(chalk.cyan("Note: ") + chalk.dim("Auto-start will still work when you run ") + chalk.white("zenflo\n"));
|
|
5492
|
+
} catch (error) {
|
|
5493
|
+
console.error(chalk.red("\u274C Uninstallation failed:"), error instanceof Error ? error.message : error);
|
|
5494
|
+
logger.debug("Failed to uninstall daemon:", error);
|
|
5495
|
+
throw error;
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
|
|
5499
|
+
const SERVICE_NAME = "zenflo-daemon";
|
|
5500
|
+
const SYSTEMD_USER_DIR = path.join(os.homedir(), ".config", "systemd", "user");
|
|
5501
|
+
const SERVICE_FILE = path.join(SYSTEMD_USER_DIR, `${SERVICE_NAME}.service`);
|
|
5502
|
+
async function uninstall$1() {
|
|
5503
|
+
try {
|
|
5504
|
+
console.log(chalk.cyan("\u{1F5D1}\uFE0F Uninstalling ZenFlo daemon systemd service...\n"));
|
|
5505
|
+
if (!existsSync$1(SERVICE_FILE)) {
|
|
5506
|
+
console.log(chalk.yellow("\u26A0\uFE0F Service not found. Nothing to uninstall."));
|
|
5507
|
+
console.log(chalk.dim(` Expected location: ${SERVICE_FILE}
|
|
5508
|
+
`));
|
|
5509
|
+
return;
|
|
5510
|
+
}
|
|
5511
|
+
try {
|
|
5512
|
+
execSync$1(`systemctl --user stop ${SERVICE_NAME}`, { stdio: "pipe" });
|
|
5513
|
+
console.log(chalk.green("\u2705 Service stopped"));
|
|
5514
|
+
} catch (error) {
|
|
5515
|
+
console.log(chalk.dim(" (Service was not running)"));
|
|
5516
|
+
}
|
|
5517
|
+
try {
|
|
5518
|
+
execSync$1(`systemctl --user disable ${SERVICE_NAME}`, { stdio: "pipe" });
|
|
5519
|
+
console.log(chalk.green("\u2705 Service disabled"));
|
|
5520
|
+
} catch (error) {
|
|
5521
|
+
console.log(chalk.dim(" (Service was not enabled)"));
|
|
5522
|
+
}
|
|
5523
|
+
unlinkSync(SERVICE_FILE);
|
|
5524
|
+
console.log(chalk.green("\u2705 Removed service file\n"));
|
|
5525
|
+
try {
|
|
5526
|
+
execSync$1("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
5527
|
+
console.log(chalk.green("\u2705 Reloaded systemd configuration\n"));
|
|
5528
|
+
} catch (error) {
|
|
5529
|
+
console.log(chalk.dim(" (Could not reload systemd)\n"));
|
|
5530
|
+
}
|
|
5531
|
+
console.log(chalk.green.bold("\u{1F389} Uninstallation complete!\n"));
|
|
5532
|
+
console.log(chalk.cyan("The daemon will no longer:"));
|
|
5533
|
+
console.log(chalk.dim(" \u2022 Start automatically at login"));
|
|
5534
|
+
console.log(chalk.dim(" \u2022 Run in the background\n"));
|
|
5535
|
+
console.log(chalk.cyan("Note: ") + chalk.dim("Auto-start will still work when you run ") + chalk.white("zenflo\n"));
|
|
5536
|
+
} catch (error) {
|
|
5537
|
+
console.error(chalk.red("\u274C Uninstallation failed:"), error instanceof Error ? error.message : error);
|
|
5538
|
+
logger.debug("Failed to uninstall daemon:", error);
|
|
5539
|
+
throw error;
|
|
5117
5540
|
}
|
|
5118
|
-
|
|
5119
|
-
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5543
|
+
async function uninstall() {
|
|
5544
|
+
switch (process.platform) {
|
|
5545
|
+
case "darwin":
|
|
5546
|
+
await uninstall$3();
|
|
5547
|
+
break;
|
|
5548
|
+
case "win32":
|
|
5549
|
+
await uninstall$2();
|
|
5550
|
+
break;
|
|
5551
|
+
case "linux":
|
|
5552
|
+
await uninstall$1();
|
|
5553
|
+
break;
|
|
5554
|
+
default:
|
|
5555
|
+
throw new Error(`Daemon uninstallation is not supported on platform: ${process.platform}`);
|
|
5120
5556
|
}
|
|
5121
|
-
logger.info("Uninstalling ZenFlo CLI daemon for macOS...");
|
|
5122
|
-
await uninstall$1();
|
|
5123
5557
|
}
|
|
5124
5558
|
|
|
5125
5559
|
async function handleAuthCommand(args) {
|
|
@@ -5875,7 +6309,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5875
6309
|
return;
|
|
5876
6310
|
} else if (subcommand === "codex") {
|
|
5877
6311
|
try {
|
|
5878
|
-
const { runCodex } = await import('./runCodex-
|
|
6312
|
+
const { runCodex } = await import('./runCodex-zJRwP8WW.mjs');
|
|
5879
6313
|
let startedBy = void 0;
|
|
5880
6314
|
for (let i = 1; i < args.length; i++) {
|
|
5881
6315
|
if (args[i] === "--started-by") {
|
|
@@ -5894,6 +6328,27 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5894
6328
|
process.exit(1);
|
|
5895
6329
|
}
|
|
5896
6330
|
return;
|
|
6331
|
+
} else if (subcommand === "ccr" || subcommand === "glm") {
|
|
6332
|
+
try {
|
|
6333
|
+
const { runCCR } = await import('./runCCR-CQVvjom9.mjs');
|
|
6334
|
+
let startedBy = void 0;
|
|
6335
|
+
for (let i = 1; i < args.length; i++) {
|
|
6336
|
+
if (args[i] === "--started-by") {
|
|
6337
|
+
startedBy = args[++i];
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
const {
|
|
6341
|
+
credentials
|
|
6342
|
+
} = await authAndSetupMachineIfNeeded();
|
|
6343
|
+
await runCCR({ credentials, startedBy });
|
|
6344
|
+
} catch (error) {
|
|
6345
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
6346
|
+
if (process.env.DEBUG) {
|
|
6347
|
+
console.error(error);
|
|
6348
|
+
}
|
|
6349
|
+
process.exit(1);
|
|
6350
|
+
}
|
|
6351
|
+
return;
|
|
5897
6352
|
} else if (subcommand === "logout") {
|
|
5898
6353
|
console.log(chalk.yellow('Note: "happy logout" is deprecated. Use "happy auth logout" instead.\n'));
|
|
5899
6354
|
try {
|
|
@@ -5974,7 +6429,27 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5974
6429
|
await stopDaemon();
|
|
5975
6430
|
process.exit(0);
|
|
5976
6431
|
} else if (daemonSubcommand === "status") {
|
|
5977
|
-
|
|
6432
|
+
try {
|
|
6433
|
+
let statusModule;
|
|
6434
|
+
switch (process.platform) {
|
|
6435
|
+
case "darwin":
|
|
6436
|
+
statusModule = await import('./status-4hHpWyGc.mjs');
|
|
6437
|
+
break;
|
|
6438
|
+
case "win32":
|
|
6439
|
+
statusModule = await import('./status-EIRGrJzv.mjs');
|
|
6440
|
+
break;
|
|
6441
|
+
case "linux":
|
|
6442
|
+
statusModule = await import('./status-DT-lQ5z3.mjs');
|
|
6443
|
+
break;
|
|
6444
|
+
default:
|
|
6445
|
+
console.error(chalk.red(`Status command not supported on platform: ${process.platform}`));
|
|
6446
|
+
process.exit(1);
|
|
6447
|
+
}
|
|
6448
|
+
await statusModule.status();
|
|
6449
|
+
} catch (error) {
|
|
6450
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
6451
|
+
process.exit(1);
|
|
6452
|
+
}
|
|
5978
6453
|
process.exit(0);
|
|
5979
6454
|
} else if (daemonSubcommand === "logs") {
|
|
5980
6455
|
const latest = await getLatestDaemonLog();
|
|
@@ -6183,4 +6658,4 @@ ${chalk.bold("Examples:")}
|
|
|
6183
6658
|
}
|
|
6184
6659
|
}
|
|
6185
6660
|
|
|
6186
|
-
export { MessageQueue2 as M,
|
|
6661
|
+
export { MessageQueue2 as M, registerKillSessionHandler as a, MessageBuffer as b, stopCaffeinate as c, hashObject as h, initialMachineMetadata as i, notifyDaemonSessionStarted as n, runClaude as r, startZenfloServer as s, trimIdent as t };
|