@zhigang1992/happy-cli 0.13.3 → 0.13.5

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.
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
  import os$1, { homedir } from 'node:os';
3
3
  import { randomUUID, randomBytes, createHmac } from 'node:crypto';
4
- import { l as logger, p as projectPath, j as backoff, k as delay, R as RawJSONLinesSchema, m as AsyncLock, c as configuration, n as readDaemonState, o as clearDaemonState, i as packageJson, r as readSettings, q as readCredentials, g as encodeBase64, u as updateSettings, s as encodeBase64Url, d as decodeBase64, w as writeCredentialsLegacy, t as writeCredentialsDataKey, v as acquireDaemonLock, x as writeDaemonState, A as ApiClient, y as releaseDaemonLock, z as authChallenge, B as clearCredentials, C as clearMachineId, D as getLatestDaemonLog } from './types-DZXtUKJF.mjs';
4
+ import { l as logger, p as projectPath, j as backoff, k as delay, R as RawJSONLinesSchema, m as AsyncLock, c as configuration, n as readDaemonState, o as clearDaemonState, i as packageJson, r as readSettings, q as readCredentials, g as encodeBase64, u as updateSettings, s as encodeBase64Url, d as decodeBase64, w as writeCredentialsLegacy, t as writeCredentialsDataKey, v as acquireDaemonLock, x as writeDaemonState, A as ApiClient, y as releaseDaemonLock, z as authChallenge, B as clearCredentials, C as clearMachineId, D as getLatestDaemonLog } from './types-kpW1rqr9.mjs';
5
5
  import { spawn, execSync, exec as exec$1, execFileSync } from 'node:child_process';
6
6
  import { resolve, join, extname, basename as basename$1 } from 'node:path';
7
7
  import { createInterface } from 'node:readline';
@@ -1497,6 +1497,7 @@ function query(config) {
1497
1497
  }
1498
1498
  if (continueConversation) args.push("--continue");
1499
1499
  if (resume) args.push("--resume", resume);
1500
+ if (config.options?.forkSession) args.push("--fork-session");
1500
1501
  if (allowedTools.length > 0) args.push("--allowedTools", allowedTools.join(","));
1501
1502
  if (disallowedTools.length > 0) args.push("--disallowedTools", disallowedTools.join(","));
