@zonease/happy 0.6.38 → 0.6.40

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.
Files changed (112) hide show
  1. package/bin/happy.mjs +10 -0
  2. package/dist/{types-DvTsFaqR.cjs → api-C7FyJfZ1.cjs} +400 -1964
  3. package/dist/{types-BWpRU1VN.mjs → api-D6WL40-U.mjs} +220 -1729
  4. package/dist/auth-C7ZScWEw.cjs +274 -0
  5. package/dist/auth-DCsIoZLT.cjs +183 -0
  6. package/dist/auth-DO9GexAR.mjs +181 -0
  7. package/dist/auth-DxJ3VvrX.mjs +270 -0
  8. package/dist/browser-AoVGRX7y.mjs +20 -0
  9. package/dist/browser-DzgO4oaD.cjs +22 -0
  10. package/dist/claudeLocal-C6BdzhDx.cjs +352 -0
  11. package/dist/claudeLocal-CWNGpJ0-.mjs +344 -0
  12. package/dist/codex/happyMcpStdioBridge.cjs +4 -1
  13. package/dist/codex/happyMcpStdioBridge.mjs +4 -1
  14. package/dist/common-BdNgghUJ.mjs +75 -0
  15. package/dist/common-CZvSRU4p.cjs +83 -0
  16. package/dist/{config-0Xnc8ARM.cjs → config-CclB3QW9.cjs} +21 -34
  17. package/dist/{config-_GW4YBCP.mjs → config-DZk-mJ0K.mjs} +7 -20
  18. package/dist/connect-BXLUKJ5P.mjs +679 -0
  19. package/dist/connect-k9CqDJ-T.cjs +681 -0
  20. package/dist/{constants-B4x1K7by.cjs → constants-E_UWYTo3.cjs} +2 -2
  21. package/dist/{constants-BO9OAFOT.mjs → constants-pmXZGibX.mjs} +1 -1
  22. package/dist/controlClient-B23M-WPp.cjs +177 -0
  23. package/dist/controlClient-DB5tDU7V.mjs +167 -0
  24. package/dist/deviceKeys-BTdo34Uz.mjs +175 -0
  25. package/dist/deviceKeys-C540DcXl.cjs +182 -0
  26. package/dist/diagnose-B3D1a_v0.cjs +60 -0
  27. package/dist/diagnose-CuRKXxt1.mjs +58 -0
  28. package/dist/doctor-BQGLhrcI.cjs +214 -0
  29. package/dist/doctor-C08m5Z9f.cjs +78 -0
  30. package/dist/doctor-CU4JLGQ1.mjs +211 -0
  31. package/dist/doctor-ON7pN5G5.mjs +74 -0
  32. package/dist/downloadImage-DZXI3mXL.mjs +887 -0
  33. package/dist/downloadImage-cQ1Z7hkC.cjs +897 -0
  34. package/dist/enroll-B55BQR56.mjs +113 -0
  35. package/dist/enroll-Bo-CNio1.cjs +115 -0
  36. package/dist/evidence-DQp8QWcv.cjs +129 -0
  37. package/dist/evidence-DTYRAaOZ.mjs +127 -0
  38. package/dist/formatImageMessage-CixDYY6G.cjs +46 -0
  39. package/dist/formatImageMessage-DbKSSjMx.mjs +43 -0
  40. package/dist/github-DKcyF1zp.mjs +57 -0
  41. package/dist/github-h9GhJJ_C.cjs +59 -0
  42. package/dist/index-CDTNgfUf.cjs +578 -0
  43. package/dist/index-CPKdvi7J.mjs +554 -0
  44. package/dist/index.cjs +812 -40
  45. package/dist/index.mjs +813 -40
  46. package/dist/install-B1e6rdy7.mjs +94 -0
  47. package/dist/install-CgUPGIoF.mjs +95 -0
  48. package/dist/install-D7Ir7ciZ.cjs +96 -0
  49. package/dist/install-DSDufaPd.cjs +98 -0
  50. package/dist/lib.cjs +18 -12
  51. package/dist/lib.d.cts +77 -0
  52. package/dist/lib.d.mts +77 -0
  53. package/dist/lib.mjs +13 -7
  54. package/dist/{loadableToolOutput-va3RLplh.mjs → loadableToolOutput-Bfei9wPq.mjs} +4 -2
  55. package/dist/{loadableToolOutput-5vdQB98M.cjs → loadableToolOutput-CbLGtvST.cjs} +63 -61
  56. package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
  57. package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
  58. package/dist/persistence-CBTtC_dm.cjs +996 -0
  59. package/dist/persistence-DKfF81pd.mjs +944 -0
  60. package/dist/projectPath-BTBIMB57.mjs +10 -0
  61. package/dist/projectPath-ChLhdOyt.cjs +13 -0
  62. package/dist/prompt-BTWDZZO0.cjs +25 -0
  63. package/dist/prompt-BsAZsPbo.mjs +22 -0
  64. package/dist/release-BMEzNONE.mjs +168 -0
  65. package/dist/release-EhOJeAZe.cjs +171 -0
  66. package/dist/run-BVZsMNwN.mjs +2164 -0
  67. package/dist/run-CURx7LhK.cjs +2188 -0
  68. package/dist/runClaude-6Gi0sYQy.mjs +3763 -0
  69. package/dist/runClaude-CL3Kt5ex.cjs +3766 -0
  70. package/dist/{runCodex-DiKzBf9q.mjs → runCodex-ClwEgJ7M.mjs} +36 -20
  71. package/dist/{runCodex-skq0j05d.cjs → runCodex-YKyVBkJ3.cjs} +169 -153
  72. package/dist/{runGemini-BeqrVq8R.mjs → runGemini-BPWxVr60.mjs} +34 -17
  73. package/dist/{runGemini-CVp-CEIh.cjs → runGemini-Xz2W1spn.cjs} +212 -195
  74. package/dist/{runOneShot-ltCpHbBB.mjs → runOneShot-CdCWiiLr.mjs} +14 -38
  75. package/dist/{runOneShot-BQNkNW61.cjs → runOneShot-DjZyCvDI.cjs} +31 -55
  76. package/dist/{serve-BNdoEDVx.mjs → serve-B48JttQ3.mjs} +12 -35
  77. package/dist/{serve-BECdtivY.cjs → serve-B8vaWQA0.cjs} +35 -58
  78. package/dist/session-BXboDn2V.mjs +108 -0
  79. package/dist/session-BZO25zxp.cjs +110 -0
  80. package/dist/sessionKeyCache-B6cGadYL.mjs +33 -0
  81. package/dist/sessionKeyCache-CDmexJ9p.cjs +36 -0
  82. package/dist/sessionList-CgAYZpNj.mjs +51 -0
  83. package/dist/sessionList-lQ-nqEhc.cjs +54 -0
  84. package/dist/sessionSummary-CcORiQSq.cjs +393 -0
  85. package/dist/sessionSummary-DCWQoaDP.mjs +387 -0
  86. package/dist/spawnHappyCLI-KiazE3kL.cjs +70 -0
  87. package/dist/spawnHappyCLI-yBIP_Oqi.mjs +66 -0
  88. package/dist/ssh-q5uZhqBf.mjs +359 -0
  89. package/dist/ssh-yMllSHu5.cjs +365 -0
  90. package/dist/systemdScope-BeOtAkhk.mjs +25 -0
  91. package/dist/systemdScope-DW3-UoKB.cjs +29 -0
  92. package/dist/task-_nr7J19j.cjs +167 -0
  93. package/dist/task-wNX1N2i4.mjs +165 -0
  94. package/dist/time-Bj2HRkKH.cjs +33 -0
  95. package/dist/time-DgsBLJA_.mjs +29 -0
  96. package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
  97. package/dist/trimIdent-BAjmv_TG.mjs +20 -0
  98. package/dist/types-BoJh4Qfv.mjs +57 -0
  99. package/dist/types-DWeB7aqh.cjs +59 -0
  100. package/dist/uninstall-Buaz7d-X.cjs +77 -0
  101. package/dist/uninstall-Dxf6_4mQ.mjs +75 -0
  102. package/dist/update-CGlIfa8e.cjs +111 -0
  103. package/dist/update-CnnoX2cV.mjs +109 -0
  104. package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
  105. package/dist/workflowCommon-Bl568-rt.cjs +62 -0
  106. package/dist/workflowReports-BEWuQesA.cjs +113 -0
  107. package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
  108. package/package.json +1 -1
  109. package/dist/index-BbCDDvoB.cjs +0 -11376
  110. package/dist/index-vvZXdswy.mjs +0 -11336
  111. package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
  112. package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+ var workflowReports = require('./workflowReports-BEWuQesA.cjs');
