autohand-cli 0.6.0 → 0.6.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.
Files changed (136) hide show
  1. package/dist/agents-32JB7KMB.js +9 -0
  2. package/dist/agents-3K6PHXQ6.js +9 -0
  3. package/dist/agents-A7AUMVQD.js +8 -0
  4. package/dist/agents-AHFECO5Q.js +9 -0
  5. package/dist/agents-DQFYBMJG.js +8 -0
  6. package/dist/agents-GX6L7BXZ.js +9 -0
  7. package/dist/agents-IWJJ7YJM.js +8 -0
  8. package/dist/agents-J2QLDVOP.js +9 -0
  9. package/dist/agents-OWTSY74S.js +9 -0
  10. package/dist/agents-RB34F4XE.js +9 -0
  11. package/dist/agents-XL27P67O.js +9 -0
  12. package/dist/agents-new-5I3B2W2I.js +9 -0
  13. package/dist/agents-new-CHV2AV34.js +9 -0
  14. package/dist/agents-new-F6F2VMDB.js +9 -0
  15. package/dist/agents-new-FDMUH7NL.js +9 -0
  16. package/dist/agents-new-GBF6JJIA.js +9 -0
  17. package/dist/agents-new-GCZEY4TE.js +8 -0
  18. package/dist/agents-new-OCIB72NU.js +9 -0
  19. package/dist/agents-new-PQGD47BZ.js +9 -0
  20. package/dist/agents-new-V6BNVJAB.js +9 -0
  21. package/dist/agents-new-WQUEZ2XH.js +8 -0
  22. package/dist/chunk-2DEJU7WQ.js +373 -0
  23. package/dist/chunk-2EPIFDFM.js +68 -0
  24. package/dist/chunk-2FUWKZFN.js +68 -0
  25. package/dist/chunk-2HIILNYH.js +197 -0
  26. package/dist/chunk-2QAL3HH4.js +79 -0
  27. package/dist/chunk-3FRM7HJY.js +57 -0
  28. package/dist/chunk-4LDR3Y3A.js +79 -0
  29. package/dist/{chunk-6PYYLBNT.js → chunk-4LLTISFP.js} +1 -1
  30. package/dist/chunk-4UISIRMD.js +288 -0
  31. package/dist/chunk-4VWPX2X3.js +131 -0
  32. package/dist/chunk-7FMMKTRG.js +64 -0
  33. package/dist/chunk-7MFSCH7E.js +382 -0
  34. package/dist/chunk-7TV5KURP.js +79 -0
  35. package/dist/chunk-7WBK33MM.js +57 -0
  36. package/dist/chunk-7XN6PAKV.js +79 -0
  37. package/dist/chunk-A7HRTONQ.js +382 -0
  38. package/dist/chunk-ALMJANSA.js +197 -0
  39. package/dist/chunk-CD7GNBIE.js +288 -0
  40. package/dist/chunk-CV3LEQRD.js +57 -0
  41. package/dist/chunk-DAHMHLM6.js +102 -0
  42. package/dist/chunk-DAMLAWGE.js +68 -0
  43. package/dist/chunk-F4YPGOQJ.js +105 -0
  44. package/dist/chunk-FQDXFNOI.js +57 -0
  45. package/dist/chunk-FQI7EJY2.js +105 -0
  46. package/dist/chunk-GAJCZDZ5.js +286 -0
  47. package/dist/chunk-GEOP77H3.js +79 -0
  48. package/dist/chunk-GRX3IQHC.js +131 -0
  49. package/dist/chunk-GX24PC3L.js +288 -0
  50. package/dist/chunk-H53NQAC2.js +131 -0
  51. package/dist/chunk-HJYISR7Y.js +382 -0
  52. package/dist/chunk-HLSI4HQM.js +105 -0
  53. package/dist/chunk-IAOMCEYU.js +68 -0
  54. package/dist/chunk-J7RENRJG.js +382 -0
  55. package/dist/chunk-JUDX6E53.js +105 -0
  56. package/dist/chunk-JZQKOM7X.js +382 -0
  57. package/dist/chunk-K75NWR5V.js +108 -0
  58. package/dist/chunk-KCMWJB53.js +288 -0
  59. package/dist/chunk-KERHTHMK.js +302 -0
  60. package/dist/chunk-KJ4M6KAK.js +57 -0
  61. package/dist/chunk-L3JXU574.js +77 -0
  62. package/dist/chunk-LR2XPUPT.js +236 -0
  63. package/dist/chunk-MCWNGAZG.js +198 -0
  64. package/dist/chunk-MQTBFYEG.js +288 -0
  65. package/dist/chunk-NCUJWSGP.js +287 -0
  66. package/dist/chunk-NWEUBPSG.js +79 -0
  67. package/dist/chunk-OJ5EBWOQ.js +232 -0
  68. package/dist/chunk-PKQZWNS2.js +131 -0
  69. package/dist/chunk-PQJIQBQ5.js +57 -0
  70. package/dist/chunk-PX5AGAEX.js +105 -0
  71. package/dist/chunk-Q7HX4VZD.js +197 -0
  72. package/dist/chunk-QE5RKNVN.js +30 -0
  73. package/dist/chunk-QLVXFPE3.js +145 -0
  74. package/dist/chunk-QUC577LO.js +79 -0
  75. package/dist/chunk-RAL2W5UX.js +55 -0
  76. package/dist/chunk-RANNBYFJ.js +105 -0
  77. package/dist/chunk-RCSSFUGL.js +131 -0
  78. package/dist/chunk-RUQVXU6K.js +131 -0
  79. package/dist/chunk-RZ7TASUI.js +57 -0
  80. package/dist/chunk-SN7D2PJO.js +68 -0
  81. package/dist/chunk-T4WQUJAE.js +79 -0
  82. package/dist/chunk-U2Z5BABG.js +57 -0
  83. package/dist/chunk-UHC4DIK5.js +105 -0
  84. package/dist/chunk-UNS4S6J3.js +197 -0
  85. package/dist/chunk-UW2LYWIM.js +131 -0
  86. package/dist/chunk-VRCQBFSX.js +102 -0
  87. package/dist/chunk-W76N6IZV.js +197 -0
  88. package/dist/chunk-WTEZYXD2.js +67 -0
  89. package/dist/chunk-X7EWON4T.js +105 -0
  90. package/dist/chunk-XARAKKJ4.js +197 -0
  91. package/dist/chunk-Y6JDGDEE.js +197 -0
  92. package/dist/chunk-Y7FSNXMR.js +382 -0
  93. package/dist/chunk-YPZMUIB5.js +50 -0
  94. package/dist/chunk-ZMDUVLR4.js +148 -0
  95. package/dist/chunk-ZRFAICDG.js +382 -0
  96. package/dist/export-HEFUNSR4.js +8 -0
  97. package/dist/feedback-3U2WYQK6.js +9 -0
  98. package/dist/feedback-5IIX372K.js +9 -0
  99. package/dist/feedback-6S6DWGIU.js +9 -0
  100. package/dist/feedback-7DEOY2AP.js +9 -0
  101. package/dist/feedback-BBQT42R6.js +9 -0
  102. package/dist/feedback-CGCSAWQT.js +9 -0
  103. package/dist/feedback-NEDFOKMA.js +9 -0
  104. package/dist/feedback-OXGGJVNA.js +9 -0
  105. package/dist/feedback-ZJECE2FS.js +8 -0
  106. package/dist/help-NQUZ7TNJ.js +10 -0
  107. package/dist/index.cjs +16 -2
  108. package/dist/index.js +2 -2
  109. package/dist/login-D53NQ7UY.js +10 -0
  110. package/dist/login-GPXDNB2F.js +10 -0
  111. package/dist/login-HDF4GSTP.js +10 -0
  112. package/dist/login-SDAZTJAK.js +10 -0
  113. package/dist/login-SM6LEDDA.js +10 -0
  114. package/dist/login-TDI7HBRZ.js +10 -0
  115. package/dist/login-Y7XXSNOZ.js +10 -0
  116. package/dist/logout-32RNT7G2.js +10 -0
  117. package/dist/logout-43W7N6JU.js +10 -0
  118. package/dist/logout-BMHTSXIY.js +10 -0
  119. package/dist/logout-JNNJJYYL.js +10 -0
  120. package/dist/logout-LW42QASH.js +10 -0
  121. package/dist/logout-QLWM6P26.js +10 -0
  122. package/dist/logout-TL7GLGWU.js +10 -0
  123. package/dist/memory-GVYG653L.js +8 -0
  124. package/dist/new-MCN36AOD.js +8 -0
  125. package/dist/{status-RNUAXIRO.js → status-DCVSUWZG.js} +1 -1
  126. package/dist/status-F6TQOCON.js +8 -0
  127. package/dist/status-IT5CYW37.js +8 -0
  128. package/dist/status-MRJOSVE3.js +8 -0
  129. package/dist/status-MWFV2DZG.js +8 -0
  130. package/dist/status-N3PMJRSB.js +8 -0
  131. package/dist/status-NK7YSBXZ.js +8 -0
  132. package/dist/status-QLQ5ZKJ3.js +8 -0
  133. package/dist/status-SQEFMII5.js +8 -0
  134. package/dist/status-U33PEUBO.js +8 -0
  135. package/dist/status-XAJH67SE.js +8 -0
  136. package/package.json +16 -2
