@zonease/happy 0.6.38 → 0.6.39

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 (109) hide show
  1. package/dist/{types-BWpRU1VN.mjs → api-CIZKyfSn.mjs} +136 -1725
  2. package/dist/{types-DvTsFaqR.cjs → api-CwOCQeLH.cjs} +317 -1961
  3. package/dist/auth-0VnlXT9f.mjs +181 -0
  4. package/dist/auth-BE8dD20T.mjs +270 -0
  5. package/dist/auth-BIleVCw0.cjs +274 -0
  6. package/dist/auth-Cas9DR3b.cjs +183 -0
  7. package/dist/browser-Cc08m7of.cjs +22 -0
  8. package/dist/browser-Dll5hxOV.mjs +20 -0
  9. package/dist/claudeLocal-CPT3zcIU.mjs +344 -0
  10. package/dist/claudeLocal-WkgLbl1a.cjs +352 -0
  11. package/dist/codex/happyMcpStdioBridge.cjs +4 -1
  12. package/dist/codex/happyMcpStdioBridge.mjs +4 -1
  13. package/dist/common-BdNgghUJ.mjs +75 -0
  14. package/dist/common-CZvSRU4p.cjs +83 -0
  15. package/dist/{config-0Xnc8ARM.cjs → config-Draa-5XC.cjs} +21 -34
  16. package/dist/{config-_GW4YBCP.mjs → config-rTT4qTU5.mjs} +7 -20
  17. package/dist/connect-BfC1tYP_.mjs +679 -0
  18. package/dist/connect-CJZ73syK.cjs +681 -0
  19. package/dist/{constants-B4x1K7by.cjs → constants-E_UWYTo3.cjs} +2 -2
  20. package/dist/{constants-BO9OAFOT.mjs → constants-pmXZGibX.mjs} +1 -1
  21. package/dist/controlClient-CM_QcJnB.mjs +159 -0
  22. package/dist/controlClient-DZMIsKsT.cjs +168 -0
  23. package/dist/deviceExec-CU1R9CRb.cjs +84 -0
  24. package/dist/deviceExec-D93AOVV4.mjs +81 -0
  25. package/dist/diagnose-B3D1a_v0.cjs +60 -0
  26. package/dist/diagnose-CuRKXxt1.mjs +58 -0
  27. package/dist/doctor-C08m5Z9f.cjs +78 -0
  28. package/dist/doctor-Cya9YSA0.cjs +214 -0
  29. package/dist/doctor-DZYB6IVc.mjs +211 -0
  30. package/dist/doctor-ON7pN5G5.mjs +74 -0
  31. package/dist/downloadImage-DfSFLb-h.mjs +887 -0
  32. package/dist/downloadImage-MQMrUUxS.cjs +897 -0
  33. package/dist/enroll-BxlbVftP.cjs +115 -0
  34. package/dist/enroll-C52x8oly.mjs +113 -0
  35. package/dist/evidence-Ccd9iYcj.mjs +127 -0
  36. package/dist/evidence-CjWBG5rX.cjs +129 -0
  37. package/dist/formatImageMessage-B4lSxlk2.mjs +43 -0
  38. package/dist/formatImageMessage-DbyG8c2j.cjs +46 -0
  39. package/dist/github-DKcyF1zp.mjs +57 -0
  40. package/dist/github-h9GhJJ_C.cjs +59 -0
  41. package/dist/index-CDTNgfUf.cjs +578 -0
  42. package/dist/index-CPKdvi7J.mjs +554 -0
  43. package/dist/index.cjs +812 -40
  44. package/dist/index.mjs +813 -40
  45. package/dist/install-BokHRgFW.cjs +98 -0
  46. package/dist/install-C_cp8b2-.cjs +96 -0
  47. package/dist/install-DAeCn8ae.mjs +94 -0
  48. package/dist/install-oRAjVLjP.mjs +95 -0
  49. package/dist/lib.cjs +18 -12
  50. package/dist/lib.mjs +13 -7
  51. package/dist/{loadableToolOutput-va3RLplh.mjs → loadableToolOutput-Cuygmd4K.mjs} +4 -2
  52. package/dist/{loadableToolOutput-5vdQB98M.cjs → loadableToolOutput-DDCJjywt.cjs} +63 -61
  53. package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
  54. package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
  55. package/dist/persistence-BFjvtUad.mjs +944 -0
  56. package/dist/persistence-JLUn_Nou.cjs +996 -0
  57. package/dist/projectPath-BTBIMB57.mjs +10 -0
  58. package/dist/projectPath-ChLhdOyt.cjs +13 -0
  59. package/dist/prompt-BTWDZZO0.cjs +25 -0
  60. package/dist/prompt-BsAZsPbo.mjs +22 -0
  61. package/dist/release-BMEzNONE.mjs +168 -0
  62. package/dist/release-EhOJeAZe.cjs +171 -0
  63. package/dist/run-BDn2aE3Q.cjs +2152 -0
  64. package/dist/run-DBZqN6Kn.mjs +2128 -0
  65. package/dist/runClaude-DNHvERX0.mjs +3763 -0
  66. package/dist/runClaude-uaKxPZPm.cjs +3766 -0
  67. package/dist/{runCodex-skq0j05d.cjs → runCodex-82UrZLme.cjs} +169 -153
  68. package/dist/{runCodex-DiKzBf9q.mjs → runCodex-C-RTM0wA.mjs} +36 -20
  69. package/dist/{runGemini-BeqrVq8R.mjs → runGemini-Bm6-4Xm2.mjs} +34 -17
  70. package/dist/{runGemini-CVp-CEIh.cjs → runGemini-CXMr4Jwb.cjs} +212 -195
  71. package/dist/{runOneShot-BQNkNW61.cjs → runOneShot-1B6RMYT7.cjs} +31 -55
  72. package/dist/{runOneShot-ltCpHbBB.mjs → runOneShot-ioARRHrx.mjs} +14 -38
  73. package/dist/{serve-BECdtivY.cjs → serve-BtdAhkIE.cjs} +35 -58
  74. package/dist/{serve-BNdoEDVx.mjs → serve-CwibwU6N.mjs} +12 -35
  75. package/dist/session-2sU4Bu1R.mjs +108 -0
  76. package/dist/session-D--F87zL.cjs +110 -0
  77. package/dist/sessionKeyCache-4Tp8pJ3N.cjs +36 -0
  78. package/dist/sessionKeyCache-D2BwO91C.mjs +33 -0
  79. package/dist/sessionList-BCSw3qYt.mjs +51 -0
  80. package/dist/sessionList-ICJsjNtJ.cjs +54 -0
  81. package/dist/sessionSummary-Bkz52BPh.cjs +393 -0
  82. package/dist/sessionSummary-lHGBWQSb.mjs +387 -0
  83. package/dist/spawnHappyCLI-CoORX0YW.mjs +66 -0
  84. package/dist/spawnHappyCLI-D_V-AAoP.cjs +70 -0
  85. package/dist/ssh-BTOlhhxi.cjs +333 -0
  86. package/dist/ssh-DL_AkRAD.mjs +328 -0
  87. package/dist/systemdScope-BeOtAkhk.mjs +25 -0
  88. package/dist/systemdScope-DW3-UoKB.cjs +29 -0
  89. package/dist/task-CQzrHRZe.mjs +165 -0
  90. package/dist/task-CSpaC9HX.cjs +167 -0
  91. package/dist/time-Bj2HRkKH.cjs +33 -0
  92. package/dist/time-DgsBLJA_.mjs +29 -0
  93. package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
  94. package/dist/trimIdent-BAjmv_TG.mjs +20 -0
  95. package/dist/types-BoJh4Qfv.mjs +57 -0
  96. package/dist/types-DWeB7aqh.cjs +59 -0
  97. package/dist/uninstall-BiKyRAb1.cjs +77 -0
  98. package/dist/uninstall-nFMFGUVM.mjs +75 -0
  99. package/dist/update-BcqRHXf2.mjs +109 -0
  100. package/dist/update-Dw8pgsAT.cjs +111 -0
  101. package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
  102. package/dist/workflowCommon-Bl568-rt.cjs +62 -0
  103. package/dist/workflowReports-BEWuQesA.cjs +113 -0
  104. package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
  105. package/package.json +1 -1
  106. package/dist/index-BbCDDvoB.cjs +0 -11376
  107. package/dist/index-vvZXdswy.mjs +0 -11336
  108. package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
  109. package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
