happy-coder 0.10.0-0 → 0.10.0-2
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 +32 -277
- package/dist/index.mjs +29 -274
- package/dist/lib.cjs +7 -1
- package/dist/lib.d.cts +78 -21
- package/dist/lib.d.mts +78 -21
- package/dist/lib.mjs +7 -1
- package/dist/{types-fU2E-jQl.cjs → types-WP9wteZE.cjs} +409 -146
- package/dist/{types-CGbH1LGX.mjs → types-xfXKJHdM.mjs} +408 -147
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var types = require('./types-
|
|
6
|
+
var types = require('./types-WP9wteZE.cjs');
|
|
7
7
|
var node_child_process = require('node:child_process');
|
|
8
8
|
var node_path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
10
10
|
var node_fs = require('node:fs');
|
|
11
|
-
var path = require('path');
|
|
12
|
-
var url = require('url');
|
|
13
11
|
var promises = require('node:fs/promises');
|
|
14
12
|
var fs = require('fs/promises');
|
|
15
13
|
var ink = require('ink');
|
|
@@ -20,10 +18,10 @@ require('node:events');
|
|
|
20
18
|
require('socket.io-client');
|
|
21
19
|
var tweetnacl = require('tweetnacl');
|
|
22
20
|
require('expo-server-sdk');
|
|
23
|
-
var child_process = require('child_process');
|
|
24
|
-
var util = require('util');
|
|
25
21
|
var crypto = require('crypto');
|
|
22
|
+
var child_process = require('child_process');
|
|
26
23
|
var fs$1 = require('fs');
|
|
24
|
+
var path = require('path');
|
|
27
25
|
var psList = require('ps-list');
|
|
28
26
|
var spawn = require('cross-spawn');
|
|
29
27
|
var os$1 = require('os');
|
|
@@ -36,6 +34,8 @@ var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
|
36
34
|
var node_http = require('node:http');
|
|
37
35
|
var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
38
36
|
var http = require('http');
|
|
37
|
+
var util = require('util');
|
|
38
|
+
require('url');
|
|
39
39
|
|
|
40
40
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
41
41
|
class Session {
|
|
@@ -148,12 +148,6 @@ function claudeCheckSession(sessionId, path) {
|
|
|
148
148
|
return hasGoodMessage;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
const __dirname$2 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
152
|
-
function projectPath() {
|
|
153
|
-
const path$1 = path.resolve(__dirname$2, "..");
|
|
154
|
-
return path$1;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
151
|
function trimIdent(text) {
|
|
158
152
|
const lines = text.split("\n");
|
|
159
153
|
while (lines.length > 0 && lines[0].trim() === "") {
|
|
@@ -187,7 +181,7 @@ const systemPrompt = trimIdent(`
|
|
|
187
181
|
Co-Authored-By: Happy <yesreply@happy.engineering>
|
|
188
182
|
`);
|
|
189
183
|
|
|
190
|
-
const claudeCliPath = node_path.resolve(node_path.join(projectPath(), "scripts", "claude_local_launcher.cjs"));
|
|
184
|
+
const claudeCliPath = node_path.resolve(node_path.join(types.projectPath(), "scripts", "claude_local_launcher.cjs"));
|
|
191
185
|
async function claudeLocal(opts) {
|
|
192
186
|
const projectDir = getProjectPath(opts.path);
|
|
193
187
|
node_fs.mkdirSync(projectDir, { recursive: true });
|
|
@@ -614,8 +608,8 @@ async function claudeLocalLauncher(session) {
|
|
|
614
608
|
}
|
|
615
609
|
await abort();
|
|
616
610
|
}
|
|
617
|
-
session.client.
|
|
618
|
-
session.client.
|
|
611
|
+
session.client.rpcHandlerManager.registerHandler("abort", doAbort);
|
|
612
|
+
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
619
613
|
session.queue.setOnMessage((message, mode) => {
|
|
620
614
|
doSwitch();
|
|
621
615
|
});
|
|
@@ -661,9 +655,9 @@ async function claudeLocalLauncher(session) {
|
|
|
661
655
|
}
|
|
662
656
|
} finally {
|
|
663
657
|
exutFuture.resolve(void 0);
|
|
664
|
-
session.client.
|
|
658
|
+
session.client.rpcHandlerManager.registerHandler("abort", async () => {
|
|
665
659
|
});
|
|
666
|
-
session.client.
|
|
660
|
+
session.client.rpcHandlerManager.registerHandler("switch", async () => {
|
|
667
661
|
});
|
|
668
662
|
session.queue.setOnMessage(null);
|
|
669
663
|
await scanner.cleanup();
|
|
@@ -1510,7 +1504,7 @@ async function claudeRemote(opts) {
|
|
|
1510
1504
|
executable: "node",
|
|
1511
1505
|
abort: opts.signal,
|
|
1512
1506
|
pathToClaudeCodeExecutable: (() => {
|
|
1513
|
-
return node_path.resolve(node_path.join(projectPath(), "scripts", "claude_remote_launcher.cjs"));
|
|
1507
|
+
return node_path.resolve(node_path.join(types.projectPath(), "scripts", "claude_remote_launcher.cjs"));
|
|
1514
1508
|
})()
|
|
1515
1509
|
};
|
|
1516
1510
|
let thinking = false;
|
|
@@ -1925,7 +1919,7 @@ class PermissionHandler {
|
|
|
1925
1919
|
* Sets up the client handler for permission responses
|
|
1926
1920
|
*/
|
|
1927
1921
|
setupClientHandler() {
|
|
1928
|
-
this.session.client.
|
|
1922
|
+
this.session.client.rpcHandlerManager.registerHandler("permission", async (message) => {
|
|
1929
1923
|
types.logger.debug(`Permission response: ${JSON.stringify(message)}`);
|
|
1930
1924
|
const id = message.id;
|
|
1931
1925
|
const pending = this.pendingRequests.get(id);
|
|
@@ -2495,8 +2489,8 @@ async function claudeRemoteLauncher(session) {
|
|
|
2495
2489
|
}
|
|
2496
2490
|
await abort();
|
|
2497
2491
|
}
|
|
2498
|
-
session.client.
|
|
2499
|
-
session.client.
|
|
2492
|
+
session.client.rpcHandlerManager.registerHandler("abort", doAbort);
|
|
2493
|
+
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
2500
2494
|
const permissionHandler = new PermissionHandler(session);
|
|
2501
2495
|
const messageQueue = new OutgoingMessageQueue(
|
|
2502
2496
|
(logMessage) => session.client.sendClaudeSessionMessage(logMessage)
|
|
@@ -2812,255 +2806,6 @@ async function loop(opts) {
|
|
|
2812
2806
|
}
|
|
2813
2807
|
}
|
|
2814
2808
|
|
|
2815
|
-
function run(args, options) {
|
|
2816
|
-
const RUNNER_PATH = path.resolve(path.join(projectPath(), "scripts", "ripgrep_launcher.cjs"));
|
|
2817
|
-
return new Promise((resolve2, reject) => {
|
|
2818
|
-
const child = child_process.spawn("node", [RUNNER_PATH, JSON.stringify(args)], {
|
|
2819
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
2820
|
-
cwd: options?.cwd
|
|
2821
|
-
});
|
|
2822
|
-
let stdout = "";
|
|
2823
|
-
let stderr = "";
|
|
2824
|
-
child.stdout.on("data", (data) => {
|
|
2825
|
-
stdout += data.toString();
|
|
2826
|
-
});
|
|
2827
|
-
child.stderr.on("data", (data) => {
|
|
2828
|
-
stderr += data.toString();
|
|
2829
|
-
});
|
|
2830
|
-
child.on("close", (code) => {
|
|
2831
|
-
resolve2({
|
|
2832
|
-
exitCode: code || 0,
|
|
2833
|
-
stdout,
|
|
2834
|
-
stderr
|
|
2835
|
-
});
|
|
2836
|
-
});
|
|
2837
|
-
child.on("error", (err) => {
|
|
2838
|
-
reject(err);
|
|
2839
|
-
});
|
|
2840
|
-
});
|
|
2841
|
-
}
|
|
2842
|
-
|
|
2843
|
-
const execAsync$1 = util.promisify(child_process.exec);
|
|
2844
|
-
function registerHandlers(session) {
|
|
2845
|
-
session.setHandler("bash", async (data) => {
|
|
2846
|
-
types.logger.debug("Shell command request:", data.command);
|
|
2847
|
-
try {
|
|
2848
|
-
const options = {
|
|
2849
|
-
cwd: data.cwd,
|
|
2850
|
-
timeout: data.timeout || 3e4
|
|
2851
|
-
// Default 30 seconds timeout
|
|
2852
|
-
};
|
|
2853
|
-
const { stdout, stderr } = await execAsync$1(data.command, options);
|
|
2854
|
-
return {
|
|
2855
|
-
success: true,
|
|
2856
|
-
stdout: stdout ? stdout.toString() : "",
|
|
2857
|
-
stderr: stderr ? stderr.toString() : "",
|
|
2858
|
-
exitCode: 0
|
|
2859
|
-
};
|
|
2860
|
-
} catch (error) {
|
|
2861
|
-
const execError = error;
|
|
2862
|
-
if (execError.code === "ETIMEDOUT" || execError.killed) {
|
|
2863
|
-
return {
|
|
2864
|
-
success: false,
|
|
2865
|
-
stdout: execError.stdout || "",
|
|
2866
|
-
stderr: execError.stderr || "",
|
|
2867
|
-
exitCode: typeof execError.code === "number" ? execError.code : -1,
|
|
2868
|
-
error: "Command timed out"
|
|
2869
|
-
};
|
|
2870
|
-
}
|
|
2871
|
-
return {
|
|
2872
|
-
success: false,
|
|
2873
|
-
stdout: execError.stdout ? execError.stdout.toString() : "",
|
|
2874
|
-
stderr: execError.stderr ? execError.stderr.toString() : execError.message || "Command failed",
|
|
2875
|
-
exitCode: typeof execError.code === "number" ? execError.code : 1,
|
|
2876
|
-
error: execError.message || "Command failed"
|
|
2877
|
-
};
|
|
2878
|
-
}
|
|
2879
|
-
});
|
|
2880
|
-
session.setHandler("readFile", async (data) => {
|
|
2881
|
-
types.logger.debug("Read file request:", data.path);
|
|
2882
|
-
try {
|
|
2883
|
-
const buffer = await fs.readFile(data.path);
|
|
2884
|
-
const content = buffer.toString("base64");
|
|
2885
|
-
return { success: true, content };
|
|
2886
|
-
} catch (error) {
|
|
2887
|
-
types.logger.debug("Failed to read file:", error);
|
|
2888
|
-
return { success: false, error: error instanceof Error ? error.message : "Failed to read file" };
|
|
2889
|
-
}
|
|
2890
|
-
});
|
|
2891
|
-
session.setHandler("writeFile", async (data) => {
|
|
2892
|
-
types.logger.debug("Write file request:", data.path);
|
|
2893
|
-
try {
|
|
2894
|
-
if (data.expectedHash !== null && data.expectedHash !== void 0) {
|
|
2895
|
-
try {
|
|
2896
|
-
const existingBuffer = await fs.readFile(data.path);
|
|
2897
|
-
const existingHash = crypto.createHash("sha256").update(existingBuffer).digest("hex");
|
|
2898
|
-
if (existingHash !== data.expectedHash) {
|
|
2899
|
-
return {
|
|
2900
|
-
success: false,
|
|
2901
|
-
error: `File hash mismatch. Expected: ${data.expectedHash}, Actual: ${existingHash}`
|
|
2902
|
-
};
|
|
2903
|
-
}
|
|
2904
|
-
} catch (error) {
|
|
2905
|
-
const nodeError = error;
|
|
2906
|
-
if (nodeError.code !== "ENOENT") {
|
|
2907
|
-
throw error;
|
|
2908
|
-
}
|
|
2909
|
-
return {
|
|
2910
|
-
success: false,
|
|
2911
|
-
error: "File does not exist but hash was provided"
|
|
2912
|
-
};
|
|
2913
|
-
}
|
|
2914
|
-
} else {
|
|
2915
|
-
try {
|
|
2916
|
-
await fs.stat(data.path);
|
|
2917
|
-
return {
|
|
2918
|
-
success: false,
|
|
2919
|
-
error: "File already exists but was expected to be new"
|
|
2920
|
-
};
|
|
2921
|
-
} catch (error) {
|
|
2922
|
-
const nodeError = error;
|
|
2923
|
-
if (nodeError.code !== "ENOENT") {
|
|
2924
|
-
throw error;
|
|
2925
|
-
}
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
|
-
const buffer = Buffer.from(data.content, "base64");
|
|
2929
|
-
await fs.writeFile(data.path, buffer);
|
|
2930
|
-
const hash = crypto.createHash("sha256").update(buffer).digest("hex");
|
|
2931
|
-
return { success: true, hash };
|
|
2932
|
-
} catch (error) {
|
|
2933
|
-
types.logger.debug("Failed to write file:", error);
|
|
2934
|
-
return { success: false, error: error instanceof Error ? error.message : "Failed to write file" };
|
|
2935
|
-
}
|
|
2936
|
-
});
|
|
2937
|
-
session.setHandler("listDirectory", async (data) => {
|
|
2938
|
-
types.logger.debug("List directory request:", data.path);
|
|
2939
|
-
try {
|
|
2940
|
-
const entries = await fs.readdir(data.path, { withFileTypes: true });
|
|
2941
|
-
const directoryEntries = await Promise.all(
|
|
2942
|
-
entries.map(async (entry) => {
|
|
2943
|
-
const fullPath = path.join(data.path, entry.name);
|
|
2944
|
-
let type = "other";
|
|
2945
|
-
let size;
|
|
2946
|
-
let modified;
|
|
2947
|
-
if (entry.isDirectory()) {
|
|
2948
|
-
type = "directory";
|
|
2949
|
-
} else if (entry.isFile()) {
|
|
2950
|
-
type = "file";
|
|
2951
|
-
}
|
|
2952
|
-
try {
|
|
2953
|
-
const stats = await fs.stat(fullPath);
|
|
2954
|
-
size = stats.size;
|
|
2955
|
-
modified = stats.mtime.getTime();
|
|
2956
|
-
} catch (error) {
|
|
2957
|
-
types.logger.debug(`Failed to stat ${fullPath}:`, error);
|
|
2958
|
-
}
|
|
2959
|
-
return {
|
|
2960
|
-
name: entry.name,
|
|
2961
|
-
type,
|
|
2962
|
-
size,
|
|
2963
|
-
modified
|
|
2964
|
-
};
|
|
2965
|
-
})
|
|
2966
|
-
);
|
|
2967
|
-
directoryEntries.sort((a, b) => {
|
|
2968
|
-
if (a.type === "directory" && b.type !== "directory") return -1;
|
|
2969
|
-
if (a.type !== "directory" && b.type === "directory") return 1;
|
|
2970
|
-
return a.name.localeCompare(b.name);
|
|
2971
|
-
});
|
|
2972
|
-
return { success: true, entries: directoryEntries };
|
|
2973
|
-
} catch (error) {
|
|
2974
|
-
types.logger.debug("Failed to list directory:", error);
|
|
2975
|
-
return { success: false, error: error instanceof Error ? error.message : "Failed to list directory" };
|
|
2976
|
-
}
|
|
2977
|
-
});
|
|
2978
|
-
session.setHandler("getDirectoryTree", async (data) => {
|
|
2979
|
-
types.logger.debug("Get directory tree request:", data.path, "maxDepth:", data.maxDepth);
|
|
2980
|
-
async function buildTree(path$1, name, currentDepth) {
|
|
2981
|
-
try {
|
|
2982
|
-
const stats = await fs.stat(path$1);
|
|
2983
|
-
const node = {
|
|
2984
|
-
name,
|
|
2985
|
-
path: path$1,
|
|
2986
|
-
type: stats.isDirectory() ? "directory" : "file",
|
|
2987
|
-
size: stats.size,
|
|
2988
|
-
modified: stats.mtime.getTime()
|
|
2989
|
-
};
|
|
2990
|
-
if (stats.isDirectory() && currentDepth < data.maxDepth) {
|
|
2991
|
-
const entries = await fs.readdir(path$1, { withFileTypes: true });
|
|
2992
|
-
const children = [];
|
|
2993
|
-
await Promise.all(
|
|
2994
|
-
entries.map(async (entry) => {
|
|
2995
|
-
if (entry.isSymbolicLink()) {
|
|
2996
|
-
types.logger.debug(`Skipping symlink: ${path.join(path$1, entry.name)}`);
|
|
2997
|
-
return;
|
|
2998
|
-
}
|
|
2999
|
-
const childPath = path.join(path$1, entry.name);
|
|
3000
|
-
const childNode = await buildTree(childPath, entry.name, currentDepth + 1);
|
|
3001
|
-
if (childNode) {
|
|
3002
|
-
children.push(childNode);
|
|
3003
|
-
}
|
|
3004
|
-
})
|
|
3005
|
-
);
|
|
3006
|
-
children.sort((a, b) => {
|
|
3007
|
-
if (a.type === "directory" && b.type !== "directory") return -1;
|
|
3008
|
-
if (a.type !== "directory" && b.type === "directory") return 1;
|
|
3009
|
-
return a.name.localeCompare(b.name);
|
|
3010
|
-
});
|
|
3011
|
-
node.children = children;
|
|
3012
|
-
}
|
|
3013
|
-
return node;
|
|
3014
|
-
} catch (error) {
|
|
3015
|
-
types.logger.debug(`Failed to process ${path$1}:`, error instanceof Error ? error.message : String(error));
|
|
3016
|
-
return null;
|
|
3017
|
-
}
|
|
3018
|
-
}
|
|
3019
|
-
try {
|
|
3020
|
-
if (data.maxDepth < 0) {
|
|
3021
|
-
return { success: false, error: "maxDepth must be non-negative" };
|
|
3022
|
-
}
|
|
3023
|
-
const baseName = data.path === "/" ? "/" : data.path.split("/").pop() || data.path;
|
|
3024
|
-
const tree = await buildTree(data.path, baseName, 0);
|
|
3025
|
-
if (!tree) {
|
|
3026
|
-
return { success: false, error: "Failed to access the specified path" };
|
|
3027
|
-
}
|
|
3028
|
-
return { success: true, tree };
|
|
3029
|
-
} catch (error) {
|
|
3030
|
-
types.logger.debug("Failed to get directory tree:", error);
|
|
3031
|
-
return { success: false, error: error instanceof Error ? error.message : "Failed to get directory tree" };
|
|
3032
|
-
}
|
|
3033
|
-
});
|
|
3034
|
-
session.setHandler("ripgrep", async (data) => {
|
|
3035
|
-
types.logger.debug("Ripgrep request with args:", data.args, "cwd:", data.cwd);
|
|
3036
|
-
try {
|
|
3037
|
-
const result = await run(data.args, { cwd: data.cwd });
|
|
3038
|
-
return {
|
|
3039
|
-
success: true,
|
|
3040
|
-
exitCode: result.exitCode,
|
|
3041
|
-
stdout: result.stdout.toString(),
|
|
3042
|
-
stderr: result.stderr.toString()
|
|
3043
|
-
};
|
|
3044
|
-
} catch (error) {
|
|
3045
|
-
types.logger.debug("Failed to run ripgrep:", error);
|
|
3046
|
-
return {
|
|
3047
|
-
success: false,
|
|
3048
|
-
error: error instanceof Error ? error.message : "Failed to run ripgrep"
|
|
3049
|
-
};
|
|
3050
|
-
}
|
|
3051
|
-
});
|
|
3052
|
-
}
|
|
3053
|
-
function registerKillSessionHandler(session, killThisHappy) {
|
|
3054
|
-
session.setHandler("killSession", async () => {
|
|
3055
|
-
types.logger.debug("Kill session request received");
|
|
3056
|
-
void killThisHappy();
|
|
3057
|
-
return {
|
|
3058
|
-
success: true,
|
|
3059
|
-
message: "Killing happy-cli process"
|
|
3060
|
-
};
|
|
3061
|
-
});
|
|
3062
|
-
}
|
|
3063
|
-
|
|
3064
2809
|
class MessageQueue2 {
|
|
3065
2810
|
queue = [];
|
|
3066
2811
|
// Made public for testing
|
|
@@ -3607,7 +3352,7 @@ async function isDaemonRunningCurrentlyInstalledHappyVersion() {
|
|
|
3607
3352
|
return false;
|
|
3608
3353
|
}
|
|
3609
3354
|
try {
|
|
3610
|
-
const packageJsonPath = path.join(projectPath(), "package.json");
|
|
3355
|
+
const packageJsonPath = path.join(types.projectPath(), "package.json");
|
|
3611
3356
|
const packageJson = JSON.parse(fs$1.readFileSync(packageJsonPath, "utf-8"));
|
|
3612
3357
|
const currentCliVersion = packageJson.version;
|
|
3613
3358
|
types.logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
|
|
@@ -3784,7 +3529,7 @@ async function runDoctorCommand(filter) {
|
|
|
3784
3529
|
console.log(`Node.js Version: ${chalk.green(process.version)}`);
|
|
3785
3530
|
console.log("");
|
|
3786
3531
|
console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
|
|
3787
|
-
const projectRoot = projectPath();
|
|
3532
|
+
const projectRoot = types.projectPath();
|
|
3788
3533
|
const wrapperPath = node_path.join(projectRoot, "bin", "happy.mjs");
|
|
3789
3534
|
const cliEntrypoint = node_path.join(projectRoot, "dist", "index.mjs");
|
|
3790
3535
|
console.log(`Project Root: ${chalk.blue(projectRoot)}`);
|
|
@@ -4157,7 +3902,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
4157
3902
|
}
|
|
4158
3903
|
|
|
4159
3904
|
function spawnHappyCLI(args, options = {}) {
|
|
4160
|
-
const projectRoot = projectPath();
|
|
3905
|
+
const projectRoot = types.projectPath();
|
|
4161
3906
|
const entrypoint = node_path.join(projectRoot, "dist", "index.mjs");
|
|
4162
3907
|
let directory;
|
|
4163
3908
|
if ("cwd" in options) {
|
|
@@ -4624,7 +4369,7 @@ async function startDaemon() {
|
|
|
4624
4369
|
startedAt: Date.now()
|
|
4625
4370
|
};
|
|
4626
4371
|
const api = new types.ApiClient(credentials.token, credentials.secret);
|
|
4627
|
-
const machine = await api.
|
|
4372
|
+
const machine = await api.getOrCreateMachine({
|
|
4628
4373
|
machineId,
|
|
4629
4374
|
metadata: initialMachineMetadata,
|
|
4630
4375
|
daemonState: initialDaemonState
|
|
@@ -4655,7 +4400,7 @@ async function startDaemon() {
|
|
|
4655
4400
|
pidToTrackedSession.delete(pid);
|
|
4656
4401
|
}
|
|
4657
4402
|
}
|
|
4658
|
-
const projectVersion = JSON.parse(fs$1.readFileSync(path.join(projectPath(), "package.json"), "utf-8")).version;
|
|
4403
|
+
const projectVersion = JSON.parse(fs$1.readFileSync(path.join(types.projectPath(), "package.json"), "utf-8")).version;
|
|
4659
4404
|
if (projectVersion !== types.configuration.currentCliVersion) {
|
|
4660
4405
|
types.logger.debug("[DAEMON RUN] Daemon is outdated, triggering self-restart with latest version, clearing heartbeat interval");
|
|
4661
4406
|
clearInterval(restartOnStaleVersionAndHeartbeat);
|
|
@@ -4806,6 +4551,17 @@ async function startHappyServer(client) {
|
|
|
4806
4551
|
};
|
|
4807
4552
|
}
|
|
4808
4553
|
|
|
4554
|
+
function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
|
|
4555
|
+
rpcHandlerManager.registerHandler("killSession", async () => {
|
|
4556
|
+
types.logger.debug("Kill session request received");
|
|
4557
|
+
void killThisHappy();
|
|
4558
|
+
return {
|
|
4559
|
+
success: true,
|
|
4560
|
+
message: "Killing happy-cli process"
|
|
4561
|
+
};
|
|
4562
|
+
});
|
|
4563
|
+
}
|
|
4564
|
+
|
|
4809
4565
|
async function start(credentials, options = {}) {
|
|
4810
4566
|
const workingDirectory = process.cwd();
|
|
4811
4567
|
const sessionTag = node_crypto.randomUUID();
|
|
@@ -4824,7 +4580,7 @@ async function start(credentials, options = {}) {
|
|
|
4824
4580
|
process.exit(1);
|
|
4825
4581
|
}
|
|
4826
4582
|
types.logger.debug(`Using machineId: ${machineId}`);
|
|
4827
|
-
await api.
|
|
4583
|
+
await api.getOrCreateMachine({
|
|
4828
4584
|
machineId,
|
|
4829
4585
|
metadata: initialMachineMetadata
|
|
4830
4586
|
});
|
|
@@ -4892,7 +4648,6 @@ async function start(credentials, options = {}) {
|
|
|
4892
4648
|
allowedTools: mode.allowedTools,
|
|
4893
4649
|
disallowedTools: mode.disallowedTools
|
|
4894
4650
|
}));
|
|
4895
|
-
registerHandlers(session);
|
|
4896
4651
|
let currentPermissionMode = options.permissionMode;
|
|
4897
4652
|
let currentModel = options.model;
|
|
4898
4653
|
let currentFallbackModel = void 0;
|
|
@@ -5039,7 +4794,7 @@ async function start(credentials, options = {}) {
|
|
|
5039
4794
|
types.logger.debug("[START] Unhandled rejection:", reason);
|
|
5040
4795
|
cleanup();
|
|
5041
4796
|
});
|
|
5042
|
-
registerKillSessionHandler(session, cleanup);
|
|
4797
|
+
registerKillSessionHandler(session.rpcHandlerManager, cleanup);
|
|
5043
4798
|
await loop({
|
|
5044
4799
|
path: workingDirectory,
|
|
5045
4800
|
model: options.model,
|