zenflo 0.11.5 → 0.11.7

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.
@@ -2,14 +2,14 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-BowvGBcM.cjs');
5
+ var types = require('./types-Dvhor4zW.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-6-qKdQ7W.cjs');
12
+ var index = require('./index-HBSmEvnF.cjs');
13
13
  var os = require('node:os');
14
14
  var node_path = require('node:path');
15
15
  var fs = require('node:fs');
@@ -792,9 +792,9 @@ async function runCodex(opts) {
792
792
  os: os.platform(),
793
793
  machineId,
794
794
  homeDir: os.homedir(),
795
- happyHomeDir: types.configuration.happyHomeDir,
796
- happyLibDir: types.projectPath(),
797
- happyToolsDir: node_path.resolve(types.projectPath(), "tools", "unpacked"),
795
+ zenfloHomeDir: types.configuration.zenfloHomeDir,
796
+ zenfloLibDir: types.projectPath(),
797
+ zenfloToolsDir: node_path.resolve(types.projectPath(), "tools", "unpacked"),
798
798
  startedFromDaemon: opts.startedBy === "daemon",
799
799
  hostPid: process.pid,
800
800
  startedBy: opts.startedBy || "terminal",
@@ -1126,11 +1126,28 @@ async function runCodex(opts) {
1126
1126
  });
1127
1127
  const zenfloServer = await index.startZenfloServer(session, api);
1128
1128
  const bridgeCommand = node_path.join(types.projectPath(), "bin", "zenflo-mcp.mjs");
1129
+ const zenModeConfig = {
1130
+ command: "node",
1131
+ args: [node_path.join(types.projectPath(), "..", "zen-mcp", "zen-mode-mcp-server", "dist", "index.js")]
1132
+ };
1133
+ if (process.env.ZENFLO_AUTH_TOKEN || process.env.ZENFLO_SECRET_KEY || process.env.ZENFLO_USER_ID) {
1134
+ zenModeConfig.env = {};
1135
+ if (process.env.ZENFLO_AUTH_TOKEN) {
1136
+ zenModeConfig.env.ZENFLO_AUTH_TOKEN = process.env.ZENFLO_AUTH_TOKEN;
1137
+ }
1138
+ if (process.env.ZENFLO_SECRET_KEY) {
1139
+ zenModeConfig.env.ZENFLO_SECRET_KEY = process.env.ZENFLO_SECRET_KEY;
1140
+ }
1141
+ if (process.env.ZENFLO_USER_ID) {
1142
+ zenModeConfig.env.ZENFLO_USER_ID = process.env.ZENFLO_USER_ID;
1143
+ }
1144
+ }
1129
1145
  const mcpServers = {
1130
1146
  happy: {
1131
1147
  command: bridgeCommand,
1132
1148
  args: ["--url", zenfloServer.url]
1133
- }
1149
+ },
1150
+ "zen-mode": zenModeConfig
1134
1151
  };
1135
1152
  let first = true;
