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 CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var types$1 = require('./types-DXK5YldG.cjs');
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.3.1-beta.2";
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.72",
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 happyPath = process.argv[1];
3170
- const runningFromBuiltBinary = happyPath.endsWith("happy") || happyPath.endsWith("happy.cmd");
3171
- let executable, spawnArgs;
3172
- if (runningFromBuiltBinary) {
3173
- executable = happyPath;
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("machine-alive")) {
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
- this.socket.volatile.emit("machine-alive", {
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 process2 of this.spawnedProcesses) {
3372
+ for (const process of this.spawnedProcesses) {
3327
3373
  try {
3328
- types$1.logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${process2.pid}`);
3329
- process2.kill("SIGTERM");
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
- process2.kill("SIGKILL");
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
- version: packageJson.version
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-BX4xv8Ty.mjs';
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.3.1-beta.2";
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.72",
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 happyPath = process.argv[1];
3149
- const runningFromBuiltBinary = happyPath.endsWith("happy") || happyPath.endsWith("happy.cmd");
3150
- let executable, spawnArgs;
3151
- if (runningFromBuiltBinary) {
3152
- executable = happyPath;
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("machine-alive")) {
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
- this.socket.volatile.emit("machine-alive", {
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 process2 of this.spawnedProcesses) {
3351
+ for (const process of this.spawnedProcesses) {
3306
3352
  try {
3307
- logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${process2.pid}`);
3308
- process2.kill("SIGTERM");
3353
+ logger.debug(`[DAEMON SESSION] Killing spawned process with PID: ${process.pid}`);
3354
+ process.kill("SIGTERM");
3309
3355
  setTimeout(() => {
3310
3356
  try {
3311
- process2.kill("SIGKILL");
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
- version: packageJson.version
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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-DXK5YldG.cjs');
3
+ var types = require('./types-eN-YHsuj.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('fs');
package/dist/lib.d.cts CHANGED
@@ -383,6 +383,7 @@ type Metadata = {
383
383
  machineId?: string;
384
384
  tools?: string[];
385
385
  slashCommands?: string[];
386
+ homeDir?: string;
386
387
  };
387
388
  type AgentState = {
388
389
  controlledByUser?: boolean | null | undefined;
package/dist/lib.d.mts CHANGED
@@ -383,6 +383,7 @@ type Metadata = {
383
383
  machineId?: string;
384
384
  tools?: string[];
385
385
  slashCommands?: string[];
386
+ homeDir?: string;
386
387
  };
387
388
  type AgentState = {
388
389
  controlledByUser?: boolean | null | undefined;
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-BX4xv8Ty.mjs';
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.1-beta.2",
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.72",
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
+ }