happy-imou-cloud 2.0.8 → 2.0.10
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/{api-D-uiH_TF.mjs → api-BjxmW-0W.mjs} +2 -2
- package/dist/{api-CN-WqYd_.cjs → api-DUE5TJBE.cjs} +43 -43
- package/dist/{command-DGFsZx58.mjs → command-ComOeFLY.mjs} +3 -3
- package/dist/{command-DjIfRZQS.cjs → command-Df7u5eAT.cjs} +3 -3
- package/dist/{index-DM6z3aeG.cjs → index-Cuvfa15L.cjs} +808 -201
- package/dist/{index-DhheEtRl.mjs → index-CzvgPwr1.mjs} +732 -125
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{names-BjEof0E2.mjs → names-CicSgRNg.mjs} +2 -2
- package/dist/{names-BnV67N_O.cjs → names-yJNZoTv_.cjs} +4 -4
- package/dist/{persistence-DiNg1DPF.mjs → persistence-BxP6Jw1f.mjs} +1 -1
- package/dist/{persistence-DBGkO8gB.cjs → persistence-D7JtnrYA.cjs} +29 -29
- package/dist/{registerKillSessionHandler-Cu9rHGsI.mjs → registerKillSessionHandler-ARQrPvnT.mjs} +2 -2
- package/dist/{registerKillSessionHandler-CYc0SIjF.cjs → registerKillSessionHandler-DCMFiXyA.cjs} +2 -2
- package/dist/{runClaude-DAR_hw3C.mjs → runClaude-B_fTMxc4.mjs} +6 -15
- package/dist/{runClaude-CPhWaFrX.cjs → runClaude-C1W_Nw0C.cjs} +32 -41
- package/dist/{runCodex-B4QAb-Go.mjs → runCodex-CUgOiIEz.mjs} +12 -13
- package/dist/{runCodex--QLrOs8X.cjs → runCodex-D2VCWVEK.cjs} +12 -13
- package/dist/{runGemini-DqowSR2w.mjs → runGemini-2_FEtJYa.mjs} +7 -16
- package/dist/{runGemini-CDyhCucw.cjs → runGemini-CiGnjflq.cjs} +7 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./api-
|
|
5
|
-
require('./persistence-
|
|
4
|
+
require('./api-DUE5TJBE.cjs');
|
|
5
|
+
require('./persistence-D7JtnrYA.cjs');
|
|
6
6
|
require('zod');
|
|
7
|
-
require('./index-
|
|
7
|
+
require('./index-Cuvfa15L.cjs');
|
|
8
8
|
require('node:child_process');
|
|
9
9
|
require('node:fs');
|
|
10
10
|
require('cross-spawn');
|
|
@@ -16,8 +16,8 @@ require('path');
|
|
|
16
16
|
require('os');
|
|
17
17
|
require('child_process');
|
|
18
18
|
require('node:path');
|
|
19
|
-
require('axios');
|
|
20
19
|
require('node:os');
|
|
20
|
+
require('axios');
|
|
21
21
|
require('node:events');
|
|
22
22
|
require('socket.io-client');
|
|
23
23
|
require('tweetnacl');
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'chalk';
|
|
2
|
-
import './api-
|
|
3
|
-
import './persistence-
|
|
2
|
+
import './api-BjxmW-0W.mjs';
|
|
3
|
+
import './persistence-BxP6Jw1f.mjs';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import './index-
|
|
5
|
+
import './index-CzvgPwr1.mjs';
|
|
6
6
|
import 'node:child_process';
|
|
7
7
|
import 'node:fs';
|
|
8
8
|
import 'cross-spawn';
|
|
@@ -14,8 +14,8 @@ import 'path';
|
|
|
14
14
|
import 'os';
|
|
15
15
|
import 'child_process';
|
|
16
16
|
import 'node:path';
|
|
17
|
-
import 'axios';
|
|
18
17
|
import 'node:os';
|
|
18
|
+
import 'axios';
|
|
19
19
|
import 'node:events';
|
|
20
20
|
import 'socket.io-client';
|
|
21
21
|
import 'tweetnacl';
|
package/dist/lib.cjs
CHANGED
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-BjxmW-0W.mjs';
|
|
2
2
|
export { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
|
|
3
3
|
import 'axios';
|
|
4
4
|
import 'chalk';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-
|
|
4
|
-
import {
|
|
3
|
+
import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-BjxmW-0W.mjs';
|
|
4
|
+
import { d as projectPath } from './index-CzvgPwr1.mjs';
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
6
6
|
import { randomUUID } from 'node:crypto';
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var os = require('node:os');
|
|
4
|
-
var
|
|
5
|
-
var api = require('./api-
|
|
6
|
-
var index = require('./index-
|
|
4
|
+
var path = require('node:path');
|
|
5
|
+
var api = require('./api-DUE5TJBE.cjs');
|
|
6
|
+
var index = require('./index-Cuvfa15L.cjs');
|
|
7
7
|
var node_events = require('node:events');
|
|
8
8
|
var node_crypto = require('node:crypto');
|
|
9
9
|
|
|
@@ -20,7 +20,7 @@ function createSessionMetadata(opts) {
|
|
|
20
20
|
homeDir: os.homedir(),
|
|
21
21
|
happyHomeDir: api.configuration.happyCloudHomeDir,
|
|
22
22
|
happyLibDir: index.projectPath(),
|
|
23
|
-
happyToolsDir:
|
|
23
|
+
happyToolsDir: path.resolve(index.projectPath(), "tools", "unpacked"),
|
|
24
24
|
startedFromDaemon: opts.startedBy === "daemon",
|
|
25
25
|
hostPid: process.pid,
|
|
26
26
|
startedBy: opts.startedBy || "terminal",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { unlink, readFile, mkdir, open, stat, writeFile, rename } from 'node:fs/promises';
|
|
2
2
|
import { existsSync, unlinkSync, readdirSync, constants, writeFileSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { join, dirname } from 'node:path';
|
|
4
|
-
import { c as configuration, l as logger, e as encodeBase64 } from './api-
|
|
4
|
+
import { c as configuration, l as logger, e as encodeBase64 } from './api-BjxmW-0W.mjs';
|
|
5
5
|
import * as z from 'zod';
|
|
6
6
|
import 'axios';
|
|
7
7
|
import 'chalk';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var promises = require('node:fs/promises');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var api = require('./api-
|
|
4
|
+
var fs = require('node:fs');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var api = require('./api-DUE5TJBE.cjs');
|
|
7
7
|
var z = require('zod');
|
|
8
8
|
require('axios');
|
|
9
9
|
require('chalk');
|
|
@@ -186,7 +186,7 @@ function migrateSettings(raw, fromVersion) {
|
|
|
186
186
|
return migrated;
|
|
187
187
|
}
|
|
188
188
|
async function readSettings() {
|
|
189
|
-
if (!
|
|
189
|
+
if (!fs.existsSync(api.configuration.settingsFile)) {
|
|
190
190
|
return { ...defaultSettings };
|
|
191
191
|
}
|
|
192
192
|
try {
|
|
@@ -220,7 +220,7 @@ async function readSettings() {
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
async function writeSettings(settings) {
|
|
223
|
-
if (!
|
|
223
|
+
if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
|
|
224
224
|
await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
|
|
225
225
|
}
|
|
226
226
|
const settingsWithVersion = {
|
|
@@ -239,7 +239,7 @@ async function updateSettings(updater) {
|
|
|
239
239
|
const tmpFile = `${api.configuration.settingsFile}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
240
240
|
let fileHandle;
|
|
241
241
|
let attempts = 0;
|
|
242
|
-
if (!
|
|
242
|
+
if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
|
|
243
243
|
await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
|
|
244
244
|
}
|
|
245
245
|
async function removeFileWithRetry(path) {
|
|
@@ -260,7 +260,7 @@ async function updateSettings(updater) {
|
|
|
260
260
|
}
|
|
261
261
|
while (attempts < MAX_LOCK_ATTEMPTS) {
|
|
262
262
|
try {
|
|
263
|
-
fileHandle = await promises.open(lockFile,
|
|
263
|
+
fileHandle = await promises.open(lockFile, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
|
|
264
264
|
break;
|
|
265
265
|
} catch (err) {
|
|
266
266
|
if (LOCK_CONTENTION_CODES.has(err?.code)) {
|
|
@@ -285,14 +285,14 @@ async function updateSettings(updater) {
|
|
|
285
285
|
try {
|
|
286
286
|
const current = await readSettings() || { ...defaultSettings };
|
|
287
287
|
const updated = await updater(current);
|
|
288
|
-
if (!
|
|
288
|
+
if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
|
|
289
289
|
await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
|
|
290
290
|
}
|
|
291
291
|
await promises.writeFile(tmpFile, JSON.stringify(updated, null, 2));
|
|
292
292
|
await promises.rename(tmpFile, api.configuration.settingsFile);
|
|
293
293
|
return updated;
|
|
294
294
|
} finally {
|
|
295
|
-
if (
|
|
295
|
+
if (fs.existsSync(tmpFile)) {
|
|
296
296
|
await removeFileWithRetry(tmpFile).catch(() => {
|
|
297
297
|
});
|
|
298
298
|
}
|
|
@@ -318,7 +318,7 @@ const credentialsSchema = z__namespace.object({
|
|
|
318
318
|
}).nullish()
|
|
319
319
|
});
|
|
320
320
|
async function readCredentials() {
|
|
321
|
-
if (!
|
|
321
|
+
if (!fs.existsSync(api.configuration.privateKeyFile)) {
|
|
322
322
|
return null;
|
|
323
323
|
}
|
|
324
324
|
try {
|
|
@@ -350,7 +350,7 @@ async function readCredentials() {
|
|
|
350
350
|
return null;
|
|
351
351
|
}
|
|
352
352
|
async function writeCredentialsLegacy(credentials) {
|
|
353
|
-
if (!
|
|
353
|
+
if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
|
|
354
354
|
await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
|
|
355
355
|
}
|
|
356
356
|
await promises.writeFile(api.configuration.privateKeyFile, JSON.stringify({
|
|
@@ -360,7 +360,7 @@ async function writeCredentialsLegacy(credentials) {
|
|
|
360
360
|
}, null, 2));
|
|
361
361
|
}
|
|
362
362
|
async function writeCredentialsDataKey(credentials) {
|
|
363
|
-
if (!
|
|
363
|
+
if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
|
|
364
364
|
await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
|
|
365
365
|
}
|
|
366
366
|
await promises.writeFile(api.configuration.privateKeyFile, JSON.stringify({
|
|
@@ -370,7 +370,7 @@ async function writeCredentialsDataKey(credentials) {
|
|
|
370
370
|
}, null, 2));
|
|
371
371
|
}
|
|
372
372
|
async function clearCredentials() {
|
|
373
|
-
if (
|
|
373
|
+
if (fs.existsSync(api.configuration.privateKeyFile)) {
|
|
374
374
|
await promises.unlink(api.configuration.privateKeyFile);
|
|
375
375
|
}
|
|
376
376
|
}
|
|
@@ -382,7 +382,7 @@ async function clearMachineId() {
|
|
|
382
382
|
}
|
|
383
383
|
async function readDaemonState() {
|
|
384
384
|
try {
|
|
385
|
-
if (!
|
|
385
|
+
if (!fs.existsSync(api.configuration.daemonStateFile)) {
|
|
386
386
|
return null;
|
|
387
387
|
}
|
|
388
388
|
const content = await promises.readFile(api.configuration.daemonStateFile, "utf-8");
|
|
@@ -393,13 +393,13 @@ async function readDaemonState() {
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
function writeDaemonState(state) {
|
|
396
|
-
|
|
396
|
+
fs.writeFileSync(api.configuration.daemonStateFile, JSON.stringify(state, null, 2), "utf-8");
|
|
397
397
|
}
|
|
398
398
|
async function clearDaemonState() {
|
|
399
|
-
if (
|
|
399
|
+
if (fs.existsSync(api.configuration.daemonStateFile)) {
|
|
400
400
|
await promises.unlink(api.configuration.daemonStateFile);
|
|
401
401
|
}
|
|
402
|
-
if (
|
|
402
|
+
if (fs.existsSync(api.configuration.daemonLockFile)) {
|
|
403
403
|
try {
|
|
404
404
|
await promises.unlink(api.configuration.daemonLockFile);
|
|
405
405
|
} catch {
|
|
@@ -408,7 +408,7 @@ async function clearDaemonState() {
|
|
|
408
408
|
}
|
|
409
409
|
async function acquireDaemonLock(maxAttempts = 3, delayIncrementMs = 1e3) {
|
|
410
410
|
const lockFileName = `daemon.lock.${process.pid}.${Date.now()}`;
|
|
411
|
-
const lockFile =
|
|
411
|
+
const lockFile = path.join(path.dirname(api.configuration.daemonLockFile), lockFileName);
|
|
412
412
|
api.logger.debug(`[ACQUIRE LOCK] Attempting to acquire lock: ${lockFile}`);
|
|
413
413
|
api.logger.debug(`[ACQUIRE LOCK] Platform: ${process.platform}, PID: ${process.pid}`);
|
|
414
414
|
const isPidAlive = (pid) => {
|
|
@@ -421,8 +421,8 @@ async function acquireDaemonLock(maxAttempts = 3, delayIncrementMs = 1e3) {
|
|
|
421
421
|
};
|
|
422
422
|
const readLockPid = () => {
|
|
423
423
|
try {
|
|
424
|
-
if (
|
|
425
|
-
const content =
|
|
424
|
+
if (fs.existsSync(lockFile)) {
|
|
425
|
+
const content = fs.readFileSync(lockFile, "utf-8").trim();
|
|
426
426
|
const pid = parseInt(content, 10);
|
|
427
427
|
if (!isNaN(pid) && pid > 0) {
|
|
428
428
|
return pid;
|
|
@@ -433,7 +433,7 @@ async function acquireDaemonLock(maxAttempts = 3, delayIncrementMs = 1e3) {
|
|
|
433
433
|
return null;
|
|
434
434
|
};
|
|
435
435
|
const writeLockPid = (pid) => {
|
|
436
|
-
|
|
436
|
+
fs.writeFileSync(lockFile, String(pid), "utf-8");
|
|
437
437
|
};
|
|
438
438
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
439
439
|
api.logger.debug(`[ACQUIRE LOCK] Attempt ${attempt}/${maxAttempts}`);
|
|
@@ -450,9 +450,9 @@ async function acquireDaemonLock(maxAttempts = 3, delayIncrementMs = 1e3) {
|
|
|
450
450
|
api.logger.debug(`[ACQUIRE LOCK] No existing lock file`);
|
|
451
451
|
}
|
|
452
452
|
try {
|
|
453
|
-
if (
|
|
453
|
+
if (fs.existsSync(lockFile)) {
|
|
454
454
|
try {
|
|
455
|
-
|
|
455
|
+
fs.unlinkSync(lockFile);
|
|
456
456
|
api.logger.debug(`[ACQUIRE LOCK] Removed existing lock file`);
|
|
457
457
|
} catch (unlinkError) {
|
|
458
458
|
api.logger.debug(`[ACQUIRE LOCK] Could not remove lock file, trying anyway`);
|
|
@@ -499,17 +499,17 @@ async function releaseDaemonLock(lockHandle) {
|
|
|
499
499
|
} catch {
|
|
500
500
|
}
|
|
501
501
|
try {
|
|
502
|
-
if (
|
|
503
|
-
|
|
502
|
+
if (fs.existsSync(api.configuration.daemonLockFile)) {
|
|
503
|
+
fs.unlinkSync(api.configuration.daemonLockFile);
|
|
504
504
|
api.logger.debug(`[RELEASE LOCK] Released daemon lock`);
|
|
505
505
|
}
|
|
506
|
-
const lockDir =
|
|
506
|
+
const lockDir = path.dirname(api.configuration.daemonLockFile);
|
|
507
507
|
try {
|
|
508
|
-
const files =
|
|
508
|
+
const files = fs.readdirSync(lockDir);
|
|
509
509
|
for (const file of files) {
|
|
510
510
|
if (file.startsWith("daemon.lock.") && file.includes(`.${process.pid}.`)) {
|
|
511
|
-
const lockPath =
|
|
512
|
-
|
|
511
|
+
const lockPath = path.join(lockDir, file);
|
|
512
|
+
fs.unlinkSync(lockPath);
|
|
513
513
|
api.logger.debug(`[RELEASE LOCK] Released lock: ${file}`);
|
|
514
514
|
}
|
|
515
515
|
}
|
package/dist/{registerKillSessionHandler-Cu9rHGsI.mjs → registerKillSessionHandler-ARQrPvnT.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as formatDisplayMessage } from './index-
|
|
2
|
-
import { l as logger } from './api-
|
|
1
|
+
import { f as formatDisplayMessage } from './index-CzvgPwr1.mjs';
|
|
2
|
+
import { l as logger } from './api-BjxmW-0W.mjs';
|
|
3
3
|
import { createHash } from 'crypto';
|
|
4
4
|
import 'axios';
|
|
5
5
|
import 'node:events';
|
package/dist/{registerKillSessionHandler-CYc0SIjF.cjs → registerKillSessionHandler-DCMFiXyA.cjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
4
|
-
var api = require('./api-
|
|
3
|
+
var index = require('./index-Cuvfa15L.cjs');
|
|
4
|
+
var api = require('./api-DUE5TJBE.cjs');
|
|
5
5
|
var crypto = require('crypto');
|
|
6
6
|
require('axios');
|
|
7
7
|
require('node:events');
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import os, { homedir } from 'node:os';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { l as logger, d as backoff, f as delay, g as AsyncLock, c as configuration, b as connectionState, A as ApiClient, p as packageJson, i as isAuthenticationRequiredError, s as startOfflineReconnection } from './api-
|
|
4
|
-
import {
|
|
3
|
+
import { l as logger, d as backoff, f as delay, g as AsyncLock, c as configuration, b as connectionState, A as ApiClient, p as packageJson, i as isAuthenticationRequiredError, s as startOfflineReconnection } from './api-BjxmW-0W.mjs';
|
|
4
|
+
import { h as getProjectPath, j as claudeLocal, E as ExitCodeError, k as isBun, l as trimIdent, m as claudeCheckSession, d as projectPath, n as getEnvironmentInfo, i as initialMachineMetadata, b as stopCaffeinate, p as publishSessionRegistration, o as startCaffeinate } from './index-CzvgPwr1.mjs';
|
|
5
5
|
import { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
|
|
6
6
|
import { dirname, basename, join, resolve } from 'node:path';
|
|
7
7
|
import { readFile } from 'node:fs/promises';
|
|
8
8
|
import { stat, watch, access } from 'fs/promises';
|
|
9
9
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
10
|
-
import { a as MessageBuffer, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler } from './registerKillSessionHandler-
|
|
10
|
+
import { a as MessageBuffer, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler } from './registerKillSessionHandler-ARQrPvnT.mjs';
|
|
11
11
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
12
12
|
import { execSync, spawn } from 'node:child_process';
|
|
13
13
|
import { createInterface } from 'node:readline';
|
|
@@ -20,7 +20,7 @@ import 'tweetnacl';
|
|
|
20
20
|
import 'expo-server-sdk';
|
|
21
21
|
import 'chalk';
|
|
22
22
|
import { isDeepStrictEqual } from 'node:util';
|
|
23
|
-
import { readSettings } from './persistence-
|
|
23
|
+
import { readSettings } from './persistence-BxP6Jw1f.mjs';
|
|
24
24
|
import { createServer } from 'node:http';
|
|
25
25
|
import 'fs';
|
|
26
26
|
import 'zod';
|
|
@@ -3206,6 +3206,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
3206
3206
|
onReconnected: async () => {
|
|
3207
3207
|
const resp = await api.getOrCreateSession({ tag: randomUUID(), metadata, state });
|
|
3208
3208
|
if (!resp) throw new Error("Server unavailable");
|
|
3209
|
+
await publishSessionRegistration(resp.id, metadata);
|
|
3209
3210
|
const session2 = api.sessionSyncClient(resp);
|
|
3210
3211
|
const scanner = await createSessionScanner({
|
|
3211
3212
|
sessionId: null,
|
|
@@ -3240,17 +3241,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
3240
3241
|
process.exit(0);
|
|
3241
3242
|
}
|
|
3242
3243
|
logger.debug(`Session created: ${response.id}`);
|
|
3243
|
-
|
|
3244
|
-
logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
3245
|
-
const result = await notifyDaemonSessionStarted(response.id, metadata);
|
|
3246
|
-
if (result.error) {
|
|
3247
|
-
logger.debug(`[START] Failed to report to daemon (may not be running):`, result.error);
|
|
3248
|
-
} else {
|
|
3249
|
-
logger.debug(`[START] Reported session ${response.id} to daemon`);
|
|
3250
|
-
}
|
|
3251
|
-
} catch (error) {
|
|
3252
|
-
logger.debug("[START] Failed to report to daemon (may not be running):", error);
|
|
3253
|
-
}
|
|
3244
|
+
await publishSessionRegistration(response.id, metadata);
|
|
3254
3245
|
extractSDKMetadataAsync(async (sdkMetadata) => {
|
|
3255
3246
|
logger.debug("[start] SDK metadata extracted, updating session:", sdkMetadata);
|
|
3256
3247
|
try {
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
var os = require('node:os');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
|
-
var api = require('./api-
|
|
6
|
-
var index = require('./index-
|
|
5
|
+
var api = require('./api-DUE5TJBE.cjs');
|
|
6
|
+
var index = require('./index-Cuvfa15L.cjs');
|
|
7
7
|
var types = require('./types-DVk3crez.cjs');
|
|
8
|
-
var
|
|
8
|
+
var path = require('node:path');
|
|
9
9
|
var promises = require('node:fs/promises');
|
|
10
10
|
var fs = require('fs/promises');
|
|
11
11
|
var ink = require('ink');
|
|
12
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
12
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-DCMFiXyA.cjs');
|
|
13
13
|
var React = require('react');
|
|
14
14
|
var node_child_process = require('node:child_process');
|
|
15
15
|
var node_readline = require('node:readline');
|
|
16
|
-
var
|
|
16
|
+
var fs$1 = require('node:fs');
|
|
17
17
|
var node_url = require('node:url');
|
|
18
18
|
require('axios');
|
|
19
19
|
require('node:events');
|
|
@@ -22,7 +22,7 @@ require('tweetnacl');
|
|
|
22
22
|
require('expo-server-sdk');
|
|
23
23
|
require('chalk');
|
|
24
24
|
var node_util = require('node:util');
|
|
25
|
-
var persistence = require('./persistence-
|
|
25
|
+
var persistence = require('./persistence-D7JtnrYA.cjs');
|
|
26
26
|
var node_http = require('node:http');
|
|
27
27
|
require('fs');
|
|
28
28
|
require('zod');
|
|
@@ -290,8 +290,8 @@ class InvalidateSync {
|
|
|
290
290
|
|
|
291
291
|
function startFileWatcher(file, onFileChange) {
|
|
292
292
|
const abortController = new AbortController();
|
|
293
|
-
const parentDir =
|
|
294
|
-
const targetName =
|
|
293
|
+
const parentDir = path.dirname(file);
|
|
294
|
+
const targetName = path.basename(file);
|
|
295
295
|
void (async () => {
|
|
296
296
|
while (true) {
|
|
297
297
|
try {
|
|
@@ -375,7 +375,7 @@ async function createSessionScanner(opts) {
|
|
|
375
375
|
}
|
|
376
376
|
function getSessionFilePath(sessionId) {
|
|
377
377
|
const override = sessionFileOverrides.get(sessionId);
|
|
378
|
-
return override ??
|
|
378
|
+
return override ?? path.join(effectiveProjectDir(), `${sessionId}.jsonl`);
|
|
379
379
|
}
|
|
380
380
|
function scheduleTranscriptMissingWarning(sessionId) {
|
|
381
381
|
if (!opts.onTranscriptMissing) {
|
|
@@ -415,7 +415,7 @@ async function createSessionScanner(opts) {
|
|
|
415
415
|
if (opts.sessionId && typeof opts.transcriptPath === "string" && opts.transcriptPath.trim()) {
|
|
416
416
|
const transcriptPath = opts.transcriptPath.trim();
|
|
417
417
|
sessionFileOverrides.set(opts.sessionId, transcriptPath);
|
|
418
|
-
projectDirOverride =
|
|
418
|
+
projectDirOverride = path.dirname(transcriptPath);
|
|
419
419
|
}
|
|
420
420
|
if (opts.sessionId) {
|
|
421
421
|
let messages = await readSessionLog(getSessionFilePath(opts.sessionId));
|
|
@@ -518,7 +518,7 @@ async function createSessionScanner(opts) {
|
|
|
518
518
|
sessionFileOverrides.set(sessionId, transcriptPath);
|
|
519
519
|
didUpdatePaths = true;
|
|
520
520
|
}
|
|
521
|
-
const nextProjectDir =
|
|
521
|
+
const nextProjectDir = path.dirname(transcriptPath);
|
|
522
522
|
if (projectDirOverride !== nextProjectDir) {
|
|
523
523
|
projectDirOverride = nextProjectDir;
|
|
524
524
|
didUpdatePaths = true;
|
|
@@ -937,8 +937,8 @@ class AbortError extends Error {
|
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
939
|
|
|
940
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runClaude-
|
|
941
|
-
const __dirname$1 =
|
|
940
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runClaude-C1W_Nw0C.cjs', document.baseURI).href)));
|
|
941
|
+
const __dirname$1 = path.join(__filename$1, "..");
|
|
942
942
|
function getGlobalClaudeVersion() {
|
|
943
943
|
try {
|
|
944
944
|
const cleanEnv = getCleanEnv();
|
|
@@ -1002,7 +1002,7 @@ function findGlobalClaudePath() {
|
|
|
1002
1002
|
cwd: homeDir,
|
|
1003
1003
|
env: cleanEnv
|
|
1004
1004
|
}).trim();
|
|
1005
|
-
if (result &&
|
|
1005
|
+
if (result && fs$1.existsSync(result)) {
|
|
1006
1006
|
api.logger.debug(`[Claude SDK] Found global claude path via which: ${result}`);
|
|
1007
1007
|
return result;
|
|
1008
1008
|
}
|
|
@@ -1012,7 +1012,7 @@ function findGlobalClaudePath() {
|
|
|
1012
1012
|
return null;
|
|
1013
1013
|
}
|
|
1014
1014
|
function getDefaultClaudeCodePath() {
|
|
1015
|
-
const nodeModulesPath =
|
|
1015
|
+
const nodeModulesPath = path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
1016
1016
|
if (process.env.HAPPY_CLAUDE_PATH) {
|
|
1017
1017
|
api.logger.debug(`[Claude SDK] Using HAPPY_CLAUDE_PATH: ${process.env.HAPPY_CLAUDE_PATH}`);
|
|
1018
1018
|
return process.env.HAPPY_CLAUDE_PATH;
|
|
@@ -1301,7 +1301,7 @@ function query(config) {
|
|
|
1301
1301
|
}
|
|
1302
1302
|
const isJsFile = pathToClaudeCodeExecutable.endsWith(".js") || pathToClaudeCodeExecutable.endsWith(".cjs");
|
|
1303
1303
|
const isCommandOnly = pathToClaudeCodeExecutable === "claude";
|
|
1304
|
-
if (!isCommandOnly && !
|
|
1304
|
+
if (!isCommandOnly && !fs$1.existsSync(pathToClaudeCodeExecutable)) {
|
|
1305
1305
|
throw new ReferenceError(`Claude Code executable not found at ${pathToClaudeCodeExecutable}. Is options.pathToClaudeCodeExecutable set?`);
|
|
1306
1306
|
}
|
|
1307
1307
|
const spawnCommand = isJsFile ? executable : pathToClaudeCodeExecutable;
|
|
@@ -1558,17 +1558,17 @@ async function awaitFileExist(file, timeout = 1e4) {
|
|
|
1558
1558
|
}
|
|
1559
1559
|
|
|
1560
1560
|
function getClaudeSettingsPath() {
|
|
1561
|
-
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR ||
|
|
1562
|
-
return
|
|
1561
|
+
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
|
|
1562
|
+
return path.join(claudeConfigDir, "settings.json");
|
|
1563
1563
|
}
|
|
1564
1564
|
function readClaudeSettings() {
|
|
1565
1565
|
try {
|
|
1566
1566
|
const settingsPath = getClaudeSettingsPath();
|
|
1567
|
-
if (!
|
|
1567
|
+
if (!fs$1.existsSync(settingsPath)) {
|
|
1568
1568
|
api.logger.debug(`[ClaudeSettings] No Claude settings file found at ${settingsPath}`);
|
|
1569
1569
|
return null;
|
|
1570
1570
|
}
|
|
1571
|
-
const settingsContent =
|
|
1571
|
+
const settingsContent = fs$1.readFileSync(settingsPath, "utf-8");
|
|
1572
1572
|
const settings = JSON.parse(settingsContent);
|
|
1573
1573
|
api.logger.debug(`[ClaudeSettings] Successfully read Claude settings from ${settingsPath}`);
|
|
1574
1574
|
api.logger.debug(`[ClaudeSettings] includeCoAuthoredBy: ${settings.includeCoAuthoredBy}`);
|
|
@@ -1677,7 +1677,7 @@ async function claudeRemote(opts) {
|
|
|
1677
1677
|
executable: opts.jsRuntime ?? "node",
|
|
1678
1678
|
abort: opts.signal,
|
|
1679
1679
|
pathToClaudeCodeExecutable: (() => {
|
|
1680
|
-
return
|
|
1680
|
+
return path.resolve(path.join(index.projectPath(), "scripts", "claude_remote_launcher.cjs"));
|
|
1681
1681
|
})(),
|
|
1682
1682
|
settingsPath: opts.hookSettingsPath
|
|
1683
1683
|
};
|
|
@@ -1713,7 +1713,7 @@ async function claudeRemote(opts) {
|
|
|
1713
1713
|
updateThinking(true);
|
|
1714
1714
|
const systemInit = message;
|
|
1715
1715
|
if (systemInit.session_id) {
|
|
1716
|
-
const transcriptPath = opts.transcriptPath && opts.sessionId === systemInit.session_id ? opts.transcriptPath :
|
|
1716
|
+
const transcriptPath = opts.transcriptPath && opts.sessionId === systemInit.session_id ? opts.transcriptPath : path.join(index.getProjectPath(opts.path), `${systemInit.session_id}.jsonl`);
|
|
1717
1717
|
api.logger.debug(`[claudeRemote] Waiting for session file to be written to disk: ${transcriptPath}`);
|
|
1718
1718
|
const found = await awaitFileExist(transcriptPath);
|
|
1719
1719
|
api.logger.debug(`[claudeRemote] Session file found: ${systemInit.session_id} ${found}`);
|
|
@@ -3115,11 +3115,11 @@ async function startHookServer(options) {
|
|
|
3115
3115
|
}
|
|
3116
3116
|
|
|
3117
3117
|
function generateHookSettingsFile(port) {
|
|
3118
|
-
const hooksDir =
|
|
3119
|
-
|
|
3118
|
+
const hooksDir = path.join(api.configuration.happyCloudHomeDir, "tmp", "hooks");
|
|
3119
|
+
fs$1.mkdirSync(hooksDir, { recursive: true });
|
|
3120
3120
|
const filename = `session-hook-${process.pid}.json`;
|
|
3121
|
-
const filepath =
|
|
3122
|
-
const forwarderScript =
|
|
3121
|
+
const filepath = path.join(hooksDir, filename);
|
|
3122
|
+
const forwarderScript = path.resolve(index.projectPath(), "scripts", "session_hook_forwarder.cjs");
|
|
3123
3123
|
const hookCommand = `node "${forwarderScript}" ${port}`;
|
|
3124
3124
|
const settings = {
|
|
3125
3125
|
hooks: {
|
|
@@ -3136,14 +3136,14 @@ function generateHookSettingsFile(port) {
|
|
|
3136
3136
|
]
|
|
3137
3137
|
}
|
|
3138
3138
|
};
|
|
3139
|
-
|
|
3139
|
+
fs$1.writeFileSync(filepath, JSON.stringify(settings, null, 2));
|
|
3140
3140
|
api.logger.debug(`[generateHookSettings] Created hook settings file: ${filepath}`);
|
|
3141
3141
|
return filepath;
|
|
3142
3142
|
}
|
|
3143
3143
|
function cleanupHookSettingsFile(filepath) {
|
|
3144
3144
|
try {
|
|
3145
|
-
if (
|
|
3146
|
-
|
|
3145
|
+
if (fs$1.existsSync(filepath)) {
|
|
3146
|
+
fs$1.unlinkSync(filepath);
|
|
3147
3147
|
api.logger.debug(`[generateHookSettings] Cleaned up hook settings file: ${filepath}`);
|
|
3148
3148
|
}
|
|
3149
3149
|
} catch (error) {
|
|
@@ -3184,7 +3184,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
3184
3184
|
homeDir: os.homedir(),
|
|
3185
3185
|
happyHomeDir: api.configuration.happyCloudHomeDir,
|
|
3186
3186
|
happyLibDir: index.projectPath(),
|
|
3187
|
-
happyToolsDir:
|
|
3187
|
+
happyToolsDir: path.resolve(index.projectPath(), "tools", "unpacked"),
|
|
3188
3188
|
startedFromDaemon: options.startedBy === "daemon",
|
|
3189
3189
|
hostPid: process.pid,
|
|
3190
3190
|
startedBy: options.startedBy || "terminal",
|
|
@@ -3209,6 +3209,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
3209
3209
|
onReconnected: async () => {
|
|
3210
3210
|
const resp = await api$1.getOrCreateSession({ tag: node_crypto.randomUUID(), metadata, state });
|
|
3211
3211
|
if (!resp) throw new Error("Server unavailable");
|
|
3212
|
+
await index.publishSessionRegistration(resp.id, metadata);
|
|
3212
3213
|
const session2 = api$1.sessionSyncClient(resp);
|
|
3213
3214
|
const scanner = await createSessionScanner({
|
|
3214
3215
|
sessionId: null,
|
|
@@ -3243,17 +3244,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
3243
3244
|
process.exit(0);
|
|
3244
3245
|
}
|
|
3245
3246
|
api.logger.debug(`Session created: ${response.id}`);
|
|
3246
|
-
|
|
3247
|
-
api.logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
3248
|
-
const result = await index.notifyDaemonSessionStarted(response.id, metadata);
|
|
3249
|
-
if (result.error) {
|
|
3250
|
-
api.logger.debug(`[START] Failed to report to daemon (may not be running):`, result.error);
|
|
3251
|
-
} else {
|
|
3252
|
-
api.logger.debug(`[START] Reported session ${response.id} to daemon`);
|
|
3253
|
-
}
|
|
3254
|
-
} catch (error) {
|
|
3255
|
-
api.logger.debug("[START] Failed to report to daemon (may not be running):", error);
|
|
3256
|
-
}
|
|
3247
|
+
await index.publishSessionRegistration(response.id, metadata);
|
|
3257
3248
|
extractSDKMetadataAsync(async (sdkMetadata) => {
|
|
3258
3249
|
api.logger.debug("[start] SDK metadata extracted, updating session:", sdkMetadata);
|
|
3259
3250
|
try {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-
|
|
3
|
-
import { readSettings } from './persistence-
|
|
4
|
-
import { f as formatDisplayMessage, v as validateCodexAcpSpawn,
|
|
5
|
-
import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, d as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, b as attachToolHappierMetaV2, r as resolveCanonicalToolNameV2, i as inferToolResultError, c as createSessionMetadata, s as setupOfflineReconnection } from './names-
|
|
6
|
-
import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-
|
|
2
|
+
import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-BjxmW-0W.mjs';
|
|
3
|
+
import { readSettings } from './persistence-BxP6Jw1f.mjs';
|
|
4
|
+
import { f as formatDisplayMessage, v as validateCodexAcpSpawn, e as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate, i as initialMachineMetadata, p as publishSessionRegistration } from './index-CzvgPwr1.mjs';
|
|
5
|
+
import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, d as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, b as attachToolHappierMetaV2, r as resolveCanonicalToolNameV2, i as inferToolResultError, c as createSessionMetadata, s as setupOfflineReconnection } from './names-CicSgRNg.mjs';
|
|
6
|
+
import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-ARQrPvnT.mjs';
|
|
7
7
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
8
8
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
9
9
|
import 'axios';
|
|
@@ -735,6 +735,7 @@ function normalizeCodexBackendError(error) {
|
|
|
735
735
|
record?.code !== void 0 && record?.code !== null ? `[code=${String(record.code)}]` : "",
|
|
736
736
|
record?.status !== void 0 && record?.status !== null ? `[status=${String(record.status)}]` : ""
|
|
737
737
|
].filter(Boolean).join(" ") : "";
|
|
738
|
+
const searchableLower = searchableText.toLowerCase();
|
|
738
739
|
if (searchableText.includes("Failed to locate @zed-industries/codex-acp-")) {
|
|
739
740
|
const hint = "Codex ACP could not start because the @zed-industries/codex-acp platform binary is missing. Reinstall codex-acp for this machine, or set HAPPY_CODEX_ACP_BIN to a working codex-acp executable.";
|
|
740
741
|
return prefix ? `${prefix} ${hint}` : hint;
|
|
@@ -743,6 +744,10 @@ function normalizeCodexBackendError(error) {
|
|
|
743
744
|
const hint = "The configured Codex ACP command does not speak the ACP protocol. Make sure HAPPY_CODEX_ACP_BIN points to codex-acp, not the codex CLI.";
|
|
744
745
|
return prefix ? `${prefix} ${hint}` : hint;
|
|
745
746
|
}
|
|
747
|
+
if ((searchableLower.includes("ripgrep") || searchableLower.includes(" rg ")) && (searchableLower.includes("not found") || searchableLower.includes("could not find") || searchableLower.includes("no such file") || searchableLower.includes("is not recognized"))) {
|
|
748
|
+
const hint = "Codex ACP could not find ripgrep (rg). Happy injects Codex's bundled rg into PATH at startup; if you still see this, restart the Happy daemon/CLI so the new environment is used, or reinstall @openai/codex.";
|
|
749
|
+
return prefix ? `${prefix} ${hint}` : hint;
|
|
750
|
+
}
|
|
746
751
|
if (typeof record?.message === "string" && record.message.trim().toLowerCase() === "internal error" && dataText) {
|
|
747
752
|
return prefix ? `${prefix} ${dataText}` : dataText;
|
|
748
753
|
}
|
|
@@ -1464,18 +1469,12 @@ async function runCodex(opts) {
|
|
|
1464
1469
|
onSessionSwap: (newSession) => {
|
|
1465
1470
|
sessionClient = newSession;
|
|
1466
1471
|
codexSession?.updateClient(newSession);
|
|
1472
|
+
void publishSessionRegistration(newSession.sessionId, metadata);
|
|
1467
1473
|
}
|
|
1468
1474
|
});
|
|
1469
1475
|
sessionClient = initialSession;
|
|
1470
1476
|
if (response) {
|
|
1471
|
-
|
|
1472
|
-
const result = await notifyDaemonSessionStarted(response.id, metadata);
|
|
1473
|
-
if (result.error) {
|
|
1474
|
-
logger.debug("[START] Failed to report to daemon:", result.error);
|
|
1475
|
-
}
|
|
1476
|
-
} catch (error) {
|
|
1477
|
-
logger.debug("[START] Failed to report to daemon:", error);
|
|
1478
|
-
}
|
|
1477
|
+
await publishSessionRegistration(response.id, metadata);
|
|
1479
1478
|
}
|
|
1480
1479
|
const messageQueue = new MessageQueue2(getCodexExecutionFingerprint);
|
|
1481
1480
|
let currentPermissionMode = initialPermissionMode;
|