1502
1503
  if (mcpServers && Object.keys(mcpServers).length > 0) {
@@ -1816,22 +1817,24 @@ async function claudeRemote(opts) {
1816
1817
  if (opts.sessionId && !claudeCheckSession(opts.sessionId, opts.path)) {
1817
1818
  startFrom = null;
1818
1819
  }
1819
- if (!startFrom && opts.claudeArgs) {
1820
+ let forkSession = false;
1821
+ if (opts.claudeArgs) {
1820
1822
  for (let i = 0; i < opts.claudeArgs.length; i++) {
1821
- if (opts.claudeArgs[i] === "--resume") {
1823
+ if (opts.claudeArgs[i] === "--fork-session") {
1824
+ forkSession = true;
1825
+ logger.debug("[claudeRemote] Found --fork-session flag");
1826
+ }
1827
+ if (!startFrom && opts.claudeArgs[i] === "--resume") {
1822
1828
  if (i + 1 < opts.claudeArgs.length) {
1823
1829
  const nextArg = opts.claudeArgs[i + 1];
1824
1830
  if (!nextArg.startsWith("-") && nextArg.includes("-")) {
1825
1831
  startFrom = nextArg;
1826
1832
  logger.debug(`[claudeRemote] Found --resume with session ID: ${startFrom}`);
1827
- break;
1828
1833
  } else {
1829
1834
  logger.debug("[claudeRemote] Found --resume without session ID - not supported in remote mode");
1830
- break;
1831
1835
  }
1832
1836
  } else {
1833
1837
  logger.debug("[claudeRemote] Found --resume without session ID - not supported in remote mode");
1834
- break;
1835
1838
  }
1836
1839
  }
1837
1840
  }
@@ -2013,6 +2016,7 @@ Echo message: ${echoMessage}` : "");
2013
2016
  const sdkOptions = {
2014
2017
  cwd: opts.path,
2015
2018
  resume: startFrom ?? void 0,
2019
+ forkSession,
2016
2020
  mcpServers: opts.mcpServers,
2017
2021
  permissionMode: initial.mode.permissionMode === "plan" ? "plan" : "default",
2018
2022
  model: initial.mode.model,
@@ -5133,7 +5137,9 @@ async function startDaemon() {
5133
5137
  "--started-by",
5134
5138
  "daemon",
5135
5139
  // Add --resume flag if resuming from a previous Claude session
5136
- ...options.resumeClaudeSessionId ? ["--resume", options.resumeClaudeSessionId] : []
5140
+ ...options.resumeClaudeSessionId ? ["--resume", options.resumeClaudeSessionId] : [],
5141
+ // Add --fork-session flag to create a new session ID when resuming
5142
+ ...options.forkSession ? ["--fork-session"] : []
5137
5143
  ];
5138
5144
  const happyProcess = spawnHappyCLI(args, {
5139
5145
  cwd: directory,
@@ -7019,7 +7025,7 @@ async function handleConnectVendor(vendor, displayName) {
7019
7025
  return;
7020
7026
  } else if (subcommand === "codex") {
7021
7027
  try {
7022
- const { runCodex } = await import('./runCodex-BoWqgEZr.mjs');
7028
+ const { runCodex } = await import('./runCodex-ZrIcuFxD.mjs');
7023
7029
  let startedBy = void 0;
7024
7030
  for (let i = 1; i < args.length; i++) {
7025
7031
  if (args[i] === "--started-by") {
@@ -7064,7 +7070,7 @@ async function handleConnectVendor(vendor, displayName) {
7064
7070
  } else if (subcommand === "list") {
7065
7071
  try {
7066
7072
  const { credentials } = await authAndSetupMachineIfNeeded();
7067
- const { listSessions } = await import('./list-D6wuSw1y.mjs');
7073
+ const { listSessions } = await import('./list-5AMxiEz4.mjs');
7068
7074
  let sessionId;
7069
7075
  let titleFilter;
7070
7076
  let recentMsgs;
@@ -7166,7 +7172,7 @@ Examples:
7166
7172
  process.exit(1);
7167
7173
  }
7168
7174
  const { credentials } = await authAndSetupMachineIfNeeded();
7169
- const { promptSession } = await import('./prompt-BooOOWHe.mjs');
7175
+ const { promptSession } = await import('./prompt-DonyiXWv.mjs');
7170
7176
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
7171
7177
  } catch (error) {
7172
7178
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -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--5a-fy9g.cjs');
6
+ var types = require('./types-CkkVG4rd.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');
@@ -1184,7 +1184,7 @@ class AbortError extends Error {
1184
1184
  }
1185
1185
  }
1186
1186
 
1187
- 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-DSexnLgz.cjs', document.baseURI).href)));
1187
+ 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-BQ2exZo8.cjs', document.baseURI).href)));
1188
1188
  const __dirname$1 = node_path.join(__filename$1, "..");
1189
1189
  function getGlobalClaudeVersion() {
1190
1190
  try {
@@ -1520,6 +1520,7 @@ function query(config) {
1520
1520
  }
1521
1521
  if (continueConversation) args.push("--continue");
1522
1522
  if (resume) args.push("--resume", resume);
1523
+ if (config.options?.forkSession) args.push("--fork-session");
1523
1524
  if (allowedTools.length > 0) args.push("--allowedTools", allowedTools.join(","));
1524
1525
  if (disallowedTools.length > 0) args.push("--disallowedTools", disallowedTools.join(","));
1525
1526
  if (mcpServers && Object.keys(mcpServers).length > 0) {
@@ -1839,22 +1840,24 @@ async function claudeRemote(opts) {
1839
1840
  if (opts.sessionId && !claudeCheckSession(opts.sessionId, opts.path)) {
1840
1841
  startFrom = null;
1841
1842
  }
1842
- if (!startFrom && opts.claudeArgs) {
1843
+ let forkSession = false;
1844
+ if (opts.claudeArgs) {
1843
1845
  for (let i = 0; i < opts.claudeArgs.length; i++) {
1844
- if (opts.claudeArgs[i] === "--resume") {
1846
+ if (opts.claudeArgs[i] === "--fork-session") {
1847
+ forkSession = true;
1848
+ types.logger.debug("[claudeRemote] Found --fork-session flag");
1849
+ }
1850
+ if (!startFrom && opts.claudeArgs[i] === "--resume") {
1845
1851
  if (i + 1 < opts.claudeArgs.length) {
1846
1852
  const nextArg = opts.claudeArgs[i + 1];
1847
1853
  if (!nextArg.startsWith("-") && nextArg.includes("-")) {
1848
1854
  startFrom = nextArg;
1849
1855
  types.logger.debug(`[claudeRemote] Found --resume with session ID: ${startFrom}`);
1850
- break;
1851
1856
  } else {
1852
1857
  types.logger.debug("[claudeRemote] Found --resume without session ID - not supported in remote mode");
1853
- break;
1854
1858
  }
1855
1859
  } else {
1856
1860
  types.logger.debug("[claudeRemote] Found --resume without session ID - not supported in remote mode");
1857
- break;
1858
1861
  }
1859
1862
  }
1860
1863
  }
@@ -2036,6 +2039,7 @@ Echo message: ${echoMessage}` : "");
2036
2039
  const sdkOptions = {
2037
2040
  cwd: opts.path,
2038
2041
  resume: startFrom ?? void 0,
2042
+ forkSession,
2039
2043
  mcpServers: opts.mcpServers,
2040
2044
  permissionMode: initial.mode.permissionMode === "plan" ? "plan" : "default",
2041
2045
  model: initial.mode.model,
@@ -5156,7 +5160,9 @@ async function startDaemon() {
5156
5160
  "--started-by",
5157
5161
  "daemon",
5158
5162
  // Add --resume flag if resuming from a previous Claude session
5159
- ...options.resumeClaudeSessionId ? ["--resume", options.resumeClaudeSessionId] : []
5163
+ ...options.resumeClaudeSessionId ? ["--resume", options.resumeClaudeSessionId] : [],
5164
+ // Add --fork-session flag to create a new session ID when resuming
5165
+ ...options.forkSession ? ["--fork-session"] : []
5160
5166
  ];
5161
5167
  const happyProcess = spawnHappyCLI(args, {
5162
5168
  cwd: directory,
@@ -7042,7 +7048,7 @@ async function handleConnectVendor(vendor, displayName) {
7042
7048
  return;
7043
7049
  } else if (subcommand === "codex") {
7044
7050
  try {
7045
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-_wtZQXU0.cjs'); });
7051
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-D1H75Lvt.cjs'); });
7046
7052
  let startedBy = void 0;
7047
7053
  for (let i = 1; i < args.length; i++) {
7048
7054
  if (args[i] === "--started-by") {
@@ -7087,7 +7093,7 @@ async function handleConnectVendor(vendor, displayName) {
7087
7093
  } else if (subcommand === "list") {
7088
7094
  try {
7089
7095
  const { credentials } = await authAndSetupMachineIfNeeded();
7090
- const { listSessions } = await Promise.resolve().then(function () { return require('./list-BPpLshMx.cjs'); });
7096
+ const { listSessions } = await Promise.resolve().then(function () { return require('./list-Css1Nqdi.cjs'); });
7091
7097
  let sessionId;
7092
7098
  let titleFilter;
7093
7099
  let recentMsgs;
@@ -7189,7 +7195,7 @@ Examples:
7189
7195
  process.exit(1);
7190
7196
  }
7191
7197
  const { credentials } = await authAndSetupMachineIfNeeded();
7192
- const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-CaJKwSsH.cjs'); });
7198
+ const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-BIX8B3nN.cjs'); });
7193
7199
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
7194
7200
  } catch (error) {
7195
7201
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-DSexnLgz.cjs');
5
- require('./types--5a-fy9g.cjs');
4
+ require('./index-BQ2exZo8.cjs');
5
+ require('./types-CkkVG4rd.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:os');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-CK4J-T-v.mjs';
3
- import './types-DZXtUKJF.mjs';
2
+ import './index-5mjr7Isp.mjs';
3
+ import './types-kpW1rqr9.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:os';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types--5a-fy9g.cjs');
3
+ var types = require('./types-CkkVG4rd.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('fs');
package/dist/lib.d.cts CHANGED
@@ -768,6 +768,8 @@ interface SpawnSessionOptions {
768
768
  agent?: 'claude' | 'codex';
769
769
  token?: string;
770
770
  resumeClaudeSessionId?: string;
771
+ /** When resuming, create a new session ID instead of reusing the original */
772
+ forkSession?: boolean;
771
773
  /** Environment variables to pass to the spawned session */
772
774
  environmentVariables?: Record<string, string>;
773
775
  }
package/dist/lib.d.mts CHANGED
@@ -768,6 +768,8 @@ interface SpawnSessionOptions {
768
768
  agent?: 'claude' | 'codex';
769
769
  token?: string;
770
770
  resumeClaudeSessionId?: string;
771
+ /** When resuming, create a new session ID instead of reusing the original */
772
+ forkSession?: boolean;
771
773
  /** Environment variables to pass to the spawned session */
772
774
  environmentVariables?: Record<string, string>;
773
775
  }
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-DZXtUKJF.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-kpW1rqr9.mjs';
2
2
  import 'axios';
3
3
  import 'chalk';
4
4
  import 'fs';
@@ -1,4 +1,4 @@
1
- import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-DZXtUKJF.mjs';
1
+ import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-kpW1rqr9.mjs';
2
2
  import axios from 'axios';
3
3
  import { existsSync, readdirSync, statSync, readFileSync } from 'fs';
4
4
  import { join } from 'path';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types--5a-fy9g.cjs');
3
+ var types = require('./types-CkkVG4rd.cjs');
4
4
  var axios = require('axios');
5
5
  var fs = require('fs');
6
6
  var path = require('path');
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types--5a-fy9g.cjs');
3
+ var types = require('./types-CkkVG4rd.cjs');
4
4
  var axios = require('axios');
5
5
  var socket_ioClient = require('socket.io-client');
6
6
  require('chalk');
@@ -1,4 +1,4 @@
1
- import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-DZXtUKJF.mjs';
1
+ import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-kpW1rqr9.mjs';
2
2
  import axios from 'axios';
3
3
  import { io } from 'socket.io-client';
4
4
  import 'chalk';
@@ -2,14 +2,14 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types--5a-fy9g.cjs');
5
+ var types = require('./types-CkkVG4rd.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-DSexnLgz.cjs');
12
+ var index = require('./index-BQ2exZo8.cjs');
13
13
  var os = require('node:os');
14
14
  var node_path = require('node:path');
15
15
  var fs = require('node:fs');
@@ -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, i as packageJson } from './types-DZXtUKJF.mjs';
3
+ import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-kpW1rqr9.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 startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-CK4J-T-v.mjs';
10
+ import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-5mjr7Isp.mjs';
11
11
  import os from 'node:os';
12
12
  import { resolve, join } from 'node:path';
13
13
  import fs from 'node:fs';
@@ -41,7 +41,7 @@ function _interopNamespaceDefault(e) {
41
41
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
42
42
 
43
43
  var name = "@zhigang1992/happy-cli";
44
- var version = "0.13.3";
44
+ var version = "0.13.5";
45
45
  var description = "Mobile and Web client for Claude Code and Codex";
46
46
  var author = "Kirill Dubovitskiy";
47
47
  var license = "MIT";
@@ -1150,7 +1150,7 @@ class RpcHandlerManager {
1150
1150
  }
1151
1151
  }
1152
1152
 
1153
- 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--5a-fy9g.cjs', document.baseURI).href))));
1153
+ 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-CkkVG4rd.cjs', document.baseURI).href))));
1154
1154
  function projectPath() {
1155
1155
  const path$1 = path.resolve(__dirname$1, "..");
1156
1156
  return path$1;
@@ -1914,12 +1914,12 @@ class ApiMachineClient {
1914
1914
  requestShutdown
1915
1915
  }) {
1916
1916
  this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
1917
- const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, environmentVariables } = params || {};
1917
+ const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, forkSession, environmentVariables } = params || {};
1918
1918
  logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
1919
1919
  if (!directory) {
1920
1920
  throw new Error("Directory is required");
1921
1921
  }
1922
- const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, environmentVariables });
1922
+ const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, forkSession, environmentVariables });
1923
1923
  switch (result.type) {
1924
1924
  case "success":
1925
1925
  logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
@@ -20,7 +20,7 @@ import { fileURLToPath } from 'url';
20
20
  import { Expo } from 'expo-server-sdk';
21
21
 
22
22
  var name = "@zhigang1992/happy-cli";
23
- var version = "0.13.3";
23
+ var version = "0.13.5";
24
24
  var description = "Mobile and Web client for Claude Code and Codex";
25
25
  var author = "Kirill Dubovitskiy";
26
26
  var license = "MIT";
@@ -1893,12 +1893,12 @@ class ApiMachineClient {
1893
1893
  requestShutdown
1894
1894
  }) {
1895
1895
  this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
1896
- const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, environmentVariables } = params || {};
1896
+ const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, forkSession, environmentVariables } = params || {};
1897
1897
  logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
1898
1898
  if (!directory) {
1899
1899
  throw new Error("Directory is required");
1900
1900
  }
1901
- const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, environmentVariables });
1901
+ const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, resumeClaudeSessionId, forkSession, environmentVariables });
1902
1902
  switch (result.type) {
1903
1903
  case "success":
1904
1904
  logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhigang1992/happy-cli",
3
- "version": "0.13.3",
3
+ "version": "0.13.5",
4
4
  "description": "Mobile and Web client for Claude Code and Codex",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "license": "MIT",