@@ -0,0 +1,68 @@
1
+ // src/constants.ts
2
+ import os from "os";
3
+ import path from "path";
4
+ var AUTOHAND_HOME = process.env.AUTOHAND_HOME || path.join(os.homedir(), ".autohand");
5
+ var AUTOHAND_PATHS = {
6
+ /** Configuration files (config.json, config.yaml, config.yml) */
7
+ config: AUTOHAND_HOME,
8
+ /** Session data storage */
9
+ sessions: path.join(AUTOHAND_HOME, "sessions"),
10
+ /** Project knowledge base */
11
+ projects: path.join(AUTOHAND_HOME, "projects"),
12
+ /** User-level memory */
13
+ memory: path.join(AUTOHAND_HOME, "memory"),
14
+ /** Feedback state and responses */
15
+ feedback: path.join(AUTOHAND_HOME, "feedback"),
16
+ /** Telemetry data */
17
+ telemetry: path.join(AUTOHAND_HOME, "telemetry"),
18
+ /** Custom commands */
19
+ commands: path.join(AUTOHAND_HOME, "commands"),
20
+ /** Agent definitions */
21
+ agents: path.join(AUTOHAND_HOME, "agents"),
22
+ /** Custom tools */
23
+ tools: path.join(AUTOHAND_HOME, "tools")
24
+ };
25
+ var AUTOHAND_FILES = {
26
+ /** Main config file */
27
+ configJson: path.join(AUTOHAND_HOME, "config.json"),
28
+ configYaml: path.join(AUTOHAND_HOME, "config.yaml"),
29
+ configYml: path.join(AUTOHAND_HOME, "config.yml"),
30
+ /** Device ID for telemetry */
31
+ deviceId: path.join(AUTOHAND_HOME, "device-id"),
32
+ /** Error log */
33
+ errorLog: path.join(AUTOHAND_HOME, "error.log"),
34
+ /** Feedback log */
35
+ feedbackLog: path.join(AUTOHAND_HOME, "feedback.log"),
36
+ /** Telemetry queue */
37
+ telemetryQueue: path.join(AUTOHAND_PATHS.telemetry, "queue.json"),
38
+ /** Session sync queue */
39
+ sessionSyncQueue: path.join(AUTOHAND_PATHS.telemetry, "session-sync-queue.json")
40
+ };
41
+ var PROJECT_DIR_NAME = ".autohand";
42
+ var AUTH_CONFIG = {
43
+ /** Base URL for the authentication API */
44
+ apiBaseUrl: "https://autohand.ai/api/auth",
45
+ /** URL where users authorize CLI devices */
46
+ authorizationUrl: "https://autohand.ai/cli-auth",
47
+ /** Polling interval in milliseconds */
48
+ pollInterval: 2e3,
49
+ /** Timeout for device authorization in milliseconds (5 minutes) */
50
+ authTimeout: 5 * 60 * 1e3,
51
+ /** CLI session expiry in days */
52
+ sessionExpiryDays: 30
53
+ };
54
+
55
+ export {
56
+ AUTOHAND_HOME,
57
+ AUTOHAND_PATHS,
58
+ AUTOHAND_FILES,
59
+ PROJECT_DIR_NAME,
60
+ AUTH_CONFIG
61
+ };
62
+ /**
63
+ * @license
64
+ * Copyright 2025 Autohand AI LLC
65
+ * SPDX-License-Identifier: Apache-2.0
66
+ *
67
+ * Centralized constants for Autohand CLI
68
+ */
@@ -0,0 +1,197 @@
1
+ import {
2
+ AUTOHAND_PATHS
3
+ } from "./chunk-7FMMKTRG.js";
4
+
5
+ // src/commands/agents.ts
6
+ import chalk from "chalk";
7
+
8
+ // src/core/agents/AgentRegistry.ts
9
+ import fs from "fs/promises";
10
+ import os from "os";
11
+ import path from "path";
12
+ import { z } from "zod";
13
+ var AgentConfigSchema = z.object({
14
+ description: z.string(),
15
+ systemPrompt: z.string(),
16
+ tools: z.array(z.string()),
17
+ model: z.string().optional()
18
+ });
19
+ var AgentRegistry = class _AgentRegistry {
20
+ constructor() {
21
+ this.agents = /* @__PURE__ */ new Map();
22
+ this.externalPaths = [];
23
+ this.agentsDir = AUTOHAND_PATHS.agents;
24
+ }
25
+ static getInstance() {
26
+ if (!_AgentRegistry.instance) {
27
+ _AgentRegistry.instance = new _AgentRegistry();
28
+ }
29
+ return _AgentRegistry.instance;
30
+ }
31
+ /**
32
+ * Set external agent paths from config
33
+ * Supports tilde (~) expansion for home directory
34
+ */
35
+ setExternalPaths(paths) {
36
+ this.externalPaths = paths.map(
37
+ (p) => p.startsWith("~") ? path.join(os.homedir(), p.slice(1)) : p
38
+ );
39
+ }
40
+ /**
41
+ * Get configured external paths
42
+ */
43
+ getExternalPaths() {
44
+ return [...this.externalPaths];
45
+ }
46
+ /**
47
+ * Scans the agents directory and all external paths for agent configurations.
48
+ */
49
+ async loadAgents() {
50
+ this.agents.clear();
51
+ await this.loadAgentsFromDir(this.agentsDir, "user");
52
+ for (const extPath of this.externalPaths) {
53
+ await this.loadAgentsFromDir(extPath, "external");
54
+ }
55
+ }
56
+ /**
57
+ * Load agents from a specific directory
58
+ */
59
+ async loadAgentsFromDir(dir, source) {
60
+ try {
61
+ if (source === "user") {
62
+ await fs.mkdir(dir, { recursive: true });
63
+ }
64
+ const exists = await fs.access(dir).then(() => true).catch(() => false);
65
+ if (!exists) {
66
+ return;
67
+ }
68
+ const files = await fs.readdir(dir);
69
+ for (const file of files) {
70
+ const filePath = path.join(dir, file);
71
+ const stat = await fs.stat(filePath).catch(() => null);
72
+ if (!stat?.isFile()) {
73
+ continue;
74
+ }
75
+ if (file.endsWith(".json")) {
76
+ await this.loadJsonAgent(filePath, source);
77
+ continue;
78
+ }
79
+ if (file.endsWith(".md") || file.endsWith(".markdown")) {
80
+ await this.loadMarkdownAgent(filePath, source);
81
+ }
82
+ }
83
+ } catch (error) {
84
+ if (source === "user") {
85
+ console.error(`Error loading agents from ${dir}:`, error);
86
+ }
87
+ }
88
+ }
89
+ getAgent(name) {
90
+ return this.agents.get(name);
91
+ }
92
+ getAllAgents() {
93
+ return Array.from(this.agents.values());
94
+ }
95
+ getAgentsDirectory() {
96
+ return this.agentsDir;
97
+ }
98
+ /**
99
+ * Get agents filtered by source
100
+ */
101
+ getAgentsBySource(source) {
102
+ return this.getAllAgents().filter((a) => a.source === source);
103
+ }
104
+ async loadJsonAgent(filePath, source) {
105
+ const name = path.basename(filePath, ".json");
106
+ try {
107
+ const content = await fs.readFile(filePath, "utf-8");
108
+ const json = JSON.parse(content);
109
+ const config = AgentConfigSchema.parse(json);
110
+ if (!this.agents.has(name)) {
111
+ this.agents.set(name, { name, path: filePath, source, ...config });
112
+ }
113
+ } catch (error) {
114
+ console.warn(`Failed to load agent '${name}': ${error.message}`);
115
+ }
116
+ }
117
+ async loadMarkdownAgent(filePath, source) {
118
+ const name = path.basename(filePath, path.extname(filePath));
119
+ try {
120
+ const content = await fs.readFile(filePath, "utf-8");
121
+ const description = extractMarkdownTitle(content) || `Agent ${name}`;
122
+ const definition = {
123
+ name,
124
+ path: filePath,
125
+ source,
126
+ description,
127
+ systemPrompt: content,
128
+ tools: [],
129
+ model: void 0
130
+ };
131
+ if (!this.agents.has(name)) {
132
+ this.agents.set(name, definition);
133
+ }
134
+ } catch (error) {
135
+ console.warn(`Failed to load agent '${name}': ${error.message}`);
136
+ }
137
+ }
138
+ };
139
+ function extractMarkdownTitle(content) {
140
+ const lines = content.split(/\r?\n/);
141
+ for (const line of lines) {
142
+ const trimmed = line.trim();
143
+ if (!trimmed) continue;
144
+ if (trimmed.startsWith("#")) {
145
+ return trimmed.replace(/^#+\s*/, "").trim() || null;
146
+ }
147
+ return trimmed;
148
+ }
149
+ return null;
150
+ }
151
+
152
+ // src/commands/agents.ts
153
+ var metadata = {
154
+ command: "/agents",
155
+ description: "list available sub-agents (markdown or json)",
156
+ implemented: true,
157
+ prd: "prd/sub_agents_architecture.md"
158
+ };
159
+ async function handler() {
160
+ const registry = AgentRegistry.getInstance();
161
+ await registry.loadAgents();
162
+ const agents = registry.getAllAgents();
163
+ if (agents.length === 0) {
164
+ return `No agents found in ${chalk.cyan(registry.getAgentsDirectory())}.
165
+ Create a markdown file (e.g., helper.md) there to define a new sub-agent.`;
166
+ }
167
+ let output = chalk.bold("Available Agents:\n\n");
168
+ for (const agent of agents) {
169
+ output += `${chalk.green("\u{1F916} " + agent.name)}
170
+ `;
171
+ output += ` ${chalk.gray(agent.description)}
172
+ `;
173
+ output += ` ${chalk.blue("Path:")} ${agent.path}
174
+ `;
175
+ if (agent.model) {
176
+ output += ` ${chalk.yellow("Model:")} ${agent.model}
177
+ `;
178
+ }
179
+ if (agent.tools?.length) {
180
+ output += ` ${chalk.blue("Tools:")} ${agent.tools.join(", ")}
181
+ `;
182
+ }
183
+ output += "\n";
184
+ }
185
+ return output.trim();
186
+ }
187
+
188
+ export {
189
+ AgentRegistry,
190
+ metadata,
191
+ handler
192
+ };
193
+ /**
194
+ * @license
195
+ * Copyright 2025 Autohand AI LLC
196
+ * SPDX-License-Identifier: Apache-2.0
197
+ */
@@ -0,0 +1,79 @@
1
+ import {
2
+ AUTOHAND_FILES
3
+ } from "./chunk-2EPIFDFM.js";
4
+
5
+ // src/commands/feedback.ts
6
+ import fs from "fs-extra";
7
+ import chalk from "chalk";
8
+ import enquirer from "enquirer";
9
+ var metadata = {
10
+ command: "/feedback",
11
+ description: "share feedback with environment details",
12
+ implemented: true
13
+ };
14
+ async function feedback(_ctx) {
15
+ const answer = await enquirer.prompt([
16
+ {
17
+ type: "input",
18
+ name: "feedback",
19
+ message: "What worked? What broke?"
20
+ }
21
+ ]);
22
+ if (!answer.feedback?.trim()) {
23
+ console.log(chalk.gray("Feedback discarded (empty)."));
24
+ return null;
25
+ }
26
+ const now = (/* @__PURE__ */ new Date()).toISOString();
27
+ const runtimeError = getLastRuntimeError();
28
+ const payload = {
29
+ timestamp: now,
30
+ feedback: answer.feedback.trim(),
31
+ env: {
32
+ platform: `${process.platform}-${process.arch}`,
33
+ node: process.version,
34
+ bun: process.versions?.bun,
35
+ cwd: process.cwd(),
36
+ shell: process.env.SHELL
37
+ },
38
+ runtimeError: runtimeError ? formatError(runtimeError) : null
39
+ };
40
+ try {
41
+ const feedbackPath = AUTOHAND_FILES.feedbackLog;
42
+ await fs.ensureFile(feedbackPath);
43
+ await fs.appendFile(feedbackPath, JSON.stringify(payload) + "\n", "utf8");
44
+ console.log(chalk.green("Feedback recorded."));
45
+ console.log(chalk.gray(`Saved to ${feedbackPath}`));
46
+ } catch (error) {
47
+ console.error(chalk.red(`Failed to save feedback: ${error.message}`));
48
+ }
49
+ if (runtimeError) {
50
+ console.log(chalk.yellow("Detected a recent runtime error; included in feedback payload."));
51
+ }
52
+ return null;
53
+ }
54
+ function getLastRuntimeError() {
55
+ const globalAny = globalThis;
56
+ return globalAny.__autohandLastError ?? null;
57
+ }
58
+ function formatError(err) {
59
+ if (!err) return {};
60
+ if (err instanceof Error) {
61
+ return { message: err.message, stack: err.stack };
62
+ }
63
+ if (typeof err === "object") {
64
+ const message = "message" in err ? String(err.message) : void 0;
65
+ const stack = "stack" in err ? String(err.stack) : void 0;
66
+ return { message, stack };
67
+ }
68
+ return { message: String(err) };
69
+ }
70
+
71
+ export {
72
+ metadata,
73
+ feedback
74
+ };
75
+ /**
76
+ * @license
77
+ * Copyright 2025 Autohand AI LLC
78
+ * SPDX-License-Identifier: Apache-2.0
79
+ */
@@ -0,0 +1,57 @@
1
+ import {
2
+ getAuthClient,
3
+ saveConfig
4
+ } from "./chunk-HJYISR7Y.js";
5
+
6
+ // src/commands/logout.ts
7
+ import chalk from "chalk";
8
+ import enquirer from "enquirer";
9
+ var metadata = {
10
+ command: "/logout",
11
+ description: "sign out of your Autohand account",
12
+ implemented: true
13
+ };
14
+ async function logout(ctx) {
15
+ const config = ctx.config;
16
+ if (!config?.auth?.token) {
17
+ console.log(chalk.yellow("You are not currently logged in."));
18
+ console.log(chalk.gray("Use /login to sign in to your Autohand account."));
19
+ return null;
20
+ }
21
+ const userName = config.auth.user?.name || config.auth.user?.email || "user";
22
+ const { confirm } = await enquirer.prompt({
23
+ type: "confirm",
24
+ name: "confirm",
25
+ message: `Log out from ${chalk.cyan(userName)}?`,
26
+ initial: true
27
+ });
28
+ if (!confirm) {
29
+ console.log(chalk.gray("Logout cancelled."));
30
+ return null;
31
+ }
32
+ const authClient = getAuthClient();
33
+ try {
34
+ await authClient.logout(config.auth.token);
35
+ } catch {
36
+ }
37
+ const updatedConfig = {
38
+ ...config,
39
+ auth: void 0
40
+ };
41
+ await saveConfig(updatedConfig);
42
+ console.log();
43
+ console.log(chalk.green("Successfully logged out."));
44
+ console.log(chalk.gray("Your local session has been cleared."));
45
+ console.log();
46
+ return null;
47
+ }
48
+
49
+ export {
50
+ metadata,
51
+ logout
52
+ };
53
+ /**
54
+ * @license
55
+ * Copyright 2025 Autohand AI LLC
56
+ * SPDX-License-Identifier: Apache-2.0
57
+ */
@@ -0,0 +1,79 @@
1
+ import {
2
+ AUTOHAND_FILES
3
+ } from "./chunk-SN7D2PJO.js";
4
+
5
+ // src/commands/feedback.ts
6
+ import fs from "fs-extra";
7
+ import chalk from "chalk";
8
+ import enquirer from "enquirer";
9
+ var metadata = {
10
+ command: "/feedback",
11
+ description: "share feedback with environment details",
12
+ implemented: true
13
+ };
14
+ async function feedback(_ctx) {
15
+ const answer = await enquirer.prompt([
16
+ {
17
+ type: "input",
18
+ name: "feedback",
19
+ message: "What worked? What broke?"
20
+ }
21
+ ]);
22
+ if (!answer.feedback?.trim()) {
23
+ console.log(chalk.gray("Feedback discarded (empty)."));
24
+ return null;
25
+ }
26
+ const now = (/* @__PURE__ */ new Date()).toISOString();
27
+ const runtimeError = getLastRuntimeError();
28
+ const payload = {
29
+ timestamp: now,
30
+ feedback: answer.feedback.trim(),
31
+ env: {
32
+ platform: `${process.platform}-${process.arch}`,
33
+ node: process.version,
34
+ bun: process.versions?.bun,
35
+ cwd: process.cwd(),
36
+ shell: process.env.SHELL
37
+ },
38
+ runtimeError: runtimeError ? formatError(runtimeError) : null
39
+ };
40
+ try {
41
+ const feedbackPath = AUTOHAND_FILES.feedbackLog;
42
+ await fs.ensureFile(feedbackPath);
43
+ await fs.appendFile(feedbackPath, JSON.stringify(payload) + "\n", "utf8");
44
+ console.log(chalk.green("Feedback recorded."));
45
+ console.log(chalk.gray(`Saved to ${feedbackPath}`));
46
+ } catch (error) {
47
+ console.error(chalk.red(`Failed to save feedback: ${error.message}`));
48
+ }
49
+ if (runtimeError) {
50
+ console.log(chalk.yellow("Detected a recent runtime error; included in feedback payload."));
51
+ }
52
+ return null;
53
+ }
54
+ function getLastRuntimeError() {
55
+ const globalAny = globalThis;
56
+ return globalAny.__autohandLastError ?? null;
57
+ }
58
+ function formatError(err) {
59
+ if (!err) return {};
60
+ if (err instanceof Error) {
61
+ return { message: err.message, stack: err.stack };
62
+ }
63
+ if (typeof err === "object") {
64
+ const message = "message" in err ? String(err.message) : void 0;
65
+ const stack = "stack" in err ? String(err.stack) : void 0;
66
+ return { message, stack };
67
+ }
68
+ return { message: String(err) };
69
+ }
70
+
71
+ export {
72
+ metadata,
73
+ feedback
74
+ };
75
+ /**
76
+ * @license
77
+ * Copyright 2025 Autohand AI LLC
78
+ * SPDX-License-Identifier: Apache-2.0
79
+ */
@@ -5,7 +5,7 @@ import readline from "readline";
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "autohand-cli",
8
- version: "0.6.0",
8
+ version: "0.1.0",
9
9
  description: "Autohand interactive coding agent CLI powered by LLMs.",
10
10
  type: "module",
11
11
  bin: {