1136
1153
  try {
@@ -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.5";
24
+ var version = "0.11.7";
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";
@@ -172,7 +172,7 @@ class Configuration {
172
172
  webappUrl;
173
173
  isDaemonProcess;
174
174
  // Directories and paths (from persistence)
175
- happyHomeDir;
175
+ zenfloHomeDir;
176
176
  logsDir;
177
177
  settingsFile;
178
178
  privateKeyFile;
@@ -182,27 +182,26 @@ class Configuration {
182
182
  isExperimentalEnabled;
183
183
  disableCaffeinate;
184
184
  constructor() {
185
- this.serverUrl = process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL || "https://zenflo.combinedmemory.com";
186
- this.webappUrl = process.env.ZENFLO_WEBAPP_URL || process.env.HAPPY_WEBAPP_URL || "https://app.combinedmemory.com";
185
+ this.serverUrl = process.env.ZENFLO_SERVER_URL || "https://zenflo.combinedmemory.com";
186
+ this.webappUrl = process.env.ZENFLO_WEBAPP_URL || "https://app.combinedmemory.com";
187
187
  const args = process.argv.slice(2);
188
188
  this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
189
- if (process.env.ZENFLO_HOME_DIR || process.env.HAPPY_HOME_DIR) {
190
- const homeDir = process.env.ZENFLO_HOME_DIR || process.env.HAPPY_HOME_DIR;
191
- const expandedPath = homeDir.replace(/^~/, homedir());
192
- this.happyHomeDir = expandedPath;
189
+ if (process.env.ZENFLO_HOME_DIR) {
190
+ const expandedPath = process.env.ZENFLO_HOME_DIR.replace(/^~/, homedir());
191
+ this.zenfloHomeDir = expandedPath;
193
192
  } else {
194
- this.happyHomeDir = join(homedir(), ".happy");
193
+ this.zenfloHomeDir = join(homedir(), ".zenflo");
195
194
  }
196
- this.logsDir = join(this.happyHomeDir, "logs");
197
- this.settingsFile = join(this.happyHomeDir, "settings.json");
198
- this.privateKeyFile = join(this.happyHomeDir, "access.key");
199
- this.daemonStateFile = join(this.happyHomeDir, "daemon.state.json");
200
- this.daemonLockFile = join(this.happyHomeDir, "daemon.state.json.lock");
201
- this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
202
- this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
195
+ this.logsDir = join(this.zenfloHomeDir, "logs");
196
+ this.settingsFile = join(this.zenfloHomeDir, "settings.json");
197
+ this.privateKeyFile = join(this.zenfloHomeDir, "access.key");
198
+ this.daemonStateFile = join(this.zenfloHomeDir, "daemon.state.json");
199
+ this.daemonLockFile = join(this.zenfloHomeDir, "daemon.state.json.lock");
200
+ this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.ZENFLO_EXPERIMENTAL?.toLowerCase() || "");
201
+ this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.ZENFLO_DISABLE_CAFFEINATE?.toLowerCase() || "");
203
202
  this.currentCliVersion = packageJson.version;
204
- if (!existsSync(this.happyHomeDir)) {
205
- mkdirSync(this.happyHomeDir, { recursive: true });
203
+ if (!existsSync(this.zenfloHomeDir)) {
204
+ mkdirSync(this.zenfloHomeDir, { recursive: true });
206
205
  }
207
206
  if (!existsSync(this.logsDir)) {
208
207
  mkdirSync(this.logsDir, { recursive: true });
@@ -362,8 +361,8 @@ async function updateSettings(updater) {
362
361
  try {
363
362
  const current = await readSettings() || { ...defaultSettings };
364
363
  const updated = await updater(current);
365
- if (!existsSync(configuration.happyHomeDir)) {
366
- await mkdir(configuration.happyHomeDir, { recursive: true });
364
+ if (!existsSync(configuration.zenfloHomeDir)) {
365
+ await mkdir(configuration.zenfloHomeDir, { recursive: true });
367
366
  }
368
367
  await writeFile(tmpFile, JSON.stringify(updated, null, 2));
369
368
  await rename(tmpFile, configuration.settingsFile);
@@ -414,8 +413,8 @@ async function readCredentials() {
414
413
  return null;
415
414
  }
416
415
  async function writeCredentialsLegacy(credentials) {
417
- if (!existsSync(configuration.happyHomeDir)) {
418
- await mkdir(configuration.happyHomeDir, { recursive: true });
416
+ if (!existsSync(configuration.zenfloHomeDir)) {
417
+ await mkdir(configuration.zenfloHomeDir, { recursive: true });
419
418
  }
420
419
  await writeFile(configuration.privateKeyFile, JSON.stringify({
421
420
  secret: encodeBase64(credentials.secret),
@@ -423,8 +422,8 @@ async function writeCredentialsLegacy(credentials) {
423
422
  }, null, 2));
424
423
  }
425
424
  async function writeCredentialsDataKey(credentials) {
426
- if (!existsSync(configuration.happyHomeDir)) {
427
- await mkdir(configuration.happyHomeDir, { recursive: true });
425
+ if (!existsSync(configuration.zenfloHomeDir)) {
426
+ await mkdir(configuration.zenfloHomeDir, { recursive: true });
428
427
  }
429
428
  await writeFile(configuration.privateKeyFile, JSON.stringify({
430
429
  encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
@@ -543,8 +542,8 @@ function getSessionLogPath() {
543
542
  class Logger {
544
543
  constructor(logFilePath = getSessionLogPath()) {
545
544
  this.logFilePath = logFilePath;
546
- if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && (process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL)) {
547
- this.dangerouslyUnencryptedServerLoggingUrl = process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL;
545
+ if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && process.env.ZENFLO_SERVER_URL) {
546
+ this.dangerouslyUnencryptedServerLoggingUrl = process.env.ZENFLO_SERVER_URL;
548
547
  console.log(chalk.yellow("[REMOTE LOGGING] Sending logs to server for AI debugging"));
549
548
  }
550
549
  }
@@ -768,10 +767,10 @@ z$1.object({
768
767
  z$1.object({
769
768
  host: z$1.string(),
770
769
  platform: z$1.string(),
771
- happyCliVersion: z$1.string(),
770
+ zenfloCliVersion: z$1.string(),
772
771
  homeDir: z$1.string(),
773
- happyHomeDir: z$1.string(),
774
- happyLibDir: z$1.string()
772
+ zenfloHomeDir: z$1.string(),
773
+ zenfloLibDir: z$1.string()
775
774
  });
776
775
  z$1.object({
777
776
  status: z$1.union([
@@ -1443,9 +1442,11 @@ class ApiSessionClient extends EventEmitter {
1443
1442
  }
1444
1443
  logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
1445
1444
  const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
1445
+ const localId = typeof body.uuid === "string" ? body.uuid : null;
1446
1446
  this.socket.emit("message", {
1447
1447
  sid: this.sessionId,
1448
- message: encrypted
1448
+ message: encrypted,
1449
+ localId
1449
1450
  });
1450
1451
  if (body.type === "assistant" && body.message.usage) {
1451
1452
  try {
@@ -2170,6 +2171,14 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
2170
2171
  type: z$1.literal("system"),
2171
2172
  uuid: z$1.string()
2172
2173
  // Used in getMessageKey()
2174
+ }).passthrough(),
2175
+ // Queue operation - internal Claude Code message for managing task queue
2176
+ // These are not sent to backend, just need to be parseable
2177
+ z$1.object({
2178
+ type: z$1.literal("queue-operation"),
2179
+ operation: z$1.enum(["enqueue", "dequeue"]),
2180
+ timestamp: z$1.string(),
2181
+ sessionId: z$1.string()
2173
2182
  }).passthrough()
2174
2183
  ]);
2175
2184
 
@@ -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.5";
45
+ var version = "0.11.7";
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";
@@ -193,7 +193,7 @@ class Configuration {
193
193
  webappUrl;
194
194
  isDaemonProcess;
195
195
  // Directories and paths (from persistence)
196
- happyHomeDir;
196
+ zenfloHomeDir;
197
197
  logsDir;
198
198
  settingsFile;
199
199
  privateKeyFile;
@@ -203,27 +203,26 @@ class Configuration {
203
203
  isExperimentalEnabled;
204
204
  disableCaffeinate;
205
205
  constructor() {
206
- this.serverUrl = process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL || "https://zenflo.combinedmemory.com";
207
- this.webappUrl = process.env.ZENFLO_WEBAPP_URL || process.env.HAPPY_WEBAPP_URL || "https://app.combinedmemory.com";
206
+ this.serverUrl = process.env.ZENFLO_SERVER_URL || "https://zenflo.combinedmemory.com";
207
+ this.webappUrl = process.env.ZENFLO_WEBAPP_URL || "https://app.combinedmemory.com";
208
208
  const args = process.argv.slice(2);
209
209
  this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
210
- if (process.env.ZENFLO_HOME_DIR || process.env.HAPPY_HOME_DIR) {
211
- const homeDir = process.env.ZENFLO_HOME_DIR || process.env.HAPPY_HOME_DIR;
212
- const expandedPath = homeDir.replace(/^~/, os.homedir());
213
- this.happyHomeDir = expandedPath;
210
+ if (process.env.ZENFLO_HOME_DIR) {
211
+ const expandedPath = process.env.ZENFLO_HOME_DIR.replace(/^~/, os.homedir());
212
+ this.zenfloHomeDir = expandedPath;
214
213
  } else {
215
- this.happyHomeDir = node_path.join(os.homedir(), ".happy");
214
+ this.zenfloHomeDir = node_path.join(os.homedir(), ".zenflo");
216
215
  }
217
- this.logsDir = node_path.join(this.happyHomeDir, "logs");
218
- this.settingsFile = node_path.join(this.happyHomeDir, "settings.json");
219
- this.privateKeyFile = node_path.join(this.happyHomeDir, "access.key");
220
- this.daemonStateFile = node_path.join(this.happyHomeDir, "daemon.state.json");
221
- this.daemonLockFile = node_path.join(this.happyHomeDir, "daemon.state.json.lock");
222
- this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
223
- this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
216
+ this.logsDir = node_path.join(this.zenfloHomeDir, "logs");
217
+ this.settingsFile = node_path.join(this.zenfloHomeDir, "settings.json");
218
+ this.privateKeyFile = node_path.join(this.zenfloHomeDir, "access.key");
219
+ this.daemonStateFile = node_path.join(this.zenfloHomeDir, "daemon.state.json");
220
+ this.daemonLockFile = node_path.join(this.zenfloHomeDir, "daemon.state.json.lock");
221
+ this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.ZENFLO_EXPERIMENTAL?.toLowerCase() || "");
222
+ this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.ZENFLO_DISABLE_CAFFEINATE?.toLowerCase() || "");
224
223
  this.currentCliVersion = packageJson.version;
225
- if (!fs.existsSync(this.happyHomeDir)) {
226
- fs.mkdirSync(this.happyHomeDir, { recursive: true });
224
+ if (!fs.existsSync(this.zenfloHomeDir)) {
225
+ fs.mkdirSync(this.zenfloHomeDir, { recursive: true });
227
226
  }
228
227
  if (!fs.existsSync(this.logsDir)) {
229
228
  fs.mkdirSync(this.logsDir, { recursive: true });
@@ -383,8 +382,8 @@ async function updateSettings(updater) {
383
382
  try {
384
383
  const current = await readSettings() || { ...defaultSettings };
385
384
  const updated = await updater(current);
386
- if (!fs.existsSync(configuration.happyHomeDir)) {
387
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
385
+ if (!fs.existsSync(configuration.zenfloHomeDir)) {
386
+ await promises.mkdir(configuration.zenfloHomeDir, { recursive: true });
388
387
  }
389
388
  await promises.writeFile(tmpFile, JSON.stringify(updated, null, 2));
390
389
  await promises.rename(tmpFile, configuration.settingsFile);
@@ -435,8 +434,8 @@ async function readCredentials() {
435
434
  return null;
436
435
  }
437
436
  async function writeCredentialsLegacy(credentials) {
438
- if (!fs.existsSync(configuration.happyHomeDir)) {
439
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
437
+ if (!fs.existsSync(configuration.zenfloHomeDir)) {
438
+ await promises.mkdir(configuration.zenfloHomeDir, { recursive: true });
440
439
  }
441
440
  await promises.writeFile(configuration.privateKeyFile, JSON.stringify({
442
441
  secret: encodeBase64(credentials.secret),
@@ -444,8 +443,8 @@ async function writeCredentialsLegacy(credentials) {
444
443
  }, null, 2));
445
444
  }
446
445
  async function writeCredentialsDataKey(credentials) {
447
- if (!fs.existsSync(configuration.happyHomeDir)) {
448
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
446
+ if (!fs.existsSync(configuration.zenfloHomeDir)) {
447
+ await promises.mkdir(configuration.zenfloHomeDir, { recursive: true });
449
448
  }
450
449
  await promises.writeFile(configuration.privateKeyFile, JSON.stringify({
451
450
  encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
@@ -564,8 +563,8 @@ function getSessionLogPath() {
564
563
  class Logger {
565
564
  constructor(logFilePath = getSessionLogPath()) {
566
565
  this.logFilePath = logFilePath;
567
- if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && (process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL)) {
568
- this.dangerouslyUnencryptedServerLoggingUrl = process.env.ZENFLO_SERVER_URL || process.env.HAPPY_SERVER_URL;
566
+ if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && process.env.ZENFLO_SERVER_URL) {
567
+ this.dangerouslyUnencryptedServerLoggingUrl = process.env.ZENFLO_SERVER_URL;
569
568
  console.log(chalk.yellow("[REMOTE LOGGING] Sending logs to server for AI debugging"));
570
569
  }
571
570
  }
@@ -789,10 +788,10 @@ z.z.object({
789
788
  z.z.object({
790
789
  host: z.z.string(),
791
790
  platform: z.z.string(),
792
- happyCliVersion: z.z.string(),
791
+ zenfloCliVersion: z.z.string(),
793
792
  homeDir: z.z.string(),
794
- happyHomeDir: z.z.string(),
795
- happyLibDir: z.z.string()
793
+ zenfloHomeDir: z.z.string(),
794
+ zenfloLibDir: z.z.string()
796
795
  });
797
796
  z.z.object({
798
797
  status: z.z.union([
@@ -1020,7 +1019,7 @@ class RpcHandlerManager {
1020
1019
  }
1021
1020
  }
1022
1021
 
1023
- 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-BowvGBcM.cjs', document.baseURI).href))));
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-Dvhor4zW.cjs', document.baseURI).href))));
1024
1023
  function projectPath() {
1025
1024
  const path$1 = path.resolve(__dirname$1, "..");
1026
1025
  return path$1;
@@ -1464,9 +1463,11 @@ class ApiSessionClient extends node_events.EventEmitter {
1464
1463
  }
1465
1464
  logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
1466
1465
  const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
1466
+ const localId = typeof body.uuid === "string" ? body.uuid : null;
1467
1467
  this.socket.emit("message", {
1468
1468
  sid: this.sessionId,
1469
- message: encrypted
1469
+ message: encrypted,
1470
+ localId
1470
1471
  });
1471
1472
  if (body.type === "assistant" && body.message.usage) {
1472
1473
  try {
@@ -2191,6 +2192,14 @@ const RawJSONLinesSchema = z.z.discriminatedUnion("type", [
2191
2192
  type: z.z.literal("system"),
2192
2193
  uuid: z.z.string()
2193
2194
  // Used in getMessageKey()
2195
+ }).passthrough(),
2196
+ // Queue operation - internal Claude Code message for managing task queue
2197
+ // These are not sent to backend, just need to be parseable
2198
+ z.z.object({
2199
+ type: z.z.literal("queue-operation"),
2200
+ operation: z.z.enum(["enqueue", "dequeue"]),
2201
+ timestamp: z.z.string(),
2202
+ sessionId: z.z.string()
2194
2203
  }).passthrough()
2195
2204
  ]);
2196
2205
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zenflo",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
4
  "description": "Mobile and Web client for Claude Code and Codex - ZenFlo edition",
5
5
  "author": "Combined Memory",
6
6
  "license": "MIT",