autohand-cli 0.7.6 → 0.7.7

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 (135) hide show
  1. package/dist/{AutomodeManager-TJSW2SQY.cjs → AutomodeManager-HV6M7EAX.cjs} +61 -22
  2. package/dist/{AutomodeManager-WIMHLG4W.js → AutomodeManager-YVCJXOMQ.js} +61 -22
  3. package/dist/CommunitySkillsCache-2BITCEAA.cjs +7 -0
  4. package/dist/{CommunitySkillsCache-XPDVYU3K.js → CommunitySkillsCache-Q22FUAR5.js} +2 -2
  5. package/dist/HookManager-X47HCM5G.cjs +6 -0
  6. package/dist/{HookManager-VIX56KFU.js → HookManager-ZXKHCD7U.js} +1 -1
  7. package/dist/MemoryManager-2ATHG7BH.js +7 -0
  8. package/dist/MemoryManager-AENCGCEW.cjs +7 -0
  9. package/dist/PermissionManager-6HZGTK2N.cjs +10 -0
  10. package/dist/{PermissionManager-YFZI4ZZ6.js → PermissionManager-HATZKTRC.js} +3 -3
  11. package/dist/SessionManager-AG4WT3DP.cjs +9 -0
  12. package/dist/{SessionManager-XDBEQUPG.js → SessionManager-S5R6O3NU.js} +2 -2
  13. package/dist/{SkillsRegistry-7NICF6FY.js → SkillsRegistry-R5WDM6T3.js} +2 -2
  14. package/dist/SkillsRegistry-ZXU6YDRP.cjs +8 -0
  15. package/dist/SyncApiClient-FAOMIZAP.js +10 -0
  16. package/dist/SyncApiClient-UOA4VLLD.cjs +10 -0
  17. package/dist/add-dir-OMK3Y4DM.cjs +8 -0
  18. package/dist/add-dir-PNU7AGKO.js +8 -0
  19. package/dist/{agents-B33IAATH.js → agents-ICAC3KD3.js} +2 -2
  20. package/dist/agents-YONWPKFS.cjs +9 -0
  21. package/dist/agents-new-NV557UVG.cjs +10 -0
  22. package/dist/{agents-new-KTXJFC5E.js → agents-new-QHM3CO4B.js} +2 -2
  23. package/dist/{chunk-MFLRXVKU.js → chunk-23JQSCTO.js} +1 -1
  24. package/dist/chunk-2JPUEN44.cjs +299 -0
  25. package/dist/{chunk-5PD2L6WI.js → chunk-3YEDXG6S.js} +1 -1
  26. package/dist/{chunk-3ZUWWML7.cjs → chunk-4M2GX7RH.cjs} +2 -2
  27. package/dist/{chunk-R5KNHJ27.js → chunk-4RWTUT2Z.js} +1 -1
  28. package/dist/{chunk-CHQMK2ZG.js → chunk-52MLYK5P.js} +1 -1
  29. package/dist/{chunk-CVYEUA3D.cjs → chunk-53BR4MUW.cjs} +3 -3
  30. package/dist/{chunk-5WKR4HIB.js → chunk-5DN5KNXU.js} +1 -1
  31. package/dist/{chunk-3CO5R6M2.cjs → chunk-7TOHYAUF.cjs} +2 -2
  32. package/dist/{chunk-67NJKV5A.cjs → chunk-7VW3A7DO.cjs} +2 -2
  33. package/dist/{chunk-2W3QTBNG.cjs → chunk-A552JHUJ.cjs} +2 -2
  34. package/dist/{chunk-NGSLABLS.js → chunk-A6QBABQ7.js} +1 -1
  35. package/dist/chunk-ARVFUZOB.js +736 -0
  36. package/dist/{chunk-VO3JKFUH.js → chunk-AVL4DKQO.js} +1 -1
  37. package/dist/{chunk-CT2VTDPQ.cjs → chunk-B4ZPNXZE.cjs} +1 -1
  38. package/dist/{chunk-OKMYLMCR.cjs → chunk-B7EUETGY.cjs} +4 -4
  39. package/dist/chunk-C26EN22G.cjs +328 -0
  40. package/dist/chunk-DOTAX65F.js +328 -0
  41. package/dist/{chunk-SKT2CRNY.cjs → chunk-DSKVMFRM.cjs} +56 -8
  42. package/dist/{chunk-FUEL6BK7.js → chunk-EKY5PKQI.js} +15 -0
  43. package/dist/{chunk-YMP7AGNT.js → chunk-G77ZY4QG.js} +1 -1
  44. package/dist/{chunk-KN5C4TR4.cjs → chunk-GDTZQSJ6.cjs} +2 -2
  45. package/dist/{chunk-536VWSZK.cjs → chunk-GFJ6AETU.cjs} +4 -4
  46. package/dist/{chunk-723DZKBU.js → chunk-GR7VWN63.js} +2 -2
  47. package/dist/{chunk-PVM5I5WI.js → chunk-GWIAMKKF.js} +1 -1
  48. package/dist/{chunk-XAM7SFVB.cjs → chunk-GWXXFQ3F.cjs} +2 -2
  49. package/dist/{chunk-REPKBECD.cjs → chunk-JHFH3N4U.cjs} +2 -2
  50. package/dist/{chunk-4L5WYXHN.js → chunk-KH7BCZJN.js} +1 -1
  51. package/dist/{chunk-JXOXZTMA.js → chunk-L5ZFPWHY.js} +54 -6
  52. package/dist/chunk-MDWULS57.js +288 -0
  53. package/dist/{chunk-6LP2GO5C.js → chunk-MJFBVQHB.js} +2 -2
  54. package/dist/{chunk-MWLAHCU7.js → chunk-NI3BQXKU.js} +1 -1
  55. package/dist/{chunk-KJ67C72C.cjs → chunk-NYQVQYIF.cjs} +2 -2
  56. package/dist/{chunk-SKU4M27Z.js → chunk-OBV3UUIL.js} +1 -1
  57. package/dist/{chunk-27ISZOFA.js → chunk-P2Z6GDEN.js} +1 -1
  58. package/dist/{chunk-XTHHDIBG.cjs → chunk-PMMSDR44.cjs} +16 -1
  59. package/dist/{chunk-K6NBYSME.cjs → chunk-PR53E47T.cjs} +6 -6
  60. package/dist/{chunk-URY4AS4L.cjs → chunk-PU534KPO.cjs} +4 -4
  61. package/dist/{chunk-5MCDN53U.js → chunk-Q3WCMY3Z.js} +4 -2
  62. package/dist/{chunk-4KZCGK7D.js → chunk-QXAPHGEW.js} +1 -1
  63. package/dist/chunk-SFGJQPGC.cjs +288 -0
  64. package/dist/{chunk-53YDUYNS.cjs → chunk-SLISYSP4.cjs} +2 -2
  65. package/dist/{chunk-2E2COWKB.cjs → chunk-SYJLMBLP.cjs} +66 -10
  66. package/dist/chunk-U5WIP4HS.js +674 -0
  67. package/dist/{chunk-7HB7GSQF.js → chunk-UL7YPRCU.js} +1 -1
  68. package/dist/{chunk-JYTXG6OV.cjs → chunk-VDZJ3W4M.cjs} +4 -2
  69. package/dist/{chunk-LUKMRIKJ.cjs → chunk-VEDIYPWY.cjs} +2 -2
  70. package/dist/{chunk-C2NFLFHH.js → chunk-VPAN5H7Q.js} +1 -1
  71. package/dist/chunk-WH3D42BQ.js +299 -0
  72. package/dist/{chunk-2FSQPRPJ.js → chunk-WIUGUR5T.js} +59 -3
  73. package/dist/{chunk-QMVTT55Y.cjs → chunk-WQSWU2QA.cjs} +4 -4
  74. package/dist/chunk-XFPITUFJ.cjs +674 -0
  75. package/dist/chunk-XFQS2VGT.cjs +736 -0
  76. package/dist/{chunk-HYTYXN2G.cjs → chunk-YAGD43KA.cjs} +10 -10
  77. package/dist/constants-G2PLP5HH.cjs +20 -0
  78. package/dist/{constants-QYBEF3DB.js → constants-ZLG6M5SI.js} +3 -1
  79. package/dist/{defaultHooks-3G3DVF6I.js → defaultHooks-R56VYG7I.js} +315 -1
  80. package/dist/{defaultHooks-Z4KA6U5C.cjs → defaultHooks-WLMRQUXG.cjs} +315 -1
  81. package/dist/{feedback-PZ2PINDU.js → feedback-HZBCTSFG.js} +2 -2
  82. package/dist/feedback-JBQ3UPGZ.cjs +10 -0
  83. package/dist/index.cjs +897 -600
  84. package/dist/index.js +1438 -1141
  85. package/dist/language-KODBDE5R.js +12 -0
  86. package/dist/language-SJT475NW.cjs +12 -0
  87. package/dist/localProjectPermissions-AYQYGTOE.cjs +17 -0
  88. package/dist/{localProjectPermissions-DURCNDZG.js → localProjectPermissions-YFFAKLUZ.js} +2 -2
  89. package/dist/login-TC2KROQI.js +14 -0
  90. package/dist/login-TYMR2ZD3.cjs +14 -0
  91. package/dist/logout-2ECV365P.js +12 -0
  92. package/dist/logout-CO3CPYZJ.cjs +12 -0
  93. package/dist/resume-EPOEF3WV.cjs +9 -0
  94. package/dist/{resume-CWYAK6XR.js → resume-LOYD5MMP.js} +2 -2
  95. package/dist/share-544SIZOY.js +10 -0
  96. package/dist/share-OETK2GUF.cjs +10 -0
  97. package/dist/{skills-CRFOVWEQ.js → skills-3YEEODHK.js} +1 -1
  98. package/dist/skills-CRM55MKM.cjs +12 -0
  99. package/dist/{skills-install-Z27KPEGF.cjs → skills-install-FTGOHOZ4.cjs} +5 -5
  100. package/dist/{skills-install-RMPXN6RK.js → skills-install-KAXAQSN6.js} +2 -2
  101. package/dist/skills-new-JF4FKNUT.cjs +11 -0
  102. package/dist/{skills-new-S2YPO635.js → skills-new-JYX2GBKM.js} +2 -2
  103. package/dist/{status-GPAZ67ZZ.js → status-7LCXYYY4.js} +2 -2
  104. package/dist/status-E7MZEQ26.cjs +9 -0
  105. package/dist/sync-3B7SNBYC.js +14 -0
  106. package/dist/sync-4RARBQIH.cjs +39 -0
  107. package/dist/sync-H4UHHLKU.js +39 -0
  108. package/dist/sync-YZ6YZ42H.cjs +14 -0
  109. package/dist/theme-3XV5BWUB.js +12 -0
  110. package/dist/theme-Z2WS5XWZ.cjs +12 -0
  111. package/package.json +4 -2
  112. package/dist/CommunitySkillsCache-X3X237QQ.cjs +0 -7
  113. package/dist/HookManager-EOMUXKJ4.cjs +0 -6
  114. package/dist/MemoryManager-UVHILGV5.js +0 -7
  115. package/dist/MemoryManager-WO3KUZVA.cjs +0 -7
  116. package/dist/PermissionManager-PMTQN263.cjs +0 -10
  117. package/dist/SessionManager-M5ZLCLCW.cjs +0 -9
  118. package/dist/SkillsRegistry-OINIPILA.cjs +0 -8
  119. package/dist/agents-GRAFXZY3.cjs +0 -9
  120. package/dist/agents-new-67NJJSDA.cjs +0 -10
  121. package/dist/constants-PE5DLI7Q.cjs +0 -18
  122. package/dist/feedback-R66B3B3C.cjs +0 -10
  123. package/dist/localProjectPermissions-75X3ZGKH.cjs +0 -17
  124. package/dist/login-NYWZRZO5.js +0 -12
  125. package/dist/login-QNJ5C42G.cjs +0 -12
  126. package/dist/logout-MBS7L3ZW.js +0 -12
  127. package/dist/logout-MVUP7GPU.cjs +0 -12
  128. package/dist/resume-ANISKRWL.cjs +0 -9
  129. package/dist/share-3PSV53CQ.js +0 -10
  130. package/dist/share-4ACH6626.cjs +0 -10
  131. package/dist/skills-6PIGHOWS.cjs +0 -12
  132. package/dist/skills-new-3QJUST7P.cjs +0 -11
  133. package/dist/status-4U5CPUVT.cjs +0 -9
  134. package/dist/theme-CVY6MVEK.cjs +0 -12
  135. package/dist/theme-CY7WF4M6.js +0 -12
