happy-coder 0.10.0-4 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-Dw96QD4T.mjs → index-BI37NnoW.mjs} +36 -7
- package/dist/{index-67rskwL7.cjs → index-ettJex_e.cjs} +58 -7
- package/dist/index.cjs +3 -2
- package/dist/index.mjs +3 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +2 -0
- package/dist/lib.d.mts +2 -0
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-BNH8w4O9.mjs → runCodex-HlLNepHI.mjs} +46 -5
- package/dist/{runCodex-BLNf5zb1.cjs → runCodex-QdQBx9HK.cjs} +46 -5
- package/dist/{types-2wHnX7UW.mjs → types-8Ad05p3x.mjs} +6 -3
- package/dist/{types-BcDnTXMg.cjs → types-CQOz_mPp.cjs} +7 -4
- package/package.json +3 -1
|
@@ -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, g as readDaemonState, h as clearDaemonState, b as packageJson, c as configuration, 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, g as readDaemonState, h as clearDaemonState, b as packageJson, c as configuration, 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-8Ad05p3x.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';
|
|
@@ -23,6 +23,7 @@ import { join as join$1 } from 'path';
|
|
|
23
23
|
import psList from 'ps-list';
|
|
24
24
|
import spawn$2 from 'cross-spawn';
|
|
25
25
|
import os from 'os';
|
|
26
|
+
import * as tmp from 'tmp';
|
|
26
27
|
import qrcode from 'qrcode-terminal';
|
|
27
28
|
import open from 'open';
|
|
28
29
|
import fastify from 'fastify';
|
|
@@ -4265,7 +4266,22 @@ async function startDaemon() {
|
|
|
4265
4266
|
}
|
|
4266
4267
|
}
|
|
4267
4268
|
try {
|
|
4269
|
+
let extraEnv = {};
|
|
4270
|
+
if (options.token) {
|
|
4271
|
+
if (options.agent === "codex") {
|
|
4272
|
+
const codexHomeDir = tmp.dirSync();
|
|
4273
|
+
fs.writeFile(join$1(codexHomeDir.name, "auth.json"), options.token);
|
|
4274
|
+
extraEnv = {
|
|
4275
|
+
CODEX_HOME: codexHomeDir.name
|
|
4276
|
+
};
|
|
4277
|
+
} else {
|
|
4278
|
+
extraEnv = {
|
|
4279
|
+
CLAUDE_CODE_OAUTH_TOKEN: options.token
|
|
4280
|
+
};
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4268
4283
|
const args = [
|
|
4284
|
+
options.agent === "claude" ? "claude" : "codex",
|
|
4269
4285
|
"--happy-starting-mode",
|
|
4270
4286
|
"remote",
|
|
4271
4287
|
"--started-by",
|
|
@@ -4275,9 +4291,12 @@ async function startDaemon() {
|
|
|
4275
4291
|
cwd: directory,
|
|
4276
4292
|
detached: true,
|
|
4277
4293
|
// Sessions stay alive when daemon stops
|
|
4278
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
4294
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
4279
4295
|
// Capture stdout/stderr for debugging
|
|
4280
|
-
|
|
4296
|
+
env: {
|
|
4297
|
+
...process.env,
|
|
4298
|
+
...extraEnv
|
|
4299
|
+
}
|
|
4281
4300
|
});
|
|
4282
4301
|
if (process.env.DEBUG) {
|
|
4283
4302
|
happyProcess.stdout?.on("data", (data) => {
|
|
@@ -4628,7 +4647,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4628
4647
|
startedBy: options.startedBy || "terminal",
|
|
4629
4648
|
// Initialize lifecycle state
|
|
4630
4649
|
lifecycleState: "running",
|
|
4631
|
-
lifecycleStateSince: Date.now()
|
|
4650
|
+
lifecycleStateSince: Date.now(),
|
|
4651
|
+
flavor: "claude"
|
|
4632
4652
|
};
|
|
4633
4653
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
4634
4654
|
logger.debug(`Session created: ${response.id}`);
|
|
@@ -5723,11 +5743,17 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5723
5743
|
return;
|
|
5724
5744
|
} else if (subcommand === "codex") {
|
|
5725
5745
|
try {
|
|
5726
|
-
const { runCodex } = await import('./runCodex-
|
|
5746
|
+
const { runCodex } = await import('./runCodex-HlLNepHI.mjs');
|
|
5747
|
+
let startedBy = void 0;
|
|
5748
|
+
for (let i = 1; i < args.length; i++) {
|
|
5749
|
+
if (args[i] === "--started-by") {
|
|
5750
|
+
startedBy = args[++i];
|
|
5751
|
+
}
|
|
5752
|
+
}
|
|
5727
5753
|
const {
|
|
5728
5754
|
credentials
|
|
5729
5755
|
} = await authAndSetupMachineIfNeeded();
|
|
5730
|
-
await runCodex({ credentials });
|
|
5756
|
+
await runCodex({ credentials, startedBy });
|
|
5731
5757
|
} catch (error) {
|
|
5732
5758
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
5733
5759
|
if (process.env.DEBUG) {
|
|
@@ -5860,6 +5886,9 @@ ${chalk.bold("To clean up runaway processes:")} Use ${chalk.cyan("happy doctor c
|
|
|
5860
5886
|
}
|
|
5861
5887
|
return;
|
|
5862
5888
|
} else {
|
|
5889
|
+
if (args.length > 0 && args[0] === "claude") {
|
|
5890
|
+
args.shift();
|
|
5891
|
+
}
|
|
5863
5892
|
const options = {};
|
|
5864
5893
|
let showHelp = false;
|
|
5865
5894
|
let showVersion = false;
|
|
@@ -6022,4 +6051,4 @@ ${chalk.bold("Examples:")}
|
|
|
6022
6051
|
}
|
|
6023
6052
|
}
|
|
6024
6053
|
|
|
6025
|
-
export { MessageQueue2 as M, MessageBuffer as a, hashObject as h, initialMachineMetadata as i, startHappyServer as s, trimIdent as t };
|
|
6054
|
+
export { MessageQueue2 as M, MessageBuffer as a, stopCaffeinate as b, hashObject as h, initialMachineMetadata as i, notifyDaemonSessionStarted as n, registerKillSessionHandler as r, startHappyServer 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-CQOz_mPp.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');
|
|
@@ -25,6 +25,7 @@ var path = require('path');
|
|
|
25
25
|
var psList = require('ps-list');
|
|
26
26
|
var spawn = require('cross-spawn');
|
|
27
27
|
var os$1 = require('os');
|
|
28
|
+
var tmp = require('tmp');
|
|
28
29
|
var qrcode = require('qrcode-terminal');
|
|
29
30
|
var open = require('open');
|
|
30
31
|
var fastify = require('fastify');
|
|
@@ -37,6 +38,25 @@ var http = require('http');
|
|
|
37
38
|
var util = require('util');
|
|
38
39
|
|
|
39
40
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
41
|
+
function _interopNamespaceDefault(e) {
|
|
42
|
+
var n = Object.create(null);
|
|
43
|
+
if (e) {
|
|
44
|
+
Object.keys(e).forEach(function (k) {
|
|
45
|
+
if (k !== 'default') {
|
|
46
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
47
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function () { return e[k]; }
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
n.default = e;
|
|
55
|
+
return Object.freeze(n);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var tmp__namespace = /*#__PURE__*/_interopNamespaceDefault(tmp);
|
|
59
|
+
|
|
40
60
|
class Session {
|
|
41
61
|
path;
|
|
42
62
|
logPath;
|
|
@@ -923,7 +943,7 @@ class AbortError extends Error {
|
|
|
923
943
|
}
|
|
924
944
|
}
|
|
925
945
|
|
|
926
|
-
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-
|
|
946
|
+
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-ettJex_e.cjs', document.baseURI).href)));
|
|
927
947
|
const __dirname$1 = node_path.join(__filename$1, "..");
|
|
928
948
|
function getDefaultClaudeCodePath() {
|
|
929
949
|
return node_path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
@@ -4268,7 +4288,22 @@ async function startDaemon() {
|
|
|
4268
4288
|
}
|
|
4269
4289
|
}
|
|
4270
4290
|
try {
|
|
4291
|
+
let extraEnv = {};
|
|
4292
|
+
if (options.token) {
|
|
4293
|
+
if (options.agent === "codex") {
|
|
4294
|
+
const codexHomeDir = tmp__namespace.dirSync();
|
|
4295
|
+
fs$1.writeFile(path.join(codexHomeDir.name, "auth.json"), options.token);
|
|
4296
|
+
extraEnv = {
|
|
4297
|
+
CODEX_HOME: codexHomeDir.name
|
|
4298
|
+
};
|
|
4299
|
+
} else {
|
|
4300
|
+
extraEnv = {
|
|
4301
|
+
CLAUDE_CODE_OAUTH_TOKEN: options.token
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4271
4305
|
const args = [
|
|
4306
|
+
options.agent === "claude" ? "claude" : "codex",
|
|
4272
4307
|
"--happy-starting-mode",
|
|
4273
4308
|
"remote",
|
|
4274
4309
|
"--started-by",
|
|
@@ -4278,9 +4313,12 @@ async function startDaemon() {
|
|
|
4278
4313
|
cwd: directory,
|
|
4279
4314
|
detached: true,
|
|
4280
4315
|
// Sessions stay alive when daemon stops
|
|
4281
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
4316
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
4282
4317
|
// Capture stdout/stderr for debugging
|
|
4283
|
-
|
|
4318
|
+
env: {
|
|
4319
|
+
...process.env,
|
|
4320
|
+
...extraEnv
|
|
4321
|
+
}
|
|
4284
4322
|
});
|
|
4285
4323
|
if (process.env.DEBUG) {
|
|
4286
4324
|
happyProcess.stdout?.on("data", (data) => {
|
|
@@ -4631,7 +4669,8 @@ async function runClaude(credentials, options = {}) {
|
|
|
4631
4669
|
startedBy: options.startedBy || "terminal",
|
|
4632
4670
|
// Initialize lifecycle state
|
|
4633
4671
|
lifecycleState: "running",
|
|
4634
|
-
lifecycleStateSince: Date.now()
|
|
4672
|
+
lifecycleStateSince: Date.now(),
|
|
4673
|
+
flavor: "claude"
|
|
4635
4674
|
};
|
|
4636
4675
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
4637
4676
|
types.logger.debug(`Session created: ${response.id}`);
|
|
@@ -5726,11 +5765,17 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5726
5765
|
return;
|
|
5727
5766
|
} else if (subcommand === "codex") {
|
|
5728
5767
|
try {
|
|
5729
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
5768
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-QdQBx9HK.cjs'); });
|
|
5769
|
+
let startedBy = void 0;
|
|
5770
|
+
for (let i = 1; i < args.length; i++) {
|
|
5771
|
+
if (args[i] === "--started-by") {
|
|
5772
|
+
startedBy = args[++i];
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5730
5775
|
const {
|
|
5731
5776
|
credentials
|
|
5732
5777
|
} = await authAndSetupMachineIfNeeded();
|
|
5733
|
-
await runCodex({ credentials });
|
|
5778
|
+
await runCodex({ credentials, startedBy });
|
|
5734
5779
|
} catch (error) {
|
|
5735
5780
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
5736
5781
|
if (process.env.DEBUG) {
|
|
@@ -5863,6 +5908,9 @@ ${chalk.bold("To clean up runaway processes:")} Use ${chalk.cyan("happy doctor c
|
|
|
5863
5908
|
}
|
|
5864
5909
|
return;
|
|
5865
5910
|
} else {
|
|
5911
|
+
if (args.length > 0 && args[0] === "claude") {
|
|
5912
|
+
args.shift();
|
|
5913
|
+
}
|
|
5866
5914
|
const options = {};
|
|
5867
5915
|
let showHelp = false;
|
|
5868
5916
|
let showVersion = false;
|
|
@@ -6029,5 +6077,8 @@ exports.MessageBuffer = MessageBuffer;
|
|
|
6029
6077
|
exports.MessageQueue2 = MessageQueue2;
|
|
6030
6078
|
exports.hashObject = hashObject;
|
|
6031
6079
|
exports.initialMachineMetadata = initialMachineMetadata;
|
|
6080
|
+
exports.notifyDaemonSessionStarted = notifyDaemonSessionStarted;
|
|
6081
|
+
exports.registerKillSessionHandler = registerKillSessionHandler;
|
|
6032
6082
|
exports.startHappyServer = startHappyServer;
|
|
6083
|
+
exports.stopCaffeinate = stopCaffeinate;
|
|
6033
6084
|
exports.trimIdent = trimIdent;
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./index-
|
|
5
|
-
require('./types-
|
|
4
|
+
require('./index-ettJex_e.cjs');
|
|
5
|
+
require('./types-CQOz_mPp.cjs');
|
|
6
6
|
require('zod');
|
|
7
7
|
require('node:child_process');
|
|
8
8
|
require('node:os');
|
|
@@ -27,6 +27,7 @@ require('path');
|
|
|
27
27
|
require('ps-list');
|
|
28
28
|
require('cross-spawn');
|
|
29
29
|
require('os');
|
|
30
|
+
require('tmp');
|
|
30
31
|
require('qrcode-terminal');
|
|
31
32
|
require('open');
|
|
32
33
|
require('fastify');
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'chalk';
|
|
2
|
-
import './index-
|
|
3
|
-
import './types-
|
|
2
|
+
import './index-BI37NnoW.mjs';
|
|
3
|
+
import './types-8Ad05p3x.mjs';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'node:child_process';
|
|
6
6
|
import 'node:os';
|
|
@@ -25,6 +25,7 @@ import 'path';
|
|
|
25
25
|
import 'ps-list';
|
|
26
26
|
import 'cross-spawn';
|
|
27
27
|
import 'os';
|
|
28
|
+
import 'tmp';
|
|
28
29
|
import 'qrcode-terminal';
|
|
29
30
|
import 'open';
|
|
30
31
|
import 'fastify';
|
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
package/dist/lib.d.mts
CHANGED
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-8Ad05p3x.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -1,12 +1,12 @@
|
|
|
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-8Ad05p3x.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 { randomUUID } from 'node:crypto';
|
|
9
|
-
import { i as initialMachineMetadata, M as MessageQueue2, h as hashObject, a as MessageBuffer, s as startHappyServer, t as trimIdent } from './index-
|
|
9
|
+
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-BI37NnoW.mjs';
|
|
10
10
|
import os from 'node:os';
|
|
11
11
|
import { resolve, join } from 'node:path';
|
|
12
12
|
import fs from 'node:fs';
|
|
@@ -30,6 +30,7 @@ import 'node:readline';
|
|
|
30
30
|
import 'node:url';
|
|
31
31
|
import 'ps-list';
|
|
32
32
|
import 'cross-spawn';
|
|
33
|
+
import 'tmp';
|
|
33
34
|
import 'qrcode-terminal';
|
|
34
35
|
import 'open';
|
|
35
36
|
import 'fastify';
|
|
@@ -679,6 +680,7 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit }) => {
|
|
|
679
680
|
async function runCodex(opts) {
|
|
680
681
|
const sessionTag = randomUUID();
|
|
681
682
|
const api = await ApiClient.create(opts.credentials);
|
|
683
|
+
logger.debug(`[codex] Starting with options: startedBy=${opts.startedBy || "terminal"}`);
|
|
682
684
|
const settings = await readSettings();
|
|
683
685
|
let machineId = settings?.machineId;
|
|
684
686
|
if (!machineId) {
|
|
@@ -703,9 +705,9 @@ async function runCodex(opts) {
|
|
|
703
705
|
happyHomeDir: configuration.happyHomeDir,
|
|
704
706
|
happyLibDir: projectPath(),
|
|
705
707
|
happyToolsDir: resolve(projectPath(), "tools", "unpacked"),
|
|
706
|
-
startedFromDaemon:
|
|
708
|
+
startedFromDaemon: opts.startedBy === "daemon",
|
|
707
709
|
hostPid: process.pid,
|
|
708
|
-
startedBy: "terminal",
|
|
710
|
+
startedBy: opts.startedBy || "terminal",
|
|
709
711
|
// Initialize lifecycle state
|
|
710
712
|
lifecycleState: "running",
|
|
711
713
|
lifecycleStateSince: Date.now(),
|
|
@@ -713,6 +715,17 @@ async function runCodex(opts) {
|
|
|
713
715
|
};
|
|
714
716
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
715
717
|
const session = api.sessionSyncClient(response);
|
|
718
|
+
try {
|
|
719
|
+
logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
720
|
+
const result = await notifyDaemonSessionStarted(response.id, metadata);
|
|
721
|
+
if (result.error) {
|
|
722
|
+
logger.debug(`[START] Failed to report to daemon (may not be running):`, result.error);
|
|
723
|
+
} else {
|
|
724
|
+
logger.debug(`[START] Reported session ${response.id} to daemon`);
|
|
725
|
+
}
|
|
726
|
+
} catch (error) {
|
|
727
|
+
logger.debug("[START] Failed to report to daemon (may not be running):", error);
|
|
728
|
+
}
|
|
716
729
|
const messageQueue = new MessageQueue2((mode) => hashObject({
|
|
717
730
|
permissionMode: mode.permissionMode,
|
|
718
731
|
model: mode.model
|
|
@@ -781,7 +794,34 @@ async function runCodex(opts) {
|
|
|
781
794
|
abortController = new AbortController();
|
|
782
795
|
}
|
|
783
796
|
}
|
|
797
|
+
const cleanup = async () => {
|
|
798
|
+
logger.debug("[Codex] Cleanup start");
|
|
799
|
+
await handleAbort();
|
|
800
|
+
logger.debug("[Codex] Cleanup completed");
|
|
801
|
+
try {
|
|
802
|
+
if (session) {
|
|
803
|
+
session.updateMetadata((currentMetadata) => ({
|
|
804
|
+
...currentMetadata,
|
|
805
|
+
lifecycleState: "archived",
|
|
806
|
+
lifecycleStateSince: Date.now(),
|
|
807
|
+
archivedBy: "cli",
|
|
808
|
+
archiveReason: "User terminated"
|
|
809
|
+
}));
|
|
810
|
+
session.sendSessionDeath();
|
|
811
|
+
await session.flush();
|
|
812
|
+
await session.close();
|
|
813
|
+
}
|
|
814
|
+
stopCaffeinate();
|
|
815
|
+
happyServer.stop();
|
|
816
|
+
logger.debug("[Codex] Cleanup complete, exiting");
|
|
817
|
+
process.exit(0);
|
|
818
|
+
} catch (error) {
|
|
819
|
+
logger.debug("[Codex] Error during cleanup:", error);
|
|
820
|
+
process.exit(1);
|
|
821
|
+
}
|
|
822
|
+
};
|
|
784
823
|
session.rpcHandlerManager.registerHandler("abort", handleAbort);
|
|
824
|
+
registerKillSessionHandler(session.rpcHandlerManager, cleanup);
|
|
785
825
|
const messageBuffer = new MessageBuffer();
|
|
786
826
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
787
827
|
let inkInstance = null;
|
|
@@ -829,7 +869,8 @@ async function runCodex(opts) {
|
|
|
829
869
|
return acc;
|
|
830
870
|
};
|
|
831
871
|
var collectFilesRecursive = collectFilesRecursive2;
|
|
832
|
-
const
|
|
872
|
+
const codexHomeDir = process.env.CODEX_HOME || join(os.homedir(), ".codex");
|
|
873
|
+
const rootDir = join(codexHomeDir, "sessions");
|
|
833
874
|
const candidates = collectFilesRecursive2(rootDir).filter((full) => full.endsWith(`-${sessionId}.jsonl`)).filter((full) => {
|
|
834
875
|
try {
|
|
835
876
|
return fs.statSync(full).isFile();
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var types = require('./types-
|
|
5
|
+
var types = require('./types-CQOz_mPp.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 node_crypto = require('node:crypto');
|
|
11
|
-
var index = require('./index-
|
|
11
|
+
var index = require('./index-ettJex_e.cjs');
|
|
12
12
|
var os = require('node:os');
|
|
13
13
|
var node_path = require('node:path');
|
|
14
14
|
var fs = require('node:fs');
|
|
@@ -32,6 +32,7 @@ require('node:readline');
|
|
|
32
32
|
require('node:url');
|
|
33
33
|
require('ps-list');
|
|
34
34
|
require('cross-spawn');
|
|
35
|
+
require('tmp');
|
|
35
36
|
require('qrcode-terminal');
|
|
36
37
|
require('open');
|
|
37
38
|
require('fastify');
|
|
@@ -681,6 +682,7 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit }) => {
|
|
|
681
682
|
async function runCodex(opts) {
|
|
682
683
|
const sessionTag = node_crypto.randomUUID();
|
|
683
684
|
const api = await types.ApiClient.create(opts.credentials);
|
|
685
|
+
types.logger.debug(`[codex] Starting with options: startedBy=${opts.startedBy || "terminal"}`);
|
|
684
686
|
const settings = await types.readSettings();
|
|
685
687
|
let machineId = settings?.machineId;
|
|
686
688
|
if (!machineId) {
|
|
@@ -705,9 +707,9 @@ async function runCodex(opts) {
|
|
|
705
707
|
happyHomeDir: types.configuration.happyHomeDir,
|
|
706
708
|
happyLibDir: types.projectPath(),
|
|
707
709
|
happyToolsDir: node_path.resolve(types.projectPath(), "tools", "unpacked"),
|
|
708
|
-
startedFromDaemon:
|
|
710
|
+
startedFromDaemon: opts.startedBy === "daemon",
|
|
709
711
|
hostPid: process.pid,
|
|
710
|
-
startedBy: "terminal",
|
|
712
|
+
startedBy: opts.startedBy || "terminal",
|
|
711
713
|
// Initialize lifecycle state
|
|
712
714
|
lifecycleState: "running",
|
|
713
715
|
lifecycleStateSince: Date.now(),
|
|
@@ -715,6 +717,17 @@ async function runCodex(opts) {
|
|
|
715
717
|
};
|
|
716
718
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
717
719
|
const session = api.sessionSyncClient(response);
|
|
720
|
+
try {
|
|
721
|
+
types.logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
722
|
+
const result = await index.notifyDaemonSessionStarted(response.id, metadata);
|
|
723
|
+
if (result.error) {
|
|
724
|
+
types.logger.debug(`[START] Failed to report to daemon (may not be running):`, result.error);
|
|
725
|
+
} else {
|
|
726
|
+
types.logger.debug(`[START] Reported session ${response.id} to daemon`);
|
|
727
|
+
}
|
|
728
|
+
} catch (error) {
|
|
729
|
+
types.logger.debug("[START] Failed to report to daemon (may not be running):", error);
|
|
730
|
+
}
|
|
718
731
|
const messageQueue = new index.MessageQueue2((mode) => index.hashObject({
|
|
719
732
|
permissionMode: mode.permissionMode,
|
|
720
733
|
model: mode.model
|
|
@@ -783,7 +796,34 @@ async function runCodex(opts) {
|
|
|
783
796
|
abortController = new AbortController();
|
|
784
797
|
}
|
|
785
798
|
}
|
|
799
|
+
const cleanup = async () => {
|
|
800
|
+
types.logger.debug("[Codex] Cleanup start");
|
|
801
|
+
await handleAbort();
|
|
802
|
+
types.logger.debug("[Codex] Cleanup completed");
|
|
803
|
+
try {
|
|
804
|
+
if (session) {
|
|
805
|
+
session.updateMetadata((currentMetadata) => ({
|
|
806
|
+
...currentMetadata,
|
|
807
|
+
lifecycleState: "archived",
|
|
808
|
+
lifecycleStateSince: Date.now(),
|
|
809
|
+
archivedBy: "cli",
|
|
810
|
+
archiveReason: "User terminated"
|
|
811
|
+
}));
|
|
812
|
+
session.sendSessionDeath();
|
|
813
|
+
await session.flush();
|
|
814
|
+
await session.close();
|
|
815
|
+
}
|
|
816
|
+
index.stopCaffeinate();
|
|
817
|
+
happyServer.stop();
|
|
818
|
+
types.logger.debug("[Codex] Cleanup complete, exiting");
|
|
819
|
+
process.exit(0);
|
|
820
|
+
} catch (error) {
|
|
821
|
+
types.logger.debug("[Codex] Error during cleanup:", error);
|
|
822
|
+
process.exit(1);
|
|
823
|
+
}
|
|
824
|
+
};
|
|
786
825
|
session.rpcHandlerManager.registerHandler("abort", handleAbort);
|
|
826
|
+
index.registerKillSessionHandler(session.rpcHandlerManager, cleanup);
|
|
787
827
|
const messageBuffer = new index.MessageBuffer();
|
|
788
828
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
789
829
|
let inkInstance = null;
|
|
@@ -831,7 +871,8 @@ async function runCodex(opts) {
|
|
|
831
871
|
return acc;
|
|
832
872
|
};
|
|
833
873
|
var collectFilesRecursive = collectFilesRecursive2;
|
|
834
|
-
const
|
|
874
|
+
const codexHomeDir = process.env.CODEX_HOME || node_path.join(os.homedir(), ".codex");
|
|
875
|
+
const rootDir = node_path.join(codexHomeDir, "sessions");
|
|
835
876
|
const candidates = collectFilesRecursive2(rootDir).filter((full) => full.endsWith(`-${sessionId}.jsonl`)).filter((full) => {
|
|
836
877
|
try {
|
|
837
878
|
return fs.statSync(full).isFile();
|
|
@@ -21,7 +21,7 @@ import { platform } from 'os';
|
|
|
21
21
|
import { Expo } from 'expo-server-sdk';
|
|
22
22
|
|
|
23
23
|
var name = "happy-coder";
|
|
24
|
-
var version = "0.10.0
|
|
24
|
+
var version = "0.10.0";
|
|
25
25
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
26
26
|
var author = "Kirill Dubovitskiy";
|
|
27
27
|
var license = "MIT";
|
|
@@ -99,6 +99,7 @@ var dependencies = {
|
|
|
99
99
|
"@types/ps-list": "^6.2.1",
|
|
100
100
|
"@types/qrcode-terminal": "^0.12.2",
|
|
101
101
|
"@types/react": "^19.1.9",
|
|
102
|
+
"@types/tmp": "^0.2.6",
|
|
102
103
|
axios: "^1.10.0",
|
|
103
104
|
chalk: "^5.4.1",
|
|
104
105
|
"cross-spawn": "^7.0.6",
|
|
@@ -114,6 +115,7 @@ var dependencies = {
|
|
|
114
115
|
react: "^19.1.1",
|
|
115
116
|
"socket.io-client": "^4.8.1",
|
|
116
117
|
tar: "^7.4.3",
|
|
118
|
+
tmp: "^0.2.5",
|
|
117
119
|
tweetnacl: "^1.0.3",
|
|
118
120
|
zod: "^3.23.8"
|
|
119
121
|
};
|
|
@@ -1627,11 +1629,12 @@ class ApiMachineClient {
|
|
|
1627
1629
|
requestShutdown
|
|
1628
1630
|
}) {
|
|
1629
1631
|
this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
|
|
1630
|
-
const { directory, sessionId, machineId, approvedNewDirectoryCreation } = params || {};
|
|
1632
|
+
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token } = params || {};
|
|
1633
|
+
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
|
|
1631
1634
|
if (!directory) {
|
|
1632
1635
|
throw new Error("Directory is required");
|
|
1633
1636
|
}
|
|
1634
|
-
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation });
|
|
1637
|
+
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token });
|
|
1635
1638
|
switch (result.type) {
|
|
1636
1639
|
case "success":
|
|
1637
1640
|
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
|
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
|
|
|
42
42
|
var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
43
43
|
|
|
44
44
|
var name = "happy-coder";
|
|
45
|
-
var version = "0.10.0
|
|
45
|
+
var version = "0.10.0";
|
|
46
46
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
47
47
|
var author = "Kirill Dubovitskiy";
|
|
48
48
|
var license = "MIT";
|
|
@@ -120,6 +120,7 @@ var dependencies = {
|
|
|
120
120
|
"@types/ps-list": "^6.2.1",
|
|
121
121
|
"@types/qrcode-terminal": "^0.12.2",
|
|
122
122
|
"@types/react": "^19.1.9",
|
|
123
|
+
"@types/tmp": "^0.2.6",
|
|
123
124
|
axios: "^1.10.0",
|
|
124
125
|
chalk: "^5.4.1",
|
|
125
126
|
"cross-spawn": "^7.0.6",
|
|
@@ -135,6 +136,7 @@ var dependencies = {
|
|
|
135
136
|
react: "^19.1.1",
|
|
136
137
|
"socket.io-client": "^4.8.1",
|
|
137
138
|
tar: "^7.4.3",
|
|
139
|
+
tmp: "^0.2.5",
|
|
138
140
|
tweetnacl: "^1.0.3",
|
|
139
141
|
zod: "^3.23.8"
|
|
140
142
|
};
|
|
@@ -1015,7 +1017,7 @@ class RpcHandlerManager {
|
|
|
1015
1017
|
}
|
|
1016
1018
|
}
|
|
1017
1019
|
|
|
1018
|
-
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-
|
|
1020
|
+
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-CQOz_mPp.cjs', document.baseURI).href))));
|
|
1019
1021
|
function projectPath() {
|
|
1020
1022
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1021
1023
|
return path$1;
|
|
@@ -1648,11 +1650,12 @@ class ApiMachineClient {
|
|
|
1648
1650
|
requestShutdown
|
|
1649
1651
|
}) {
|
|
1650
1652
|
this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
|
|
1651
|
-
const { directory, sessionId, machineId, approvedNewDirectoryCreation } = params || {};
|
|
1653
|
+
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token } = params || {};
|
|
1654
|
+
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
|
|
1652
1655
|
if (!directory) {
|
|
1653
1656
|
throw new Error("Directory is required");
|
|
1654
1657
|
}
|
|
1655
|
-
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation });
|
|
1658
|
+
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token });
|
|
1656
1659
|
switch (result.type) {
|
|
1657
1660
|
case "success":
|
|
1658
1661
|
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "happy-coder",
|
|
3
|
-
"version": "0.10.0
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Mobile and Web client for Claude Code and Codex",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"@types/ps-list": "^6.2.1",
|
|
79
79
|
"@types/qrcode-terminal": "^0.12.2",
|
|
80
80
|
"@types/react": "^19.1.9",
|
|
81
|
+
"@types/tmp": "^0.2.6",
|
|
81
82
|
"axios": "^1.10.0",
|
|
82
83
|
"chalk": "^5.4.1",
|
|
83
84
|
"cross-spawn": "^7.0.6",
|
|
@@ -93,6 +94,7 @@
|
|
|
93
94
|
"react": "^19.1.1",
|
|
94
95
|
"socket.io-client": "^4.8.1",
|
|
95
96
|
"tar": "^7.4.3",
|
|
97
|
+
"tmp": "^0.2.5",
|
|
96
98
|
"tweetnacl": "^1.0.3",
|
|
97
99
|
"zod": "^3.23.8"
|
|
98
100
|
},
|