@@ -0,0 +1,75 @@
1
+ import { l as logger } from './persistence-BFjvtUad.mjs';
2
+ import { existsSync, unlinkSync } from 'fs';
3
+ import { execSync } from 'child_process';
4
+ import { join } from 'path';
5
+ import os from 'os';
6
+ import { s as systemdScopeFor, i as isRootUser, S as SERVICE_NAME } from './systemdScope-BeOtAkhk.mjs';
7
+ import { stopDaemon } from './controlClient-CM_QcJnB.mjs';
8
+ import 'node:fs/promises';
9
+ import 'node:fs';
10
+ import 'node:os';
11
+ import 'node:path';
12
+ import 'zod';
13
+ import 'node:crypto';
14
+ import 'tweetnacl';
15
+ import 'chalk';
16
+ import './projectPath-BTBIMB57.mjs';
17
+ import 'url';
18
+
19
+ const PLIST_LABEL = "com.happy-cli.daemon";
20
+ const PLIST_PATH = join(os.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
21
+ async function uninstall$2() {
22
+ if (!existsSync(PLIST_PATH)) {
23
+ logger.info("No LaunchAgent found. Auto-start is not enabled.");
24
+ return;
25
+ }
26
+ try {
27
+ execSync(`launchctl unload ${PLIST_PATH}`, { stdio: "ignore" });
28
+ } catch {
29
+ }
30
+ unlinkSync(PLIST_PATH);
31
+ logger.info("Daemon auto-start disabled.");
32
+ }
33
+
34
+ async function uninstall$1() {
35
+ const scopes = [systemdScopeFor(true), systemdScopeFor(false)].filter((scope) => existsSync(scope.unitPath));
36
+ if (scopes.length === 0) {
37
+ logger.info("No systemd service found. Auto-start is not enabled.");
38
+ return;
39
+ }
40
+ for (const scope of scopes) {
41
+ if (scope.system && !isRootUser()) {
42
+ logger.info(`Skipping ${scope.unitPath} \u2014 removing it needs root: sudo happy daemon disable`);
43
+ continue;
44
+ }
45
+ try {
46
+ execSync(`systemctl ${scope.systemctlFlag} disable --now ${SERVICE_NAME}`.trim(), { stdio: "ignore" });
47
+ } catch {
48
+ }
49
+ unlinkSync(scope.unitPath);
50
+ try {
51
+ execSync(`systemctl ${scope.systemctlFlag} daemon-reload`.trim(), { stdio: "ignore" });
52
+ } catch {
53
+ }
54
+ logger.info(`Removed ${scope.unitPath}`);
55
+ }
56
+ logger.info("Daemon auto-start disabled.");
57
+ }
58
+
59
+ async function uninstall() {
60
+ if (process.platform === "darwin") {
61
+ logger.info("Removing daemon auto-start for macOS...");
62
+ await uninstall$2();
63
+ } else if (process.platform === "linux") {
64
+ logger.info("Removing daemon auto-start for Linux...");
65
+ await uninstall$1();
66
+ } else {
67
+ throw new Error(`Unsupported platform: ${process.platform}. Only macOS and Linux are supported.`);
68
+ }
69
+ try {
70
+ await stopDaemon();
71
+ } catch {
72
+ }
73
+ }
74
+
75
+ export { uninstall };
@@ -0,0 +1,109 @@
1
+ import chalk from 'chalk';
2
+ import { execFileSync, execSync } from 'node:child_process';
3
+ import { realpathSync } from 'node:fs';
4
+ import { p as packageJson } from './persistence-BFjvtUad.mjs';
5
+ import { checkIfDaemonRunningAndCleanupStaleState, stopDaemon } from './controlClient-CM_QcJnB.mjs';
6
+ import { s as spawnHappyCLI } from './spawnHappyCLI-CoORX0YW.mjs';
7
+ import 'node:fs/promises';
8
+ import 'node:os';
9
+ import 'node:path';
10
+ import 'zod';
11
+ import 'node:crypto';
12
+ import 'tweetnacl';
13
+ import 'fs';
14
+ import './projectPath-BTBIMB57.mjs';
15
+ import 'path';
16
+ import 'url';
17
+ import 'child_process';
18
+
19
+ const PACKAGE_NAME = "@zonease/happy";
20
+ function detectPackageManager() {
21
+ try {
22
+ const whichOutput = execSync("which happy", { encoding: "utf-8" }).trim();
23
+ const realPath = realpathSync(whichOutput);
24
+ if (realPath.includes("/pnpm/") || realPath.includes("/pnpm-global/")) {
25
+ return "pnpm";
26
+ }
27
+ if (realPath.includes("/.yarn/") || realPath.includes("/yarn/")) {
28
+ return "yarn";
29
+ }
30
+ } catch {
31
+ }
32
+ return "npm";
33
+ }
34
+ function getUpgradeCommand(pm) {
35
+ switch (pm) {
36
+ case "pnpm":
37
+ return ["pnpm", "add", "-g", `${PACKAGE_NAME}@latest`];
38
+ case "yarn":
39
+ return ["yarn", "global", "add", `${PACKAGE_NAME}@latest`];
40
+ case "npm":
41
+ return ["npm", "install", "-g", `${PACKAGE_NAME}@latest`];
42
+ }
43
+ }
44
+ function getLatestVersion() {
45
+ try {
46
+ return execFileSync("npm", ["view", PACKAGE_NAME, "version"], { encoding: "utf-8" }).trim();
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+ async function handleUpdateCommand() {
52
+ const currentVersion = packageJson.version;
53
+ console.log(chalk.gray("Checking for updates..."));
54
+ const latestVersion = getLatestVersion();
55
+ if (!latestVersion) {
56
+ console.error(chalk.red("Failed to check latest version. Please check your network connection."));
57
+ process.exit(1);
58
+ }
59
+ console.log(`Current version: ${chalk.cyan(currentVersion)}`);
60
+ console.log(`Latest version: ${chalk.cyan(latestVersion)}`);
61
+ console.log("");
62
+ if (currentVersion === latestVersion) {
63
+ console.log(chalk.green("\u2713 Already up to date"));
64
+ process.exit(0);
65
+ }
66
+ const pm = detectPackageManager();
67
+ const command = getUpgradeCommand(pm);
68
+ console.log(`Upgrading via ${chalk.bold(pm)}...`);
69
+ try {
70
+ execFileSync(command[0], command.slice(1), { stdio: "inherit" });
71
+ } catch {
72
+ console.error(chalk.red(`
73
+ \u2717 Upgrade failed. You can try manually:`));
74
+ console.error(chalk.gray(` ${command.join(" ")}`));
75
+ process.exit(1);
76
+ }
77
+ console.log(chalk.green(`
78
+ \u2713 Upgraded to ${latestVersion}`));
79
+ try {
80
+ const daemonRunning = await checkIfDaemonRunningAndCleanupStaleState();
81
+ if (daemonRunning) {
82
+ console.log("Restarting daemon...");
83
+ await stopDaemon();
84
+ const child = spawnHappyCLI(["daemon", "start-sync"], {
85
+ detached: true,
86
+ stdio: "ignore",
87
+ env: process.env
88
+ });
89
+ child.unref();
90
+ let started = false;
91
+ for (let i = 0; i < 50; i++) {
92
+ if (await checkIfDaemonRunningAndCleanupStaleState()) {
93
+ started = true;
94
+ break;
95
+ }
96
+ await new Promise((resolve) => setTimeout(resolve, 100));
97
+ }
98
+ if (started) {
99
+ console.log(chalk.green("\u2713 Daemon restarted"));
100
+ } else {
101
+ console.log(chalk.yellow('\u26A0 Daemon restart timed out. Run "happy daemon start" manually.'));
102
+ }
103
+ }
104
+ } catch {
105
+ }
106
+ process.exit(0);
107
+ }
108
+
109
+ export { handleUpdateCommand };
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+ var node_child_process = require('node:child_process');
5
+ var fs = require('node:fs');
6
+ var logger = require('./persistence-JLUn_Nou.cjs');
7
+ var controlClient = require('./controlClient-DZMIsKsT.cjs');
8
+ var spawnHappyCLI = require('./spawnHappyCLI-D_V-AAoP.cjs');
9
+ require('node:fs/promises');
10
+ require('node:os');
11
+ require('node:path');
12
+ require('zod');
13
+ require('node:crypto');
14
+ require('tweetnacl');
15
+ require('fs');
16
+ require('./projectPath-ChLhdOyt.cjs');
17
+ require('path');
18
+ require('url');
19
+ require('child_process');
20
+
21
+ const PACKAGE_NAME = "@zonease/happy";
22
+ function detectPackageManager() {
23
+ try {
24
+ const whichOutput = node_child_process.execSync("which happy", { encoding: "utf-8" }).trim();
25
+ const realPath = fs.realpathSync(whichOutput);
26
+ if (realPath.includes("/pnpm/") || realPath.includes("/pnpm-global/")) {
27
+ return "pnpm";
28
+ }
29
+ if (realPath.includes("/.yarn/") || realPath.includes("/yarn/")) {
30
+ return "yarn";
31
+ }
32
+ } catch {
33
+ }
34
+ return "npm";
35
+ }
36
+ function getUpgradeCommand(pm) {
37
+ switch (pm) {
38
+ case "pnpm":
39
+ return ["pnpm", "add", "-g", `${PACKAGE_NAME}@latest`];
40
+ case "yarn":
41
+ return ["yarn", "global", "add", `${PACKAGE_NAME}@latest`];
42
+ case "npm":
43
+ return ["npm", "install", "-g", `${PACKAGE_NAME}@latest`];
44
+ }
45
+ }
46
+ function getLatestVersion() {
47
+ try {
48
+ return node_child_process.execFileSync("npm", ["view", PACKAGE_NAME, "version"], { encoding: "utf-8" }).trim();
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ async function handleUpdateCommand() {
54
+ const currentVersion = logger.packageJson.version;
55
+ console.log(chalk.gray("Checking for updates..."));
56
+ const latestVersion = getLatestVersion();
57
+ if (!latestVersion) {
58
+ console.error(chalk.red("Failed to check latest version. Please check your network connection."));
59
+ process.exit(1);
60
+ }
61
+ console.log(`Current version: ${chalk.cyan(currentVersion)}`);
62
+ console.log(`Latest version: ${chalk.cyan(latestVersion)}`);
63
+ console.log("");
64
+ if (currentVersion === latestVersion) {
65
+ console.log(chalk.green("\u2713 Already up to date"));
66
+ process.exit(0);
67
+ }
68
+ const pm = detectPackageManager();
69
+ const command = getUpgradeCommand(pm);
70
+ console.log(`Upgrading via ${chalk.bold(pm)}...`);
71
+ try {
72
+ node_child_process.execFileSync(command[0], command.slice(1), { stdio: "inherit" });
73
+ } catch {
74
+ console.error(chalk.red(`
75
+ \u2717 Upgrade failed. You can try manually:`));
76
+ console.error(chalk.gray(` ${command.join(" ")}`));
77
+ process.exit(1);
78
+ }
79
+ console.log(chalk.green(`
80
+ \u2713 Upgraded to ${latestVersion}`));
81
+ try {
82
+ const daemonRunning = await controlClient.checkIfDaemonRunningAndCleanupStaleState();
83
+ if (daemonRunning) {
84
+ console.log("Restarting daemon...");
85
+ await controlClient.stopDaemon();
86
+ const child = spawnHappyCLI.spawnHappyCLI(["daemon", "start-sync"], {
87
+ detached: true,
88
+ stdio: "ignore",
89
+ env: process.env
90
+ });
91
+ child.unref();
92
+ let started = false;
93
+ for (let i = 0; i < 50; i++) {
94
+ if (await controlClient.checkIfDaemonRunningAndCleanupStaleState()) {
95
+ started = true;
96
+ break;
97
+ }
98
+ await new Promise((resolve) => setTimeout(resolve, 100));
99
+ }
100
+ if (started) {
101
+ console.log(chalk.green("\u2713 Daemon restarted"));
102
+ } else {
103
+ console.log(chalk.yellow('\u26A0 Daemon restart timed out. Run "happy daemon start" manually.'));
104
+ }
105
+ }
106
+ } catch {
107
+ }
108
+ process.exit(0);
109
+ }
110
+
111
+ exports.handleUpdateCommand = handleUpdateCommand;
@@ -0,0 +1,56 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+
3
+ function parseWorkflowArgs(args, valueFlags) {
4
+ const positionals = [];
5
+ const flags = /* @__PURE__ */ new Map();
6
+ for (let i = 0; i < args.length; i++) {
7
+ const arg = args[i];
8
+ if (!arg.startsWith("-") || arg === "-") {
9
+ positionals.push(arg);
10
+ continue;
11
+ }
12
+ const equalIndex = arg.indexOf("=");
13
+ const flag = equalIndex === -1 ? arg : arg.slice(0, equalIndex);
14
+ if (equalIndex !== -1) {
15
+ flags.set(flag, arg.slice(equalIndex + 1));
16
+ continue;
17
+ }
18
+ if (valueFlags.has(flag)) {
19
+ const value = args[++i];
20
+ if (!value || value.startsWith("--")) {
21
+ throw new Error(`${flag} requires a value.`);
22
+ }
23
+ flags.set(flag, value);
24
+ } else {
25
+ flags.set(flag, true);
26
+ }
27
+ }
28
+ return { positionals, flags };
29
+ }
30
+ function stringFlag(parsed, flag) {
31
+ const value = parsed.flags.get(flag);
32
+ if (value === void 0 || value === true) return void 0;
33
+ return value;
34
+ }
35
+ function numberFlag(parsed, flag) {
36
+ const value = stringFlag(parsed, flag);
37
+ if (value === void 0) return void 0;
38
+ const parsedValue = Number(value);
39
+ if (!Number.isInteger(parsedValue)) {
40
+ throw new Error(`${flag} must be an integer.`);
41
+ }
42
+ return parsedValue;
43
+ }
44
+ function booleanFlag(parsed, flag) {
45
+ return parsed.flags.get(flag) === true;
46
+ }
47
+ async function printOrWriteOutput(content, outputPath) {
48
+ if (outputPath) {
49
+ await writeFile(outputPath, content, "utf8");
50
+ console.log(outputPath);
51
+ } else {
52
+ console.log(content);
53
+ }
54
+ }
55
+
56
+ export { printOrWriteOutput as a, booleanFlag as b, numberFlag as n, parseWorkflowArgs as p, stringFlag as s };
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ var promises = require('node:fs/promises');
4
+
5
+ function parseWorkflowArgs(args, valueFlags) {
6
+ const positionals = [];
7
+ const flags = /* @__PURE__ */ new Map();
8
+ for (let i = 0; i < args.length; i++) {
9
+ const arg = args[i];
10
+ if (!arg.startsWith("-") || arg === "-") {
11
+ positionals.push(arg);
12
+ continue;
13
+ }
14
+ const equalIndex = arg.indexOf("=");
15
+ const flag = equalIndex === -1 ? arg : arg.slice(0, equalIndex);
16
+ if (equalIndex !== -1) {
17
+ flags.set(flag, arg.slice(equalIndex + 1));
18
+ continue;
19
+ }
20
+ if (valueFlags.has(flag)) {
21
+ const value = args[++i];
22
+ if (!value || value.startsWith("--")) {
23
+ throw new Error(`${flag} requires a value.`);
24
+ }
25
+ flags.set(flag, value);
26
+ } else {
27
+ flags.set(flag, true);
28
+ }
29
+ }
30
+ return { positionals, flags };
31
+ }
32
+ function stringFlag(parsed, flag) {
33
+ const value = parsed.flags.get(flag);
34
+ if (value === void 0 || value === true) return void 0;
35
+ return value;
36
+ }
37
+ function numberFlag(parsed, flag) {
38
+ const value = stringFlag(parsed, flag);
39
+ if (value === void 0) return void 0;
40
+ const parsedValue = Number(value);
41
+ if (!Number.isInteger(parsedValue)) {
42
+ throw new Error(`${flag} must be an integer.`);
43
+ }
44
+ return parsedValue;
45
+ }
46
+ function booleanFlag(parsed, flag) {
47
+ return parsed.flags.get(flag) === true;
48
+ }
49
+ async function printOrWriteOutput(content, outputPath) {
50
+ if (outputPath) {
51
+ await promises.writeFile(outputPath, content, "utf8");
52
+ console.log(outputPath);
53
+ } else {
54
+ console.log(content);
55
+ }
56
+ }
57
+
58
+ exports.booleanFlag = booleanFlag;
59
+ exports.numberFlag = numberFlag;
60
+ exports.parseWorkflowArgs = parseWorkflowArgs;
61
+ exports.printOrWriteOutput = printOrWriteOutput;
62
+ exports.stringFlag = stringFlag;
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ var path = require('node:path');
4
+
5
+ const IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"]);
6
+ const LOG_EXTENSIONS = /* @__PURE__ */ new Set([".log", ".txt", ".jsonl"]);
7
+ function bashQuote(value) {
8
+ return `'${value.replace(/'/g, `'\\''`)}'`;
9
+ }
10
+ function inferEvidenceKind(target) {
11
+ if (/^https?:\/\//i.test(target)) return "url";
12
+ const extension = path.extname(target).toLowerCase();
13
+ if (IMAGE_EXTENSIONS.has(extension)) return "image";
14
+ if (LOG_EXTENSIONS.has(extension)) return "log";
15
+ return "file";
16
+ }
17
+ function buildGithubTakeoverReport(input) {
18
+ const targetLabel = input.target || "(issue-or-pr)";
19
+ const repoLine = input.repo ? `- Repository: \`${input.repo}\`` : "- Repository: infer from URL or current checkout";
20
+ const modeLine = input.mode && input.mode !== "auto" ? `- Mode: ${input.mode}` : "- Mode: auto-detect PR vs issue";
21
+ return `# GitHub Task Takeover
22
+
23
+ - Target: \`${targetLabel}\`
24
+ ${repoLine}
25
+ ${modeLine}
26
+
27
+ ## Execution Checklist
28
+
29
+ 1. Read repository instructions first: \`AGENTS.md\`, \`CLAUDE.md\`, and scoped rules.
30
+ 2. Fetch the PR/issue body, comments, unresolved review threads, changed files, and CI status.
31
+ 3. Summarize the requested outcome, blockers, and acceptance criteria before editing.
32
+ 4. Claim or create the local task/plan record if the repository uses PMA.
33
+ 5. Preserve existing user/agent changes; do not reset or overwrite unrelated files.
34
+ 6. Implement the smallest safe patch.
35
+ 7. Run focused verification and then the package-required typecheck/build/test command.
36
+ 8. Report changed files, verification results, and any remaining blockers.
37
+
38
+ ## Copy-Paste Agent Prompt
39
+
40
+ Take over GitHub work for \`${targetLabel}\`${input.repo ? ` in \`${input.repo}\`` : ""}.
41
+
42
+ - Inspect repository instructions before editing.
43
+ - Read PR/issue metadata, comments, unresolved review threads, changed files, and CI.
44
+ - Identify exactly what must be fixed.
45
+ - Implement the minimal patch without touching unrelated user changes.
46
+ - Run focused tests plus the repository-required verification.
47
+ - Return a concise Chinese summary with changed files and verification evidence.
48
+ `;
49
+ }
50
+ function buildRemoteDiagnoseReport(input) {
51
+ const serviceClause = input.service ? `SERVICE=${bashQuote(input.service)}` : `SERVICE=${bashQuote("<service-name>")}`;
52
+ const keywordClause = input.keyword ? `KEYWORD=${bashQuote(input.keyword)}` : `KEYWORD=${bashQuote("<error-keyword>")}`;
53
+ const healthUrl = input.healthUrl ?? "http://127.0.0.1:8090/health";
54
+ return `# Remote Diagnosis Evidence Pack
55
+
56
+ - Host: \`${input.host}\`
57
+ - Since: \`${input.since}\`
58
+ - Service: \`${input.service ?? "(optional)"}\`
59
+ - Keyword: \`${input.keyword ?? "(optional)"}\`
60
+ - Health URL: \`${healthUrl}\`
61
+
62
+ Run these commands manually after confirming the target host. They are read-only evidence commands.
63
+
64
+ \`\`\`bash
65
+ HOST=${bashQuote(input.host)}
66
+ ${serviceClause}
67
+ ${keywordClause}
68
+ SINCE=${bashQuote(input.since)}
69
+
70
+ ssh "$HOST" 'hostname; date; uptime; df -h; free -m'
71
+ ssh "$HOST" 'systemctl --failed --no-pager || true'
72
+ ssh "$HOST" 'docker ps --format "table {{.Names}}\\t{{.Image}}\\t{{.Status}}" || true'
73
+ ssh "$HOST" "curl -fsS ${healthUrl} || true"
74
+ ssh "$HOST" "journalctl --since \\"$SINCE\\" -p warning..alert --no-pager | tail -200 || true"
75
+ ssh "$HOST" "docker logs --since \\"$SINCE\\" \\"$SERVICE\\" 2>&1 | tail -300 || true"
76
+ ssh "$HOST" "grep -RIn --exclude-dir=node_modules --exclude-dir=.git \\"$KEYWORD\\" /tmp /var/log 2>/dev/null | tail -100 || true"
77
+ \`\`\`
78
+
79
+ ## Evidence To Return
80
+
81
+ - Exact failing request or user-visible symptom.
82
+ - Health check output.
83
+ - Last 200 warning/error journal lines.
84
+ - Last 300 service log lines.
85
+ - Any screenshot or UI evidence path, added with \`happy evidence add <path>\`.
86
+ `;
87
+ }
88
+ function renderEvidenceReport(entries, title = "Evidence Report") {
89
+ const lines = [`# ${title}`, "", `Total evidence: ${entries.length}`, ""];
90
+ for (const entry of entries) {
91
+ const session = entry.sessionId ? ` session=${entry.sessionId}` : "";
92
+ lines.push(`## ${entry.title}`);
93
+ lines.push("");
94
+ lines.push(`- ID: \`${entry.id}\``);
95
+ lines.push(`- Created: ${entry.createdAt}`);
96
+ lines.push(`- Kind: ${entry.kind}${session}`);
97
+ lines.push(`- Target: \`${entry.target}\``);
98
+ if (entry.note) lines.push(`- Note: ${entry.note}`);
99
+ if (entry.kind === "image") {
100
+ const label = entry.title || path.basename(entry.target);
101
+ const imageTarget = entry.target.startsWith("/") ? `file://${entry.target}` : entry.target;
102
+ lines.push("");
103
+ lines.push(`![${label}](${imageTarget})`);
104
+ }
105
+ lines.push("");
106
+ }
107
+ return lines.join("\n").trimEnd();
108
+ }
109
+
110
+ exports.buildGithubTakeoverReport = buildGithubTakeoverReport;
111
+ exports.buildRemoteDiagnoseReport = buildRemoteDiagnoseReport;
112
+ exports.inferEvidenceKind = inferEvidenceKind;
113
+ exports.renderEvidenceReport = renderEvidenceReport;
@@ -0,0 +1,108 @@
1
+ import { basename, extname } from 'node:path';
2
+
3
+ const IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"]);
4
+ const LOG_EXTENSIONS = /* @__PURE__ */ new Set([".log", ".txt", ".jsonl"]);
5
+ function bashQuote(value) {
6
+ return `'${value.replace(/'/g, `'\\''`)}'`;
7
+ }
8
+ function inferEvidenceKind(target) {
9
+ if (/^https?:\/\//i.test(target)) return "url";
10
+ const extension = extname(target).toLowerCase();
11
+ if (IMAGE_EXTENSIONS.has(extension)) return "image";
12
+ if (LOG_EXTENSIONS.has(extension)) return "log";
13
+ return "file";
14
+ }
15
+ function buildGithubTakeoverReport(input) {
16
+ const targetLabel = input.target || "(issue-or-pr)";
17
+ const repoLine = input.repo ? `- Repository: \`${input.repo}\`` : "- Repository: infer from URL or current checkout";
18
+ const modeLine = input.mode && input.mode !== "auto" ? `- Mode: ${input.mode}` : "- Mode: auto-detect PR vs issue";
19
+ return `# GitHub Task Takeover
20
+
21
+ - Target: \`${targetLabel}\`
22
+ ${repoLine}
23
+ ${modeLine}
24
+
25
+ ## Execution Checklist
26
+
27
+ 1. Read repository instructions first: \`AGENTS.md\`, \`CLAUDE.md\`, and scoped rules.
28
+ 2. Fetch the PR/issue body, comments, unresolved review threads, changed files, and CI status.
29
+ 3. Summarize the requested outcome, blockers, and acceptance criteria before editing.
30
+ 4. Claim or create the local task/plan record if the repository uses PMA.
31
+ 5. Preserve existing user/agent changes; do not reset or overwrite unrelated files.
32
+ 6. Implement the smallest safe patch.
33
+ 7. Run focused verification and then the package-required typecheck/build/test command.
34
+ 8. Report changed files, verification results, and any remaining blockers.
35
+
36
+ ## Copy-Paste Agent Prompt
37
+
38
+ Take over GitHub work for \`${targetLabel}\`${input.repo ? ` in \`${input.repo}\`` : ""}.
39
+
40
+ - Inspect repository instructions before editing.
41
+ - Read PR/issue metadata, comments, unresolved review threads, changed files, and CI.
42
+ - Identify exactly what must be fixed.
43
+ - Implement the minimal patch without touching unrelated user changes.
44
+ - Run focused tests plus the repository-required verification.
45
+ - Return a concise Chinese summary with changed files and verification evidence.
46
+ `;
47
+ }
48
+ function buildRemoteDiagnoseReport(input) {
49
+ const serviceClause = input.service ? `SERVICE=${bashQuote(input.service)}` : `SERVICE=${bashQuote("<service-name>")}`;
50
+ const keywordClause = input.keyword ? `KEYWORD=${bashQuote(input.keyword)}` : `KEYWORD=${bashQuote("<error-keyword>")}`;
51
+ const healthUrl = input.healthUrl ?? "http://127.0.0.1:8090/health";
52
+ return `# Remote Diagnosis Evidence Pack
53
+
54
+ - Host: \`${input.host}\`
55
+ - Since: \`${input.since}\`
56
+ - Service: \`${input.service ?? "(optional)"}\`
57
+ - Keyword: \`${input.keyword ?? "(optional)"}\`
58
+ - Health URL: \`${healthUrl}\`
59
+
60
+ Run these commands manually after confirming the target host. They are read-only evidence commands.
61
+
62
+ \`\`\`bash
63
+ HOST=${bashQuote(input.host)}
64
+ ${serviceClause}
65
+ ${keywordClause}
66
+ SINCE=${bashQuote(input.since)}
67
+
68
+ ssh "$HOST" 'hostname; date; uptime; df -h; free -m'
69
+ ssh "$HOST" 'systemctl --failed --no-pager || true'
70
+ ssh "$HOST" 'docker ps --format "table {{.Names}}\\t{{.Image}}\\t{{.Status}}" || true'
71
+ ssh "$HOST" "curl -fsS ${healthUrl} || true"
72
+ ssh "$HOST" "journalctl --since \\"$SINCE\\" -p warning..alert --no-pager | tail -200 || true"
73
+ ssh "$HOST" "docker logs --since \\"$SINCE\\" \\"$SERVICE\\" 2>&1 | tail -300 || true"
74
+ ssh "$HOST" "grep -RIn --exclude-dir=node_modules --exclude-dir=.git \\"$KEYWORD\\" /tmp /var/log 2>/dev/null | tail -100 || true"
75
+ \`\`\`
76
+
77
+ ## Evidence To Return
78
+
79
+ - Exact failing request or user-visible symptom.
80
+ - Health check output.
81
+ - Last 200 warning/error journal lines.
82
+ - Last 300 service log lines.
83
+ - Any screenshot or UI evidence path, added with \`happy evidence add <path>\`.
84
+ `;
85
+ }
86
+ function renderEvidenceReport(entries, title = "Evidence Report") {
87
+ const lines = [`# ${title}`, "", `Total evidence: ${entries.length}`, ""];
88
+ for (const entry of entries) {
89
+ const session = entry.sessionId ? ` session=${entry.sessionId}` : "";
90
+ lines.push(`## ${entry.title}`);
91
+ lines.push("");
92
+ lines.push(`- ID: \`${entry.id}\``);
93
+ lines.push(`- Created: ${entry.createdAt}`);
94
+ lines.push(`- Kind: ${entry.kind}${session}`);
95
+ lines.push(`- Target: \`${entry.target}\``);
96
+ if (entry.note) lines.push(`- Note: ${entry.note}`);
97
+ if (entry.kind === "image") {
98
+ const label = entry.title || basename(entry.target);
99
+ const imageTarget = entry.target.startsWith("/") ? `file://${entry.target}` : entry.target;
100
+ lines.push("");
101
+ lines.push(`![${label}](${imageTarget})`);
102
+ }
103
+ lines.push("");
104
+ }
105
+ return lines.join("\n").trimEnd();
106
+ }
107
+
108
+ export { buildRemoteDiagnoseReport as a, buildGithubTakeoverReport as b, inferEvidenceKind as i, renderEvidenceReport as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonease/happy",
3
- "version": "0.6.38",
3
+ "version": "0.6.39",
4
4
  "description": "Mobile and Web client for Claude Code, Codex, and Gemini",
5
5
  "author": "ZonEaseTech",
6
6
  "license": "MIT",