5
+ var workflowCommon = require('./workflowCommon-Bl568-rt.cjs');
6
+ require('node:path');
7
+ require('node:fs/promises');
8
+
9
+ function printDiagnoseHelp() {
10
+ console.log(`
11
+ ${chalk.bold("happy diagnose")} - Diagnosis evidence helpers
12
+
13
+ ${chalk.bold("Usage:")}
14
+ happy diagnose remote --host <host> [options]
15
+
16
+ ${chalk.bold("Options:")}
17
+ --host <host> SSH host alias or user@host
18
+ --service <name> Service/container name for docker logs
19
+ --keyword <text> Keyword to grep in logs
20
+ --since <duration> Log window, e.g. "2 hours ago" or "2026-05-13 10:00"
21
+ --health-url <url> Health endpoint to curl on the host
22
+ --out <path> Write the evidence pack to a markdown file
23
+ --json Print machine-readable JSON
24
+ -h, --help Show this help
25
+ `);
26
+ }
27
+ async function handleDiagnoseCommand(args) {
28
+ const action = args[0];
29
+ if (!action || action === "-h" || action === "--help") {
30
+ printDiagnoseHelp();
31
+ return;
32
+ }
33
+ if (action !== "remote") {
34
+ throw new Error(`Unknown diagnose command: ${action}. Use "happy diagnose remote".`);
35
+ }
36
+ const parsed = workflowCommon.parseWorkflowArgs(args.slice(1), /* @__PURE__ */ new Set(["--host", "--service", "--keyword", "--since", "--health-url", "--out"]));
37
+ if (workflowCommon.booleanFlag(parsed, "--help") || workflowCommon.booleanFlag(parsed, "-h")) {
38
+ printDiagnoseHelp();
39
+ return;
40
+ }
41
+ const host = workflowCommon.stringFlag(parsed, "--host") ?? parsed.positionals[0];
42
+ if (!host) {
43
+ throw new Error("--host is required.");
44
+ }
45
+ const input = {
46
+ host,
47
+ service: workflowCommon.stringFlag(parsed, "--service"),
48
+ keyword: workflowCommon.stringFlag(parsed, "--keyword"),
49
+ since: workflowCommon.stringFlag(parsed, "--since") ?? "2 hours ago",
50
+ healthUrl: workflowCommon.stringFlag(parsed, "--health-url")
51
+ };
52
+ const report = workflowReports.buildRemoteDiagnoseReport(input);
53
+ if (workflowCommon.booleanFlag(parsed, "--json")) {
54
+ console.log(JSON.stringify({ ...input, report }, null, 2));
55
+ return;
56
+ }
57
+ await workflowCommon.printOrWriteOutput(report, workflowCommon.stringFlag(parsed, "--out"));
58
+ }
59
+
60
+ exports.handleDiagnoseCommand = handleDiagnoseCommand;
@@ -0,0 +1,58 @@
1
+ import chalk from 'chalk';
2
+ import { a as buildRemoteDiagnoseReport } from './workflowReports-Dd8-4-8f.mjs';
3
+ import { p as parseWorkflowArgs, b as booleanFlag, s as stringFlag, a as printOrWriteOutput } from './workflowCommon-B0d01Y_a.mjs';
4
+ import 'node:path';
5
+ import 'node:fs/promises';
6
+
7
+ function printDiagnoseHelp() {
8
+ console.log(`
9
+ ${chalk.bold("happy diagnose")} - Diagnosis evidence helpers
10
+
11
+ ${chalk.bold("Usage:")}
12
+ happy diagnose remote --host <host> [options]
13
+
14
+ ${chalk.bold("Options:")}
15
+ --host <host> SSH host alias or user@host
16
+ --service <name> Service/container name for docker logs
17
+ --keyword <text> Keyword to grep in logs
18
+ --since <duration> Log window, e.g. "2 hours ago" or "2026-05-13 10:00"
19
+ --health-url <url> Health endpoint to curl on the host
20
+ --out <path> Write the evidence pack to a markdown file
21
+ --json Print machine-readable JSON
22
+ -h, --help Show this help
23
+ `);
24
+ }
25
+ async function handleDiagnoseCommand(args) {
26
+ const action = args[0];
27
+ if (!action || action === "-h" || action === "--help") {
28
+ printDiagnoseHelp();
29
+ return;
30
+ }
31
+ if (action !== "remote") {
32
+ throw new Error(`Unknown diagnose command: ${action}. Use "happy diagnose remote".`);
33
+ }
34
+ const parsed = parseWorkflowArgs(args.slice(1), /* @__PURE__ */ new Set(["--host", "--service", "--keyword", "--since", "--health-url", "--out"]));
35
+ if (booleanFlag(parsed, "--help") || booleanFlag(parsed, "-h")) {
36
+ printDiagnoseHelp();
37
+ return;
38
+ }
39
+ const host = stringFlag(parsed, "--host") ?? parsed.positionals[0];
40
+ if (!host) {
41
+ throw new Error("--host is required.");
42
+ }
43
+ const input = {
44
+ host,
45
+ service: stringFlag(parsed, "--service"),
46
+ keyword: stringFlag(parsed, "--keyword"),
47
+ since: stringFlag(parsed, "--since") ?? "2 hours ago",
48
+ healthUrl: stringFlag(parsed, "--health-url")
49
+ };
50
+ const report = buildRemoteDiagnoseReport(input);
51
+ if (booleanFlag(parsed, "--json")) {
52
+ console.log(JSON.stringify({ ...input, report }, null, 2));
53
+ return;
54
+ }
55
+ await printOrWriteOutput(report, stringFlag(parsed, "--out"));
56
+ }
57
+
58
+ export { handleDiagnoseCommand };
@@ -0,0 +1,214 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+ var logger = require('./persistence-CBTtC_dm.cjs');
5
+ var controlClient = require('./controlClient-B23M-WPp.cjs');
6
+ var doctor = require('./doctor-C08m5Z9f.cjs');
7
+ var fs = require('node:fs');
8
+ var path = require('node:path');
9
+ var projectPath = require('./projectPath-ChLhdOyt.cjs');
10
+ require('node:fs/promises');
11
+ require('node:os');
12
+ require('zod');
13
+ require('node:crypto');
14
+ require('tweetnacl');
15
+ require('fs');
16
+ require('path');
17
+ require('ps-list');
18
+ require('cross-spawn');
19
+ require('url');
20
+
21
+ function getEnvironmentInfo() {
22
+ return {
23
+ PWD: process.env.PWD,
24
+ HAPPY_HOME_DIR: process.env.HAPPY_HOME_DIR,
25
+ HAPPY_SERVER_URL: process.env.HAPPY_SERVER_URL,
26
+ HAPPY_PROJECT_ROOT: process.env.HAPPY_PROJECT_ROOT,
27
+ DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING: process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING,
28
+ NODE_ENV: process.env.NODE_ENV,
29
+ DEBUG: process.env.DEBUG,
30
+ workingDirectory: process.cwd(),
31
+ processArgv: process.argv,
32
+ happyDir: logger.configuration?.happyHomeDir,
33
+ serverUrl: logger.configuration?.serverUrl,
34
+ logsDir: logger.configuration?.logsDir,
35
+ processPid: process.pid,
36
+ nodeVersion: process.version,
37
+ platform: process.platform,
38
+ arch: process.arch,
39
+ user: process.env.USER,
40
+ home: process.env.HOME,
41
+ shell: process.env.SHELL,
42
+ terminal: process.env.TERM
43
+ };
44
+ }
45
+ function getLogFiles(logDir) {
46
+ if (!fs.existsSync(logDir)) {
47
+ return [];
48
+ }
49
+ try {
50
+ return fs.readdirSync(logDir).filter((file) => file.endsWith(".log")).map((file) => {
51
+ const path$1 = path.join(logDir, file);
52
+ const stats = fs.statSync(path$1);
53
+ return { file, path: path$1, modified: stats.mtime };
54
+ }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
55
+ } catch {
56
+ return [];
57
+ }
58
+ }
59
+ async function runDoctorCommand(filter) {
60
+ if (!filter) {
61
+ filter = "all";
62
+ }
63
+ console.log(chalk.bold.cyan("\n\u{1FA7A} Happy AI CLI Doctor\n"));
64
+ if (filter === "all") {
65
+ console.log(chalk.bold("\u{1F4CB} Basic Information"));
66
+ console.log(`Happy AI CLI Version: ${chalk.green(logger.packageJson.version)}`);
67
+ console.log(`Platform: ${chalk.green(process.platform)} ${process.arch}`);
68
+ console.log(`Node.js Version: ${chalk.green(process.version)}`);
69
+ console.log("");
70
+ console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
71
+ const projectRoot = projectPath.projectPath();
72
+ const wrapperPath = path.join(projectRoot, "bin", "happy.mjs");
73
+ const cliEntrypoint = path.join(projectRoot, "dist", "index.mjs");
74
+ console.log(`Project Root: ${chalk.blue(projectRoot)}`);
75
+ console.log(`Wrapper Script: ${chalk.blue(wrapperPath)}`);
76
+ console.log(`CLI Entrypoint: ${chalk.blue(cliEntrypoint)}`);
77
+ console.log(`Wrapper Exists: ${fs.existsSync(wrapperPath) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
78
+ console.log(`CLI Exists: ${fs.existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
79
+ console.log("");
80
+ console.log(chalk.bold("\u2699\uFE0F Configuration"));
81
+ console.log(`Happy AI Home: ${chalk.blue(logger.configuration.happyHomeDir)}`);
82
+ console.log(`Server URL: ${chalk.blue(logger.configuration.serverUrl)}`);
83
+ console.log(`Logs Dir: ${chalk.blue(logger.configuration.logsDir)}`);
84
+ console.log(chalk.bold("\n\u{1F30D} Environment Variables"));
85
+ const env = getEnvironmentInfo();
86
+ console.log(`HAPPY_HOME_DIR: ${env.HAPPY_HOME_DIR ? chalk.green(env.HAPPY_HOME_DIR) : chalk.gray("not set")}`);
87
+ console.log(`HAPPY_SERVER_URL: ${env.HAPPY_SERVER_URL ? chalk.green(env.HAPPY_SERVER_URL) : chalk.gray("not set")}`);
88
+ console.log(`DANGEROUSLY_LOG_TO_SERVER: ${env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING ? chalk.yellow("ENABLED") : chalk.gray("not set")}`);
89
+ console.log(`DEBUG: ${env.DEBUG ? chalk.green(env.DEBUG) : chalk.gray("not set")}`);
90
+ console.log(`NODE_ENV: ${env.NODE_ENV ? chalk.green(env.NODE_ENV) : chalk.gray("not set")}`);
91
+ try {
92
+ const settings = await logger.readSettings();
93
+ console.log(chalk.bold("\n\u{1F4C4} Settings (settings.json):"));
94
+ console.log(chalk.gray(JSON.stringify(settings, null, 2)));
95
+ } catch (error) {
96
+ console.log(chalk.bold("\n\u{1F4C4} Settings:"));
97
+ console.log(chalk.red("\u274C Failed to read settings"));
98
+ }
99
+ console.log(chalk.bold("\n\u{1F510} Authentication"));
100
+ try {
101
+ const credentials = await logger.readCredentials();
102
+ if (credentials) {
103
+ console.log(chalk.green("\u2713 Authenticated (credentials found)"));
104
+ } else {
105
+ console.log(chalk.yellow("\u26A0\uFE0F Not authenticated (no credentials)"));
106
+ }
107
+ } catch (error) {
108
+ console.log(chalk.red("\u274C Error reading credentials"));
109
+ }
110
+ }
111
+ console.log(chalk.bold("\n\u{1F916} Daemon Status"));
112
+ try {
113
+ const isRunning = await controlClient.checkIfDaemonRunningAndCleanupStaleState();
114
+ const state = await logger.readDaemonState();
115
+ if (isRunning && state) {
116
+ console.log(chalk.green("\u2713 Daemon is running"));
117
+ console.log(` PID: ${state.pid}`);
118
+ console.log(` Started: ${new Date(state.startTime).toLocaleString()}`);
119
+ console.log(` CLI Version: ${state.startedWithCliVersion}`);
120
+ if (state.httpPort) {
121
+ console.log(` HTTP Port: ${state.httpPort}`);
122
+ }
123
+ } else if (state && !isRunning) {
124
+ console.log(chalk.yellow("\u26A0\uFE0F Daemon state exists but process not running (stale)"));
125
+ } else {
126
+ console.log(chalk.red("\u274C Daemon is not running"));
127
+ }
128
+ if (state) {
129
+ console.log(chalk.bold("\n\u{1F4C4} Daemon State:"));
130
+ console.log(chalk.blue(`Location: ${logger.configuration.daemonStateFile}`));
131
+ console.log(chalk.gray(JSON.stringify(state, null, 2)));
132
+ }
133
+ const allProcesses = await doctor.findAllHappyProcesses();
134
+ if (allProcesses.length > 0) {
135
+ console.log(chalk.bold("\n\u{1F50D} All Happy CLI Processes"));
136
+ const grouped = allProcesses.reduce((groups, process2) => {
137
+ if (!groups[process2.type]) groups[process2.type] = [];
138
+ groups[process2.type].push(process2);
139
+ return groups;
140
+ }, {});
141
+ Object.entries(grouped).forEach(([type, processes]) => {
142
+ const typeLabels = {
143
+ "current": "\u{1F4CD} Current Process",
144
+ "daemon": "\u{1F916} Daemon",
145
+ "daemon-version-check": "\u{1F50D} Daemon Version Check (stuck)",
146
+ "daemon-spawned-session": "\u{1F517} Daemon-Spawned Sessions",
147
+ "user-session": "\u{1F464} User Sessions",
148
+ "dev-daemon": "\u{1F6E0}\uFE0F Dev Daemon",
149
+ "dev-daemon-version-check": "\u{1F6E0}\uFE0F Dev Daemon Version Check (stuck)",
150
+ "dev-session": "\u{1F6E0}\uFE0F Dev Sessions",
151
+ "dev-doctor": "\u{1F6E0}\uFE0F Dev Doctor",
152
+ "dev-related": "\u{1F6E0}\uFE0F Dev Related",
153
+ "doctor": "\u{1FA7A} Doctor",
154
+ "unknown": "\u2753 Unknown"
155
+ };
156
+ console.log(chalk.blue(`
157
+ ${typeLabels[type] || type}:`));
158
+ processes.forEach(({ pid, command }) => {
159
+ const color = type === "current" ? chalk.green : type.startsWith("dev") ? chalk.cyan : type.includes("daemon") ? chalk.blue : chalk.gray;
160
+ console.log(` ${color(`PID ${pid}`)}: ${chalk.gray(command)}`);
161
+ });
162
+ });
163
+ } else {
164
+ console.log(chalk.red("\u274C No happy processes found"));
165
+ }
166
+ if (filter === "all" && allProcesses.length > 1) {
167
+ console.log(chalk.bold("\n\u{1F4A1} Process Management"));
168
+ console.log(chalk.gray("To clean up runaway processes: happy doctor clean"));
169
+ }
170
+ } catch (error) {
171
+ console.log(chalk.red("\u274C Error checking daemon status"));
172
+ }
173
+ if (filter === "all") {
174
+ console.log(chalk.bold("\n\u{1F4DD} Log Files"));
175
+ const allLogs = getLogFiles(logger.configuration.logsDir);
176
+ if (allLogs.length > 0) {
177
+ const daemonLogs = allLogs.filter(({ file }) => file.includes("daemon"));
178
+ const regularLogs = allLogs.filter(({ file }) => !file.includes("daemon"));
179
+ if (regularLogs.length > 0) {
180
+ console.log(chalk.blue("\nRecent Logs:"));
181
+ const logsToShow = regularLogs.slice(0, 10);
182
+ logsToShow.forEach(({ file, path, modified }) => {
183
+ console.log(` ${chalk.green(file)} - ${modified.toLocaleString()}`);
184
+ console.log(chalk.gray(` ${path}`));
185
+ });
186
+ if (regularLogs.length > 10) {
187
+ console.log(chalk.gray(` ... and ${regularLogs.length - 10} more log files`));
188
+ }
189
+ }
190
+ if (daemonLogs.length > 0) {
191
+ console.log(chalk.blue("\nDaemon Logs:"));
192
+ const daemonLogsToShow = daemonLogs.slice(0, 5);
193
+ daemonLogsToShow.forEach(({ file, path, modified }) => {
194
+ console.log(` ${chalk.green(file)} - ${modified.toLocaleString()}`);
195
+ console.log(chalk.gray(` ${path}`));
196
+ });
197
+ if (daemonLogs.length > 5) {
198
+ console.log(chalk.gray(` ... and ${daemonLogs.length - 5} more daemon log files`));
199
+ }
200
+ } else {
201
+ console.log(chalk.yellow("\nNo daemon log files found"));
202
+ }
203
+ } else {
204
+ console.log(chalk.yellow("No log files found"));
205
+ }
206
+ console.log(chalk.bold("\n\u{1F41B} Support & Bug Reports"));
207
+ console.log(`Report issues: ${chalk.blue("https://github.com/ZonEaseTech/happy-wfs/issues")}`);
208
+ console.log(`Documentation: ${chalk.blue("https://github.com/ZonEaseTech/happy-wfs")}`);
209
+ }
210
+ console.log(chalk.green("\n\u2705 Doctor diagnosis complete!\n"));
211
+ }
212
+
213
+ exports.getEnvironmentInfo = getEnvironmentInfo;
214
+ exports.runDoctorCommand = runDoctorCommand;
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ var psList = require('ps-list');
4
+ var spawn = require('cross-spawn');
5
+
6
+ async function findAllHappyProcesses() {
7
+ try {
8
+ const processes = await psList();
9
+ const allProcesses = [];
10
+ for (const proc of processes) {
11
+ const cmd = proc.cmd || "";
12
+ const name = proc.name || "";
13
+ const isHappy = name.includes("happy") || name === "node" && (cmd.includes("happy-cli") || cmd.includes("dist/index.mjs")) || cmd.includes("happy.mjs") || cmd.includes("@zonease/happy") || cmd.includes("tsx") && cmd.includes("src/index.ts") && cmd.includes("happy-cli");
14
+ if (!isHappy) continue;
15
+ let type = "unknown";
16
+ if (proc.pid === process.pid) {
17
+ type = "current";
18
+ } else if (cmd.includes("--version")) {
19
+ type = cmd.includes("tsx") ? "dev-daemon-version-check" : "daemon-version-check";
20
+ } else if (cmd.includes("daemon start-sync") || cmd.includes("daemon start")) {
21
+ type = cmd.includes("tsx") ? "dev-daemon" : "daemon";
22
+ } else if (cmd.includes("--started-by daemon")) {
23
+ type = cmd.includes("tsx") ? "dev-daemon-spawned" : "daemon-spawned-session";
24
+ } else if (cmd.includes("doctor")) {
25
+ type = cmd.includes("tsx") ? "dev-doctor" : "doctor";
26
+ } else if (cmd.includes("--yolo")) {
27
+ type = "dev-session";
28
+ } else {
29
+ type = cmd.includes("tsx") ? "dev-related" : "user-session";
30
+ }
31
+ allProcesses.push({ pid: proc.pid, command: cmd || name, type });
32
+ }
33
+ return allProcesses;
34
+ } catch (error) {
35
+ return [];
36
+ }
37
+ }
38
+ async function findRunawayHappyProcesses() {
39
+ const allProcesses = await findAllHappyProcesses();
40
+ return allProcesses.filter(
41
+ (p) => p.pid !== process.pid && (p.type === "daemon" || p.type === "dev-daemon" || p.type === "daemon-spawned-session" || p.type === "dev-daemon-spawned" || p.type === "daemon-version-check" || p.type === "dev-daemon-version-check")
42
+ ).map((p) => ({ pid: p.pid, command: p.command }));
43
+ }
44
+ async function killRunawayHappyProcesses() {
45
+ const runawayProcesses = await findRunawayHappyProcesses();
46
+ const errors = [];
47
+ let killed = 0;
48
+ for (const { pid, command } of runawayProcesses) {
49
+ try {
50
+ console.log(`Killing runaway process PID ${pid}: ${command}`);
51
+ if (process.platform === "win32") {
52
+ const result = spawn.sync("taskkill", ["/F", "/PID", pid.toString()], { stdio: "pipe" });
53
+ if (result.error) throw result.error;
54
+ if (result.status !== 0) throw new Error(`taskkill exited with code ${result.status}`);
55
+ } else {
56
+ process.kill(pid, "SIGTERM");
57
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
58
+ const processes = await psList();
59
+ const stillAlive = processes.find((p) => p.pid === pid);
60
+ if (stillAlive) {
61
+ console.log(`Process PID ${pid} ignored SIGTERM, using SIGKILL`);
62
+ process.kill(pid, "SIGKILL");
63
+ }
64
+ }
65
+ console.log(`Successfully killed runaway process PID ${pid}`);
66
+ killed++;
67
+ } catch (error) {
68
+ const errorMessage = error.message;
69
+ errors.push({ pid, error: errorMessage });
70
+ console.log(`Failed to kill process PID ${pid}: ${errorMessage}`);
71
+ }
72
+ }
73
+ return { killed, errors };
74
+ }
75
+
76
+ exports.findAllHappyProcesses = findAllHappyProcesses;
77
+ exports.findRunawayHappyProcesses = findRunawayHappyProcesses;
78
+ exports.killRunawayHappyProcesses = killRunawayHappyProcesses;
@@ -0,0 +1,211 @@
1
+ import chalk from 'chalk';
2
+ import { p as packageJson, c as configuration, a as readSettings, r as readCredentials, j as readDaemonState } from './persistence-DKfF81pd.mjs';
3
+ import { checkIfDaemonRunningAndCleanupStaleState } from './controlClient-DB5tDU7V.mjs';
4
+ import { findAllHappyProcesses } from './doctor-ON7pN5G5.mjs';
5
+ import { existsSync, readdirSync, statSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { p as projectPath } from './projectPath-BTBIMB57.mjs';
8
+ import 'node:fs/promises';
9
+ import 'node:os';
10
+ import 'zod';
11
+ import 'node:crypto';
12
+ import 'tweetnacl';
13
+ import 'fs';
14
+ import 'path';
15
+ import 'ps-list';
16
+ import 'cross-spawn';
17
+ import 'url';
18
+
19
+ function getEnvironmentInfo() {
20
+ return {
21
+ PWD: process.env.PWD,
22
+ HAPPY_HOME_DIR: process.env.HAPPY_HOME_DIR,
23
+ HAPPY_SERVER_URL: process.env.HAPPY_SERVER_URL,
24
+ HAPPY_PROJECT_ROOT: process.env.HAPPY_PROJECT_ROOT,
25
+ DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING: process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING,
26
+ NODE_ENV: process.env.NODE_ENV,
27
+ DEBUG: process.env.DEBUG,
28
+ workingDirectory: process.cwd(),
29
+ processArgv: process.argv,
30
+ happyDir: configuration?.happyHomeDir,
31
+ serverUrl: configuration?.serverUrl,
32
+ logsDir: configuration?.logsDir,
33
+ processPid: process.pid,
34
+ nodeVersion: process.version,
35
+ platform: process.platform,
36
+ arch: process.arch,
37
+ user: process.env.USER,
38
+ home: process.env.HOME,
39
+ shell: process.env.SHELL,
40
+ terminal: process.env.TERM
41
+ };
42
+ }
43
+ function getLogFiles(logDir) {
44
+ if (!existsSync(logDir)) {
45
+ return [];
46
+ }
47
+ try {
48
+ return readdirSync(logDir).filter((file) => file.endsWith(".log")).map((file) => {
49
+ const path = join(logDir, file);
50
+ const stats = statSync(path);
51
+ return { file, path, modified: stats.mtime };
52
+ }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
53
+ } catch {
54
+ return [];
55
+ }
56
+ }
57
+ async function runDoctorCommand(filter) {
58
+ if (!filter) {
59
+ filter = "all";
60
+ }
61
+ console.log(chalk.bold.cyan("\n\u{1FA7A} Happy AI CLI Doctor\n"));
62
+ if (filter === "all") {
63
+ console.log(chalk.bold("\u{1F4CB} Basic Information"));
64
+ console.log(`Happy AI CLI Version: ${chalk.green(packageJson.version)}`);
65
+ console.log(`Platform: ${chalk.green(process.platform)} ${process.arch}`);
66
+ console.log(`Node.js Version: ${chalk.green(process.version)}`);
67
+ console.log("");
68
+ console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
69
+ const projectRoot = projectPath();
70
+ const wrapperPath = join(projectRoot, "bin", "happy.mjs");
71
+ const cliEntrypoint = join(projectRoot, "dist", "index.mjs");
72
+ console.log(`Project Root: ${chalk.blue(projectRoot)}`);
73
+ console.log(`Wrapper Script: ${chalk.blue(wrapperPath)}`);
74
+ console.log(`CLI Entrypoint: ${chalk.blue(cliEntrypoint)}`);
75
+ console.log(`Wrapper Exists: ${existsSync(wrapperPath) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
76
+ console.log(`CLI Exists: ${existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
77
+ console.log("");
78
+ console.log(chalk.bold("\u2699\uFE0F Configuration"));
79
+ console.log(`Happy AI Home: ${chalk.blue(configuration.happyHomeDir)}`);
80
+ console.log(`Server URL: ${chalk.blue(configuration.serverUrl)}`);
81
+ console.log(`Logs Dir: ${chalk.blue(configuration.logsDir)}`);
82
+ console.log(chalk.bold("\n\u{1F30D} Environment Variables"));
83
+ const env = getEnvironmentInfo();
84
+ console.log(`HAPPY_HOME_DIR: ${env.HAPPY_HOME_DIR ? chalk.green(env.HAPPY_HOME_DIR) : chalk.gray("not set")}`);
85
+ console.log(`HAPPY_SERVER_URL: ${env.HAPPY_SERVER_URL ? chalk.green(env.HAPPY_SERVER_URL) : chalk.gray("not set")}`);
86
+ console.log(`DANGEROUSLY_LOG_TO_SERVER: ${env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING ? chalk.yellow("ENABLED") : chalk.gray("not set")}`);
87
+ console.log(`DEBUG: ${env.DEBUG ? chalk.green(env.DEBUG) : chalk.gray("not set")}`);
88
+ console.log(`NODE_ENV: ${env.NODE_ENV ? chalk.green(env.NODE_ENV) : chalk.gray("not set")}`);
89
+ try {
90
+ const settings = await readSettings();
91
+ console.log(chalk.bold("\n\u{1F4C4} Settings (settings.json):"));
92
+ console.log(chalk.gray(JSON.stringify(settings, null, 2)));
93
+ } catch (error) {
94
+ console.log(chalk.bold("\n\u{1F4C4} Settings:"));
95
+ console.log(chalk.red("\u274C Failed to read settings"));
96
+ }
97
+ console.log(chalk.bold("\n\u{1F510} Authentication"));
98
+ try {
99
+ const credentials = await readCredentials();
100
+ if (credentials) {
101
+ console.log(chalk.green("\u2713 Authenticated (credentials found)"));
102
+ } else {
103
+ console.log(chalk.yellow("\u26A0\uFE0F Not authenticated (no credentials)"));
104
+ }
105
+ } catch (error) {
106
+ console.log(chalk.red("\u274C Error reading credentials"));
107
+ }
108
+ }
109
+ console.log(chalk.bold("\n\u{1F916} Daemon Status"));
110
+ try {
111
+ const isRunning = await checkIfDaemonRunningAndCleanupStaleState();
112
+ const state = await readDaemonState();
113
+ if (isRunning && state) {
114
+ console.log(chalk.green("\u2713 Daemon is running"));
115
+ console.log(` PID: ${state.pid}`);
116
+ console.log(` Started: ${new Date(state.startTime).toLocaleString()}`);
117
+ console.log(` CLI Version: ${state.startedWithCliVersion}`);
118
+ if (state.httpPort) {
119
+ console.log(` HTTP Port: ${state.httpPort}`);
120
+ }
121
+ } else if (state && !isRunning) {
122
+ console.log(chalk.yellow("\u26A0\uFE0F Daemon state exists but process not running (stale)"));
123
+ } else {
124
+ console.log(chalk.red("\u274C Daemon is not running"));
125
+ }
126
+ if (state) {
127
+ console.log(chalk.bold("\n\u{1F4C4} Daemon State:"));
128
+ console.log(chalk.blue(`Location: ${configuration.daemonStateFile}`));
129
+ console.log(chalk.gray(JSON.stringify(state, null, 2)));
130
+ }
131
+ const allProcesses = await findAllHappyProcesses();
132
+ if (allProcesses.length > 0) {
133
+ console.log(chalk.bold("\n\u{1F50D} All Happy CLI Processes"));
134
+ const grouped = allProcesses.reduce((groups, process2) => {
135
+ if (!groups[process2.type]) groups[process2.type] = [];
136
+ groups[process2.type].push(process2);
137
+ return groups;
138
+ }, {});
139
+ Object.entries(grouped).forEach(([type, processes]) => {
140
+ const typeLabels = {
141
+ "current": "\u{1F4CD} Current Process",
142
+ "daemon": "\u{1F916} Daemon",
143
+ "daemon-version-check": "\u{1F50D} Daemon Version Check (stuck)",
144
+ "daemon-spawned-session": "\u{1F517} Daemon-Spawned Sessions",
145
+ "user-session": "\u{1F464} User Sessions",
146
+ "dev-daemon": "\u{1F6E0}\uFE0F Dev Daemon",
147
+ "dev-daemon-version-check": "\u{1F6E0}\uFE0F Dev Daemon Version Check (stuck)",
148
+ "dev-session": "\u{1F6E0}\uFE0F Dev Sessions",
149
+ "dev-doctor": "\u{1F6E0}\uFE0F Dev Doctor",
150
+ "dev-related": "\u{1F6E0}\uFE0F Dev Related",
151
+ "doctor": "\u{1FA7A} Doctor",
152
+ "unknown": "\u2753 Unknown"
153
+ };
154
+ console.log(chalk.blue(`
155
+ ${typeLabels[type] || type}:`));
156
+ processes.forEach(({ pid, command }) => {
157
+ const color = type === "current" ? chalk.green : type.startsWith("dev") ? chalk.cyan : type.includes("daemon") ? chalk.blue : chalk.gray;
158
+ console.log(` ${color(`PID ${pid}`)}: ${chalk.gray(command)}`);
159
+ });
160
+ });
161
+ } else {
162
+ console.log(chalk.red("\u274C No happy processes found"));
163
+ }
164
+ if (filter === "all" && allProcesses.length > 1) {
165
+ console.log(chalk.bold("\n\u{1F4A1} Process Management"));
166
+ console.log(chalk.gray("To clean up runaway processes: happy doctor clean"));
167
+ }
168
+ } catch (error) {
169
+ console.log(chalk.red("\u274C Error checking daemon status"));
170
+ }
171
+ if (filter === "all") {
172
+ console.log(chalk.bold("\n\u{1F4DD} Log Files"));
173
+ const allLogs = getLogFiles(configuration.logsDir);
174
+ if (allLogs.length > 0) {
175
+ const daemonLogs = allLogs.filter(({ file }) => file.includes("daemon"));
176
+ const regularLogs = allLogs.filter(({ file }) => !file.includes("daemon"));
177
+ if (regularLogs.length > 0) {
178
+ console.log(chalk.blue("\nRecent Logs:"));
179
+ const logsToShow = regularLogs.slice(0, 10);
180
+ logsToShow.forEach(({ file, path, modified }) => {
181
+ console.log(` ${chalk.green(file)} - ${modified.toLocaleString()}`);
182
+ console.log(chalk.gray(` ${path}`));
183
+ });
184
+ if (regularLogs.length > 10) {
185
+ console.log(chalk.gray(` ... and ${regularLogs.length - 10} more log files`));
186
+ }
187
+ }
188
+ if (daemonLogs.length > 0) {
189
+ console.log(chalk.blue("\nDaemon Logs:"));
190
+ const daemonLogsToShow = daemonLogs.slice(0, 5);
191
+ daemonLogsToShow.forEach(({ file, path, modified }) => {
192
+ console.log(` ${chalk.green(file)} - ${modified.toLocaleString()}`);
193
+ console.log(chalk.gray(` ${path}`));
194
+ });
195
+ if (daemonLogs.length > 5) {
196
+ console.log(chalk.gray(` ... and ${daemonLogs.length - 5} more daemon log files`));
197
+ }
198
+ } else {
199
+ console.log(chalk.yellow("\nNo daemon log files found"));
200
+ }
201
+ } else {
202
+ console.log(chalk.yellow("No log files found"));
203
+ }
204
+ console.log(chalk.bold("\n\u{1F41B} Support & Bug Reports"));
205
+ console.log(`Report issues: ${chalk.blue("https://github.com/ZonEaseTech/happy-wfs/issues")}`);
206
+ console.log(`Documentation: ${chalk.blue("https://github.com/ZonEaseTech/happy-wfs")}`);
207
+ }
208
+ console.log(chalk.green("\n\u2705 Doctor diagnosis complete!\n"));
209
+ }
210
+
211
+ export { getEnvironmentInfo, runDoctorCommand };