autohand-cli 0.7.4 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,9 +2,10 @@
2
2
  "use strict"; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await 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; }
3
3
 
4
4
  var _chunkOKMYLMCRcjs = require('./chunk-OKMYLMCR.cjs');
5
+ require('./chunk-3CO5R6M2.cjs');
5
6
 
6
7
 
7
- var _chunkUPR5PKX4cjs = require('./chunk-UPR5PKX4.cjs');
8
+ var _chunk67NJKV5Acjs = require('./chunk-67NJKV5A.cjs');
8
9
 
9
10
 
10
11
  var _chunkURY4AS4Lcjs = require('./chunk-URY4AS4L.cjs');
@@ -28,7 +29,9 @@ var _chunkHYTYXN2Gcjs = require('./chunk-HYTYXN2G.cjs');
28
29
 
29
30
 
30
31
  var _chunkOTS4YFSZcjs = require('./chunk-OTS4YFSZ.cjs');
31
- require('./chunk-3CO5R6M2.cjs');
32
+
33
+
34
+ var _chunkK6NBYSMEcjs = require('./chunk-K6NBYSME.cjs');
32
35
 
33
36
 
34
37
  var _chunkM7RVTUWEcjs = require('./chunk-M7RVTUWE.cjs');
@@ -40,8 +43,10 @@ var _chunkJBKP2CLAcjs = require('./chunk-JBKP2CLA.cjs');
40
43
  var _chunkC3IFF3EHcjs = require('./chunk-C3IFF3EH.cjs');
41
44
 
42
45
 
46
+ var _chunkKJ67C72Ccjs = require('./chunk-KJ67C72C.cjs');
43
47
 
44
- var _chunkXJZYEURAcjs = require('./chunk-XJZYEURA.cjs');
48
+
49
+ var _chunkJYTXG6OVcjs = require('./chunk-JYTXG6OV.cjs');
45
50
 
46
51
 
47
52
  var _chunk2E2COWKBcjs = require('./chunk-2E2COWKB.cjs');
@@ -95,26 +100,26 @@ var _chunkKNLBEUAVcjs = require('./chunk-KNLBEUAV.cjs');
95
100
  var _chunkZ4J4W6YQcjs = require('./chunk-Z4J4W6YQ.cjs');
96
101
 
97
102
 
103
+ var _chunkXT4OSHSBcjs = require('./chunk-XT4OSHSB.cjs');
98
104
 
99
105
 
106
+ var _chunkV5MTBGM4cjs = require('./chunk-V5MTBGM4.cjs');
100
107
 
101
- var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
102
108
 
109
+ var _chunkWBDPILKIcjs = require('./chunk-WBDPILKI.cjs');
103
110
 
104
- var _chunkXT4OSHSBcjs = require('./chunk-XT4OSHSB.cjs');
105
111
 
106
112
 
107
- var _chunkV5MTBGM4cjs = require('./chunk-V5MTBGM4.cjs');
113
+ var _chunkBEIG7V7Qcjs = require('./chunk-BEIG7V7Q.cjs');
108
114
 
109
115
 
110
- var _chunkWBDPILKIcjs = require('./chunk-WBDPILKI.cjs');
116
+ var _chunk2W3QTBNGcjs = require('./chunk-2W3QTBNG.cjs');
111
117
 
112
118
 
113
119
 
114
- var _chunkBEIG7V7Qcjs = require('./chunk-BEIG7V7Q.cjs');
115
120
 
116
121
 
117
- var _chunkRYY5I7QNcjs = require('./chunk-RYY5I7QN.cjs');
122
+ var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
118
123
 
119
124
 
120
125
  var _chunkVMMGT42Ecjs = require('./chunk-VMMGT42E.cjs');
@@ -123,7 +128,6 @@ var _chunkVMMGT42Ecjs = require('./chunk-VMMGT42E.cjs');
123
128
  require('dotenv/config');
124
129
  var _commander = require('commander');
125
130
  var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
126
- var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
127
131
  var _child_process = require('child_process');
128
132
 
129
133
  // src/startup/checks.ts
@@ -228,20 +232,66 @@ async function checkWorkspaceWritable(workspaceRoot) {
228
232
  };
229
233
  }
230
234
  }
231
- function checkGitRepo(workspaceRoot) {
235
+ function isEmptyDirectory(dir) {
236
+ try {
237
+ const entries = _fsextra2.default.readdirSync(dir);
238
+ const significantEntries = entries.filter((e) => !e.startsWith(".") || e === ".git");
239
+ return significantEntries.length === 0;
240
+ } catch (e3) {
241
+ return false;
242
+ }
243
+ }
244
+ function getGitBranch(workspaceRoot) {
232
245
  try {
233
246
  const result = _child_process.spawnSync.call(void 0, "git", ["rev-parse", "--abbrev-ref", "HEAD"], {
234
247
  cwd: workspaceRoot,
235
248
  encoding: "utf8",
236
249
  timeout: 5e3
237
250
  });
238
- if (result.status === 0) {
239
- return {
240
- isGitRepo: true,
241
- branch: result.stdout.trim()
242
- };
251
+ if (result.status === 0 && result.stdout.trim()) {
252
+ return result.stdout.trim();
253
+ }
254
+ } catch (e4) {
255
+ }
256
+ try {
257
+ const result = _child_process.spawnSync.call(void 0, "git", ["symbolic-ref", "--short", "HEAD"], {
258
+ cwd: workspaceRoot,
259
+ encoding: "utf8",
260
+ timeout: 5e3
261
+ });
262
+ if (result.status === 0 && result.stdout.trim()) {
263
+ return result.stdout.trim();
264
+ }
265
+ } catch (e5) {
266
+ }
267
+ return void 0;
268
+ }
269
+ function checkGitRepo(workspaceRoot) {
270
+ const gitDirExists = _fsextra2.default.existsSync(`${workspaceRoot}/.git`);
271
+ if (gitDirExists) {
272
+ const branch = getGitBranch(workspaceRoot);
273
+ return {
274
+ isGitRepo: true,
275
+ branch
276
+ };
277
+ }
278
+ if (isEmptyDirectory(workspaceRoot)) {
279
+ try {
280
+ const initResult = _child_process.spawnSync.call(void 0, "git", ["init"], {
281
+ cwd: workspaceRoot,
282
+ encoding: "utf8",
283
+ timeout: 5e3
284
+ });
285
+ if (initResult.status === 0) {
286
+ const branch = getGitBranch(workspaceRoot) || "main";
287
+ return {
288
+ isGitRepo: true,
289
+ branch,
290
+ initialized: true
291
+ };
292
+ }
293
+ } catch (e6) {
243
294
  }
244
- } catch (e3) {
245
295
  }
246
296
  return { isGitRepo: false };
247
297
  }
@@ -285,6 +335,7 @@ async function runStartupChecks(workspaceRoot) {
285
335
  writable: workspaceCheck.writable,
286
336
  isGitRepo: gitCheck.isGitRepo,
287
337
  branch: gitCheck.branch,
338
+ initialized: gitCheck.initialized,
288
339
  error: workspaceCheck.error
289
340
  },
290
341
  allRequiredMet,
@@ -294,6 +345,10 @@ async function runStartupChecks(workspaceRoot) {
294
345
  function printStartupCheckResults(results, verbose = false) {
295
346
  const missingRequired = results.tools.filter((t) => t.required && !t.installed);
296
347
  const missingOptional = results.tools.filter((t) => !t.required && !t.installed);
348
+ if (results.workspace.initialized) {
349
+ console.log(_chalk2.default.green("\u2713 Initialized git repository"));
350
+ console.log();
351
+ }
297
352
  if (missingRequired.length === 0 && !verbose) {
298
353
  return;
299
354
  }
@@ -389,7 +444,7 @@ function normalizePath(inputPath) {
389
444
  let normalized = path17.default.resolve(inputPath);
390
445
  try {
391
446
  normalized = _fsextra2.default.realpathSync(normalized);
392
- } catch (e4) {
447
+ } catch (e7) {
393
448
  }
394
449
  if (normalized.length > 1 && normalized.endsWith(path17.default.sep)) {
395
450
  normalized = normalized.slice(0, -1);
@@ -611,7 +666,7 @@ async function readCache() {
611
666
  const data = await _fsextra2.default.readJson(CACHE_FILE);
612
667
  return data;
613
668
  }
614
- } catch (e5) {
669
+ } catch (e8) {
615
670
  }
616
671
  return null;
617
672
  }
@@ -619,7 +674,7 @@ async function writeCache(cache) {
619
674
  try {
620
675
  await _fsextra2.default.ensureDir(path17.default.dirname(CACHE_FILE));
621
676
  await _fsextra2.default.writeJson(CACHE_FILE, cache, { spaces: 2 });
622
- } catch (e6) {
677
+ } catch (e9) {
623
678
  }
624
679
  }
625
680
  function isCacheValid(cache, intervalHours) {
@@ -628,7 +683,7 @@ function isCacheValid(cache, intervalHours) {
628
683
  const now = /* @__PURE__ */ new Date();
629
684
  const hoursSinceCheck = (now.getTime() - lastCheck.getTime()) / (1e3 * 60 * 60);
630
685
  return hoursSinceCheck < intervalHours;
631
- } catch (e7) {
686
+ } catch (e10) {
632
687
  return false;
633
688
  }
634
689
  }
@@ -654,7 +709,7 @@ async function fetchLatestRelease() {
654
709
  url: data.html_url || `https://github.com/autohandai/code-cli/releases/tag/${data.tag_name}`
655
710
  };
656
711
  }
657
- } catch (e8) {
712
+ } catch (e11) {
658
713
  }
659
714
  return null;
660
715
  }
@@ -780,7 +835,7 @@ var GitIgnoreParser = class {
780
835
  let content = "";
781
836
  try {
782
837
  content = _fsextra2.default.readFileSync(patternsFilePath, "utf8");
783
- } catch (e9) {
838
+ } catch (e12) {
784
839
  return [];
785
840
  }
786
841
  const isExcludeFile = patternsFilePath.endsWith(path17.default.join(".git", "info", "exclude"));
@@ -1188,7 +1243,7 @@ var FileActionManager = class {
1188
1243
  file: normalizedRel || path17.default.basename(current),
1189
1244
  snippet
1190
1245
  });
1191
- } catch (e10) {
1246
+ } catch (e13) {
1192
1247
  continue;
1193
1248
  }
1194
1249
  }
@@ -1213,19 +1268,19 @@ var FileActionManager = class {
1213
1268
  let realPath;
1214
1269
  try {
1215
1270
  realPath = _fsextra2.default.realpathSync(resolved);
1216
- } catch (e11) {
1271
+ } catch (e14) {
1217
1272
  const parentDir = path17.default.dirname(resolved);
1218
1273
  try {
1219
1274
  const realParent = _fsextra2.default.realpathSync(parentDir);
1220
1275
  realPath = path17.default.join(realParent, path17.default.basename(resolved));
1221
- } catch (e12) {
1276
+ } catch (e15) {
1222
1277
  realPath = resolved;
1223
1278
  }
1224
1279
  }
1225
1280
  let realWorkspaceRoot;
1226
1281
  try {
1227
1282
  realWorkspaceRoot = _fsextra2.default.realpathSync(this.workspaceRoot);
1228
- } catch (e13) {
1283
+ } catch (e16) {
1229
1284
  realWorkspaceRoot = this.workspaceRoot;
1230
1285
  }
1231
1286
  const rootWithSep = realWorkspaceRoot.endsWith(path17.default.sep) ? realWorkspaceRoot : `${realWorkspaceRoot}${path17.default.sep}`;
@@ -1270,7 +1325,7 @@ var FileActionManager = class {
1270
1325
  }
1271
1326
  }
1272
1327
  }
1273
- } catch (e14) {
1328
+ } catch (e17) {
1274
1329
  continue;
1275
1330
  }
1276
1331
  }
@@ -1373,7 +1428,7 @@ var OllamaProvider = class {
1373
1428
  try {
1374
1429
  const response = await fetch(`${this.baseUrl}/api/tags`);
1375
1430
  return response.ok;
1376
- } catch (e15) {
1431
+ } catch (e18) {
1377
1432
  return false;
1378
1433
  }
1379
1434
  }
@@ -1431,7 +1486,7 @@ var OllamaProvider = class {
1431
1486
  delete body.tools;
1432
1487
  return this.complete(request);
1433
1488
  }
1434
- } catch (e16) {
1489
+ } catch (e19) {
1435
1490
  }
1436
1491
  throw new Error(`Ollama API error: ${response.status} ${response.statusText}${errorDetail}`);
1437
1492
  }
@@ -1488,7 +1543,7 @@ var OllamaProvider = class {
1488
1543
  const data = JSON.parse(line);
1489
1544
  fullContent += data.message.content;
1490
1545
  lastData = data;
1491
- } catch (e17) {
1546
+ } catch (e20) {
1492
1547
  }
1493
1548
  }
1494
1549
  }
@@ -1534,7 +1589,7 @@ var OpenAIProvider = class {
1534
1589
  }
1535
1590
  });
1536
1591
  return response.ok;
1537
- } catch (e18) {
1592
+ } catch (e21) {
1538
1593
  return false;
1539
1594
  }
1540
1595
  }
@@ -1638,7 +1693,7 @@ var LlamaCppProvider = class {
1638
1693
  }
1639
1694
  const data = await response.json();
1640
1695
  return _nullishCoalesce(_optionalChain([data, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.map, 'call', _9 => _9((m) => m.id)]), () => ( [this.model]));
1641
- } catch (e19) {
1696
+ } catch (e22) {
1642
1697
  return this.model ? [this.model] : [];
1643
1698
  }
1644
1699
  }
@@ -1646,7 +1701,7 @@ var LlamaCppProvider = class {
1646
1701
  try {
1647
1702
  const response = await fetch(`${this.baseUrl}/health`);
1648
1703
  return response.ok;
1649
- } catch (e20) {
1704
+ } catch (e23) {
1650
1705
  return false;
1651
1706
  }
1652
1707
  }
@@ -1778,6 +1833,26 @@ var OpenRouterClient = class {
1778
1833
  payload.tool_choice = request.toolChoice;
1779
1834
  }
1780
1835
  }
1836
+ const model = (_nullishCoalesce(request.model, () => ( this.defaultModel))).toLowerCase();
1837
+ if (request.thinkingLevel && request.thinkingLevel !== "normal") {
1838
+ if (model.includes("o1") || model.includes("o3")) {
1839
+ if (request.thinkingLevel === "extended") {
1840
+ payload.reasoning_effort = "high";
1841
+ } else if (request.thinkingLevel === "none") {
1842
+ payload.reasoning_effort = "low";
1843
+ }
1844
+ }
1845
+ if (model.includes("claude") && request.thinkingLevel === "extended") {
1846
+ payload.provider = {
1847
+ anthropic: {
1848
+ thinking: {
1849
+ type: "enabled",
1850
+ budget_tokens: 1e4
1851
+ }
1852
+ }
1853
+ };
1854
+ }
1855
+ }
1781
1856
  const headers = {
1782
1857
  "Content-Type": "application/json",
1783
1858
  "HTTP-Referer": "https://github.com/autohandai/code-cli",
@@ -1904,10 +1979,10 @@ var OpenRouterClient = class {
1904
1979
  if (typeof errorDetail === "object") {
1905
1980
  errorDetail = JSON.stringify(errorDetail);
1906
1981
  }
1907
- } catch (e21) {
1982
+ } catch (e24) {
1908
1983
  try {
1909
1984
  errorDetail = await response.text();
1910
- } catch (e22) {
1985
+ } catch (e25) {
1911
1986
  }
1912
1987
  }
1913
1988
  const friendlyMessage = FRIENDLY_ERRORS[status];
@@ -2020,7 +2095,7 @@ var MLXProvider = class {
2020
2095
  }
2021
2096
  const data = await response.json();
2022
2097
  return _nullishCoalesce(_optionalChain([data, 'access', _42 => _42.data, 'optionalAccess', _43 => _43.map, 'call', _44 => _44((m) => m.id)]), () => ( (this.model ? [this.model] : [])));
2023
- } catch (e23) {
2098
+ } catch (e26) {
2024
2099
  return this.model ? [this.model] : [];
2025
2100
  }
2026
2101
  }
@@ -2031,7 +2106,7 @@ var MLXProvider = class {
2031
2106
  try {
2032
2107
  const response = await fetch(`${this.baseUrl}/v1/models`);
2033
2108
  return response.ok;
2034
- } catch (e24) {
2109
+ } catch (e27) {
2035
2110
  return false;
2036
2111
  }
2037
2112
  }
