very-happy-cli 0.2.136 → 0.2.138
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/{AcpBackend-CRzu0_1Z.cjs → AcpBackend-BUoDXZnv.cjs} +2 -2
- package/dist/{AcpBackend-C142vP3p.mjs → AcpBackend-bqVGMkPh.mjs} +2 -2
- package/dist/{AcpSessionManager-CosTbAlR.mjs → AcpSessionManager-BBAQ8EQf.mjs} +1 -1
- package/dist/{AcpSessionManager-Ba6WMLXc.cjs → AcpSessionManager-DmmA52Ep.cjs} +1 -1
- package/dist/{agentGuidance-6yh_wPwD.cjs → agentGuidance-4HV-BOge.cjs} +1 -1
- package/dist/{agentGuidance-ASxKHxBP.mjs → agentGuidance-WHZsBKpm.mjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-VqHQ67d8.mjs → config-BRXqgJJj.mjs} +4 -4
- package/dist/{config--cxxmkOd.cjs → config-DpuZN2Rs.cjs} +4 -4
- package/dist/{index-BPVQFcKW.cjs → index-3N-qu-RG.cjs} +6 -6
- package/dist/{index-BqbtKX0T.cjs → index-CHP265gs.cjs} +4 -4
- package/dist/{index-8bwU9d-4.cjs → index-CRRK5P1r.cjs} +115 -23
- package/dist/{index-vN4Xf0zB.mjs → index-D8Q3OhdR.mjs} +4 -4
- package/dist/{index-D3vlFjXy.mjs → index-DQe7ljLR.mjs} +7 -7
- package/dist/{index-CHI7iTa0.mjs → index-Dbl5U_N0.mjs} +111 -19
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-2POBqVlu.cjs → installTerminalHooks-CWGkoWDD.cjs} +4 -4
- package/dist/{installTerminalHooks-D0YRu_p-.mjs → installTerminalHooks-DfUGgeyb.mjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.mjs +2 -2
- package/dist/{limits-DRrdJ7gr.cjs → limits-CfzVummd.cjs} +7 -7
- package/dist/{limits-kjHZUlSp.mjs → limits-DEsg_gHi.mjs} +7 -7
- package/dist/{mcp-C1JQsM1s.cjs → mcp-CN2UVfut.cjs} +4 -4
- package/dist/{mcp-CgjEHlky.mjs → mcp-UnjB3I8_.mjs} +4 -4
- package/dist/{runGemini-B9Rc-H0G.cjs → runGemini-BUVjTJKn.cjs} +6 -6
- package/dist/{runGemini-DufGnnl2.mjs → runGemini-BZ0xXRj-.mjs} +6 -6
- package/dist/{runOpenClaw-DAl2nnjB.mjs → runOpenClaw-BcUmnBpW.mjs} +5 -5
- package/dist/{runOpenClaw-BsRRKDvF.cjs → runOpenClaw-Bj2EgRHB.cjs} +5 -5
- package/dist/{send-DP6n2J9x.cjs → send-BkypdBpK.cjs} +4 -4
- package/dist/{send-BHquPaeG.mjs → send-snK_NGAA.mjs} +4 -4
- package/dist/{sessions-Q4BR02dG.cjs → sessions-9A-uoJL_.cjs} +4 -4
- package/dist/{sessions-BtrLzv5U.mjs → sessions-DxlC4C4g.mjs} +4 -4
- package/dist/{spawn-CMjhlwlD.cjs → spawn-BORLpj60.cjs} +4 -4
- package/dist/{spawn-DuQXydqI.mjs → spawn-DFfHCafP.mjs} +4 -4
- package/dist/{teams-CkdUH10-.cjs → teams-9x2FO9RW.cjs} +4 -4
- package/dist/{teams-D5HxnyaW.mjs → teams-Cfr-2Yd-.mjs} +4 -4
- package/dist/{todo-BiLIZH4t.mjs → todo-CU5cjQZU.mjs} +3 -3
- package/dist/{todo-CaYedmtq.cjs → todo-DydKcknX.cjs} +3 -3
- package/dist/{types-DbBPNIwf.cjs → types-CRxf_3n8.cjs} +78 -6
- package/dist/{types-BKrZubg8.mjs → types-D5EsIAOe.mjs} +77 -5
- package/package.json +7 -7
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var persistence = require('./limits-
|
|
7
|
-
var index = require('./index-
|
|
6
|
+
var persistence = require('./limits-CfzVummd.cjs');
|
|
7
|
+
var index = require('./index-CRRK5P1r.cjs');
|
|
8
8
|
require('node:fs/promises');
|
|
9
9
|
require('node:os');
|
|
10
10
|
require('zod');
|
|
11
11
|
require('node:crypto');
|
|
12
12
|
require('tweetnacl');
|
|
13
13
|
require('node:util');
|
|
14
|
-
require('./types-
|
|
14
|
+
require('./types-CRxf_3n8.cjs');
|
|
15
15
|
require('axios');
|
|
16
16
|
require('node:events');
|
|
17
17
|
require('socket.io-client');
|
|
@@ -30,7 +30,7 @@ require('fs');
|
|
|
30
30
|
require('node:readline');
|
|
31
31
|
require('@anthropic-ai/sandbox-runtime');
|
|
32
32
|
require('expo-server-sdk');
|
|
33
|
-
require('./agentGuidance-
|
|
33
|
+
require('./agentGuidance-4HV-BOge.cjs');
|
|
34
34
|
require('ink');
|
|
35
35
|
require('react');
|
|
36
36
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { r as readPersistedSessions, c as configuration } from './limits-
|
|
5
|
-
import { d as sendUserMessage, a as sessionWebUrl } from './index-
|
|
4
|
+
import { r as readPersistedSessions, c as configuration } from './limits-DEsg_gHi.mjs';
|
|
5
|
+
import { d as sendUserMessage, a as sessionWebUrl } from './index-Dbl5U_N0.mjs';
|
|
6
6
|
import 'node:fs/promises';
|
|
7
7
|
import 'node:os';
|
|
8
8
|
import 'zod';
|
|
9
9
|
import 'node:crypto';
|
|
10
10
|
import 'tweetnacl';
|
|
11
11
|
import 'node:util';
|
|
12
|
-
import './types-
|
|
12
|
+
import './types-D5EsIAOe.mjs';
|
|
13
13
|
import 'axios';
|
|
14
14
|
import 'node:events';
|
|
15
15
|
import 'socket.io-client';
|
|
@@ -28,7 +28,7 @@ import 'fs';
|
|
|
28
28
|
import 'node:readline';
|
|
29
29
|
import '@anthropic-ai/sandbox-runtime';
|
|
30
30
|
import 'expo-server-sdk';
|
|
31
|
-
import './agentGuidance-
|
|
31
|
+
import './agentGuidance-WHZsBKpm.mjs';
|
|
32
32
|
import 'ink';
|
|
33
33
|
import 'react';
|
|
34
34
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var index = require('./index-
|
|
5
|
-
var api = require('./types-
|
|
4
|
+
var index = require('./index-CRRK5P1r.cjs');
|
|
5
|
+
var api = require('./types-CRxf_3n8.cjs');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./limits-
|
|
8
|
+
require('./limits-CfzVummd.cjs');
|
|
9
9
|
require('node:fs/promises');
|
|
10
10
|
require('node:fs');
|
|
11
11
|
require('node:path');
|
|
@@ -14,7 +14,7 @@ require('tweetnacl');
|
|
|
14
14
|
require('node:util');
|
|
15
15
|
require('cross-spawn');
|
|
16
16
|
require('node:readline');
|
|
17
|
-
require('./agentGuidance-
|
|
17
|
+
require('./agentGuidance-4HV-BOge.cjs');
|
|
18
18
|
require('fs/promises');
|
|
19
19
|
require('ink');
|
|
20
20
|
require('react');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, e as listSessions, r as readSessionTranscript, f as stopSession, g as resolvePermissionRequest, h as archiveSession } from './index-
|
|
3
|
-
import { i as isValidSessionId } from './types-
|
|
2
|
+
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, e as listSessions, r as readSessionTranscript, f as stopSession, g as resolvePermissionRequest, h as archiveSession } from './index-Dbl5U_N0.mjs';
|
|
3
|
+
import { i as isValidSessionId } from './types-D5EsIAOe.mjs';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './limits-
|
|
6
|
+
import './limits-DEsg_gHi.mjs';
|
|
7
7
|
import 'node:fs/promises';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'node:path';
|
|
@@ -12,7 +12,7 @@ import 'tweetnacl';
|
|
|
12
12
|
import 'node:util';
|
|
13
13
|
import 'cross-spawn';
|
|
14
14
|
import 'node:readline';
|
|
15
|
-
import './agentGuidance-
|
|
15
|
+
import './agentGuidance-WHZsBKpm.mjs';
|
|
16
16
|
import 'fs/promises';
|
|
17
17
|
import 'ink';
|
|
18
18
|
import 'react';
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var persistence = require('./limits-
|
|
6
|
+
var index = require('./index-CRRK5P1r.cjs');
|
|
7
|
+
var persistence = require('./limits-CfzVummd.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
|
-
require('./types-
|
|
10
|
+
require('./types-CRxf_3n8.cjs');
|
|
11
11
|
require('axios');
|
|
12
12
|
require('node:events');
|
|
13
13
|
require('socket.io-client');
|
|
@@ -29,7 +29,7 @@ require('tweetnacl');
|
|
|
29
29
|
require('node:readline');
|
|
30
30
|
require('@anthropic-ai/sandbox-runtime');
|
|
31
31
|
require('expo-server-sdk');
|
|
32
|
-
require('./agentGuidance-
|
|
32
|
+
require('./agentGuidance-4HV-BOge.cjs');
|
|
33
33
|
require('ink');
|
|
34
34
|
require('react');
|
|
35
35
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS, w as waitForSessionKey, d as sendUserMessage } from './index-
|
|
5
|
-
import { l as logger } from './limits-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS, w as waitForSessionKey, d as sendUserMessage } from './index-Dbl5U_N0.mjs';
|
|
5
|
+
import { l as logger } from './limits-DEsg_gHi.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
|
-
import './types-
|
|
8
|
+
import './types-D5EsIAOe.mjs';
|
|
9
9
|
import 'axios';
|
|
10
10
|
import 'node:events';
|
|
11
11
|
import 'socket.io-client';
|
|
@@ -27,7 +27,7 @@ import 'tweetnacl';
|
|
|
27
27
|
import 'node:readline';
|
|
28
28
|
import '@anthropic-ai/sandbox-runtime';
|
|
29
29
|
import 'expo-server-sdk';
|
|
30
|
-
import './agentGuidance-
|
|
30
|
+
import './agentGuidance-WHZsBKpm.mjs';
|
|
31
31
|
import 'ink';
|
|
32
32
|
import 'react';
|
|
33
33
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -4,15 +4,15 @@ var os = require('node:os');
|
|
|
4
4
|
var promises = require('node:fs/promises');
|
|
5
5
|
var z = require('zod');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
|
-
var agentGuidance = require('./agentGuidance-
|
|
8
|
-
var persistence = require('./limits-
|
|
7
|
+
var agentGuidance = require('./agentGuidance-4HV-BOge.cjs');
|
|
8
|
+
var persistence = require('./limits-CfzVummd.cjs');
|
|
9
9
|
var path = require('node:path');
|
|
10
|
-
var index = require('./index-
|
|
10
|
+
var index = require('./index-CRRK5P1r.cjs');
|
|
11
11
|
require('node:fs');
|
|
12
12
|
require('tweetnacl');
|
|
13
13
|
require('chalk');
|
|
14
14
|
require('node:util');
|
|
15
|
-
require('./types-
|
|
15
|
+
require('./types-CRxf_3n8.cjs');
|
|
16
16
|
require('axios');
|
|
17
17
|
require('node:events');
|
|
18
18
|
require('socket.io-client');
|
|
@@ -2,15 +2,15 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { unlink, rmdir, mkdir, lstat, readFile, writeFile, rename } from 'node:fs/promises';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { createHash, randomUUID } from 'node:crypto';
|
|
5
|
-
import { d as teamRequest, e as createTeamsClient } from './agentGuidance-
|
|
6
|
-
import { d as readCredentialsForConfiguredRelay } from './limits-
|
|
5
|
+
import { d as teamRequest, e as createTeamsClient } from './agentGuidance-WHZsBKpm.mjs';
|
|
6
|
+
import { d as readCredentialsForConfiguredRelay } from './limits-DEsg_gHi.mjs';
|
|
7
7
|
import { join, resolve, dirname } from 'node:path';
|
|
8
|
-
import { T as TEAM_SKILL } from './index-
|
|
8
|
+
import { T as TEAM_SKILL } from './index-Dbl5U_N0.mjs';
|
|
9
9
|
import 'node:fs';
|
|
10
10
|
import 'tweetnacl';
|
|
11
11
|
import 'chalk';
|
|
12
12
|
import 'node:util';
|
|
13
|
-
import './types-
|
|
13
|
+
import './types-D5EsIAOe.mjs';
|
|
14
14
|
import 'axios';
|
|
15
15
|
import 'node:events';
|
|
16
16
|
import 'socket.io-client';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as readCredentialsForConfiguredRelay, c as configuration } from './limits-
|
|
2
|
-
import { b as createBuiltinTodoClient, B as BUILTIN_TODO_SKILL } from './types-
|
|
3
|
-
import { c as readTeamScope, t as teamScopePath } from './agentGuidance-
|
|
1
|
+
import { d as readCredentialsForConfiguredRelay, c as configuration } from './limits-DEsg_gHi.mjs';
|
|
2
|
+
import { b as createBuiltinTodoClient, B as BUILTIN_TODO_SKILL } from './types-D5EsIAOe.mjs';
|
|
3
|
+
import { c as readTeamScope, t as teamScopePath } from './agentGuidance-WHZsBKpm.mjs';
|
|
4
4
|
import 'node:fs/promises';
|
|
5
5
|
import 'node:fs';
|
|
6
6
|
import 'node:os';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./limits-
|
|
4
|
-
var api = require('./types-
|
|
5
|
-
var agentGuidance = require('./agentGuidance-
|
|
3
|
+
var persistence = require('./limits-CfzVummd.cjs');
|
|
4
|
+
var api = require('./types-CRxf_3n8.cjs');
|
|
5
|
+
var agentGuidance = require('./agentGuidance-4HV-BOge.cjs');
|
|
6
6
|
require('node:fs/promises');
|
|
7
7
|
require('node:fs');
|
|
8
8
|
require('node:os');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var axios = require('axios');
|
|
4
|
-
var persistence = require('./limits-
|
|
4
|
+
var persistence = require('./limits-CfzVummd.cjs');
|
|
5
5
|
var node_events = require('node:events');
|
|
6
6
|
var socket_ioClient = require('socket.io-client');
|
|
7
7
|
var z = require('zod');
|
|
@@ -1369,7 +1369,7 @@ class RpcHandlerManager {
|
|
|
1369
1369
|
}
|
|
1370
1370
|
}
|
|
1371
1371
|
|
|
1372
|
-
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-
|
|
1372
|
+
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-CRxf_3n8.cjs', document.baseURI).href))));
|
|
1373
1373
|
function projectPath() {
|
|
1374
1374
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1375
1375
|
return path$1;
|
|
@@ -3050,10 +3050,14 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3050
3050
|
return;
|
|
3051
3051
|
}
|
|
3052
3052
|
const localId = data.body.message.localId;
|
|
3053
|
-
|
|
3053
|
+
const relayAccepted = !!localId && this.directInboundLocalIds.delete(localId);
|
|
3054
|
+
if (localId && this.routedInboundLocalIds.has(localId)) {
|
|
3054
3055
|
this.lastSeq = messageSeq;
|
|
3055
3056
|
return;
|
|
3056
3057
|
}
|
|
3058
|
+
if (relayAccepted) {
|
|
3059
|
+
persistence.logger.debug(`[API] Routing relay-accepted message ${localId} from the central echo (own persist still pending or failed)`);
|
|
3060
|
+
}
|
|
3057
3061
|
const body = persistence.decrypt(this.encryptionKey, this.encryptionVariant, persistence.decodeBase64(data.body.message.content.c));
|
|
3058
3062
|
persistence.logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
|
|
3059
3063
|
this.routeIncomingMessage(body, localId);
|
|
@@ -3306,6 +3310,13 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3306
3310
|
}
|
|
3307
3311
|
return;
|
|
3308
3312
|
}
|
|
3313
|
+
const role = typeof message === "object" && message !== null ? message.role : void 0;
|
|
3314
|
+
if (role === "user") {
|
|
3315
|
+
persistence.logger.debug("[API] Inbound user-role message did not match UserMessageSchema; forwarding as generic message", {
|
|
3316
|
+
sourceLocalId: sourceLocalId ?? null,
|
|
3317
|
+
issues: userResult.error.issues.slice(0, 5).map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3309
3320
|
this.emit("message", message);
|
|
3310
3321
|
}
|
|
3311
3322
|
async fetchMessages() {
|
|
@@ -3334,12 +3345,13 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3334
3345
|
maxSeq = message.seq;
|
|
3335
3346
|
}
|
|
3336
3347
|
if (skipRouting) continue;
|
|
3337
|
-
|
|
3338
|
-
continue;
|
|
3339
|
-
}
|
|
3348
|
+
const relayAccepted = !!message.localId && this.directInboundLocalIds.delete(message.localId);
|
|
3340
3349
|
if (message.localId && this.routedInboundLocalIds.has(message.localId)) {
|
|
3341
3350
|
continue;
|
|
3342
3351
|
}
|
|
3352
|
+
if (relayAccepted) {
|
|
3353
|
+
persistence.logger.debug(`[API] Routing relay-accepted message ${message.localId} from catch-up fetch (own persist still pending or failed)`);
|
|
3354
|
+
}
|
|
3343
3355
|
if (message.content?.t !== "encrypted") {
|
|
3344
3356
|
continue;
|
|
3345
3357
|
}
|
|
@@ -3471,6 +3483,8 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3471
3483
|
}
|
|
3472
3484
|
callback({ ok: true, messages: stored });
|
|
3473
3485
|
} catch (error) {
|
|
3486
|
+
const routed = batch.filter((item) => this.routedInboundLocalIds.has(item.localId)).length;
|
|
3487
|
+
persistence.logger.debug(`[API] Relay-delivered persist failed for ${batch.length} message(s) (${routed} already routed via central echo): ${error instanceof Error ? error.message : error}`);
|
|
3474
3488
|
for (const item of batch) this.directInboundLocalIds.delete(item.localId);
|
|
3475
3489
|
callback({ ok: false, error: error instanceof Error ? error.message : "Failed to persist session messages" });
|
|
3476
3490
|
}
|
|
@@ -12966,6 +12980,9 @@ class CodexAppServerClient {
|
|
|
12966
12980
|
// Tracks in-flight interruptTurn() RPCs so sendTurnAndWait can wait for them
|
|
12967
12981
|
// before starting a new turn (prevents stale turn/interrupt from aborting the next turn).
|
|
12968
12982
|
pendingInterrupt = null;
|
|
12983
|
+
// In-flight idle release (B-461); ensureConnected() waits for it so a message
|
|
12984
|
+
// arriving mid-release cannot spawn a second app-server against a dying one.
|
|
12985
|
+
idleRelease = null;
|
|
12969
12986
|
notificationProtocol = "unknown";
|
|
12970
12987
|
completedTurnIds = /* @__PURE__ */ new Set();
|
|
12971
12988
|
rawFileChangesByItemId = /* @__PURE__ */ new Map();
|
|
@@ -13299,6 +13316,53 @@ class CodexAppServerClient {
|
|
|
13299
13316
|
async disconnect() {
|
|
13300
13317
|
await this.disconnectInternal();
|
|
13301
13318
|
}
|
|
13319
|
+
/** True while an app-server child process is owned by this client. */
|
|
13320
|
+
get hasProcess() {
|
|
13321
|
+
return this.process !== null;
|
|
13322
|
+
}
|
|
13323
|
+
/**
|
|
13324
|
+
* Drop the app-server process while the session is idle, keeping the thread
|
|
13325
|
+
* id and defaults so the next turn can `thread/resume` it (B-461). Refuses —
|
|
13326
|
+
* returning false — whenever anything is still in flight: an active turn, a
|
|
13327
|
+
* pending interrupt, or any outstanding RPC. See codexIdleRelease.ts.
|
|
13328
|
+
*/
|
|
13329
|
+
async releaseIdleProcess() {
|
|
13330
|
+
if (this.idleRelease) return this.idleRelease;
|
|
13331
|
+
if (!this.connected && !this.process) return false;
|
|
13332
|
+
if (this.pendingTurnCompletion || this.pendingInterrupt || this.pending.size > 0) {
|
|
13333
|
+
persistence.logger.debug("[CodexAppServer] Idle release skipped: work still in flight");
|
|
13334
|
+
return false;
|
|
13335
|
+
}
|
|
13336
|
+
const run = (async () => {
|
|
13337
|
+
const threadId = this._threadId;
|
|
13338
|
+
persistence.logger.debug(`[CodexAppServer] Releasing idle app-server; thread=${threadId ?? "none"} kept for resume`);
|
|
13339
|
+
await this.disconnectInternal({ preserveThreadState: !!threadId });
|
|
13340
|
+
return true;
|
|
13341
|
+
})();
|
|
13342
|
+
this.idleRelease = run;
|
|
13343
|
+
try {
|
|
13344
|
+
return await run;
|
|
13345
|
+
} finally {
|
|
13346
|
+
if (this.idleRelease === run) this.idleRelease = null;
|
|
13347
|
+
}
|
|
13348
|
+
}
|
|
13349
|
+
/**
|
|
13350
|
+
* Make sure an app-server is running and, if a thread is remembered, resumed
|
|
13351
|
+
* in it. Cheap no-op while connected. Covers both the idle release above and
|
|
13352
|
+
* an app-server that exited on its own between turns.
|
|
13353
|
+
*/
|
|
13354
|
+
async ensureConnected() {
|
|
13355
|
+
if (this.idleRelease) await this.idleRelease;
|
|
13356
|
+
if (this.connected) return;
|
|
13357
|
+
const threadId = this._threadId;
|
|
13358
|
+
if (this.process) {
|
|
13359
|
+
await this.disconnectInternal({ preserveThreadState: !!threadId });
|
|
13360
|
+
}
|
|
13361
|
+
await this.connect();
|
|
13362
|
+
if (threadId) {
|
|
13363
|
+
await this.resumeThread({ threadId });
|
|
13364
|
+
}
|
|
13365
|
+
}
|
|
13302
13366
|
buildThreadConfig(mcpServers) {
|
|
13303
13367
|
return mcpServers ? { mcp_servers: mcpServers } : null;
|
|
13304
13368
|
}
|
|
@@ -13313,6 +13377,7 @@ class CodexAppServerClient {
|
|
|
13313
13377
|
}
|
|
13314
13378
|
// ─── Thread management ──────────────────────────────────────
|
|
13315
13379
|
async startThread(opts) {
|
|
13380
|
+
await this.ensureConnected();
|
|
13316
13381
|
const params = {
|
|
13317
13382
|
model: opts.model ?? null,
|
|
13318
13383
|
modelProvider: null,
|
|
@@ -13340,6 +13405,7 @@ class CodexAppServerClient {
|
|
|
13340
13405
|
if (!threadId) {
|
|
13341
13406
|
throw new Error("No thread available to resume.");
|
|
13342
13407
|
}
|
|
13408
|
+
await this.ensureConnected();
|
|
13343
13409
|
const defaults = this.threadDefaults ?? {};
|
|
13344
13410
|
const params = {
|
|
13345
13411
|
threadId,
|
|
@@ -13367,6 +13433,7 @@ class CodexAppServerClient {
|
|
|
13367
13433
|
return { threadId: result.thread.id, model: result.model };
|
|
13368
13434
|
}
|
|
13369
13435
|
async forkThread(opts) {
|
|
13436
|
+
await this.ensureConnected();
|
|
13370
13437
|
const defaults = this.threadDefaults ?? {};
|
|
13371
13438
|
const params = {
|
|
13372
13439
|
threadId: opts.threadId,
|
|
@@ -13395,6 +13462,7 @@ class CodexAppServerClient {
|
|
|
13395
13462
|
return { threadId: result.thread.id, model: result.model, thread: result.thread };
|
|
13396
13463
|
}
|
|
13397
13464
|
async readThread(opts) {
|
|
13465
|
+
await this.ensureConnected();
|
|
13398
13466
|
const params = {
|
|
13399
13467
|
threadId: opts.threadId,
|
|
13400
13468
|
includeTurns: opts.includeTurns ?? true
|
|
@@ -13402,6 +13470,7 @@ class CodexAppServerClient {
|
|
|
13402
13470
|
return await this.request("thread/read", params);
|
|
13403
13471
|
}
|
|
13404
13472
|
async rollbackThread(opts) {
|
|
13473
|
+
await this.ensureConnected();
|
|
13405
13474
|
const params = {
|
|
13406
13475
|
threadId: opts.threadId,
|
|
13407
13476
|
numTurns: opts.numTurns
|
|
@@ -13409,6 +13478,7 @@ class CodexAppServerClient {
|
|
|
13409
13478
|
return await this.request("thread/rollback", params);
|
|
13410
13479
|
}
|
|
13411
13480
|
async injectItems(opts) {
|
|
13481
|
+
await this.ensureConnected();
|
|
13412
13482
|
const params = {
|
|
13413
13483
|
threadId: opts.threadId,
|
|
13414
13484
|
items: opts.items
|
|
@@ -13513,6 +13583,7 @@ class CodexAppServerClient {
|
|
|
13513
13583
|
if (!this._threadId) {
|
|
13514
13584
|
throw new Error("No active thread. Call startThread first.");
|
|
13515
13585
|
}
|
|
13586
|
+
await this.ensureConnected();
|
|
13516
13587
|
const input = [
|
|
13517
13588
|
{ type: "text", text: prompt },
|
|
13518
13589
|
...(opts?.images ?? []).map((path) => ({ type: "localImage", path }))
|
|
@@ -13558,6 +13629,7 @@ class CodexAppServerClient {
|
|
|
13558
13629
|
await this.pendingInterrupt;
|
|
13559
13630
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13560
13631
|
}
|
|
13632
|
+
await this.ensureConnected();
|
|
13561
13633
|
const timeoutMs = opts?.turnTimeoutMs ?? CodexAppServerClient.TURN_TIMEOUT_MS;
|
|
13562
13634
|
let timer = null;
|
|
13563
13635
|
const completion = new Promise((resolve) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import { l as logger, i as encodeBase64, j as encrypt, k as decrypt, m as decodeBase64, c as configuration, o as decryptBlob, q as prepareClipboardText, g as readSettings, r as readPersistedSessions, s as credentialRelayProblem, p as packageJson, t as readTrackedClaudeSessionIds, u as libsodiumEncryptForPublicKey, v as libsodiumPublicKeyFromSecretKey, x as getRandomBytes, y as redactLogValue } from './limits-
|
|
2
|
+
import { l as logger, i as encodeBase64, j as encrypt, k as decrypt, m as decodeBase64, c as configuration, o as decryptBlob, q as prepareClipboardText, g as readSettings, r as readPersistedSessions, s as credentialRelayProblem, p as packageJson, t as readTrackedClaudeSessionIds, u as libsodiumEncryptForPublicKey, v as libsodiumPublicKeyFromSecretKey, x as getRandomBytes, y as redactLogValue } from './limits-DEsg_gHi.mjs';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { io } from 'socket.io-client';
|
|
5
5
|
import * as z from 'zod';
|
|
@@ -3028,10 +3028,14 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3028
3028
|
return;
|
|
3029
3029
|
}
|
|
3030
3030
|
const localId = data.body.message.localId;
|
|
3031
|
-
|
|
3031
|
+
const relayAccepted = !!localId && this.directInboundLocalIds.delete(localId);
|
|
3032
|
+
if (localId && this.routedInboundLocalIds.has(localId)) {
|
|
3032
3033
|
this.lastSeq = messageSeq;
|
|
3033
3034
|
return;
|
|
3034
3035
|
}
|
|
3036
|
+
if (relayAccepted) {
|
|
3037
|
+
logger.debug(`[API] Routing relay-accepted message ${localId} from the central echo (own persist still pending or failed)`);
|
|
3038
|
+
}
|
|
3035
3039
|
const body = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.message.content.c));
|
|
3036
3040
|
logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
|
|
3037
3041
|
this.routeIncomingMessage(body, localId);
|
|
@@ -3284,6 +3288,13 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3284
3288
|
}
|
|
3285
3289
|
return;
|
|
3286
3290
|
}
|
|
3291
|
+
const role = typeof message === "object" && message !== null ? message.role : void 0;
|
|
3292
|
+
if (role === "user") {
|
|
3293
|
+
logger.debug("[API] Inbound user-role message did not match UserMessageSchema; forwarding as generic message", {
|
|
3294
|
+
sourceLocalId: sourceLocalId ?? null,
|
|
3295
|
+
issues: userResult.error.issues.slice(0, 5).map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
3296
|
+
});
|
|
3297
|
+
}
|
|
3287
3298
|
this.emit("message", message);
|
|
3288
3299
|
}
|
|
3289
3300
|
async fetchMessages() {
|
|
@@ -3312,12 +3323,13 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3312
3323
|
maxSeq = message.seq;
|
|
3313
3324
|
}
|
|
3314
3325
|
if (skipRouting) continue;
|
|
3315
|
-
|
|
3316
|
-
continue;
|
|
3317
|
-
}
|
|
3326
|
+
const relayAccepted = !!message.localId && this.directInboundLocalIds.delete(message.localId);
|
|
3318
3327
|
if (message.localId && this.routedInboundLocalIds.has(message.localId)) {
|
|
3319
3328
|
continue;
|
|
3320
3329
|
}
|
|
3330
|
+
if (relayAccepted) {
|
|
3331
|
+
logger.debug(`[API] Routing relay-accepted message ${message.localId} from catch-up fetch (own persist still pending or failed)`);
|
|
3332
|
+
}
|
|
3321
3333
|
if (message.content?.t !== "encrypted") {
|
|
3322
3334
|
continue;
|
|
3323
3335
|
}
|
|
@@ -3449,6 +3461,8 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3449
3461
|
}
|
|
3450
3462
|
callback({ ok: true, messages: stored });
|
|
3451
3463
|
} catch (error) {
|
|
3464
|
+
const routed = batch.filter((item) => this.routedInboundLocalIds.has(item.localId)).length;
|
|
3465
|
+
logger.debug(`[API] Relay-delivered persist failed for ${batch.length} message(s) (${routed} already routed via central echo): ${error instanceof Error ? error.message : error}`);
|
|
3452
3466
|
for (const item of batch) this.directInboundLocalIds.delete(item.localId);
|
|
3453
3467
|
callback({ ok: false, error: error instanceof Error ? error.message : "Failed to persist session messages" });
|
|
3454
3468
|
}
|
|
@@ -12944,6 +12958,9 @@ class CodexAppServerClient {
|
|
|
12944
12958
|
// Tracks in-flight interruptTurn() RPCs so sendTurnAndWait can wait for them
|
|
12945
12959
|
// before starting a new turn (prevents stale turn/interrupt from aborting the next turn).
|
|
12946
12960
|
pendingInterrupt = null;
|
|
12961
|
+
// In-flight idle release (B-461); ensureConnected() waits for it so a message
|
|
12962
|
+
// arriving mid-release cannot spawn a second app-server against a dying one.
|
|
12963
|
+
idleRelease = null;
|
|
12947
12964
|
notificationProtocol = "unknown";
|
|
12948
12965
|
completedTurnIds = /* @__PURE__ */ new Set();
|
|
12949
12966
|
rawFileChangesByItemId = /* @__PURE__ */ new Map();
|
|
@@ -13277,6 +13294,53 @@ class CodexAppServerClient {
|
|
|
13277
13294
|
async disconnect() {
|
|
13278
13295
|
await this.disconnectInternal();
|
|
13279
13296
|
}
|
|
13297
|
+
/** True while an app-server child process is owned by this client. */
|
|
13298
|
+
get hasProcess() {
|
|
13299
|
+
return this.process !== null;
|
|
13300
|
+
}
|
|
13301
|
+
/**
|
|
13302
|
+
* Drop the app-server process while the session is idle, keeping the thread
|
|
13303
|
+
* id and defaults so the next turn can `thread/resume` it (B-461). Refuses —
|
|
13304
|
+
* returning false — whenever anything is still in flight: an active turn, a
|
|
13305
|
+
* pending interrupt, or any outstanding RPC. See codexIdleRelease.ts.
|
|
13306
|
+
*/
|
|
13307
|
+
async releaseIdleProcess() {
|
|
13308
|
+
if (this.idleRelease) return this.idleRelease;
|
|
13309
|
+
if (!this.connected && !this.process) return false;
|
|
13310
|
+
if (this.pendingTurnCompletion || this.pendingInterrupt || this.pending.size > 0) {
|
|
13311
|
+
logger.debug("[CodexAppServer] Idle release skipped: work still in flight");
|
|
13312
|
+
return false;
|
|
13313
|
+
}
|
|
13314
|
+
const run = (async () => {
|
|
13315
|
+
const threadId = this._threadId;
|
|
13316
|
+
logger.debug(`[CodexAppServer] Releasing idle app-server; thread=${threadId ?? "none"} kept for resume`);
|
|
13317
|
+
await this.disconnectInternal({ preserveThreadState: !!threadId });
|
|
13318
|
+
return true;
|
|
13319
|
+
})();
|
|
13320
|
+
this.idleRelease = run;
|
|
13321
|
+
try {
|
|
13322
|
+
return await run;
|
|
13323
|
+
} finally {
|
|
13324
|
+
if (this.idleRelease === run) this.idleRelease = null;
|
|
13325
|
+
}
|
|
13326
|
+
}
|
|
13327
|
+
/**
|
|
13328
|
+
* Make sure an app-server is running and, if a thread is remembered, resumed
|
|
13329
|
+
* in it. Cheap no-op while connected. Covers both the idle release above and
|
|
13330
|
+
* an app-server that exited on its own between turns.
|
|
13331
|
+
*/
|
|
13332
|
+
async ensureConnected() {
|
|
13333
|
+
if (this.idleRelease) await this.idleRelease;
|
|
13334
|
+
if (this.connected) return;
|
|
13335
|
+
const threadId = this._threadId;
|
|
13336
|
+
if (this.process) {
|
|
13337
|
+
await this.disconnectInternal({ preserveThreadState: !!threadId });
|
|
13338
|
+
}
|
|
13339
|
+
await this.connect();
|
|
13340
|
+
if (threadId) {
|
|
13341
|
+
await this.resumeThread({ threadId });
|
|
13342
|
+
}
|
|
13343
|
+
}
|
|
13280
13344
|
buildThreadConfig(mcpServers) {
|
|
13281
13345
|
return mcpServers ? { mcp_servers: mcpServers } : null;
|
|
13282
13346
|
}
|
|
@@ -13291,6 +13355,7 @@ class CodexAppServerClient {
|
|
|
13291
13355
|
}
|
|
13292
13356
|
// ─── Thread management ──────────────────────────────────────
|
|
13293
13357
|
async startThread(opts) {
|
|
13358
|
+
await this.ensureConnected();
|
|
13294
13359
|
const params = {
|
|
13295
13360
|
model: opts.model ?? null,
|
|
13296
13361
|
modelProvider: null,
|
|
@@ -13318,6 +13383,7 @@ class CodexAppServerClient {
|
|
|
13318
13383
|
if (!threadId) {
|
|
13319
13384
|
throw new Error("No thread available to resume.");
|
|
13320
13385
|
}
|
|
13386
|
+
await this.ensureConnected();
|
|
13321
13387
|
const defaults = this.threadDefaults ?? {};
|
|
13322
13388
|
const params = {
|
|
13323
13389
|
threadId,
|
|
@@ -13345,6 +13411,7 @@ class CodexAppServerClient {
|
|
|
13345
13411
|
return { threadId: result.thread.id, model: result.model };
|
|
13346
13412
|
}
|
|
13347
13413
|
async forkThread(opts) {
|
|
13414
|
+
await this.ensureConnected();
|
|
13348
13415
|
const defaults = this.threadDefaults ?? {};
|
|
13349
13416
|
const params = {
|
|
13350
13417
|
threadId: opts.threadId,
|
|
@@ -13373,6 +13440,7 @@ class CodexAppServerClient {
|
|
|
13373
13440
|
return { threadId: result.thread.id, model: result.model, thread: result.thread };
|
|
13374
13441
|
}
|
|
13375
13442
|
async readThread(opts) {
|
|
13443
|
+
await this.ensureConnected();
|
|
13376
13444
|
const params = {
|
|
13377
13445
|
threadId: opts.threadId,
|
|
13378
13446
|
includeTurns: opts.includeTurns ?? true
|
|
@@ -13380,6 +13448,7 @@ class CodexAppServerClient {
|
|
|
13380
13448
|
return await this.request("thread/read", params);
|
|
13381
13449
|
}
|
|
13382
13450
|
async rollbackThread(opts) {
|
|
13451
|
+
await this.ensureConnected();
|
|
13383
13452
|
const params = {
|
|
13384
13453
|
threadId: opts.threadId,
|
|
13385
13454
|
numTurns: opts.numTurns
|
|
@@ -13387,6 +13456,7 @@ class CodexAppServerClient {
|
|
|
13387
13456
|
return await this.request("thread/rollback", params);
|
|
13388
13457
|
}
|
|
13389
13458
|
async injectItems(opts) {
|
|
13459
|
+
await this.ensureConnected();
|
|
13390
13460
|
const params = {
|
|
13391
13461
|
threadId: opts.threadId,
|
|
13392
13462
|
items: opts.items
|
|
@@ -13491,6 +13561,7 @@ class CodexAppServerClient {
|
|
|
13491
13561
|
if (!this._threadId) {
|
|
13492
13562
|
throw new Error("No active thread. Call startThread first.");
|
|
13493
13563
|
}
|
|
13564
|
+
await this.ensureConnected();
|
|
13494
13565
|
const input = [
|
|
13495
13566
|
{ type: "text", text: prompt },
|
|
13496
13567
|
...(opts?.images ?? []).map((path) => ({ type: "localImage", path }))
|
|
@@ -13536,6 +13607,7 @@ class CodexAppServerClient {
|
|
|
13536
13607
|
await this.pendingInterrupt;
|
|
13537
13608
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13538
13609
|
}
|
|
13610
|
+
await this.ensureConnected();
|
|
13539
13611
|
const timeoutMs = opts?.turnTimeoutMs ?? CodexAppServerClient.TURN_TIMEOUT_MS;
|
|
13540
13612
|
let timer = null;
|
|
13541
13613
|
const completion = new Promise((resolve) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.138",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.138",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.138",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.138",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.138",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.138",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.138"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|