happy-coder 0.3.1-beta.2 → 0.4.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.cjs +72 -25
- package/dist/index.mjs +72 -25
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +1 -0
- package/dist/lib.d.mts +1 -0
- package/dist/lib.mjs +1 -1
- package/dist/{types-BX4xv8Ty.mjs → types-VkaGP8up.mjs} +2 -1
- package/dist/{types-DXK5YldG.cjs → types-eN-YHsuj.cjs} +2 -0
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var types$1 = require('./types-
|
|
4
|
+
var types$1 = require('./types-eN-YHsuj.cjs');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var node_path = require('node:path');
|
|
@@ -2248,7 +2248,7 @@ async function loop(opts) {
|
|
|
2248
2248
|
}
|
|
2249
2249
|
|
|
2250
2250
|
var name = "happy-coder";
|
|
2251
|
-
var version = "0.
|
|
2251
|
+
var version = "0.4.0";
|
|
2252
2252
|
var description = "Claude Code session sharing CLI";
|
|
2253
2253
|
var author = "Kirill Dubovitskiy";
|
|
2254
2254
|
var license = "MIT";
|
|
@@ -2297,13 +2297,13 @@ var scripts = {
|
|
|
2297
2297
|
build: "shx rm -rf dist && tsc --noEmit && pkgroll",
|
|
2298
2298
|
prepublishOnly: "yarn build && yarn test",
|
|
2299
2299
|
typecheck: "tsc --noEmit",
|
|
2300
|
-
dev: "npx tsx --env-file .env.sample src/index.ts",
|
|
2301
|
-
"dev:local-server": "cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
2300
|
+
dev: "yarn build && npx tsx --env-file .env.sample src/index.ts",
|
|
2301
|
+
"dev:local-server": "yarn build && cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
2302
2302
|
"version:prerelease": "npm version prerelease --preid=beta",
|
|
2303
2303
|
"publish:prerelease": "npm publish --tag beta"
|
|
2304
2304
|
};
|
|
2305
2305
|
var dependencies = {
|
|
2306
|
-
"@anthropic-ai/claude-code": "^1.0.
|
|
2306
|
+
"@anthropic-ai/claude-code": "^1.0.73",
|
|
2307
2307
|
"@anthropic-ai/sdk": "^0.56.0",
|
|
2308
2308
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
2309
2309
|
"@stablelib/base64": "^2.0.1",
|
|
@@ -2962,7 +2962,8 @@ async function start(credentials, options = {}) {
|
|
|
2962
2962
|
host: os.hostname(),
|
|
2963
2963
|
version: packageJson.version,
|
|
2964
2964
|
os: os.platform(),
|
|
2965
|
-
machineId: settings.machineId
|
|
2965
|
+
machineId: settings.machineId,
|
|
2966
|
+
homeDir: os.homedir()
|
|
2966
2967
|
};
|
|
2967
2968
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
2968
2969
|
types$1.logger.debug(`Session created: ${response.id}`);
|
|
@@ -3116,6 +3117,7 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3116
3117
|
token;
|
|
3117
3118
|
secret;
|
|
3118
3119
|
spawnedProcesses = /* @__PURE__ */ new Set();
|
|
3120
|
+
machineRegistered = false;
|
|
3119
3121
|
constructor(token, secret, machineIdentity) {
|
|
3120
3122
|
super();
|
|
3121
3123
|
this.token = token;
|
|
@@ -3137,9 +3139,12 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3137
3139
|
withCredentials: true,
|
|
3138
3140
|
autoConnect: false
|
|
3139
3141
|
});
|
|
3140
|
-
socket.on("connect", () => {
|
|
3142
|
+
socket.on("connect", async () => {
|
|
3141
3143
|
types$1.logger.debug("[DAEMON SESSION] Socket connected");
|
|
3142
3144
|
types$1.logger.debug(`[DAEMON SESSION] Connected with auth - token: ${this.token.substring(0, 10)}..., machineId: ${this.machineIdentity.machineId}`);
|
|
3145
|
+
if (!this.machineRegistered) {
|
|
3146
|
+
await this.registerMachine();
|
|
3147
|
+
}
|
|
3143
3148
|
const rpcMethod = `${this.machineIdentity.machineId}:spawn-happy-session`;
|
|
3144
3149
|
socket.emit("rpc-register", { method: rpcMethod });
|
|
3145
3150
|
types$1.logger.debug(`[DAEMON SESSION] Emitted RPC registration: ${rpcMethod}`);
|
|
@@ -3166,16 +3171,11 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3166
3171
|
args.push("--local");
|
|
3167
3172
|
}
|
|
3168
3173
|
types$1.logger.debug(`[DAEMON SESSION] Spawning happy in directory: ${directory} with args: ${args.join(" ")}`);
|
|
3169
|
-
const
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
spawnArgs = args;
|
|
3175
|
-
} else {
|
|
3176
|
-
executable = "npx";
|
|
3177
|
-
spawnArgs = ["tsx", happyPath, ...args];
|
|
3178
|
-
}
|
|
3174
|
+
const happyBinPath = path.join(projectPath(), "bin", "happy.mjs");
|
|
3175
|
+
types$1.logger.debug(`[DAEMON SESSION] Using happy binary at: ${happyBinPath}`);
|
|
3176
|
+
const executable = happyBinPath;
|
|
3177
|
+
const spawnArgs = args;
|
|
3178
|
+
types$1.logger.debug(`[DAEMON SESSION] Spawn: executable=${executable}, args=${JSON.stringify(spawnArgs)}, cwd=${directory}`);
|
|
3179
3179
|
const happyProcess = child_process.spawn(executable, spawnArgs, {
|
|
3180
3180
|
cwd: directory,
|
|
3181
3181
|
detached: true,
|
|
@@ -3268,7 +3268,7 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3268
3268
|
types$1.logger.debug(`[DAEMON SESSION] RPC error: ${JSON.stringify(data)}`);
|
|
3269
3269
|
});
|
|
3270
3270
|
socket.onAny((event, ...args) => {
|
|
3271
|
-
if (!event.startsWith("
|
|
3271
|
+
if (!event.startsWith("session-alive") && event !== "ephemeral") {
|
|
3272
3272
|
types$1.logger.debug(`[DAEMON SESSION] Socket event: ${event}, args: ${JSON.stringify(args)}`);
|
|
3273
3273
|
}
|
|
3274
3274
|
});
|
|
@@ -3291,12 +3291,47 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3291
3291
|
});
|
|
3292
3292
|
this.socket = socket;
|
|
3293
3293
|
}
|
|
3294
|
+
async registerMachine() {
|
|
3295
|
+
try {
|
|
3296
|
+
const metadata = {
|
|
3297
|
+
host: this.machineIdentity.machineHost,
|
|
3298
|
+
platform: this.machineIdentity.platform,
|
|
3299
|
+
happyCliVersion: this.machineIdentity.happyCliVersion,
|
|
3300
|
+
happyHomeDirectory: this.machineIdentity.happyHomeDirectory
|
|
3301
|
+
};
|
|
3302
|
+
const encrypted = types$1.encrypt(JSON.stringify(metadata), this.secret);
|
|
3303
|
+
const encryptedMetadata = types$1.encodeBase64(encrypted);
|
|
3304
|
+
const response = await fetch(`${types$1.configuration.serverUrl}/v1/machines`, {
|
|
3305
|
+
method: "POST",
|
|
3306
|
+
headers: {
|
|
3307
|
+
"Authorization": `Bearer ${this.token}`,
|
|
3308
|
+
"Content-Type": "application/json"
|
|
3309
|
+
},
|
|
3310
|
+
body: JSON.stringify({
|
|
3311
|
+
id: this.machineIdentity.machineId,
|
|
3312
|
+
metadata: encryptedMetadata
|
|
3313
|
+
})
|
|
3314
|
+
});
|
|
3315
|
+
if (response.ok) {
|
|
3316
|
+
types$1.logger.debug("[DAEMON SESSION] Machine registered/updated successfully");
|
|
3317
|
+
this.machineRegistered = true;
|
|
3318
|
+
} else {
|
|
3319
|
+
types$1.logger.debug(`[DAEMON SESSION] Failed to register machine: ${response.status}`);
|
|
3320
|
+
}
|
|
3321
|
+
} catch (error) {
|
|
3322
|
+
types$1.logger.debug("[DAEMON SESSION] Failed to register machine:", error);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3294
3325
|
startKeepAlive() {
|
|
3295
3326
|
this.stopKeepAlive();
|
|
3296
3327
|
this.keepAliveInterval = setInterval(() => {
|
|
3297
|
-
|
|
3328
|
+
const payload = {
|
|
3329
|
+
type: "machine-scoped",
|
|
3330
|
+
machineId: this.machineIdentity.machineId,
|
|
3298
3331
|
time: Date.now()
|
|
3299
|
-
}
|
|
3332
|
+
};
|
|
3333
|
+
types$1.logger.debugLargeJson(`[DAEMON SESSION] Emitting session-alive`, payload);
|
|
3334
|
+
this.socket.emit("session-alive", payload);
|
|
3300
3335
|
}, 2e4);
|
|
3301
3336
|
}
|
|
3302
3337
|
stopKeepAlive() {
|
|
@@ -3321,15 +3356,26 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3321
3356
|
connect() {
|
|
3322
3357
|
this.socket.connect();
|
|
3323
3358
|
}
|
|
3359
|
+
updateMetadata(updates) {
|
|
3360
|
+
const metadata = {
|
|
3361
|
+
host: this.machineIdentity.machineHost,
|
|
3362
|
+
platform: this.machineIdentity.platform,
|
|
3363
|
+
happyCliVersion: updates.happyCliVersion || this.machineIdentity.happyCliVersion,
|
|
3364
|
+
happyHomeDirectory: updates.happyHomeDirectory || this.machineIdentity.happyHomeDirectory
|
|
3365
|
+
};
|
|
3366
|
+
const encrypted = types$1.encrypt(JSON.stringify(metadata), this.secret);
|
|
3367
|
+
const encryptedMetadata = types$1.encodeBase64(encrypted);
|
|
3368
|
+
this.socket.emit("update-machine-metadata", { metadata: encryptedMetadata });
|
|
3369
|
+
}
|
|
3324
3370
|
shutdown() {
|
|
3325
3371
|
types$1.logger.debug(`[DAEMON SESSION] Shutting down daemon, killing ${this.spawnedProcesses.size} spawned processes`);
|
|
3326
|
-
for (const
|
|
3372
|
+
for (const process of this.spawnedProcesses) {
|
|
3327
3373
|
try {
|
|
3328
|
-
types$1.logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${
|
|
3329
|
-
|
|
3374
|
+
types$1.logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${process.pid}`);
|
|
3375
|
+
process.kill("SIGTERM");
|
|
3330
3376
|
setTimeout(() => {
|
|
3331
3377
|
try {
|
|
3332
|
-
|
|
3378
|
+
process.kill("SIGKILL");
|
|
3333
3379
|
} catch (e) {
|
|
3334
3380
|
}
|
|
3335
3381
|
}, 1e3);
|
|
@@ -3405,7 +3451,8 @@ async function startDaemon() {
|
|
|
3405
3451
|
machineId: settings.machineId,
|
|
3406
3452
|
machineHost: settings.machineHost || os$1.hostname(),
|
|
3407
3453
|
platform: process.platform,
|
|
3408
|
-
|
|
3454
|
+
happyCliVersion: packageJson.version,
|
|
3455
|
+
happyHomeDirectory: process.cwd()
|
|
3409
3456
|
};
|
|
3410
3457
|
let credentials = await readCredentials();
|
|
3411
3458
|
if (!credentials) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { l as logger, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as encodeBase64, A as ApiClient, g as encodeBase64Url, h as decodeBase64, b as initializeConfiguration, i as initLoggerWithGlobalConfiguration } from './types-
|
|
2
|
+
import { l as logger, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as encodeBase64, A as ApiClient, g as encodeBase64Url, h as decodeBase64, j as encrypt, b as initializeConfiguration, i as initLoggerWithGlobalConfiguration } from './types-VkaGP8up.mjs';
|
|
3
3
|
import { randomUUID, randomBytes } from 'node:crypto';
|
|
4
4
|
import { spawn, execSync } from 'node:child_process';
|
|
5
5
|
import { resolve, join, dirname as dirname$1 } from 'node:path';
|
|
@@ -2227,7 +2227,7 @@ async function loop(opts) {
|
|
|
2227
2227
|
}
|
|
2228
2228
|
|
|
2229
2229
|
var name = "happy-coder";
|
|
2230
|
-
var version = "0.
|
|
2230
|
+
var version = "0.4.0";
|
|
2231
2231
|
var description = "Claude Code session sharing CLI";
|
|
2232
2232
|
var author = "Kirill Dubovitskiy";
|
|
2233
2233
|
var license = "MIT";
|
|
@@ -2276,13 +2276,13 @@ var scripts = {
|
|
|
2276
2276
|
build: "shx rm -rf dist && tsc --noEmit && pkgroll",
|
|
2277
2277
|
prepublishOnly: "yarn build && yarn test",
|
|
2278
2278
|
typecheck: "tsc --noEmit",
|
|
2279
|
-
dev: "npx tsx --env-file .env.sample src/index.ts",
|
|
2280
|
-
"dev:local-server": "cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
2279
|
+
dev: "yarn build && npx tsx --env-file .env.sample src/index.ts",
|
|
2280
|
+
"dev:local-server": "yarn build && cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
2281
2281
|
"version:prerelease": "npm version prerelease --preid=beta",
|
|
2282
2282
|
"publish:prerelease": "npm publish --tag beta"
|
|
2283
2283
|
};
|
|
2284
2284
|
var dependencies = {
|
|
2285
|
-
"@anthropic-ai/claude-code": "^1.0.
|
|
2285
|
+
"@anthropic-ai/claude-code": "^1.0.73",
|
|
2286
2286
|
"@anthropic-ai/sdk": "^0.56.0",
|
|
2287
2287
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
2288
2288
|
"@stablelib/base64": "^2.0.1",
|
|
@@ -2941,7 +2941,8 @@ async function start(credentials, options = {}) {
|
|
|
2941
2941
|
host: os.hostname(),
|
|
2942
2942
|
version: packageJson.version,
|
|
2943
2943
|
os: os.platform(),
|
|
2944
|
-
machineId: settings.machineId
|
|
2944
|
+
machineId: settings.machineId,
|
|
2945
|
+
homeDir: os.homedir()
|
|
2945
2946
|
};
|
|
2946
2947
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
2947
2948
|
logger.debug(`Session created: ${response.id}`);
|
|
@@ -3095,6 +3096,7 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3095
3096
|
token;
|
|
3096
3097
|
secret;
|
|
3097
3098
|
spawnedProcesses = /* @__PURE__ */ new Set();
|
|
3099
|
+
machineRegistered = false;
|
|
3098
3100
|
constructor(token, secret, machineIdentity) {
|
|
3099
3101
|
super();
|
|
3100
3102
|
this.token = token;
|
|
@@ -3116,9 +3118,12 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3116
3118
|
withCredentials: true,
|
|
3117
3119
|
autoConnect: false
|
|
3118
3120
|
});
|
|
3119
|
-
socket.on("connect", () => {
|
|
3121
|
+
socket.on("connect", async () => {
|
|
3120
3122
|
logger.debug("[DAEMON SESSION] Socket connected");
|
|
3121
3123
|
logger.debug(`[DAEMON SESSION] Connected with auth - token: ${this.token.substring(0, 10)}..., machineId: ${this.machineIdentity.machineId}`);
|
|
3124
|
+
if (!this.machineRegistered) {
|
|
3125
|
+
await this.registerMachine();
|
|
3126
|
+
}
|
|
3122
3127
|
const rpcMethod = `${this.machineIdentity.machineId}:spawn-happy-session`;
|
|
3123
3128
|
socket.emit("rpc-register", { method: rpcMethod });
|
|
3124
3129
|
logger.debug(`[DAEMON SESSION] Emitted RPC registration: ${rpcMethod}`);
|
|
@@ -3145,16 +3150,11 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3145
3150
|
args.push("--local");
|
|
3146
3151
|
}
|
|
3147
3152
|
logger.debug(`[DAEMON SESSION] Spawning happy in directory: ${directory} with args: ${args.join(" ")}`);
|
|
3148
|
-
const
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
spawnArgs = args;
|
|
3154
|
-
} else {
|
|
3155
|
-
executable = "npx";
|
|
3156
|
-
spawnArgs = ["tsx", happyPath, ...args];
|
|
3157
|
-
}
|
|
3153
|
+
const happyBinPath = join$1(projectPath(), "bin", "happy.mjs");
|
|
3154
|
+
logger.debug(`[DAEMON SESSION] Using happy binary at: ${happyBinPath}`);
|
|
3155
|
+
const executable = happyBinPath;
|
|
3156
|
+
const spawnArgs = args;
|
|
3157
|
+
logger.debug(`[DAEMON SESSION] Spawn: executable=${executable}, args=${JSON.stringify(spawnArgs)}, cwd=${directory}`);
|
|
3158
3158
|
const happyProcess = spawn$1(executable, spawnArgs, {
|
|
3159
3159
|
cwd: directory,
|
|
3160
3160
|
detached: true,
|
|
@@ -3247,7 +3247,7 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3247
3247
|
logger.debug(`[DAEMON SESSION] RPC error: ${JSON.stringify(data)}`);
|
|
3248
3248
|
});
|
|
3249
3249
|
socket.onAny((event, ...args) => {
|
|
3250
|
-
if (!event.startsWith("
|
|
3250
|
+
if (!event.startsWith("session-alive") && event !== "ephemeral") {
|
|
3251
3251
|
logger.debug(`[DAEMON SESSION] Socket event: ${event}, args: ${JSON.stringify(args)}`);
|
|
3252
3252
|
}
|
|
3253
3253
|
});
|
|
@@ -3270,12 +3270,47 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3270
3270
|
});
|
|
3271
3271
|
this.socket = socket;
|
|
3272
3272
|
}
|
|
3273
|
+
async registerMachine() {
|
|
3274
|
+
try {
|
|
3275
|
+
const metadata = {
|
|
3276
|
+
host: this.machineIdentity.machineHost,
|
|
3277
|
+
platform: this.machineIdentity.platform,
|
|
3278
|
+
happyCliVersion: this.machineIdentity.happyCliVersion,
|
|
3279
|
+
happyHomeDirectory: this.machineIdentity.happyHomeDirectory
|
|
3280
|
+
};
|
|
3281
|
+
const encrypted = encrypt(JSON.stringify(metadata), this.secret);
|
|
3282
|
+
const encryptedMetadata = encodeBase64(encrypted);
|
|
3283
|
+
const response = await fetch(`${configuration.serverUrl}/v1/machines`, {
|
|
3284
|
+
method: "POST",
|
|
3285
|
+
headers: {
|
|
3286
|
+
"Authorization": `Bearer ${this.token}`,
|
|
3287
|
+
"Content-Type": "application/json"
|
|
3288
|
+
},
|
|
3289
|
+
body: JSON.stringify({
|
|
3290
|
+
id: this.machineIdentity.machineId,
|
|
3291
|
+
metadata: encryptedMetadata
|
|
3292
|
+
})
|
|
3293
|
+
});
|
|
3294
|
+
if (response.ok) {
|
|
3295
|
+
logger.debug("[DAEMON SESSION] Machine registered/updated successfully");
|
|
3296
|
+
this.machineRegistered = true;
|
|
3297
|
+
} else {
|
|
3298
|
+
logger.debug(`[DAEMON SESSION] Failed to register machine: ${response.status}`);
|
|
3299
|
+
}
|
|
3300
|
+
} catch (error) {
|
|
3301
|
+
logger.debug("[DAEMON SESSION] Failed to register machine:", error);
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3273
3304
|
startKeepAlive() {
|
|
3274
3305
|
this.stopKeepAlive();
|
|
3275
3306
|
this.keepAliveInterval = setInterval(() => {
|
|
3276
|
-
|
|
3307
|
+
const payload = {
|
|
3308
|
+
type: "machine-scoped",
|
|
3309
|
+
machineId: this.machineIdentity.machineId,
|
|
3277
3310
|
time: Date.now()
|
|
3278
|
-
}
|
|
3311
|
+
};
|
|
3312
|
+
logger.debugLargeJson(`[DAEMON SESSION] Emitting session-alive`, payload);
|
|
3313
|
+
this.socket.emit("session-alive", payload);
|
|
3279
3314
|
}, 2e4);
|
|
3280
3315
|
}
|
|
3281
3316
|
stopKeepAlive() {
|
|
@@ -3300,15 +3335,26 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3300
3335
|
connect() {
|
|
3301
3336
|
this.socket.connect();
|
|
3302
3337
|
}
|
|
3338
|
+
updateMetadata(updates) {
|
|
3339
|
+
const metadata = {
|
|
3340
|
+
host: this.machineIdentity.machineHost,
|
|
3341
|
+
platform: this.machineIdentity.platform,
|
|
3342
|
+
happyCliVersion: updates.happyCliVersion || this.machineIdentity.happyCliVersion,
|
|
3343
|
+
happyHomeDirectory: updates.happyHomeDirectory || this.machineIdentity.happyHomeDirectory
|
|
3344
|
+
};
|
|
3345
|
+
const encrypted = encrypt(JSON.stringify(metadata), this.secret);
|
|
3346
|
+
const encryptedMetadata = encodeBase64(encrypted);
|
|
3347
|
+
this.socket.emit("update-machine-metadata", { metadata: encryptedMetadata });
|
|
3348
|
+
}
|
|
3303
3349
|
shutdown() {
|
|
3304
3350
|
logger.debug(`[DAEMON SESSION] Shutting down daemon, killing ${this.spawnedProcesses.size} spawned processes`);
|
|
3305
|
-
for (const
|
|
3351
|
+
for (const process of this.spawnedProcesses) {
|
|
3306
3352
|
try {
|
|
3307
|
-
logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${
|
|
3308
|
-
|
|
3353
|
+
logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${process.pid}`);
|
|
3354
|
+
process.kill("SIGTERM");
|
|
3309
3355
|
setTimeout(() => {
|
|
3310
3356
|
try {
|
|
3311
|
-
|
|
3357
|
+
process.kill("SIGKILL");
|
|
3312
3358
|
} catch (e) {
|
|
3313
3359
|
}
|
|
3314
3360
|
}, 1e3);
|
|
@@ -3384,7 +3430,8 @@ async function startDaemon() {
|
|
|
3384
3430
|
machineId: settings.machineId,
|
|
3385
3431
|
machineHost: settings.machineHost || hostname(),
|
|
3386
3432
|
platform: process.platform,
|
|
3387
|
-
|
|
3433
|
+
happyCliVersion: packageJson.version,
|
|
3434
|
+
happyHomeDirectory: process.cwd()
|
|
3388
3435
|
};
|
|
3389
3436
|
let credentials = await readCredentials();
|
|
3390
3437
|
if (!credentials) {
|
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, i as initLoggerWithGlobalConfiguration, b as initializeConfiguration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, i as initLoggerWithGlobalConfiguration, b as initializeConfiguration, l as logger } from './types-VkaGP8up.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -532,6 +532,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
532
532
|
*/
|
|
533
533
|
keepAlive(thinking, mode) {
|
|
534
534
|
this.socket.volatile.emit("session-alive", {
|
|
535
|
+
type: "session-scoped",
|
|
535
536
|
sid: this.sessionId,
|
|
536
537
|
time: Date.now(),
|
|
537
538
|
thinking,
|
|
@@ -878,4 +879,4 @@ const RawJSONLinesSchema = z.discriminatedUnion("type", [
|
|
|
878
879
|
}).passthrough()
|
|
879
880
|
]);
|
|
880
881
|
|
|
881
|
-
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, initializeConfiguration as b, configuration as c, backoff as d, delay as e, encodeBase64 as f, encodeBase64Url as g, decodeBase64 as h, initLoggerWithGlobalConfiguration as i, logger as l };
|
|
882
|
+
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, initializeConfiguration as b, configuration as c, backoff as d, delay as e, encodeBase64 as f, encodeBase64Url as g, decodeBase64 as h, initLoggerWithGlobalConfiguration as i, encrypt as j, logger as l };
|
|
@@ -534,6 +534,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
534
534
|
*/
|
|
535
535
|
keepAlive(thinking, mode) {
|
|
536
536
|
this.socket.volatile.emit("session-alive", {
|
|
537
|
+
type: "session-scoped",
|
|
537
538
|
sid: this.sessionId,
|
|
538
539
|
time: Date.now(),
|
|
539
540
|
thinking,
|
|
@@ -888,5 +889,6 @@ exports.decodeBase64 = decodeBase64;
|
|
|
888
889
|
exports.delay = delay;
|
|
889
890
|
exports.encodeBase64 = encodeBase64;
|
|
890
891
|
exports.encodeBase64Url = encodeBase64Url;
|
|
892
|
+
exports.encrypt = encrypt;
|
|
891
893
|
exports.initLoggerWithGlobalConfiguration = initLoggerWithGlobalConfiguration;
|
|
892
894
|
exports.initializeConfiguration = initializeConfiguration;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "happy-coder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Claude Code session sharing CLI",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"build": "shx rm -rf dist && tsc --noEmit && pkgroll",
|
|
50
50
|
"prepublishOnly": "yarn build && yarn test",
|
|
51
51
|
"typecheck": "tsc --noEmit",
|
|
52
|
-
"dev": "npx tsx --env-file .env.sample src/index.ts",
|
|
53
|
-
"dev:local-server": "cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
52
|
+
"dev": "yarn build && npx tsx --env-file .env.sample src/index.ts",
|
|
53
|
+
"dev:local-server": "yarn build && cross-env HANDY_SERVER_URL=http://localhost:3005 tsx --env-file .env.sample src/index.ts",
|
|
54
54
|
"version:prerelease": "npm version prerelease --preid=beta",
|
|
55
55
|
"publish:prerelease": "npm publish --tag beta"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@anthropic-ai/claude-code": "^1.0.
|
|
58
|
+
"@anthropic-ai/claude-code": "^1.0.73",
|
|
59
59
|
"@anthropic-ai/sdk": "^0.56.0",
|
|
60
60
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
61
61
|
"@stablelib/base64": "^2.0.1",
|
|
@@ -91,4 +91,4 @@
|
|
|
91
91
|
"overrides": {
|
|
92
92
|
"whatwg-url": "14.2.0"
|
|
93
93
|
}
|
|
94
|
-
}
|
|
94
|
+
}
|