zenflo 0.11.2 → 0.11.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/README.md +12 -12
- package/dist/{index-DOSJeDVm.mjs → index-BFbq03uJ.mjs} +65 -65
- package/dist/{index-CHuQvfiV.cjs → index-FBQqV3tt.cjs} +66 -66
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +2 -2
- package/dist/lib.d.mts +2 -2
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-4WtZDlEl.cjs → runCodex-CzeejIBC.cjs} +8 -8
- package/dist/{runCodex-CLOGxmC3.mjs → runCodex-DAY1lCxR.mjs} +8 -8
- package/dist/{types-D5e0nXc5.cjs → types-B4VPN3pY.cjs} +7 -7
- package/dist/{types-qUJrSxtv.mjs → types-D1IoNz1N.mjs} +6 -6
- package/package.json +6 -6
- /package/dist/codex/{happyMcpStdioBridge.cjs → zenfloMcpStdioBridge.cjs} +0 -0
- /package/dist/codex/{happyMcpStdioBridge.d.cts → zenfloMcpStdioBridge.d.cts} +0 -0
- /package/dist/codex/{happyMcpStdioBridge.d.mts → zenfloMcpStdioBridge.d.mts} +0 -0
- /package/dist/codex/{happyMcpStdioBridge.mjs → zenfloMcpStdioBridge.mjs} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ZenFlo
|
|
2
2
|
|
|
3
3
|
Code on the go controlling claude code from your mobile device.
|
|
4
4
|
|
|
@@ -7,13 +7,13 @@ Free. Open source. Code anywhere.
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g
|
|
10
|
+
npm install -g zenflo
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
zenflo
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
This will:
|
|
@@ -23,12 +23,12 @@ This will:
|
|
|
23
23
|
|
|
24
24
|
## Commands
|
|
25
25
|
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
28
|
-
- `
|
|
29
|
-
- `
|
|
30
|
-
- `
|
|
31
|
-
- `
|
|
26
|
+
- `zenflo auth` – Manage authentication
|
|
27
|
+
- `zenflo codex` – Start Codex mode
|
|
28
|
+
- `zenflo connect` – Store AI vendor API keys in ZenFlo cloud
|
|
29
|
+
- `zenflo notify` – Send a push notification to your devices
|
|
30
|
+
- `zenflo daemon` – Manage background service
|
|
31
|
+
- `zenflo doctor` – System diagnostics & troubleshooting
|
|
32
32
|
|
|
33
33
|
## Options
|
|
34
34
|
|
|
@@ -41,9 +41,9 @@ This will:
|
|
|
41
41
|
|
|
42
42
|
## Environment Variables
|
|
43
43
|
|
|
44
|
-
- `HAPPY_SERVER_URL` - Custom server URL (default: https://
|
|
45
|
-
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://app.
|
|
46
|
-
- `HAPPY_HOME_DIR` - Custom home directory for
|
|
44
|
+
- `HAPPY_SERVER_URL` - Custom server URL (default: https://zenflo.combinedmemory.com)
|
|
45
|
+
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://app.combinedmemory.com)
|
|
46
|
+
- `HAPPY_HOME_DIR` - Custom home directory for ZenFlo data (default: ~/.happy)
|
|
47
47
|
- `HAPPY_DISABLE_CAFFEINATE` - Disable macOS sleep prevention (set to `true`, `1`, or `yes`)
|
|
48
48
|
- `HAPPY_EXPERIMENTAL` - Enable experimental features (set to `true`, `1`, or `yes`)
|
|
49
49
|
|
|
@@ -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, d as backoff, e as delay, R as RawJSONLinesSchema, f as AsyncLock, c as configuration, g as readDaemonState, h as clearDaemonState, b as packageJson, r 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-
|
|
4
|
+
import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, f as AsyncLock, c as configuration, g as readDaemonState, h as clearDaemonState, b as packageJson, r 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-D1IoNz1N.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';
|
|
@@ -3464,7 +3464,7 @@ async function findAllHappyProcesses() {
|
|
|
3464
3464
|
for (const proc of processes) {
|
|
3465
3465
|
const cmd = proc.cmd || "";
|
|
3466
3466
|
const name = proc.name || "";
|
|
3467
|
-
const isHappy = name.includes("happy") || name === "node" && (cmd.includes("happy-cli") || cmd.includes("dist/index.mjs")) || cmd.includes("happy.mjs") || cmd.includes("
|
|
3467
|
+
const isHappy = name.includes("happy") || name === "node" && (cmd.includes("happy-cli") || cmd.includes("dist/index.mjs")) || cmd.includes("happy.mjs") || cmd.includes("zenflo") || cmd.includes("tsx") && cmd.includes("src/index.ts") && cmd.includes("happy-cli");
|
|
3468
3468
|
if (!isHappy) continue;
|
|
3469
3469
|
let type = "unknown";
|
|
3470
3470
|
if (proc.pid === process.pid) {
|
|
@@ -3569,10 +3569,10 @@ async function runDoctorCommand(filter) {
|
|
|
3569
3569
|
if (!filter) {
|
|
3570
3570
|
filter = "all";
|
|
3571
3571
|
}
|
|
3572
|
-
console.log(chalk.bold.cyan("\n\u{1FA7A}
|
|
3572
|
+
console.log(chalk.bold.cyan("\n\u{1FA7A} ZenFlo CLI Doctor\n"));
|
|
3573
3573
|
if (filter === "all") {
|
|
3574
3574
|
console.log(chalk.bold("\u{1F4CB} Basic Information"));
|
|
3575
|
-
console.log(`
|
|
3575
|
+
console.log(`ZenFlo CLI Version: ${chalk.green(packageJson.version)}`);
|
|
3576
3576
|
console.log(`Platform: ${chalk.green(process.platform)} ${process.arch}`);
|
|
3577
3577
|
console.log(`Node.js Version: ${chalk.green(process.version)}`);
|
|
3578
3578
|
console.log("");
|
|
@@ -3641,7 +3641,7 @@ async function runDoctorCommand(filter) {
|
|
|
3641
3641
|
}
|
|
3642
3642
|
const allProcesses = await findAllHappyProcesses();
|
|
3643
3643
|
if (allProcesses.length > 0) {
|
|
3644
|
-
console.log(chalk.bold("\n\u{1F50D} All
|
|
3644
|
+
console.log(chalk.bold("\n\u{1F50D} All ZenFlo CLI Processes"));
|
|
3645
3645
|
const grouped = allProcesses.reduce((groups, process2) => {
|
|
3646
3646
|
if (!groups[process2.type]) groups[process2.type] = [];
|
|
3647
3647
|
groups[process2.type].push(process2);
|
|
@@ -3980,7 +3980,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
3980
3980
|
return { credentials, machineId: settings.machineId };
|
|
3981
3981
|
}
|
|
3982
3982
|
|
|
3983
|
-
function
|
|
3983
|
+
function spawnZenfloCLI(args, options = {}) {
|
|
3984
3984
|
const projectRoot = projectPath();
|
|
3985
3985
|
const entrypoint = join(projectRoot, "dist", "index.mjs");
|
|
3986
3986
|
let directory;
|
|
@@ -3989,8 +3989,8 @@ function spawnHappyCLI(args, options = {}) {
|
|
|
3989
3989
|
} else {
|
|
3990
3990
|
directory = process.cwd();
|
|
3991
3991
|
}
|
|
3992
|
-
const fullCommand = `
|
|
3993
|
-
logger.debug(`[SPAWN
|
|
3992
|
+
const fullCommand = `zenflo ${args.join(" ")}`;
|
|
3993
|
+
logger.debug(`[SPAWN ZENFLO CLI] Spawning: ${fullCommand} in ${directory}`);
|
|
3994
3994
|
const nodeArgs = [
|
|
3995
3995
|
"--no-warnings",
|
|
3996
3996
|
"--no-deprecation",
|
|
@@ -3999,7 +3999,7 @@ function spawnHappyCLI(args, options = {}) {
|
|
|
3999
3999
|
];
|
|
4000
4000
|
if (!existsSync(entrypoint)) {
|
|
4001
4001
|
const errorMessage = `Entrypoint ${entrypoint} does not exist`;
|
|
4002
|
-
logger.debug(`[SPAWN
|
|
4002
|
+
logger.debug(`[SPAWN ZENFLO CLI] ${errorMessage}`);
|
|
4003
4003
|
throw new Error(errorMessage);
|
|
4004
4004
|
}
|
|
4005
4005
|
return spawn$1("node", nodeArgs, options);
|
|
@@ -4045,7 +4045,7 @@ function startDaemonControlServer({
|
|
|
4045
4045
|
200: z.object({
|
|
4046
4046
|
children: z.array(z.object({
|
|
4047
4047
|
startedBy: z.string(),
|
|
4048
|
-
|
|
4048
|
+
zenfloSessionId: z.string(),
|
|
4049
4049
|
pid: z.number()
|
|
4050
4050
|
}))
|
|
4051
4051
|
})
|
|
@@ -4055,9 +4055,9 @@ function startDaemonControlServer({
|
|
|
4055
4055
|
const children = getChildren();
|
|
4056
4056
|
logger.debug(`[CONTROL SERVER] Listing ${children.length} sessions`);
|
|
4057
4057
|
return {
|
|
4058
|
-
children: children.filter((child) => child.
|
|
4058
|
+
children: children.filter((child) => child.zenfloSessionId !== void 0).map((child) => ({
|
|
4059
4059
|
startedBy: child.startedBy,
|
|
4060
|
-
|
|
4060
|
+
zenfloSessionId: child.zenfloSessionId,
|
|
4061
4061
|
pid: child.pid
|
|
4062
4062
|
}))
|
|
4063
4063
|
};
|
|
@@ -4256,8 +4256,8 @@ async function startDaemon() {
|
|
|
4256
4256
|
logger.debug(`[DAEMON RUN] Current tracked sessions before webhook: ${Array.from(pidToTrackedSession.keys()).join(", ")}`);
|
|
4257
4257
|
const existingSession = pidToTrackedSession.get(pid);
|
|
4258
4258
|
if (existingSession && existingSession.startedBy === "daemon") {
|
|
4259
|
-
existingSession.
|
|
4260
|
-
existingSession.
|
|
4259
|
+
existingSession.zenfloSessionId = sessionId;
|
|
4260
|
+
existingSession.zenfloSessionMetadataFromLocalWebhook = sessionMetadata;
|
|
4261
4261
|
logger.debug(`[DAEMON RUN] Updated daemon-spawned session ${sessionId} with metadata`);
|
|
4262
4262
|
const awaiter = pidToAwaiter.get(pid);
|
|
4263
4263
|
if (awaiter) {
|
|
@@ -4268,8 +4268,8 @@ async function startDaemon() {
|
|
|
4268
4268
|
} else if (!existingSession) {
|
|
4269
4269
|
const trackedSession = {
|
|
4270
4270
|
startedBy: "happy directly - likely by user from terminal",
|
|
4271
|
-
|
|
4272
|
-
|
|
4271
|
+
zenfloSessionId: sessionId,
|
|
4272
|
+
zenfloSessionMetadataFromLocalWebhook: sessionMetadata,
|
|
4273
4273
|
pid
|
|
4274
4274
|
};
|
|
4275
4275
|
pidToTrackedSession.set(pid, trackedSession);
|
|
@@ -4338,7 +4338,7 @@ async function startDaemon() {
|
|
|
4338
4338
|
"--started-by",
|
|
4339
4339
|
"daemon"
|
|
4340
4340
|
];
|
|
4341
|
-
const
|
|
4341
|
+
const zenfloProcess = spawnZenfloCLI(args, {
|
|
4342
4342
|
cwd: directory,
|
|
4343
4343
|
detached: true,
|
|
4344
4344
|
// Sessions stay alive when daemon stops
|
|
@@ -4350,57 +4350,57 @@ async function startDaemon() {
|
|
|
4350
4350
|
}
|
|
4351
4351
|
});
|
|
4352
4352
|
if (process.env.DEBUG) {
|
|
4353
|
-
|
|
4353
|
+
zenfloProcess.stdout?.on("data", (data) => {
|
|
4354
4354
|
logger.debug(`[DAEMON RUN] Child stdout: ${data.toString()}`);
|
|
4355
4355
|
});
|
|
4356
|
-
|
|
4356
|
+
zenfloProcess.stderr?.on("data", (data) => {
|
|
4357
4357
|
logger.debug(`[DAEMON RUN] Child stderr: ${data.toString()}`);
|
|
4358
4358
|
});
|
|
4359
4359
|
}
|
|
4360
|
-
if (!
|
|
4360
|
+
if (!zenfloProcess.pid) {
|
|
4361
4361
|
logger.debug("[DAEMON RUN] Failed to spawn process - no PID returned");
|
|
4362
4362
|
return {
|
|
4363
4363
|
type: "error",
|
|
4364
|
-
errorMessage: "Failed to spawn
|
|
4364
|
+
errorMessage: "Failed to spawn ZenFlo process - no PID returned"
|
|
4365
4365
|
};
|
|
4366
4366
|
}
|
|
4367
|
-
logger.debug(`[DAEMON RUN] Spawned process with PID ${
|
|
4367
|
+
logger.debug(`[DAEMON RUN] Spawned process with PID ${zenfloProcess.pid}`);
|
|
4368
4368
|
const trackedSession = {
|
|
4369
4369
|
startedBy: "daemon",
|
|
4370
|
-
pid:
|
|
4371
|
-
childProcess:
|
|
4370
|
+
pid: zenfloProcess.pid,
|
|
4371
|
+
childProcess: zenfloProcess,
|
|
4372
4372
|
directoryCreated,
|
|
4373
4373
|
message: directoryCreated ? `The path '${directory}' did not exist. We created a new folder and spawned a new session there.` : void 0
|
|
4374
4374
|
};
|
|
4375
|
-
pidToTrackedSession.set(
|
|
4376
|
-
|
|
4377
|
-
logger.debug(`[DAEMON RUN] Child PID ${
|
|
4378
|
-
if (
|
|
4379
|
-
onChildExited(
|
|
4375
|
+
pidToTrackedSession.set(zenfloProcess.pid, trackedSession);
|
|
4376
|
+
zenfloProcess.on("exit", (code, signal) => {
|
|
4377
|
+
logger.debug(`[DAEMON RUN] Child PID ${zenfloProcess.pid} exited with code ${code}, signal ${signal}`);
|
|
4378
|
+
if (zenfloProcess.pid) {
|
|
4379
|
+
onChildExited(zenfloProcess.pid);
|
|
4380
4380
|
}
|
|
4381
4381
|
});
|
|
4382
|
-
|
|
4382
|
+
zenfloProcess.on("error", (error) => {
|
|
4383
4383
|
logger.debug(`[DAEMON RUN] Child process error:`, error);
|
|
4384
|
-
if (
|
|
4385
|
-
onChildExited(
|
|
4384
|
+
if (zenfloProcess.pid) {
|
|
4385
|
+
onChildExited(zenfloProcess.pid);
|
|
4386
4386
|
}
|
|
4387
4387
|
});
|
|
4388
|
-
logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${
|
|
4388
|
+
logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${zenfloProcess.pid}`);
|
|
4389
4389
|
return new Promise((resolve) => {
|
|
4390
4390
|
const timeout = setTimeout(() => {
|
|
4391
|
-
pidToAwaiter.delete(
|
|
4392
|
-
logger.debug(`[DAEMON RUN] Session webhook timeout for PID ${
|
|
4391
|
+
pidToAwaiter.delete(zenfloProcess.pid);
|
|
4392
|
+
logger.debug(`[DAEMON RUN] Session webhook timeout for PID ${zenfloProcess.pid}`);
|
|
4393
4393
|
resolve({
|
|
4394
4394
|
type: "error",
|
|
4395
|
-
errorMessage: `Session webhook timeout for PID ${
|
|
4395
|
+
errorMessage: `Session webhook timeout for PID ${zenfloProcess.pid}`
|
|
4396
4396
|
});
|
|
4397
4397
|
}, 15e3);
|
|
4398
|
-
pidToAwaiter.set(
|
|
4398
|
+
pidToAwaiter.set(zenfloProcess.pid, (completedSession) => {
|
|
4399
4399
|
clearTimeout(timeout);
|
|
4400
|
-
logger.debug(`[DAEMON RUN] Session ${completedSession.
|
|
4400
|
+
logger.debug(`[DAEMON RUN] Session ${completedSession.zenfloSessionId} fully spawned with webhook`);
|
|
4401
4401
|
resolve({
|
|
4402
4402
|
type: "success",
|
|
4403
|
-
sessionId: completedSession.
|
|
4403
|
+
sessionId: completedSession.zenfloSessionId
|
|
4404
4404
|
});
|
|
4405
4405
|
});
|
|
4406
4406
|
});
|
|
@@ -4416,7 +4416,7 @@ async function startDaemon() {
|
|
|
4416
4416
|
const stopSession = (sessionId) => {
|
|
4417
4417
|
logger.debug(`[DAEMON RUN] Attempting to stop session ${sessionId}`);
|
|
4418
4418
|
for (const [pid, session] of pidToTrackedSession.entries()) {
|
|
4419
|
-
if (session.
|
|
4419
|
+
if (session.zenfloSessionId === sessionId || sessionId.startsWith("PID-") && pid === parseInt(sessionId.replace("PID-", ""))) {
|
|
4420
4420
|
if (session.startedBy === "daemon" && session.childProcess) {
|
|
4421
4421
|
try {
|
|
4422
4422
|
session.childProcess.kill("SIGTERM");
|
|
@@ -4503,7 +4503,7 @@ async function startDaemon() {
|
|
|
4503
4503
|
logger.debug("[DAEMON RUN] Daemon is outdated, triggering self-restart with latest version, clearing heartbeat interval");
|
|
4504
4504
|
clearInterval(restartOnStaleVersionAndHeartbeat);
|
|
4505
4505
|
try {
|
|
4506
|
-
|
|
4506
|
+
spawnZenfloCLI(["daemon", "start"], {
|
|
4507
4507
|
detached: true,
|
|
4508
4508
|
stdio: "ignore"
|
|
4509
4509
|
});
|
|
@@ -4567,9 +4567,9 @@ async function startDaemon() {
|
|
|
4567
4567
|
}
|
|
4568
4568
|
}
|
|
4569
4569
|
|
|
4570
|
-
async function
|
|
4570
|
+
async function startZenfloServer(client, apiClient) {
|
|
4571
4571
|
const handler = async (title) => {
|
|
4572
|
-
logger.debug("[
|
|
4572
|
+
logger.debug("[zenfloMCP] Changing title to:", title);
|
|
4573
4573
|
try {
|
|
4574
4574
|
client.sendClaudeSessionMessage({
|
|
4575
4575
|
type: "summary",
|
|
@@ -4594,7 +4594,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4594
4594
|
}
|
|
4595
4595
|
}, async (args) => {
|
|
4596
4596
|
const response = await handler(args.title);
|
|
4597
|
-
logger.debug("[
|
|
4597
|
+
logger.debug("[zenfloMCP] Response:", response);
|
|
4598
4598
|
if (response.success) {
|
|
4599
4599
|
return {
|
|
4600
4600
|
content: [
|
|
@@ -4627,7 +4627,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4627
4627
|
priority: z.enum(["low", "normal", "high"]).optional().describe("Message priority (affects icon and color)")
|
|
4628
4628
|
}
|
|
4629
4629
|
}, async (args) => {
|
|
4630
|
-
logger.debug("[
|
|
4630
|
+
logger.debug("[zenfloMCP] Sending inbox message:", args.title);
|
|
4631
4631
|
try {
|
|
4632
4632
|
await apiClient.sendInboxMessage({
|
|
4633
4633
|
title: args.title,
|
|
@@ -4645,7 +4645,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4645
4645
|
isError: false
|
|
4646
4646
|
};
|
|
4647
4647
|
} catch (error) {
|
|
4648
|
-
logger.debug("[
|
|
4648
|
+
logger.debug("[zenfloMCP] Error sending inbox message:", error);
|
|
4649
4649
|
return {
|
|
4650
4650
|
content: [
|
|
4651
4651
|
{
|
|
@@ -4683,7 +4683,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4683
4683
|
url: baseUrl.toString(),
|
|
4684
4684
|
toolNames: ["change_title", "send_inbox_message"],
|
|
4685
4685
|
stop: () => {
|
|
4686
|
-
logger.debug("[
|
|
4686
|
+
logger.debug("[zenfloMCP] Stopping server");
|
|
4687
4687
|
mcp.close();
|
|
4688
4688
|
server.close();
|
|
4689
4689
|
}
|
|
@@ -4704,7 +4704,7 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
|
|
|
4704
4704
|
async function runClaude(credentials, options = {}) {
|
|
4705
4705
|
const workingDirectory = process.cwd();
|
|
4706
4706
|
const sessionTag = randomUUID();
|
|
4707
|
-
logger.debugLargeJson("[START]
|
|
4707
|
+
logger.debugLargeJson("[START] ZenFlo process started", getEnvironmentInfo());
|
|
4708
4708
|
logger.debug(`[START] Options: startedBy=${options.startedBy}, startingMode=${options.startingMode}`);
|
|
4709
4709
|
if (options.startedBy === "daemon" && options.startingMode === "local") {
|
|
4710
4710
|
logger.debug("Daemon spawn requested with local mode - forcing remote mode");
|
|
@@ -4768,8 +4768,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4768
4768
|
}
|
|
4769
4769
|
});
|
|
4770
4770
|
const session = api.sessionSyncClient(response);
|
|
4771
|
-
const
|
|
4772
|
-
logger.debug(`[START]
|
|
4771
|
+
const zenfloServer = await startZenfloServer(session, api);
|
|
4772
|
+
logger.debug(`[START] ZenFlo MCP server started at ${zenfloServer.url}`);
|
|
4773
4773
|
const logPath = logger.logFilePath;
|
|
4774
4774
|
logger.infoDeveloper(`Session: ${response.id}`);
|
|
4775
4775
|
logger.infoDeveloper(`Logs: ${logPath}`);
|
|
@@ -4918,7 +4918,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4918
4918
|
await session.close();
|
|
4919
4919
|
}
|
|
4920
4920
|
stopCaffeinate();
|
|
4921
|
-
|
|
4921
|
+
zenfloServer.stop();
|
|
4922
4922
|
logger.debug("[START] Cleanup complete, exiting");
|
|
4923
4923
|
process.exit(0);
|
|
4924
4924
|
} catch (error) {
|
|
@@ -4944,7 +4944,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4944
4944
|
startingMode: options.startingMode,
|
|
4945
4945
|
messageQueue,
|
|
4946
4946
|
api,
|
|
4947
|
-
allowedTools:
|
|
4947
|
+
allowedTools: zenfloServer.toolNames.map((toolName) => `mcp__zenflo__${toolName}`),
|
|
4948
4948
|
onModeChange: (newMode) => {
|
|
4949
4949
|
session.sendSessionEvent({ type: "switch", mode: newMode });
|
|
4950
4950
|
session.updateAgentState((currentState) => ({
|
|
@@ -4955,9 +4955,9 @@ async function runClaude(credentials, options = {}) {
|
|
|
4955
4955
|
onSessionReady: (_sessionInstance) => {
|
|
4956
4956
|
},
|
|
4957
4957
|
mcpServers: {
|
|
4958
|
-
"
|
|
4958
|
+
"zenflo": {
|
|
4959
4959
|
type: "http",
|
|
4960
|
-
url:
|
|
4960
|
+
url: zenfloServer.url
|
|
4961
4961
|
}
|
|
4962
4962
|
},
|
|
4963
4963
|
session,
|
|
@@ -4971,8 +4971,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4971
4971
|
await session.close();
|
|
4972
4972
|
stopCaffeinate();
|
|
4973
4973
|
logger.debug("Stopped sleep prevention");
|
|
4974
|
-
|
|
4975
|
-
logger.debug("Stopped
|
|
4974
|
+
zenfloServer.stop();
|
|
4975
|
+
logger.debug("Stopped ZenFlo MCP server");
|
|
4976
4976
|
process.exit(0);
|
|
4977
4977
|
}
|
|
4978
4978
|
|
|
@@ -5043,7 +5043,7 @@ async function install() {
|
|
|
5043
5043
|
if (process.getuid && process.getuid() !== 0) {
|
|
5044
5044
|
throw new Error("Daemon installation requires sudo privileges. Please run with sudo.");
|
|
5045
5045
|
}
|
|
5046
|
-
logger.info("Installing
|
|
5046
|
+
logger.info("Installing ZenFlo CLI daemon for macOS...");
|
|
5047
5047
|
await install$1();
|
|
5048
5048
|
}
|
|
5049
5049
|
|
|
@@ -5077,7 +5077,7 @@ async function uninstall() {
|
|
|
5077
5077
|
if (process.getuid && process.getuid() !== 0) {
|
|
5078
5078
|
throw new Error("Daemon uninstallation requires sudo privileges. Please run with sudo.");
|
|
5079
5079
|
}
|
|
5080
|
-
logger.info("Uninstalling
|
|
5080
|
+
logger.info("Uninstalling ZenFlo CLI daemon for macOS...");
|
|
5081
5081
|
await uninstall$1();
|
|
5082
5082
|
}
|
|
5083
5083
|
|
|
@@ -5796,7 +5796,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5796
5796
|
(async () => {
|
|
5797
5797
|
const args = process.argv.slice(2);
|
|
5798
5798
|
if (!args.includes("--version")) {
|
|
5799
|
-
logger.debug("Starting
|
|
5799
|
+
logger.debug("Starting ZenFlo CLI with args: ", process.argv);
|
|
5800
5800
|
}
|
|
5801
5801
|
const subcommand = args[0];
|
|
5802
5802
|
if (subcommand === "doctor") {
|
|
@@ -5834,7 +5834,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5834
5834
|
return;
|
|
5835
5835
|
} else if (subcommand === "codex") {
|
|
5836
5836
|
try {
|
|
5837
|
-
const { runCodex } = await import('./runCodex-
|
|
5837
|
+
const { runCodex } = await import('./runCodex-DAY1lCxR.mjs');
|
|
5838
5838
|
let startedBy = void 0;
|
|
5839
5839
|
for (let i = 1; i < args.length; i++) {
|
|
5840
5840
|
if (args[i] === "--started-by") {
|
|
@@ -5905,7 +5905,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5905
5905
|
}
|
|
5906
5906
|
return;
|
|
5907
5907
|
} else if (daemonSubcommand === "start") {
|
|
5908
|
-
const child =
|
|
5908
|
+
const child = spawnZenfloCLI(["daemon", "start-sync"], {
|
|
5909
5909
|
detached: true,
|
|
5910
5910
|
stdio: "ignore",
|
|
5911
5911
|
env: process.env
|
|
@@ -6051,10 +6051,10 @@ ${chalk.bold.cyan("Claude Code Options (from `claude --help`):")}
|
|
|
6051
6051
|
const {
|
|
6052
6052
|
credentials
|
|
6053
6053
|
} = await authAndSetupMachineIfNeeded();
|
|
6054
|
-
logger.debug("Ensuring
|
|
6054
|
+
logger.debug("Ensuring ZenFlo background service is running & matches our version...");
|
|
6055
6055
|
if (!await isDaemonRunningCurrentlyInstalledHappyVersion()) {
|
|
6056
|
-
logger.debug("Starting
|
|
6057
|
-
const daemonProcess =
|
|
6056
|
+
logger.debug("Starting ZenFlo background service...");
|
|
6057
|
+
const daemonProcess = spawnZenfloCLI(["daemon", "start-sync"], {
|
|
6058
6058
|
detached: true,
|
|
6059
6059
|
stdio: "ignore",
|
|
6060
6060
|
env: process.env
|
|
@@ -6142,4 +6142,4 @@ ${chalk.bold("Examples:")}
|
|
|
6142
6142
|
}
|
|
6143
6143
|
}
|
|
6144
6144
|
|
|
6145
|
-
export { MessageQueue2 as M, MessageBuffer as a, stopCaffeinate as b, hashObject as h, initialMachineMetadata as i, notifyDaemonSessionStarted as n, registerKillSessionHandler as r,
|
|
6145
|
+
export { MessageQueue2 as M, MessageBuffer as a, stopCaffeinate as b, hashObject as h, initialMachineMetadata as i, notifyDaemonSessionStarted as n, registerKillSessionHandler as r, startZenfloServer as s, trimIdent as t };
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var types = require('./types-
|
|
6
|
+
var types = require('./types-B4VPN3pY.cjs');
|
|
7
7
|
var node_child_process = require('node:child_process');
|
|
8
8
|
var node_path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -981,7 +981,7 @@ class AbortError extends Error {
|
|
|
981
981
|
}
|
|
982
982
|
}
|
|
983
983
|
|
|
984
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
984
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-FBQqV3tt.cjs', document.baseURI).href)));
|
|
985
985
|
const __dirname$1 = node_path.join(__filename$1, "..");
|
|
986
986
|
function getDefaultClaudeCodePath() {
|
|
987
987
|
return node_path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
@@ -3486,7 +3486,7 @@ async function findAllHappyProcesses() {
|
|
|
3486
3486
|
for (const proc of processes) {
|
|
3487
3487
|
const cmd = proc.cmd || "";
|
|
3488
3488
|
const name = proc.name || "";
|
|
3489
|
-
const isHappy = name.includes("happy") || name === "node" && (cmd.includes("happy-cli") || cmd.includes("dist/index.mjs")) || cmd.includes("happy.mjs") || cmd.includes("
|
|
3489
|
+
const isHappy = name.includes("happy") || name === "node" && (cmd.includes("happy-cli") || cmd.includes("dist/index.mjs")) || cmd.includes("happy.mjs") || cmd.includes("zenflo") || cmd.includes("tsx") && cmd.includes("src/index.ts") && cmd.includes("happy-cli");
|
|
3490
3490
|
if (!isHappy) continue;
|
|
3491
3491
|
let type = "unknown";
|
|
3492
3492
|
if (proc.pid === process.pid) {
|
|
@@ -3591,10 +3591,10 @@ async function runDoctorCommand(filter) {
|
|
|
3591
3591
|
if (!filter) {
|
|
3592
3592
|
filter = "all";
|
|
3593
3593
|
}
|
|
3594
|
-
console.log(chalk.bold.cyan("\n\u{1FA7A}
|
|
3594
|
+
console.log(chalk.bold.cyan("\n\u{1FA7A} ZenFlo CLI Doctor\n"));
|
|
3595
3595
|
if (filter === "all") {
|
|
3596
3596
|
console.log(chalk.bold("\u{1F4CB} Basic Information"));
|
|
3597
|
-
console.log(`
|
|
3597
|
+
console.log(`ZenFlo CLI Version: ${chalk.green(types.packageJson.version)}`);
|
|
3598
3598
|
console.log(`Platform: ${chalk.green(process.platform)} ${process.arch}`);
|
|
3599
3599
|
console.log(`Node.js Version: ${chalk.green(process.version)}`);
|
|
3600
3600
|
console.log("");
|
|
@@ -3663,7 +3663,7 @@ async function runDoctorCommand(filter) {
|
|
|
3663
3663
|
}
|
|
3664
3664
|
const allProcesses = await findAllHappyProcesses();
|
|
3665
3665
|
if (allProcesses.length > 0) {
|
|
3666
|
-
console.log(chalk.bold("\n\u{1F50D} All
|
|
3666
|
+
console.log(chalk.bold("\n\u{1F50D} All ZenFlo CLI Processes"));
|
|
3667
3667
|
const grouped = allProcesses.reduce((groups, process2) => {
|
|
3668
3668
|
if (!groups[process2.type]) groups[process2.type] = [];
|
|
3669
3669
|
groups[process2.type].push(process2);
|
|
@@ -4002,7 +4002,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
4002
4002
|
return { credentials, machineId: settings.machineId };
|
|
4003
4003
|
}
|
|
4004
4004
|
|
|
4005
|
-
function
|
|
4005
|
+
function spawnZenfloCLI(args, options = {}) {
|
|
4006
4006
|
const projectRoot = types.projectPath();
|
|
4007
4007
|
const entrypoint = node_path.join(projectRoot, "dist", "index.mjs");
|
|
4008
4008
|
let directory;
|
|
@@ -4011,8 +4011,8 @@ function spawnHappyCLI(args, options = {}) {
|
|
|
4011
4011
|
} else {
|
|
4012
4012
|
directory = process.cwd();
|
|
4013
4013
|
}
|
|
4014
|
-
const fullCommand = `
|
|
4015
|
-
types.logger.debug(`[SPAWN
|
|
4014
|
+
const fullCommand = `zenflo ${args.join(" ")}`;
|
|
4015
|
+
types.logger.debug(`[SPAWN ZENFLO CLI] Spawning: ${fullCommand} in ${directory}`);
|
|
4016
4016
|
const nodeArgs = [
|
|
4017
4017
|
"--no-warnings",
|
|
4018
4018
|
"--no-deprecation",
|
|
@@ -4021,7 +4021,7 @@ function spawnHappyCLI(args, options = {}) {
|
|
|
4021
4021
|
];
|
|
4022
4022
|
if (!fs.existsSync(entrypoint)) {
|
|
4023
4023
|
const errorMessage = `Entrypoint ${entrypoint} does not exist`;
|
|
4024
|
-
types.logger.debug(`[SPAWN
|
|
4024
|
+
types.logger.debug(`[SPAWN ZENFLO CLI] ${errorMessage}`);
|
|
4025
4025
|
throw new Error(errorMessage);
|
|
4026
4026
|
}
|
|
4027
4027
|
return child_process.spawn("node", nodeArgs, options);
|
|
@@ -4067,7 +4067,7 @@ function startDaemonControlServer({
|
|
|
4067
4067
|
200: z.z.object({
|
|
4068
4068
|
children: z.z.array(z.z.object({
|
|
4069
4069
|
startedBy: z.z.string(),
|
|
4070
|
-
|
|
4070
|
+
zenfloSessionId: z.z.string(),
|
|
4071
4071
|
pid: z.z.number()
|
|
4072
4072
|
}))
|
|
4073
4073
|
})
|
|
@@ -4077,9 +4077,9 @@ function startDaemonControlServer({
|
|
|
4077
4077
|
const children = getChildren();
|
|
4078
4078
|
types.logger.debug(`[CONTROL SERVER] Listing ${children.length} sessions`);
|
|
4079
4079
|
return {
|
|
4080
|
-
children: children.filter((child) => child.
|
|
4080
|
+
children: children.filter((child) => child.zenfloSessionId !== void 0).map((child) => ({
|
|
4081
4081
|
startedBy: child.startedBy,
|
|
4082
|
-
|
|
4082
|
+
zenfloSessionId: child.zenfloSessionId,
|
|
4083
4083
|
pid: child.pid
|
|
4084
4084
|
}))
|
|
4085
4085
|
};
|
|
@@ -4278,8 +4278,8 @@ async function startDaemon() {
|
|
|
4278
4278
|
types.logger.debug(`[DAEMON RUN] Current tracked sessions before webhook: ${Array.from(pidToTrackedSession.keys()).join(", ")}`);
|
|
4279
4279
|
const existingSession = pidToTrackedSession.get(pid);
|
|
4280
4280
|
if (existingSession && existingSession.startedBy === "daemon") {
|
|
4281
|
-
existingSession.
|
|
4282
|
-
existingSession.
|
|
4281
|
+
existingSession.zenfloSessionId = sessionId;
|
|
4282
|
+
existingSession.zenfloSessionMetadataFromLocalWebhook = sessionMetadata;
|
|
4283
4283
|
types.logger.debug(`[DAEMON RUN] Updated daemon-spawned session ${sessionId} with metadata`);
|
|
4284
4284
|
const awaiter = pidToAwaiter.get(pid);
|
|
4285
4285
|
if (awaiter) {
|
|
@@ -4290,8 +4290,8 @@ async function startDaemon() {
|
|
|
4290
4290
|
} else if (!existingSession) {
|
|
4291
4291
|
const trackedSession = {
|
|
4292
4292
|
startedBy: "happy directly - likely by user from terminal",
|
|
4293
|
-
|
|
4294
|
-
|
|
4293
|
+
zenfloSessionId: sessionId,
|
|
4294
|
+
zenfloSessionMetadataFromLocalWebhook: sessionMetadata,
|
|
4295
4295
|
pid
|
|
4296
4296
|
};
|
|
4297
4297
|
pidToTrackedSession.set(pid, trackedSession);
|
|
@@ -4360,7 +4360,7 @@ async function startDaemon() {
|
|
|
4360
4360
|
"--started-by",
|
|
4361
4361
|
"daemon"
|
|
4362
4362
|
];
|
|
4363
|
-
const
|
|
4363
|
+
const zenfloProcess = spawnZenfloCLI(args, {
|
|
4364
4364
|
cwd: directory,
|
|
4365
4365
|
detached: true,
|
|
4366
4366
|
// Sessions stay alive when daemon stops
|
|
@@ -4372,57 +4372,57 @@ async function startDaemon() {
|
|
|
4372
4372
|
}
|
|
4373
4373
|
});
|
|
4374
4374
|
if (process.env.DEBUG) {
|
|
4375
|
-
|
|
4375
|
+
zenfloProcess.stdout?.on("data", (data) => {
|
|
4376
4376
|
types.logger.debug(`[DAEMON RUN] Child stdout: ${data.toString()}`);
|
|
4377
4377
|
});
|
|
4378
|
-
|
|
4378
|
+
zenfloProcess.stderr?.on("data", (data) => {
|
|
4379
4379
|
types.logger.debug(`[DAEMON RUN] Child stderr: ${data.toString()}`);
|
|
4380
4380
|
});
|
|
4381
4381
|
}
|
|
4382
|
-
if (!
|
|
4382
|
+
if (!zenfloProcess.pid) {
|
|
4383
4383
|
types.logger.debug("[DAEMON RUN] Failed to spawn process - no PID returned");
|
|
4384
4384
|
return {
|
|
4385
4385
|
type: "error",
|
|
4386
|
-
errorMessage: "Failed to spawn
|
|
4386
|
+
errorMessage: "Failed to spawn ZenFlo process - no PID returned"
|
|
4387
4387
|
};
|
|
4388
4388
|
}
|
|
4389
|
-
types.logger.debug(`[DAEMON RUN] Spawned process with PID ${
|
|
4389
|
+
types.logger.debug(`[DAEMON RUN] Spawned process with PID ${zenfloProcess.pid}`);
|
|
4390
4390
|
const trackedSession = {
|
|
4391
4391
|
startedBy: "daemon",
|
|
4392
|
-
pid:
|
|
4393
|
-
childProcess:
|
|
4392
|
+
pid: zenfloProcess.pid,
|
|
4393
|
+
childProcess: zenfloProcess,
|
|
4394
4394
|
directoryCreated,
|
|
4395
4395
|
message: directoryCreated ? `The path '${directory}' did not exist. We created a new folder and spawned a new session there.` : void 0
|
|
4396
4396
|
};
|
|
4397
|
-
pidToTrackedSession.set(
|
|
4398
|
-
|
|
4399
|
-
types.logger.debug(`[DAEMON RUN] Child PID ${
|
|
4400
|
-
if (
|
|
4401
|
-
onChildExited(
|
|
4397
|
+
pidToTrackedSession.set(zenfloProcess.pid, trackedSession);
|
|
4398
|
+
zenfloProcess.on("exit", (code, signal) => {
|
|
4399
|
+
types.logger.debug(`[DAEMON RUN] Child PID ${zenfloProcess.pid} exited with code ${code}, signal ${signal}`);
|
|
4400
|
+
if (zenfloProcess.pid) {
|
|
4401
|
+
onChildExited(zenfloProcess.pid);
|
|
4402
4402
|
}
|
|
4403
4403
|
});
|
|
4404
|
-
|
|
4404
|
+
zenfloProcess.on("error", (error) => {
|
|
4405
4405
|
types.logger.debug(`[DAEMON RUN] Child process error:`, error);
|
|
4406
|
-
if (
|
|
4407
|
-
onChildExited(
|
|
4406
|
+
if (zenfloProcess.pid) {
|
|
4407
|
+
onChildExited(zenfloProcess.pid);
|
|
4408
4408
|
}
|
|
4409
4409
|
});
|
|
4410
|
-
types.logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${
|
|
4410
|
+
types.logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${zenfloProcess.pid}`);
|
|
4411
4411
|
return new Promise((resolve) => {
|
|
4412
4412
|
const timeout = setTimeout(() => {
|
|
4413
|
-
pidToAwaiter.delete(
|
|
4414
|
-
types.logger.debug(`[DAEMON RUN] Session webhook timeout for PID ${
|
|
4413
|
+
pidToAwaiter.delete(zenfloProcess.pid);
|
|
4414
|
+
types.logger.debug(`[DAEMON RUN] Session webhook timeout for PID ${zenfloProcess.pid}`);
|
|
4415
4415
|
resolve({
|
|
4416
4416
|
type: "error",
|
|
4417
|
-
errorMessage: `Session webhook timeout for PID ${
|
|
4417
|
+
errorMessage: `Session webhook timeout for PID ${zenfloProcess.pid}`
|
|
4418
4418
|
});
|
|
4419
4419
|
}, 15e3);
|
|
4420
|
-
pidToAwaiter.set(
|
|
4420
|
+
pidToAwaiter.set(zenfloProcess.pid, (completedSession) => {
|
|
4421
4421
|
clearTimeout(timeout);
|
|
4422
|
-
types.logger.debug(`[DAEMON RUN] Session ${completedSession.
|
|
4422
|
+
types.logger.debug(`[DAEMON RUN] Session ${completedSession.zenfloSessionId} fully spawned with webhook`);
|
|
4423
4423
|
resolve({
|
|
4424
4424
|
type: "success",
|
|
4425
|
-
sessionId: completedSession.
|
|
4425
|
+
sessionId: completedSession.zenfloSessionId
|
|
4426
4426
|
});
|
|
4427
4427
|
});
|
|
4428
4428
|
});
|
|
@@ -4438,7 +4438,7 @@ async function startDaemon() {
|
|
|
4438
4438
|
const stopSession = (sessionId) => {
|
|
4439
4439
|
types.logger.debug(`[DAEMON RUN] Attempting to stop session ${sessionId}`);
|
|
4440
4440
|
for (const [pid, session] of pidToTrackedSession.entries()) {
|
|
4441
|
-
if (session.
|
|
4441
|
+
if (session.zenfloSessionId === sessionId || sessionId.startsWith("PID-") && pid === parseInt(sessionId.replace("PID-", ""))) {
|
|
4442
4442
|
if (session.startedBy === "daemon" && session.childProcess) {
|
|
4443
4443
|
try {
|
|
4444
4444
|
session.childProcess.kill("SIGTERM");
|
|
@@ -4525,7 +4525,7 @@ async function startDaemon() {
|
|
|
4525
4525
|
types.logger.debug("[DAEMON RUN] Daemon is outdated, triggering self-restart with latest version, clearing heartbeat interval");
|
|
4526
4526
|
clearInterval(restartOnStaleVersionAndHeartbeat);
|
|
4527
4527
|
try {
|
|
4528
|
-
|
|
4528
|
+
spawnZenfloCLI(["daemon", "start"], {
|
|
4529
4529
|
detached: true,
|
|
4530
4530
|
stdio: "ignore"
|
|
4531
4531
|
});
|
|
@@ -4589,9 +4589,9 @@ async function startDaemon() {
|
|
|
4589
4589
|
}
|
|
4590
4590
|
}
|
|
4591
4591
|
|
|
4592
|
-
async function
|
|
4592
|
+
async function startZenfloServer(client, apiClient) {
|
|
4593
4593
|
const handler = async (title) => {
|
|
4594
|
-
types.logger.debug("[
|
|
4594
|
+
types.logger.debug("[zenfloMCP] Changing title to:", title);
|
|
4595
4595
|
try {
|
|
4596
4596
|
client.sendClaudeSessionMessage({
|
|
4597
4597
|
type: "summary",
|
|
@@ -4616,7 +4616,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4616
4616
|
}
|
|
4617
4617
|
}, async (args) => {
|
|
4618
4618
|
const response = await handler(args.title);
|
|
4619
|
-
types.logger.debug("[
|
|
4619
|
+
types.logger.debug("[zenfloMCP] Response:", response);
|
|
4620
4620
|
if (response.success) {
|
|
4621
4621
|
return {
|
|
4622
4622
|
content: [
|
|
@@ -4649,7 +4649,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4649
4649
|
priority: z.z.enum(["low", "normal", "high"]).optional().describe("Message priority (affects icon and color)")
|
|
4650
4650
|
}
|
|
4651
4651
|
}, async (args) => {
|
|
4652
|
-
types.logger.debug("[
|
|
4652
|
+
types.logger.debug("[zenfloMCP] Sending inbox message:", args.title);
|
|
4653
4653
|
try {
|
|
4654
4654
|
await apiClient.sendInboxMessage({
|
|
4655
4655
|
title: args.title,
|
|
@@ -4667,7 +4667,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4667
4667
|
isError: false
|
|
4668
4668
|
};
|
|
4669
4669
|
} catch (error) {
|
|
4670
|
-
types.logger.debug("[
|
|
4670
|
+
types.logger.debug("[zenfloMCP] Error sending inbox message:", error);
|
|
4671
4671
|
return {
|
|
4672
4672
|
content: [
|
|
4673
4673
|
{
|
|
@@ -4705,7 +4705,7 @@ async function startHappyServer(client, apiClient) {
|
|
|
4705
4705
|
url: baseUrl.toString(),
|
|
4706
4706
|
toolNames: ["change_title", "send_inbox_message"],
|
|
4707
4707
|
stop: () => {
|
|
4708
|
-
types.logger.debug("[
|
|
4708
|
+
types.logger.debug("[zenfloMCP] Stopping server");
|
|
4709
4709
|
mcp.close();
|
|
4710
4710
|
server.close();
|
|
4711
4711
|
}
|
|
@@ -4726,7 +4726,7 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
|
|
|
4726
4726
|
async function runClaude(credentials, options = {}) {
|
|
4727
4727
|
const workingDirectory = process.cwd();
|
|
4728
4728
|
const sessionTag = node_crypto.randomUUID();
|
|
4729
|
-
types.logger.debugLargeJson("[START]
|
|
4729
|
+
types.logger.debugLargeJson("[START] ZenFlo process started", getEnvironmentInfo());
|
|
4730
4730
|
types.logger.debug(`[START] Options: startedBy=${options.startedBy}, startingMode=${options.startingMode}`);
|
|
4731
4731
|
if (options.startedBy === "daemon" && options.startingMode === "local") {
|
|
4732
4732
|
types.logger.debug("Daemon spawn requested with local mode - forcing remote mode");
|
|
@@ -4790,8 +4790,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4790
4790
|
}
|
|
4791
4791
|
});
|
|
4792
4792
|
const session = api.sessionSyncClient(response);
|
|
4793
|
-
const
|
|
4794
|
-
types.logger.debug(`[START]
|
|
4793
|
+
const zenfloServer = await startZenfloServer(session, api);
|
|
4794
|
+
types.logger.debug(`[START] ZenFlo MCP server started at ${zenfloServer.url}`);
|
|
4795
4795
|
const logPath = types.logger.logFilePath;
|
|
4796
4796
|
types.logger.infoDeveloper(`Session: ${response.id}`);
|
|
4797
4797
|
types.logger.infoDeveloper(`Logs: ${logPath}`);
|
|
@@ -4940,7 +4940,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4940
4940
|
await session.close();
|
|
4941
4941
|
}
|
|
4942
4942
|
stopCaffeinate();
|
|
4943
|
-
|
|
4943
|
+
zenfloServer.stop();
|
|
4944
4944
|
types.logger.debug("[START] Cleanup complete, exiting");
|
|
4945
4945
|
process.exit(0);
|
|
4946
4946
|
} catch (error) {
|
|
@@ -4966,7 +4966,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4966
4966
|
startingMode: options.startingMode,
|
|
4967
4967
|
messageQueue,
|
|
4968
4968
|
api,
|
|
4969
|
-
allowedTools:
|
|
4969
|
+
allowedTools: zenfloServer.toolNames.map((toolName) => `mcp__zenflo__${toolName}`),
|
|
4970
4970
|
onModeChange: (newMode) => {
|
|
4971
4971
|
session.sendSessionEvent({ type: "switch", mode: newMode });
|
|
4972
4972
|
session.updateAgentState((currentState) => ({
|
|
@@ -4977,9 +4977,9 @@ async function runClaude(credentials, options = {}) {
|
|
|
4977
4977
|
onSessionReady: (_sessionInstance) => {
|
|
4978
4978
|
},
|
|
4979
4979
|
mcpServers: {
|
|
4980
|
-
"
|
|
4980
|
+
"zenflo": {
|
|
4981
4981
|
type: "http",
|
|
4982
|
-
url:
|
|
4982
|
+
url: zenfloServer.url
|
|
4983
4983
|
}
|
|
4984
4984
|
},
|
|
4985
4985
|
session,
|
|
@@ -4993,8 +4993,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4993
4993
|
await session.close();
|
|
4994
4994
|
stopCaffeinate();
|
|
4995
4995
|
types.logger.debug("Stopped sleep prevention");
|
|
4996
|
-
|
|
4997
|
-
types.logger.debug("Stopped
|
|
4996
|
+
zenfloServer.stop();
|
|
4997
|
+
types.logger.debug("Stopped ZenFlo MCP server");
|
|
4998
4998
|
process.exit(0);
|
|
4999
4999
|
}
|
|
5000
5000
|
|
|
@@ -5065,7 +5065,7 @@ async function install() {
|
|
|
5065
5065
|
if (process.getuid && process.getuid() !== 0) {
|
|
5066
5066
|
throw new Error("Daemon installation requires sudo privileges. Please run with sudo.");
|
|
5067
5067
|
}
|
|
5068
|
-
types.logger.info("Installing
|
|
5068
|
+
types.logger.info("Installing ZenFlo CLI daemon for macOS...");
|
|
5069
5069
|
await install$1();
|
|
5070
5070
|
}
|
|
5071
5071
|
|
|
@@ -5099,7 +5099,7 @@ async function uninstall() {
|
|
|
5099
5099
|
if (process.getuid && process.getuid() !== 0) {
|
|
5100
5100
|
throw new Error("Daemon uninstallation requires sudo privileges. Please run with sudo.");
|
|
5101
5101
|
}
|
|
5102
|
-
types.logger.info("Uninstalling
|
|
5102
|
+
types.logger.info("Uninstalling ZenFlo CLI daemon for macOS...");
|
|
5103
5103
|
await uninstall$1();
|
|
5104
5104
|
}
|
|
5105
5105
|
|
|
@@ -5818,7 +5818,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5818
5818
|
(async () => {
|
|
5819
5819
|
const args = process.argv.slice(2);
|
|
5820
5820
|
if (!args.includes("--version")) {
|
|
5821
|
-
types.logger.debug("Starting
|
|
5821
|
+
types.logger.debug("Starting ZenFlo CLI with args: ", process.argv);
|
|
5822
5822
|
}
|
|
5823
5823
|
const subcommand = args[0];
|
|
5824
5824
|
if (subcommand === "doctor") {
|
|
@@ -5856,7 +5856,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5856
5856
|
return;
|
|
5857
5857
|
} else if (subcommand === "codex") {
|
|
5858
5858
|
try {
|
|
5859
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
5859
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CzeejIBC.cjs'); });
|
|
5860
5860
|
let startedBy = void 0;
|
|
5861
5861
|
for (let i = 1; i < args.length; i++) {
|
|
5862
5862
|
if (args[i] === "--started-by") {
|
|
@@ -5927,7 +5927,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5927
5927
|
}
|
|
5928
5928
|
return;
|
|
5929
5929
|
} else if (daemonSubcommand === "start") {
|
|
5930
|
-
const child =
|
|
5930
|
+
const child = spawnZenfloCLI(["daemon", "start-sync"], {
|
|
5931
5931
|
detached: true,
|
|
5932
5932
|
stdio: "ignore",
|
|
5933
5933
|
env: process.env
|
|
@@ -6073,10 +6073,10 @@ ${chalk.bold.cyan("Claude Code Options (from `claude --help`):")}
|
|
|
6073
6073
|
const {
|
|
6074
6074
|
credentials
|
|
6075
6075
|
} = await authAndSetupMachineIfNeeded();
|
|
6076
|
-
types.logger.debug("Ensuring
|
|
6076
|
+
types.logger.debug("Ensuring ZenFlo background service is running & matches our version...");
|
|
6077
6077
|
if (!await isDaemonRunningCurrentlyInstalledHappyVersion()) {
|
|
6078
|
-
types.logger.debug("Starting
|
|
6079
|
-
const daemonProcess =
|
|
6078
|
+
types.logger.debug("Starting ZenFlo background service...");
|
|
6079
|
+
const daemonProcess = spawnZenfloCLI(["daemon", "start-sync"], {
|
|
6080
6080
|
detached: true,
|
|
6081
6081
|
stdio: "ignore",
|
|
6082
6082
|
env: process.env
|
|
@@ -6170,6 +6170,6 @@ exports.hashObject = hashObject;
|
|
|
6170
6170
|
exports.initialMachineMetadata = initialMachineMetadata;
|
|
6171
6171
|
exports.notifyDaemonSessionStarted = notifyDaemonSessionStarted;
|
|
6172
6172
|
exports.registerKillSessionHandler = registerKillSessionHandler;
|
|
6173
|
-
exports.
|
|
6173
|
+
exports.startZenfloServer = startZenfloServer;
|
|
6174
6174
|
exports.stopCaffeinate = stopCaffeinate;
|
|
6175
6175
|
exports.trimIdent = trimIdent;
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
|
@@ -717,7 +717,7 @@ declare class PushNotificationClient {
|
|
|
717
717
|
}
|
|
718
718
|
|
|
719
719
|
/**
|
|
720
|
-
* Minimal persistence functions for
|
|
720
|
+
* Minimal persistence functions for ZenFlo CLI
|
|
721
721
|
*
|
|
722
722
|
* Handles settings and private key storage in ~/.happy/ or local .happy/
|
|
723
723
|
*/
|
|
@@ -799,7 +799,7 @@ declare class Logger {
|
|
|
799
799
|
declare let logger: Logger;
|
|
800
800
|
|
|
801
801
|
/**
|
|
802
|
-
* Global configuration for
|
|
802
|
+
* Global configuration for ZenFlo CLI
|
|
803
803
|
*
|
|
804
804
|
* Centralizes all configuration including environment variables and paths
|
|
805
805
|
* Environment files should be loaded using Node's --env-file flag
|
package/dist/lib.d.mts
CHANGED
|
@@ -717,7 +717,7 @@ declare class PushNotificationClient {
|
|
|
717
717
|
}
|
|
718
718
|
|
|
719
719
|
/**
|
|
720
|
-
* Minimal persistence functions for
|
|
720
|
+
* Minimal persistence functions for ZenFlo CLI
|
|
721
721
|
*
|
|
722
722
|
* Handles settings and private key storage in ~/.happy/ or local .happy/
|
|
723
723
|
*/
|
|
@@ -799,7 +799,7 @@ declare class Logger {
|
|
|
799
799
|
declare let logger: Logger;
|
|
800
800
|
|
|
801
801
|
/**
|
|
802
|
-
* Global configuration for
|
|
802
|
+
* Global configuration for ZenFlo CLI
|
|
803
803
|
*
|
|
804
804
|
* Centralizes all configuration including environment variables and paths
|
|
805
805
|
* Environment files should be loaded using Node's --env-file flag
|
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-D1IoNz1N.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var types = require('./types-
|
|
5
|
+
var types = require('./types-B4VPN3pY.cjs');
|
|
6
6
|
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
|
|
7
7
|
var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
8
8
|
var z = require('zod');
|
|
9
9
|
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
|
10
10
|
var child_process = require('child_process');
|
|
11
11
|
var node_crypto = require('node:crypto');
|
|
12
|
-
var index = require('./index-
|
|
12
|
+
var index = require('./index-FBQqV3tt.cjs');
|
|
13
13
|
var os = require('node:os');
|
|
14
14
|
var node_path = require('node:path');
|
|
15
15
|
var fs = require('node:fs');
|
|
@@ -919,7 +919,7 @@ async function runCodex(opts) {
|
|
|
919
919
|
await session.close();
|
|
920
920
|
}
|
|
921
921
|
index.stopCaffeinate();
|
|
922
|
-
|
|
922
|
+
zenfloServer.stop();
|
|
923
923
|
types.logger.debug("[Codex] Session termination complete, exiting");
|
|
924
924
|
process.exit(0);
|
|
925
925
|
} catch (error) {
|
|
@@ -1124,12 +1124,12 @@ async function runCodex(opts) {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
}
|
|
1126
1126
|
});
|
|
1127
|
-
const
|
|
1128
|
-
const bridgeCommand = node_path.join(types.projectPath(), "bin", "
|
|
1127
|
+
const zenfloServer = await index.startZenfloServer(session, api);
|
|
1128
|
+
const bridgeCommand = node_path.join(types.projectPath(), "bin", "zenflo-mcp.mjs");
|
|
1129
1129
|
const mcpServers = {
|
|
1130
1130
|
happy: {
|
|
1131
1131
|
command: bridgeCommand,
|
|
1132
|
-
args: ["--url",
|
|
1132
|
+
args: ["--url", zenfloServer.url]
|
|
1133
1133
|
}
|
|
1134
1134
|
};
|
|
1135
1135
|
let first = true;
|
|
@@ -1305,8 +1305,8 @@ async function runCodex(opts) {
|
|
|
1305
1305
|
types.logger.debug("[codex]: client.disconnect begin");
|
|
1306
1306
|
await client.disconnect();
|
|
1307
1307
|
types.logger.debug("[codex]: client.disconnect done");
|
|
1308
|
-
types.logger.debug("[codex]:
|
|
1309
|
-
|
|
1308
|
+
types.logger.debug("[codex]: zenfloServer.stop");
|
|
1309
|
+
zenfloServer.stop();
|
|
1310
1310
|
if (process.stdin.isTTY) {
|
|
1311
1311
|
types.logger.debug("[codex]: setRawMode(false)");
|
|
1312
1312
|
try {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
-
import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-
|
|
3
|
+
import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-D1IoNz1N.mjs';
|
|
4
4
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
5
5
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
8
8
|
import { execSync } from 'child_process';
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
|
-
import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as
|
|
10
|
+
import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startZenfloServer, t as trimIdent, b as stopCaffeinate } from './index-BFbq03uJ.mjs';
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import { resolve, join } from 'node:path';
|
|
13
13
|
import fs from 'node:fs';
|
|
@@ -917,7 +917,7 @@ async function runCodex(opts) {
|
|
|
917
917
|
await session.close();
|
|
918
918
|
}
|
|
919
919
|
stopCaffeinate();
|
|
920
|
-
|
|
920
|
+
zenfloServer.stop();
|
|
921
921
|
logger.debug("[Codex] Session termination complete, exiting");
|
|
922
922
|
process.exit(0);
|
|
923
923
|
} catch (error) {
|
|
@@ -1122,12 +1122,12 @@ async function runCodex(opts) {
|
|
|
1122
1122
|
}
|
|
1123
1123
|
}
|
|
1124
1124
|
});
|
|
1125
|
-
const
|
|
1126
|
-
const bridgeCommand = join(projectPath(), "bin", "
|
|
1125
|
+
const zenfloServer = await startZenfloServer(session, api);
|
|
1126
|
+
const bridgeCommand = join(projectPath(), "bin", "zenflo-mcp.mjs");
|
|
1127
1127
|
const mcpServers = {
|
|
1128
1128
|
happy: {
|
|
1129
1129
|
command: bridgeCommand,
|
|
1130
|
-
args: ["--url",
|
|
1130
|
+
args: ["--url", zenfloServer.url]
|
|
1131
1131
|
}
|
|
1132
1132
|
};
|
|
1133
1133
|
let first = true;
|
|
@@ -1303,8 +1303,8 @@ async function runCodex(opts) {
|
|
|
1303
1303
|
logger.debug("[codex]: client.disconnect begin");
|
|
1304
1304
|
await client.disconnect();
|
|
1305
1305
|
logger.debug("[codex]: client.disconnect done");
|
|
1306
|
-
logger.debug("[codex]:
|
|
1307
|
-
|
|
1306
|
+
logger.debug("[codex]: zenfloServer.stop");
|
|
1307
|
+
zenfloServer.stop();
|
|
1308
1308
|
if (process.stdin.isTTY) {
|
|
1309
1309
|
logger.debug("[codex]: setRawMode(false)");
|
|
1310
1310
|
try {
|
|
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
|
|
|
42
42
|
var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
43
43
|
|
|
44
44
|
var name = "zenflo";
|
|
45
|
-
var version = "0.11.
|
|
45
|
+
var version = "0.11.4";
|
|
46
46
|
var description = "Mobile and Web client for Claude Code and Codex - ZenFlo edition";
|
|
47
47
|
var author = "Combined Memory";
|
|
48
48
|
var license = "MIT";
|
|
@@ -78,14 +78,14 @@ var exports$1 = {
|
|
|
78
78
|
"default": "./dist/lib.mjs"
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
"./codex/
|
|
81
|
+
"./codex/zenfloMcpStdioBridge": {
|
|
82
82
|
require: {
|
|
83
|
-
types: "./dist/codex/
|
|
84
|
-
"default": "./dist/codex/
|
|
83
|
+
types: "./dist/codex/zenfloMcpStdioBridge.d.cts",
|
|
84
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.cjs"
|
|
85
85
|
},
|
|
86
86
|
"import": {
|
|
87
|
-
types: "./dist/codex/
|
|
88
|
-
"default": "./dist/codex/
|
|
87
|
+
types: "./dist/codex/zenfloMcpStdioBridge.d.mts",
|
|
88
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.mjs"
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
};
|
|
@@ -1019,7 +1019,7 @@ class RpcHandlerManager {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
}
|
|
1021
1021
|
|
|
1022
|
-
const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1022
|
+
const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-B4VPN3pY.cjs', document.baseURI).href))));
|
|
1023
1023
|
function projectPath() {
|
|
1024
1024
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1025
1025
|
return path$1;
|
|
@@ -21,7 +21,7 @@ import { platform } from 'os';
|
|
|
21
21
|
import { Expo } from 'expo-server-sdk';
|
|
22
22
|
|
|
23
23
|
var name = "zenflo";
|
|
24
|
-
var version = "0.11.
|
|
24
|
+
var version = "0.11.4";
|
|
25
25
|
var description = "Mobile and Web client for Claude Code and Codex - ZenFlo edition";
|
|
26
26
|
var author = "Combined Memory";
|
|
27
27
|
var license = "MIT";
|
|
@@ -57,14 +57,14 @@ var exports$1 = {
|
|
|
57
57
|
"default": "./dist/lib.mjs"
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
|
-
"./codex/
|
|
60
|
+
"./codex/zenfloMcpStdioBridge": {
|
|
61
61
|
require: {
|
|
62
|
-
types: "./dist/codex/
|
|
63
|
-
"default": "./dist/codex/
|
|
62
|
+
types: "./dist/codex/zenfloMcpStdioBridge.d.cts",
|
|
63
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.cjs"
|
|
64
64
|
},
|
|
65
65
|
"import": {
|
|
66
|
-
types: "./dist/codex/
|
|
67
|
-
"default": "./dist/codex/
|
|
66
|
+
types: "./dist/codex/zenfloMcpStdioBridge.d.mts",
|
|
67
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.mjs"
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zenflo",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.4",
|
|
4
4
|
"description": "Mobile and Web client for Claude Code and Codex - ZenFlo edition",
|
|
5
5
|
"author": "Combined Memory",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"default": "./dist/lib.mjs"
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
-
"./codex/
|
|
39
|
+
"./codex/zenfloMcpStdioBridge": {
|
|
40
40
|
"require": {
|
|
41
|
-
"types": "./dist/codex/
|
|
42
|
-
"default": "./dist/codex/
|
|
41
|
+
"types": "./dist/codex/zenfloMcpStdioBridge.d.cts",
|
|
42
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.cjs"
|
|
43
43
|
},
|
|
44
44
|
"import": {
|
|
45
|
-
"types": "./dist/codex/
|
|
46
|
-
"default": "./dist/codex/
|
|
45
|
+
"types": "./dist/codex/zenfloMcpStdioBridge.d.mts",
|
|
46
|
+
"default": "./dist/codex/zenfloMcpStdioBridge.mjs"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|