@@ -2203,12 +2278,11 @@ var ProviderFactory = class {
2203
2278
  var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
2204
2279
 
2205
2280
  var _ora = require('ora'); var _ora2 = _interopRequireDefault(_ora);
2206
-
2207
- var _readline = require('readline'); var _readline2 = _interopRequireDefault(_readline);
2281
+ var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
2208
2282
 
2209
2283
  // src/ui/inputPrompt.ts
2210
2284
 
2211
-
2285
+ var _readline = require('readline'); var _readline2 = _interopRequireDefault(_readline);
2212
2286
  var _fs = require('fs');
2213
2287
 
2214
2288
 
@@ -2296,7 +2370,7 @@ var MentionPreview = class {
2296
2370
  this.disposed = false;
2297
2371
  this.lastSuggestions = [];
2298
2372
  const input = rl.input;
2299
- _readline2.default.emitKeypressEvents(input, rl);
2373
+ safeEmitKeypressEvents(input);
2300
2374
  this.statusLine = statusLine ? _chalk2.default.gray(statusLine) : void 0;
2301
2375
  this.keypressHandler = this.handleKeypress.bind(this);
2302
2376
  input.prependListener("keypress", this.keypressHandler);
@@ -2630,7 +2704,7 @@ function parseBase64DataUrl(dataUrl) {
2630
2704
  try {
2631
2705
  const data = Buffer.from(base64Data, "base64");
2632
2706
  return { mimeType, data };
2633
- } catch (e25) {
2707
+ } catch (e28) {
2634
2708
  return void 0;
2635
2709
  }
2636
2710
  }
@@ -2664,6 +2738,13 @@ function drawInputBox(prompt, width) {
2664
2738
  // src/ui/inputPrompt.ts
2665
2739
  var NEWLINE_MARKER = " \u21B5 ";
2666
2740
  var MAX_NEWLINES = 2;
2741
+ var instrumentedStreams = /* @__PURE__ */ new WeakSet();
2742
+ function safeEmitKeypressEvents(stream) {
2743
+ if (!instrumentedStreams.has(stream)) {
2744
+ _readline2.default.emitKeypressEvents(stream);
2745
+ instrumentedStreams.add(stream);
2746
+ }
2747
+ }
2667
2748
  function countNewlineMarkers(text) {
2668
2749
  return (text.match(new RegExp(NEWLINE_MARKER, "g")) || []).length;
2669
2750
  }
@@ -2677,6 +2758,7 @@ async function readInstruction(files, slashCommands, statusLine, io = {}, onImag
2677
2758
  }, 1e4);
2678
2759
  try {
2679
2760
  while (true) {
2761
+ await new Promise((resolve) => process.nextTick(resolve));
2680
2762
  const result = await promptOnce({
2681
2763
  files,
2682
2764
  slashCommands,
@@ -2695,8 +2777,11 @@ async function readInstruction(files, slashCommands, statusLine, io = {}, onImag
2695
2777
  }
2696
2778
  }
2697
2779
  function createReadline(stdInput, stdOutput) {
2698
- if (stdInput.isPaused && stdInput.isPaused()) {
2780
+ stdOutput.write("\r");
2781
+ safeEmitKeypressEvents(stdInput);
2782
+ try {
2699
2783
  stdInput.resume();
2784
+ } catch (e29) {
2700
2785
  }
2701
2786
  const rl = _readline2.default.createInterface({
2702
2787
  input: stdInput,
@@ -2759,7 +2844,7 @@ async function promptOnce(options) {
2759
2844
  \u{1F4F7} Loaded image: ${filePath} -> [Image #${id}]
2760
2845
  `));
2761
2846
  }
2762
- } catch (e26) {
2847
+ } catch (e30) {
2763
2848
  }
2764
2849
  }
2765
2850
  }
@@ -2799,7 +2884,7 @@ async function promptOnce(options) {
2799
2884
  \u{1F4F7} Loaded image: ${filePath} -> [Image #${id}]
2800
2885
  `));
2801
2886
  }
2802
- } catch (e27) {
2887
+ } catch (e31) {
2803
2888
  }
2804
2889
  }
2805
2890
  }
@@ -2819,7 +2904,7 @@ async function promptOnce(options) {
2819
2904
  \u{1F4F7} Loaded image: ${filePath} -> [Image #${id}]
2820
2905
  `));
2821
2906
  }
2822
- } catch (e28) {
2907
+ } catch (e32) {
2823
2908
  }
2824
2909
  }
2825
2910
  }
@@ -2893,6 +2978,9 @@ ${_chalk2.default.gray("Press Ctrl+C again to exit.")}
2893
2978
  input.on("keypress", handleKeypress);
2894
2979
  rl.setPrompt(`${_chalk2.default.gray("\u203A")} `);
2895
2980
  rl.prompt(true);
2981
+ process.nextTick(() => {
2982
+ stdOutput.write(`\r${_chalk2.default.gray("\u203A")} `);
2983
+ });
2896
2984
  rl.on("line", (value) => {
2897
2985
  let finalValue = convertNewlineMarkersToNewlines(value).trim();
2898
2986
  finalValue = processImagesInText(finalValue);
@@ -3942,7 +4030,7 @@ var SLASH_COMMANDS = [
3942
4030
  _chunkV5MTBGM4cjs.metadata,
3943
4031
  _chunkBEIG7V7Qcjs.metadata,
3944
4032
  _chunkBEIG7V7Qcjs.aliasMetadata,
3945
- _chunkRYY5I7QNcjs.metadata,
4033
+ _chunk2W3QTBNGcjs.metadata,
3946
4034
  _chunkVMMGT42Ecjs.metadata,
3947
4035
  _chunkMFK6HE47cjs.metadata,
3948
4036
  _chunk3ZUWWML7cjs.metadata,
@@ -3955,7 +4043,7 @@ var SLASH_COMMANDS = [
3955
4043
  _chunkM7RVTUWEcjs.metadata,
3956
4044
  _chunkJBKP2CLAcjs.metadata,
3957
4045
  _chunkC3IFF3EHcjs.metadata,
3958
- _chunkXJZYEURAcjs.metadata,
4046
+ _chunkKJ67C72Ccjs.metadata,
3959
4047
  _chunk2E2COWKBcjs.metadata,
3960
4048
  _chunk536VWSZKcjs.metadata,
3961
4049
  _chunkB5N5UAMOcjs.metadata,
@@ -3964,7 +4052,8 @@ var SLASH_COMMANDS = [
3964
4052
  _chunkCT2VTDPQcjs.installMetadata,
3965
4053
  _chunkLUKMRIKJcjs.metadata,
3966
4054
  _chunkHYTYXN2Gcjs.metadata,
3967
- _chunkOTS4YFSZcjs.metadata
4055
+ _chunkOTS4YFSZcjs.metadata,
4056
+ _chunkK6NBYSMEcjs.metadata
3968
4057
  ];
3969
4058
 
3970
4059
  // src/core/conversationManager.ts
@@ -5743,7 +5832,7 @@ async function listDirectoryTree(root, options = {}) {
5743
5832
  if (stats.isDirectory() && currentDepth < depth) {
5744
5833
  await walk(full, `${prefix} `, currentDepth + 1);
5745
5834
  }
5746
- } catch (e29) {
5835
+ } catch (e33) {
5747
5836
  continue;
5748
5837
  }
5749
5838
  if (result.length >= maxEntries) {
@@ -5969,7 +6058,7 @@ var WorktreeManager = class {
5969
6058
  try {
5970
6059
  await this.remove(wt.path, { force: true, deleteBranch: options.removeMerged });
5971
6060
  removed.push(wt.path);
5972
- } catch (e30) {
6061
+ } catch (e34) {
5973
6062
  }
5974
6063
  }
5975
6064
  _child_process.spawnSync.call(void 0, "git", ["worktree", "prune"], { cwd: this.repoRoot });
@@ -6046,7 +6135,7 @@ var WorktreeManager = class {
6046
6135
  } catch (error) {
6047
6136
  try {
6048
6137
  await this.runInWorktree(wt.path, `git ${strategy} --abort`);
6049
- } catch (e31) {
6138
+ } catch (e35) {
6050
6139
  }
6051
6140
  failed.push(`${wt.path}: ${error.message}`);
6052
6141
  }
@@ -6399,7 +6488,7 @@ async function fetchUrl(url, options = {}) {
6399
6488
  try {
6400
6489
  const json = JSON.parse(content);
6401
6490
  return JSON.stringify(json, null, 2).slice(0, maxLength);
6402
- } catch (e32) {
6491
+ } catch (e36) {
6403
6492
  }
6404
6493
  }
6405
6494
  const text = htmlToText(content);
@@ -6690,10 +6779,10 @@ var ToolsRegistry = class {
6690
6779
  if (this.isValidMetaTool(data)) {
6691
6780
  this.metaToolCache.set(data.name, data);
6692
6781
  }
6693
- } catch (e33) {
6782
+ } catch (e37) {
6694
6783
  }
6695
6784
  }
6696
- } catch (e34) {
6785
+ } catch (e38) {
6697
6786
  }
6698
6787
  }
6699
6788
  isValidMetaTool(candidate) {
@@ -7808,7 +7897,7 @@ ${result.removed.map((p) => ` - ${p}`).join("\n")}`;
7808
7897
  const content = await this.files.readFile(todoPath);
7809
7898
  const parsed = JSON.parse(content);
7810
7899
  existingTodos = Array.isArray(parsed) ? parsed : [];
7811
- } catch (e35) {
7900
+ } catch (e39) {
7812
7901
  }
7813
7902
  const todoMap = new Map(existingTodos.map((t) => [t.id, t]));
7814
7903
  for (const task of action.tasks) {
@@ -8534,7 +8623,7 @@ var SlashCommandHandler = class {
8534
8623
  return feedback(this.ctx);
8535
8624
  }
8536
8625
  case "/resume": {
8537
- const { resume } = await Promise.resolve().then(() => _interopRequireWildcard(require("./resume-OYZMJRNO.cjs")));
8626
+ const { resume } = await Promise.resolve().then(() => _interopRequireWildcard(require("./resume-ANISKRWL.cjs")));
8538
8627
  return resume({ sessionManager: this.ctx.sessionManager, args });
8539
8628
  }
8540
8629
  case "/sessions": {
@@ -8592,8 +8681,21 @@ var SlashCommandHandler = class {
8592
8681
  });
8593
8682
  return null;
8594
8683
  }
8684
+ case "/share": {
8685
+ const { execute } = await Promise.resolve().then(() => _interopRequireWildcard(require("./share-4ACH6626.cjs")));
8686
+ await execute(args.join(" "), {
8687
+ sessionManager: this.ctx.sessionManager,
8688
+ currentSession: this.ctx.currentSession,
8689
+ model: this.ctx.model,
8690
+ provider: this.ctx.provider,
8691
+ config: this.ctx.config,
8692
+ getTotalTokensUsed: this.ctx.getTotalTokensUsed,
8693
+ workspaceRoot: this.ctx.workspaceRoot
8694
+ });
8695
+ return null;
8696
+ }
8595
8697
  case "/status": {
8596
- const { status } = await Promise.resolve().then(() => _interopRequireWildcard(require("./status-U5NH6SYY.cjs")));
8698
+ const { status } = await Promise.resolve().then(() => _interopRequireWildcard(require("./status-4U5CPUVT.cjs")));
8597
8699
  return status(this.ctx);
8598
8700
  }
8599
8701
  case "/login": {
@@ -8885,189 +8987,1169 @@ var ProjectManager = class {
8885
8987
  }
8886
8988
  };
8887
8989
 
8888
- // src/core/agents/AgentDelegator.ts
8889
-
8990
+ // src/onboarding/projectAnalyzer.ts
8890
8991
 
8891
- // src/core/agents/SubAgent.ts
8892
8992
 
8893
- var DELEGATION_TOOL_DEFINITIONS = [
8894
- {
8895
- name: "delegate_task",
8896
- description: "Delegate a task to another specialized sub-agent",
8897
- parameters: {
8898
- type: "object",
8899
- properties: {
8900
- agent_name: { type: "string", description: "Name of the agent to delegate to" },
8901
- task: { type: "string", description: "Task description for the sub-agent" }
8902
- },
8903
- required: ["agent_name", "task"]
8904
- }
8905
- },
8906
- {
8907
- name: "delegate_parallel",
8908
- description: "Run multiple sub-agents in parallel (max 5)",
8909
- parameters: {
8910
- type: "object",
8911
- properties: {
8912
- tasks: { type: "array", description: "Array of {agent_name, task} objects" }
8913
- },
8914
- required: ["tasks"]
8915
- }
8916
- }
8917
- ];
8918
- var SubAgent = class {
8919
- constructor(config, llm, actionExecutor, options) {
8920
- this.config = config;
8921
- this.llm = llm;
8922
- this.actionExecutor = actionExecutor;
8923
- this.delegator = null;
8924
- this.name = config.name;
8925
- this.options = options;
8926
- const canDelegate = options.depth < options.maxDepth;
8927
- const allowedTools = new Set(config.tools);
8928
- let definitions = DEFAULT_TOOL_DEFINITIONS.filter((def) => allowedTools.has(def.name));
8929
- if (canDelegate) {
8930
- definitions = [...definitions, ...DELEGATION_TOOL_DEFINITIONS];
8931
- }
8932
- const toolFilter = new ToolFilter(options.clientContext);
8933
- definitions = toolFilter.filterDefinitions(definitions);
8934
- if (canDelegate) {
8935
- this.delegator = new AgentDelegator(llm, actionExecutor, {
8936
- clientContext: options.clientContext,
8937
- currentDepth: options.depth,
8938
- maxDepth: options.maxDepth
8939
- });
8940
- }
8941
- this.toolManager = new ToolManager({
8942
- executor: async (action, context) => {
8943
- if (action.type === "delegate_task" && this.delegator) {
8944
- return this.delegator.delegateTask(
8945
- action.agent_name,
8946
- action.task
8947
- );
8948
- }
8949
- if (action.type === "delegate_parallel" && this.delegator) {
8950
- return this.delegator.delegateParallel(action.tasks);
8951
- }
8952
- return this.actionExecutor.execute(action, context);
8953
- },
8954
- confirmApproval: async () => true,
8955
- // Sub-agents auto-approve (inherit from main agent in future)
8956
- definitions,
8957
- clientContext: options.clientContext
8958
- });
8959
- const enhancedSystemPrompt = this.buildSystemPrompt(config.systemPrompt, definitions);
8960
- this.conversation = new ConversationManager();
8961
- this.conversation.reset(enhancedSystemPrompt);
8993
+ var ProjectAnalyzer = class {
8994
+ constructor(workspaceRoot) {
8995
+ this.workspaceRoot = workspaceRoot;
8962
8996
  }
8963
8997
  /**
8964
- * Build system prompt with tool signatures for the LLM
8998
+ * Analyze the workspace and return project information
8965
8999
  */
8966
- buildSystemPrompt(basePrompt, tools) {
8967
- const toolSignatures = tools.map((def) => this.formatToolSignature(def)).join("\n");
8968
- return [
8969
- basePrompt,
8970
- "",
8971
- "## Available Tools",
8972
- "You have access to the following tools. Use them when needed:",
8973
- "",
8974
- toolSignatures,
8975
- "",
8976
- "## Response Format",
8977
- "Always respond with structured JSON:",
8978
- "```json",
8979
- "{",
8980
- ' "thought": "Your reasoning about what to do next",',
8981
- ' "toolCalls": [{"tool": "tool_name", "args": {...}}],',
8982
- ' "finalResponse": "Your final answer when done (omit toolCalls if providing this)"',
8983
- "}",
8984
- "```",
8985
- "",
8986
- `Depth: ${this.options.depth}/${this.options.maxDepth} ${this.delegator ? "(can delegate further)" : "(max depth reached)"}`
8987
- ].join("\n");
9000
+ async analyze() {
9001
+ const info = {};
9002
+ await this.analyzeNodeProject(info);
9003
+ await this.analyzeRustProject(info);
9004
+ await this.analyzeGoProject(info);
9005
+ await this.analyzePythonProject(info);
9006
+ return info;
8988
9007
  }
8989
9008
  /**
8990
- * Format a tool definition as a signature string
9009
+ * Analyze Node.js/JavaScript/TypeScript project
8991
9010
  */
8992
- formatToolSignature(def) {
8993
- const params = _optionalChain([def, 'access', _185 => _185.parameters, 'optionalAccess', _186 => _186.properties]) ? Object.entries(def.parameters.properties).map(([name, prop]) => {
8994
- const required = _optionalChain([def, 'access', _187 => _187.parameters, 'optionalAccess', _188 => _188.required, 'optionalAccess', _189 => _189.includes, 'call', _190 => _190(name)]) ? "" : "?";
8995
- return `${name}${required}: ${prop.type}`;
8996
- }).join(", ") : "";
8997
- return `- ${def.name}(${params}): ${def.description}`;
8998
- }
8999
- async run(task) {
9000
- console.log(_chalk2.default.cyan(`
9001
- \u{1F916} Sub-agent '${this.name}' starting task... (depth ${this.options.depth}/${this.options.maxDepth})`));
9002
- this.conversation.addMessage({ role: "user", content: task });
9003
- const tools = this.toolManager.toFunctionDefinitions();
9004
- const maxIterations = 10;
9005
- for (let i = 0; i < maxIterations; i++) {
9006
- const completion = await this.llm.complete({
9007
- messages: this.conversation.history(),
9008
- model: this.config.model,
9009
- temperature: 0.2,
9010
- tools: tools.length > 0 ? tools : void 0,
9011
- toolChoice: tools.length > 0 ? "auto" : void 0
9012
- });
9013
- const payload = this.parseResponse(completion);
9014
- if (_optionalChain([completion, 'access', _191 => _191.toolCalls, 'optionalAccess', _192 => _192.length])) {
9015
- this.conversation.addMessage({
9016
- role: "assistant",
9017
- content: completion.content || ""
9018
- });
9011
+ async analyzeNodeProject(info) {
9012
+ const pkgPath = _path.join.call(void 0, this.workspaceRoot, "package.json");
9013
+ if (!await _fsextra.pathExists.call(void 0, pkgPath)) {
9014
+ return;
9015
+ }
9016
+ try {
9017
+ const pkg = await _fsextra.readJson.call(void 0, pkgPath);
9018
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
9019
+ if (deps.typescript || _optionalChain([pkg, 'access', _185 => _185.devDependencies, 'optionalAccess', _186 => _186.typescript])) {
9020
+ info.language = "TypeScript";
9019
9021
  } else {
9020
- this.conversation.addMessage({ role: "assistant", content: completion.content });
9021
- }
9022
- if (payload.thought) {
9023
- console.log(_chalk2.default.gray(`[${this.name}] ${payload.thought}`));
9024
- }
9025
- if (payload.toolCalls && payload.toolCalls.length > 0) {
9026
- const results = await this.toolManager.execute(payload.toolCalls);
9027
- for (let j = 0; j < results.length; j++) {
9028
- const result = results[j];
9029
- const toolCall = _optionalChain([completion, 'access', _193 => _193.toolCalls, 'optionalAccess', _194 => _194[j]]);
9030
- const content = result.success ? _nullishCoalesce(result.output, () => ( "(no output)")) : _nullishCoalesce(result.error, () => ( "Tool failed"));
9031
- this.conversation.addMessage({
9032
- role: "tool",
9033
- name: result.tool,
9034
- content,
9035
- tool_call_id: _optionalChain([toolCall, 'optionalAccess', _195 => _195.id])
9036
- });
9037
- if (!result.success) {
9038
- console.log(_chalk2.default.red(`[${this.name}] Tool ${result.tool} failed: ${content}`));
9039
- }
9040
- }
9041
- continue;
9042
- }
9043
- const response = _nullishCoalesce(_nullishCoalesce(payload.finalResponse, () => ( payload.response)), () => ( completion.content));
9044
- console.log(_chalk2.default.cyan(`[${this.name}] Finished.`));
9045
- return response;
9022
+ info.language = "JavaScript";
9023
+ }
9024
+ info.framework = this.detectNodeFramework(deps);
9025
+ info.packageManager = await this.detectNodePackageManager();
9026
+ info.testFramework = this.detectNodeTestFramework(deps);
9027
+ info.linter = this.detectNodeLinter(deps);
9028
+ info.formatter = this.detectNodeFormatter(deps);
9029
+ info.buildTool = this.detectNodeBuildTool(deps);
9030
+ } catch (e40) {
9046
9031
  }
9047
- return `[${this.name}] Failed to complete task within ${maxIterations} iterations.`;
9048
9032
  }
9049
9033
  /**
9050
- * Parse LLM response, preferring native tool calls over JSON parsing
9034
+ * Detect Node.js framework from dependencies
9051
9035
  */
9052
- parseResponse(completion) {
9053
- if (completion.toolCalls && completion.toolCalls.length > 0) {
9054
- return {
9055
- thought: completion.content || void 0,
9056
- toolCalls: completion.toolCalls.map((tc) => ({
9057
- tool: tc.function.name,
9058
- args: this.safeParseJson(tc.function.arguments)
9059
- }))
9060
- };
9061
- }
9062
- return this.parsePayload(completion.content);
9036
+ detectNodeFramework(deps) {
9037
+ if (deps.next) return "Next.js";
9038
+ if (deps.nuxt) return "Nuxt";
9039
+ if (deps["@remix-run/node"] || deps["@remix-run/react"]) return "Remix";
9040
+ if (deps["@angular/core"]) return "Angular";
9041
+ if (deps.svelte) return "Svelte";
9042
+ if (deps.vue) return "Vue";
9043
+ if (deps.react) return "React";
9044
+ if (deps.solid) return "Solid";
9045
+ if (deps["@nestjs/core"]) return "NestJS";
9046
+ if (deps.fastify) return "Fastify";
9047
+ if (deps.hono) return "Hono";
9048
+ if (deps.koa) return "Koa";
9049
+ if (deps.express) return "Express";
9050
+ return void 0;
9063
9051
  }
9064
9052
  /**
9065
- * Safely parse JSON, returning empty object on failure
9053
+ * Detect Node.js package manager from lockfiles
9054
+ */
9055
+ async detectNodePackageManager() {
9056
+ if (await _fsextra.pathExists.call(void 0, _path.join.call(void 0, this.workspaceRoot, "bun.lockb")) || await _fsextra.pathExists.call(void 0, _path.join.call(void 0, this.workspaceRoot, "bun.lock"))) {
9057
+ return "bun";
9058
+ }
9059
+ if (await _fsextra.pathExists.call(void 0, _path.join.call(void 0, this.workspaceRoot, "pnpm-lock.yaml"))) {
9060
+ return "pnpm";
9061
+ }
9062
+ if (await _fsextra.pathExists.call(void 0, _path.join.call(void 0, this.workspaceRoot, "yarn.lock"))) {
9063
+ return "yarn";
9064
+ }
9065
+ if (await _fsextra.pathExists.call(void 0, _path.join.call(void 0, this.workspaceRoot, "package-lock.json"))) {
9066
+ return "npm";
9067
+ }
9068
+ return "npm";
9069
+ }
9070
+ /**
9071
+ * Detect Node.js test framework
9072
+ */
9073
+ detectNodeTestFramework(deps) {
9074
+ if (deps.vitest) return "Vitest";
9075
+ if (deps.jest) return "Jest";
9076
+ if (deps.mocha) return "Mocha";
9077
+ if (deps.ava) return "AVA";
9078
+ if (deps["@playwright/test"]) return "Playwright";
9079
+ if (deps.cypress) return "Cypress";
9080
+ if (deps.puppeteer) return "Puppeteer";
9081
+ return void 0;
9082
+ }
9083
+ /**
9084
+ * Detect Node.js linter
9085
+ */
9086
+ detectNodeLinter(deps) {
9087
+ if (deps["@biomejs/biome"]) return "Biome";
9088
+ if (deps.eslint) return "ESLint";
9089
+ if (deps.oxlint) return "Oxlint";
9090
+ return void 0;
9091
+ }
9092
+ /**
9093
+ * Detect Node.js formatter
9094
+ */
9095
+ detectNodeFormatter(deps) {
9096
+ if (deps.prettier) return "Prettier";
9097
+ if (deps["@biomejs/biome"]) return "Biome";
9098
+ if (deps.dprint) return "dprint";
9099
+ return void 0;
9100
+ }
9101
+ /**
9102
+ * Detect Node.js build tool
9103
+ */
9104
+ detectNodeBuildTool(deps) {
9105
+ if (deps.vite) return "Vite";
9106
+ if (deps.tsup) return "tsup";
9107
+ if (deps.esbuild) return "esbuild";
9108
+ if (deps.rollup) return "Rollup";
9109
+ if (deps.webpack) return "Webpack";
9110
+ if (deps.parcel) return "Parcel";
9111
+ if (deps.turbopack || deps.turbo) return "Turbopack";
9112
+ return void 0;
9113
+ }
9114
+ /**
9115
+ * Analyze Rust project
9116
+ */
9117
+ async analyzeRustProject(info) {
9118
+ const cargoPath = _path.join.call(void 0, this.workspaceRoot, "Cargo.toml");
9119
+ if (!await _fsextra.pathExists.call(void 0, cargoPath)) {
9120
+ return;
9121
+ }
9122
+ info.language = "Rust";
9123
+ info.packageManager = "cargo";
9124
+ try {
9125
+ const cargoContent = await _fsextra.readFile.call(void 0, cargoPath, "utf-8");
9126
+ if (cargoContent.includes("actix-web")) {
9127
+ info.framework = "Actix";
9128
+ } else if (cargoContent.includes("axum")) {
9129
+ info.framework = "Axum";
9130
+ } else if (cargoContent.includes("rocket")) {
9131
+ info.framework = "Rocket";
9132
+ } else if (cargoContent.includes("warp")) {
9133
+ info.framework = "Warp";
9134
+ } else if (cargoContent.includes("tauri")) {
9135
+ info.framework = "Tauri";
9136
+ }
9137
+ } catch (e41) {
9138
+ }
9139
+ }
9140
+ /**
9141
+ * Analyze Go project
9142
+ */
9143
+ async analyzeGoProject(info) {
9144
+ const goModPath = _path.join.call(void 0, this.workspaceRoot, "go.mod");
9145
+ if (!await _fsextra.pathExists.call(void 0, goModPath)) {
9146
+ return;
9147
+ }
9148
+ info.language = "Go";
9149
+ info.packageManager = "go";
9150
+ try {
9151
+ const goModContent = await _fsextra.readFile.call(void 0, goModPath, "utf-8");
9152
+ if (goModContent.includes("github.com/gin-gonic/gin")) {
9153
+ info.framework = "Gin";
9154
+ } else if (goModContent.includes("github.com/gofiber/fiber")) {
9155
+ info.framework = "Fiber";
9156
+ } else if (goModContent.includes("github.com/labstack/echo")) {
9157
+ info.framework = "Echo";
9158
+ } else if (goModContent.includes("github.com/gorilla/mux")) {
9159
+ info.framework = "Gorilla";
9160
+ }
9161
+ } catch (e42) {
9162
+ }
9163
+ }
9164
+ /**
9165
+ * Analyze Python project
9166
+ */
9167
+ async analyzePythonProject(info) {
9168
+ const pyprojectPath = _path.join.call(void 0, this.workspaceRoot, "pyproject.toml");
9169
+ const requirementsPath = _path.join.call(void 0, this.workspaceRoot, "requirements.txt");
9170
+ const poetryLockPath = _path.join.call(void 0, this.workspaceRoot, "poetry.lock");
9171
+ const pipfilePath = _path.join.call(void 0, this.workspaceRoot, "Pipfile");
9172
+ const hasPyproject = await _fsextra.pathExists.call(void 0, pyprojectPath);
9173
+ const hasRequirements = await _fsextra.pathExists.call(void 0, requirementsPath);
9174
+ if (!hasPyproject && !hasRequirements) {
9175
+ return;
9176
+ }
9177
+ info.language = "Python";
9178
+ if (await _fsextra.pathExists.call(void 0, poetryLockPath)) {
9179
+ info.packageManager = "poetry";
9180
+ } else if (await _fsextra.pathExists.call(void 0, pipfilePath)) {
9181
+ info.packageManager = "pipenv";
9182
+ } else if (hasPyproject) {
9183
+ info.packageManager = "pip";
9184
+ } else {
9185
+ info.packageManager = "pip";
9186
+ }
9187
+ let depsContent = "";
9188
+ try {
9189
+ if (hasRequirements) {
9190
+ depsContent = await _fsextra.readFile.call(void 0, requirementsPath, "utf-8");
9191
+ } else if (hasPyproject) {
9192
+ depsContent = await _fsextra.readFile.call(void 0, pyprojectPath, "utf-8");
9193
+ }
9194
+ if (depsContent.includes("django")) {
9195
+ info.framework = "Django";
9196
+ } else if (depsContent.includes("fastapi")) {
9197
+ info.framework = "FastAPI";
9198
+ } else if (depsContent.includes("flask")) {
9199
+ info.framework = "Flask";
9200
+ } else if (depsContent.includes("starlette")) {
9201
+ info.framework = "Starlette";
9202
+ } else if (depsContent.includes("tornado")) {
9203
+ info.framework = "Tornado";
9204
+ }
9205
+ if (depsContent.includes("pytest")) {
9206
+ info.testFramework = "pytest";
9207
+ } else if (depsContent.includes("unittest")) {
9208
+ info.testFramework = "unittest";
9209
+ } else if (depsContent.includes("nose")) {
9210
+ info.testFramework = "nose";
9211
+ }
9212
+ if (depsContent.includes("ruff")) {
9213
+ info.linter = "Ruff";
9214
+ } else if (depsContent.includes("flake8")) {
9215
+ info.linter = "Flake8";
9216
+ } else if (depsContent.includes("pylint")) {
9217
+ info.linter = "Pylint";
9218
+ }
9219
+ if (depsContent.includes("black")) {
9220
+ info.formatter = "Black";
9221
+ } else if (depsContent.includes("ruff")) {
9222
+ info.formatter = "Ruff";
9223
+ } else if (depsContent.includes("autopep8")) {
9224
+ info.formatter = "autopep8";
9225
+ }
9226
+ } catch (e43) {
9227
+ }
9228
+ }
9229
+ };
9230
+
9231
+ // src/onboarding/agentsGenerator.ts
9232
+ var AgentsGenerator = class {
9233
+ /**
9234
+ * Generate AGENTS.md content
9235
+ */
9236
+ generateContent(info, options) {
9237
+ const sections = [];
9238
+ sections.push("# AGENTS.md");
9239
+ sections.push("");
9240
+ sections.push("This file helps Autohand understand how to work with this project.");
9241
+ sections.push("");
9242
+ sections.push(this.generateProjectOverview(info));
9243
+ if (info.packageManager) {
9244
+ sections.push(this.generateCommandsSection(info));
9245
+ }
9246
+ if (info.testFramework) {
9247
+ sections.push(this.generateTestingSection(info));
9248
+ }
9249
+ if (info.framework) {
9250
+ const frameworkSection = this.generateFrameworkSection(info);
9251
+ if (frameworkSection) {
9252
+ sections.push(frameworkSection);
9253
+ }
9254
+ }
9255
+ sections.push(this.generateCodeStyleSection(info));
9256
+ sections.push(this.generateConstraintsSection());
9257
+ if (_optionalChain([options, 'optionalAccess', _187 => _187.customSections])) {
9258
+ for (const section of options.customSections) {
9259
+ sections.push(`## ${section.title}`);
9260
+ sections.push("");
9261
+ sections.push(section.content);
9262
+ sections.push("");
9263
+ }
9264
+ }
9265
+ return sections.join("\n");
9266
+ }
9267
+ /**
9268
+ * Generate project overview section
9269
+ */
9270
+ generateProjectOverview(info) {
9271
+ const lines = [];
9272
+ lines.push("## Project Overview");
9273
+ lines.push("");
9274
+ if (info.language) {
9275
+ lines.push(`- **Language**: ${info.language}`);
9276
+ }
9277
+ if (info.framework) {
9278
+ lines.push(`- **Framework**: ${info.framework}`);
9279
+ }
9280
+ if (info.packageManager) {
9281
+ lines.push(`- **Package Manager**: ${info.packageManager}`);
9282
+ }
9283
+ if (info.testFramework) {
9284
+ lines.push(`- **Test Framework**: ${info.testFramework}`);
9285
+ }
9286
+ if (info.buildTool) {
9287
+ lines.push(`- **Build Tool**: ${info.buildTool}`);
9288
+ }
9289
+ lines.push("");
9290
+ return lines.join("\n");
9291
+ }
9292
+ /**
9293
+ * Generate commands section based on package manager
9294
+ */
9295
+ generateCommandsSection(info) {
9296
+ const lines = [];
9297
+ lines.push("## Commands");
9298
+ lines.push("");
9299
+ const pm = info.packageManager;
9300
+ if (info.language === "Rust") {
9301
+ lines.push("- **Build**: `cargo build`");
9302
+ lines.push("- **Build (release)**: `cargo build --release`");
9303
+ lines.push("- **Run**: `cargo run`");
9304
+ lines.push("- **Test**: `cargo test`");
9305
+ lines.push("- **Check**: `cargo check`");
9306
+ lines.push("- **Format**: `cargo fmt`");
9307
+ lines.push("- **Lint**: `cargo clippy`");
9308
+ } else if (info.language === "Go") {
9309
+ lines.push("- **Build**: `go build`");
9310
+ lines.push("- **Run**: `go run .`");
9311
+ lines.push("- **Test**: `go test ./...`");
9312
+ lines.push("- **Format**: `go fmt ./...`");
9313
+ lines.push("- **Vet**: `go vet ./...`");
9314
+ } else if (info.language === "Python") {
9315
+ if (pm === "poetry") {
9316
+ lines.push("- **Install**: `poetry install`");
9317
+ lines.push("- **Run**: `poetry run python main.py`");
9318
+ lines.push("- **Add dependency**: `poetry add <package>`");
9319
+ if (info.testFramework) {
9320
+ lines.push(`- **Test**: \`poetry run pytest\``);
9321
+ }
9322
+ } else if (pm === "pipenv") {
9323
+ lines.push("- **Install**: `pipenv install`");
9324
+ lines.push("- **Run**: `pipenv run python main.py`");
9325
+ if (info.testFramework) {
9326
+ lines.push(`- **Test**: \`pipenv run pytest\``);
9327
+ }
9328
+ } else {
9329
+ lines.push("- **Install**: `pip install -r requirements.txt`");
9330
+ lines.push("- **Run**: `python main.py`");
9331
+ if (info.testFramework) {
9332
+ lines.push(`- **Test**: \`pytest\``);
9333
+ }
9334
+ }
9335
+ } else {
9336
+ const run = pm === "npm" ? "npm run" : pm;
9337
+ const install = pm === "npm" ? "npm install" : `${pm} install`;
9338
+ lines.push(`- **Install**: \`${install}\``);
9339
+ lines.push(`- **Dev**: \`${run} dev\``);
9340
+ lines.push(`- **Build**: \`${run} build\``);
9341
+ if (info.testFramework) {
9342
+ lines.push(`- **Test**: \`${run} test\``);
9343
+ }
9344
+ if (info.linter) {
9345
+ lines.push(`- **Lint**: \`${run} lint\``);
9346
+ }
9347
+ if (info.formatter) {
9348
+ lines.push(`- **Format**: \`${run} format\``);
9349
+ }
9350
+ }
9351
+ lines.push("");
9352
+ return lines.join("\n");
9353
+ }
9354
+ /**
9355
+ * Generate testing section
9356
+ */
9357
+ generateTestingSection(info) {
9358
+ const lines = [];
9359
+ lines.push("## Testing");
9360
+ lines.push("");
9361
+ lines.push(`This project uses **${info.testFramework}** for testing.`);
9362
+ lines.push("");
9363
+ lines.push("- Write tests for new features before implementation");
9364
+ lines.push("- Run tests before committing changes");
9365
+ lines.push("- Aim for good test coverage on critical paths");
9366
+ if (info.testFramework === "Vitest" || info.testFramework === "Jest") {
9367
+ lines.push("- Use `describe` and `it` blocks to organize tests");
9368
+ lines.push("- Mock external dependencies when appropriate");
9369
+ } else if (info.testFramework === "pytest") {
9370
+ lines.push("- Use fixtures for shared test setup");
9371
+ lines.push("- Use `pytest.mark` for test categorization");
9372
+ } else if (info.testFramework === "Playwright" || info.testFramework === "Cypress") {
9373
+ lines.push("- Write E2E tests for critical user flows");
9374
+ lines.push("- Keep selectors stable and meaningful");
9375
+ }
9376
+ lines.push("");
9377
+ return lines.join("\n");
9378
+ }
9379
+ /**
9380
+ * Generate framework-specific section
9381
+ */
9382
+ generateFrameworkSection(info) {
9383
+ const lines = [];
9384
+ switch (info.framework) {
9385
+ case "Next.js":
9386
+ lines.push("## Next.js Guidelines");
9387
+ lines.push("");
9388
+ lines.push("- Use the App Router for new pages (`app/` directory)");
9389
+ lines.push("- Prefer Server Components by default");
9390
+ lines.push('- Use `"use client"` only when needed for interactivity');
9391
+ lines.push("- Keep API routes in `app/api/`");
9392
+ lines.push("- Use `next/image` for optimized images");
9393
+ lines.push("- Use `next/link` for client-side navigation");
9394
+ break;
9395
+ case "React":
9396
+ lines.push("## React Guidelines");
9397
+ lines.push("");
9398
+ lines.push("- Use functional components with hooks");
9399
+ lines.push("- Keep components small and focused");
9400
+ lines.push("- Use custom hooks to share logic");
9401
+ lines.push("- Prefer composition over inheritance");
9402
+ lines.push("- Use TypeScript interfaces for props");
9403
+ break;
9404
+ case "Vue":
9405
+ lines.push("## Vue Guidelines");
9406
+ lines.push("");
9407
+ lines.push("- Use Composition API for new components");
9408
+ lines.push("- Keep components in single-file format (.vue)");
9409
+ lines.push("- Use composables to share logic");
9410
+ break;
9411
+ case "Express":
9412
+ lines.push("## Express Guidelines");
9413
+ lines.push("");
9414
+ lines.push("- Use middleware for cross-cutting concerns");
9415
+ lines.push("- Keep route handlers thin, delegate to services");
9416
+ lines.push("- Use async/await with proper error handling");
9417
+ lines.push("- Validate request input before processing");
9418
+ break;
9419
+ case "FastAPI":
9420
+ lines.push("## FastAPI Guidelines");
9421
+ lines.push("");
9422
+ lines.push("- Use Pydantic models for request/response validation");
9423
+ lines.push("- Use dependency injection for shared resources");
9424
+ lines.push("- Keep endpoints in organized routers");
9425
+ lines.push("- Use async functions for I/O operations");
9426
+ break;
9427
+ case "Django":
9428
+ lines.push("## Django Guidelines");
9429
+ lines.push("");
9430
+ lines.push("- Follow Django project structure conventions");
9431
+ lines.push("- Use class-based views where appropriate");
9432
+ lines.push("- Keep business logic in models or services");
9433
+ lines.push("- Use Django ORM for database operations");
9434
+ break;
9435
+ case "Flask":
9436
+ lines.push("## Flask Guidelines");
9437
+ lines.push("");
9438
+ lines.push("- Use blueprints to organize routes");
9439
+ lines.push("- Keep route handlers focused");
9440
+ lines.push("- Use Flask extensions for common functionality");
9441
+ break;
9442
+ case "NestJS":
9443
+ lines.push("## NestJS Guidelines");
9444
+ lines.push("");
9445
+ lines.push("- Follow module-based architecture");
9446
+ lines.push("- Use dependency injection");
9447
+ lines.push("- Use decorators for metadata");
9448
+ lines.push("- Keep controllers thin, services fat");
9449
+ break;
9450
+ default:
9451
+ return null;
9452
+ }
9453
+ lines.push("");
9454
+ return lines.join("\n");
9455
+ }
9456
+ /**
9457
+ * Generate code style section
9458
+ */
9459
+ generateCodeStyleSection(info) {
9460
+ const lines = [];
9461
+ lines.push("## Code Style");
9462
+ lines.push("");
9463
+ if (info.language === "TypeScript") {
9464
+ lines.push("- Use strict TypeScript settings");
9465
+ lines.push("- Define types/interfaces for data structures");
9466
+ lines.push("- Avoid `any` type - use `unknown` if type is truly unknown");
9467
+ lines.push("- Use type inference where obvious");
9468
+ } else if (info.language === "Python") {
9469
+ lines.push("- Follow PEP 8 style guidelines");
9470
+ lines.push("- Use type hints for function signatures");
9471
+ lines.push("- Use docstrings for public functions");
9472
+ } else if (info.language === "Rust") {
9473
+ lines.push("- Follow Rust naming conventions (snake_case for functions)");
9474
+ lines.push("- Use descriptive error types");
9475
+ lines.push("- Prefer `Result` over panicking");
9476
+ } else if (info.language === "Go") {
9477
+ lines.push("- Follow Go idioms and conventions");
9478
+ lines.push("- Use short variable names in small scopes");
9479
+ lines.push("- Handle errors explicitly");
9480
+ }
9481
+ lines.push("- Follow existing patterns in the codebase");
9482
+ lines.push("- Use meaningful variable and function names");
9483
+ lines.push("- Add comments for complex logic");
9484
+ lines.push("- Keep functions focused and small");
9485
+ if (info.linter) {
9486
+ lines.push(`- Run **${info.linter}** before committing`);
9487
+ }
9488
+ if (info.formatter) {
9489
+ lines.push(`- Format code with **${info.formatter}**`);
9490
+ }
9491
+ lines.push("");
9492
+ return lines.join("\n");
9493
+ }
9494
+ /**
9495
+ * Generate constraints section
9496
+ */
9497
+ generateConstraintsSection() {
9498
+ const lines = [];
9499
+ lines.push("## Constraints");
9500
+ lines.push("");
9501
+ lines.push("- Do not modify files outside the project directory");
9502
+ lines.push("- Ask before making breaking changes");
9503
+ lines.push("- Prefer editing existing files over creating new ones");
9504
+ lines.push("- Do not delete files without confirmation");
9505
+ lines.push("- Keep dependencies minimal - avoid adding new ones without good reason");
9506
+ lines.push("- Do not commit sensitive data (API keys, secrets, credentials)");
9507
+ lines.push("");
9508
+ return lines.join("\n");
9509
+ }
9510
+ };
9511
+
9512
+ // src/onboarding/setupWizard.ts
9513
+
9514
+
9515
+
9516
+
9517
+ var ASCII_FRIEND = [
9518
+ "\u2880\u2874\u281B\u281B\u283B\u28F7\u2844\u2800\u28E0\u2876\u281F\u281B\u283B\u28F6\u2844\u2880\u28F4\u287E\u281B\u281B\u28BF\u28E6\u2800\u2880\u28F4\u281E\u281B\u281B\u2836\u2840",
9519
+ "\u284E\u2800\u28B0\u28F6\u2846\u2808\u28FF\u28F4\u28FF\u2801\u28F4\u28F6\u2844\u2818\u28FF\u28FE\u284F\u2880\u28F6\u28E6\u2800\u28BB\u2847\u28FF\u2803\u28A0\u28F6\u2846\u2800\u28B9",
9520
+ "\u28A7\u2800\u2818\u281B\u2803\u28A0\u287F\u2819\u28FF\u2840\u2819\u281B\u2803\u28F0\u287F\u28BB\u28E7\u2808\u281B\u281B\u2880\u28FE\u2807\u28BB\u28C6\u2808\u281B\u280B\u2800\u287C",
9521
+ "\u2808\u283B\u28B6\u28F6\u287E\u281F\u2801\u2800\u2818\u283F\u28B6\u28F6\u287E\u281F\u2801\u2800\u2819\u2837\u28F6\u28F6\u283F\u280B\u2800\u2808\u283B\u2837\u28F6\u2876\u281A\u2801",
9522
+ "\u2880\u28F4\u283F\u283F\u2837\u28E6\u2840\u2800\u28E0\u28F6\u283F\u283B\u28B7\u28E6\u2840\u2800\u28E0\u287E\u281F\u283F\u28F6\u28C4\u2800\u2880\u28F4\u287E\u283F\u283F\u28F6\u28C4",
9523
+ "\u287E\u2803\u28A0\u28E4\u2844\u2818\u28FF\u28E0\u28FF\u2801\u28E0\u28E4\u2844\u2839\u28F7\u28FC\u284F\u2880\u28E4\u28E4\u2808\u28BF\u2846\u28FE\u280F\u2880\u28E4\u28C4\u2808\u28BF",
9524
+ "\u28A7\u2840\u2838\u283F\u2807\u2880\u28FF\u283A\u28FF\u2840\u283B\u283F\u2803\u28B0\u28FF\u28BF\u28C7\u2808\u283F\u283F\u2800\u28FC\u2847\u28BF\u28C7\u2818\u283F\u2807\u2800\u28F8",
9525
+ "\u2808\u28BF\u28E6\u28E4\u28F4\u287F\u2803\u2800\u2819\u28B7\u28E6\u28E4\u28F6\u287F\u2801\u2808\u283B\u28F7\u28E4\u28E4\u287E\u281B\u2800\u2808\u28BF\u28E6\u28E4\u28E4\u2834\u2801"
9526
+ ].join("\n");
9527
+ var SetupWizard = class {
9528
+ constructor(workspaceRoot, existingConfig) {
9529
+ this.workspaceRoot = workspaceRoot;
9530
+ this.existingConfig = _nullishCoalesce(existingConfig, () => ( null));
9531
+ this.state = {
9532
+ currentStep: "welcome",
9533
+ skipped: [],
9534
+ completed: false
9535
+ };
9536
+ }
9537
+ /**
9538
+ * Run the full onboarding wizard
9539
+ */
9540
+ async run(options) {
9541
+ if (!_optionalChain([options, 'optionalAccess', _188 => _188.force]) && this.isAlreadyConfigured()) {
9542
+ return {
9543
+ success: true,
9544
+ config: {},
9545
+ skippedSteps: ["welcome", "provider", "apiKey", "model", "telemetry", "preferences", "agentsFile"],
9546
+ cancelled: false
9547
+ };
9548
+ }
9549
+ try {
9550
+ if (!_optionalChain([options, 'optionalAccess', _189 => _189.skipWelcome])) {
9551
+ await this.showWelcome();
9552
+ }
9553
+ const provider = await this.promptProvider();
9554
+ if (!provider) return this.cancelled();
9555
+ if (this.requiresApiKey(provider)) {
9556
+ const apiKey = await this.promptApiKey(provider);
9557
+ if (apiKey === null) return this.cancelled();
9558
+ }
9559
+ const model = await this.promptModel(provider);
9560
+ if (!model) return this.cancelled();
9561
+ await this.promptTelemetry();
9562
+ if (!_optionalChain([options, 'optionalAccess', _190 => _190.quickSetup])) {
9563
+ await this.promptPreferences();
9564
+ } else {
9565
+ this.state.skipped.push("preferences");
9566
+ }
9567
+ await this.promptAgentsFile();
9568
+ return this.complete();
9569
+ } catch (error) {
9570
+ if (this.isCancellation(error)) {
9571
+ return this.cancelled();
9572
+ }
9573
+ throw error;
9574
+ }
9575
+ }
9576
+ /**
9577
+ * Check if configuration is already complete
9578
+ */
9579
+ isAlreadyConfigured() {
9580
+ if (!this.existingConfig) return false;
9581
+ const provider = this.existingConfig.provider;
9582
+ if (!provider) return false;
9583
+ const providerConfig = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.existingConfig, provider);
9584
+ return providerConfig !== null;
9585
+ }
9586
+ /**
9587
+ * Show welcome screen
9588
+ */
9589
+ async showWelcome() {
9590
+ console.clear();
9591
+ console.log(_chalk2.default.gray(ASCII_FRIEND));
9592
+ console.log();
9593
+ console.log(_chalk2.default.cyan.bold(" Welcome to Autohand!"));
9594
+ console.log(_chalk2.default.gray(" Your super fast AI coding agent"));
9595
+ console.log();
9596
+ console.log(_chalk2.default.white(" Let's get you set up in just a few steps."));
9597
+ console.log();
9598
+ await this.pressEnter();
9599
+ }
9600
+ /**
9601
+ * Prompt for provider selection
9602
+ */
9603
+ async promptProvider() {
9604
+ this.state.currentStep = "provider";
9605
+ const providers = ProviderFactory.getProviderNames();
9606
+ const choices = providers.map((p) => ({
9607
+ name: p,
9608
+ message: this.getProviderDisplayName(p),
9609
+ hint: this.getProviderHint(p)
9610
+ }));
9611
+ const result = await _enquirer2.default.prompt({
9612
+ type: "select",
9613
+ name: "provider",
9614
+ message: "Which LLM provider would you like to use?",
9615
+ choices,
9616
+ initial: _optionalChain([this, 'access', _191 => _191.existingConfig, 'optionalAccess', _192 => _192.provider]) ? providers.indexOf(this.existingConfig.provider) : 0
9617
+ });
9618
+ this.state.provider = result.provider;
9619
+ return result.provider;
9620
+ }
9621
+ /**
9622
+ * Prompt for API key (cloud providers)
9623
+ */
9624
+ async promptApiKey(provider) {
9625
+ this.state.currentStep = "apiKey";
9626
+ const existingKey = this.getExistingApiKey(provider);
9627
+ if (existingKey && existingKey !== "replace-me") {
9628
+ const { useExisting } = await _enquirer2.default.prompt({
9629
+ type: "confirm",
9630
+ name: "useExisting",
9631
+ message: `Use existing ${this.getProviderDisplayName(provider)} API key? (ends with ...${existingKey.slice(-4)})`,
9632
+ initial: true
9633
+ });
9634
+ if (useExisting) {
9635
+ this.state.apiKey = existingKey;
9636
+ return existingKey;
9637
+ }
9638
+ }
9639
+ console.log(_chalk2.default.gray(`
9640
+ Get your API key at: ${this.getApiKeyUrl(provider)}
9641
+ `));
9642
+ const result = await _enquirer2.default.prompt({
9643
+ type: "password",
9644
+ name: "apiKey",
9645
+ message: `Enter your ${this.getProviderDisplayName(provider)} API key`,
9646
+ validate: (val) => {
9647
+ const v = val;
9648
+ if (!_optionalChain([v, 'optionalAccess', _193 => _193.trim, 'call', _194 => _194()])) return "API key is required";
9649
+ if (v.length < 10) return "API key seems too short";
9650
+ return true;
9651
+ }
9652
+ });
9653
+ this.state.apiKey = result.apiKey.trim();
9654
+ return this.state.apiKey;
9655
+ }
9656
+ /**
9657
+ * Prompt for model selection
9658
+ */
9659
+ async promptModel(provider) {
9660
+ this.state.currentStep = "model";
9661
+ const defaultModel = this.getDefaultModel(provider);
9662
+ const result = await _enquirer2.default.prompt({
9663
+ type: "input",
9664
+ name: "model",
9665
+ message: "Enter model ID",
9666
+ initial: defaultModel,
9667
+ validate: (val) => {
9668
+ const v = val;
9669
+ return _optionalChain([v, 'optionalAccess', _195 => _195.trim, 'call', _196 => _196()]) ? true : "Model is required";
9670
+ }
9671
+ });
9672
+ this.state.model = result.model.trim();
9673
+ return this.state.model;
9674
+ }
9675
+ /**
9676
+ * Prompt for telemetry preference
9677
+ */
9678
+ async promptTelemetry() {
9679
+ this.state.currentStep = "telemetry";
9680
+ console.log();
9681
+ console.log(_chalk2.default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
9682
+ console.log(_chalk2.default.white.bold(" Help us improve Autohand"));
9683
+ console.log(_chalk2.default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
9684
+ console.log();
9685
+ console.log(_chalk2.default.gray(" We collect anonymous usage data to understand how"));
9686
+ console.log(_chalk2.default.gray(" Autohand is used and where we can make it better."));
9687
+ console.log();
9688
+ console.log(_chalk2.default.gray(" What we collect:"));
9689
+ console.log(_chalk2.default.gray(" - Command usage (which features are popular)"));
9690
+ console.log(_chalk2.default.gray(" - Error rates (to fix bugs faster)"));
9691
+ console.log(_chalk2.default.gray(" - Performance metrics (to speed things up)"));
9692
+ console.log();
9693
+ console.log(_chalk2.default.gray(" What we never collect:"));
9694
+ console.log(_chalk2.default.gray(" - Your code or file contents"));
9695
+ console.log(_chalk2.default.gray(" - API keys or credentials"));
9696
+ console.log(_chalk2.default.gray(" - Personal information"));
9697
+ console.log();
9698
+ const { telemetryEnabled } = await _enquirer2.default.prompt({
9699
+ type: "confirm",
9700
+ name: "telemetryEnabled",
9701
+ message: "Share anonymous usage data to help improve Autohand?",
9702
+ initial: true
9703
+ });
9704
+ this.state.telemetryEnabled = telemetryEnabled;
9705
+ if (telemetryEnabled) {
9706
+ console.log(_chalk2.default.green(" Thanks for helping us improve Autohand!"));
9707
+ } else {
9708
+ console.log(_chalk2.default.gray(" No problem! You can change this anytime in config."));
9709
+ }
9710
+ }
9711
+ /**
9712
+ * Prompt for additional preferences
9713
+ */
9714
+ async promptPreferences() {
9715
+ this.state.currentStep = "preferences";
9716
+ const { configurePrefs } = await _enquirer2.default.prompt({
9717
+ type: "confirm",
9718
+ name: "configurePrefs",
9719
+ message: "Would you like to configure additional preferences? (theme, auto-confirm)",
9720
+ initial: false
9721
+ });
9722
+ if (!configurePrefs) {
9723
+ this.state.skipped.push("preferences");
9724
+ return;
9725
+ }
9726
+ const themes = ["dark", "light", "dracula", "sandy", "tui"];
9727
+ const themeDescriptions = {
9728
+ dark: "Default dark theme",
9729
+ light: "Light theme for light backgrounds",
9730
+ dracula: "Popular Dracula color scheme",
9731
+ sandy: "Warm, earthy desert tones",
9732
+ tui: "New Zealand inspired colors"
9733
+ };
9734
+ const { theme } = await _enquirer2.default.prompt({
9735
+ type: "select",
9736
+ name: "theme",
9737
+ message: "Select a theme",
9738
+ choices: themes.map((t) => ({ name: t, message: t, hint: themeDescriptions[t] })),
9739
+ initial: 0
9740
+ });
9741
+ const { autoConfirm } = await _enquirer2.default.prompt({
9742
+ type: "confirm",
9743
+ name: "autoConfirm",
9744
+ message: "Auto-confirm non-destructive actions?",
9745
+ initial: false
9746
+ });
9747
+ const { checkForUpdates: checkForUpdates2 } = await _enquirer2.default.prompt({
9748
+ type: "confirm",
9749
+ name: "checkForUpdates",
9750
+ message: "Check for updates on startup?",
9751
+ initial: true
9752
+ });
9753
+ this.state.preferences = { theme, autoConfirm, checkForUpdates: checkForUpdates2 };
9754
+ }
9755
+ /**
9756
+ * Prompt for AGENTS.md creation
9757
+ */
9758
+ async promptAgentsFile() {
9759
+ this.state.currentStep = "agentsFile";
9760
+ const agentsPath = _path.join.call(void 0, this.workspaceRoot, "AGENTS.md");
9761
+ const exists = await _fsextra.pathExists.call(void 0, agentsPath);
9762
+ if (exists) {
9763
+ const { overwrite } = await _enquirer2.default.prompt({
9764
+ type: "confirm",
9765
+ name: "overwrite",
9766
+ message: "AGENTS.md already exists. Would you like to regenerate it?",
9767
+ initial: false
9768
+ });
9769
+ if (!overwrite) {
9770
+ this.state.skipped.push("agentsFile");
9771
+ console.log(_chalk2.default.gray(" Keeping existing AGENTS.md"));
9772
+ return;
9773
+ }
9774
+ } else {
9775
+ console.log();
9776
+ console.log(_chalk2.default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
9777
+ console.log(_chalk2.default.white.bold(" Project Configuration"));
9778
+ console.log(_chalk2.default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
9779
+ console.log();
9780
+ console.log(_chalk2.default.gray(" AGENTS.md helps Autohand understand your project better."));
9781
+ console.log(_chalk2.default.gray(" It contains instructions specific to your codebase."));
9782
+ console.log();
9783
+ const { createAgents } = await _enquirer2.default.prompt({
9784
+ type: "confirm",
9785
+ name: "createAgents",
9786
+ message: "Generate AGENTS.md based on your project?",
9787
+ initial: true
9788
+ });
9789
+ if (!createAgents) {
9790
+ this.state.skipped.push("agentsFile");
9791
+ console.log(_chalk2.default.gray(" You can create it later with /init"));
9792
+ return;
9793
+ }
9794
+ }
9795
+ console.log();
9796
+ console.log(_chalk2.default.gray(" Analyzing your project..."));
9797
+ const analyzer = new ProjectAnalyzer(this.workspaceRoot);
9798
+ const projectInfo = await analyzer.analyze();
9799
+ if (Object.keys(projectInfo).length > 0) {
9800
+ console.log();
9801
+ console.log(_chalk2.default.gray(" Detected:"));
9802
+ if (projectInfo.language) {
9803
+ console.log(_chalk2.default.white(` - Language: ${projectInfo.language}`));
9804
+ }
9805
+ if (projectInfo.framework) {
9806
+ console.log(_chalk2.default.white(` - Framework: ${projectInfo.framework}`));
9807
+ }
9808
+ if (projectInfo.packageManager) {
9809
+ console.log(_chalk2.default.white(` - Package manager: ${projectInfo.packageManager}`));
9810
+ }
9811
+ if (projectInfo.testFramework) {
9812
+ console.log(_chalk2.default.white(` - Test framework: ${projectInfo.testFramework}`));
9813
+ }
9814
+ }
9815
+ const generator = new AgentsGenerator();
9816
+ const content = generator.generateContent(projectInfo);
9817
+ await _fsextra.writeFile.call(void 0, agentsPath, content);
9818
+ this.state.agentsFileCreated = true;
9819
+ console.log();
9820
+ console.log(_chalk2.default.green(" Created AGENTS.md"));
9821
+ console.log(_chalk2.default.gray(" You can customize it anytime to improve Autohand's understanding."));
9822
+ }
9823
+ /**
9824
+ * Build final config and return success
9825
+ */
9826
+ complete() {
9827
+ this.state.currentStep = "complete";
9828
+ this.state.completed = true;
9829
+ const config = {
9830
+ provider: this.state.provider
9831
+ };
9832
+ if (this.state.provider) {
9833
+ if (this.requiresApiKey(this.state.provider)) {
9834
+ config[this.state.provider] = {
9835
+ apiKey: this.state.apiKey,
9836
+ model: this.state.model,
9837
+ baseUrl: this.getDefaultBaseUrl(this.state.provider)
9838
+ };
9839
+ } else {
9840
+ config[this.state.provider] = {
9841
+ model: this.state.model,
9842
+ baseUrl: this.getDefaultBaseUrl(this.state.provider)
9843
+ };
9844
+ }
9845
+ }
9846
+ config.telemetry = {
9847
+ enabled: _nullishCoalesce(this.state.telemetryEnabled, () => ( true))
9848
+ };
9849
+ if (this.state.preferences) {
9850
+ config.ui = {
9851
+ theme: this.state.preferences.theme,
9852
+ autoConfirm: this.state.preferences.autoConfirm,
9853
+ checkForUpdates: this.state.preferences.checkForUpdates
9854
+ };
9855
+ }
9856
+ this.showCompletionMessage();
9857
+ return {
9858
+ success: true,
9859
+ config,
9860
+ skippedSteps: this.state.skipped,
9861
+ cancelled: false,
9862
+ agentsFileCreated: this.state.agentsFileCreated
9863
+ };
9864
+ }
9865
+ /**
9866
+ * Show setup complete message
9867
+ */
9868
+ showCompletionMessage() {
9869
+ console.log();
9870
+ console.log();
9871
+ console.log(_chalk2.default.green(" Setup complete!"));
9872
+ console.log();
9873
+ console.log(_chalk2.default.gray(" What was created:"));
9874
+ console.log(_chalk2.default.white(" - ~/.autohand/config.json (your settings)"));
9875
+ if (this.state.agentsFileCreated) {
9876
+ console.log(_chalk2.default.white(" - AGENTS.md (project instructions for Autohand)"));
9877
+ }
9878
+ console.log();
9879
+ console.log(_chalk2.default.gray(" Quick tips:"));
9880
+ console.log(_chalk2.default.white(" - Type your request and press Enter to start"));
9881
+ console.log(_chalk2.default.white(" - Use @filename to mention files"));
9882
+ console.log(_chalk2.default.white(" - Type /help for all commands"));
9883
+ console.log(_chalk2.default.white(" - Press Ctrl+C twice to exit"));
9884
+ console.log();
9885
+ }
9886
+ /**
9887
+ * Return cancelled result
9888
+ */
9889
+ cancelled() {
9890
+ return {
9891
+ success: false,
9892
+ config: {},
9893
+ skippedSteps: [],
9894
+ cancelled: true
9895
+ };
9896
+ }
9897
+ // Helper methods
9898
+ requiresApiKey(provider) {
9899
+ return provider === "openrouter" || provider === "openai";
9900
+ }
9901
+ getProviderDisplayName(provider) {
9902
+ const names = {
9903
+ openrouter: "OpenRouter",
9904
+ openai: "OpenAI",
9905
+ ollama: "Ollama",
9906
+ llamacpp: "llama.cpp",
9907
+ mlx: "MLX (Apple Silicon)"
9908
+ };
9909
+ return names[provider] || provider;
9910
+ }
9911
+ getProviderHint(provider) {
9912
+ const hints = {
9913
+ openrouter: "Cloud - Access to 100+ models (Claude, GPT-4, etc.)",
9914
+ openai: "Cloud - Official OpenAI models (GPT-4o, o1, etc.)",
9915
+ ollama: "Local - Run models on your machine (free)",
9916
+ llamacpp: "Local - Fast inference with GGUF models",
9917
+ mlx: "Local - Optimized for Apple Silicon Macs"
9918
+ };
9919
+ return hints[provider] || "";
9920
+ }
9921
+ getApiKeyUrl(provider) {
9922
+ const urls = {
9923
+ openrouter: "https://openrouter.ai/keys",
9924
+ openai: "https://platform.openai.com/api-keys"
9925
+ };
9926
+ return urls[provider] || "";
9927
+ }
9928
+ getDefaultModel(provider) {
9929
+ const defaults = {
9930
+ openrouter: "anthropic/claude-sonnet-4-20250514",
9931
+ openai: "gpt-4o",
9932
+ ollama: "llama3.2:latest",
9933
+ llamacpp: "default",
9934
+ mlx: "mlx-community/Llama-3.2-3B-Instruct-4bit"
9935
+ };
9936
+ return defaults[provider] || "";
9937
+ }
9938
+ getDefaultBaseUrl(provider) {
9939
+ const urls = {
9940
+ openrouter: "https://openrouter.ai/api/v1",
9941
+ openai: "https://api.openai.com/v1",
9942
+ ollama: "http://localhost:11434",
9943
+ llamacpp: "http://localhost:8080",
9944
+ mlx: "http://localhost:8080"
9945
+ };
9946
+ return urls[provider] || "";
9947
+ }
9948
+ getExistingApiKey(provider) {
9949
+ if (!this.existingConfig) return null;
9950
+ const config = this.existingConfig[provider];
9951
+ return _optionalChain([config, 'optionalAccess', _197 => _197.apiKey]) || null;
9952
+ }
9953
+ isCancellation(error) {
9954
+ if (error && typeof error === "object") {
9955
+ const e = error;
9956
+ return e.code === "ERR_USE_AFTER_CLOSE" || _optionalChain([e, 'access', _198 => _198.message, 'optionalAccess', _199 => _199.includes, 'call', _200 => _200("cancelled")]) || _optionalChain([e, 'access', _201 => _201.message, 'optionalAccess', _202 => _202.includes, 'call', _203 => _203("canceled")]);
9957
+ }
9958
+ return false;
9959
+ }
9960
+ async pressEnter() {
9961
+ console.log(_chalk2.default.gray(" Press Enter to continue..."));
9962
+ await _enquirer2.default.prompt({
9963
+ type: "invisible",
9964
+ name: "continue",
9965
+ message: ""
9966
+ });
9967
+ }
9968
+ };
9969
+
9970
+ // src/core/agents/AgentDelegator.ts
9971
+
9972
+
9973
+ // src/core/agents/SubAgent.ts
9974
+
9975
+ var DELEGATION_TOOL_DEFINITIONS = [
9976
+ {
9977
+ name: "delegate_task",
9978
+ description: "Delegate a task to another specialized sub-agent",
9979
+ parameters: {
9980
+ type: "object",
9981
+ properties: {
9982
+ agent_name: { type: "string", description: "Name of the agent to delegate to" },
9983
+ task: { type: "string", description: "Task description for the sub-agent" }
9984
+ },
9985
+ required: ["agent_name", "task"]
9986
+ }
9987
+ },
9988
+ {
9989
+ name: "delegate_parallel",
9990
+ description: "Run multiple sub-agents in parallel (max 5)",
9991
+ parameters: {
9992
+ type: "object",
9993
+ properties: {
9994
+ tasks: { type: "array", description: "Array of {agent_name, task} objects" }
9995
+ },
9996
+ required: ["tasks"]
9997
+ }
9998
+ }
9999
+ ];
10000
+ var SubAgent = class {
10001
+ constructor(config, llm, actionExecutor, options) {
10002
+ this.config = config;
10003
+ this.llm = llm;
10004
+ this.actionExecutor = actionExecutor;
10005
+ this.delegator = null;
10006
+ this.name = config.name;
10007
+ this.options = options;
10008
+ const canDelegate = options.depth < options.maxDepth;
10009
+ const allowedTools = new Set(config.tools);
10010
+ let definitions = DEFAULT_TOOL_DEFINITIONS.filter((def) => allowedTools.has(def.name));
10011
+ if (canDelegate) {
10012
+ definitions = [...definitions, ...DELEGATION_TOOL_DEFINITIONS];
10013
+ }
10014
+ const toolFilter = new ToolFilter(options.clientContext);
10015
+ definitions = toolFilter.filterDefinitions(definitions);
10016
+ if (canDelegate) {
10017
+ this.delegator = new AgentDelegator(llm, actionExecutor, {
10018
+ clientContext: options.clientContext,
10019
+ currentDepth: options.depth,
10020
+ maxDepth: options.maxDepth
10021
+ });
10022
+ }
10023
+ this.toolManager = new ToolManager({
10024
+ executor: async (action, context) => {
10025
+ if (action.type === "delegate_task" && this.delegator) {
10026
+ return this.delegator.delegateTask(
10027
+ action.agent_name,
10028
+ action.task
10029
+ );
10030
+ }
10031
+ if (action.type === "delegate_parallel" && this.delegator) {
10032
+ return this.delegator.delegateParallel(action.tasks);
10033
+ }
10034
+ return this.actionExecutor.execute(action, context);
10035
+ },
10036
+ confirmApproval: async () => true,
10037
+ // Sub-agents auto-approve (inherit from main agent in future)
10038
+ definitions,
10039
+ clientContext: options.clientContext
10040
+ });
10041
+ const enhancedSystemPrompt = this.buildSystemPrompt(config.systemPrompt, definitions);
10042
+ this.conversation = new ConversationManager();
10043
+ this.conversation.reset(enhancedSystemPrompt);
10044
+ }
10045
+ /**
10046
+ * Build system prompt with tool signatures for the LLM
10047
+ */
10048
+ buildSystemPrompt(basePrompt, tools) {
10049
+ const toolSignatures = tools.map((def) => this.formatToolSignature(def)).join("\n");
10050
+ return [
10051
+ basePrompt,
10052
+ "",
10053
+ "## Available Tools",
10054
+ "You have access to the following tools. Use them when needed:",
10055
+ "",
10056
+ toolSignatures,
10057
+ "",
10058
+ "## Response Format",
10059
+ "Always respond with structured JSON:",
10060
+ "```json",
10061
+ "{",
10062
+ ' "thought": "Your reasoning about what to do next",',
10063
+ ' "toolCalls": [{"tool": "tool_name", "args": {...}}],',
10064
+ ' "finalResponse": "Your final answer when done (omit toolCalls if providing this)"',
10065
+ "}",
10066
+ "```",
10067
+ "",
10068
+ `Depth: ${this.options.depth}/${this.options.maxDepth} ${this.delegator ? "(can delegate further)" : "(max depth reached)"}`
10069
+ ].join("\n");
10070
+ }
10071
+ /**
10072
+ * Format a tool definition as a signature string
10073
+ */
10074
+ formatToolSignature(def) {
10075
+ const params = _optionalChain([def, 'access', _204 => _204.parameters, 'optionalAccess', _205 => _205.properties]) ? Object.entries(def.parameters.properties).map(([name, prop]) => {
10076
+ const required = _optionalChain([def, 'access', _206 => _206.parameters, 'optionalAccess', _207 => _207.required, 'optionalAccess', _208 => _208.includes, 'call', _209 => _209(name)]) ? "" : "?";
10077
+ return `${name}${required}: ${prop.type}`;
10078
+ }).join(", ") : "";
10079
+ return `- ${def.name}(${params}): ${def.description}`;
10080
+ }
10081
+ async run(task) {
10082
+ console.log(_chalk2.default.cyan(`
10083
+ \u{1F916} Sub-agent '${this.name}' starting task... (depth ${this.options.depth}/${this.options.maxDepth})`));
10084
+ this.conversation.addMessage({ role: "user", content: task });
10085
+ const tools = this.toolManager.toFunctionDefinitions();
10086
+ const maxIterations = 10;
10087
+ for (let i = 0; i < maxIterations; i++) {
10088
+ const completion = await this.llm.complete({
10089
+ messages: this.conversation.history(),
10090
+ model: this.config.model,
10091
+ temperature: 0.2,
10092
+ tools: tools.length > 0 ? tools : void 0,
10093
+ toolChoice: tools.length > 0 ? "auto" : void 0
10094
+ });
10095
+ const payload = this.parseResponse(completion);
10096
+ if (_optionalChain([completion, 'access', _210 => _210.toolCalls, 'optionalAccess', _211 => _211.length])) {
10097
+ this.conversation.addMessage({
10098
+ role: "assistant",
10099
+ content: completion.content || ""
10100
+ });
10101
+ } else {
10102
+ this.conversation.addMessage({ role: "assistant", content: completion.content });
10103
+ }
10104
+ if (payload.thought) {
10105
+ console.log(_chalk2.default.gray(`[${this.name}] ${payload.thought}`));
10106
+ }
10107
+ if (payload.toolCalls && payload.toolCalls.length > 0) {
10108
+ const results = await this.toolManager.execute(payload.toolCalls);
10109
+ for (let j = 0; j < results.length; j++) {
10110
+ const result = results[j];
10111
+ const toolCall = _optionalChain([completion, 'access', _212 => _212.toolCalls, 'optionalAccess', _213 => _213[j]]);
10112
+ const content = result.success ? _nullishCoalesce(result.output, () => ( "(no output)")) : _nullishCoalesce(result.error, () => ( "Tool failed"));
10113
+ this.conversation.addMessage({
10114
+ role: "tool",
10115
+ name: result.tool,
10116
+ content,
10117
+ tool_call_id: _optionalChain([toolCall, 'optionalAccess', _214 => _214.id])
10118
+ });
10119
+ if (!result.success) {
10120
+ console.log(_chalk2.default.red(`[${this.name}] Tool ${result.tool} failed: ${content}`));
10121
+ }
10122
+ }
10123
+ continue;
10124
+ }
10125
+ const response = _nullishCoalesce(_nullishCoalesce(payload.finalResponse, () => ( payload.response)), () => ( completion.content));
10126
+ console.log(_chalk2.default.cyan(`[${this.name}] Finished.`));
10127
+ return response;
10128
+ }
10129
+ return `[${this.name}] Failed to complete task within ${maxIterations} iterations.`;
10130
+ }
10131
+ /**
10132
+ * Parse LLM response, preferring native tool calls over JSON parsing
10133
+ */
10134
+ parseResponse(completion) {
10135
+ if (completion.toolCalls && completion.toolCalls.length > 0) {
10136
+ return {
10137
+ thought: completion.content || void 0,
10138
+ toolCalls: completion.toolCalls.map((tc) => ({
10139
+ tool: tc.function.name,
10140
+ args: this.safeParseJson(tc.function.arguments)
10141
+ }))
10142
+ };
10143
+ }
10144
+ return this.parsePayload(completion.content);
10145
+ }
10146
+ /**
10147
+ * Safely parse JSON, returning empty object on failure
9066
10148
  */
9067
10149
  safeParseJson(json) {
9068
10150
  try {
9069
10151
  return JSON.parse(json);
9070
- } catch (e36) {
10152
+ } catch (e44) {
9071
10153
  return {};
9072
10154
  }
9073
10155
  }
@@ -9092,7 +10174,7 @@ var SubAgent = class {
9092
10174
  return { finalResponse: contentValue };
9093
10175
  }
9094
10176
  return { finalResponse: raw.trim() };
9095
- } catch (e37) {
10177
+ } catch (e45) {
9096
10178
  return { finalResponse: raw.trim() };
9097
10179
  }
9098
10180
  }
@@ -9293,7 +10375,7 @@ var ErrorLogger = class {
9293
10375
  used: totalMem - freeMem
9294
10376
  },
9295
10377
  cpu: {
9296
- model: _optionalChain([cpus, 'access', _196 => _196[0], 'optionalAccess', _197 => _197.model]) || "Unknown",
10378
+ model: _optionalChain([cpus, 'access', _215 => _215[0], 'optionalAccess', _216 => _216.model]) || "Unknown",
9297
10379
  cores: cpus.length
9298
10380
  },
9299
10381
  hostname: _os2.default.hostname(),
@@ -9309,12 +10391,12 @@ var ErrorLogger = class {
9309
10391
  const entries = content.split("\n---\n").filter((entry) => entry.trim()).map((entry) => {
9310
10392
  try {
9311
10393
  return JSON.parse(entry);
9312
- } catch (e38) {
10394
+ } catch (e46) {
9313
10395
  return null;
9314
10396
  }
9315
10397
  }).filter((entry) => entry !== null);
9316
10398
  return entries.slice(-count);
9317
- } catch (e39) {
10399
+ } catch (e47) {
9318
10400
  return [];
9319
10401
  }
9320
10402
  }
@@ -9338,7 +10420,7 @@ var DEFAULT_CONFIG = {
9338
10420
  timeout: 5e3,
9339
10421
  maxRetries: 3,
9340
10422
  offlineQueue: true,
9341
- cliVersion: _chunkXJZYEURAcjs.package_default.version
10423
+ cliVersion: _chunkJYTXG6OVcjs.package_default.version
9342
10424
  };
9343
10425
  var FeedbackApiClient = class {
9344
10426
  constructor(configOverrides) {
@@ -9360,13 +10442,13 @@ var FeedbackApiClient = class {
9360
10442
  this.deviceId = (await _fsextra2.default.readFile(this.deviceIdPath, "utf8")).trim();
9361
10443
  return this.deviceId;
9362
10444
  }
9363
- } catch (e40) {
10445
+ } catch (e48) {
9364
10446
  }
9365
10447
  this.deviceId = `anon_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
9366
10448
  try {
9367
10449
  await _fsextra2.default.ensureDir(path17.default.dirname(this.deviceIdPath));
9368
10450
  await _fsextra2.default.writeFile(this.deviceIdPath, this.deviceId);
9369
- } catch (e41) {
10451
+ } catch (e49) {
9370
10452
  }
9371
10453
  return this.deviceId;
9372
10454
  }
@@ -9466,7 +10548,7 @@ var FeedbackApiClient = class {
9466
10548
  }
9467
10549
  await _fsextra2.default.ensureDir(path17.default.dirname(this.queuePath));
9468
10550
  await _fsextra2.default.writeJson(this.queuePath, queue, { spaces: 2 });
9469
- } catch (e42) {
10551
+ } catch (e50) {
9470
10552
  }
9471
10553
  }
9472
10554
  /**
@@ -9496,7 +10578,7 @@ var FeedbackApiClient = class {
9496
10578
  remaining.push(item);
9497
10579
  failed++;
9498
10580
  }
9499
- } catch (e43) {
10581
+ } catch (e51) {
9500
10582
  item.attempts++;
9501
10583
  item.lastAttempt = (/* @__PURE__ */ new Date()).toISOString();
9502
10584
  remaining.push(item);
@@ -9508,7 +10590,7 @@ var FeedbackApiClient = class {
9508
10590
  } else {
9509
10591
  await _fsextra2.default.remove(this.queuePath);
9510
10592
  }
9511
- } catch (e44) {
10593
+ } catch (e52) {
9512
10594
  }
9513
10595
  return { sent, failed };
9514
10596
  }
@@ -9523,9 +10605,9 @@ var FeedbackApiClient = class {
9523
10605
  const queue = await _fsextra2.default.readJson(this.queuePath);
9524
10606
  return {
9525
10607
  pending: queue.length,
9526
- oldestItem: _optionalChain([queue, 'access', _198 => _198[0], 'optionalAccess', _199 => _199.lastAttempt]) || null
10608
+ oldestItem: _optionalChain([queue, 'access', _217 => _217[0], 'optionalAccess', _218 => _218.lastAttempt]) || null
9527
10609
  };
9528
- } catch (e45) {
10610
+ } catch (e53) {
9529
10611
  return { pending: 0, oldestItem: null };
9530
10612
  }
9531
10613
  }
@@ -9543,7 +10625,7 @@ var FeedbackApiClient = class {
9543
10625
  });
9544
10626
  clearTimeout(timeoutId);
9545
10627
  return response.ok;
9546
- } catch (e46) {
10628
+ } catch (e54) {
9547
10629
  return false;
9548
10630
  }
9549
10631
  }
@@ -9602,7 +10684,7 @@ var FeedbackManager = class {
9602
10684
  if (_fsextra2.default.existsSync(this.statePath)) {
9603
10685
  return _fsextra2.default.readJsonSync(this.statePath);
9604
10686
  }
9605
- } catch (e47) {
10687
+ } catch (e55) {
9606
10688
  }
9607
10689
  return {
9608
10690
  lastPromptedAt: null,
@@ -9616,11 +10698,13 @@ var FeedbackManager = class {
9616
10698
  };
9617
10699
  }
9618
10700
  saveState() {
9619
- try {
9620
- _fsextra2.default.ensureDirSync(this.stateDir);
9621
- _fsextra2.default.writeJsonSync(this.statePath, this.state, { spaces: 2 });
9622
- } catch (e48) {
9623
- }
10701
+ setImmediate(() => {
10702
+ try {
10703
+ _fsextra2.default.ensureDirSync(this.stateDir);
10704
+ _fsextra2.default.writeJsonSync(this.statePath, this.state, { spaces: 2 });
10705
+ } catch (e56) {
10706
+ }
10707
+ });
9624
10708
  }
9625
10709
  async saveFeedbackResponse(response) {
9626
10710
  try {
@@ -9631,12 +10715,12 @@ var FeedbackManager = class {
9631
10715
  }
9632
10716
  responses.push(response);
9633
10717
  _fsextra2.default.writeJsonSync(this.responsesPath, responses, { spaces: 2 });
9634
- } catch (e49) {
10718
+ } catch (e57) {
9635
10719
  }
9636
10720
  if (this.config.sendToApi) {
9637
10721
  try {
9638
10722
  await this.apiClient.submit(response);
9639
- } catch (e50) {
10723
+ } catch (e58) {
9640
10724
  }
9641
10725
  }
9642
10726
  }
@@ -9733,26 +10817,63 @@ var FeedbackManager = class {
9733
10817
  try {
9734
10818
  return await _enquirer2.default.prompt(config);
9735
10819
  } catch (error) {
9736
- if (_optionalChain([error, 'optionalAccess', _200 => _200.code]) === "ERR_USE_AFTER_CLOSE") {
10820
+ if (_optionalChain([error, 'optionalAccess', _219 => _219.code]) === "ERR_USE_AFTER_CLOSE") {
9737
10821
  return null;
9738
10822
  }
9739
10823
  throw error;
9740
10824
  }
9741
10825
  };
9742
10826
  try {
9743
- const npsResult = await safePrompt({
9744
- type: "select",
10827
+ const { Select } = _enquirer2.default;
10828
+ const ratingChoices = [
10829
+ { name: "5", message: `${_chalk2.default.green("5")} - Excellent` },
10830
+ { name: "4", message: `${_chalk2.default.green("4")} - Good` },
10831
+ { name: "3", message: `${_chalk2.default.yellow("3")} - Okay` },
10832
+ { name: "2", message: `${_chalk2.default.red("2")} - Poor` },
10833
+ { name: "1", message: `${_chalk2.default.red("1")} - Very Poor` },
10834
+ { name: "skip", message: `${_chalk2.default.gray("s")} - Skip` }
10835
+ ];
10836
+ const ratingPrompt = new Select({
9745
10837
  name: "score",
9746
- message: "How would you rate your experience?",
9747
- choices: [
9748
- { name: "5", message: `${_chalk2.default.green("5")} - Excellent` },
9749
- { name: "4", message: `${_chalk2.default.green("4")} - Good` },
9750
- { name: "3", message: `${_chalk2.default.yellow("3")} - Okay` },
9751
- { name: "2", message: `${_chalk2.default.red("2")} - Poor` },
9752
- { name: "1", message: `${_chalk2.default.red("1")} - Very Poor` },
9753
- { name: "skip", message: `${_chalk2.default.gray("Skip")}` }
9754
- ]
10838
+ message: "How would you rate your experience? (press 1-5 or s to skip)",
10839
+ choices: ratingChoices
9755
10840
  });
10841
+ const originalKeypress = ratingPrompt.keypress.bind(ratingPrompt);
10842
+ ratingPrompt.keypress = async function(char, key) {
10843
+ if (char >= "1" && char <= "5") {
10844
+ const targetName = char;
10845
+ const index = ratingChoices.findIndex((c) => c.name === targetName);
10846
+ if (index !== -1) {
10847
+ this.index = index;
10848
+ this.selected = this.choices[index];
10849
+ this.value = this.choices[index].name;
10850
+ await this.render();
10851
+ return this.submit();
10852
+ }
10853
+ }
10854
+ if (char === "s" || char === "S") {
10855
+ const index = ratingChoices.findIndex((c) => c.name === "skip");
10856
+ if (index !== -1) {
10857
+ this.index = index;
10858
+ this.selected = this.choices[index];
10859
+ this.value = this.choices[index].name;
10860
+ await this.render();
10861
+ return this.submit();
10862
+ }
10863
+ }
10864
+ return originalKeypress(char, key);
10865
+ };
10866
+ let npsResult = null;
10867
+ try {
10868
+ const score = await ratingPrompt.run();
10869
+ npsResult = { score };
10870
+ } catch (error) {
10871
+ if (_optionalChain([error, 'optionalAccess', _220 => _220.code]) === "ERR_USE_AFTER_CLOSE") {
10872
+ npsResult = null;
10873
+ } else {
10874
+ throw error;
10875
+ }
10876
+ }
9756
10877
  if (!npsResult) {
9757
10878
  this.state.dismissed++;
9758
10879
  this.saveState();
@@ -9774,7 +10895,7 @@ var FeedbackManager = class {
9774
10895
  name: "reason",
9775
10896
  message: "What do you like most about Autohand? (optional, press Enter to skip)"
9776
10897
  });
9777
- reason = _optionalChain([followUp, 'optionalAccess', _201 => _201.reason]) || void 0;
10898
+ reason = _optionalChain([followUp, 'optionalAccess', _221 => _221.reason]) || void 0;
9778
10899
  if (followUp) {
9779
10900
  const recResult = await safePrompt({
9780
10901
  type: "confirm",
@@ -9782,7 +10903,7 @@ var FeedbackManager = class {
9782
10903
  message: "Would you recommend Autohand to a colleague?",
9783
10904
  initial: true
9784
10905
  });
9785
- recommend = _optionalChain([recResult, 'optionalAccess', _202 => _202.recommend]);
10906
+ recommend = _optionalChain([recResult, 'optionalAccess', _222 => _222.recommend]);
9786
10907
  }
9787
10908
  } else {
9788
10909
  const followUp = await safePrompt({
@@ -9790,7 +10911,7 @@ var FeedbackManager = class {
9790
10911
  name: "improvement",
9791
10912
  message: "What could we do better? (optional, press Enter to skip)"
9792
10913
  });
9793
- improvement = _optionalChain([followUp, 'optionalAccess', _203 => _203.improvement]) || void 0;
10914
+ improvement = _optionalChain([followUp, 'optionalAccess', _223 => _223.improvement]) || void 0;
9794
10915
  }
9795
10916
  const response = {
9796
10917
  npsScore,
@@ -9817,7 +10938,7 @@ var FeedbackManager = class {
9817
10938
  console.log();
9818
10939
  return true;
9819
10940
  } catch (error) {
9820
- if (_optionalChain([error, 'optionalAccess', _204 => _204.code]) === "ERR_USE_AFTER_CLOSE") {
10941
+ if (_optionalChain([error, 'optionalAccess', _224 => _224.code]) === "ERR_USE_AFTER_CLOSE") {
9821
10942
  return false;
9822
10943
  }
9823
10944
  this.state.dismissed++;
@@ -9899,7 +11020,7 @@ var FeedbackManager = class {
9899
11020
  if (_fsextra2.default.existsSync(this.responsesPath)) {
9900
11021
  return _fsextra2.default.readJsonSync(this.responsesPath);
9901
11022
  }
9902
- } catch (e51) {
11023
+ } catch (e59) {
9903
11024
  }
9904
11025
  return [];
9905
11026
  }
@@ -9950,7 +11071,7 @@ var TelemetryClient = class {
9950
11071
  const id = _crypto2.default.randomUUID();
9951
11072
  _fsextra2.default.writeFileSync(DEVICE_ID_FILE, id);
9952
11073
  return id;
9953
- } catch (e52) {
11074
+ } catch (e60) {
9954
11075
  return _crypto2.default.randomUUID();
9955
11076
  }
9956
11077
  }
@@ -9964,7 +11085,7 @@ var TelemetryClient = class {
9964
11085
  const data = _fsextra2.default.readFileSync(QUEUE_FILE, "utf8");
9965
11086
  this.queue = JSON.parse(data);
9966
11087
  }
9967
- } catch (e53) {
11088
+ } catch (e61) {
9968
11089
  this.queue = [];
9969
11090
  }
9970
11091
  }
@@ -9975,7 +11096,7 @@ var TelemetryClient = class {
9975
11096
  try {
9976
11097
  _fsextra2.default.ensureDirSync(TELEMETRY_DIR);
9977
11098
  _fsextra2.default.writeFileSync(QUEUE_FILE, JSON.stringify(this.queue, null, 2));
9978
- } catch (e54) {
11099
+ } catch (e62) {
9979
11100
  }
9980
11101
  }
9981
11102
  /**
@@ -10018,7 +11139,7 @@ var TelemetryClient = class {
10018
11139
  });
10019
11140
  clearTimeout(timeout);
10020
11141
  return response.ok;
10021
- } catch (e55) {
11142
+ } catch (e63) {
10022
11143
  return false;
10023
11144
  }
10024
11145
  }
@@ -10068,7 +11189,7 @@ var TelemetryClient = class {
10068
11189
  headers: {
10069
11190
  "Content-Type": "application/json",
10070
11191
  "Authorization": `Bearer ${authToken}`,
10071
- "X-CLI-Version": _optionalChain([eventsToSend, 'access', _205 => _205[0], 'optionalAccess', _206 => _206.cliVersion]) || "unknown"
11192
+ "X-CLI-Version": _optionalChain([eventsToSend, 'access', _225 => _225[0], 'optionalAccess', _226 => _226.cliVersion]) || "unknown"
10072
11193
  },
10073
11194
  body: JSON.stringify({ events: eventsToSend })
10074
11195
  });
@@ -10080,7 +11201,7 @@ var TelemetryClient = class {
10080
11201
  } else {
10081
11202
  failed = eventsToSend.length;
10082
11203
  }
10083
- } catch (e56) {
11204
+ } catch (e64) {
10084
11205
  failed = eventsToSend.length;
10085
11206
  await new Promise((resolve) => setTimeout(resolve, 1e3 * (attempt + 1)));
10086
11207
  }
@@ -10135,7 +11256,7 @@ var TelemetryClient = class {
10135
11256
  }
10136
11257
  _fsextra2.default.writeFileSync(syncQueueFile, JSON.stringify(syncQueue, null, 2));
10137
11258
  return { success: false, error: "Offline - queued for sync" };
10138
- } catch (e57) {
11259
+ } catch (e65) {
10139
11260
  return { success: false, error: "Failed to queue session" };
10140
11261
  }
10141
11262
  }
@@ -10193,7 +11314,7 @@ var TelemetryClient = class {
10193
11314
  _fsextra2.default.removeSync(syncQueueFile);
10194
11315
  }
10195
11316
  return { synced, failed };
10196
- } catch (e58) {
11317
+ } catch (e66) {
10197
11318
  return { synced: 0, failed: 0 };
10198
11319
  }
10199
11320
  }
@@ -10239,7 +11360,7 @@ var TelemetryManager = class {
10239
11360
  */
10240
11361
  getSystemInfo() {
10241
11362
  return {
10242
- cliVersion: _chunkXJZYEURAcjs.package_default.version,
11363
+ cliVersion: _chunkJYTXG6OVcjs.package_default.version,
10243
11364
  platform: process.platform,
10244
11365
  osVersion: _os2.default.release(),
10245
11366
  nodeVersion: process.version,
@@ -10315,7 +11436,7 @@ var TelemetryManager = class {
10315
11436
  */
10316
11437
  async trackError(data) {
10317
11438
  this.errorsCount++;
10318
- const sanitizedStack = _optionalChain([data, 'access', _207 => _207.stack, 'optionalAccess', _208 => _208.replace, 'call', _209 => _209(/\/Users\/[^/]+/g, "/Users/***"), 'access', _210 => _210.replace, 'call', _211 => _211(/\/home\/[^/]+/g, "/home/***"), 'access', _212 => _212.replace, 'call', _213 => _213(/C:\\Users\\[^\\]+/g, "C:\\Users\\***")]);
11439
+ const sanitizedStack = _optionalChain([data, 'access', _227 => _227.stack, 'optionalAccess', _228 => _228.replace, 'call', _229 => _229(/\/Users\/[^/]+/g, "/Users/***"), 'access', _230 => _230.replace, 'call', _231 => _231(/\/home\/[^/]+/g, "/home/***"), 'access', _232 => _232.replace, 'call', _233 => _233(/C:\\Users\\[^\\]+/g, "C:\\Users\\***")]);
10319
11440
  await this.trackEvent("error", {
10320
11441
  type: data.type,
10321
11442
  message: data.message,
@@ -10329,7 +11450,7 @@ var TelemetryManager = class {
10329
11450
  */
10330
11451
  async trackSessionFailureBug(data) {
10331
11452
  this.errorsCount++;
10332
- const sanitizedStack = _optionalChain([data, 'access', _214 => _214.error, 'access', _215 => _215.stack, 'optionalAccess', _216 => _216.replace, 'call', _217 => _217(/\/Users\/[^/]+/g, "/Users/***"), 'access', _218 => _218.replace, 'call', _219 => _219(/\/home\/[^/]+/g, "/home/***"), 'access', _220 => _220.replace, 'call', _221 => _221(/C:\\Users\\[^\\]+/g, "C:\\Users\\***")]);
11453
+ const sanitizedStack = _optionalChain([data, 'access', _234 => _234.error, 'access', _235 => _235.stack, 'optionalAccess', _236 => _236.replace, 'call', _237 => _237(/\/Users\/[^/]+/g, "/Users/***"), 'access', _238 => _238.replace, 'call', _239 => _239(/\/home\/[^/]+/g, "/home/***"), 'access', _240 => _240.replace, 'call', _241 => _241(/C:\\Users\\[^\\]+/g, "C:\\Users\\***")]);
10333
11454
  const bugData = {
10334
11455
  type: "BUG:session_failure",
10335
11456
  errorMessage: data.error.message,
@@ -10407,10 +11528,10 @@ var TelemetryManager = class {
10407
11528
  metadata: {
10408
11529
  model: this.currentModel || void 0,
10409
11530
  provider: this.currentProvider || void 0,
10410
- totalTokens: _optionalChain([data, 'access', _222 => _222.metadata, 'optionalAccess', _223 => _223.totalTokens]),
10411
- startTime: _optionalChain([this, 'access', _224 => _224.sessionStartTime, 'optionalAccess', _225 => _225.toISOString, 'call', _226 => _226()]),
11531
+ totalTokens: _optionalChain([data, 'access', _242 => _242.metadata, 'optionalAccess', _243 => _243.totalTokens]),
11532
+ startTime: _optionalChain([this, 'access', _244 => _244.sessionStartTime, 'optionalAccess', _245 => _245.toISOString, 'call', _246 => _246()]),
10412
11533
  endTime: (/* @__PURE__ */ new Date()).toISOString(),
10413
- workspaceRoot: _optionalChain([data, 'access', _227 => _227.metadata, 'optionalAccess', _228 => _228.workspaceRoot])
11534
+ workspaceRoot: _optionalChain([data, 'access', _247 => _247.metadata, 'optionalAccess', _248 => _248.workspaceRoot])
10414
11535
  }
10415
11536
  });
10416
11537
  }
@@ -10489,7 +11610,7 @@ var CommunitySkillsClient = class {
10489
11610
  if (_fsextra2.default.existsSync(deviceIdPath)) {
10490
11611
  return _fsextra2.default.readFileSync(deviceIdPath, "utf-8").trim();
10491
11612
  }
10492
- } catch (e59) {
11613
+ } catch (e67) {
10493
11614
  }
10494
11615
  return `anon_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
10495
11616
  }
@@ -10504,7 +11625,7 @@ var CommunitySkillsClient = class {
10504
11625
  if (_fsextra2.default.existsSync(queuePath)) {
10505
11626
  this.queue = _fsextra2.default.readJsonSync(queuePath);
10506
11627
  }
10507
- } catch (e60) {
11628
+ } catch (e68) {
10508
11629
  this.queue = [];
10509
11630
  }
10510
11631
  }
@@ -10515,7 +11636,7 @@ var CommunitySkillsClient = class {
10515
11636
  try {
10516
11637
  _fsextra2.default.ensureDirSync(this.queueDir);
10517
11638
  _fsextra2.default.writeJsonSync(path17.default.join(this.queueDir, "queue.json"), this.queue);
10518
- } catch (e61) {
11639
+ } catch (e69) {
10519
11640
  }
10520
11641
  }
10521
11642
  /**
@@ -10573,34 +11694,34 @@ var CommunitySkillsClient = class {
10573
11694
  */
10574
11695
  async listSkills(filters) {
10575
11696
  const params = new URLSearchParams();
10576
- if (_optionalChain([filters, 'optionalAccess', _229 => _229.languages, 'optionalAccess', _230 => _230.length])) {
11697
+ if (_optionalChain([filters, 'optionalAccess', _249 => _249.languages, 'optionalAccess', _250 => _250.length])) {
10577
11698
  params.set("languages", filters.languages.join(","));
10578
11699
  }
10579
- if (_optionalChain([filters, 'optionalAccess', _231 => _231.frameworks, 'optionalAccess', _232 => _232.length])) {
11700
+ if (_optionalChain([filters, 'optionalAccess', _251 => _251.frameworks, 'optionalAccess', _252 => _252.length])) {
10580
11701
  params.set("frameworks", filters.frameworks.join(","));
10581
11702
  }
10582
- if (_optionalChain([filters, 'optionalAccess', _233 => _233.patterns, 'optionalAccess', _234 => _234.length])) {
11703
+ if (_optionalChain([filters, 'optionalAccess', _253 => _253.patterns, 'optionalAccess', _254 => _254.length])) {
10583
11704
  params.set("patterns", filters.patterns.join(","));
10584
11705
  }
10585
- if (_optionalChain([filters, 'optionalAccess', _235 => _235.search])) {
11706
+ if (_optionalChain([filters, 'optionalAccess', _255 => _255.search])) {
10586
11707
  params.set("search", filters.search);
10587
11708
  }
10588
- if (_optionalChain([filters, 'optionalAccess', _236 => _236.curated])) {
11709
+ if (_optionalChain([filters, 'optionalAccess', _256 => _256.curated])) {
10589
11710
  params.set("curated", "true");
10590
11711
  }
10591
- if (_optionalChain([filters, 'optionalAccess', _237 => _237.featured])) {
11712
+ if (_optionalChain([filters, 'optionalAccess', _257 => _257.featured])) {
10592
11713
  params.set("featured", "true");
10593
11714
  }
10594
- if (_optionalChain([filters, 'optionalAccess', _238 => _238.limit])) {
11715
+ if (_optionalChain([filters, 'optionalAccess', _258 => _258.limit])) {
10595
11716
  params.set("limit", String(filters.limit));
10596
11717
  }
10597
- if (_optionalChain([filters, 'optionalAccess', _239 => _239.offset])) {
11718
+ if (_optionalChain([filters, 'optionalAccess', _259 => _259.offset])) {
10598
11719
  params.set("offset", String(filters.offset));
10599
11720
  }
10600
11721
  const query = params.toString();
10601
11722
  const endpoint = `/v1/community-skills${query ? `?${query}` : ""}`;
10602
11723
  const result = await this.request(endpoint);
10603
- return result.ok ? _optionalChain([result, 'access', _240 => _240.data, 'optionalAccess', _241 => _241.skills]) || [] : [];
11724
+ return result.ok ? _optionalChain([result, 'access', _260 => _260.data, 'optionalAccess', _261 => _261.skills]) || [] : [];
10604
11725
  }
10605
11726
  /**
10606
11727
  * Download a skill by name
@@ -10609,7 +11730,7 @@ var CommunitySkillsClient = class {
10609
11730
  const result = await this.request(
10610
11731
  `/v1/community-skills/${encodeURIComponent(name)}/download`
10611
11732
  );
10612
- if (result.ok && _optionalChain([result, 'access', _242 => _242.data, 'optionalAccess', _243 => _243.skill])) {
11733
+ if (result.ok && _optionalChain([result, 'access', _262 => _262.data, 'optionalAccess', _263 => _263.skill])) {
10613
11734
  return { success: true, skill: result.data.skill };
10614
11735
  }
10615
11736
  return { success: false, error: result.error || "Failed to download skill" };
@@ -10631,7 +11752,7 @@ var CommunitySkillsClient = class {
10631
11752
  const query = params.toString();
10632
11753
  const endpoint = `/v1/community-skills/suggestions${query ? `?${query}` : ""}`;
10633
11754
  const result = await this.request(endpoint);
10634
- return result.ok ? _optionalChain([result, 'access', _244 => _244.data, 'optionalAccess', _245 => _245.suggestions]) || [] : [];
11755
+ return result.ok ? _optionalChain([result, 'access', _264 => _264.data, 'optionalAccess', _265 => _265.suggestions]) || [] : [];
10635
11756
  }
10636
11757
  /**
10637
11758
  * Submit a skill for community review
@@ -10641,17 +11762,17 @@ var CommunitySkillsClient = class {
10641
11762
  method: "POST",
10642
11763
  body: JSON.stringify(skill)
10643
11764
  });
10644
- if (result.ok && _optionalChain([result, 'access', _246 => _246.data, 'optionalAccess', _247 => _247.success])) {
11765
+ if (result.ok && _optionalChain([result, 'access', _266 => _266.data, 'optionalAccess', _267 => _267.success])) {
10645
11766
  return {
10646
11767
  success: true,
10647
11768
  id: result.data.id,
10648
11769
  pending: result.data.pending
10649
11770
  };
10650
11771
  }
10651
- if (!result.ok && _optionalChain([result, 'access', _248 => _248.error, 'optionalAccess', _249 => _249.includes, 'call', _250 => _250("fetch")])) {
11772
+ if (!result.ok && _optionalChain([result, 'access', _268 => _268.error, 'optionalAccess', _269 => _269.includes, 'call', _270 => _270("fetch")])) {
10652
11773
  this.addToQueue("submit", skill);
10653
11774
  }
10654
- return { success: false, error: result.error || _optionalChain([result, 'access', _251 => _251.data, 'optionalAccess', _252 => _252.error]) };
11775
+ return { success: false, error: result.error || _optionalChain([result, 'access', _271 => _271.data, 'optionalAccess', _272 => _272.error]) };
10655
11776
  }
10656
11777
  // ============ Backup Operations ============
10657
11778
  /**
@@ -10668,7 +11789,7 @@ var CommunitySkillsClient = class {
10668
11789
  })
10669
11790
  }
10670
11791
  );
10671
- if (result.ok && _optionalChain([result, 'access', _253 => _253.data, 'optionalAccess', _254 => _254.backed])) {
11792
+ if (result.ok && _optionalChain([result, 'access', _273 => _273.data, 'optionalAccess', _274 => _274.backed])) {
10672
11793
  return true;
10673
11794
  }
10674
11795
  this.addToQueue("backup", skill);
@@ -10690,8 +11811,8 @@ var CommunitySkillsClient = class {
10690
11811
  });
10691
11812
  if (result.ok) {
10692
11813
  return {
10693
- backed: _optionalChain([result, 'access', _255 => _255.data, 'optionalAccess', _256 => _256.backed]) || 0,
10694
- failed: _optionalChain([result, 'access', _257 => _257.data, 'optionalAccess', _258 => _258.skipped]) || 0
11814
+ backed: _optionalChain([result, 'access', _275 => _275.data, 'optionalAccess', _276 => _276.backed]) || 0,
11815
+ failed: _optionalChain([result, 'access', _277 => _277.data, 'optionalAccess', _278 => _278.skipped]) || 0
10695
11816
  };
10696
11817
  }
10697
11818
  for (const skill of skills) {
@@ -10706,7 +11827,7 @@ var CommunitySkillsClient = class {
10706
11827
  const result = await this.request(
10707
11828
  `/v1/skills-backup/${encodeURIComponent(this.deviceId)}`
10708
11829
  );
10709
- return result.ok ? _optionalChain([result, 'access', _259 => _259.data, 'optionalAccess', _260 => _260.backups]) || [] : [];
11830
+ return result.ok ? _optionalChain([result, 'access', _279 => _279.data, 'optionalAccess', _280 => _280.backups]) || [] : [];
10710
11831
  }
10711
11832
  /**
10712
11833
  * Restore skills from backup
@@ -10764,7 +11885,7 @@ var CommunitySkillsClient = class {
10764
11885
  })
10765
11886
  }
10766
11887
  );
10767
- success = result.ok && (_optionalChain([result, 'access', _261 => _261.data, 'optionalAccess', _262 => _262.backed]) || 0) > 0;
11888
+ success = result.ok && (_optionalChain([result, 'access', _281 => _281.data, 'optionalAccess', _282 => _282.backed]) || 0) > 0;
10768
11889
  } else if (op.type === "submit") {
10769
11890
  const result = await this.request(
10770
11891
  "/v1/community-skills",
@@ -10773,7 +11894,7 @@ var CommunitySkillsClient = class {
10773
11894
  body: JSON.stringify(op.payload)
10774
11895
  }
10775
11896
  );
10776
- success = result.ok && _optionalChain([result, 'access', _263 => _263.data, 'optionalAccess', _264 => _264.success]) === true;
11897
+ success = result.ok && _optionalChain([result, 'access', _283 => _283.data, 'optionalAccess', _284 => _284.success]) === true;
10777
11898
  }
10778
11899
  if (success) {
10779
11900
  sent++;
@@ -10797,7 +11918,6 @@ var CommunitySkillsClient = class {
10797
11918
 
10798
11919
  // src/ui/persistentInput.ts
10799
11920
 
10800
-
10801
11921
  var _events = require('events'); var _events2 = _interopRequireDefault(_events);
10802
11922
 
10803
11923
  // src/ui/terminalRegions.ts
@@ -10961,7 +12081,7 @@ var PersistentInput = class extends _events2.default {
10961
12081
  if (!this.isActive || this.isPaused) {
10962
12082
  return;
10963
12083
  }
10964
- if (_optionalChain([key, 'optionalAccess', _265 => _265.name]) === "return" || _optionalChain([key, 'optionalAccess', _266 => _266.name]) === "enter") {
12084
+ if (_optionalChain([key, 'optionalAccess', _285 => _285.name]) === "return" || _optionalChain([key, 'optionalAccess', _286 => _286.name]) === "enter") {
10965
12085
  if (this.currentInput.trim()) {
10966
12086
  this.addToQueue(this.currentInput.trim());
10967
12087
  this.currentInput = "";
@@ -10971,7 +12091,7 @@ var PersistentInput = class extends _events2.default {
10971
12091
  }
10972
12092
  return;
10973
12093
  }
10974
- if (_optionalChain([key, 'optionalAccess', _267 => _267.name]) === "backspace") {
12094
+ if (_optionalChain([key, 'optionalAccess', _287 => _287.name]) === "backspace") {
10975
12095
  if (this.currentInput.length > 0) {
10976
12096
  this.currentInput = this.currentInput.slice(0, -1);
10977
12097
  if (!this.silentMode) {
@@ -10980,15 +12100,15 @@ var PersistentInput = class extends _events2.default {
10980
12100
  }
10981
12101
  return;
10982
12102
  }
10983
- if (_optionalChain([key, 'optionalAccess', _268 => _268.name]) === "escape") {
12103
+ if (_optionalChain([key, 'optionalAccess', _288 => _288.name]) === "escape") {
10984
12104
  this.emit("escape");
10985
12105
  return;
10986
12106
  }
10987
- if (_optionalChain([key, 'optionalAccess', _269 => _269.name]) === "c" && key.ctrl) {
12107
+ if (_optionalChain([key, 'optionalAccess', _289 => _289.name]) === "c" && key.ctrl) {
10988
12108
  this.emit("ctrl-c");
10989
12109
  return;
10990
12110
  }
10991
- if (_optionalChain([key, 'optionalAccess', _270 => _270.ctrl]) || _optionalChain([key, 'optionalAccess', _271 => _271.meta])) {
12111
+ if (_optionalChain([key, 'optionalAccess', _290 => _290.ctrl]) || _optionalChain([key, 'optionalAccess', _291 => _291.meta])) {
10992
12112
  return;
10993
12113
  }
10994
12114
  if (_str) {
@@ -11019,7 +12139,7 @@ var PersistentInput = class extends _events2.default {
11019
12139
  this.currentInput = "";
11020
12140
  this.isPaused = false;
11021
12141
  if (this.silentMode) {
11022
- _readline2.default.emitKeypressEvents(this.input);
12142
+ safeEmitKeypressEvents(this.input);
11023
12143
  const supportsRaw = typeof this.input.setRawMode === "function";
11024
12144
  const wasRaw = this.input.isRaw;
11025
12145
  if (!wasRaw && supportsRaw) {
@@ -11030,7 +12150,7 @@ var PersistentInput = class extends _events2.default {
11030
12150
  this.input.on("keypress", this.handleKeypress);
11031
12151
  } else {
11032
12152
  this.regions.enable();
11033
- _readline2.default.emitKeypressEvents(this.input);
12153
+ safeEmitKeypressEvents(this.input);
11034
12154
  const supportsRaw = typeof this.input.setRawMode === "function";
11035
12155
  if (supportsRaw) {
11036
12156
  this.input.setRawMode(true);
@@ -11218,7 +12338,7 @@ function formatToolOutputForDisplay(options) {
11218
12338
  const { tool, content, charLimit, filePath, command, commandArgs } = options;
11219
12339
  const totalChars = content.length;
11220
12340
  if (tool === "run_command" && command) {
11221
- const fullCommand = _optionalChain([commandArgs, 'optionalAccess', _272 => _272.length]) ? `${command} ${commandArgs.join(" ")}` : command;
12341
+ const fullCommand = _optionalChain([commandArgs, 'optionalAccess', _292 => _292.length]) ? `${command} ${commandArgs.join(" ")}` : command;
11222
12342
  const outputLines = content ? content.split("\n").length : 0;
11223
12343
  const truncatedContent = charLimit > 0 && totalChars > charLimit ? `${content.slice(0, charLimit)}
11224
12344
  ... (${totalChars} chars)` : content;
@@ -11334,24 +12454,30 @@ async function confirm(message, context) {
11334
12454
  initial: 0
11335
12455
  });
11336
12456
  const originalKeypress = prompt.keypress.bind(prompt);
11337
- prompt.keypress = function(char, key) {
12457
+ prompt.keypress = async function(char, key) {
11338
12458
  if (char === "1" || char === "2" || char === "3") {
11339
12459
  const index = parseInt(char, 10) - 1;
11340
12460
  if (index >= 0 && index < choices.length) {
11341
12461
  this.index = index;
11342
- this.submit();
11343
- return;
12462
+ this.selected = this.choices[index];
12463
+ this.value = this.choices[index].name;
12464
+ await this.render();
12465
+ return this.submit();
11344
12466
  }
11345
12467
  }
11346
12468
  if (char === "y" || char === "Y") {
11347
12469
  this.index = 0;
11348
- this.submit();
11349
- return;
12470
+ this.selected = this.choices[0];
12471
+ this.value = this.choices[0].name;
12472
+ await this.render();
12473
+ return this.submit();
11350
12474
  }
11351
12475
  if (char === "n" || char === "N") {
11352
12476
  this.index = 1;
11353
- this.submit();
11354
- return;
12477
+ this.selected = this.choices[1];
12478
+ this.value = this.choices[1].name;
12479
+ await this.render();
12480
+ return this.submit();
11355
12481
  }
11356
12482
  return originalKeypress(char, key);
11357
12483
  };
@@ -11366,14 +12492,14 @@ async function confirm(message, context) {
11366
12492
  message: "Enter alternative action (or empty to cancel)"
11367
12493
  });
11368
12494
  const altAnswer = await inputPrompt.run();
11369
- if (_optionalChain([altAnswer, 'optionalAccess', _273 => _273.trim, 'call', _274 => _274()])) {
12495
+ if (_optionalChain([altAnswer, 'optionalAccess', _293 => _293.trim, 'call', _294 => _294()])) {
11370
12496
  confirm.lastAlternative = altAnswer.trim();
11371
12497
  return "alternative";
11372
12498
  }
11373
12499
  return false;
11374
12500
  }
11375
12501
  return false;
11376
- } catch (e62) {
12502
+ } catch (e70) {
11377
12503
  return false;
11378
12504
  }
11379
12505
  }
@@ -11704,12 +12830,12 @@ var EnvironmentBootstrap = class {
11704
12830
  * @returns Bootstrap result with all steps
11705
12831
  */
11706
12832
  async run(workspaceRoot, options) {
11707
- if (!_optionalChain([options, 'optionalAccess', _275 => _275.force]) && this.isCacheValid()) {
12833
+ if (!_optionalChain([options, 'optionalAccess', _295 => _295.force]) && this.isCacheValid()) {
11708
12834
  return this.lastResult;
11709
12835
  }
11710
12836
  const startTime = Date.now();
11711
12837
  const steps = [];
11712
- if (!_optionalChain([options, 'optionalAccess', _276 => _276.skipGitSync])) {
12838
+ if (!_optionalChain([options, 'optionalAccess', _296 => _296.skipGitSync])) {
11713
12839
  steps.push(await this.gitSync(workspaceRoot));
11714
12840
  }
11715
12841
  const pm = await this.detectPackageManager(workspaceRoot);
@@ -11720,7 +12846,7 @@ var EnvironmentBootstrap = class {
11720
12846
  detail: `Detected: ${pm}`
11721
12847
  });
11722
12848
  }
11723
- if (pm && !_optionalChain([options, 'optionalAccess', _277 => _277.skipInstall])) {
12849
+ if (pm && !_optionalChain([options, 'optionalAccess', _297 => _297.skipInstall])) {
11724
12850
  steps.push(await this.installDependencies(workspaceRoot, pm));
11725
12851
  }
11726
12852
  steps.push(await this.validateToolchain(workspaceRoot));
@@ -11756,7 +12882,7 @@ var EnvironmentBootstrap = class {
11756
12882
  }
11757
12883
  }
11758
12884
  return "npm";
11759
- } catch (e63) {
12885
+ } catch (e71) {
11760
12886
  return null;
11761
12887
  }
11762
12888
  }
@@ -11794,7 +12920,7 @@ var EnvironmentBootstrap = class {
11794
12920
  try {
11795
12921
  await execAsync("git pull --ff-only", { cwd: root, timeout: 6e4 });
11796
12922
  step.detail = "Pulled latest changes";
11797
- } catch (e64) {
12923
+ } catch (e72) {
11798
12924
  step.detail = "Behind remote (pull failed, may need manual merge)";
11799
12925
  }
11800
12926
  } else if (statusOutput.includes("Your branch is ahead")) {
@@ -11979,28 +13105,28 @@ var CodeQualityPipeline = class {
11979
13105
  const startTime = Date.now();
11980
13106
  const scripts = await this.detectScripts(workspaceRoot);
11981
13107
  const checks = [];
11982
- if (_optionalChain([options, 'optionalAccess', _278 => _278.autoFix]) && scripts.lint) {
13108
+ if (_optionalChain([options, 'optionalAccess', _298 => _298.autoFix]) && scripts.lint) {
11983
13109
  await this.runAutoFix(workspaceRoot, scripts.lint);
11984
13110
  }
11985
13111
  const parallelChecks = [];
11986
- if (scripts.lint && !_optionalChain([options, 'optionalAccess', _279 => _279.skipLint])) {
13112
+ if (scripts.lint && !_optionalChain([options, 'optionalAccess', _299 => _299.skipLint])) {
11987
13113
  parallelChecks.push(this.runCheck(workspaceRoot, "lint", "Lint", scripts.lint));
11988
13114
  }
11989
- if (scripts.typecheck && !_optionalChain([options, 'optionalAccess', _280 => _280.skipTypecheck])) {
13115
+ if (scripts.typecheck && !_optionalChain([options, 'optionalAccess', _300 => _300.skipTypecheck])) {
11990
13116
  parallelChecks.push(this.runCheck(workspaceRoot, "typecheck", "Types", scripts.typecheck));
11991
13117
  }
11992
13118
  if (parallelChecks.length > 0) {
11993
13119
  const parallelResults = await Promise.all(parallelChecks);
11994
13120
  checks.push(...parallelResults);
11995
13121
  }
11996
- if (scripts.test && !_optionalChain([options, 'optionalAccess', _281 => _281.skipTest])) {
13122
+ if (scripts.test && !_optionalChain([options, 'optionalAccess', _301 => _301.skipTest])) {
11997
13123
  let testCmd = scripts.test;
11998
- if (_optionalChain([options, 'optionalAccess', _282 => _282.testFilter])) {
13124
+ if (_optionalChain([options, 'optionalAccess', _302 => _302.testFilter])) {
11999
13125
  testCmd = `${scripts.test} --grep "${options.testFilter}"`;
12000
13126
  }
12001
13127
  checks.push(await this.runCheck(workspaceRoot, "test", "Tests", testCmd));
12002
13128
  }
12003
- if (scripts.build && !_optionalChain([options, 'optionalAccess', _283 => _283.skipBuild])) {
13129
+ if (scripts.build && !_optionalChain([options, 'optionalAccess', _303 => _303.skipBuild])) {
12004
13130
  checks.push(await this.runCheck(workspaceRoot, "build", "Build", scripts.build));
12005
13131
  }
12006
13132
  const passed = checks.every((c) => c.status === "passed" || c.status === "skipped");
@@ -12030,7 +13156,7 @@ var CodeQualityPipeline = class {
12030
13156
  test: this.findScript(scripts, this.scriptPatterns.test),
12031
13157
  build: this.findScript(scripts, this.scriptPatterns.build)
12032
13158
  };
12033
- } catch (e65) {
13159
+ } catch (e73) {
12034
13160
  return {};
12035
13161
  }
12036
13162
  }
@@ -12095,7 +13221,7 @@ var CodeQualityPipeline = class {
12095
13221
  try {
12096
13222
  await execAsync2(`npm run ${fixScript}`, { cwd: root, timeout: 6e4 });
12097
13223
  return;
12098
- } catch (e66) {
13224
+ } catch (e74) {
12099
13225
  }
12100
13226
  }
12101
13227
  }
@@ -12184,7 +13310,7 @@ var CodeQualityPipeline = class {
12184
13310
  };
12185
13311
 
12186
13312
  // src/core/agent.ts
12187
- var AutohandAgent = class {
13313
+ var AutohandAgent = class _AutohandAgent {
12188
13314
  constructor(llm, files, runtime) {
12189
13315
  this.llm = llm;
12190
13316
  this.files = files;
@@ -12193,6 +13319,8 @@ var AutohandAgent = class {
12193
13319
  this.contextPercentLeft = 100;
12194
13320
  this.toolOutputQueue = Promise.resolve();
12195
13321
  this.workspaceFiles = [];
13322
+ this.workspaceFilesCachedAt = 0;
13323
+ // 5 seconds
12196
13324
  this.isInstructionActive = false;
12197
13325
  this.hasPrintedExplorationHeader = false;
12198
13326
  this.taskStartedAt = null;
@@ -12211,7 +13339,7 @@ var AutohandAgent = class {
12211
13339
  this.sessionRetryCount = 0;
12212
13340
  const initialProvider = _nullishCoalesce(runtime.config.provider, () => ( "openrouter"));
12213
13341
  const providerSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, runtime.config, initialProvider);
12214
- const model = _nullishCoalesce(_nullishCoalesce(runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _284 => _284.model]))), () => ( "unconfigured"));
13342
+ const model = _nullishCoalesce(_nullishCoalesce(runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _304 => _304.model]))), () => ( "unconfigured"));
12215
13343
  this.contextWindow = getContextWindow(model);
12216
13344
  this.ignoreFilter = new GitIgnoreParser(runtime.workspaceRoot, []);
12217
13345
  this.conversation = ConversationManager.getInstance();
@@ -12255,7 +13383,7 @@ var AutohandAgent = class {
12255
13383
  onExploration: (entry) => this.recordExploration(entry),
12256
13384
  onToolOutput: (chunk) => this.handleToolOutput(chunk),
12257
13385
  toolsRegistry: this.toolsRegistry,
12258
- getRegisteredTools: () => _nullishCoalesce(_optionalChain([this, 'access', _285 => _285.toolManager, 'optionalAccess', _286 => _286.listDefinitions, 'call', _287 => _287()]), () => ( [])),
13386
+ getRegisteredTools: () => _nullishCoalesce(_optionalChain([this, 'access', _305 => _305.toolManager, 'optionalAccess', _306 => _306.listDefinitions, 'call', _307 => _307()]), () => ( [])),
12259
13387
  memoryManager: this.memoryManager,
12260
13388
  permissionManager: this.permissionManager,
12261
13389
  onFileModified: () => this.markFilesModified(),
@@ -12267,7 +13395,7 @@ var AutohandAgent = class {
12267
13395
  permissionType: "tool_approval"
12268
13396
  });
12269
13397
  for (const result of results) {
12270
- if (_optionalChain([result, 'access', _288 => _288.response, 'optionalAccess', _289 => _289.decision])) {
13398
+ if (_optionalChain([result, 'access', _308 => _308.response, 'optionalAccess', _309 => _309.decision])) {
12271
13399
  return {
12272
13400
  decision: result.response.decision,
12273
13401
  reason: result.response.reason,
@@ -12294,20 +13422,20 @@ var AutohandAgent = class {
12294
13422
  });
12295
13423
  }
12296
13424
  });
12297
- this.errorLogger = new ErrorLogger(_chunkXJZYEURAcjs.package_default.version);
13425
+ this.errorLogger = new ErrorLogger(_chunkJYTXG6OVcjs.package_default.version);
12298
13426
  this.feedbackManager = new FeedbackManager({
12299
- apiBaseUrl: _optionalChain([runtime, 'access', _290 => _290.config, 'access', _291 => _291.api, 'optionalAccess', _292 => _292.baseUrl]) || "https://api.autohand.ai",
12300
- cliVersion: _chunkXJZYEURAcjs.package_default.version
13427
+ apiBaseUrl: _optionalChain([runtime, 'access', _310 => _310.config, 'access', _311 => _311.api, 'optionalAccess', _312 => _312.baseUrl]) || "https://api.autohand.ai",
13428
+ cliVersion: _chunkJYTXG6OVcjs.package_default.version
12301
13429
  });
12302
13430
  this.skillsRegistry = new (0, _chunkCVYEUA3Dcjs.SkillsRegistry)(_chunkXTHHDIBGcjs.AUTOHAND_PATHS.skills);
12303
13431
  this.telemetryManager = new TelemetryManager({
12304
- enabled: _optionalChain([runtime, 'access', _293 => _293.config, 'access', _294 => _294.telemetry, 'optionalAccess', _295 => _295.enabled]) === true,
12305
- apiBaseUrl: _optionalChain([runtime, 'access', _296 => _296.config, 'access', _297 => _297.telemetry, 'optionalAccess', _298 => _298.apiBaseUrl]) || "https://api.autohand.ai",
12306
- enableSessionSync: _optionalChain([runtime, 'access', _299 => _299.config, 'access', _300 => _300.telemetry, 'optionalAccess', _301 => _301.enableSessionSync]) === true
13432
+ enabled: _optionalChain([runtime, 'access', _313 => _313.config, 'access', _314 => _314.telemetry, 'optionalAccess', _315 => _315.enabled]) === true,
13433
+ apiBaseUrl: _optionalChain([runtime, 'access', _316 => _316.config, 'access', _317 => _317.telemetry, 'optionalAccess', _318 => _318.apiBaseUrl]) || "https://api.autohand.ai",
13434
+ enableSessionSync: _optionalChain([runtime, 'access', _319 => _319.config, 'access', _320 => _320.telemetry, 'optionalAccess', _321 => _321.enableSessionSync]) === true
12307
13435
  });
12308
13436
  const communitySettings = _nullishCoalesce(runtime.config.communitySkills, () => ( {}));
12309
13437
  this.communityClient = new CommunitySkillsClient({
12310
- apiBaseUrl: _optionalChain([runtime, 'access', _302 => _302.config, 'access', _303 => _303.api, 'optionalAccess', _304 => _304.baseUrl]) || "https://api.autohand.ai",
13438
+ apiBaseUrl: _optionalChain([runtime, 'access', _322 => _322.config, 'access', _323 => _323.api, 'optionalAccess', _324 => _324.baseUrl]) || "https://api.autohand.ai",
12311
13439
  enabled: communitySettings.enabled !== false
12312
13440
  });
12313
13441
  this.skillsRegistry.setTelemetryManager(this.telemetryManager);
@@ -12399,9 +13527,9 @@ var AutohandAgent = class {
12399
13527
  definitions: [...DEFAULT_TOOL_DEFINITIONS, ...delegationTools],
12400
13528
  clientContext
12401
13529
  });
12402
- this.sessionManager = new (0, _chunkUPR5PKX4cjs.SessionManager)();
13530
+ this.sessionManager = new (0, _chunk67NJKV5Acjs.SessionManager)();
12403
13531
  this.projectManager = new ProjectManager();
12404
- this.useInkRenderer = _optionalChain([runtime, 'access', _305 => _305.config, 'access', _306 => _306.ui, 'optionalAccess', _307 => _307.useInkRenderer]) === true;
13532
+ this.useInkRenderer = _optionalChain([runtime, 'access', _325 => _325.config, 'access', _326 => _326.ui, 'optionalAccess', _327 => _327.useInkRenderer]) === true;
12405
13533
  this.persistentInput = createPersistentInput({
12406
13534
  maxQueueSize: 10,
12407
13535
  silentMode: true
@@ -12420,7 +13548,8 @@ var AutohandAgent = class {
12420
13548
  }, 1500);
12421
13549
  }
12422
13550
  });
12423
- this.slashHandler = new SlashCommandHandler({
13551
+ const sessionMgr = this.sessionManager;
13552
+ const slashContext = {
12424
13553
  promptModelSelection: () => this.promptModelSelection(),
12425
13554
  createAgentsFile: () => this.createAgentsFile(),
12426
13555
  sessionManager: this.sessionManager,
@@ -12438,8 +13567,16 @@ var AutohandAgent = class {
12438
13567
  provider: this.activeProvider,
12439
13568
  config: runtime.config,
12440
13569
  getContextPercentLeft: () => this.contextPercentLeft,
12441
- getTotalTokensUsed: () => this.totalTokensUsed
12442
- }, SLASH_COMMANDS);
13570
+ getTotalTokensUsed: () => this.totalTokensUsed,
13571
+ // Share command needs current session - use getter for dynamic access
13572
+ get currentSession() {
13573
+ return _nullishCoalesce(sessionMgr.getCurrentSession(), () => ( void 0));
13574
+ }
13575
+ };
13576
+ this.slashHandler = new SlashCommandHandler(slashContext, SLASH_COMMANDS);
13577
+ }
13578
+ static {
13579
+ this.WORKSPACE_FILES_CACHE_TTL = 5e3;
12443
13580
  }
12444
13581
  async runInteractive() {
12445
13582
  await this.sessionManager.initialize();
@@ -12451,7 +13588,7 @@ var AutohandAgent = class {
12451
13588
  await this.resetConversationContext();
12452
13589
  this.feedbackManager.startSession();
12453
13590
  const providerSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider);
12454
- const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _308 => _308.model]))), () => ( "unconfigured"));
13591
+ const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _328 => _328.model]))), () => ( "unconfigured"));
12455
13592
  await this.sessionManager.createSession(this.runtime.workspaceRoot, model);
12456
13593
  const session = this.sessionManager.getCurrentSession();
12457
13594
  if (session) {
@@ -12462,7 +13599,7 @@ var AutohandAgent = class {
12462
13599
  );
12463
13600
  }
12464
13601
  await this.hookManager.executeHooks("session-start", {
12465
- sessionId: _optionalChain([session, 'optionalAccess', _309 => _309.metadata, 'access', _310 => _310.sessionId]),
13602
+ sessionId: _optionalChain([session, 'optionalAccess', _329 => _329.metadata, 'access', _330 => _330.sessionId]),
12466
13603
  sessionType: "startup"
12467
13604
  });
12468
13605
  await this.runInteractiveLoop();
@@ -12479,7 +13616,7 @@ var AutohandAgent = class {
12479
13616
  await this.hookManager.initialize();
12480
13617
  await this.resetConversationContext();
12481
13618
  const providerSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider);
12482
- const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _311 => _311.model]))), () => ( "unconfigured"));
13619
+ const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _331 => _331.model]))), () => ( "unconfigured"));
12483
13620
  await this.sessionManager.createSession(this.runtime.workspaceRoot, model);