@@ -0,0 +1,328 @@
1
+ // src/commands/add-dir.ts
2
+ import chalk2 from "chalk";
3
+ import fs2 from "fs-extra";
4
+ import path2 from "path";
5
+
6
+ // src/startup/workspaceSafety.ts
7
+ import os from "os";
8
+ import path from "path";
9
+ import fs from "fs-extra";
10
+ import chalk from "chalk";
11
+ var DANGEROUS_PATHS = {
12
+ // Filesystem roots (Unix and Windows)
13
+ roots: ["/", "C:\\", "D:\\", "E:\\", "F:\\", "G:\\"],
14
+ // System directories (Unix/Linux)
15
+ unix: [
16
+ "/etc",
17
+ "/var",
18
+ "/usr",
19
+ "/opt",
20
+ "/bin",
21
+ "/sbin",
22
+ "/lib",
23
+ "/lib64",
24
+ "/root",
25
+ "/sys",
26
+ "/proc",
27
+ "/dev",
28
+ "/boot",
29
+ "/run",
30
+ "/snap"
31
+ ],
32
+ // System directories (macOS)
33
+ macos: [
34
+ "/System",
35
+ "/Library",
36
+ "/Applications",
37
+ "/private",
38
+ "/cores",
39
+ "/Volumes"
40
+ ],
41
+ // System directories (Windows)
42
+ windows: [
43
+ "C:\\Windows",
44
+ "C:\\Program Files",
45
+ "C:\\Program Files (x86)",
46
+ "C:\\ProgramData",
47
+ "C:\\Recovery",
48
+ "C:\\$Recycle.Bin"
49
+ ],
50
+ // WSL mount points (Windows drives mounted in WSL)
51
+ wsl: ["/mnt/c", "/mnt/d", "/mnt/e", "/mnt/f"]
52
+ };
53
+ function normalizePath(inputPath) {
54
+ let normalized = path.resolve(inputPath);
55
+ try {
56
+ normalized = fs.realpathSync(normalized);
57
+ } catch {
58
+ }
59
+ if (normalized.length > 1 && normalized.endsWith(path.sep)) {
60
+ normalized = normalized.slice(0, -1);
61
+ }
62
+ return normalized;
63
+ }
64
+ function pathsEqual(path1, path22) {
65
+ const normalized1 = normalizePath(path1);
66
+ const normalized2 = normalizePath(path22);
67
+ if (process.platform === "darwin" || process.platform === "win32") {
68
+ return normalized1.toLowerCase() === normalized2.toLowerCase();
69
+ }
70
+ return normalized1 === normalized2;
71
+ }
72
+ function isFilesystemRoot(workspacePath) {
73
+ const normalized = normalizePath(workspacePath);
74
+ if (normalized === "/") {
75
+ return true;
76
+ }
77
+ if (process.platform === "win32") {
78
+ if (/^[A-Za-z]:[\\/]?$/.test(normalized)) {
79
+ return true;
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+ function isHomeDirectory(workspacePath) {
85
+ const homeDir = os.homedir();
86
+ return pathsEqual(workspacePath, homeDir);
87
+ }
88
+ function isParentOfHome(workspacePath) {
89
+ const homeDir = os.homedir();
90
+ const normalized = normalizePath(workspacePath);
91
+ const normalizedHome = normalizePath(homeDir);
92
+ if (process.platform === "darwin" || process.platform === "win32") {
93
+ return normalizedHome.toLowerCase().startsWith(normalized.toLowerCase() + path.sep);
94
+ }
95
+ return normalizedHome.startsWith(normalized + path.sep);
96
+ }
97
+ function isSystemDirectory(workspacePath) {
98
+ const normalized = normalizePath(workspacePath);
99
+ const dangerousPaths = [
100
+ ...DANGEROUS_PATHS.roots,
101
+ ...DANGEROUS_PATHS.unix,
102
+ ...DANGEROUS_PATHS.macos,
103
+ ...DANGEROUS_PATHS.windows,
104
+ ...DANGEROUS_PATHS.wsl
105
+ ];
106
+ for (const dangerous of dangerousPaths) {
107
+ if (pathsEqual(normalized, dangerous)) {
108
+ return true;
109
+ }
110
+ }
111
+ return false;
112
+ }
113
+ function isWindowsUserHome(workspacePath) {
114
+ const windowsUsersPattern = /^[A-Za-z]:[/\\]Users([/\\][^/\\]+)?$/i;
115
+ if (windowsUsersPattern.test(workspacePath)) {
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ function isWslWindowsHome(workspacePath) {
121
+ const normalized = normalizePath(workspacePath);
122
+ for (const wslMount of DANGEROUS_PATHS.wsl) {
123
+ if (pathsEqual(normalized, wslMount)) {
124
+ return true;
125
+ }
126
+ }
127
+ const wslUsersPattern = /^\/mnt\/[a-z]\/users(\/[^/]+)?$/i;
128
+ if (wslUsersPattern.test(normalized)) {
129
+ return true;
130
+ }
131
+ const wslWindowsPattern = /^\/mnt\/[a-z]\/windows$/i;
132
+ if (wslWindowsPattern.test(normalized)) {
133
+ return true;
134
+ }
135
+ return false;
136
+ }
137
+ function getDangerReason(workspacePath) {
138
+ const normalized = normalizePath(workspacePath);
139
+ if (isFilesystemRoot(workspacePath)) {
140
+ return "This is the filesystem root directory.";
141
+ }
142
+ if (isHomeDirectory(workspacePath)) {
143
+ return "This is your home directory.";
144
+ }
145
+ if (isParentOfHome(workspacePath)) {
146
+ return "This directory contains user home directories.";
147
+ }
148
+ if (isWslWindowsHome(workspacePath)) {
149
+ return "This is a Windows system directory accessed via WSL.";
150
+ }
151
+ if (normalized.startsWith("/etc") || normalized.match(/^[A-Za-z]:\\Windows/i)) {
152
+ return "This is a system configuration directory.";
153
+ }
154
+ if (normalized.startsWith("/var") || normalized.match(/^[A-Za-z]:\\ProgramData/i)) {
155
+ return "This is a system data directory.";
156
+ }
157
+ if (normalized.startsWith("/usr") || normalized.match(/^[A-Za-z]:\\Program Files/i)) {
158
+ return "This is a system programs directory.";
159
+ }
160
+ if (normalized.startsWith("/System") || normalized.startsWith("/Library")) {
161
+ return "This is a macOS system directory.";
162
+ }
163
+ return "This directory is too broad for safe AI agent operation.";
164
+ }
165
+ function checkWorkspaceSafety(workspacePath) {
166
+ try {
167
+ const normalized = normalizePath(workspacePath);
168
+ if (isFilesystemRoot(normalized)) {
169
+ return {
170
+ safe: false,
171
+ reason: "This is the filesystem root directory. Running an AI agent here could modify critical system files.",
172
+ suggestion: "Navigate to a specific project folder and try again."
173
+ };
174
+ }
175
+ if (isHomeDirectory(normalized)) {
176
+ return {
177
+ safe: false,
178
+ reason: "This is your home directory. Running an AI agent here could modify files across your entire user account.",
179
+ suggestion: "Navigate to a specific project folder (e.g., ~/projects/my-app) and try again."
180
+ };
181
+ }
182
+ if (isParentOfHome(normalized)) {
183
+ return {
184
+ safe: false,
185
+ reason: "This directory contains user home directories. Running an AI agent here is too broad.",
186
+ suggestion: "Navigate to a specific project folder and try again."
187
+ };
188
+ }
189
+ if (isSystemDirectory(normalized)) {
190
+ return {
191
+ safe: false,
192
+ reason: getDangerReason(normalized),
193
+ suggestion: "Navigate to a specific project folder and try again."
194
+ };
195
+ }
196
+ if (isWslWindowsHome(normalized)) {
197
+ return {
198
+ safe: false,
199
+ reason: getDangerReason(normalized),
200
+ suggestion: "Navigate to a specific project folder and try again."
201
+ };
202
+ }
203
+ if (isWindowsUserHome(workspacePath)) {
204
+ return {
205
+ safe: false,
206
+ reason: "This is a Windows user home directory. Running an AI agent here could modify files across the user account.",
207
+ suggestion: "Navigate to a specific project folder and try again."
208
+ };
209
+ }
210
+ return { safe: true };
211
+ } catch (error) {
212
+ console.warn(`Warning: Could not verify workspace safety for "${workspacePath}": ${error}`);
213
+ return { safe: true };
214
+ }
215
+ }
216
+ function printDangerousWorkspaceWarning(workspacePath, result) {
217
+ const boxWidth = 65;
218
+ const horizontalLine = "\u2500".repeat(boxWidth - 2);
219
+ console.log();
220
+ console.log(chalk.red(`\u250C${horizontalLine}\u2510`));
221
+ console.log(chalk.red(`\u2502`) + chalk.yellow.bold(" \u26A0\uFE0F Unsafe Workspace Directory") + " ".repeat(boxWidth - 35) + chalk.red("\u2502"));
222
+ console.log(chalk.red(`\u251C${horizontalLine}\u2524`));
223
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
224
+ console.log(chalk.red(`\u2502`) + chalk.white(" You're trying to run autohand in:") + " ".repeat(boxWidth - 38) + chalk.red("\u2502"));
225
+ const pathLine = ` ${workspacePath}`;
226
+ const truncatedPath = pathLine.length > boxWidth - 4 ? pathLine.slice(0, boxWidth - 7) + "..." : pathLine;
227
+ console.log(chalk.red(`\u2502`) + chalk.cyan(truncatedPath) + " ".repeat(Math.max(0, boxWidth - 2 - truncatedPath.length)) + chalk.red("\u2502"));
228
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
229
+ if (result.reason) {
230
+ const reasonWords = result.reason.split(" ");
231
+ let currentLine = " ";
232
+ for (const word of reasonWords) {
233
+ if (currentLine.length + word.length + 1 > boxWidth - 4) {
234
+ const paddedLine = currentLine + " ".repeat(Math.max(0, boxWidth - 2 - currentLine.length));
235
+ console.log(chalk.red(`\u2502`) + chalk.white(paddedLine) + chalk.red("\u2502"));
236
+ currentLine = " ";
237
+ }
238
+ currentLine += (currentLine === " " ? "" : " ") + word;
239
+ }
240
+ if (currentLine.length > 2) {
241
+ const paddedLine = currentLine + " ".repeat(Math.max(0, boxWidth - 2 - currentLine.length));
242
+ console.log(chalk.red(`\u2502`) + chalk.white(paddedLine) + chalk.red("\u2502"));
243
+ }
244
+ }
245
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
246
+ console.log(chalk.red(`\u2502`) + chalk.white(" Please navigate to a specific project folder:") + " ".repeat(boxWidth - 50) + chalk.red("\u2502"));
247
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
248
+ console.log(chalk.red(`\u2502`) + chalk.cyan(" cd ~/projects/my-app") + " ".repeat(boxWidth - 27) + chalk.red("\u2502"));
249
+ console.log(chalk.red(`\u2502`) + chalk.cyan(" autohand") + " ".repeat(boxWidth - 15) + chalk.red("\u2502"));
250
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
251
+ console.log(chalk.red(`\u2502`) + chalk.white(" Or specify a path directly:") + " ".repeat(boxWidth - 32) + chalk.red("\u2502"));
252
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
253
+ console.log(chalk.red(`\u2502`) + chalk.cyan(" autohand --path ~/projects/my-app") + " ".repeat(boxWidth - 40) + chalk.red("\u2502"));
254
+ console.log(chalk.red(`\u2502`) + " ".repeat(boxWidth - 2) + chalk.red("\u2502"));
255
+ console.log(chalk.red(`\u2514${horizontalLine}\u2518`));
256
+ console.log();
257
+ }
258
+
259
+ // src/commands/add-dir.ts
260
+ async function addDir(ctx, args) {
261
+ const dirPath = args.join(" ").trim();
262
+ if (!dirPath) {
263
+ console.log();
264
+ console.log(chalk2.bold.cyan("Workspace Directories"));
265
+ console.log(chalk2.gray("\u2500".repeat(50)));
266
+ console.log();
267
+ console.log(chalk2.bold("Primary Workspace:"));
268
+ console.log(chalk2.cyan(` ${ctx.workspaceRoot}`));
269
+ console.log();
270
+ if (ctx.additionalDirs.length > 0) {
271
+ console.log(chalk2.bold("Additional Directories:"));
272
+ ctx.additionalDirs.forEach((dir, index) => {
273
+ console.log(chalk2.green(` ${index + 1}. ${dir}`));
274
+ });
275
+ } else {
276
+ console.log(chalk2.gray("No additional directories configured."));
277
+ }
278
+ console.log();
279
+ console.log(chalk2.gray("Usage: /add-dir <path> to add a new directory"));
280
+ console.log();
281
+ return null;
282
+ }
283
+ const resolvedPath = path2.resolve(dirPath);
284
+ if (!await fs2.pathExists(resolvedPath)) {
285
+ console.log(chalk2.red(`Error: Directory does not exist: ${dirPath}`));
286
+ return null;
287
+ }
288
+ const stats = await fs2.stat(resolvedPath);
289
+ if (!stats.isDirectory()) {
290
+ console.log(chalk2.red(`Error: Path is not a directory: ${dirPath}`));
291
+ return null;
292
+ }
293
+ const safetyResult = checkWorkspaceSafety(resolvedPath);
294
+ if (!safetyResult.safe) {
295
+ console.log(chalk2.red(`Error: Unsafe directory: ${dirPath}`));
296
+ console.log(chalk2.yellow(` ${safetyResult.reason}`));
297
+ return null;
298
+ }
299
+ if (resolvedPath === ctx.workspaceRoot) {
300
+ console.log(chalk2.yellow(`Directory is already the primary workspace: ${resolvedPath}`));
301
+ return null;
302
+ }
303
+ if (ctx.additionalDirs.includes(resolvedPath)) {
304
+ console.log(chalk2.yellow(`Directory already added: ${resolvedPath}`));
305
+ return null;
306
+ }
307
+ ctx.addAdditionalDir(resolvedPath);
308
+ console.log(chalk2.green(`Added directory: ${resolvedPath}`));
309
+ console.log(chalk2.gray("You can now read, write, and modify files in this directory."));
310
+ return null;
311
+ }
312
+ var metadata = {
313
+ command: "/add-dir",
314
+ description: "add additional directories to workspace scope",
315
+ implemented: true
316
+ };
317
+
318
+ export {
319
+ checkWorkspaceSafety,
320
+ printDangerousWorkspaceWarning,
321
+ addDir,
322
+ metadata
323
+ };
324
+ /**
325
+ * @license
326
+ * Copyright 2025 Autohand AI LLC
327
+ * SPDX-License-Identifier: Apache-2.0
328
+ */
@@ -28,7 +28,7 @@ var HookManager = class {
28
28
  */
29
29
  async installDefaultHooks() {
30
30
  try {
31
- const { DEFAULT_HOOKS, SMART_COMMIT_HOOK } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-Z4KA6U5C.cjs")));
31
+ const { DEFAULT_HOOKS, SMART_COMMIT_HOOK } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-WLMRQUXG.cjs")));
32
32
  this.settings.hooks = [...DEFAULT_HOOKS, SMART_COMMIT_HOOK];
33
33
  if (this.onPersist) {
34
34
  await this.onPersist();
@@ -56,7 +56,7 @@ var HookManager = class {
56
56
  */
57
57
  async mergeDefaultHooks() {
58
58
  try {
59
- const { DEFAULT_HOOKS, SMART_COMMIT_HOOK } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-Z4KA6U5C.cjs")));
59
+ const { DEFAULT_HOOKS, SMART_COMMIT_HOOK } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-WLMRQUXG.cjs")));
60
60
  const allDefaults = [...DEFAULT_HOOKS, SMART_COMMIT_HOOK];
61
61
  const existingHooks = _nullishCoalesce(this.settings.hooks, () => ( []));
62
62
  const existingIds = new Set(existingHooks.map((h) => this.getHookIdentifier(h)));
@@ -74,6 +74,7 @@ var HookManager = class {
74
74
  /**
75
75
  * Ensure all hook scripts exist in ~/.autohand/hooks/
76
76
  * Installs bundled scripts for built-in hooks
77
+ * On Windows, also creates PowerShell (.ps1) versions
77
78
  */
78
79
  async ensureHookScripts() {
79
80
  try {
@@ -81,15 +82,27 @@ var HookManager = class {
81
82
  const path = await Promise.resolve().then(() => _interopRequireWildcard(require("path")));
82
83
  const os = await Promise.resolve().then(() => _interopRequireWildcard(require("os")));
83
84
  const hooksDir = path.join(os.homedir(), ".autohand", "hooks");
85
+ const isWindows = os.platform() === "win32";
84
86
  await fs.ensureDir(hooksDir);
85
- const { HOOK_SCRIPTS } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-Z4KA6U5C.cjs")));
87
+ const { HOOK_SCRIPTS, HOOK_SCRIPTS_WINDOWS } = await Promise.resolve().then(() => _interopRequireWildcard(require("./defaultHooks-WLMRQUXG.cjs")));
86
88
  for (const [scriptName, scriptContent] of Object.entries(HOOK_SCRIPTS)) {
87
89
  const scriptPath = path.join(hooksDir, scriptName);
88
90
  if (!await fs.pathExists(scriptPath)) {
89
91
  await fs.writeFile(scriptPath, scriptContent, { mode: 493 });
90
92
  }
91
93
  }
92
- } catch (e2) {
94
+ if (isWindows && HOOK_SCRIPTS_WINDOWS) {
95
+ for (const [scriptName, scriptContent] of Object.entries(HOOK_SCRIPTS_WINDOWS)) {
96
+ const scriptPath = path.join(hooksDir, scriptName);
97
+ if (!await fs.pathExists(scriptPath)) {
98
+ await fs.writeFile(scriptPath, scriptContent);
99
+ }
100
+ }
101
+ }
102
+ } catch (error) {
103
+ if (process.env.DEBUG || process.env.AUTOHAND_DEBUG) {
104
+ console.error("[hooks] Failed to install hook scripts:", error);
105
+ }
93
106
  }
94
107
  }
95
108
  /**
@@ -214,7 +227,7 @@ var HookManager = class {
214
227
  }
215
228
  try {
216
229
  return new RegExp(hook.matcher).test(value);
217
- } catch (e3) {
230
+ } catch (e2) {
218
231
  return false;
219
232
  }
220
233
  }
@@ -251,6 +264,19 @@ var HookManager = class {
251
264
  if (context.permissionType) env.HOOK_PERMISSION_TYPE = context.permissionType;
252
265
  if (context.notificationType) env.HOOK_NOTIFICATION_TYPE = context.notificationType;
253
266
  if (context.notificationMessage) env.HOOK_NOTIFICATION_MSG = context.notificationMessage;
267
+ if (context.automodeSessionId) env.HOOK_AUTOMODE_SESSION_ID = context.automodeSessionId;
268
+ if (context.automodePrompt) env.HOOK_AUTOMODE_PROMPT = context.automodePrompt;
269
+ if (context.automodeIteration !== void 0) env.HOOK_AUTOMODE_ITERATION = String(context.automodeIteration);
270
+ if (context.automodeMaxIterations !== void 0) env.HOOK_AUTOMODE_MAX_ITERATIONS = String(context.automodeMaxIterations);
271
+ if (context.automodeActions) env.HOOK_AUTOMODE_ACTIONS = JSON.stringify(context.automodeActions);
272
+ if (context.automodeFilesCreated !== void 0) env.HOOK_AUTOMODE_FILES_CREATED = String(context.automodeFilesCreated);
273
+ if (context.automodeFilesModified !== void 0) env.HOOK_AUTOMODE_FILES_MODIFIED = String(context.automodeFilesModified);
274
+ if (context.automodeCancelReason) env.HOOK_AUTOMODE_CANCEL_REASON = context.automodeCancelReason;
275
+ if (context.automodeCheckpointCommit) env.HOOK_AUTOMODE_CHECKPOINT = context.automodeCheckpointCommit;
276
+ if (context.automodeTotalCost !== void 0) env.HOOK_AUTOMODE_COST = String(context.automodeTotalCost);
277
+ if (context.additionalWorkspaces && context.additionalWorkspaces.length > 0) {
278
+ env.HOOK_ADDITIONAL_WORKSPACES = JSON.stringify(context.additionalWorkspaces);
279
+ }
254
280
  return env;
255
281
  }
256
282
  /**
@@ -296,7 +322,20 @@ var HookManager = class {
296
322
  permission_type: context.permissionType,
297
323
  // Notification context
298
324
  notification_type: context.notificationType,
299
- notification_message: context.notificationMessage
325
+ notification_message: context.notificationMessage,
326
+ // Auto-mode context
327
+ automode_session_id: context.automodeSessionId,
328
+ automode_prompt: context.automodePrompt,
329
+ automode_iteration: context.automodeIteration,
330
+ automode_max_iterations: context.automodeMaxIterations,
331
+ automode_actions: context.automodeActions,
332
+ automode_files_created: context.automodeFilesCreated,
333
+ automode_files_modified: context.automodeFilesModified,
334
+ automode_cancel_reason: context.automodeCancelReason,
335
+ automode_checkpoint_commit: context.automodeCheckpointCommit,
336
+ automode_total_cost: context.automodeTotalCost,
337
+ // Multi-directory support
338
+ additional_workspaces: context.additionalWorkspaces
300
339
  });
301
340
  }
302
341
  /**
@@ -309,7 +348,7 @@ var HookManager = class {
309
348
  }
310
349
  try {
311
350
  return JSON.parse(trimmed);
312
- } catch (e4) {
351
+ } catch (e3) {
313
352
  return void 0;
314
353
  }
315
354
  }
@@ -474,7 +513,16 @@ var HookManager = class {
474
513
  "session-start",
475
514
  "session-end",
476
515
  "permission-request",
477
- "notification"
516
+ "notification",
517
+ // Auto-mode events
518
+ "automode:start",
519
+ "automode:iteration",
520
+ "automode:checkpoint",
521
+ "automode:pause",
522
+ "automode:resume",
523
+ "automode:cancel",
524
+ "automode:complete",
525
+ "automode:error"
478
526
  ];
479
527
  const summary = {};
480
528
  for (const event of events) {
@@ -53,6 +53,20 @@ var AUTH_CONFIG = {
53
53
  authTimeout: 5 * 60 * 1e3,
54
54
  sessionExpiryDays: 30
55
55
  };
56
+ var SYNC_CONFIG = {
57
+ /** Default sync interval in ms (5 minutes) */
58
+ defaultInterval: 5 * 60 * 1e3,
59
+ /** API endpoint for sync operations */
60
+ get apiBaseUrl() {
61
+ return `${getAuthBaseUrl()}/api`;
62
+ },
63
+ /** Maximum file size to sync (10MB) */
64
+ maxFileSize: 10 * 1024 * 1024,
65
+ /** Maximum total sync size (100MB) */
66
+ maxTotalSize: 100 * 1024 * 1024,
67
+ /** Request timeout in ms */
68
+ timeout: 3e4
69
+ };
56
70
  var SKILL_LOCATIONS = [
57
71
  { basePath: path.join(os.homedir(), ".codex", "skills"), source: "codex-user", recursive: true },
58
72
  { basePath: path.join(os.homedir(), ".claude", "skills"), source: "claude-user", recursive: false },
@@ -73,6 +87,7 @@ export {
73
87
  AUTOHAND_FILES,
74
88
  PROJECT_DIR_NAME,
75
89
  AUTH_CONFIG,
90
+ SYNC_CONFIG,
76
91
  SKILL_LOCATIONS,
77
92
  getProjectSkillLocations
78
93
  };
@@ -2,7 +2,7 @@ import {
2
2
  addToLocalWhitelist,
3
3
  loadLocalProjectSettings,
4
4
  mergePermissions
5
- } from "./chunk-27ISZOFA.js";
5
+ } from "./chunk-P2Z6GDEN.js";
6
6
 
7
7
  // src/permissions/PermissionManager.ts
8
8
  var DEFAULT_SECURITY_BLACKLIST = [
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
3
+ var _chunkPMMSDR44cjs = require('./chunk-PMMSDR44.cjs');
4
4
 
5
5
  // src/skills/CommunitySkillsCache.ts
6
6
  var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
@@ -9,7 +9,7 @@ var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
9
9
  var DEFAULT_MAX_SKILLS_CACHE = 50;
10
10
  var CommunitySkillsCache = class {
11
11
  constructor(config = {}) {
12
- this.cacheDir = config.cacheDir || _path2.default.join(_chunkXTHHDIBGcjs.AUTOHAND_HOME, "community-skills", "cache");
12
+ this.cacheDir = config.cacheDir || _path2.default.join(_chunkPMMSDR44cjs.AUTOHAND_HOME, "community-skills", "cache");
13
13
  this.ttlMs = _nullishCoalesce(config.ttlMs, () => ( DEFAULT_TTL_MS));
14
14
  this.maxSkillsCache = _nullishCoalesce(config.maxSkillsCache, () => ( DEFAULT_MAX_SKILLS_CACHE));
15
15
  }
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkREPKBECDcjs = require('./chunk-REPKBECD.cjs');
3
+ var _chunkJHFH3N4Ucjs = require('./chunk-JHFH3N4U.cjs');
4
4
 
5
5
 
6
- var _chunkQMVTT55Ycjs = require('./chunk-QMVTT55Y.cjs');
6
+ var _chunkWQSWU2QAcjs = require('./chunk-WQSWU2QA.cjs');
7
7
 
8
8
 
9
9
  var _chunk3HPUOQJNcjs = require('./chunk-3HPUOQJN.cjs');
@@ -33,7 +33,7 @@ async function logout(ctx) {
33
33
  console.log(_chalk2.default.gray("Logout cancelled."));
34
34
  return null;
35
35
  }
36
- const authClient = _chunkREPKBECDcjs.getAuthClient.call(void 0, );
36
+ const authClient = _chunkJHFH3N4Ucjs.getAuthClient.call(void 0, );
37
37
  try {
38
38
  await authClient.logout(config.auth.token);
39
39
  } catch (e) {
@@ -42,7 +42,7 @@ async function logout(ctx) {
42
42
  ...config,
43
43
  auth: void 0
44
44
  };
45
- await _chunkQMVTT55Ycjs.saveConfig.call(void 0, updatedConfig);
45
+ await _chunkWQSWU2QAcjs.saveConfig.call(void 0, updatedConfig);
46
46
  console.log();
47
47
  console.log(_chalk2.default.green("Successfully logged out."));
48
48
  console.log(_chalk2.default.gray("Your local session has been cleared."));
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  package_default
3
- } from "./chunk-5MCDN53U.js";
3
+ } from "./chunk-Q3WCMY3Z.js";
4
4
  import {
5
5
  AUTOHAND_PATHS
6
- } from "./chunk-FUEL6BK7.js";
6
+ } from "./chunk-EKY5PKQI.js";
7
7
 
8
8
  // src/commands/share.ts
9
9
  import chalk from "chalk";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AUTOHAND_FILES
3
- } from "./chunk-FUEL6BK7.js";
3
+ } from "./chunk-EKY5PKQI.js";
4
4
 
5
5
  // src/ui/theme/Theme.ts
6
6
  var Theme = class {
@@ -3,7 +3,7 @@
3
3
  var _chunk3HPUOQJNcjs = require('./chunk-3HPUOQJN.cjs');
4
4
 
5
5
 
6
- var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
6
+ var _chunkPMMSDR44cjs = require('./chunk-PMMSDR44.cjs');
7
7
 
8
8
  // src/commands/feedback.ts
9
9
  var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
@@ -40,7 +40,7 @@ async function feedback(_ctx) {
40
40
  runtimeError: runtimeError ? formatError(runtimeError) : null
41
41
  };
42
42
  try {
43
- const feedbackPath = _chunkXTHHDIBGcjs.AUTOHAND_FILES.feedbackLog;
43
+ const feedbackPath = _chunkPMMSDR44cjs.AUTOHAND_FILES.feedbackLog;
44
44
  await _fsextra2.default.ensureFile(feedbackPath);
45
45
  await _fsextra2.default.appendFile(feedbackPath, JSON.stringify(payload) + "\n", "utf8");
46
46
  console.log(_chalk2.default.green("Feedback recorded."));
@@ -1,12 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
3
+ var _chunkPMMSDR44cjs = require('./chunk-PMMSDR44.cjs');
4
4
 
5
5
  // src/auth/AuthClient.ts
6
6
  var DEFAULT_TIMEOUT = 1e4;
7
7
  var AuthClient = class {
8
8
  constructor(config = {}) {
9
- this.baseUrl = config.baseUrl || _chunkXTHHDIBGcjs.AUTH_CONFIG.apiBaseUrl;
9
+ this.baseUrl = config.baseUrl || _chunkPMMSDR44cjs.AUTH_CONFIG.apiBaseUrl;
10
10
  this.timeout = config.timeout || DEFAULT_TIMEOUT;
11
11
  }
12
12
  /**
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AUTOHAND_PATHS,
3
3
  PROJECT_DIR_NAME
4
- } from "./chunk-FUEL6BK7.js";
4
+ } from "./chunk-EKY5PKQI.js";
5
5
 
6
6
  // src/memory/MemoryManager.ts
7
7
  import fs from "fs-extra";