12484
13621
  const session = this.sessionManager.getCurrentSession();
12485
13622
  if (session) {
@@ -12490,7 +13627,7 @@ var AutohandAgent = class {
12490
13627
  );
12491
13628
  }
12492
13629
  await this.hookManager.executeHooks("session-start", {
12493
- sessionId: _optionalChain([session, 'optionalAccess', _312 => _312.metadata, 'access', _313 => _313.sessionId]),
13630
+ sessionId: _optionalChain([session, 'optionalAccess', _332 => _332.metadata, 'access', _333 => _333.sessionId]),
12494
13631
  sessionType: "startup"
12495
13632
  });
12496
13633
  }
@@ -12501,21 +13638,23 @@ var AutohandAgent = class {
12501
13638
  const turnDuration = Date.now() - turnStartTime;
12502
13639
  const session = this.sessionManager.getCurrentSession();
12503
13640
  await this.hookManager.executeHooks("stop", {
12504
- sessionId: _optionalChain([session, 'optionalAccess', _314 => _314.metadata, 'access', _315 => _315.sessionId]),
13641
+ sessionId: _optionalChain([session, 'optionalAccess', _334 => _334.metadata, 'access', _335 => _335.sessionId]),
12505
13642
  turnDuration,
12506
13643
  tokensUsed: this.sessionTokensUsed
12507
13644
  });
12508
- if (_optionalChain([this, 'access', _316 => _316.runtime, 'access', _317 => _317.config, 'access', _318 => _318.ui, 'optionalAccess', _319 => _319.terminalBell]) !== false) {
13645
+ this.ensureStdinReady();
13646
+ if (_optionalChain([this, 'access', _336 => _336.runtime, 'access', _337 => _337.config, 'access', _338 => _338.ui, 'optionalAccess', _339 => _339.terminalBell]) !== false) {
12509
13647
  process.stdout.write("\x07");
12510
13648
  }
12511
13649
  if (this.runtime.options.autoCommit) {
12512
13650
  await this.performAutoCommit();
12513
13651
  }
12514
13652
  await this.hookManager.executeHooks("session-end", {
12515
- sessionId: _optionalChain([session, 'optionalAccess', _320 => _320.metadata, 'access', _321 => _321.sessionId]),
13653
+ sessionId: _optionalChain([session, 'optionalAccess', _340 => _340.metadata, 'access', _341 => _341.sessionId]),
12516
13654
  sessionEndReason: "exit",
12517
13655
  duration: Date.now() - this.sessionStartedAt
12518
13656
  });
13657
+ this.ensureStdinReady();
12519
13658
  await this.telemetryManager.endSession("completed");
12520
13659
  }
12521
13660
  /**
@@ -12586,7 +13725,7 @@ If lint or tests fail, report the issues but do NOT commit.`;
12586
13725
  id: tc.id,
12587
13726
  type: "function",
12588
13727
  function: {
12589
- name: tc.tool || _optionalChain([tc, 'access', _322 => _322.function, 'optionalAccess', _323 => _323.name]) || "unknown",
13728
+ name: tc.tool || _optionalChain([tc, 'access', _342 => _342.function, 'optionalAccess', _343 => _343.name]) || "unknown",
12590
13729
  arguments: typeof tc.args === "string" ? tc.args : JSON.stringify(tc.args || {})
12591
13730
  }
12592
13731
  }));
@@ -12618,7 +13757,7 @@ If lint or tests fail, report the issues but do NOT commit.`;
12618
13757
  context: "resumeSession"
12619
13758
  });
12620
13759
  const providerSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider);
12621
- const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _324 => _324.model]))), () => ( "unconfigured"));
13760
+ const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _344 => _344.model]))), () => ( "unconfigured"));
12622
13761
  await this.sessionManager.createSession(this.runtime.workspaceRoot, model);
12623
13762
  await this.runInteractiveLoop();
12624
13763
  }
@@ -12637,7 +13776,7 @@ If lint or tests fail, report the issues but do NOT commit.`;
12637
13776
  console.log(_chalk2.default.gray(` ${remaining} more request(s) queued`));
12638
13777
  }
12639
13778
  }
12640
- } else if (_optionalChain([this, 'access', _325 => _325.inkRenderer, 'optionalAccess', _326 => _326.hasQueuedInstructions, 'call', _327 => _327()])) {
13779
+ } else if (_optionalChain([this, 'access', _345 => _345.inkRenderer, 'optionalAccess', _346 => _346.hasQueuedInstructions, 'call', _347 => _347()])) {
12641
13780
  instruction = _nullishCoalesce(this.inkRenderer.dequeueInstruction(), () => ( null));
12642
13781
  if (instruction) {
12643
13782
  console.log(_chalk2.default.cyan(`
@@ -12669,7 +13808,7 @@ If lint or tests fail, report the issues but do NOT commit.`;
12669
13808
  const trigger = this.feedbackManager.shouldPrompt({ sessionEnding: true });
12670
13809
  if (trigger) {
12671
13810
  const session2 = this.sessionManager.getCurrentSession();
12672
- await this.feedbackManager.promptForFeedback(trigger, _optionalChain([session2, 'optionalAccess', _328 => _328.metadata, 'access', _329 => _329.sessionId]));
13811
+ await this.feedbackManager.promptForFeedback(trigger, _optionalChain([session2, 'optionalAccess', _348 => _348.metadata, 'access', _349 => _349.sessionId]));
12673
13812
  }
12674
13813
  await this.closeSession();
12675
13814
  return;
@@ -12686,11 +13825,12 @@ If lint or tests fail, report the issues but do NOT commit.`;
12686
13825
  const turnDuration = Date.now() - turnStartTime;
12687
13826
  const session = this.sessionManager.getCurrentSession();
12688
13827
  await this.hookManager.executeHooks("stop", {
12689
- sessionId: _optionalChain([session, 'optionalAccess', _330 => _330.metadata, 'access', _331 => _331.sessionId]),
13828
+ sessionId: _optionalChain([session, 'optionalAccess', _350 => _350.metadata, 'access', _351 => _351.sessionId]),
12690
13829
  turnDuration,
12691
13830
  tokensUsed: this.sessionTokensUsed
12692
13831
  });
12693
- if (_optionalChain([this, 'access', _332 => _332.runtime, 'access', _333 => _333.config, 'access', _334 => _334.ui, 'optionalAccess', _335 => _335.terminalBell]) !== false) {
13832
+ this.ensureStdinReady();
13833
+ if (_optionalChain([this, 'access', _352 => _352.runtime, 'access', _353 => _353.config, 'access', _354 => _354.ui, 'optionalAccess', _355 => _355.terminalBell]) !== false) {
12694
13834
  process.stdout.write("\x07");
12695
13835
  }
12696
13836
  this.feedbackManager.recordInteraction();
@@ -12704,13 +13844,13 @@ If lint or tests fail, report the issues but do NOT commit.`;
12704
13844
  if (feedbackTrigger === "gratitude") {
12705
13845
  await this.feedbackManager.quickRating();
12706
13846
  } else {
12707
- await this.feedbackManager.promptForFeedback(feedbackTrigger, _optionalChain([session2, 'optionalAccess', _336 => _336.metadata, 'access', _337 => _337.sessionId]));
13847
+ await this.feedbackManager.promptForFeedback(feedbackTrigger, _optionalChain([session2, 'optionalAccess', _356 => _356.metadata, 'access', _357 => _357.sessionId]));
12708
13848
  }
12709
13849
  }
12710
13850
  console.log();
12711
13851
  } catch (error) {
12712
13852
  const errorObj = error;
12713
- const isCancel = errorObj.name === "ExitPromptError" || errorObj.isCanceled || _optionalChain([errorObj, 'access', _338 => _338.message, 'optionalAccess', _339 => _339.includes, 'call', _340 => _340("canceled")]) || _optionalChain([errorObj, 'access', _341 => _341.message, 'optionalAccess', _342 => _342.includes, 'call', _343 => _343("User force closed")]) || !errorObj.message;
13853
+ const isCancel = errorObj.name === "ExitPromptError" || errorObj.isCanceled || _optionalChain([errorObj, 'access', _358 => _358.message, 'optionalAccess', _359 => _359.includes, 'call', _360 => _360("canceled")]) || _optionalChain([errorObj, 'access', _361 => _361.message, 'optionalAccess', _362 => _362.includes, 'call', _363 => _363("User force closed")]) || !errorObj.message;
12714
13854
  if (isCancel) {
12715
13855
  continue;
12716
13856
  }
@@ -12846,6 +13986,10 @@ If lint or tests fail, report the issues but do NOT commit.`;
12846
13986
  console.log();
12847
13987
  }
12848
13988
  async collectWorkspaceFiles() {
13989
+ const now = Date.now();
13990
+ if (this.workspaceFiles.length > 0 && now - this.workspaceFilesCachedAt < _AutohandAgent.WORKSPACE_FILES_CACHE_TTL) {
13991
+ return this.workspaceFiles;
13992
+ }
12849
13993
  const git = _child_process.spawnSync.call(void 0, "git", ["ls-files", "--cached", "--others", "--exclude-standard"], {
12850
13994
  cwd: this.runtime.workspaceRoot,
12851
13995
  encoding: "utf8"
@@ -12858,16 +14002,18 @@ If lint or tests fail, report the issues but do NOT commit.`;
12858
14002
  files.push(file);
12859
14003
  }
12860
14004
  });
14005
+ this.workspaceFilesCachedAt = now;
12861
14006
  return files;
12862
14007
  }
12863
14008
  await this.walkWorkspace(this.runtime.workspaceRoot, files);
14009
+ this.workspaceFilesCachedAt = now;
12864
14010
  return files;
12865
14011
  }
12866
14012
  async walkWorkspace(current, acc) {
12867
14013
  let entries;
12868
14014
  try {
12869
14015
  entries = await _fsextra2.default.readdir(current);
12870
- } catch (e67) {
14016
+ } catch (e75) {
12871
14017
  return;
12872
14018
  }
12873
14019
  for (const entry of entries) {
@@ -12883,7 +14029,7 @@ If lint or tests fail, report the issues but do NOT commit.`;
12883
14029
  } else if (stats.isFile()) {
12884
14030
  acc.push(rel);
12885
14031
  }
12886
- } catch (e68) {
14032
+ } catch (e76) {
12887
14033
  continue;
12888
14034
  }
12889
14035
  }
@@ -12952,7 +14098,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
12952
14098
  }
12953
14099
  await this.changeProviderModel(selectedProvider);
12954
14100
  } catch (error) {
12955
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _344 => _344.message, 'optionalAccess', _345 => _345.includes, 'call', _346 => _346("canceled")])) {
14101
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _364 => _364.message, 'optionalAccess', _365 => _365.includes, 'call', _366 => _366("canceled")])) {
12956
14102
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
12957
14103
  return;
12958
14104
  }
@@ -13014,7 +14160,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
13014
14160
  this.resetLlmClient("openrouter", answers.model);
13015
14161
  console.log(_chalk2.default.green("\n\u2713 OpenRouter configured successfully!"));
13016
14162
  } catch (error) {
13017
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _347 => _347.message, 'optionalAccess', _348 => _348.includes, 'call', _349 => _349("canceled")])) {
14163
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _367 => _367.message, 'optionalAccess', _368 => _368.includes, 'call', _369 => _369("canceled")])) {
13018
14164
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
13019
14165
  return;
13020
14166
  }
@@ -13031,9 +14177,9 @@ ${selectedProvider} is not configured yet. Let's set it up!
13031
14177
  const response = await fetch(`${ollamaUrl}/api/tags`);
13032
14178
  if (response.ok) {
13033
14179
  const data = await response.json();
13034
- availableModels = _optionalChain([data, 'access', _350 => _350.models, 'optionalAccess', _351 => _351.map, 'call', _352 => _352((m) => m.name)]) || [];
14180
+ availableModels = _optionalChain([data, 'access', _370 => _370.models, 'optionalAccess', _371 => _371.map, 'call', _372 => _372((m) => m.name)]) || [];
13035
14181
  }
13036
- } catch (e69) {
14182
+ } catch (e77) {
13037
14183
  console.log(_chalk2.default.yellow("\u26A0 Could not connect to Ollama. Make sure it's running.\n"));
13038
14184
  }
13039
14185
  let modelAnswer;
@@ -13068,7 +14214,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
13068
14214
  this.resetLlmClient("ollama", modelAnswer.model);
13069
14215
  console.log(_chalk2.default.green("\n\u2713 Ollama configured successfully!"));
13070
14216
  } catch (error) {
13071
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _353 => _353.message, 'optionalAccess', _354 => _354.includes, 'call', _355 => _355("canceled")])) {
14217
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _373 => _373.message, 'optionalAccess', _374 => _374.includes, 'call', _375 => _375("canceled")])) {
13072
14218
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
13073
14219
  return;
13074
14220
  }
@@ -13104,7 +14250,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
13104
14250
  this.resetLlmClient("llamacpp", answers.model);
13105
14251
  console.log(_chalk2.default.green("\n\u2713 llama.cpp configured successfully!"));
13106
14252
  } catch (error) {
13107
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _356 => _356.message, 'optionalAccess', _357 => _357.includes, 'call', _358 => _358("canceled")])) {
14253
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _376 => _376.message, 'optionalAccess', _377 => _377.includes, 'call', _378 => _378("canceled")])) {
13108
14254
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
13109
14255
  return;
13110
14256
  }
@@ -13146,7 +14292,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
13146
14292
  this.resetLlmClient("openai", answers.model);
13147
14293
  console.log(_chalk2.default.green("\n\u2713 OpenAI configured successfully!"));
13148
14294
  } catch (error) {
13149
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _359 => _359.message, 'optionalAccess', _360 => _360.includes, 'call', _361 => _361("canceled")])) {
14295
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _379 => _379.message, 'optionalAccess', _380 => _380.includes, 'call', _381 => _381("canceled")])) {
13150
14296
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
13151
14297
  return;
13152
14298
  }
@@ -13164,9 +14310,9 @@ ${selectedProvider} is not configured yet. Let's set it up!
13164
14310
  const response = await fetch(`${mlxUrl}/v1/models`);
13165
14311
  if (response.ok) {
13166
14312
  const data = await response.json();
13167
- availableModels = _optionalChain([data, 'access', _362 => _362.data, 'optionalAccess', _363 => _363.map, 'call', _364 => _364((m) => m.id)]) || [];
14313
+ availableModels = _optionalChain([data, 'access', _382 => _382.data, 'optionalAccess', _383 => _383.map, 'call', _384 => _384((m) => m.id)]) || [];
13168
14314
  }
13169
- } catch (e70) {
14315
+ } catch (e78) {
13170
14316
  console.log(_chalk2.default.yellow("\u26A0 Could not connect to MLX server. Make sure it's running.\n"));
13171
14317
  }
13172
14318
  let modelAnswer;
@@ -13199,7 +14345,7 @@ ${selectedProvider} is not configured yet. Let's set it up!
13199
14345
  this.resetLlmClient("mlx", modelAnswer.model);
13200
14346
  console.log(_chalk2.default.green("\n\u2713 MLX configured successfully!"));
13201
14347
  } catch (error) {
13202
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _365 => _365.message, 'optionalAccess', _366 => _366.includes, 'call', _367 => _367("canceled")])) {
14348
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _385 => _385.message, 'optionalAccess', _386 => _386.includes, 'call', _387 => _387("canceled")])) {
13203
14349
  console.log(_chalk2.default.gray("\nConfiguration cancelled."));
13204
14350
  return;
13205
14351
  }
@@ -13209,13 +14355,17 @@ ${selectedProvider} is not configured yet. Let's set it up!
13209
14355
  async changeProviderModel(provider) {
13210
14356
  try {
13211
14357
  const currentSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, provider);
13212
- const currentModel = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([currentSettings, 'optionalAccess', _368 => _368.model]))), () => ( ""));
13213
- if (provider === "ollama" && _optionalChain([currentSettings, 'optionalAccess', _369 => _369.baseUrl])) {
14358
+ const currentModel = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([currentSettings, 'optionalAccess', _388 => _388.model]))), () => ( ""));
14359
+ if (provider === "openai" || provider === "openrouter") {
14360
+ await this.changeCloudProviderSettings(provider, currentModel, currentSettings);
14361
+ return;
14362
+ }
14363
+ if (provider === "ollama" && _optionalChain([currentSettings, 'optionalAccess', _389 => _389.baseUrl])) {
13214
14364
  try {
13215
14365
  const response = await fetch(`${currentSettings.baseUrl}/api/tags`);
13216
14366
  if (response.ok) {
13217
14367
  const data = await response.json();
13218
- const models = _optionalChain([data, 'access', _370 => _370.models, 'optionalAccess', _371 => _371.map, 'call', _372 => _372((m) => m.name)]) || [];
14368
+ const models = _optionalChain([data, 'access', _390 => _390.models, 'optionalAccess', _391 => _391.map, 'call', _392 => _392((m) => m.name)]) || [];
13219
14369
  if (models.length > 0) {
13220
14370
  const answer2 = await _enquirer2.default.prompt([
13221
14371
  {
@@ -13230,23 +14380,9 @@ ${selectedProvider} is not configured yet. Let's set it up!
13230
14380
  return;
13231
14381
  }
13232
14382
  }
13233
- } catch (e71) {
14383
+ } catch (e79) {
13234
14384
  }
13235
14385
  }
13236
- if (provider === "openai") {
13237
- const models = ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"];
13238
- const answer2 = await _enquirer2.default.prompt([
13239
- {
13240
- type: "select",
13241
- name: "model",
13242
- message: "Select a model",
13243
- choices: models,
13244
- initial: Math.max(0, models.indexOf(currentModel))
13245
- }
13246
- ]);
13247
- await this.applyModelChange(provider, answer2.model, currentModel);
13248
- return;
13249
- }
13250
14386
  const answer = await _enquirer2.default.prompt([
13251
14387
  {
13252
14388
  type: "input",
@@ -13255,15 +14391,174 @@ ${selectedProvider} is not configured yet. Let's set it up!
13255
14391
  initial: currentModel
13256
14392
  }
13257
14393
  ]);
13258
- await this.applyModelChange(provider, _optionalChain([answer, 'access', _373 => _373.model, 'optionalAccess', _374 => _374.trim, 'call', _375 => _375()]), currentModel);
14394
+ await this.applyModelChange(provider, _optionalChain([answer, 'access', _393 => _393.model, 'optionalAccess', _394 => _394.trim, 'call', _395 => _395()]), currentModel);
13259
14395
  } catch (error) {
13260
- if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _376 => _376.message, 'optionalAccess', _377 => _377.includes, 'call', _378 => _378("canceled")])) {
14396
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _396 => _396.message, 'optionalAccess', _397 => _397.includes, 'call', _398 => _398("canceled")])) {
13261
14397
  console.log(_chalk2.default.gray("\nModel change cancelled."));
13262
14398
  return;
13263
14399
  }
13264
14400
  throw error;
13265
14401
  }
13266
14402
  }
14403
+ async changeCloudProviderSettings(provider, currentModel, currentSettings) {
14404
+ const providerName = provider === "openai" ? "OpenAI" : "OpenRouter";
14405
+ const maskedKey = _optionalChain([currentSettings, 'optionalAccess', _399 => _399.apiKey]) ? `...${currentSettings.apiKey.slice(-4)}` : "not set";
14406
+ console.log(_chalk2.default.cyan(`
14407
+ ${providerName} Settings`));
14408
+ console.log(_chalk2.default.gray(`Current model: ${currentModel || "not set"}`));
14409
+ console.log(_chalk2.default.gray(`Current API key: ${maskedKey}
14410
+ `));
14411
+ const { action } = await _enquirer2.default.prompt([
14412
+ {
14413
+ type: "select",
14414
+ name: "action",
14415
+ message: "What would you like to change?",
14416
+ choices: [
14417
+ { name: "model", message: "Change model only" },
14418
+ { name: "apiKey", message: "Change API key only" },
14419
+ { name: "both", message: "Change both model and API key" }
14420
+ ]
14421
+ }
14422
+ ]);
14423
+ let newModel = currentModel;
14424
+ let newApiKey = _optionalChain([currentSettings, 'optionalAccess', _400 => _400.apiKey]) || "";
14425
+ if (action === "apiKey" || action === "both") {
14426
+ const keyUrl = provider === "openai" ? "https://platform.openai.com/api-keys" : "https://openrouter.ai/keys";
14427
+ console.log(_chalk2.default.gray(`
14428
+ Get your API key at: ${keyUrl}
14429
+ `));
14430
+ const { apiKey } = await _enquirer2.default.prompt([
14431
+ {
14432
+ type: "password",
14433
+ name: "apiKey",
14434
+ message: `Enter your ${providerName} API key`,
14435
+ validate: (val) => {
14436
+ const v = val;
14437
+ if (!_optionalChain([v, 'optionalAccess', _401 => _401.trim, 'call', _402 => _402()])) return "API key is required";
14438
+ if (v.length < 10) return "API key seems too short";
14439
+ return true;
14440
+ }
14441
+ }
14442
+ ]);
14443
+ console.log(_chalk2.default.gray("\nValidating API key..."));
14444
+ const validationResult = await this.validateApiKey(provider, apiKey.trim());
14445
+ if (!validationResult.valid) {
14446
+ console.log(_chalk2.default.red(`
14447
+ \u2717 ${validationResult.error}`));
14448
+ console.log(_chalk2.default.gray(validationResult.hint || ""));
14449
+ return;
14450
+ }
14451
+ console.log(_chalk2.default.green("\u2713 API key is valid\n"));
14452
+ newApiKey = apiKey.trim();
14453
+ }
14454
+ if (action === "model" || action === "both") {
14455
+ if (provider === "openai") {
14456
+ const models = ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo", "o1", "o1-mini"];
14457
+ const { model } = await _enquirer2.default.prompt([
14458
+ {
14459
+ type: "select",
14460
+ name: "model",
14461
+ message: "Select a model",
14462
+ choices: models,
14463
+ initial: Math.max(0, models.indexOf(currentModel))
14464
+ }
14465
+ ]);
14466
+ newModel = model;
14467
+ } else {
14468
+ const { model } = await _enquirer2.default.prompt([
14469
+ {
14470
+ type: "input",
14471
+ name: "model",
14472
+ message: "Enter the model ID",
14473
+ initial: currentModel || "anthropic/claude-sonnet-4-20250514"
14474
+ }
14475
+ ]);
14476
+ newModel = model.trim();
14477
+ }
14478
+ }
14479
+ const baseUrl = provider === "openai" ? "https://api.openai.com/v1" : "https://openrouter.ai/api/v1";
14480
+ this.runtime.config[provider] = {
14481
+ apiKey: newApiKey,
14482
+ baseUrl,
14483
+ model: newModel
14484
+ };
14485
+ this.runtime.config.provider = provider;
14486
+ this.runtime.options.model = newModel;
14487
+ await _chunkQMVTT55Ycjs.saveConfig.call(void 0, this.runtime.config);
14488
+ this.resetLlmClient(provider, newModel);
14489
+ this.contextWindow = getContextWindow(newModel);
14490
+ this.contextPercentLeft = 100;
14491
+ this.emitStatus();
14492
+ console.log(_chalk2.default.green(`
14493
+ \u2713 ${providerName} settings updated successfully!`));
14494
+ console.log(_chalk2.default.gray(` Provider: ${provider}`));
14495
+ console.log(_chalk2.default.gray(` Model: ${newModel}`));
14496
+ }
14497
+ async validateApiKey(provider, apiKey) {
14498
+ try {
14499
+ const baseUrl = provider === "openai" ? "https://api.openai.com/v1" : "https://openrouter.ai/api/v1";
14500
+ const response = await fetch(`${baseUrl}/models`, {
14501
+ method: "GET",
14502
+ headers: {
14503
+ "Authorization": `Bearer ${apiKey}`,
14504
+ "Content-Type": "application/json",
14505
+ ...provider === "openrouter" && {
14506
+ "HTTP-Referer": "https://autohand.dev",
14507
+ "X-Title": "Autohand CLI"
14508
+ }
14509
+ }
14510
+ });
14511
+ if (response.ok) {
14512
+ return { valid: true };
14513
+ }
14514
+ const status = response.status;
14515
+ let errorData = {};
14516
+ try {
14517
+ errorData = await response.json();
14518
+ } catch (e80) {
14519
+ }
14520
+ if (status === 401) {
14521
+ return {
14522
+ valid: false,
14523
+ error: "Invalid API key",
14524
+ hint: provider === "openai" ? "Check that your API key is correct at https://platform.openai.com/api-keys" : "Check that your API key is correct at https://openrouter.ai/keys"
14525
+ };
14526
+ }
14527
+ if (status === 403) {
14528
+ return {
14529
+ valid: false,
14530
+ error: "API key does not have permission",
14531
+ hint: "Your API key may have restricted permissions or your account may need to add a payment method."
14532
+ };
14533
+ }
14534
+ if (status === 429) {
14535
+ return {
14536
+ valid: false,
14537
+ error: "Rate limited or quota exceeded",
14538
+ hint: "You may have exceeded your API quota. Check your usage and billing settings."
14539
+ };
14540
+ }
14541
+ return {
14542
+ valid: false,
14543
+ error: _optionalChain([errorData, 'optionalAccess', _403 => _403.error, 'optionalAccess', _404 => _404.message]) || `API returned status ${status}`,
14544
+ hint: "Please verify your API key and try again."
14545
+ };
14546
+ } catch (error) {
14547
+ const err = error;
14548
+ if (_optionalChain([err, 'access', _405 => _405.message, 'optionalAccess', _406 => _406.includes, 'call', _407 => _407("fetch")]) || _optionalChain([err, 'access', _408 => _408.message, 'optionalAccess', _409 => _409.includes, 'call', _410 => _410("network")])) {
14549
+ return {
14550
+ valid: false,
14551
+ error: "Network error - could not reach the API",
14552
+ hint: "Check your internet connection and try again."
14553
+ };
14554
+ }
14555
+ return {
14556
+ valid: false,
14557
+ error: `Validation failed: ${err.message}`,
14558
+ hint: "Please try again or check your network connection."
14559
+ };
14560
+ }
14561
+ }
13267
14562
  async applyModelChange(provider, newModel, currentModel) {
13268
14563
  if (!newModel || newModel === currentModel && provider === this.activeProvider) {
13269
14564
  console.log(_chalk2.default.gray("Model unchanged."));
@@ -13309,12 +14604,28 @@ ${selectedProvider} is not configured yet. Let's set it up!
13309
14604
  console.log(_chalk2.default.gray("AGENTS.md already exists in this workspace."));
13310
14605
  return;
13311
14606
  }
13312
- const template = `# Project Autopilot
13313
-
13314
- Describe how Autohand should work in this repo. Include framework commands, testing requirements, and any constraints.
13315
- `;
13316
- await _fsextra2.default.writeFile(target, template, "utf8");
13317
- console.log(_chalk2.default.green("Created AGENTS.md template. Customize it to guide the agent."));
14607
+ console.log(_chalk2.default.gray("Analyzing project structure..."));
14608
+ const analyzer = new ProjectAnalyzer(this.runtime.workspaceRoot);
14609
+ const projectInfo = await analyzer.analyze();
14610
+ if (Object.keys(projectInfo).length > 0) {
14611
+ console.log(_chalk2.default.gray("Detected:"));
14612
+ if (projectInfo.language) {
14613
+ console.log(_chalk2.default.white(` - Language: ${projectInfo.language}`));
14614
+ }
14615
+ if (projectInfo.framework) {
14616
+ console.log(_chalk2.default.white(` - Framework: ${projectInfo.framework}`));
14617
+ }
14618
+ if (projectInfo.packageManager) {
14619
+ console.log(_chalk2.default.white(` - Package manager: ${projectInfo.packageManager}`));
14620
+ }
14621
+ if (projectInfo.testFramework) {
14622
+ console.log(_chalk2.default.white(` - Test framework: ${projectInfo.testFramework}`));
14623
+ }
14624
+ }
14625
+ const generator = new AgentsGenerator();
14626
+ const content = generator.generateContent(projectInfo);
14627
+ await _fsextra2.default.writeFile(target, content, "utf8");
14628
+ console.log(_chalk2.default.green("Created AGENTS.md based on your project. Customize it to guide the agent."));
13318
14629
  }
13319
14630
  /**
13320
14631
  * Detect if instruction is simple chat that doesn't need tools
@@ -13426,8 +14737,8 @@ No provider is configured yet. Let's set one up!
13426
14737
  return this.runInstruction(instruction);
13427
14738
  }
13428
14739
  const err = error instanceof Error ? error : new Error(String(error));
13429
- const maxRetries = _nullishCoalesce(_optionalChain([this, 'access', _379 => _379.runtime, 'access', _380 => _380.config, 'access', _381 => _381.agent, 'optionalAccess', _382 => _382.sessionRetryLimit]), () => ( 3));
13430
- const baseDelay = _nullishCoalesce(_optionalChain([this, 'access', _383 => _383.runtime, 'access', _384 => _384.config, 'access', _385 => _385.agent, 'optionalAccess', _386 => _386.sessionRetryDelay]), () => ( 1e3));
14740
+ const maxRetries = _nullishCoalesce(_optionalChain([this, 'access', _411 => _411.runtime, 'access', _412 => _412.config, 'access', _413 => _413.agent, 'optionalAccess', _414 => _414.sessionRetryLimit]), () => ( 3));
14741
+ const baseDelay = _nullishCoalesce(_optionalChain([this, 'access', _415 => _415.runtime, 'access', _416 => _416.config, 'access', _417 => _417.agent, 'optionalAccess', _418 => _418.sessionRetryDelay]), () => ( 1e3));
13431
14742
  if (this.isRetryableSessionError(err) && this.sessionRetryCount < maxRetries) {
13432
14743
  this.sessionRetryCount++;
13433
14744
  await this.submitSessionFailureBugReport(err, this.sessionRetryCount, maxRetries);
@@ -13468,7 +14779,7 @@ No provider is configured yet. Let's set one up!
13468
14779
  if (this.taskStartedAt && !canceledByUser && !this.useInkRenderer) {
13469
14780
  const elapsed = this.formatElapsedTime(this.taskStartedAt);
13470
14781
  const tokens = this.formatTokens(this.totalTokensUsed);
13471
- const queueCount = this.pendingInkInstructions.length + (_nullishCoalesce(_optionalChain([this, 'access', _387 => _387.inkRenderer, 'optionalAccess', _388 => _388.getQueueCount, 'call', _389 => _389()]), () => ( 0))) + this.persistentInput.getQueueLength();
14782
+ const queueCount = this.pendingInkInstructions.length + (_nullishCoalesce(_optionalChain([this, 'access', _419 => _419.inkRenderer, 'optionalAccess', _420 => _420.getQueueCount, 'call', _421 => _421()]), () => ( 0))) + this.persistentInput.getQueueLength();
13472
14783
  const queueStatus = queueCount > 0 ? ` \xB7 ${queueCount} queued` : "";
13473
14784
  console.log(_chalk2.default.gray(`
13474
14785
  Completed in ${elapsed} \xB7 ${tokens} used${queueStatus}`));
@@ -13541,7 +14852,7 @@ Completed in ${elapsed} \xB7 ${tokens} used${queueStatus}`));
13541
14852
  const session = this.sessionManager.getCurrentSession();
13542
14853
  const sessionDuration = Date.now() - this.sessionStartedAt;
13543
14854
  await this.hookManager.executeHooks("session-end", {
13544
- sessionId: _optionalChain([session, 'optionalAccess', _390 => _390.metadata, 'access', _391 => _391.sessionId]),
14855
+ sessionId: _optionalChain([session, 'optionalAccess', _422 => _422.metadata, 'access', _423 => _423.sessionId]),
13545
14856
  sessionEndReason: "quit",
13546
14857
  duration: sessionDuration
13547
14858
  });
@@ -13552,7 +14863,7 @@ Completed in ${elapsed} \xB7 ${tokens} used${queueStatus}`));
13552
14863
  }
13553
14864
  const messages = session.getMessages();
13554
14865
  const lastUserMsg = messages.filter((m) => m.role === "user").slice(-1)[0];
13555
- const summary = _optionalChain([lastUserMsg, 'optionalAccess', _392 => _392.content, 'access', _393 => _393.slice, 'call', _394 => _394(0, 60)]) || "Session complete";
14866
+ const summary = _optionalChain([lastUserMsg, 'optionalAccess', _424 => _424.content, 'access', _425 => _425.slice, 'call', _426 => _426(0, 60)]) || "Session complete";
13556
14867
  const syncResult = await this.telemetryManager.syncSession({
13557
14868
  messages: messages.map((m) => ({
13558
14869
  role: m.role,
@@ -13575,15 +14886,15 @@ Completed in ${elapsed} \xB7 ${tokens} used${queueStatus}`));
13575
14886
  `));
13576
14887
  }
13577
14888
  async runReactLoop(abortController) {
13578
- const debugMode = _optionalChain([this, 'access', _395 => _395.runtime, 'access', _396 => _396.config, 'access', _397 => _397.agent, 'optionalAccess', _398 => _398.debug]) === true || process.env.AUTOHAND_DEBUG === "1";
14889
+ const debugMode = _optionalChain([this, 'access', _427 => _427.runtime, 'access', _428 => _428.config, 'access', _429 => _429.agent, 'optionalAccess', _430 => _430.debug]) === true || process.env.AUTOHAND_DEBUG === "1";
13579
14890
  if (debugMode) process.stderr.write(`[AGENT DEBUG] runReactLoop started
13580
14891
  `);
13581
- const maxIterations = _nullishCoalesce(_optionalChain([this, 'access', _399 => _399.runtime, 'access', _400 => _400.config, 'access', _401 => _401.agent, 'optionalAccess', _402 => _402.maxIterations]), () => ( 100));
14892
+ const maxIterations = _nullishCoalesce(_optionalChain([this, 'access', _431 => _431.runtime, 'access', _432 => _432.config, 'access', _433 => _433.agent, 'optionalAccess', _434 => _434.maxIterations]), () => ( 100));
13582
14893
  const allTools = this.toolManager.toFunctionDefinitions();
13583
14894
  if (debugMode) process.stderr.write(`[AGENT DEBUG] Loaded ${allTools.length} tools, maxIterations=${maxIterations}
13584
14895
  `);
13585
14896
  this.startStatusUpdates();
13586
- const showThinking = _optionalChain([this, 'access', _403 => _403.runtime, 'access', _404 => _404.config, 'access', _405 => _405.ui, 'optionalAccess', _406 => _406.showThinking]) !== false;
14897
+ const showThinking = _optionalChain([this, 'access', _435 => _435.runtime, 'access', _436 => _436.config, 'access', _437 => _437.ui, 'optionalAccess', _438 => _438.showThinking]) !== false;
13587
14898
  for (let iteration = 0; iteration < maxIterations; iteration += 1) {
13588
14899
  if (abortController.signal.aborted) {
13589
14900
  if (debugMode) process.stderr.write("[AGENT DEBUG] Abort detected at loop start, breaking\n");
@@ -13591,14 +14902,14 @@ Completed in ${elapsed} \xB7 ${tokens} used${queueStatus}`));
13591
14902
  }
13592
14903
  const messages = this.conversation.history();
13593
14904
  const tools = filterToolsByRelevance(allTools, messages);
13594
- const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _407 => _407.model]))), () => ( "unconfigured"));
14905
+ const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _439 => _439.model]))), () => ( "unconfigured"));
13595
14906
  const contextUsage = calculateContextUsage(
13596
14907
  messages,
13597
14908
  tools,
13598
14909
  model
13599
14910
  );
13600
14911
  if (contextUsage.isCritical) {
13601
- _optionalChain([this, 'access', _408 => _408.runtime, 'access', _409 => _409.spinner, 'optionalAccess', _410 => _410.stop, 'call', _411 => _411()]);
14912
+ _optionalChain([this, 'access', _440 => _440.runtime, 'access', _441 => _441.spinner, 'optionalAccess', _442 => _442.stop, 'call', _443 => _443()]);
13602
14913
  console.log(_chalk2.default.yellow("\n\u26A0 Context at critical level, auto-cropping old messages..."));
13603
14914
  const targetTokens = Math.floor(contextUsage.contextWindow * 0.7);
13604
14915
  const tokensToRemove = contextUsage.totalTokens - targetTokens;
@@ -13621,15 +14932,16 @@ ${summary}`
13621
14932
  \u26A0 Context at ${Math.round(contextUsage.usagePercent * 100)}% - approaching limit`));
13622
14933
  }
13623
14934
  if (iteration >= 10 && iteration % 10 === 0) {
13624
- _optionalChain([this, 'access', _412 => _412.runtime, 'access', _413 => _413.spinner, 'optionalAccess', _414 => _414.start, 'call', _415 => _415(`Working... (step ${iteration + 1})`)]);
14935
+ _optionalChain([this, 'access', _444 => _444.runtime, 'access', _445 => _445.spinner, 'optionalAccess', _446 => _446.start, 'call', _447 => _447(`Working... (step ${iteration + 1})`)]);
13625
14936
  } else {
13626
- _optionalChain([this, 'access', _416 => _416.runtime, 'access', _417 => _417.spinner, 'optionalAccess', _418 => _418.start, 'call', _419 => _419("Working ...")]);
14937
+ _optionalChain([this, 'access', _448 => _448.runtime, 'access', _449 => _449.spinner, 'optionalAccess', _450 => _450.start, 'call', _451 => _451("Working ...")]);
13627
14938
  }
13628
14939
  const messagesWithImages = this.getMessagesWithImages();
13629
14940
  if (debugMode) process.stderr.write(`[AGENT DEBUG] Calling LLM with ${messagesWithImages.length} messages, ${tools.length} tools
13630
14941
  `);
13631
14942
  let completion;
13632
14943
  try {
14944
+ const thinkingLevel = process.env.AUTOHAND_THINKING_LEVEL || "normal";
13633
14945
  completion = await this.llm.complete({
13634
14946
  messages: messagesWithImages,
13635
14947
  temperature: _nullishCoalesce(this.runtime.options.temperature, () => ( 0.2)),
@@ -13637,10 +14949,11 @@ ${summary}`
13637
14949
  signal: abortController.signal,
13638
14950
  tools: tools.length > 0 ? tools : void 0,
13639
14951
  toolChoice: tools.length > 0 ? "auto" : void 0,
13640
- maxTokens: 16e3
14952
+ maxTokens: 16e3,
13641
14953
  // Allow large outputs for file generation
14954
+ thinkingLevel
13642
14955
  });
13643
- if (debugMode) process.stderr.write(`[AGENT DEBUG] LLM returned: content length=${_nullishCoalesce(_optionalChain([completion, 'access', _420 => _420.content, 'optionalAccess', _421 => _421.length]), () => ( 0))}, toolCalls=${_nullishCoalesce(_optionalChain([completion, 'access', _422 => _422.toolCalls, 'optionalAccess', _423 => _423.length]), () => ( 0))}
14956
+ if (debugMode) process.stderr.write(`[AGENT DEBUG] LLM returned: content length=${_nullishCoalesce(_optionalChain([completion, 'access', _452 => _452.content, 'optionalAccess', _453 => _453.length]), () => ( 0))}, toolCalls=${_nullishCoalesce(_optionalChain([completion, 'access', _454 => _454.toolCalls, 'optionalAccess', _455 => _455.length]), () => ( 0))}
13644
14957
  `);
13645
14958
  } catch (llmError) {
13646
14959
  const errMsg = llmError instanceof Error ? llmError.message : String(llmError);
@@ -13656,10 +14969,10 @@ ${summary}`
13656
14969
  this.forceRenderSpinner();
13657
14970
  }
13658
14971
  const payload = this.parseAssistantResponse(completion);
13659
- if (debugMode) process.stderr.write(`[AGENT DEBUG] Parsed payload: finalResponse=${!!payload.finalResponse}, thought=${!!payload.thought}, toolCalls=${_nullishCoalesce(_optionalChain([payload, 'access', _424 => _424.toolCalls, 'optionalAccess', _425 => _425.length]), () => ( 0))}
14972
+ if (debugMode) process.stderr.write(`[AGENT DEBUG] Parsed payload: finalResponse=${!!payload.finalResponse}, thought=${!!payload.thought}, toolCalls=${_nullishCoalesce(_optionalChain([payload, 'access', _456 => _456.toolCalls, 'optionalAccess', _457 => _457.length]), () => ( 0))}
13660
14973
  `);
13661
14974
  const assistantMessage = { role: "assistant", content: completion.content };
13662
- if (_optionalChain([completion, 'access', _426 => _426.toolCalls, 'optionalAccess', _427 => _427.length])) {
14975
+ if (_optionalChain([completion, 'access', _458 => _458.toolCalls, 'optionalAccess', _459 => _459.length])) {
13663
14976
  assistantMessage.tool_calls = completion.toolCalls;
13664
14977
  }
13665
14978
  this.conversation.addMessage(assistantMessage);
@@ -13668,14 +14981,14 @@ ${summary}`
13668
14981
  if (debugMode) {
13669
14982
  console.log(_chalk2.default.yellow(`
13670
14983
  [DEBUG] Iteration ${iteration}:`));
13671
- console.log(_chalk2.default.yellow(` - toolCalls: ${_nullishCoalesce(_optionalChain([payload, 'access', _428 => _428.toolCalls, 'optionalAccess', _429 => _429.length]), () => ( 0))}`));
13672
- console.log(_chalk2.default.yellow(` - thought: ${_optionalChain([payload, 'access', _430 => _430.thought, 'optionalAccess', _431 => _431.slice, 'call', _432 => _432(0, 100)]) || "(none)"}`));
13673
- console.log(_chalk2.default.yellow(` - finalResponse: ${_optionalChain([payload, 'access', _433 => _433.finalResponse, 'optionalAccess', _434 => _434.slice, 'call', _435 => _435(0, 100)]) || "(none)"}`));
13674
- console.log(_chalk2.default.yellow(` - raw content: ${_optionalChain([completion, 'access', _436 => _436.content, 'optionalAccess', _437 => _437.slice, 'call', _438 => _438(0, 200)]) || "(empty)"}`));
14984
+ console.log(_chalk2.default.yellow(` - toolCalls: ${_nullishCoalesce(_optionalChain([payload, 'access', _460 => _460.toolCalls, 'optionalAccess', _461 => _461.length]), () => ( 0))}`));
14985
+ console.log(_chalk2.default.yellow(` - thought: ${_optionalChain([payload, 'access', _462 => _462.thought, 'optionalAccess', _463 => _463.slice, 'call', _464 => _464(0, 100)]) || "(none)"}`));
14986
+ console.log(_chalk2.default.yellow(` - finalResponse: ${_optionalChain([payload, 'access', _465 => _465.finalResponse, 'optionalAccess', _466 => _466.slice, 'call', _467 => _467(0, 100)]) || "(none)"}`));
14987
+ console.log(_chalk2.default.yellow(` - raw content: ${_optionalChain([completion, 'access', _468 => _468.content, 'optionalAccess', _469 => _469.slice, 'call', _470 => _470(0, 200)]) || "(empty)"}`));
13675
14988
  }
13676
- const toolCount = _nullishCoalesce(_optionalChain([payload, 'access', _439 => _439.toolCalls, 'optionalAccess', _440 => _440.length]), () => ( 0));
14989
+ const toolCount = _nullishCoalesce(_optionalChain([payload, 'access', _471 => _471.toolCalls, 'optionalAccess', _472 => _472.length]), () => ( 0));
13677
14990
  const hasResponse = Boolean(payload.finalResponse || payload.response || !toolCount && payload.thought);
13678
- const thoughtPreview = _optionalChain([payload, 'access', _441 => _441.thought, 'optionalAccess', _442 => _442.slice, 'call', _443 => _443(0, 80)]) || "";
14991
+ const thoughtPreview = _optionalChain([payload, 'access', _473 => _473.thought, 'optionalAccess', _474 => _474.slice, 'call', _475 => _475(0, 80)]) || "";
13679
14992
  if (this.inkRenderer) {
13680
14993
  if (toolCount > 0) {
13681
14994
  const toolNames = payload.toolCalls.map((t) => t.tool).join(", ");
@@ -13722,23 +15035,23 @@ ${summary}`
13722
15035
  role: "tool",
13723
15036
  name: result.tool,
13724
15037
  content,
13725
- tool_call_id: _optionalChain([otherCalls, 'access', _444 => _444[i], 'optionalAccess', _445 => _445.id])
15038
+ tool_call_id: _optionalChain([otherCalls, 'access', _476 => _476[i], 'optionalAccess', _477 => _477.id])
13726
15039
  });
13727
- await this.saveToolMessage(result.tool, content, _optionalChain([otherCalls, 'access', _446 => _446[i], 'optionalAccess', _447 => _447.id]));
15040
+ await this.saveToolMessage(result.tool, content, _optionalChain([otherCalls, 'access', _478 => _478[i], 'optionalAccess', _479 => _479.id]));
13728
15041
  }
13729
15042
  this.updateContextUsage(this.conversation.history(), tools);
13730
- const charLimit = _nullishCoalesce(_optionalChain([this, 'access', _448 => _448.runtime, 'access', _449 => _449.config, 'access', _450 => _450.ui, 'optionalAccess', _451 => _451.readFileCharLimit]), () => ( 300));
15043
+ const charLimit = _nullishCoalesce(_optionalChain([this, 'access', _480 => _480.runtime, 'access', _481 => _481.config, 'access', _482 => _482.ui, 'optionalAccess', _483 => _483.readFileCharLimit]), () => ( 300));
13731
15044
  outputLines.push(this.formatToolResultsBatch(results, charLimit, otherCalls, thought));
13732
15045
  }
13733
15046
  if (this.inkRenderer) {
13734
15047
  const thought2 = showThinking && payload.thought && !payload.thought.trim().startsWith("{") ? payload.thought : void 0;
13735
15048
  if (results.length > 0) {
13736
- const charLimit = _nullishCoalesce(_optionalChain([this, 'access', _452 => _452.runtime, 'access', _453 => _453.config, 'access', _454 => _454.ui, 'optionalAccess', _455 => _455.readFileCharLimit]), () => ( 300));
15049
+ const charLimit = _nullishCoalesce(_optionalChain([this, 'access', _484 => _484.runtime, 'access', _485 => _485.config, 'access', _486 => _486.ui, 'optionalAccess', _487 => _487.readFileCharLimit]), () => ( 300));
13737
15050
  this.addUIToolOutputs(results.map((r, i) => {
13738
15051
  const call = otherCalls[i];
13739
- const filePath = _optionalChain([call, 'optionalAccess', _456 => _456.args, 'optionalAccess', _457 => _457.path]);
13740
- const command = _optionalChain([call, 'optionalAccess', _458 => _458.args, 'optionalAccess', _459 => _459.command]);
13741
- const commandArgs = _optionalChain([call, 'optionalAccess', _460 => _460.args, 'optionalAccess', _461 => _461.args]);
15052
+ const filePath = _optionalChain([call, 'optionalAccess', _488 => _488.args, 'optionalAccess', _489 => _489.path]);
15053
+ const command = _optionalChain([call, 'optionalAccess', _490 => _490.args, 'optionalAccess', _491 => _491.command]);
15054
+ const commandArgs = _optionalChain([call, 'optionalAccess', _492 => _492.args, 'optionalAccess', _493 => _493.args]);
13742
15055
  return {
13743
15056
  tool: r.tool,
13744
15057
  success: r.success,
@@ -13749,13 +15062,13 @@ ${summary}`
13749
15062
  }));
13750
15063
  }
13751
15064
  } else {
13752
- _optionalChain([this, 'access', _462 => _462.runtime, 'access', _463 => _463.spinner, 'optionalAccess', _464 => _464.stop, 'call', _465 => _465()]);
15065
+ _optionalChain([this, 'access', _494 => _494.runtime, 'access', _495 => _495.spinner, 'optionalAccess', _496 => _496.stop, 'call', _497 => _497()]);
13753
15066
  if (outputLines.length > 0) {
13754
15067
  console.log("\n" + outputLines.join("\n"));
13755
15068
  }
13756
15069
  }
13757
15070
  if (results.length > 0) {
13758
- const sessionId = _optionalChain([this, 'access', _466 => _466.sessionManager, 'access', _467 => _467.getCurrentSession, 'call', _468 => _468(), 'optionalAccess', _469 => _469.metadata, 'access', _470 => _470.sessionId]) || "unknown";
15071
+ const sessionId = _optionalChain([this, 'access', _498 => _498.sessionManager, 'access', _499 => _499.getCurrentSession, 'call', _500 => _500(), 'optionalAccess', _501 => _501.metadata, 'access', _502 => _502.sessionId]) || "unknown";
13759
15072
  for (const result of results) {
13760
15073
  if (result.success) {
13761
15074
  await this.projectManager.recordSuccess(this.runtime.workspaceRoot, {
@@ -13789,7 +15102,7 @@ ${summary}`
13789
15102
  const searchTools = ["search", "search_with_context", "semantic_search"];
13790
15103
  const searchCallsThisIteration = otherCalls.filter((call) => searchTools.includes(call.tool));
13791
15104
  for (const call of searchCallsThisIteration) {
13792
- const query = String(_optionalChain([call, 'access', _471 => _471.args, 'optionalAccess', _472 => _472.query]) || _optionalChain([call, 'access', _473 => _473.args, 'optionalAccess', _474 => _474.pattern]) || "unknown");
15105
+ const query = String(_optionalChain([call, 'access', _503 => _503.args, 'optionalAccess', _504 => _504.query]) || _optionalChain([call, 'access', _505 => _505.args, 'optionalAccess', _506 => _506.pattern]) || "unknown");
13793
15106
  this.searchQueries.push(query);
13794
15107
  }
13795
15108
  if (searchCallsThisIteration.length >= 3) {
@@ -13810,7 +15123,7 @@ ${summary}`
13810
15123
  continue;
13811
15124
  }
13812
15125
  const pendingResponse = payload.finalResponse || payload.response || "";
13813
- if (this.expressesIntentToAct(pendingResponse) && !_optionalChain([payload, 'access', _475 => _475.toolCalls, 'optionalAccess', _476 => _476.length])) {
15126
+ if (this.expressesIntentToAct(pendingResponse) && !_optionalChain([payload, 'access', _507 => _507.toolCalls, 'optionalAccess', _508 => _508.length])) {
13814
15127
  const intentRetryKey = "__intentRetryCount";
13815
15128
  const intentRetries = (_nullishCoalesce(this[intentRetryKey], () => ( 0))) + 1;
13816
15129
  this[intentRetryKey] = intentRetries;
@@ -13826,17 +15139,21 @@ ${summary}`
13826
15139
  }
13827
15140
  this.stopStatusUpdates();
13828
15141
  let rawResponse;
15142
+ const usedThoughtAsResponse = Boolean(payload.thought) && !payload.finalResponse && !payload.response && !_optionalChain([payload, 'access', _509 => _509.toolCalls, 'optionalAccess', _510 => _510.length]);
13829
15143
  if (payload.finalResponse) {
13830
15144
  rawResponse = payload.finalResponse;
13831
15145
  } else if (payload.response) {
13832
15146
  rawResponse = payload.response;
13833
- } else if (!_optionalChain([payload, 'access', _477 => _477.toolCalls, 'optionalAccess', _478 => _478.length]) && payload.thought) {
15147
+ } else if (!_optionalChain([payload, 'access', _511 => _511.toolCalls, 'optionalAccess', _512 => _512.length]) && payload.thought) {
13834
15148
  rawResponse = payload.thought;
13835
15149
  } else {
13836
15150
  const cleanedContent = this.cleanupModelResponse(completion.content);
13837
15151
  rawResponse = cleanedContent.startsWith("{") ? "" : cleanedContent;
13838
15152
  }
13839
- const response = this.cleanupModelResponse(rawResponse.trim());
15153
+ let response = this.cleanupModelResponse(rawResponse.trim());
15154
+ if (!response && usedThoughtAsResponse && payload.thought) {
15155
+ response = payload.thought.trim();
15156
+ }
13840
15157
  if (!response && iteration > 0) {
13841
15158
  const consecutiveEmptyKey = "__consecutiveEmpty";
13842
15159
  const consecutiveEmpty = (_nullishCoalesce(this[consecutiveEmptyKey], () => ( 0))) + 1;
@@ -13850,7 +15167,7 @@ ${summary}`
13850
15167
  this.inkRenderer.setWorking(false);
13851
15168
  this.inkRenderer.setFinalResponse(fallback);
13852
15169
  } else {
13853
- _optionalChain([this, 'access', _479 => _479.runtime, 'access', _480 => _480.spinner, 'optionalAccess', _481 => _481.stop, 'call', _482 => _482()]);
15170
+ _optionalChain([this, 'access', _513 => _513.runtime, 'access', _514 => _514.spinner, 'optionalAccess', _515 => _515.stop, 'call', _516 => _516()]);
13854
15171
  console.log(fallback);
13855
15172
  }
13856
15173
  this[consecutiveEmptyKey] = 0;
@@ -13863,12 +15180,13 @@ ${summary}`
13863
15180
  continue;
13864
15181
  }
13865
15182
  this.__consecutiveEmpty = 0;
13866
- if (payload.thought) {
15183
+ const suppressThinking = usedThoughtAsResponse && response.length > 0;
15184
+ if (payload.thought && !suppressThinking) {
13867
15185
  this.emitOutput({ type: "thinking", thought: payload.thought });
13868
15186
  }
13869
15187
  this.emitOutput({ type: "message", content: response });
13870
15188
  if (this.inkRenderer) {
13871
- if (showThinking && payload.thought) {
15189
+ if (showThinking && payload.thought && !suppressThinking) {
13872
15190
  this.inkRenderer.setThinking(payload.thought);
13873
15191
  }
13874
15192
  this.inkRenderer.setElapsed(this.formatElapsedTime(this.sessionStartedAt));
@@ -13876,8 +15194,8 @@ ${summary}`
13876
15194
  this.inkRenderer.setWorking(false);
13877
15195
  this.inkRenderer.setFinalResponse(response);
13878
15196
  } else {
13879
- _optionalChain([this, 'access', _483 => _483.runtime, 'access', _484 => _484.spinner, 'optionalAccess', _485 => _485.stop, 'call', _486 => _486()]);
13880
- if (showThinking && payload.thought && !payload.thought.trim().startsWith("{")) {
15197
+ _optionalChain([this, 'access', _517 => _517.runtime, 'access', _518 => _518.spinner, 'optionalAccess', _519 => _519.stop, 'call', _520 => _520()]);
15198
+ if (showThinking && payload.thought && !suppressThinking && !payload.thought.trim().startsWith("{")) {
13881
15199
  console.log(_chalk2.default.gray(`Thinking: ${payload.thought}`));
13882
15200
  console.log();
13883
15201
  }
@@ -13886,7 +15204,7 @@ ${summary}`
13886
15204
  return;
13887
15205
  }
13888
15206
  this.stopStatusUpdates();
13889
- _optionalChain([this, 'access', _487 => _487.runtime, 'access', _488 => _488.spinner, 'optionalAccess', _489 => _489.stop, 'call', _490 => _490()]);
15207
+ _optionalChain([this, 'access', _521 => _521.runtime, 'access', _522 => _522.spinner, 'optionalAccess', _523 => _523.stop, 'call', _524 => _524()]);
13890
15208
  console.log(_chalk2.default.yellow(`
13891
15209
  \u26A0 Task exceeded ${maxIterations} tool iterations without completing.`));
13892
15210
  console.log(_chalk2.default.gray("This usually means the task is too complex for a single turn."));
@@ -13899,7 +15217,7 @@ ${summary}`
13899
15217
  * while falling back to JSON parsing for providers without native support.
13900
15218
  */
13901
15219
  parseAssistantResponse(completion) {
13902
- if (_optionalChain([completion, 'access', _491 => _491.toolCalls, 'optionalAccess', _492 => _492.length])) {
15220
+ if (_optionalChain([completion, 'access', _525 => _525.toolCalls, 'optionalAccess', _526 => _526.length])) {
13903
15221
  let thought;
13904
15222
  if (completion.content) {
13905
15223
  const trimmed = completion.content.trim();
@@ -13907,7 +15225,7 @@ ${summary}`
13907
15225
  try {
13908
15226
  const parsed = JSON.parse(trimmed);
13909
15227
  thought = typeof parsed.thought === "string" ? parsed.thought : void 0;
13910
- } catch (e72) {
15228
+ } catch (e81) {
13911
15229
  thought = this.cleanupModelResponse(trimmed) || void 0;
13912
15230
  }
13913
15231
  } else {
@@ -13974,9 +15292,9 @@ ${summary}`
13974
15292
  return { finalResponse: contentValue };
13975
15293
  }
13976
15294
  return { finalResponse: raw.trim() };
13977
- } catch (e73) {
15295
+ } catch (e82) {
13978
15296
  const thoughtMatch = raw.match(/"thought"\s*:\s*"([^"]+)"/);
13979
- if (_optionalChain([thoughtMatch, 'optionalAccess', _493 => _493[1]])) {
15297
+ if (_optionalChain([thoughtMatch, 'optionalAccess', _527 => _527[1]])) {
13980
15298
  return { thought: thoughtMatch[1], finalResponse: thoughtMatch[1] };
13981
15299
  }
13982
15300
  if (raw.trim().startsWith("{")) {
@@ -14116,11 +15434,11 @@ ${mentionContext.block}`);
14116
15434
  return `- ${def.name}(${args}) - ${def.description}`;
14117
15435
  }
14118
15436
  async buildSystemPrompt() {
14119
- const toolDefs = _nullishCoalesce(_optionalChain([this, 'access', _494 => _494.toolManager, 'optionalAccess', _495 => _495.listDefinitions, 'call', _496 => _496()]), () => ( []));
15437
+ const toolDefs = _nullishCoalesce(_optionalChain([this, 'access', _528 => _528.toolManager, 'optionalAccess', _529 => _529.listDefinitions, 'call', _530 => _530()]), () => ( []));
14120
15438
  const toolSignatures = toolDefs.map((def) => this.formatToolSignature(def)).join("\n");
14121
15439
  const memories = await this.memoryManager.getContextMemories();
14122
15440
  const instructions = await this.loadInstructionFiles();
14123
- const authUser = _optionalChain([this, 'access', _497 => _497.runtime, 'access', _498 => _498.config, 'access', _499 => _499.auth, 'optionalAccess', _500 => _500.user]);
15441
+ const authUser = _optionalChain([this, 'access', _531 => _531.runtime, 'access', _532 => _532.config, 'access', _533 => _533.auth, 'optionalAccess', _534 => _534.user]);
14124
15442
  const parts = [
14125
15443
  // ═══════════════════════════════════════════════════════════════════
14126
15444
  // 1. IDENTITY & CORE STANDARDS
@@ -14456,7 +15774,7 @@ ${toolSignatures}
14456
15774
  try {
14457
15775
  const stats = await _fsextra2.default.stat(fullPath);
14458
15776
  return stats.isFile();
14459
- } catch (e74) {
15777
+ } catch (e83) {
14460
15778
  return false;
14461
15779
  }
14462
15780
  }
@@ -14617,10 +15935,10 @@ ${ctx.contents}`).join("\n\n");
14617
15935
  for (let i = 0; i < results.length; i++) {
14618
15936
  const result = results[i];
14619
15937
  const content = result.success ? _nullishCoalesce(result.output, () => ( "(no output)")) : _nullishCoalesce(_nullishCoalesce(result.error, () => ( result.output)), () => ( "Tool failed without error message"));
14620
- const call = _optionalChain([toolCalls, 'optionalAccess', _501 => _501[i]]);
14621
- const filePath = _optionalChain([call, 'optionalAccess', _502 => _502.args, 'optionalAccess', _503 => _503.path]);
14622
- const command = _optionalChain([call, 'optionalAccess', _504 => _504.args, 'optionalAccess', _505 => _505.command]);
14623
- const commandArgs = _optionalChain([call, 'optionalAccess', _506 => _506.args, 'optionalAccess', _507 => _507.args]);
15938
+ const call = _optionalChain([toolCalls, 'optionalAccess', _535 => _535[i]]);
15939
+ const filePath = _optionalChain([call, 'optionalAccess', _536 => _536.args, 'optionalAccess', _537 => _537.path]);
15940
+ const command = _optionalChain([call, 'optionalAccess', _538 => _538.args, 'optionalAccess', _539 => _539.command]);
15941
+ const commandArgs = _optionalChain([call, 'optionalAccess', _540 => _540.args, 'optionalAccess', _541 => _541.args]);
14624
15942
  const display = result.success ? formatToolOutputForDisplay({ tool: result.tool, content, charLimit, filePath, command, commandArgs }) : { output: content, truncated: false, totalChars: content.length };
14625
15943
  const icon = result.success ? _chalk2.default.green("\u2714") : _chalk2.default.red("\u2716");
14626
15944
  lines.push(`${icon} ${_chalk2.default.bold(result.tool)}`);
@@ -14651,22 +15969,22 @@ ${ctx.contents}`).join("\n\n");
14651
15969
  )));
14652
15970
  this.inkRenderer = createInkRenderer({
14653
15971
  onInstruction: (text) => {
14654
- _optionalChain([this, 'access', _508 => _508.inkRenderer, 'optionalAccess', _509 => _509.addQueuedInstruction, 'call', _510 => _510(text)]);
15972
+ _optionalChain([this, 'access', _542 => _542.inkRenderer, 'optionalAccess', _543 => _543.addQueuedInstruction, 'call', _544 => _544(text)]);
14655
15973
  },
14656
15974
  onEscape: () => {
14657
15975
  if (abortController && !abortController.signal.aborted) {
14658
15976
  abortController.abort();
14659
- _optionalChain([onCancel, 'optionalCall', _511 => _511()]);
15977
+ _optionalChain([onCancel, 'optionalCall', _545 => _545()]);
14660
15978
  }
14661
15979
  },
14662
15980
  onCtrlC: () => {
14663
15981
  },
14664
- enableQueueInput: _optionalChain([this, 'access', _512 => _512.runtime, 'access', _513 => _513.config, 'access', _514 => _514.agent, 'optionalAccess', _515 => _515.enableRequestQueue]) !== false
15982
+ enableQueueInput: _optionalChain([this, 'access', _546 => _546.runtime, 'access', _547 => _547.config, 'access', _548 => _548.agent, 'optionalAccess', _549 => _549.enableRequestQueue]) !== false
14665
15983
  });
14666
15984
  this.inkRenderer.start();
14667
15985
  this.inkRenderer.setWorking(true, "Gathering context...");
14668
15986
  this.runtime.inkRenderer = this.inkRenderer;
14669
- } catch (e75) {
15987
+ } catch (e84) {
14670
15988
  this.useInkRenderer = false;
14671
15989
  this.initFallbackSpinner();
14672
15990
  }
@@ -14819,7 +16137,7 @@ ${parts.join("\n")}`
14819
16137
  return () => {
14820
16138
  };
14821
16139
  }
14822
- _readline2.default.emitKeypressEvents(input);
16140
+ safeEmitKeypressEvents(input);
14823
16141
  const supportsRaw = typeof input.setRawMode === "function";
14824
16142
  const wasRaw = input.isRaw;
14825
16143
  if (!wasRaw && supportsRaw) {
@@ -14827,17 +16145,17 @@ ${parts.join("\n")}`
14827
16145
  }
14828
16146
  let ctrlCCount = 0;
14829
16147
  this.queueInput = "";
14830
- const enableQueue = _optionalChain([this, 'access', _516 => _516.runtime, 'access', _517 => _517.config, 'access', _518 => _518.agent, 'optionalAccess', _519 => _519.enableRequestQueue]) !== false;
16148
+ const enableQueue = _optionalChain([this, 'access', _550 => _550.runtime, 'access', _551 => _551.config, 'access', _552 => _552.agent, 'optionalAccess', _553 => _553.enableRequestQueue]) !== false;
14831
16149
  const handler = (_str, key) => {
14832
16150
  if (controller.signal.aborted) {
14833
16151
  return;
14834
16152
  }
14835
- if (_optionalChain([key, 'optionalAccess', _520 => _520.name]) === "escape") {
16153
+ if (_optionalChain([key, 'optionalAccess', _554 => _554.name]) === "escape") {
14836
16154
  controller.abort();
14837
16155
  onCancel();
14838
16156
  return;
14839
16157
  }
14840
- if (ctrlCInterrupt && _optionalChain([key, 'optionalAccess', _521 => _521.name]) === "c" && key.ctrl) {
16158
+ if (ctrlCInterrupt && _optionalChain([key, 'optionalAccess', _555 => _555.name]) === "c" && key.ctrl) {
14841
16159
  ctrlCCount += 1;
14842
16160
  if (ctrlCCount >= 2) {
14843
16161
  controller.abort();
@@ -14848,7 +16166,7 @@ ${parts.join("\n")}`
14848
16166
  return;
14849
16167
  }
14850
16168
  if (enableQueue) {
14851
- if (_optionalChain([key, 'optionalAccess', _522 => _522.name]) === "return" || _optionalChain([key, 'optionalAccess', _523 => _523.name]) === "enter") {
16169
+ if (_optionalChain([key, 'optionalAccess', _556 => _556.name]) === "return" || _optionalChain([key, 'optionalAccess', _557 => _557.name]) === "enter") {
14852
16170
  if (this.queueInput.trim()) {
14853
16171
  const text = this.queueInput.trim();
14854
16172
  this.queueInput = "";
@@ -14864,12 +16182,12 @@ ${parts.join("\n")}`
14864
16182
  }
14865
16183
  return;
14866
16184
  }
14867
- if (_optionalChain([key, 'optionalAccess', _524 => _524.name]) === "backspace") {
16185
+ if (_optionalChain([key, 'optionalAccess', _558 => _558.name]) === "backspace") {
14868
16186
  this.queueInput = this.queueInput.slice(0, -1);
14869
16187
  this.updateInputLine();
14870
16188
  return;
14871
16189
  }
14872
- if (_optionalChain([key, 'optionalAccess', _525 => _525.ctrl]) || _optionalChain([key, 'optionalAccess', _526 => _526.meta])) {
16190
+ if (_optionalChain([key, 'optionalAccess', _559 => _559.ctrl]) || _optionalChain([key, 'optionalAccess', _560 => _560.meta])) {
14873
16191
  return;
14874
16192
  }
14875
16193
  if (_str) {
@@ -15000,8 +16318,8 @@ ${parts.join("\n")}`
15000
16318
  async submitSessionFailureBugReport(error, retryAttempt, maxRetries) {
15001
16319
  try {
15002
16320
  const history = this.conversation.history();
15003
- const recentToolCalls = history.filter((m) => m.role === "assistant" && m.tool_calls).slice(-3).flatMap((m) => _optionalChain([m, 'access', _527 => _527.tool_calls, 'optionalAccess', _528 => _528.map, 'call', _529 => _529((tc) => _optionalChain([tc, 'access', _530 => _530.function, 'optionalAccess', _531 => _531.name]))]) || []).filter(Boolean);
15004
- const model = _nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _532 => _532.model])));
16321
+ const recentToolCalls = history.filter((m) => m.role === "assistant" && m.tool_calls).slice(-3).flatMap((m) => _optionalChain([m, 'access', _561 => _561.tool_calls, 'optionalAccess', _562 => _562.map, 'call', _563 => _563((tc) => _optionalChain([tc, 'access', _564 => _564.function, 'optionalAccess', _565 => _565.name]))]) || []).filter(Boolean);
16322
+ const model = _nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _566 => _566.model])));
15005
16323
  await this.telemetryManager.trackSessionFailureBug({
15006
16324
  error,
15007
16325
  retryAttempt,
@@ -15224,7 +16542,7 @@ ${parts.join("\n")}`
15224
16542
  const elapsed = this.formatElapsedTime(this.taskStartedAt);
15225
16543
  const sessionTotal = this.sessionTokensUsed + this.totalTokensUsed;
15226
16544
  const tokens = this.formatTokens(sessionTotal);
15227
- const queueCount = _nullishCoalesce(_optionalChain([this, 'access', _533 => _533.inkRenderer, 'optionalAccess', _534 => _534.getQueueCount, 'call', _535 => _535()]), () => ( this.persistentInput.getQueueLength()));
16545
+ const queueCount = _nullishCoalesce(_optionalChain([this, 'access', _567 => _567.inkRenderer, 'optionalAccess', _568 => _568.getQueueCount, 'call', _569 => _569()]), () => ( this.persistentInput.getQueueLength()));
15228
16546
  const queueHint = queueCount > 0 ? ` [${queueCount} queued]` : "";
15229
16547
  const statusLine = `Working... (esc to interrupt \xB7 ${elapsed} \xB7 ${tokens}${queueHint})`;
15230
16548
  if (this.inkRenderer) {
@@ -15264,7 +16582,7 @@ ${_chalk2.default.gray("\u203A")} ${inputPreview}${_chalk2.default.gray("\u258B"
15264
16582
  return;
15265
16583
  }
15266
16584
  if (tools) {
15267
- const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _536 => _536.model]))), () => ( "unconfigured"));
16585
+ const model = _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([_chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider), 'optionalAccess', _570 => _570.model]))), () => ( "unconfigured"));
15268
16586
  const usage = calculateContextUsage(
15269
16587
  messages,
15270
16588
  tools,
@@ -15278,9 +16596,28 @@ ${_chalk2.default.gray("\u203A")} ${inputPreview}${_chalk2.default.gray("\u258B"
15278
16596
  }
15279
16597
  this.emitStatus();
15280
16598
  }
16599
+ /**
16600
+ * Ensure stdin is in a known good state for readline input.
16601
+ * This is called after operations that may interfere with stdin state,
16602
+ * such as hook execution with shell: true.
16603
+ */
16604
+ ensureStdinReady() {
16605
+ const stdin = process.stdin;
16606
+ if (!stdin.isTTY) return;
16607
+ try {
16608
+ if (typeof stdin.setRawMode === "function" && stdin.isRaw) {
16609
+ stdin.setRawMode(false);
16610
+ }
16611
+ if (stdin.isPaused()) {
16612
+ stdin.resume();
16613
+ }
16614
+ safeEmitKeypressEvents(stdin);
16615
+ } catch (e85) {
16616
+ }
16617
+ }
15281
16618
  formatStatusLine() {
15282
16619
  const percent = Number.isFinite(this.contextPercentLeft) ? Math.max(0, Math.min(100, this.contextPercentLeft)) : 100;
15283
- const queueCount = _nullishCoalesce(_optionalChain([this, 'access', _537 => _537.inkRenderer, 'optionalAccess', _538 => _538.getQueueCount, 'call', _539 => _539()]), () => ( this.persistentInput.getQueueLength()));
16620
+ const queueCount = _nullishCoalesce(_optionalChain([this, 'access', _571 => _571.inkRenderer, 'optionalAccess', _572 => _572.getQueueCount, 'call', _573 => _573()]), () => ( this.persistentInput.getQueueLength()));
15284
16621
  const queueStatus = queueCount > 0 ? ` \xB7 ${queueCount} queued` : "";
15285
16622
  return `${percent}% context left \xB7 / for commands \xB7 @ to mention files${queueStatus}`;
15286
16623
  }
@@ -15336,7 +16673,7 @@ ${_chalk2.default.gray("\u203A")} ${inputPreview}${_chalk2.default.gray("\u258B"
15336
16673
  this.activeProvider = provider;
15337
16674
  }
15338
16675
  async confirmDangerousAction(message, context) {
15339
- if (this.runtime.options.yes || _optionalChain([this, 'access', _540 => _540.runtime, 'access', _541 => _541.config, 'access', _542 => _542.ui, 'optionalAccess', _543 => _543.autoConfirm])) {
16676
+ if (this.runtime.options.yes || _optionalChain([this, 'access', _574 => _574.runtime, 'access', _575 => _575.config, 'access', _576 => _576.ui, 'optionalAccess', _577 => _577.autoConfirm])) {
15340
16677
  return true;
15341
16678
  }
15342
16679
  if (this.confirmationCallback) {
@@ -15346,9 +16683,9 @@ ${_chalk2.default.gray("\u203A")} ${inputPreview}${_chalk2.default.gray("\u258B"
15346
16683
  return confirm(message);
15347
16684
  }
15348
16685
  this.stopStatusUpdates();
15349
- const spinnerWasSpinning = _optionalChain([this, 'access', _544 => _544.runtime, 'access', _545 => _545.spinner, 'optionalAccess', _546 => _546.isSpinning]);
16686
+ const spinnerWasSpinning = _optionalChain([this, 'access', _578 => _578.runtime, 'access', _579 => _579.spinner, 'optionalAccess', _580 => _580.isSpinning]);
15350
16687
  if (spinnerWasSpinning) {
15351
- _optionalChain([this, 'access', _547 => _547.runtime, 'access', _548 => _548.spinner, 'optionalAccess', _549 => _549.stop, 'call', _550 => _550()]);
16688
+ _optionalChain([this, 'access', _581 => _581.runtime, 'access', _582 => _582.spinner, 'optionalAccess', _583 => _583.stop, 'call', _584 => _584()]);
15352
16689
  }
15353
16690
  this.persistentInput.pause();
15354
16691
  if (this.inkRenderer) {
@@ -15409,7 +16746,7 @@ ${_chalk2.default.gray("\u203A")} ${inputPreview}${_chalk2.default.gray("\u258B"
15409
16746
  getStatusSnapshot() {
15410
16747
  const providerSettings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, this.runtime.config, this.activeProvider);
15411
16748
  return {
15412
- model: _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _551 => _551.model]))), () => ( "unconfigured")),
16749
+ model: _nullishCoalesce(_nullishCoalesce(this.runtime.options.model, () => ( _optionalChain([providerSettings, 'optionalAccess', _585 => _585.model]))), () => ( "unconfigured")),
15413
16750
  workspace: this.runtime.workspaceRoot,
15414
16751
  contextPercent: this.contextPercentLeft,
15415
16752
  tokensUsed: this.totalTokensUsed
@@ -15498,7 +16835,7 @@ var PYTHON_FRAMEWORKS = {
15498
16835
  tensorflow: ["tensorflow"],
15499
16836
  pytorch: ["torch"]
15500
16837
  };
15501
- var ProjectAnalyzer = class {
16838
+ var ProjectAnalyzer2 = class {
15502
16839
  constructor(projectRoot) {
15503
16840
  this.projectRoot = projectRoot;
15504
16841
  }
@@ -15595,7 +16932,7 @@ var ProjectAnalyzer = class {
15595
16932
  if (allDeps.eslint || allDeps.prettier || allDeps.biome) {
15596
16933
  analysis.patterns.push("linting");
15597
16934
  }
15598
- } catch (e76) {
16935
+ } catch (e86) {
15599
16936
  }
15600
16937
  }
15601
16938
  /**
@@ -15620,7 +16957,7 @@ var ProjectAnalyzer = class {
15620
16957
  analysis.hasTests = true;
15621
16958
  analysis.patterns.push("testing");
15622
16959
  }
15623
- } catch (e77) {
16960
+ } catch (e87) {
15624
16961
  }
15625
16962
  }
15626
16963
  if (await _fsextra2.default.pathExists(pyprojectPath)) {
@@ -15689,7 +17026,7 @@ var ProjectAnalyzer = class {
15689
17026
  }
15690
17027
  }
15691
17028
  }
15692
- } catch (e78) {
17029
+ } catch (e88) {
15693
17030
  }
15694
17031
  }
15695
17032
  await walk(this.projectRoot, 0);
@@ -15805,21 +17142,21 @@ async function generateAutoSkills(analysis, llm) {
15805
17142
  let skills = [];
15806
17143
  try {
15807
17144
  skills = JSON.parse(content);
15808
- } catch (e79) {
17145
+ } catch (e89) {
15809
17146
  const jsonMatch = content.match(/\[[\s\S]*\]/);
15810
17147
  if (!jsonMatch) {
15811
17148
  return [];
15812
17149
  }
15813
17150
  try {
15814
17151
  skills = JSON.parse(jsonMatch[0]);
15815
- } catch (e80) {
17152
+ } catch (e90) {
15816
17153
  return [];
15817
17154
  }
15818
17155
  }
15819
17156
  return skills.filter(
15820
17157
  (s) => s && typeof s.name === "string" && typeof s.description === "string" && typeof s.body === "string" && /^[a-z0-9-]+$/.test(s.name)
15821
17158
  );
15822
- } catch (e81) {
17159
+ } catch (e91) {
15823
17160
  return [];
15824
17161
  }
15825
17162
  }
@@ -15842,7 +17179,7 @@ allowed-tools: ${skill.allowedTools.join(" ")}`;
15842
17179
  const content = frontmatter + skill.body + "\n";
15843
17180
  await _fsextra2.default.writeFile(skillPath, content, "utf-8");
15844
17181
  return true;
15845
- } catch (e82) {
17182
+ } catch (e92) {
15846
17183
  return false;
15847
17184
  }
15848
17185
  }
@@ -15853,11 +17190,11 @@ async function runAutoSkillGeneration(workspaceRoot, llm) {
15853
17190
  skills: []
15854
17191
  };
15855
17192
  console.log(_chalk2.default.cyan("Analyzing project structure..."));
15856
- const analyzer = new ProjectAnalyzer(workspaceRoot);
17193
+ const analyzer = new ProjectAnalyzer2(workspaceRoot);
15857
17194
  let analysis;
15858
17195
  try {
15859
17196
  analysis = await analyzer.analyze();
15860
- } catch (e83) {
17197
+ } catch (e93) {
15861
17198
  result.error = "Failed to analyze project";
15862
17199
  return result;
15863
17200
  }
@@ -16021,7 +17358,7 @@ function parseRequest(line) {
16021
17358
  let parsed;
16022
17359
  try {
16023
17360
  parsed = JSON.parse(trimmed);
16024
- } catch (e84) {
17361
+ } catch (e94) {
16025
17362
  return {
16026
17363
  type: "error",
16027
17364
  code: JSON_RPC_ERROR_CODES.PARSE_ERROR,
@@ -16228,7 +17565,7 @@ var RPCAdapter = class {
16228
17565
  this.model = model;
16229
17566
  this.workspace = workspace;
16230
17567
  this.sessionId = generateId("session");
16231
- this.imageManager = _nullishCoalesce(_optionalChain([agent, 'access', _552 => _552.getImageManager, 'optionalCall', _553 => _553()]), () => ( new ImageManager()));
17568
+ this.imageManager = _nullishCoalesce(_optionalChain([agent, 'access', _586 => _586.getImageManager, 'optionalCall', _587 => _587()]), () => ( new ImageManager()));
16232
17569
  agent.setStatusListener((snapshot) => {
16233
17570
  this.contextPercent = snapshot.contextPercent;
16234
17571
  this.model = snapshot.model;
@@ -16254,7 +17591,7 @@ var RPCAdapter = class {
16254
17591
  model: this.model,
16255
17592
  workspace: this.workspace,
16256
17593
  contextPercent: this.contextPercent,
16257
- messageCount: _nullishCoalesce(_optionalChain([this, 'access', _554 => _554.conversation, 'optionalAccess', _555 => _555.history, 'call', _556 => _556(), 'access', _557 => _557.length]), () => ( 0))
17594
+ messageCount: _nullishCoalesce(_optionalChain([this, 'access', _588 => _588.conversation, 'optionalAccess', _589 => _589.history, 'call', _590 => _590(), 'access', _591 => _591.length]), () => ( 0))
16258
17595
  };
16259
17596
  }
16260
17597
  /**
@@ -16291,7 +17628,7 @@ var RPCAdapter = class {
16291
17628
  });
16292
17629
  try {
16293
17630
  const imagePlaceholders = [];
16294
- process.stderr.write(`[RPC] handlePrompt: images=${_optionalChain([params, 'access', _558 => _558.images, 'optionalAccess', _559 => _559.length]) || 0}, hasImageManager=${!!this.imageManager}, model=${this.model}
17631
+ process.stderr.write(`[RPC] handlePrompt: images=${_optionalChain([params, 'access', _592 => _592.images, 'optionalAccess', _593 => _593.length]) || 0}, hasImageManager=${!!this.imageManager}, model=${this.model}
16295
17632
  `);
16296
17633
  if (params.images && params.images.length > 0) {
16297
17634
  if (!supportsVision(this.model)) {
@@ -16310,7 +17647,7 @@ var RPCAdapter = class {
16310
17647
  `);
16311
17648
  for (const img of params.images) {
16312
17649
  try {
16313
- process.stderr.write(`[RPC] Image: mimeType=${img.mimeType}, dataLength=${_optionalChain([img, 'access', _560 => _560.data, 'optionalAccess', _561 => _561.length]) || 0}
17650
+ process.stderr.write(`[RPC] Image: mimeType=${img.mimeType}, dataLength=${_optionalChain([img, 'access', _594 => _594.data, 'optionalAccess', _595 => _595.length]) || 0}
16314
17651
  `);
16315
17652
  if (!isValidImageMimeType(img.mimeType)) {
16316
17653
  process.stderr.write(`[RPC] Invalid MIME type: ${img.mimeType}
@@ -16363,7 +17700,7 @@ ${instruction}`;
16363
17700
  process.stderr.write(`[RPC] WARNING: Images provided but no placeholders generated!
16364
17701
  `);
16365
17702
  }
16366
- if (_optionalChain([params, 'access', _562 => _562.context, 'optionalAccess', _563 => _563.selection])) {
17703
+ if (_optionalChain([params, 'access', _596 => _596.context, 'optionalAccess', _597 => _597.selection])) {
16367
17704
  const sel = params.context.selection;
16368
17705
  instruction = `${instruction}
16369
17706
 
@@ -16454,6 +17791,22 @@ ${sel.text}
16454
17791
  }
16455
17792
  process.stderr.write(`[RPC DEBUG] Instruction completed, success=${success}, content length=${this.currentMessageContent.length}
16456
17793
  `);
17794
+ const turnDuration = this.turnStartTime ? Date.now() - this.turnStartTime : 0;
17795
+ const hookManager = _optionalChain([this, 'access', _598 => _598.agent, 'optionalAccess', _599 => _599.getHookManager, 'optionalCall', _600 => _600()]);
17796
+ if (hookManager) {
17797
+ const snapshot2 = _optionalChain([this, 'access', _601 => _601.agent, 'optionalAccess', _602 => _602.getStatusSnapshot, 'call', _603 => _603()]);
17798
+ await hookManager.executeHooks("stop", {
17799
+ sessionId: this.sessionId || void 0,
17800
+ turnDuration,
17801
+ tokensUsed: _nullishCoalesce(_optionalChain([snapshot2, 'optionalAccess', _604 => _604.tokensUsed]), () => ( 0))
17802
+ });
17803
+ this.emitHookStop(
17804
+ _nullishCoalesce(_optionalChain([snapshot2, 'optionalAccess', _605 => _605.tokensUsed]), () => ( 0)),
17805
+ 0,
17806
+ // toolCallsCount - not tracked per turn currently
17807
+ turnDuration
17808
+ );
17809
+ }
16457
17810
  } catch (err) {
16458
17811
  const errorMessage = err instanceof Error ? err.message : String(err);
16459
17812
  const errorStack = err instanceof Error ? err.stack : "";
@@ -16475,12 +17828,12 @@ ${sel.text}
16475
17828
  timestamp: createTimestamp()
16476
17829
  });
16477
17830
  const durationMs = this.turnStartTime ? Date.now() - this.turnStartTime : void 0;
16478
- const snapshot = _optionalChain([this, 'access', _564 => _564.agent, 'optionalAccess', _565 => _565.getStatusSnapshot, 'call', _566 => _566()]);
17831
+ const snapshot = _optionalChain([this, 'access', _606 => _606.agent, 'optionalAccess', _607 => _607.getStatusSnapshot, 'call', _608 => _608()]);
16479
17832
  writeNotification(RPC_NOTIFICATIONS.TURN_END, {
16480
17833
  turnId: this.currentTurnId,
16481
17834
  timestamp: createTimestamp(),
16482
17835
  contextPercent: this.contextPercent,
16483
- tokensUsed: _optionalChain([snapshot, 'optionalAccess', _567 => _567.tokensUsed]),
17836
+ tokensUsed: _optionalChain([snapshot, 'optionalAccess', _609 => _609.tokensUsed]),
16484
17837
  durationMs
16485
17838
  });
16486
17839
  this.status = "idle";
@@ -16491,12 +17844,12 @@ ${sel.text}
16491
17844
  return { success };
16492
17845
  } catch (error) {
16493
17846
  const durationMs = this.turnStartTime ? Date.now() - this.turnStartTime : void 0;
16494
- const snapshot = _optionalChain([this, 'access', _568 => _568.agent, 'optionalAccess', _569 => _569.getStatusSnapshot, 'call', _570 => _570()]);
17847
+ const snapshot = _optionalChain([this, 'access', _610 => _610.agent, 'optionalAccess', _611 => _611.getStatusSnapshot, 'call', _612 => _612()]);
16495
17848
  writeNotification(RPC_NOTIFICATIONS.TURN_END, {
16496
17849
  turnId: this.currentTurnId,
16497
17850
  timestamp: createTimestamp(),
16498
17851
  contextPercent: this.contextPercent,
16499
- tokensUsed: _optionalChain([snapshot, 'optionalAccess', _571 => _571.tokensUsed]),
17852
+ tokensUsed: _optionalChain([snapshot, 'optionalAccess', _613 => _613.tokensUsed]),
16500
17853
  durationMs
16501
17854
  });
16502
17855
  this.status = "idle";
@@ -16535,12 +17888,12 @@ ${sel.text}
16535
17888
  }
16536
17889
  if (this.currentTurnId) {
16537
17890
  const durationMs = this.turnStartTime ? Date.now() - this.turnStartTime : void 0;
16538
- const snapshot = _optionalChain([this, 'access', _572 => _572.agent, 'optionalAccess', _573 => _573.getStatusSnapshot, 'call', _574 => _574()]);
17891
+ const snapshot = _optionalChain([this, 'access', _614 => _614.agent, 'optionalAccess', _615 => _615.getStatusSnapshot, 'call', _616 => _616()]);
16539
17892
  writeNotification(RPC_NOTIFICATIONS.TURN_END, {
16540
17893
  turnId: this.currentTurnId,
16541
17894
  timestamp: createTimestamp(),
16542
17895
  contextPercent: this.contextPercent,
16543
- tokensUsed: _optionalChain([snapshot, 'optionalAccess', _575 => _575.tokensUsed]),
17896
+ tokensUsed: _optionalChain([snapshot, 'optionalAccess', _617 => _617.tokensUsed]),
16544
17897
  durationMs
16545
17898
  });
16546
17899
  }
@@ -16559,10 +17912,10 @@ ${sel.text}
16559
17912
  handleReset(requestId) {
16560
17913
  if (this.conversation) {
16561
17914
  const history = this.conversation.history();
16562
- const systemPrompt = _nullishCoalesce(_optionalChain([history, 'access', _576 => _576.find, 'call', _577 => _577((m) => m.role === "system"), 'optionalAccess', _578 => _578.content]), () => ( ""));
17915
+ const systemPrompt = _nullishCoalesce(_optionalChain([history, 'access', _618 => _618.find, 'call', _619 => _619((m) => m.role === "system"), 'optionalAccess', _620 => _620.content]), () => ( ""));
16563
17916
  this.conversation.reset(systemPrompt);
16564
17917
  }
16565
- _optionalChain([this, 'access', _579 => _579.imageManager, 'optionalAccess', _580 => _580.clear, 'call', _581 => _581()]);
17918
+ _optionalChain([this, 'access', _621 => _621.imageManager, 'optionalAccess', _622 => _622.clear, 'call', _623 => _623()]);
16566
17919
  this.sessionId = generateId("session");
16567
17920
  this.status = "idle";
16568
17921
  this.currentTurnId = null;
@@ -16922,7 +18275,7 @@ ${sel.text}
16922
18275
  * Handle changes decision from client (accept/reject)
16923
18276
  */
16924
18277
  async handleChangesDecision(requestId, params) {
16925
- const fileManager = _optionalChain([this, 'access', _582 => _582.agent, 'optionalAccess', _583 => _583.getFileManager, 'optionalCall', _584 => _584()]);
18278
+ const fileManager = _optionalChain([this, 'access', _624 => _624.agent, 'optionalAccess', _625 => _625.getFileManager, 'optionalCall', _626 => _626()]);
16926
18279
  if (!fileManager) {
16927
18280
  return {
16928
18281
  success: false,
@@ -16974,7 +18327,7 @@ ${sel.text}
16974
18327
  const cache = new CommunitySkillsCache();
16975
18328
  const fetcher = new GitHubRegistryFetcher();
16976
18329
  let registry;
16977
- if (_optionalChain([params, 'optionalAccess', _585 => _585.forceRefresh])) {
18330
+ if (_optionalChain([params, 'optionalAccess', _627 => _627.forceRefresh])) {
16978
18331
  process.stderr.write("[RPC] Force refreshing skills registry from GitHub\n");
16979
18332
  registry = await fetcher.fetchRegistry();
16980
18333
  await cache.setRegistry(registry);
@@ -17021,7 +18374,7 @@ ${sel.text}
17021
18374
  */
17022
18375
  async handleInstallSkill(requestId, params) {
17023
18376
  try {
17024
- const skillsRegistry = _optionalChain([this, 'access', _586 => _586.agent, 'optionalAccess', _587 => _587.getSkillsRegistry, 'optionalCall', _588 => _588()]);
18377
+ const skillsRegistry = _optionalChain([this, 'access', _628 => _628.agent, 'optionalAccess', _629 => _629.getSkillsRegistry, 'optionalCall', _630 => _630()]);
17025
18378
  if (!skillsRegistry) {
17026
18379
  return {
17027
18380
  success: false,
@@ -17125,7 +18478,7 @@ ${sel.text}
17125
18478
  * Handle output events from the agent
17126
18479
  */
17127
18480
  handleAgentOutput(event) {
17128
- process.stderr.write(`[RPC DEBUG] handleAgentOutput: type=${event.type}, content length=${_nullishCoalesce(_optionalChain([event, 'access', _589 => _589.content, 'optionalAccess', _590 => _590.length]), () => ( 0))}
18481
+ process.stderr.write(`[RPC DEBUG] handleAgentOutput: type=${event.type}, content length=${_nullishCoalesce(_optionalChain([event, 'access', _631 => _631.content, 'optionalAccess', _632 => _632.length]), () => ( 0))}
17129
18482
  `);
17130
18483
  switch (event.type) {
17131
18484
  case "thinking":
@@ -17233,14 +18586,14 @@ ${sel.text}
17233
18586
  toolCalls = msg.tool_calls.map((tc) => {
17234
18587
  let args = {};
17235
18588
  try {
17236
- if (_optionalChain([tc, 'access', _591 => _591.function, 'optionalAccess', _592 => _592.arguments])) {
18589
+ if (_optionalChain([tc, 'access', _633 => _633.function, 'optionalAccess', _634 => _634.arguments])) {
17237
18590
  args = JSON.parse(tc.function.arguments);
17238
18591
  }
17239
- } catch (e85) {
18592
+ } catch (e95) {
17240
18593
  }
17241
18594
  return {
17242
18595
  id: tc.id,
17243
- name: _nullishCoalesce(_optionalChain([tc, 'access', _593 => _593.function, 'optionalAccess', _594 => _594.name]), () => ( "unknown")),
18596
+ name: _nullishCoalesce(_optionalChain([tc, 'access', _635 => _635.function, 'optionalAccess', _636 => _636.name]), () => ( "unknown")),
17244
18597
  args
17245
18598
  };
17246
18599
  });
@@ -17299,18 +18652,18 @@ async function runRpcMode(options) {
17299
18652
  adapter.initialize(
17300
18653
  agent,
17301
18654
  conversation,
17302
- _nullishCoalesce(_nullishCoalesce(options.model, () => ( _optionalChain([config, 'access', _595 => _595.openrouter, 'optionalAccess', _596 => _596.model]))), () => ( "unknown")),
18655
+ _nullishCoalesce(_nullishCoalesce(options.model, () => ( _optionalChain([config, 'access', _637 => _637.openrouter, 'optionalAccess', _638 => _638.model]))), () => ( "unknown")),
17303
18656
  workspaceRoot
17304
18657
  );
17305
18658
  agent.setConfirmationCallback(async (message, context) => {
17306
18659
  if (!adapter) {
17307
18660
  throw new Error("RPC adapter not initialized");
17308
18661
  }
17309
- const tool = _nullishCoalesce(_optionalChain([context, 'optionalAccess', _597 => _597.tool]), () => ( "action"));
18662
+ const tool = _nullishCoalesce(_optionalChain([context, 'optionalAccess', _639 => _639.tool]), () => ( "action"));
17310
18663
  const description = message;
17311
18664
  const permContext = {};
17312
- if (_optionalChain([context, 'optionalAccess', _598 => _598.command])) permContext.command = context.command;
17313
- if (_optionalChain([context, 'optionalAccess', _599 => _599.path])) permContext.path = context.path;
18665
+ if (_optionalChain([context, 'optionalAccess', _640 => _640.command])) permContext.command = context.command;
18666
+ if (_optionalChain([context, 'optionalAccess', _641 => _641.path])) permContext.path = context.path;
17314
18667
  return adapter.requestPermission(tool, description, permContext);
17315
18668
  });
17316
18669
  const reader = new LineReader(process.stdin);
@@ -17329,7 +18682,7 @@ async function runRpcMode(options) {
17329
18682
  } catch (error) {
17330
18683
  const message = error instanceof Error ? error.message : String(error);
17331
18684
  writeErrorResponse(null, JSON_RPC_ERROR_CODES.INTERNAL_ERROR, `Initialization error: ${message}`);
17332
- _optionalChain([adapter, 'optionalAccess', _600 => _600.shutdown, 'call', _601 => _601("error")]);
18685
+ _optionalChain([adapter, 'optionalAccess', _642 => _642.shutdown, 'call', _643 => _643("error")]);
17333
18686
  process.exit(1);
17334
18687
  }
17335
18688
  }
@@ -17362,7 +18715,7 @@ async function handleSingleRequest(request, adapter) {
17362
18715
  switch (method) {
17363
18716
  case RPC_METHODS.PROMPT: {
17364
18717
  const promptParams = params;
17365
- if (!_optionalChain([promptParams, 'optionalAccess', _602 => _602.message])) {
18718
+ if (!_optionalChain([promptParams, 'optionalAccess', _644 => _644.message])) {
17366
18719
  if (shouldRespond) {
17367
18720
  return createErrorResponse(
17368
18721
  id,
@@ -17404,12 +18757,12 @@ async function handleSingleRequest(request, adapter) {
17404
18757
  }
17405
18758
  case RPC_METHODS.GET_MESSAGES: {
17406
18759
  const messagesParams = params;
17407
- result = adapter.handleGetMessages(id, _optionalChain([messagesParams, 'optionalAccess', _603 => _603.limit]));
18760
+ result = adapter.handleGetMessages(id, _optionalChain([messagesParams, 'optionalAccess', _645 => _645.limit]));
17408
18761
  break;
17409
18762
  }
17410
18763
  case RPC_METHODS.PERMISSION_RESPONSE: {
17411
18764
  const permParams = params;
17412
- if (!_optionalChain([permParams, 'optionalAccess', _604 => _604.requestId]) || _optionalChain([permParams, 'optionalAccess', _605 => _605.allowed]) === void 0) {
18765
+ if (!_optionalChain([permParams, 'optionalAccess', _646 => _646.requestId]) || _optionalChain([permParams, 'optionalAccess', _647 => _647.allowed]) === void 0) {
17413
18766
  if (shouldRespond) {
17414
18767
  return createErrorResponse(
17415
18768
  id,
@@ -17424,7 +18777,7 @@ async function handleSingleRequest(request, adapter) {
17424
18777
  }
17425
18778
  case RPC_METHODS.PERMISSION_ACKNOWLEDGED: {
17426
18779
  const ackParams = params;
17427
- if (!_optionalChain([ackParams, 'optionalAccess', _606 => _606.requestId])) {
18780
+ if (!_optionalChain([ackParams, 'optionalAccess', _648 => _648.requestId])) {
17428
18781
  if (shouldRespond) {
17429
18782
  return createErrorResponse(
17430
18783
  id,
@@ -17439,7 +18792,7 @@ async function handleSingleRequest(request, adapter) {
17439
18792
  }
17440
18793
  case RPC_METHODS.CHANGES_DECISION: {
17441
18794
  const decisionParams = params;
17442
- if (!_optionalChain([decisionParams, 'optionalAccess', _607 => _607.batchId]) || !_optionalChain([decisionParams, 'optionalAccess', _608 => _608.action])) {
18795
+ if (!_optionalChain([decisionParams, 'optionalAccess', _649 => _649.batchId]) || !_optionalChain([decisionParams, 'optionalAccess', _650 => _650.action])) {
17443
18796
  if (shouldRespond) {
17444
18797
  return createErrorResponse(
17445
18798
  id,
@@ -17459,7 +18812,7 @@ async function handleSingleRequest(request, adapter) {
17459
18812
  }
17460
18813
  case RPC_METHODS.INSTALL_SKILL: {
17461
18814
  const installParams = params;
17462
- if (!_optionalChain([installParams, 'optionalAccess', _609 => _609.skillName]) || !_optionalChain([installParams, 'optionalAccess', _610 => _610.scope])) {
18815
+ if (!_optionalChain([installParams, 'optionalAccess', _651 => _651.skillName]) || !_optionalChain([installParams, 'optionalAccess', _652 => _652.scope])) {
17463
18816
  if (shouldRespond) {
17464
18817
  return createErrorResponse(
17465
18818
  id,
@@ -17504,20 +18857,20 @@ async function handleSingleRequest(request, adapter) {
17504
18857
  process.title = "autohand";
17505
18858
  function getGitCommit() {
17506
18859
  if (true) {
17507
- return "5392e8c";
18860
+ return "fc318c0";
17508
18861
  }
17509
18862
  try {
17510
18863
  return _child_process.execSync.call(void 0, "git rev-parse --short HEAD", { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
17511
- } catch (e86) {
18864
+ } catch (e96) {
17512
18865
  return "unknown";
17513
18866
  }
17514
18867
  }
17515
18868
  function getVersionString() {
17516
18869
  const commit = getGitCommit();
17517
- return `${_chunkXJZYEURAcjs.package_default.version} (${commit})`;
18870
+ return `${_chunkJYTXG6OVcjs.package_default.version} (${commit})`;
17518
18871
  }
17519
18872
  async function validateAuthOnStartup(config) {
17520
- if (!_optionalChain([config, 'access', _611 => _611.auth, 'optionalAccess', _612 => _612.token])) {
18873
+ if (!_optionalChain([config, 'access', _653 => _653.auth, 'optionalAccess', _654 => _654.token])) {
17521
18874
  return void 0;
17522
18875
  }
17523
18876
  if (config.auth.expiresAt) {
@@ -17526,7 +18879,7 @@ async function validateAuthOnStartup(config) {
17526
18879
  config.auth = void 0;
17527
18880
  try {
17528
18881
  await _chunkQMVTT55Ycjs.saveConfig.call(void 0, config);
17529
- } catch (e87) {
18882
+ } catch (e97) {
17530
18883
  }
17531
18884
  return void 0;
17532
18885
  }
@@ -17538,16 +18891,16 @@ async function validateAuthOnStartup(config) {
17538
18891
  config.auth = void 0;
17539
18892
  try {
17540
18893
  await _chunkQMVTT55Ycjs.saveConfig.call(void 0, config);
17541
- } catch (e88) {
18894
+ } catch (e98) {
17542
18895
  }
17543
18896
  return void 0;
17544
18897
  }
17545
18898
  if (result.user && config.auth) {
17546
18899
  config.auth.user = result.user;
17547
18900
  }
17548
- return _optionalChain([config, 'access', _613 => _613.auth, 'optionalAccess', _614 => _614.user]);
17549
- } catch (e89) {
17550
- return _optionalChain([config, 'access', _615 => _615.auth, 'optionalAccess', _616 => _616.user]);
18901
+ return _optionalChain([config, 'access', _655 => _655.auth, 'optionalAccess', _656 => _656.user]);
18902
+ } catch (e99) {
18903
+ return _optionalChain([config, 'access', _657 => _657.auth, 'optionalAccess', _658 => _658.user]);
17551
18904
  }
17552
18905
  }
17553
18906
  process.on("uncaughtException", (err) => {
@@ -17562,7 +18915,7 @@ process.on("unhandledRejection", (reason, promise) => {
17562
18915
  globalThis.__autohandLastError = reason;
17563
18916
  console.error("[DEBUG] Unhandled Rejection at:", promise, "reason:", reason);
17564
18917
  });
17565
- var ASCII_FRIEND = [
18918
+ var ASCII_FRIEND2 = [
17566
18919
  "\u2880\u2874\u281B\u281B\u283B\u28F7\u2844\u2800\u28E0\u2876\u281F\u281B\u283B\u28F6\u2844\u2880\u28F4\u287E\u281B\u281B\u28BF\u28E6\u2800\u2880\u28F4\u281E\u281B\u281B\u2836\u2840",
17567
18920
  "\u284E\u2800\u28B0\u28F6\u2846\u2808\u28FF\u28F4\u28FF\u2801\u28F4\u28F6\u2844\u2818\u28FF\u28FE\u284F\u2880\u28F6\u28E6\u2800\u28BB\u2847\u28FF\u2803\u28A0\u28F6\u2846\u2800\u28B9",
17568
18921
  "\u28A7\u2800\u2818\u281B\u2803\u28A0\u287F\u2819\u28FF\u2840\u2819\u281B\u2803\u28F0\u287F\u28BB\u28E7\u2808\u281B\u281B\u2880\u28FE\u2807\u28BB\u28C6\u2808\u281B\u280B\u2800\u287C",
@@ -17573,7 +18926,7 @@ var ASCII_FRIEND = [
17573
18926
  "\u2808\u28BF\u28E6\u28E4\u28F4\u287F\u2803\u2800\u2819\u28B7\u28E6\u28E4\u28F6\u287F\u2801\u2808\u283B\u28F7\u28E4\u28E4\u287E\u281B\u2800\u2808\u28BF\u28E6\u28E4\u28E4\u2834\u2801"
17574
18927
  ].join("\n");
17575
18928
  var program = new (0, _commander.Command)();
17576
- program.name("autohand").description("Autonomous LLM-powered coding agent CLI").version(getVersionString(), "-v, --version", "output the current version").option("-p, --prompt <text>", "Run a single instruction in command mode").option("--path <path>", "Workspace path to operate in").option("-y, --yes", "Auto-confirm risky actions", false).option("--dry-run", "Preview actions without applying mutations", false).option("-d, --debug", "Enable debug output (verbose logging)", false).option("--model <model>", "Override the configured LLM model").option("--config <path>", "Path to config file (default ~/.autohand/config.json)").option("--temperature <value>", "Sampling temperature", parseFloat).option("-c, --auto-commit", "Auto-commit with LLM-generated message (runs lint & test first)", false).option("--unrestricted", "Run without any approval prompts (use with caution)", false).option("--restricted", "Deny all dangerous operations automatically", false).option("--auto-skill", "Auto-generate skills based on project analysis", false).option("--skill-install [skill-name]", "Install a community skill (opens browser if no name)").option("--project", "Install skill to project level (with --skill-install)", false).option("--permissions", "Display current permission settings and exit", false).option("--patch", "Generate git patch without applying changes (requires --prompt)", false).option("--output <file>", "Output file for patch (default: stdout, used with --patch)").option("--mode <mode>", "Run mode: interactive (default) or rpc", "interactive").option("--auto-mode <prompt>", "Start autonomous development loop with the given task").option("--max-iterations <n>", "Max auto-mode iterations (default: 50)", parseInt).option("--completion-promise <text>", 'Completion marker text (default: "DONE")').option("--no-worktree", "Disable git worktree isolation in auto-mode").option("--checkpoint-interval <n>", "Git commit every N iterations (default: 5)", parseInt).option("--max-runtime <m>", "Max runtime in minutes (default: 120)", parseInt).option("--max-cost <d>", "Max API cost in dollars (default: 10)", parseFloat).action(async (opts) => {
18929
+ program.name("autohand").description("Autonomous LLM-powered coding agent CLI").version(getVersionString(), "-v, --version", "output the current version").option("-p, --prompt <text>", "Run a single instruction in command mode").option("--path <path>", "Workspace path to operate in").option("-y, --yes", "Auto-confirm risky actions", false).option("--dry-run", "Preview actions without applying mutations", false).option("-d, --debug", "Enable debug output (verbose logging)", false).option("--model <model>", "Override the configured LLM model").option("--config <path>", "Path to config file (default ~/.autohand/config.json)").option("--temperature <value>", "Sampling temperature", parseFloat).option("-c, --auto-commit", "Auto-commit with LLM-generated message (runs lint & test first)", false).option("--unrestricted", "Run without any approval prompts (use with caution)", false).option("--restricted", "Deny all dangerous operations automatically", false).option("--auto-skill", "Auto-generate skills based on project analysis", false).option("--skill-install [skill-name]", "Install a community skill (opens browser if no name)").option("--project", "Install skill to project level (with --skill-install)", false).option("--permissions", "Display current permission settings and exit", false).option("--login", "Sign in to your Autohand account", false).option("--logout", "Sign out of your Autohand account", false).option("--patch", "Generate git patch without applying changes (requires --prompt)", false).option("--output <file>", "Output file for patch (default: stdout, used with --patch)").option("--mode <mode>", "Run mode: interactive (default) or rpc", "interactive").option("--auto-mode <prompt>", "Start autonomous development loop with the given task").option("--max-iterations <n>", "Max auto-mode iterations (default: 50)", parseInt).option("--completion-promise <text>", 'Completion marker text (default: "DONE")').option("--no-worktree", "Disable git worktree isolation in auto-mode").option("--checkpoint-interval <n>", "Git commit every N iterations (default: 5)", parseInt).option("--max-runtime <m>", "Max runtime in minutes (default: 120)", parseInt).option("--max-cost <d>", "Max API cost in dollars (default: 10)", parseFloat).option("--setup", "Run the setup wizard to configure or reconfigure Autohand", false).action(async (opts) => {
17577
18930
  if (opts.skillInstall !== void 0) {
17578
18931
  await runSkillInstall(opts);
17579
18932
  return;
@@ -17582,6 +18935,34 @@ program.name("autohand").description("Autonomous LLM-powered coding agent CLI").
17582
18935
  await displayPermissions(opts);
17583
18936
  return;
17584
18937
  }
18938
+ if (opts.login) {
18939
+ const { login } = await Promise.resolve().then(() => _interopRequireWildcard(require("./login-QNJ5C42G.cjs")));
18940
+ const config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, opts.config);
18941
+ await login({ config });
18942
+ process.exit(0);
18943
+ }
18944
+ if (opts.logout) {
18945
+ const { logout } = await Promise.resolve().then(() => _interopRequireWildcard(require("./logout-MVUP7GPU.cjs")));
18946
+ const config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, opts.config);
18947
+ await logout({ config });
18948
+ process.exit(0);
18949
+ }
18950
+ if (opts.setup) {
18951
+ const config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, opts.config);
18952
+ const workspaceRoot = _chunkQMVTT55Ycjs.resolveWorkspaceRoot.call(void 0, config, opts.path);
18953
+ const wizard = new SetupWizard(workspaceRoot, config);
18954
+ const result = await wizard.run({ skipWelcome: false });
18955
+ if (result.cancelled) {
18956
+ console.log(_chalk2.default.gray("\nSetup cancelled."));
18957
+ process.exit(0);
18958
+ }
18959
+ if (result.success) {
18960
+ const newConfig = { ...config, ...result.config };
18961
+ await _chunkQMVTT55Ycjs.saveConfig.call(void 0, newConfig);
18962
+ console.log(_chalk2.default.green("\nSetup complete! Run `autohand` to start."));
18963
+ }
18964
+ process.exit(0);
18965
+ }
17585
18966
  if (opts.patch) {
17586
18967
  await runPatchMode(opts);
17587
18968
  return;
@@ -17600,59 +18981,38 @@ program.name("autohand").description("Autonomous LLM-powered coding agent CLI").
17600
18981
  program.command("resume <sessionId>").description("Resume a previous session").option("--path <path>", "Workspace path to operate in").option("--model <model>", "Override the configured LLM model").action(async (sessionId, opts) => {
17601
18982
  await runCLI({ ...opts, resumeSessionId: sessionId });
17602
18983
  });
18984
+ program.command("login").description("Sign in to your Autohand account").action(async () => {
18985
+ const { login } = await Promise.resolve().then(() => _interopRequireWildcard(require("./login-QNJ5C42G.cjs")));
18986
+ const config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, );
18987
+ await login({ config });
18988
+ process.exit(0);
18989
+ });
18990
+ program.command("logout").description("Sign out of your Autohand account").action(async () => {
18991
+ const { logout } = await Promise.resolve().then(() => _interopRequireWildcard(require("./logout-MVUP7GPU.cjs")));
18992
+ const config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, );
18993
+ await logout({ config });
18994
+ process.exit(0);
18995
+ });
17603
18996
  async function runCLI(options) {
17604
18997
  const statusPanel = null;
17605
18998
  try {
17606
18999
  let config = await _chunkQMVTT55Ycjs.loadConfig.call(void 0, options.config);
19000
+ const workspaceRoot = _chunkQMVTT55Ycjs.resolveWorkspaceRoot.call(void 0, config, options.path);
17607
19001
  const providerName = _nullishCoalesce(config.provider, () => ( "openrouter"));
17608
19002
  const providerConfig = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, config, providerName);
17609
19003
  if (!providerConfig) {
17610
- if (config.isNewConfig) {
17611
- console.log(_chalk2.default.cyan("\n\u2728 Welcome to Autohand!\n"));
17612
- console.log(_chalk2.default.gray(`Config created at: ${config.configPath}
17613
- `));
17614
- }
17615
- console.log(_chalk2.default.yellow(`No ${providerName} API key configured.
17616
- `));
17617
- let apiKey;
17618
- try {
17619
- const result = await _enquirer2.default.prompt({
17620
- type: "password",
17621
- name: "apiKey",
17622
- message: `Enter your ${providerName === "openrouter" ? "OpenRouter" : providerName} API key`,
17623
- validate: (val) => {
17624
- if (typeof val !== "string" || !val.trim()) {
17625
- return "API key is required";
17626
- }
17627
- return true;
17628
- }
17629
- });
17630
- apiKey = result.apiKey;
17631
- } catch (error) {
17632
- if (_optionalChain([error, 'optionalAccess', _617 => _617.code]) === "ERR_USE_AFTER_CLOSE" || _optionalChain([error, 'optionalAccess', _618 => _618.message, 'optionalAccess', _619 => _619.includes, 'call', _620 => _620("cancelled")])) {
17633
- console.log(_chalk2.default.gray("\nSetup cancelled."));
17634
- process.exit(0);
17635
- }
17636
- throw error;
19004
+ const wizard = new SetupWizard(workspaceRoot, config);
19005
+ const result = await wizard.run({ skipWelcome: !config.isNewConfig });
19006
+ if (result.cancelled) {
19007
+ console.log(_chalk2.default.gray("\nSetup cancelled."));
19008
+ process.exit(0);
17637
19009
  }
17638
- if (providerName === "openrouter") {
17639
- config.openrouter = {
17640
- ...config.openrouter,
17641
- apiKey: apiKey.trim(),
17642
- baseUrl: _optionalChain([config, 'access', _621 => _621.openrouter, 'optionalAccess', _622 => _622.baseUrl]) || "https://openrouter.ai/api/v1",
17643
- model: _optionalChain([config, 'access', _623 => _623.openrouter, 'optionalAccess', _624 => _624.model]) || "anthropic/claude-sonnet-4-20250514"
17644
- };
17645
- } else if (providerName === "openai") {
17646
- config.openai = {
17647
- ...config.openai,
17648
- apiKey: apiKey.trim(),
17649
- model: _optionalChain([config, 'access', _625 => _625.openai, 'optionalAccess', _626 => _626.model]) || "gpt-4o"
17650
- };
19010
+ if (result.success) {
19011
+ config = { ...config, ...result.config };
19012
+ await _chunkQMVTT55Ycjs.saveConfig.call(void 0, config);
19013
+ console.log();
17651
19014
  }
17652
- await _chunkQMVTT55Ycjs.saveConfig.call(void 0, config);
17653
- console.log(_chalk2.default.green("\u2713 API key saved to config\n"));
17654
19015
  }
17655
- const workspaceRoot = _chunkQMVTT55Ycjs.resolveWorkspaceRoot.call(void 0, config, options.path);
17656
19016
  const safetyCheck = checkWorkspaceSafety(workspaceRoot);
17657
19017
  if (!safetyCheck.safe) {
17658
19018
  printDangerousWorkspaceWarning(workspaceRoot, safetyCheck);
@@ -17664,8 +19024,8 @@ async function runCLI(options) {
17664
19024
  options
17665
19025
  };
17666
19026
  const authUser = await validateAuthOnStartup(config);
17667
- const versionCheck = _optionalChain([config, 'access', _627 => _627.ui, 'optionalAccess', _628 => _628.checkForUpdates]) !== false ? await checkForUpdates(_chunkXJZYEURAcjs.package_default.version, {
17668
- checkIntervalHours: _nullishCoalesce(_optionalChain([config, 'access', _629 => _629.ui, 'optionalAccess', _630 => _630.updateCheckInterval]), () => ( 24))
19027
+ const versionCheck = _optionalChain([config, 'access', _659 => _659.ui, 'optionalAccess', _660 => _660.checkForUpdates]) !== false ? await checkForUpdates(_chunkJYTXG6OVcjs.package_default.version, {
19028
+ checkIntervalHours: _nullishCoalesce(_optionalChain([config, 'access', _661 => _661.ui, 'optionalAccess', _662 => _662.updateCheckInterval]), () => ( 24))
17669
19029
  }) : null;
17670
19030
  printBanner();
17671
19031
  printWelcome(runtime, authUser, versionCheck);
@@ -17697,6 +19057,7 @@ async function runCLI(options) {
17697
19057
  const agent = new AutohandAgent(llmProvider, files, runtime);
17698
19058
  if (options.prompt) {
17699
19059
  await agent.runCommandMode(options.prompt);
19060
+ process.exit(0);
17700
19061
  } else if (options.resumeSessionId) {
17701
19062
  await agent.resumeSession(options.resumeSessionId);
17702
19063
  } else {
@@ -17716,7 +19077,7 @@ function printBanner() {
17716
19077
  return;
17717
19078
  }
17718
19079
  if (process.stdout.isTTY) {
17719
- console.log(_chalk2.default.gray(ASCII_FRIEND));
19080
+ console.log(_chalk2.default.gray(ASCII_FRIEND2));
17720
19081
  } else {
17721
19082
  console.log("autohand");
17722
19083
  }
@@ -17728,8 +19089,8 @@ function printWelcome(runtime, authUser, versionCheck) {
17728
19089
  const model = (() => {
17729
19090
  try {
17730
19091
  const settings = _chunkQMVTT55Ycjs.getProviderConfig.call(void 0, runtime.config);
17731
- return _nullishCoalesce(_nullishCoalesce(runtime.options.model, () => ( _optionalChain([settings, 'optionalAccess', _631 => _631.model]))), () => ( "unknown"));
17732
- } catch (e90) {
19092
+ return _nullishCoalesce(_nullishCoalesce(runtime.options.model, () => ( _optionalChain([settings, 'optionalAccess', _663 => _663.model]))), () => ( "unknown"));
19093
+ } catch (e100) {
17733
19094
  return _nullishCoalesce(runtime.options.model, () => ( "unknown"));
17734
19095
  }
17735
19096
  })();
@@ -17743,7 +19104,7 @@ function printWelcome(runtime, authUser, versionCheck) {
17743
19104
  }
17744
19105
  }
17745
19106
  console.log(versionLine);
17746
- if (_optionalChain([versionCheck, 'optionalAccess', _632 => _632.updateAvailable])) {
19107
+ if (_optionalChain([versionCheck, 'optionalAccess', _664 => _664.updateAvailable])) {
17747
19108
  console.log(_chalk2.default.gray(" \u21B3 Run: ") + _chalk2.default.cyan("curl -fsSL https://autohand.ai/install.sh | sh"));
17748
19109
  }
17749
19110
  if (authUser) {
@@ -17791,18 +19152,18 @@ async function displayPermissions(opts) {
17791
19152
  const { loadLocalProjectSettings } = await Promise.resolve().then(() => _interopRequireWildcard(require("./localProjectPermissions-75X3ZGKH.cjs")));
17792
19153
  const localSettings = await loadLocalProjectSettings(workspaceRoot);
17793
19154
  const mergedSettings = {
17794
- mode: _nullishCoalesce(_nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _633 => _633.permissions, 'optionalAccess', _634 => _634.mode]), () => ( _optionalChain([config, 'access', _635 => _635.permissions, 'optionalAccess', _636 => _636.mode]))), () => ( "interactive")),
19155
+ mode: _nullishCoalesce(_nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _665 => _665.permissions, 'optionalAccess', _666 => _666.mode]), () => ( _optionalChain([config, 'access', _667 => _667.permissions, 'optionalAccess', _668 => _668.mode]))), () => ( "interactive")),
17795
19156
  whitelist: [
17796
- ..._nullishCoalesce(_optionalChain([config, 'access', _637 => _637.permissions, 'optionalAccess', _638 => _638.whitelist]), () => ( [])),
17797
- ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _639 => _639.permissions, 'optionalAccess', _640 => _640.whitelist]), () => ( []))
19157
+ ..._nullishCoalesce(_optionalChain([config, 'access', _669 => _669.permissions, 'optionalAccess', _670 => _670.whitelist]), () => ( [])),
19158
+ ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _671 => _671.permissions, 'optionalAccess', _672 => _672.whitelist]), () => ( []))
17798
19159
  ],
17799
19160
  blacklist: [
17800
- ..._nullishCoalesce(_optionalChain([config, 'access', _641 => _641.permissions, 'optionalAccess', _642 => _642.blacklist]), () => ( [])),
17801
- ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _643 => _643.permissions, 'optionalAccess', _644 => _644.blacklist]), () => ( []))
19161
+ ..._nullishCoalesce(_optionalChain([config, 'access', _673 => _673.permissions, 'optionalAccess', _674 => _674.blacklist]), () => ( [])),
19162
+ ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _675 => _675.permissions, 'optionalAccess', _676 => _676.blacklist]), () => ( []))
17802
19163
  ],
17803
19164
  rules: [
17804
- ..._nullishCoalesce(_optionalChain([config, 'access', _645 => _645.permissions, 'optionalAccess', _646 => _646.rules]), () => ( [])),
17805
- ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _647 => _647.permissions, 'optionalAccess', _648 => _648.rules]), () => ( []))
19165
+ ..._nullishCoalesce(_optionalChain([config, 'access', _677 => _677.permissions, 'optionalAccess', _678 => _678.rules]), () => ( [])),
19166
+ ..._nullishCoalesce(_optionalChain([localSettings, 'optionalAccess', _679 => _679.permissions, 'optionalAccess', _680 => _680.rules]), () => ( []))
17806
19167
  ]
17807
19168
  };
17808
19169
  const manager = new PermissionManager2({ settings: mergedSettings });
@@ -17934,13 +19295,13 @@ async function runAutoMode(opts) {
17934
19295
  }
17935
19296
  const { AutomodeManager, getAutomodeOptions } = await Promise.resolve().then(() => _interopRequireWildcard(require("./AutomodeManager-TJSW2SQY.cjs")));
17936
19297
  const { HookManager: HookManager2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./HookManager-EOMUXKJ4.cjs")));
17937
- const { SessionManager: SessionManager2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./SessionManager-VZNWGX4O.cjs")));
19298
+ const { SessionManager: SessionManager2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./SessionManager-M5ZLCLCW.cjs")));
17938
19299
  const { MemoryManager: MemoryManager2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./MemoryManager-WO3KUZVA.cjs")));
17939
- const readline5 = await Promise.resolve().then(() => _interopRequireWildcard(require("readline")));
19300
+ const readline3 = await Promise.resolve().then(() => _interopRequireWildcard(require("readline")));
17940
19301
  const llmProvider = ProviderFactory.create(config);
17941
19302
  const files = new FileActionManager(workspaceRoot);
17942
19303
  const providerName = _nullishCoalesce(config.provider, () => ( "openrouter"));
17943
- const modelName = _nullishCoalesce(_nullishCoalesce(opts.model, () => ( _optionalChain([config, 'access', _649 => _649[providerName], 'optionalAccess', _650 => _650.model]))), () => ( "unknown"));
19304
+ const modelName = _nullishCoalesce(_nullishCoalesce(opts.model, () => ( _optionalChain([config, 'access', _681 => _681[providerName], 'optionalAccess', _682 => _682.model]))), () => ( "unknown"));
17944
19305
  const sessionManager = new SessionManager2();
17945
19306
  await sessionManager.initialize();
17946
19307
  const session = await sessionManager.createSession(workspaceRoot, modelName);
@@ -17965,7 +19326,7 @@ async function runAutoMode(opts) {
17965
19326
  console.log(_chalk2.default.gray("Worktree Isolation:"), _chalk2.default.cyan(automodeOptions.useWorktree !== false ? "enabled" : "disabled"));
17966
19327
  console.log();
17967
19328
  if (process.stdin.isTTY) {
17968
- readline5.emitKeypressEvents(process.stdin);
19329
+ readline3.emitKeypressEvents(process.stdin);
17969
19330
  process.stdin.setRawMode(true);
17970
19331
  process.stdin.on("keypress", (_str, key) => {
17971
19332
  if (key && key.name === "escape") {
@@ -18022,11 +19383,44 @@ async function runAutoMode(opts) {
18022
19383
  if (finalState) {
18023
19384
  session.metadata.automodeIterations = finalState.currentIteration;
18024
19385
  const statusText = finalState.status === "completed" ? "completed" : `ended (${finalState.status})`;
18025
- await sessionManager.closeSession(`Auto-mode ${statusText} after ${finalState.currentIteration} iterations: ${_optionalChain([opts, 'access', _651 => _651.autoMode, 'optionalAccess', _652 => _652.slice, 'call', _653 => _653(0, 50)])}...`);
19386
+ console.log(_chalk2.default.gray(`
19387
+ \u{1F4CA} Auto-mode ${statusText} after ${finalState.currentIteration} iterations`));
19388
+ }
19389
+ console.log(_chalk2.default.cyan("\n\u{1F504} Auto-mode finished. You can continue working interactively.\n"));
19390
+ console.log(_chalk2.default.gray("Press Enter to continue in interactive mode, or Ctrl+C to exit.\n"));
19391
+ const continuePromise = new Promise((resolve) => {
19392
+ if (!process.stdin.isTTY) {
19393
+ resolve(false);
19394
+ return;
19395
+ }
19396
+ readline3.emitKeypressEvents(process.stdin);
19397
+ process.stdin.setRawMode(true);
19398
+ process.stdin.resume();
19399
+ const handleKey = (_str, key) => {
19400
+ process.stdin.off("keypress", handleKey);
19401
+ if (process.stdin.isTTY) {
19402
+ process.stdin.setRawMode(false);
19403
+ }
19404
+ if (key && key.ctrl && key.name === "c") {
19405
+ resolve(false);
19406
+ } else if (key && key.name === "return") {
19407
+ resolve(true);
19408
+ } else {
19409
+ resolve(true);
19410
+ }
19411
+ };
19412
+ process.stdin.on("keypress", handleKey);
19413
+ });
19414
+ const shouldContinue = await continuePromise;
19415
+ if (!shouldContinue) {
19416
+ const statusText = _optionalChain([finalState, 'optionalAccess', _683 => _683.status]) === "completed" ? "completed" : `ended (${_optionalChain([finalState, 'optionalAccess', _684 => _684.status])})`;
19417
+ await sessionManager.closeSession(`Auto-mode ${statusText} after ${_nullishCoalesce(_optionalChain([finalState, 'optionalAccess', _685 => _685.currentIteration]), () => ( 0))} iterations: ${_optionalChain([opts, 'access', _686 => _686.autoMode, 'optionalAccess', _687 => _687.slice, 'call', _688 => _688(0, 50)])}...`);
18026
19418
  console.log(_chalk2.default.gray(`
18027
19419
  \u{1F4C1} Session saved: ${session.metadata.sessionId}`));
19420
+ process.exit(_optionalChain([finalState, 'optionalAccess', _689 => _689.status]) === "completed" ? 0 : 1);
18028
19421
  }
18029
- process.exit(_optionalChain([finalState, 'optionalAccess', _654 => _654.status]) === "completed" ? 0 : 1);
19422
+ console.log(_chalk2.default.cyan("\n\u25B6\uFE0F Continuing in interactive mode...\n"));
19423
+ await agent.runInteractive();
18030
19424
  } catch (error) {
18031
19425
  if (process.stdin.isTTY) {
18032
19426
  process.stdin.setRawMode(false);