oroute-cli 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/oroute.cjs +1156 -259
  2. package/package.json +3 -2
package/dist/oroute.cjs CHANGED
@@ -23388,7 +23388,7 @@ var require_pdf_worker = __commonJS({
23388
23388
  });
23389
23389
  }
23390
23390
  },
23391
- parse: function parse(_ref4) {
23391
+ parse: function parse2(_ref4) {
23392
23392
  var xref = _ref4.xref, isEvalSupported = _ref4.isEvalSupported, fn = _ref4.fn;
23393
23393
  var IR = this.getIR({
23394
23394
  xref,
@@ -25624,7 +25624,7 @@ var require_pdf_worker = __commonJS({
25624
25624
  return encodeURIComponent(c);
25625
25625
  }
25626
25626
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
25627
- function parse(input, stateOverride, base) {
25627
+ function parse2(input, stateOverride, base) {
25628
25628
  function err(message) {
25629
25629
  errors.push(message);
25630
25630
  }
@@ -25986,7 +25986,7 @@ var require_pdf_worker = __commonJS({
25986
25986
  this._url = url;
25987
25987
  clear.call(this);
25988
25988
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
25989
- parse.call(this, input, null, base);
25989
+ parse2.call(this, input, null, base);
25990
25990
  }
25991
25991
  JURL.prototype = {
25992
25992
  toString: function toString() {
@@ -26004,7 +26004,7 @@ var require_pdf_worker = __commonJS({
26004
26004
  },
26005
26005
  set href(value) {
26006
26006
  clear.call(this);
26007
- parse.call(this, value);
26007
+ parse2.call(this, value);
26008
26008
  },
26009
26009
  get protocol() {
26010
26010
  return this._scheme + ":";
@@ -26013,7 +26013,7 @@ var require_pdf_worker = __commonJS({
26013
26013
  if (this._isInvalid) {
26014
26014
  return;
26015
26015
  }
26016
- parse.call(this, value + ":", "scheme start");
26016
+ parse2.call(this, value + ":", "scheme start");
26017
26017
  },
26018
26018
  get host() {
26019
26019
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -26022,7 +26022,7 @@ var require_pdf_worker = __commonJS({
26022
26022
  if (this._isInvalid || !this._isRelative) {
26023
26023
  return;
26024
26024
  }
26025
- parse.call(this, value, "host");
26025
+ parse2.call(this, value, "host");
26026
26026
  },
26027
26027
  get hostname() {
26028
26028
  return this._host;
@@ -26031,7 +26031,7 @@ var require_pdf_worker = __commonJS({
26031
26031
  if (this._isInvalid || !this._isRelative) {
26032
26032
  return;
26033
26033
  }
26034
- parse.call(this, value, "hostname");
26034
+ parse2.call(this, value, "hostname");
26035
26035
  },
26036
26036
  get port() {
26037
26037
  return this._port;
@@ -26040,7 +26040,7 @@ var require_pdf_worker = __commonJS({
26040
26040
  if (this._isInvalid || !this._isRelative) {
26041
26041
  return;
26042
26042
  }
26043
- parse.call(this, value, "port");
26043
+ parse2.call(this, value, "port");
26044
26044
  },
26045
26045
  get pathname() {
26046
26046
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -26050,7 +26050,7 @@ var require_pdf_worker = __commonJS({
26050
26050
  return;
26051
26051
  }
26052
26052
  this._path = [];
26053
- parse.call(this, value, "relative path start");
26053
+ parse2.call(this, value, "relative path start");
26054
26054
  },
26055
26055
  get search() {
26056
26056
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -26063,7 +26063,7 @@ var require_pdf_worker = __commonJS({
26063
26063
  if (value[0] === "?") {
26064
26064
  value = value.slice(1);
26065
26065
  }
26066
- parse.call(this, value, "query");
26066
+ parse2.call(this, value, "query");
26067
26067
  },
26068
26068
  get hash() {
26069
26069
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -26076,7 +26076,7 @@ var require_pdf_worker = __commonJS({
26076
26076
  if (value[0] === "#") {
26077
26077
  value = value.slice(1);
26078
26078
  }
26079
- parse.call(this, value, "fragment");
26079
+ parse2.call(this, value, "fragment");
26080
26080
  },
26081
26081
  get origin() {
26082
26082
  var host;
@@ -32121,7 +32121,7 @@ var require_pdf_worker = __commonJS({
32121
32121
  };
32122
32122
  }
32123
32123
  JpegImage2.prototype = {
32124
- parse: function parse(data) {
32124
+ parse: function parse2(data) {
32125
32125
  function readUint16() {
32126
32126
  var value = data[offset] << 8 | data[offset + 1];
32127
32127
  offset += 2;
@@ -37804,7 +37804,7 @@ var require_pdf_worker = __commonJS({
37804
37804
  args: [x1, y1, x2, y2, x3, y3]
37805
37805
  });
37806
37806
  }
37807
- function parse(code2) {
37807
+ function parse2(code2) {
37808
37808
  var i = 0;
37809
37809
  while (i < code2.length) {
37810
37810
  var stackClean = false;
@@ -37868,7 +37868,7 @@ var require_pdf_worker = __commonJS({
37868
37868
  n = stack.pop() + font.subrsBias;
37869
37869
  subrCode = font.subrs[n];
37870
37870
  if (subrCode) {
37871
- parse(subrCode);
37871
+ parse2(subrCode);
37872
37872
  }
37873
37873
  break;
37874
37874
  case 11:
@@ -38054,7 +38054,7 @@ var require_pdf_worker = __commonJS({
38054
38054
  n = stack.pop() + font.gsubrsBias;
38055
38055
  subrCode = font.gsubrs[n];
38056
38056
  if (subrCode) {
38057
- parse(subrCode);
38057
+ parse2(subrCode);
38058
38058
  }
38059
38059
  break;
38060
38060
  case 30:
@@ -38120,7 +38120,7 @@ var require_pdf_worker = __commonJS({
38120
38120
  }
38121
38121
  }
38122
38122
  }
38123
- parse(code);
38123
+ parse2(code);
38124
38124
  }
38125
38125
  var noop = "";
38126
38126
  function CompiledFont(fontMatrix) {
@@ -52673,7 +52673,7 @@ var require_pdf = __commonJS({
52673
52673
  return encodeURIComponent(c);
52674
52674
  }
52675
52675
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
52676
- function parse(input, stateOverride, base) {
52676
+ function parse2(input, stateOverride, base) {
52677
52677
  function err(message) {
52678
52678
  errors.push(message);
52679
52679
  }
@@ -53035,7 +53035,7 @@ var require_pdf = __commonJS({
53035
53035
  this._url = url;
53036
53036
  clear.call(this);
53037
53037
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
53038
- parse.call(this, input, null, base);
53038
+ parse2.call(this, input, null, base);
53039
53039
  }
53040
53040
  JURL.prototype = {
53041
53041
  toString: function toString() {
@@ -53053,7 +53053,7 @@ var require_pdf = __commonJS({
53053
53053
  },
53054
53054
  set href(value) {
53055
53055
  clear.call(this);
53056
- parse.call(this, value);
53056
+ parse2.call(this, value);
53057
53057
  },
53058
53058
  get protocol() {
53059
53059
  return this._scheme + ":";
@@ -53062,7 +53062,7 @@ var require_pdf = __commonJS({
53062
53062
  if (this._isInvalid) {
53063
53063
  return;
53064
53064
  }
53065
- parse.call(this, value + ":", "scheme start");
53065
+ parse2.call(this, value + ":", "scheme start");
53066
53066
  },
53067
53067
  get host() {
53068
53068
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -53071,7 +53071,7 @@ var require_pdf = __commonJS({
53071
53071
  if (this._isInvalid || !this._isRelative) {
53072
53072
  return;
53073
53073
  }
53074
- parse.call(this, value, "host");
53074
+ parse2.call(this, value, "host");
53075
53075
  },
53076
53076
  get hostname() {
53077
53077
  return this._host;
@@ -53080,7 +53080,7 @@ var require_pdf = __commonJS({
53080
53080
  if (this._isInvalid || !this._isRelative) {
53081
53081
  return;
53082
53082
  }
53083
- parse.call(this, value, "hostname");
53083
+ parse2.call(this, value, "hostname");
53084
53084
  },
53085
53085
  get port() {
53086
53086
  return this._port;
@@ -53089,7 +53089,7 @@ var require_pdf = __commonJS({
53089
53089
  if (this._isInvalid || !this._isRelative) {
53090
53090
  return;
53091
53091
  }
53092
- parse.call(this, value, "port");
53092
+ parse2.call(this, value, "port");
53093
53093
  },
53094
53094
  get pathname() {
53095
53095
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -53099,7 +53099,7 @@ var require_pdf = __commonJS({
53099
53099
  return;
53100
53100
  }
53101
53101
  this._path = [];
53102
- parse.call(this, value, "relative path start");
53102
+ parse2.call(this, value, "relative path start");
53103
53103
  },
53104
53104
  get search() {
53105
53105
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -53112,7 +53112,7 @@ var require_pdf = __commonJS({
53112
53112
  if (value[0] === "?") {
53113
53113
  value = value.slice(1);
53114
53114
  }
53115
- parse.call(this, value, "query");
53115
+ parse2.call(this, value, "query");
53116
53116
  },
53117
53117
  get hash() {
53118
53118
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -53125,7 +53125,7 @@ var require_pdf = __commonJS({
53125
53125
  if (value[0] === "#") {
53126
53126
  value = value.slice(1);
53127
53127
  }
53128
- parse.call(this, value, "fragment");
53128
+ parse2.call(this, value, "fragment");
53129
53129
  },
53130
53130
  get origin() {
53131
53131
  var host;
@@ -61161,8 +61161,8 @@ var require_pdf = __commonJS({
61161
61161
  }
61162
61162
  }
61163
61163
  var fs20 = require("fs");
61164
- var http = require("http");
61165
- var https = require("https");
61164
+ var http2 = require("http");
61165
+ var https2 = require("https");
61166
61166
  var url = require("url");
61167
61167
  var PDFNodeStream = (function() {
61168
61168
  function PDFNodeStream2(options) {
@@ -61441,9 +61441,9 @@ var require_pdf = __commonJS({
61441
61441
  };
61442
61442
  _this5._request = null;
61443
61443
  if (_this5._url.protocol === "http:") {
61444
- _this5._request = http.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
61444
+ _this5._request = http2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
61445
61445
  } else {
61446
- _this5._request = https.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
61446
+ _this5._request = https2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
61447
61447
  }
61448
61448
  _this5._request.on("error", function(reason) {
61449
61449
  _this5._errored = true;
@@ -61471,11 +61471,11 @@ var require_pdf = __commonJS({
61471
61471
  _this6._httpHeaders["Range"] = "bytes=" + start + "-" + (end - 1);
61472
61472
  _this6._request = null;
61473
61473
  if (_this6._url.protocol === "http:") {
61474
- _this6._request = http.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
61474
+ _this6._request = http2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
61475
61475
  _this6._setReadableStream(response);
61476
61476
  });
61477
61477
  } else {
61478
- _this6._request = https.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
61478
+ _this6._request = https2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
61479
61479
  _this6._setReadableStream(response);
61480
61480
  });
61481
61481
  }
@@ -85592,7 +85592,7 @@ var require_pdf_worker2 = __commonJS({
85592
85592
  });
85593
85593
  }
85594
85594
  },
85595
- parse: function parse(_ref4) {
85595
+ parse: function parse2(_ref4) {
85596
85596
  var xref = _ref4.xref, isEvalSupported = _ref4.isEvalSupported, fn = _ref4.fn;
85597
85597
  var IR = this.getIR({
85598
85598
  xref,
@@ -87839,7 +87839,7 @@ var require_pdf_worker2 = __commonJS({
87839
87839
  return encodeURIComponent(c);
87840
87840
  }
87841
87841
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
87842
- function parse(input, stateOverride, base) {
87842
+ function parse2(input, stateOverride, base) {
87843
87843
  function err(message) {
87844
87844
  errors.push(message);
87845
87845
  }
@@ -88201,7 +88201,7 @@ var require_pdf_worker2 = __commonJS({
88201
88201
  this._url = url;
88202
88202
  clear.call(this);
88203
88203
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
88204
- parse.call(this, input, null, base);
88204
+ parse2.call(this, input, null, base);
88205
88205
  }
88206
88206
  JURL.prototype = {
88207
88207
  toString: function toString() {
@@ -88219,7 +88219,7 @@ var require_pdf_worker2 = __commonJS({
88219
88219
  },
88220
88220
  set href(value) {
88221
88221
  clear.call(this);
88222
- parse.call(this, value);
88222
+ parse2.call(this, value);
88223
88223
  },
88224
88224
  get protocol() {
88225
88225
  return this._scheme + ":";
@@ -88228,7 +88228,7 @@ var require_pdf_worker2 = __commonJS({
88228
88228
  if (this._isInvalid) {
88229
88229
  return;
88230
88230
  }
88231
- parse.call(this, value + ":", "scheme start");
88231
+ parse2.call(this, value + ":", "scheme start");
88232
88232
  },
88233
88233
  get host() {
88234
88234
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -88237,7 +88237,7 @@ var require_pdf_worker2 = __commonJS({
88237
88237
  if (this._isInvalid || !this._isRelative) {
88238
88238
  return;
88239
88239
  }
88240
- parse.call(this, value, "host");
88240
+ parse2.call(this, value, "host");
88241
88241
  },
88242
88242
  get hostname() {
88243
88243
  return this._host;
@@ -88246,7 +88246,7 @@ var require_pdf_worker2 = __commonJS({
88246
88246
  if (this._isInvalid || !this._isRelative) {
88247
88247
  return;
88248
88248
  }
88249
- parse.call(this, value, "hostname");
88249
+ parse2.call(this, value, "hostname");
88250
88250
  },
88251
88251
  get port() {
88252
88252
  return this._port;
@@ -88255,7 +88255,7 @@ var require_pdf_worker2 = __commonJS({
88255
88255
  if (this._isInvalid || !this._isRelative) {
88256
88256
  return;
88257
88257
  }
88258
- parse.call(this, value, "port");
88258
+ parse2.call(this, value, "port");
88259
88259
  },
88260
88260
  get pathname() {
88261
88261
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -88265,7 +88265,7 @@ var require_pdf_worker2 = __commonJS({
88265
88265
  return;
88266
88266
  }
88267
88267
  this._path = [];
88268
- parse.call(this, value, "relative path start");
88268
+ parse2.call(this, value, "relative path start");
88269
88269
  },
88270
88270
  get search() {
88271
88271
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -88278,7 +88278,7 @@ var require_pdf_worker2 = __commonJS({
88278
88278
  if (value[0] === "?") {
88279
88279
  value = value.slice(1);
88280
88280
  }
88281
- parse.call(this, value, "query");
88281
+ parse2.call(this, value, "query");
88282
88282
  },
88283
88283
  get hash() {
88284
88284
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -88291,7 +88291,7 @@ var require_pdf_worker2 = __commonJS({
88291
88291
  if (value[0] === "#") {
88292
88292
  value = value.slice(1);
88293
88293
  }
88294
- parse.call(this, value, "fragment");
88294
+ parse2.call(this, value, "fragment");
88295
88295
  },
88296
88296
  get origin() {
88297
88297
  var host;
@@ -94329,7 +94329,7 @@ var require_pdf_worker2 = __commonJS({
94329
94329
  };
94330
94330
  }
94331
94331
  JpegImage2.prototype = {
94332
- parse: function parse(data) {
94332
+ parse: function parse2(data) {
94333
94333
  function readUint16() {
94334
94334
  var value = data[offset] << 8 | data[offset + 1];
94335
94335
  offset += 2;
@@ -100006,7 +100006,7 @@ var require_pdf_worker2 = __commonJS({
100006
100006
  args: [x1, y1, x2, y2, x3, y3]
100007
100007
  });
100008
100008
  }
100009
- function parse(code2) {
100009
+ function parse2(code2) {
100010
100010
  var i = 0;
100011
100011
  while (i < code2.length) {
100012
100012
  var stackClean = false;
@@ -100070,7 +100070,7 @@ var require_pdf_worker2 = __commonJS({
100070
100070
  n = stack.pop() + font.subrsBias;
100071
100071
  subrCode = font.subrs[n];
100072
100072
  if (subrCode) {
100073
- parse(subrCode);
100073
+ parse2(subrCode);
100074
100074
  }
100075
100075
  break;
100076
100076
  case 11:
@@ -100256,7 +100256,7 @@ var require_pdf_worker2 = __commonJS({
100256
100256
  n = stack.pop() + font.gsubrsBias;
100257
100257
  subrCode = font.gsubrs[n];
100258
100258
  if (subrCode) {
100259
- parse(subrCode);
100259
+ parse2(subrCode);
100260
100260
  }
100261
100261
  break;
100262
100262
  case 30:
@@ -100322,7 +100322,7 @@ var require_pdf_worker2 = __commonJS({
100322
100322
  }
100323
100323
  }
100324
100324
  }
100325
- parse(code);
100325
+ parse2(code);
100326
100326
  }
100327
100327
  var noop = "";
100328
100328
  function CompiledFont(fontMatrix) {
@@ -114992,7 +114992,7 @@ var require_pdf2 = __commonJS({
114992
114992
  return encodeURIComponent(c);
114993
114993
  }
114994
114994
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
114995
- function parse(input, stateOverride, base) {
114995
+ function parse2(input, stateOverride, base) {
114996
114996
  function err(message) {
114997
114997
  errors.push(message);
114998
114998
  }
@@ -115354,7 +115354,7 @@ var require_pdf2 = __commonJS({
115354
115354
  this._url = url;
115355
115355
  clear.call(this);
115356
115356
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
115357
- parse.call(this, input, null, base);
115357
+ parse2.call(this, input, null, base);
115358
115358
  }
115359
115359
  JURL.prototype = {
115360
115360
  toString: function toString() {
@@ -115372,7 +115372,7 @@ var require_pdf2 = __commonJS({
115372
115372
  },
115373
115373
  set href(value) {
115374
115374
  clear.call(this);
115375
- parse.call(this, value);
115375
+ parse2.call(this, value);
115376
115376
  },
115377
115377
  get protocol() {
115378
115378
  return this._scheme + ":";
@@ -115381,7 +115381,7 @@ var require_pdf2 = __commonJS({
115381
115381
  if (this._isInvalid) {
115382
115382
  return;
115383
115383
  }
115384
- parse.call(this, value + ":", "scheme start");
115384
+ parse2.call(this, value + ":", "scheme start");
115385
115385
  },
115386
115386
  get host() {
115387
115387
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -115390,7 +115390,7 @@ var require_pdf2 = __commonJS({
115390
115390
  if (this._isInvalid || !this._isRelative) {
115391
115391
  return;
115392
115392
  }
115393
- parse.call(this, value, "host");
115393
+ parse2.call(this, value, "host");
115394
115394
  },
115395
115395
  get hostname() {
115396
115396
  return this._host;
@@ -115399,7 +115399,7 @@ var require_pdf2 = __commonJS({
115399
115399
  if (this._isInvalid || !this._isRelative) {
115400
115400
  return;
115401
115401
  }
115402
- parse.call(this, value, "hostname");
115402
+ parse2.call(this, value, "hostname");
115403
115403
  },
115404
115404
  get port() {
115405
115405
  return this._port;
@@ -115408,7 +115408,7 @@ var require_pdf2 = __commonJS({
115408
115408
  if (this._isInvalid || !this._isRelative) {
115409
115409
  return;
115410
115410
  }
115411
- parse.call(this, value, "port");
115411
+ parse2.call(this, value, "port");
115412
115412
  },
115413
115413
  get pathname() {
115414
115414
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -115418,7 +115418,7 @@ var require_pdf2 = __commonJS({
115418
115418
  return;
115419
115419
  }
115420
115420
  this._path = [];
115421
- parse.call(this, value, "relative path start");
115421
+ parse2.call(this, value, "relative path start");
115422
115422
  },
115423
115423
  get search() {
115424
115424
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -115431,7 +115431,7 @@ var require_pdf2 = __commonJS({
115431
115431
  if (value[0] === "?") {
115432
115432
  value = value.slice(1);
115433
115433
  }
115434
- parse.call(this, value, "query");
115434
+ parse2.call(this, value, "query");
115435
115435
  },
115436
115436
  get hash() {
115437
115437
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -115444,7 +115444,7 @@ var require_pdf2 = __commonJS({
115444
115444
  if (value[0] === "#") {
115445
115445
  value = value.slice(1);
115446
115446
  }
115447
- parse.call(this, value, "fragment");
115447
+ parse2.call(this, value, "fragment");
115448
115448
  },
115449
115449
  get origin() {
115450
115450
  var host;
@@ -122997,8 +122997,8 @@ var require_pdf2 = __commonJS({
122997
122997
  }
122998
122998
  }
122999
122999
  var fs20 = require("fs");
123000
- var http = require("http");
123001
- var https = require("https");
123000
+ var http2 = require("http");
123001
+ var https2 = require("https");
123002
123002
  var url = require("url");
123003
123003
  var PDFNodeStream = (function() {
123004
123004
  function PDFNodeStream2(options) {
@@ -123277,9 +123277,9 @@ var require_pdf2 = __commonJS({
123277
123277
  };
123278
123278
  _this5._request = null;
123279
123279
  if (_this5._url.protocol === "http:") {
123280
- _this5._request = http.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
123280
+ _this5._request = http2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
123281
123281
  } else {
123282
- _this5._request = https.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
123282
+ _this5._request = https2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
123283
123283
  }
123284
123284
  _this5._request.on("error", function(reason) {
123285
123285
  _this5._errored = true;
@@ -123307,11 +123307,11 @@ var require_pdf2 = __commonJS({
123307
123307
  _this6._httpHeaders["Range"] = "bytes=" + start + "-" + (end - 1);
123308
123308
  _this6._request = null;
123309
123309
  if (_this6._url.protocol === "http:") {
123310
- _this6._request = http.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
123310
+ _this6._request = http2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
123311
123311
  _this6._setReadableStream(response);
123312
123312
  });
123313
123313
  } else {
123314
- _this6._request = https.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
123314
+ _this6._request = https2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
123315
123315
  _this6._setReadableStream(response);
123316
123316
  });
123317
123317
  }
@@ -153463,7 +153463,7 @@ var require_pdf_worker3 = __commonJS({
153463
153463
  args: [x1, y1, x2, y2, x3, y3]
153464
153464
  });
153465
153465
  }
153466
- function parse(code2) {
153466
+ function parse2(code2) {
153467
153467
  var i = 0;
153468
153468
  while (i < code2.length) {
153469
153469
  var stackClean = false;
@@ -153527,7 +153527,7 @@ var require_pdf_worker3 = __commonJS({
153527
153527
  n = stack.pop() + font.subrsBias;
153528
153528
  subrCode = font.subrs[n];
153529
153529
  if (subrCode) {
153530
- parse(subrCode);
153530
+ parse2(subrCode);
153531
153531
  }
153532
153532
  break;
153533
153533
  case 11:
@@ -153713,7 +153713,7 @@ var require_pdf_worker3 = __commonJS({
153713
153713
  n = stack.pop() + font.gsubrsBias;
153714
153714
  subrCode = font.gsubrs[n];
153715
153715
  if (subrCode) {
153716
- parse(subrCode);
153716
+ parse2(subrCode);
153717
153717
  }
153718
153718
  break;
153719
153719
  case 30:
@@ -153779,7 +153779,7 @@ var require_pdf_worker3 = __commonJS({
153779
153779
  }
153780
153780
  }
153781
153781
  }
153782
- parse(code);
153782
+ parse2(code);
153783
153783
  }
153784
153784
  var noop = "";
153785
153785
  function CompiledFont(fontMatrix) {
@@ -158339,7 +158339,7 @@ var require_pdf_worker3 = __commonJS({
158339
158339
  };
158340
158340
  }
158341
158341
  JpegImage2.prototype = {
158342
- parse: function parse(data) {
158342
+ parse: function parse2(data) {
158343
158343
  function readUint16() {
158344
158344
  var value = data[offset] << 8 | data[offset + 1];
158345
158345
  offset += 2;
@@ -164488,7 +164488,7 @@ var require_pdf_worker3 = __commonJS({
164488
164488
  return encodeURIComponent(c);
164489
164489
  }
164490
164490
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
164491
- function parse(input, stateOverride, base) {
164491
+ function parse2(input, stateOverride, base) {
164492
164492
  function err(message) {
164493
164493
  errors.push(message);
164494
164494
  }
@@ -164850,7 +164850,7 @@ var require_pdf_worker3 = __commonJS({
164850
164850
  this._url = url;
164851
164851
  clear.call(this);
164852
164852
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
164853
- parse.call(this, input, null, base);
164853
+ parse2.call(this, input, null, base);
164854
164854
  }
164855
164855
  JURL.prototype = {
164856
164856
  toString: function toString() {
@@ -164868,7 +164868,7 @@ var require_pdf_worker3 = __commonJS({
164868
164868
  },
164869
164869
  set href(value) {
164870
164870
  clear.call(this);
164871
- parse.call(this, value);
164871
+ parse2.call(this, value);
164872
164872
  },
164873
164873
  get protocol() {
164874
164874
  return this._scheme + ":";
@@ -164877,7 +164877,7 @@ var require_pdf_worker3 = __commonJS({
164877
164877
  if (this._isInvalid) {
164878
164878
  return;
164879
164879
  }
164880
- parse.call(this, value + ":", "scheme start");
164880
+ parse2.call(this, value + ":", "scheme start");
164881
164881
  },
164882
164882
  get host() {
164883
164883
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -164886,7 +164886,7 @@ var require_pdf_worker3 = __commonJS({
164886
164886
  if (this._isInvalid || !this._isRelative) {
164887
164887
  return;
164888
164888
  }
164889
- parse.call(this, value, "host");
164889
+ parse2.call(this, value, "host");
164890
164890
  },
164891
164891
  get hostname() {
164892
164892
  return this._host;
@@ -164895,7 +164895,7 @@ var require_pdf_worker3 = __commonJS({
164895
164895
  if (this._isInvalid || !this._isRelative) {
164896
164896
  return;
164897
164897
  }
164898
- parse.call(this, value, "hostname");
164898
+ parse2.call(this, value, "hostname");
164899
164899
  },
164900
164900
  get port() {
164901
164901
  return this._port;
@@ -164904,7 +164904,7 @@ var require_pdf_worker3 = __commonJS({
164904
164904
  if (this._isInvalid || !this._isRelative) {
164905
164905
  return;
164906
164906
  }
164907
- parse.call(this, value, "port");
164907
+ parse2.call(this, value, "port");
164908
164908
  },
164909
164909
  get pathname() {
164910
164910
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -164914,7 +164914,7 @@ var require_pdf_worker3 = __commonJS({
164914
164914
  return;
164915
164915
  }
164916
164916
  this._path = [];
164917
- parse.call(this, value, "relative path start");
164917
+ parse2.call(this, value, "relative path start");
164918
164918
  },
164919
164919
  get search() {
164920
164920
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -164927,7 +164927,7 @@ var require_pdf_worker3 = __commonJS({
164927
164927
  if (value[0] === "?") {
164928
164928
  value = value.slice(1);
164929
164929
  }
164930
- parse.call(this, value, "query");
164930
+ parse2.call(this, value, "query");
164931
164931
  },
164932
164932
  get hash() {
164933
164933
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -164940,7 +164940,7 @@ var require_pdf_worker3 = __commonJS({
164940
164940
  if (value[0] === "#") {
164941
164941
  value = value.slice(1);
164942
164942
  }
164943
- parse.call(this, value, "fragment");
164943
+ parse2.call(this, value, "fragment");
164944
164944
  },
164945
164945
  get origin() {
164946
164946
  var host;
@@ -178054,7 +178054,7 @@ var require_pdf3 = __commonJS({
178054
178054
  return encodeURIComponent(c);
178055
178055
  }
178056
178056
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
178057
- function parse(input, stateOverride, base) {
178057
+ function parse2(input, stateOverride, base) {
178058
178058
  function err(message) {
178059
178059
  errors.push(message);
178060
178060
  }
@@ -178416,7 +178416,7 @@ var require_pdf3 = __commonJS({
178416
178416
  this._url = url;
178417
178417
  clear.call(this);
178418
178418
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
178419
- parse.call(this, input, null, base);
178419
+ parse2.call(this, input, null, base);
178420
178420
  }
178421
178421
  JURL.prototype = {
178422
178422
  toString: function toString() {
@@ -178434,7 +178434,7 @@ var require_pdf3 = __commonJS({
178434
178434
  },
178435
178435
  set href(value) {
178436
178436
  clear.call(this);
178437
- parse.call(this, value);
178437
+ parse2.call(this, value);
178438
178438
  },
178439
178439
  get protocol() {
178440
178440
  return this._scheme + ":";
@@ -178443,7 +178443,7 @@ var require_pdf3 = __commonJS({
178443
178443
  if (this._isInvalid) {
178444
178444
  return;
178445
178445
  }
178446
- parse.call(this, value + ":", "scheme start");
178446
+ parse2.call(this, value + ":", "scheme start");
178447
178447
  },
178448
178448
  get host() {
178449
178449
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -178452,7 +178452,7 @@ var require_pdf3 = __commonJS({
178452
178452
  if (this._isInvalid || !this._isRelative) {
178453
178453
  return;
178454
178454
  }
178455
- parse.call(this, value, "host");
178455
+ parse2.call(this, value, "host");
178456
178456
  },
178457
178457
  get hostname() {
178458
178458
  return this._host;
@@ -178461,7 +178461,7 @@ var require_pdf3 = __commonJS({
178461
178461
  if (this._isInvalid || !this._isRelative) {
178462
178462
  return;
178463
178463
  }
178464
- parse.call(this, value, "hostname");
178464
+ parse2.call(this, value, "hostname");
178465
178465
  },
178466
178466
  get port() {
178467
178467
  return this._port;
@@ -178470,7 +178470,7 @@ var require_pdf3 = __commonJS({
178470
178470
  if (this._isInvalid || !this._isRelative) {
178471
178471
  return;
178472
178472
  }
178473
- parse.call(this, value, "port");
178473
+ parse2.call(this, value, "port");
178474
178474
  },
178475
178475
  get pathname() {
178476
178476
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -178480,7 +178480,7 @@ var require_pdf3 = __commonJS({
178480
178480
  return;
178481
178481
  }
178482
178482
  this._path = [];
178483
- parse.call(this, value, "relative path start");
178483
+ parse2.call(this, value, "relative path start");
178484
178484
  },
178485
178485
  get search() {
178486
178486
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -178493,7 +178493,7 @@ var require_pdf3 = __commonJS({
178493
178493
  if (value[0] === "?") {
178494
178494
  value = value.slice(1);
178495
178495
  }
178496
- parse.call(this, value, "query");
178496
+ parse2.call(this, value, "query");
178497
178497
  },
178498
178498
  get hash() {
178499
178499
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -178506,7 +178506,7 @@ var require_pdf3 = __commonJS({
178506
178506
  if (value[0] === "#") {
178507
178507
  value = value.slice(1);
178508
178508
  }
178509
- parse.call(this, value, "fragment");
178509
+ parse2.call(this, value, "fragment");
178510
178510
  },
178511
178511
  get origin() {
178512
178512
  var host;
@@ -180268,7 +180268,7 @@ var require_pdf_worker4 = __commonJS({
180268
180268
  return encodeURIComponent(c);
180269
180269
  }
180270
180270
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
180271
- function parse(input, stateOverride, base) {
180271
+ function parse2(input, stateOverride, base) {
180272
180272
  function err(message) {
180273
180273
  errors.push(message);
180274
180274
  }
@@ -180630,7 +180630,7 @@ var require_pdf_worker4 = __commonJS({
180630
180630
  this._url = url;
180631
180631
  clear.call(this);
180632
180632
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
180633
- parse.call(this, input, null, base);
180633
+ parse2.call(this, input, null, base);
180634
180634
  }
180635
180635
  JURL.prototype = {
180636
180636
  toString: function toString() {
@@ -180648,7 +180648,7 @@ var require_pdf_worker4 = __commonJS({
180648
180648
  },
180649
180649
  set href(value) {
180650
180650
  clear.call(this);
180651
- parse.call(this, value);
180651
+ parse2.call(this, value);
180652
180652
  },
180653
180653
  get protocol() {
180654
180654
  return this._scheme + ":";
@@ -180657,7 +180657,7 @@ var require_pdf_worker4 = __commonJS({
180657
180657
  if (this._isInvalid) {
180658
180658
  return;
180659
180659
  }
180660
- parse.call(this, value + ":", "scheme start");
180660
+ parse2.call(this, value + ":", "scheme start");
180661
180661
  },
180662
180662
  get host() {
180663
180663
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -180666,7 +180666,7 @@ var require_pdf_worker4 = __commonJS({
180666
180666
  if (this._isInvalid || !this._isRelative) {
180667
180667
  return;
180668
180668
  }
180669
- parse.call(this, value, "host");
180669
+ parse2.call(this, value, "host");
180670
180670
  },
180671
180671
  get hostname() {
180672
180672
  return this._host;
@@ -180675,7 +180675,7 @@ var require_pdf_worker4 = __commonJS({
180675
180675
  if (this._isInvalid || !this._isRelative) {
180676
180676
  return;
180677
180677
  }
180678
- parse.call(this, value, "hostname");
180678
+ parse2.call(this, value, "hostname");
180679
180679
  },
180680
180680
  get port() {
180681
180681
  return this._port;
@@ -180684,7 +180684,7 @@ var require_pdf_worker4 = __commonJS({
180684
180684
  if (this._isInvalid || !this._isRelative) {
180685
180685
  return;
180686
180686
  }
180687
- parse.call(this, value, "port");
180687
+ parse2.call(this, value, "port");
180688
180688
  },
180689
180689
  get pathname() {
180690
180690
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -180694,7 +180694,7 @@ var require_pdf_worker4 = __commonJS({
180694
180694
  return;
180695
180695
  }
180696
180696
  this._path = [];
180697
- parse.call(this, value, "relative path start");
180697
+ parse2.call(this, value, "relative path start");
180698
180698
  },
180699
180699
  get search() {
180700
180700
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -180707,7 +180707,7 @@ var require_pdf_worker4 = __commonJS({
180707
180707
  if (value[0] === "?") {
180708
180708
  value = value.slice(1);
180709
180709
  }
180710
- parse.call(this, value, "query");
180710
+ parse2.call(this, value, "query");
180711
180711
  },
180712
180712
  get hash() {
180713
180713
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -180720,7 +180720,7 @@ var require_pdf_worker4 = __commonJS({
180720
180720
  if (value[0] === "#") {
180721
180721
  value = value.slice(1);
180722
180722
  }
180723
- parse.call(this, value, "fragment");
180723
+ parse2.call(this, value, "fragment");
180724
180724
  },
180725
180725
  get origin() {
180726
180726
  var host;
@@ -194299,7 +194299,7 @@ var require_pdf_worker4 = __commonJS({
194299
194299
  };
194300
194300
  }
194301
194301
  JpegImage2.prototype = {
194302
- parse: function parse(data) {
194302
+ parse: function parse2(data) {
194303
194303
  var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, _ref$dnlScanLines = _ref.dnlScanLines, dnlScanLines = _ref$dnlScanLines === void 0 ? null : _ref$dnlScanLines;
194304
194304
  function readUint16() {
194305
194305
  var value = data[offset] << 8 | data[offset + 1];
@@ -215210,7 +215210,7 @@ var require_pdf_worker4 = __commonJS({
215210
215210
  args: [x1, y1, x2, y2, x3, y3]
215211
215211
  });
215212
215212
  }
215213
- function parse(code2) {
215213
+ function parse2(code2) {
215214
215214
  var i = 0;
215215
215215
  while (i < code2.length) {
215216
215216
  var stackClean = false;
@@ -215292,7 +215292,7 @@ var require_pdf_worker4 = __commonJS({
215292
215292
  subrCode = font.subrs[n + font.subrsBias];
215293
215293
  }
215294
215294
  if (subrCode) {
215295
- parse(subrCode);
215295
+ parse2(subrCode);
215296
215296
  }
215297
215297
  break;
215298
215298
  case 11:
@@ -215478,7 +215478,7 @@ var require_pdf_worker4 = __commonJS({
215478
215478
  n = stack.pop() + font.gsubrsBias;
215479
215479
  subrCode = font.gsubrs[n];
215480
215480
  if (subrCode) {
215481
- parse(subrCode);
215481
+ parse2(subrCode);
215482
215482
  }
215483
215483
  break;
215484
215484
  case 30:
@@ -215544,7 +215544,7 @@ var require_pdf_worker4 = __commonJS({
215544
215544
  }
215545
215545
  }
215546
215546
  }
215547
- parse(code);
215547
+ parse2(code);
215548
215548
  }
215549
215549
  var noop = "";
215550
215550
  function CompiledFont(fontMatrix) {
@@ -220336,7 +220336,7 @@ var require_pdf_worker4 = __commonJS({
220336
220336
  });
220337
220337
  }
220338
220338
  },
220339
- parse: function parse(_ref4) {
220339
+ parse: function parse2(_ref4) {
220340
220340
  var xref = _ref4.xref, isEvalSupported = _ref4.isEvalSupported, fn = _ref4.fn;
220341
220341
  var IR = this.getIR({
220342
220342
  xref,
@@ -223650,7 +223650,7 @@ var require_pdf4 = __commonJS({
223650
223650
  return encodeURIComponent(c);
223651
223651
  }
223652
223652
  var EOF, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
223653
- function parse(input, stateOverride, base) {
223653
+ function parse2(input, stateOverride, base) {
223654
223654
  function err(message) {
223655
223655
  errors.push(message);
223656
223656
  }
@@ -224012,7 +224012,7 @@ var require_pdf4 = __commonJS({
224012
224012
  this._url = url;
224013
224013
  clear.call(this);
224014
224014
  var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
224015
- parse.call(this, input, null, base);
224015
+ parse2.call(this, input, null, base);
224016
224016
  }
224017
224017
  JURL.prototype = {
224018
224018
  toString: function toString() {
@@ -224030,7 +224030,7 @@ var require_pdf4 = __commonJS({
224030
224030
  },
224031
224031
  set href(value) {
224032
224032
  clear.call(this);
224033
- parse.call(this, value);
224033
+ parse2.call(this, value);
224034
224034
  },
224035
224035
  get protocol() {
224036
224036
  return this._scheme + ":";
@@ -224039,7 +224039,7 @@ var require_pdf4 = __commonJS({
224039
224039
  if (this._isInvalid) {
224040
224040
  return;
224041
224041
  }
224042
- parse.call(this, value + ":", "scheme start");
224042
+ parse2.call(this, value + ":", "scheme start");
224043
224043
  },
224044
224044
  get host() {
224045
224045
  return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
@@ -224048,7 +224048,7 @@ var require_pdf4 = __commonJS({
224048
224048
  if (this._isInvalid || !this._isRelative) {
224049
224049
  return;
224050
224050
  }
224051
- parse.call(this, value, "host");
224051
+ parse2.call(this, value, "host");
224052
224052
  },
224053
224053
  get hostname() {
224054
224054
  return this._host;
@@ -224057,7 +224057,7 @@ var require_pdf4 = __commonJS({
224057
224057
  if (this._isInvalid || !this._isRelative) {
224058
224058
  return;
224059
224059
  }
224060
- parse.call(this, value, "hostname");
224060
+ parse2.call(this, value, "hostname");
224061
224061
  },
224062
224062
  get port() {
224063
224063
  return this._port;
@@ -224066,7 +224066,7 @@ var require_pdf4 = __commonJS({
224066
224066
  if (this._isInvalid || !this._isRelative) {
224067
224067
  return;
224068
224068
  }
224069
- parse.call(this, value, "port");
224069
+ parse2.call(this, value, "port");
224070
224070
  },
224071
224071
  get pathname() {
224072
224072
  return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
@@ -224076,7 +224076,7 @@ var require_pdf4 = __commonJS({
224076
224076
  return;
224077
224077
  }
224078
224078
  this._path = [];
224079
- parse.call(this, value, "relative path start");
224079
+ parse2.call(this, value, "relative path start");
224080
224080
  },
224081
224081
  get search() {
224082
224082
  return this._isInvalid || !this._query || this._query === "?" ? "" : this._query;
@@ -224089,7 +224089,7 @@ var require_pdf4 = __commonJS({
224089
224089
  if (value[0] === "?") {
224090
224090
  value = value.slice(1);
224091
224091
  }
224092
- parse.call(this, value, "query");
224092
+ parse2.call(this, value, "query");
224093
224093
  },
224094
224094
  get hash() {
224095
224095
  return this._isInvalid || !this._fragment || this._fragment === "#" ? "" : this._fragment;
@@ -224102,7 +224102,7 @@ var require_pdf4 = __commonJS({
224102
224102
  if (value[0] === "#") {
224103
224103
  value = value.slice(1);
224104
224104
  }
224105
- parse.call(this, value, "fragment");
224105
+ parse2.call(this, value, "fragment");
224106
224106
  },
224107
224107
  get origin() {
224108
224108
  var host;
@@ -238007,8 +238007,8 @@ var require_pdf4 = __commonJS({
238007
238007
  }
238008
238008
  }
238009
238009
  var fs20 = require("fs");
238010
- var http = require("http");
238011
- var https = require("https");
238010
+ var http2 = require("http");
238011
+ var https2 = require("https");
238012
238012
  var url = require("url");
238013
238013
  var fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//;
238014
238014
  function parseUrl(sourceUrl) {
@@ -238308,9 +238308,9 @@ var require_pdf4 = __commonJS({
238308
238308
  };
238309
238309
  _this5._request = null;
238310
238310
  if (_this5._url.protocol === "http:") {
238311
- _this5._request = http.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
238311
+ _this5._request = http2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
238312
238312
  } else {
238313
- _this5._request = https.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
238313
+ _this5._request = https2.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
238314
238314
  }
238315
238315
  _this5._request.on("error", function(reason) {
238316
238316
  _this5._errored = true;
@@ -238338,11 +238338,11 @@ var require_pdf4 = __commonJS({
238338
238338
  _this6._httpHeaders["Range"] = "bytes=" + start + "-" + (end - 1);
238339
238339
  _this6._request = null;
238340
238340
  if (_this6._url.protocol === "http:") {
238341
- _this6._request = http.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
238341
+ _this6._request = http2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
238342
238342
  _this6._setReadableStream(response);
238343
238343
  });
238344
238344
  } else {
238345
- _this6._request = https.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
238345
+ _this6._request = https2.request(createRequestOptions(_this6._url, _this6._httpHeaders), function(response) {
238346
238346
  _this6._setReadableStream(response);
238347
238347
  });
238348
238348
  }
@@ -239659,6 +239659,8 @@ var os9 = __toESM(require("node:os"), 1);
239659
239659
  var os7 = __toESM(require("node:os"), 1);
239660
239660
  var fs17 = __toESM(require("node:fs"), 1);
239661
239661
  var path16 = __toESM(require("node:path"), 1);
239662
+ var http = __toESM(require("node:http"), 1);
239663
+ var https = __toESM(require("node:https"), 1);
239662
239664
  var readline2 = __toESM(require("node:readline"), 1);
239663
239665
 
239664
239666
  // src/tools/readFile.ts
@@ -239865,6 +239867,39 @@ var readFileDefinition = {
239865
239867
  // src/tools/writeFile.ts
239866
239868
  var fs3 = __toESM(require("node:fs"), 1);
239867
239869
  var path3 = __toESM(require("node:path"), 1);
239870
+ var SECRET_PATTERNS = [
239871
+ [/\bsk-[a-zA-Z0-9]{20,}/g, "OpenAI API key (sk-...)"],
239872
+ [/\bor-[a-zA-Z0-9]{20,}/g, "O'Route API key (or-...)"],
239873
+ [/\bAKIA[A-Z0-9]{12,}/g, "AWS Access Key (AKIA...)"],
239874
+ [/password\s*[=:]\s*["'][^"']{4,}["']/gi, "Hardcoded password"],
239875
+ [/secret\s*[=:]\s*["'][^"']{4,}["']/gi, "Hardcoded secret"],
239876
+ [/token\s*[=:]\s*["'][^"']{8,}["']/gi, "Hardcoded token"],
239877
+ [/\bghp_[a-zA-Z0-9]{30,}/g, "GitHub personal access token"],
239878
+ [/\bglpat-[a-zA-Z0-9\-]{20,}/g, "GitLab personal access token"],
239879
+ [/\bxox[bprs]-[a-zA-Z0-9\-]{10,}/g, "Slack token"],
239880
+ [/-----BEGIN (?:RSA )?PRIVATE KEY-----/g, "Private key"]
239881
+ ];
239882
+ function scanForSecrets(content) {
239883
+ const warnings = [];
239884
+ for (const [pattern, label] of SECRET_PATTERNS) {
239885
+ pattern.lastIndex = 0;
239886
+ if (pattern.test(content)) {
239887
+ warnings.push(label);
239888
+ }
239889
+ }
239890
+ return warnings;
239891
+ }
239892
+ function checkWritePermission(dirPath) {
239893
+ try {
239894
+ fs3.accessSync(dirPath, fs3.constants.W_OK);
239895
+ } catch {
239896
+ throw new Error(
239897
+ `No write permission on directory: ${dirPath}
239898
+ Check permissions with: ls -la "${path3.dirname(dirPath)}"
239899
+ Fix with: chmod u+w "${dirPath}"`
239900
+ );
239901
+ }
239902
+ }
239868
239903
  function writeFileTool(input, cwd) {
239869
239904
  const resolved = smartResolve(input.path, cwd);
239870
239905
  const isNew = !fs3.existsSync(resolved);
@@ -239872,9 +239907,22 @@ function writeFileTool(input, cwd) {
239872
239907
  if (!fs3.existsSync(dir)) {
239873
239908
  fs3.mkdirSync(dir, { recursive: true });
239874
239909
  }
239910
+ checkWritePermission(dir);
239911
+ if (!isNew) {
239912
+ checkWritePermission(path3.dirname(resolved));
239913
+ try {
239914
+ fs3.accessSync(resolved, fs3.constants.W_OK);
239915
+ } catch {
239916
+ throw new Error(
239917
+ `No write permission on file: ${resolved}
239918
+ Fix with: chmod u+w "${resolved}"`
239919
+ );
239920
+ }
239921
+ }
239922
+ const secretWarnings = scanForSecrets(input.content);
239875
239923
  fs3.writeFileSync(resolved, input.content, "utf-8");
239876
239924
  const stat = fs3.statSync(resolved);
239877
- return { success: true, bytesWritten: stat.size, isNew };
239925
+ return { success: true, bytesWritten: stat.size, isNew, secretWarnings };
239878
239926
  }
239879
239927
  function generateDiff(filePath, newContent, cwd) {
239880
239928
  const resolved = smartResolve(filePath, cwd);
@@ -240523,8 +240571,12 @@ function diffFilesTool(input, cwd) {
240523
240571
  const pathB = smartResolve(input.file_b, cwd);
240524
240572
  if (!fs9.existsSync(pathA)) throw new Error(`File not found: ${pathA}`);
240525
240573
  if (!fs9.existsSync(pathB)) throw new Error(`File not found: ${pathB}`);
240526
- const linesA = fs9.readFileSync(pathA, "utf-8").split("\n");
240527
- const linesB = fs9.readFileSync(pathB, "utf-8").split("\n");
240574
+ let linesA = fs9.readFileSync(pathA, "utf-8").split("\n");
240575
+ let linesB = fs9.readFileSync(pathB, "utf-8").split("\n");
240576
+ if (input.ignoreWhitespace) {
240577
+ linesA = linesA.map((l) => l.trim());
240578
+ linesB = linesB.map((l) => l.trim());
240579
+ }
240528
240580
  const result = [];
240529
240581
  result.push(`--- ${input.file_a}`);
240530
240582
  result.push(`+++ ${input.file_b}`);
@@ -240584,20 +240636,82 @@ function diffFilesTool(input, cwd) {
240584
240636
 
240585
240637
  // src/ui.ts
240586
240638
  var readline = __toESM(require("node:readline"), 1);
240639
+ var colorScheme = process.env["OROUTE_COLOR_SCHEME"] ?? "default";
240640
+ var THEME_PRESETS = {
240641
+ default: {
240642
+ green: "\x1B[32m",
240643
+ cyan: "\x1B[36m",
240644
+ yellow: "\x1B[33m",
240645
+ red: "\x1B[31m",
240646
+ magenta: "\x1B[35m",
240647
+ blue: "\x1B[34m",
240648
+ gray: "\x1B[90m",
240649
+ white: "\x1B[97m"
240650
+ },
240651
+ nord: {
240652
+ green: "\x1B[38;2;163;190;140m",
240653
+ // #A3BE8C
240654
+ cyan: "\x1B[38;2;136;192;208m",
240655
+ // #88C0D0
240656
+ yellow: "\x1B[38;2;235;203;139m",
240657
+ // #EBCB8B
240658
+ red: "\x1B[38;2;191;97;106m",
240659
+ // #BF616A
240660
+ magenta: "\x1B[38;2;180;142;173m",
240661
+ // #B48EAD
240662
+ blue: "\x1B[38;2;129;161;193m",
240663
+ // #81A1C1
240664
+ gray: "\x1B[38;2;76;86;106m",
240665
+ // #4C566A
240666
+ white: "\x1B[38;2;236;239;244m"
240667
+ // #ECEFF4
240668
+ },
240669
+ dracula: {
240670
+ green: "\x1B[38;2;80;250;123m",
240671
+ // #50FA7B
240672
+ cyan: "\x1B[38;2;139;233;253m",
240673
+ // #8BE9FD
240674
+ yellow: "\x1B[38;2;241;250;140m",
240675
+ // #F1FA8C
240676
+ red: "\x1B[38;2;255;85;85m",
240677
+ // #FF5555
240678
+ magenta: "\x1B[38;2;255;121;198m",
240679
+ // #FF79C6
240680
+ blue: "\x1B[38;2;189;147;249m",
240681
+ // #BD93F9
240682
+ gray: "\x1B[38;2;98;114;164m",
240683
+ // #6272A4
240684
+ white: "\x1B[38;2;248;248;242m"
240685
+ // #F8F8F2
240686
+ }
240687
+ };
240688
+ var theme = THEME_PRESETS[colorScheme] ?? THEME_PRESETS.default;
240587
240689
  var isLightTheme = process.env["OROUTE_THEME"] === "light";
240588
- var GREEN = isLightTheme ? "\x1B[32m" : "\x1B[32m";
240589
- var GRAY = isLightTheme ? "\x1B[37m" : "\x1B[90m";
240690
+ var GREEN = isLightTheme ? "\x1B[32m" : theme.green;
240691
+ var GRAY = isLightTheme ? "\x1B[37m" : theme.gray;
240590
240692
  var BOLD = "\x1B[1m";
240591
240693
  var DIM = "\x1B[2m";
240592
240694
  var RESET = "\x1B[0m";
240593
- var CYAN = isLightTheme ? "\x1B[36m" : "\x1B[36m";
240594
- var YELLOW = isLightTheme ? "\x1B[33m" : "\x1B[33m";
240595
- var WHITE = isLightTheme ? "\x1B[30m" : "\x1B[97m";
240596
- var RED = "\x1B[31m";
240597
- var MAGENTA = "\x1B[35m";
240598
- var BLUE = isLightTheme ? "\x1B[34m" : "\x1B[34m";
240695
+ var CYAN = isLightTheme ? "\x1B[36m" : theme.cyan;
240696
+ var YELLOW = isLightTheme ? "\x1B[33m" : theme.yellow;
240697
+ var WHITE = isLightTheme ? "\x1B[30m" : theme.white;
240698
+ var RED = isLightTheme ? "\x1B[31m" : theme.red;
240699
+ var MAGENTA = isLightTheme ? "\x1B[35m" : theme.magenta;
240700
+ var BLUE = isLightTheme ? "\x1B[34m" : theme.blue;
240599
240701
  var BG_YELLOW = "\x1B[43m";
240600
240702
  var BLACK = "\x1B[30m";
240703
+ var LOG_LEVEL_PRIORITY = {
240704
+ error: 0,
240705
+ warn: 1,
240706
+ info: 2,
240707
+ debug: 3,
240708
+ trace: 4
240709
+ };
240710
+ var currentLogLevel = (() => {
240711
+ const env = (process.env["OROUTE_LOG_LEVEL"] ?? "info").toLowerCase();
240712
+ if (env in LOG_LEVEL_PRIORITY) return env;
240713
+ return "info";
240714
+ })();
240601
240715
  var TOOL_COLORS = {
240602
240716
  read_file: CYAN,
240603
240717
  write_file: YELLOW,
@@ -240924,69 +241038,14 @@ function extractPackageJson(filePath) {
240924
241038
  return "";
240925
241039
  }
240926
241040
  }
240927
- function getGitBranch(cwd) {
240928
- try {
240929
- return (0, import_node_child_process2.execSync)("git rev-parse --abbrev-ref HEAD 2>/dev/null", { cwd, encoding: "utf-8" }).trim() || void 0;
240930
- } catch {
240931
- return void 0;
240932
- }
240933
- }
240934
- function getGitStatusSummary(cwd) {
240935
- try {
240936
- const isGit = (0, import_node_child_process2.execSync)("git rev-parse --is-inside-work-tree 2>/dev/null", { cwd, encoding: "utf-8" }).trim();
240937
- if (isGit !== "true") return void 0;
240938
- const status = (0, import_node_child_process2.execSync)("git status --short 2>/dev/null", { cwd, encoding: "utf-8" }).trim();
240939
- if (!status) return "clean";
240940
- const lines = status.split("\n");
240941
- const modified = lines.filter((l) => l.startsWith(" M") || l.startsWith("M ")).length;
240942
- const added = lines.filter((l) => l.startsWith("A ") || l.startsWith("??")).length;
240943
- const deleted = lines.filter((l) => l.startsWith(" D") || l.startsWith("D ")).length;
240944
- const parts = [];
240945
- if (modified > 0) parts.push(`${modified} modified`);
240946
- if (added > 0) parts.push(`${added} untracked/added`);
240947
- if (deleted > 0) parts.push(`${deleted} deleted`);
240948
- return parts.join(", ") || "clean";
240949
- } catch {
240950
- return void 0;
240951
- }
240952
- }
240953
- function detectMonorepo(cwd) {
240954
- const indicators = [
240955
- { file: "pnpm-workspace.yaml", type: "pnpm workspace" },
240956
- { file: "turbo.json", type: "turborepo" },
240957
- { file: "nx.json", type: "nx" },
240958
- { file: "lerna.json", type: "lerna" },
240959
- { file: "rush.json", type: "rush" }
240960
- ];
240961
- for (const { file, type } of indicators) {
240962
- if (fs10.existsSync(path9.join(cwd, file))) {
240963
- const dirs = ["apps", "packages", "libs", "services"].filter(
240964
- (d) => fs10.existsSync(path9.join(cwd, d)) && fs10.statSync(path9.join(cwd, d)).isDirectory()
240965
- );
240966
- const packages = dirs.flatMap((d) => {
240967
- try {
240968
- return fs10.readdirSync(path9.join(cwd, d)).filter(
240969
- (f) => fs10.statSync(path9.join(cwd, d, f)).isDirectory()
240970
- ).map((f) => `${d}/${f}`);
240971
- } catch {
240972
- return [];
240973
- }
240974
- });
240975
- return `${type} (${packages.length} packages: ${packages.slice(0, 8).join(", ")}${packages.length > 8 ? "..." : ""})`;
240976
- }
240977
- }
240978
- return null;
240979
- }
240980
241041
  function loadProjectContext(cwd) {
240981
241042
  const contextFiles = [];
240982
- const candidates = [
241043
+ const essentialCandidates = [
240983
241044
  { name: "CLAUDE.md", loader: () => safeReadFile(path9.join(cwd, "CLAUDE.md")) },
240984
- { name: ".claude/CLAUDE.md", loader: () => safeReadFile(path9.join(cwd, ".claude", "CLAUDE.md")) },
240985
- { name: ".oroute.md", loader: () => safeReadFile(path9.join(cwd, ".oroute.md")) },
240986
241045
  { name: "package.json", loader: () => extractPackageJson(path9.join(cwd, "package.json")) }
240987
241046
  ];
240988
241047
  let totalChars = 0;
240989
- for (const c of candidates) {
241048
+ for (const c of essentialCandidates) {
240990
241049
  if (totalChars >= MAX_CONTEXT_CHARS) break;
240991
241050
  const content = c.loader();
240992
241051
  if (!content) continue;
@@ -240995,13 +241054,7 @@ function loadProjectContext(cwd) {
240995
241054
  contextFiles.push({ name: c.name, content: trimmed });
240996
241055
  totalChars += trimmed.length;
240997
241056
  }
240998
- const gitBranch = getGitBranch(cwd);
240999
- const gitStatus = getGitStatusSummary(cwd);
241000
- const monorepoType = detectMonorepo(cwd);
241001
- if (monorepoType) {
241002
- contextFiles.push({ name: "monorepo", content: monorepoType });
241003
- }
241004
- return { files: contextFiles, gitBranch, gitStatus };
241057
+ return { files: contextFiles, gitBranch: void 0, gitStatus: void 0 };
241005
241058
  }
241006
241059
  function buildContextString(ctx) {
241007
241060
  const parts = [];
@@ -241136,7 +241189,7 @@ ${summaryParts.join("\n")}`
241136
241189
  }
241137
241190
 
241138
241191
  // src/streaming.ts
241139
- async function parseSSEStream(response, onTextDelta) {
241192
+ async function parseSSEStream(response, onTextDelta, onTokenUpdate) {
241140
241193
  const contentBlocks = [];
241141
241194
  let stopReason = null;
241142
241195
  let usage = { input_tokens: 0, output_tokens: 0 };
@@ -241169,6 +241222,7 @@ async function parseSSEStream(response, onTextDelta) {
241169
241222
  },
241170
241223
  setUsage: (u) => {
241171
241224
  usage = u;
241225
+ if (onTokenUpdate) onTokenUpdate(u);
241172
241226
  },
241173
241227
  setModel: (m) => {
241174
241228
  model = m;
@@ -241246,7 +241300,9 @@ function processSSEEvent(evt, contentBlocks, onTextDelta, cb) {
241246
241300
  if (block.type === "text") {
241247
241301
  block.text = (block.text ?? "") + text;
241248
241302
  }
241249
- onTextDelta(text);
241303
+ for (const char of text) {
241304
+ onTextDelta(char);
241305
+ }
241250
241306
  } else if (delta["type"] === "input_json_delta") {
241251
241307
  const partial = delta["partial_json"];
241252
241308
  if (block.type === "tool_use") {
@@ -241399,6 +241455,15 @@ function printCostSummary(stats) {
241399
241455
  }
241400
241456
  console.log();
241401
241457
  }
241458
+ function isBudgetExceeded(stats, maxCostPerSession) {
241459
+ if (maxCostPerSession <= 0) return false;
241460
+ return estimateCost(stats) >= maxCostPerSession;
241461
+ }
241462
+ function printBudgetWarning(stats, maxCostPerSession) {
241463
+ const cost = estimateCost(stats);
241464
+ console.log(`${YELLOW} \u26A0 Session cost ($${cost.toFixed(4)}) has reached the budget limit ($${maxCostPerSession.toFixed(4)}).${RESET}`);
241465
+ console.log(`${GRAY} Set maxCost in .oroute/config.json to adjust, or type "continue" to proceed.${RESET}`);
241466
+ }
241402
241467
  function printExitSummary(stats) {
241403
241468
  if (stats.requests === 0) return;
241404
241469
  const cost = estimateCost(stats);
@@ -241411,6 +241476,26 @@ var fs12 = __toESM(require("node:fs"), 1);
241411
241476
  var path11 = __toESM(require("node:path"), 1);
241412
241477
  var os3 = __toESM(require("node:os"), 1);
241413
241478
  var SESSIONS_DIR = path11.join(os3.homedir(), ".oroute", "sessions");
241479
+ var SESSION_CACHE_MAX = 3;
241480
+ var sessionCache = /* @__PURE__ */ new Map();
241481
+ function cacheSession(id, session) {
241482
+ sessionCache.delete(id);
241483
+ sessionCache.set(id, session);
241484
+ if (sessionCache.size > SESSION_CACHE_MAX) {
241485
+ const oldestKey = sessionCache.keys().next().value;
241486
+ if (oldestKey !== void 0) {
241487
+ sessionCache.delete(oldestKey);
241488
+ }
241489
+ }
241490
+ }
241491
+ function getCachedSession(id) {
241492
+ const session = sessionCache.get(id);
241493
+ if (session) {
241494
+ sessionCache.delete(id);
241495
+ sessionCache.set(id, session);
241496
+ }
241497
+ return session;
241498
+ }
241414
241499
  function ensureSessionsDir() {
241415
241500
  if (!fs12.existsSync(SESSIONS_DIR)) {
241416
241501
  fs12.mkdirSync(SESSIONS_DIR, { recursive: true });
@@ -241463,19 +241548,28 @@ function listSessions(limit = 10) {
241463
241548
  }
241464
241549
  function loadSession(id) {
241465
241550
  ensureSessionsDir();
241551
+ const cached = getCachedSession(id);
241552
+ if (cached) return cached;
241466
241553
  const exactPath = path11.join(SESSIONS_DIR, `${id}.json`);
241467
241554
  if (fs12.existsSync(exactPath)) {
241468
241555
  try {
241469
- return JSON.parse(fs12.readFileSync(exactPath, "utf-8"));
241556
+ const session = JSON.parse(fs12.readFileSync(exactPath, "utf-8"));
241557
+ cacheSession(id, session);
241558
+ return session;
241470
241559
  } catch {
241471
241560
  return null;
241472
241561
  }
241473
241562
  }
241474
241563
  const files = fs12.readdirSync(SESSIONS_DIR).filter((f) => f.endsWith(".json") && f.startsWith(id)).sort().reverse();
241475
241564
  if (files.length === 0) return null;
241565
+ const resolvedId = files[0].replace(".json", "");
241566
+ const cachedPartial = getCachedSession(resolvedId);
241567
+ if (cachedPartial) return cachedPartial;
241476
241568
  const filePath = path11.join(SESSIONS_DIR, files[0]);
241477
241569
  try {
241478
- return JSON.parse(fs12.readFileSync(filePath, "utf-8"));
241570
+ const session = JSON.parse(fs12.readFileSync(filePath, "utf-8"));
241571
+ cacheSession(resolvedId, session);
241572
+ return session;
241479
241573
  } catch {
241480
241574
  return null;
241481
241575
  }
@@ -241834,7 +241928,20 @@ var ALL_COMMANDS = [
241834
241928
  "/btw",
241835
241929
  "/batch",
241836
241930
  "/color",
241837
- "/terminal"
241931
+ "/terminal",
241932
+ // New features (11-17)
241933
+ "/explain",
241934
+ "/refs",
241935
+ "/resolve",
241936
+ "/stash",
241937
+ "/changelog",
241938
+ // Navigation & Search (41, 43)
241939
+ "/goto",
241940
+ "/find",
241941
+ // Code analysis (Features 7, 8, 10)
241942
+ "/test-gen",
241943
+ "/dead-code",
241944
+ "/deps"
241838
241945
  ];
241839
241946
  var COMMAND_DESCRIPTIONS = {
241840
241947
  "/help": "Show all available commands",
@@ -241919,7 +242026,17 @@ var COMMAND_DESCRIPTIONS = {
241919
242026
  "/btw": "Quick side question",
241920
242027
  "/batch": "Batch operations",
241921
242028
  "/color": "Terminal color palette",
241922
- "/terminal": "Terminal settings info"
242029
+ "/terminal": "Terminal settings info",
242030
+ "/explain": "Explain code at file:line using AI",
242031
+ "/refs": "Find all references of a symbol across project",
242032
+ "/resolve": "Detect and AI-resolve merge conflicts",
242033
+ "/stash": "Git stash management (save/pop/list)",
242034
+ "/changelog": "Generate CHANGELOG.md from git log",
242035
+ "/goto": "Navigate to type/function/class definition",
242036
+ "/find": "Semantic code search using AI",
242037
+ "/test-gen": "Generate tests for current file context",
242038
+ "/dead-code": "Detect unused imports/exports",
242039
+ "/deps": "Show dependency graph for a file"
241923
242040
  };
241924
242041
  var KNOWN_COMMANDS = new Set(ALL_COMMANDS);
241925
242042
  function shell(cmd, cwd) {
@@ -242101,20 +242218,36 @@ function handleSlashCommand(input, ctx) {
242101
242218
  console.log();
242102
242219
  return "handled";
242103
242220
  case "/pr":
242104
- console.log(`${CYAN} Creating pull request...${RESET}`);
242105
- shellPrint('gh pr create --web 2>/dev/null || echo " Install GitHub CLI: brew install gh"', ctx.cwd);
242221
+ handlePr(arg, ctx);
242106
242222
  return "handled";
242107
242223
  case "/pull":
242108
242224
  console.log(`${CYAN} Pulling latest changes...${RESET}`);
242109
242225
  shellPrint("git pull", ctx.cwd);
242110
242226
  return "handled";
242111
242227
  case "/push":
242112
- console.log(`${CYAN} Pushing to remote...${RESET}`);
242113
- shellPrint("git push", ctx.cwd);
242228
+ handlePush(ctx);
242114
242229
  return "handled";
242115
242230
  case "/commit":
242116
242231
  handleCommit(arg, ctx);
242117
242232
  return "handled";
242233
+ case "/stash":
242234
+ handleStash(arg, ctx);
242235
+ return "handled";
242236
+ case "/changelog":
242237
+ handleChangelog(ctx);
242238
+ return "handled";
242239
+ case "/resolve":
242240
+ handleResolveConflicts(ctx);
242241
+ return "handled";
242242
+ // -----------------------------------------------------------------------
242243
+ // Navigation & Search (41, 43)
242244
+ // -----------------------------------------------------------------------
242245
+ case "/goto":
242246
+ handleGoto(arg, ctx);
242247
+ return "handled";
242248
+ case "/find":
242249
+ handleFind(arg, ctx);
242250
+ return "handled";
242118
242251
  // -----------------------------------------------------------------------
242119
242252
  // File / Code commands
242120
242253
  // -----------------------------------------------------------------------
@@ -242134,6 +242267,12 @@ function handleSlashCommand(input, ctx) {
242134
242267
  console.log();
242135
242268
  }
242136
242269
  return "handled";
242270
+ case "/explain":
242271
+ handleExplain(arg, ctx);
242272
+ return "handled";
242273
+ case "/refs":
242274
+ handleRefs(arg, ctx);
242275
+ return "handled";
242137
242276
  case "/open":
242138
242277
  if (!arg) {
242139
242278
  console.log(`${YELLOW} Usage: /open <file|url> (opens in system default app)${RESET}`);
@@ -242408,6 +242547,18 @@ function handleSlashCommand(input, ctx) {
242408
242547
  );
242409
242548
  return "handled";
242410
242549
  // -----------------------------------------------------------------------
242550
+ // Code analysis (Features 7, 8, 10)
242551
+ // -----------------------------------------------------------------------
242552
+ case "/test-gen":
242553
+ handleTestGen(arg, ctx);
242554
+ return "handled";
242555
+ case "/dead-code":
242556
+ handleDeadCode(arg, ctx);
242557
+ return "handled";
242558
+ case "/deps":
242559
+ handleDeps(arg, ctx);
242560
+ return "handled";
242561
+ // -----------------------------------------------------------------------
242411
242562
  // Misc
242412
242563
  // -----------------------------------------------------------------------
242413
242564
  case "/btw":
@@ -242692,6 +242843,204 @@ function handleUndo() {
242692
242843
  console.log(`${RED} Failed to undo: ${err instanceof Error ? err.message : String(err)}${RESET}`);
242693
242844
  }
242694
242845
  }
242846
+ function handleExplain(arg, ctx) {
242847
+ if (!arg) {
242848
+ console.log(`${YELLOW} Usage: /explain <file:line> (e.g. /explain src/agent.ts:42)${RESET}`);
242849
+ return;
242850
+ }
242851
+ const match = arg.match(/^(.+?):(\d+)$/);
242852
+ if (!match) {
242853
+ console.log(`${YELLOW} Usage: /explain <file:line> (e.g. /explain src/agent.ts:42)${RESET}`);
242854
+ return;
242855
+ }
242856
+ const filePath = path14.resolve(ctx.cwd, match[1]);
242857
+ const lineNum = parseInt(match[2], 10);
242858
+ if (!fs15.existsSync(filePath)) {
242859
+ console.log(`${RED} File not found: ${filePath}${RESET}`);
242860
+ return;
242861
+ }
242862
+ try {
242863
+ const fileLines = fs15.readFileSync(filePath, "utf-8").split("\n");
242864
+ const start = Math.max(0, lineNum - 10);
242865
+ const end = Math.min(fileLines.length, lineNum + 10);
242866
+ const snippet = fileLines.slice(start, end).map((l, i) => {
242867
+ const num = start + i + 1;
242868
+ const marker = num === lineNum ? ">>>" : " ";
242869
+ return `${marker} ${String(num).padStart(4)} | ${l}`;
242870
+ }).join("\n");
242871
+ console.log();
242872
+ console.log(`${WHITE} ${match[1]}:${lineNum}${RESET}`);
242873
+ console.log(`${GRAY}${"\u2500".repeat(50)}${RESET}`);
242874
+ console.log(snippet);
242875
+ console.log(`${GRAY}${"\u2500".repeat(50)}${RESET}`);
242876
+ console.log();
242877
+ const prompt = `Please explain this code step by step. File: ${match[1]}, around line ${lineNum}:
242878
+
242879
+ \`\`\`
242880
+ ${snippet}
242881
+ \`\`\``;
242882
+ ctx.messages.push({ role: "user", content: prompt });
242883
+ ctx.setMessages(ctx.messages);
242884
+ console.log(`${GRAY} Asking AI to explain...${RESET}`);
242885
+ } catch (err) {
242886
+ console.log(`${RED} Failed to read: ${err instanceof Error ? err.message : String(err)}${RESET}`);
242887
+ }
242888
+ }
242889
+ function handleRefs(arg, ctx) {
242890
+ if (!arg) {
242891
+ console.log(`${YELLOW} Usage: /refs <symbol> (e.g. /refs handleSlashCommand)${RESET}`);
242892
+ return;
242893
+ }
242894
+ console.log(`${CYAN} Searching for "${arg}" across project...${RESET}`);
242895
+ console.log();
242896
+ const escaped = arg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
242897
+ const output = shell(`grep -rn --color=never "${escaped}" . --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' --include='*.py' --include='*.go' --include='*.rs' --include='*.java' --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=dist --exclude-dir=.next 2>/dev/null | head -50`, ctx.cwd);
242898
+ if (!output || output.includes("Command failed")) {
242899
+ console.log(`${GRAY} No references found for "${arg}".${RESET}`);
242900
+ } else {
242901
+ const resultLines = output.split("\n");
242902
+ console.log(`${WHITE} Found ${resultLines.length} reference(s):${RESET}`);
242903
+ console.log();
242904
+ for (const line of resultLines) console.log(` ${line}`);
242905
+ }
242906
+ console.log();
242907
+ }
242908
+ function handlePr(_arg, ctx) {
242909
+ const ghCheck = shell("which gh 2>/dev/null", ctx.cwd);
242910
+ if (!ghCheck || ghCheck.includes("Command failed")) {
242911
+ console.log(`${YELLOW} GitHub CLI not found. Install: brew install gh${RESET}`);
242912
+ return;
242913
+ }
242914
+ console.log(`${CYAN} Preparing pull request...${RESET}`);
242915
+ console.log();
242916
+ const branch = shell("git rev-parse --abbrev-ref HEAD", ctx.cwd);
242917
+ if (!branch || branch === "HEAD") {
242918
+ console.log(`${RED} Not on a branch. Cannot create PR.${RESET}`);
242919
+ return;
242920
+ }
242921
+ const recentCommits = shell("git log --oneline -5 2>/dev/null", ctx.cwd);
242922
+ const firstCommitLine = recentCommits.split("\n")[0] ?? "";
242923
+ const suggestedTitle = firstCommitLine.replace(/^[a-f0-9]+ /, "");
242924
+ const mainBranch = shell('git remote show origin 2>/dev/null | grep "HEAD branch" | sed "s/.*: //"', ctx.cwd) || "main";
242925
+ const diffStat = shell(`git diff ${mainBranch}...HEAD --stat 2>/dev/null`, ctx.cwd);
242926
+ const commitCount = shell(`git rev-list --count ${mainBranch}..HEAD 2>/dev/null`, ctx.cwd);
242927
+ console.log(`${WHITE} Branch: ${branch}${RESET}`);
242928
+ console.log(`${WHITE} Base: ${mainBranch}${RESET}`);
242929
+ console.log(`${WHITE} Commits: ${commitCount || "?"}${RESET}`);
242930
+ if (diffStat) console.log(`${GRAY}${diffStat}${RESET}`);
242931
+ console.log();
242932
+ console.log(`${WHITE} Suggested title: ${suggestedTitle}${RESET}`);
242933
+ console.log(`${WHITE} Recent commits:${RESET}`);
242934
+ console.log(`${GRAY}${recentCommits}${RESET}`);
242935
+ console.log();
242936
+ const safeTitle = suggestedTitle.replace(/"/g, '\\"');
242937
+ const safeDiff = (diffStat || "").replace(/\n/g, "\\n").replace(/"/g, '\\"');
242938
+ shellPrint(`gh pr create --title "${safeTitle}" --body "## Changes\\n${safeDiff}\\n\\nCommits: ${commitCount || "?"}" --web 2>/dev/null || echo " Failed to create PR. Run: gh auth login"`, ctx.cwd);
242939
+ console.log();
242940
+ }
242941
+ function handleResolveConflicts(ctx) {
242942
+ console.log(`${CYAN} Scanning for merge conflicts...${RESET}`);
242943
+ const output = shell('grep -rn "<<<<<<< " . --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" --include="*.md" --exclude-dir=node_modules --exclude-dir=.git 2>/dev/null | head -20', ctx.cwd);
242944
+ if (!output || output.includes("Command failed")) {
242945
+ console.log(`${GREEN} No merge conflicts found.${RESET}`);
242946
+ console.log();
242947
+ return;
242948
+ }
242949
+ const resultLines = output.split("\n").filter(Boolean);
242950
+ const files = [...new Set(resultLines.map((l) => l.split(":")[0]))];
242951
+ console.log(`${YELLOW} Found conflicts in ${files.length} file(s):${RESET}`);
242952
+ console.log();
242953
+ for (const file of files) console.log(`${RED} \u2716 ${file}${RESET}`);
242954
+ console.log();
242955
+ const prompt = `I have merge conflicts in these files:
242956
+ ${files.map((f) => `- ${f}`).join("\n")}
242957
+
242958
+ Please read each conflicted file, understand both sides of the conflict (between <<<<<<< and >>>>>>>) and suggest the best resolution. For each file, use edit_file to resolve the conflict by removing the conflict markers and keeping the correct code.`;
242959
+ ctx.messages.push({ role: "user", content: prompt });
242960
+ ctx.setMessages(ctx.messages);
242961
+ console.log(`${GRAY} Asking AI to resolve conflicts...${RESET}`);
242962
+ }
242963
+ function handleStash(arg, ctx) {
242964
+ const stashParts = arg.trim().split(/\s+/);
242965
+ const sub = stashParts[0] ?? "";
242966
+ const stashMsg = stashParts.slice(1).join(" ");
242967
+ switch (sub) {
242968
+ case "":
242969
+ case "save": {
242970
+ console.log(`${CYAN} Stashing changes...${RESET}`);
242971
+ const cmd = stashMsg ? `git stash push -m "${stashMsg.replace(/"/g, '\\"')}"` : "git stash push";
242972
+ shellPrint(cmd, ctx.cwd);
242973
+ break;
242974
+ }
242975
+ case "pop":
242976
+ console.log(`${CYAN} Applying latest stash...${RESET}`);
242977
+ shellPrint("git stash pop", ctx.cwd);
242978
+ break;
242979
+ case "list":
242980
+ console.log(`${BOLD} Git Stash List${RESET}`);
242981
+ console.log(`${GRAY} ${"\u2500".repeat(40)}${RESET}`);
242982
+ shellPrint("git stash list", ctx.cwd);
242983
+ break;
242984
+ case "drop":
242985
+ console.log(`${CYAN} Dropping latest stash...${RESET}`);
242986
+ shellPrint("git stash drop", ctx.cwd);
242987
+ break;
242988
+ case "show":
242989
+ shellPrint("git stash show -p", ctx.cwd);
242990
+ break;
242991
+ default:
242992
+ console.log(`${YELLOW} Usage: /stash [save|pop|list|drop|show] [message]${RESET}`);
242993
+ }
242994
+ console.log();
242995
+ }
242996
+ function handlePush(ctx) {
242997
+ const branch = shell("git rev-parse --abbrev-ref HEAD", ctx.cwd);
242998
+ if (["main", "master", "production", "prod"].includes(branch)) {
242999
+ console.log(`${RED} \u26A0 WARNING: You are on the '${branch}' branch!${RESET}`);
243000
+ console.log(`${YELLOW} Direct pushes to ${branch} are discouraged.${RESET}`);
243001
+ console.log(`${GRAY} Consider creating a feature branch and a pull request instead.${RESET}`);
243002
+ console.log(`${GRAY} Pushing anyway...${RESET}`);
243003
+ }
243004
+ console.log(`${CYAN} Pushing to remote...${RESET}`);
243005
+ shellPrint("git push", ctx.cwd);
243006
+ }
243007
+ function handleChangelog(ctx) {
243008
+ console.log(`${CYAN} Generating changelog...${RESET}`);
243009
+ console.log();
243010
+ const log = shell("git log --oneline -20 2>/dev/null", ctx.cwd);
243011
+ if (!log || log.includes("Command failed")) {
243012
+ console.log(`${YELLOW} No git history found.${RESET}`);
243013
+ return;
243014
+ }
243015
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
243016
+ const logLines = log.split("\n").filter(Boolean);
243017
+ const categories = {};
243018
+ for (const line of logLines) {
243019
+ const commitMsg = line.replace(/^[a-f0-9]+ /, "");
243020
+ const typeMatch = commitMsg.match(/^(feat|fix|refactor|docs|test|chore|perf|ci|style|build)(\(.*?\))?:\s*/);
243021
+ const type = typeMatch ? typeMatch[1] : "other";
243022
+ const msg = typeMatch ? commitMsg.replace(typeMatch[0], "") : commitMsg;
243023
+ if (!categories[type]) categories[type] = [];
243024
+ categories[type].push(msg);
243025
+ }
243026
+ const typeLabels = { feat: "Features", fix: "Bug Fixes", refactor: "Refactoring", docs: "Documentation", test: "Tests", perf: "Performance", chore: "Chores", other: "Other" };
243027
+ const changelogEntryLines = [`## [Unreleased] - ${today}`, ""];
243028
+ for (const [type, msgs] of Object.entries(categories)) {
243029
+ changelogEntryLines.push(`### ${typeLabels[type] ?? type}`);
243030
+ for (const msg of msgs) changelogEntryLines.push(`- ${msg}`);
243031
+ changelogEntryLines.push("");
243032
+ }
243033
+ const changelog = changelogEntryLines.join("\n");
243034
+ console.log(changelog);
243035
+ const changelogPath = path14.join(ctx.cwd, "CHANGELOG.md");
243036
+ const existing = fs15.existsSync(changelogPath) ? fs15.readFileSync(changelogPath, "utf-8") : "";
243037
+ const header = existing.startsWith("# Changelog") ? "" : "# Changelog\n\n";
243038
+ const newContent = existing ? existing.replace(/(# Changelog\n\n?)/, `$1${changelog}
243039
+ `) : `${header}${changelog}`;
243040
+ fs15.writeFileSync(changelogPath, newContent, "utf-8");
243041
+ console.log(`${GREEN} Updated: ${changelogPath}${RESET}`);
243042
+ console.log();
243043
+ }
242695
243044
  function printHelp() {
242696
243045
  console.log();
242697
243046
  console.log(`${BOLD} O'Route CLI Commands${RESET}`);
@@ -242767,6 +243116,9 @@ function printHelp() {
242767
243116
  console.log(`${GREEN} /seo${RESET} SEO analysis`);
242768
243117
  console.log(`${GREEN} /security${RESET} Security audit`);
242769
243118
  console.log(`${GREEN} /deploy-audit${RESET} Deployment readiness check`);
243119
+ console.log(`${GREEN} /test-gen [file]${RESET} Generate tests for a file`);
243120
+ console.log(`${GREEN} /dead-code [scope]${RESET} Detect unused imports/exports`);
243121
+ console.log(`${GREEN} /deps <file>${RESET} Show dependency graph for a file`);
242770
243122
  console.log();
242771
243123
  console.log(`${BOLD} Sub-agents & Plugins${RESET}`);
242772
243124
  console.log(`${GRAY} ${"\u2500".repeat(50)}${RESET}`);
@@ -242925,12 +243277,30 @@ function printTools() {
242925
243277
  function printKeybindings() {
242926
243278
  console.log();
242927
243279
  console.log(`${BOLD} Keyboard Shortcuts${RESET}`);
242928
- console.log(`${GRAY} ${"\u2500".repeat(40)}${RESET}`);
242929
- console.log(`${WHITE} Ctrl+C${RESET} Cancel current input / interrupt`);
242930
- console.log(`${WHITE} Ctrl+D${RESET} Exit CLI`);
242931
- console.log(`${WHITE} Up/Down${RESET} Navigate input history`);
242932
- console.log(`${WHITE} Tab${RESET} Autocomplete slash commands`);
242933
- console.log(`${WHITE} """${RESET} Toggle multi-line input mode`);
243280
+ console.log(`${GRAY} ${"\u2500".repeat(50)}${RESET}`);
243281
+ console.log();
243282
+ console.log(`${BOLD} Navigation${RESET}`);
243283
+ console.log(`${GREEN} Ctrl+C${RESET} Cancel current input / interrupt streaming`);
243284
+ console.log(`${GREEN} Ctrl+D${RESET} Exit CLI (end of input)`);
243285
+ console.log(`${GREEN} Ctrl+L${RESET} Clear terminal screen`);
243286
+ console.log();
243287
+ console.log(`${BOLD} History${RESET}`);
243288
+ console.log(`${GREEN} Up Arrow${RESET} Previous command from history`);
243289
+ console.log(`${GREEN} Down Arrow${RESET} Next command from history`);
243290
+ console.log(`${GREEN} Ctrl+R${RESET} Reverse search history (shell)`);
243291
+ console.log();
243292
+ console.log(`${BOLD} Editing${RESET}`);
243293
+ console.log(`${GREEN} Tab${RESET} Autocomplete slash commands`);
243294
+ console.log(`${GREEN} Ctrl+A${RESET} Move cursor to start of line`);
243295
+ console.log(`${GREEN} Ctrl+E${RESET} Move cursor to end of line`);
243296
+ console.log(`${GREEN} Ctrl+W${RESET} Delete word before cursor`);
243297
+ console.log(`${GREEN} Ctrl+U${RESET} Delete from cursor to start of line`);
243298
+ console.log(`${GREEN} Ctrl+K${RESET} Delete from cursor to end of line`);
243299
+ console.log();
243300
+ console.log(`${BOLD} Input Modes${RESET}`);
243301
+ console.log(`${GREEN} """${RESET} Toggle multi-line input mode`);
243302
+ console.log(`${GREEN} !<cmd>${RESET} Execute shell command directly`);
243303
+ console.log(`${GREEN} /<command>${RESET} Run a slash command`);
242934
243304
  console.log();
242935
243305
  }
242936
243306
  function printColorPalette() {
@@ -243024,6 +243394,126 @@ function handleExport(arg, ctx) {
243024
243394
  }
243025
243395
  console.log();
243026
243396
  }
243397
+ function handleGoto(symbol, ctx) {
243398
+ if (!symbol) {
243399
+ console.log(`${YELLOW} Usage: /goto <symbol> (e.g. /goto UserService, /goto handleLogin)${RESET}`);
243400
+ return;
243401
+ }
243402
+ console.log(`${CYAN} Searching for definition of "${symbol}"...${RESET}`);
243403
+ const escapedSymbol = symbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
243404
+ const pattern = `export.*(function|class|type|interface|const|enum)\\s+${escapedSymbol}`;
243405
+ const output = shell(
243406
+ `grep -rn --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' -E "${pattern}" . 2>/dev/null | head -20`,
243407
+ ctx.cwd
243408
+ );
243409
+ if (!output || output.startsWith("Command failed")) {
243410
+ console.log(`${GRAY} No exported definition found for "${symbol}". Trying broader search...${RESET}`);
243411
+ const broadOutput = shell(
243412
+ `grep -rn --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' -E "(function|class|type|interface|const|enum)\\s+${escapedSymbol}" . 2>/dev/null | head -20`,
243413
+ ctx.cwd
243414
+ );
243415
+ if (!broadOutput || broadOutput.startsWith("Command failed")) {
243416
+ console.log(`${YELLOW} No definition found for "${symbol}".${RESET}`);
243417
+ } else {
243418
+ console.log();
243419
+ console.log(broadOutput);
243420
+ }
243421
+ } else {
243422
+ console.log();
243423
+ console.log(output);
243424
+ }
243425
+ console.log();
243426
+ }
243427
+ function handleFind(description, ctx) {
243428
+ if (!description) {
243429
+ console.log(`${YELLOW} Usage: /find <description> (e.g. /find "function that validates email")${RESET}`);
243430
+ return;
243431
+ }
243432
+ const prompt = `Search this project's codebase to find code that matches this description: "${description}". Use search_files and glob tools to locate relevant files, then read the matching sections. Show the file path, line number, and a brief snippet for each match.`;
243433
+ ctx.messages.push({ role: "user", content: prompt });
243434
+ console.log(`${CYAN} Asking AI to find: "${description}"${RESET}`);
243435
+ console.log(`${GRAY} (AI will use tools to search the codebase)${RESET}`);
243436
+ console.log();
243437
+ }
243438
+ function handleTestGen(arg, ctx) {
243439
+ const target = arg || "the most recently discussed file";
243440
+ const prompt = `Generate comprehensive unit tests for ${target}. Follow these steps:
243441
+ 1. Read the target file(s) using read_file
243442
+ 2. Analyze all exported functions, classes, and key logic
243443
+ 3. Write test cases covering: happy path, edge cases, error handling, boundary conditions
243444
+ 4. Use the project's existing test framework (detect from package.json \u2014 jest, vitest, mocha, etc.)
243445
+ 5. If no test framework is detected, use Node.js built-in test runner
243446
+ 6. Write the tests to a corresponding test file (e.g., foo.ts \u2192 foo.test.ts)
243447
+ 7. Include at minimum: 1 test per exported function, 1 edge case per function, 1 error case per function
243448
+
243449
+ Output the complete test file content.`;
243450
+ ctx.messages.push({ role: "user", content: prompt });
243451
+ console.log(`${CYAN} Generating tests for: ${target}${RESET}`);
243452
+ console.log(`${GRAY} (AI will read the file and create tests)${RESET}`);
243453
+ console.log();
243454
+ }
243455
+ function handleDeadCode(arg, ctx) {
243456
+ const scope = arg || ".";
243457
+ const prompt = `Analyze the codebase at "${scope}" for dead code. Follow these steps:
243458
+ 1. Use glob to find all TypeScript/JavaScript source files in the scope
243459
+ 2. For each file, identify all exports (functions, classes, types, constants)
243460
+ 3. Use search_files to check if each export is imported/used elsewhere in the project
243461
+ 4. Report:
243462
+ - Unused exports (exported but never imported)
243463
+ - Unused imports (imported but never referenced in the file)
243464
+ - Unreachable code (code after return/throw statements)
243465
+ - Unused variables/parameters (if obvious)
243466
+
243467
+ Format the results as a list grouped by file, showing the symbol name, type, and line number.
243468
+ Mark severity: HIGH (unused export), MEDIUM (unused import), LOW (unused variable).`;
243469
+ ctx.messages.push({ role: "user", content: prompt });
243470
+ console.log(`${CYAN} Analyzing dead code in: ${scope}${RESET}`);
243471
+ console.log(`${GRAY} (AI will scan imports/exports across the project)${RESET}`);
243472
+ console.log();
243473
+ }
243474
+ function handleDeps(arg, ctx) {
243475
+ if (!arg) {
243476
+ console.log(`${YELLOW} Usage: /deps <file> (e.g. /deps src/agent.ts)${RESET}`);
243477
+ console.log(`${GRAY} Shows all files that import the given file (reverse dependencies).${RESET}`);
243478
+ return;
243479
+ }
243480
+ const basename6 = path14.basename(arg).replace(/\.(ts|tsx|js|jsx)$/, "");
243481
+ const searchPatterns = [
243482
+ `from.*['"].*${basename6}['"]`,
243483
+ `require.*['"].*${basename6}['"]`
243484
+ ];
243485
+ console.log(`${BOLD} Dependency Graph: ${arg}${RESET}`);
243486
+ console.log(`${GRAY} ${"\u2500".repeat(40)}${RESET}`);
243487
+ console.log();
243488
+ console.log(`${WHITE} Files that import "${basename6}":${RESET}`);
243489
+ let totalFound = 0;
243490
+ for (const pattern of searchPatterns) {
243491
+ try {
243492
+ const result = shell(
243493
+ `grep -rn --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' "${pattern}" . 2>/dev/null | grep -v node_modules | grep -v '.d.ts'`,
243494
+ ctx.cwd
243495
+ );
243496
+ if (result && !result.startsWith("Command failed")) {
243497
+ const lines = result.split("\n").filter(Boolean);
243498
+ for (const line of lines) {
243499
+ const [filePart] = line.split(":");
243500
+ if (filePart && !filePart.includes(arg)) {
243501
+ console.log(`${GREEN} ${line}${RESET}`);
243502
+ totalFound++;
243503
+ }
243504
+ }
243505
+ }
243506
+ } catch {
243507
+ }
243508
+ }
243509
+ if (totalFound === 0) {
243510
+ console.log(`${GRAY} No files import "${basename6}" in this project.${RESET}`);
243511
+ } else {
243512
+ console.log();
243513
+ console.log(`${GRAY} Found ${totalFound} reference(s).${RESET}`);
243514
+ }
243515
+ console.log();
243516
+ }
243027
243517
 
243028
243518
  // src/hooks.ts
243029
243519
  var fs16 = __toESM(require("node:fs"), 1);
@@ -243108,6 +243598,8 @@ function substituteEnvVars(command, env) {
243108
243598
 
243109
243599
  // src/agent.ts
243110
243600
  init_mcpLoader();
243601
+ var keepAliveHttpAgent = new http.Agent({ keepAlive: true });
243602
+ var keepAliveHttpsAgent = new https.Agent({ keepAlive: true });
243111
243603
  var TOOL_DEFINITIONS = [
243112
243604
  readFileDefinition,
243113
243605
  writeFileDefinition,
@@ -243126,20 +243618,56 @@ var PARALLEL_SAFE_TOOLS = /* @__PURE__ */ new Set([
243126
243618
  "read_image"
243127
243619
  ]);
243128
243620
  var MAX_TOOL_RESULT_CHARS = 4e3;
243129
- var MIN_API_DELAY_MS = 500;
243621
+ var MODEL_DELAYS = {
243622
+ opus: 2e3,
243623
+ sonnet: 1e3,
243624
+ haiku: 300,
243625
+ mini: 300
243626
+ };
243627
+ var DEFAULT_API_DELAY_MS = 500;
243628
+ function getModelDelay(model) {
243629
+ const lower = model.toLowerCase();
243630
+ for (const [key, delay] of Object.entries(MODEL_DELAYS)) {
243631
+ if (lower.includes(key)) return delay;
243632
+ }
243633
+ return DEFAULT_API_DELAY_MS;
243634
+ }
243130
243635
  var lastApiCallTime = 0;
243131
- function appendAuditLog(toolName, filePath) {
243636
+ var turnRollbackBuffer = /* @__PURE__ */ new Map();
243637
+ function appendAuditLog(toolName, filePath, extra) {
243132
243638
  try {
243133
243639
  const auditDir = path16.join(os7.homedir(), ".oroute");
243134
243640
  if (!fs17.existsSync(auditDir)) fs17.mkdirSync(auditDir, { recursive: true });
243135
243641
  const logPath = path16.join(auditDir, "audit.log");
243136
243642
  const ts = (/* @__PURE__ */ new Date()).toISOString();
243137
- const entry = `${ts} tool=${toolName} path=${filePath ?? "-"}
243138
- `;
243139
- fs17.appendFileSync(logPath, entry);
243643
+ let entry = `${ts} tool=${toolName} path=${filePath ?? "-"}`;
243644
+ if (extra?.command) entry += ` cmd=${extra.command}`;
243645
+ if (extra?.escalation) entry += ` escalation=${extra.escalation}`;
243646
+ if (extra?.affectedFiles && extra.affectedFiles.length > 0) entry += ` affected=${extra.affectedFiles.join(",")}`;
243647
+ fs17.appendFileSync(logPath, entry + "\n");
243140
243648
  } catch {
243141
243649
  }
243142
243650
  }
243651
+ function detectCommandEscalation(command) {
243652
+ const modifyingPatterns = [
243653
+ [/\bgit\s+(add|commit|reset|checkout|merge|rebase|push|rm)\b/, "git-modify"],
243654
+ [/\bnpm\s+(install|uninstall|update|publish|init)\b/, "npm-modify"],
243655
+ [/\bpnpm\s+(add|remove|install|update|publish)\b/, "pnpm-modify"],
243656
+ [/\byarn\s+(add|remove|install|upgrade|publish)\b/, "yarn-modify"],
243657
+ [/\brm\s/, "file-delete"],
243658
+ [/\bmv\s/, "file-move"],
243659
+ [/\bcp\s/, "file-copy"],
243660
+ [/\bchmod\s/, "permission-change"],
243661
+ [/\bchown\s/, "ownership-change"],
243662
+ [/\bmkdir\s/, "directory-create"]
243663
+ ];
243664
+ for (const [pattern, reason] of modifyingPatterns) {
243665
+ if (pattern.test(command)) {
243666
+ return { escalation: reason, reason: `Command matches modifying pattern: ${reason}` };
243667
+ }
243668
+ }
243669
+ return null;
243670
+ }
243143
243671
  function maskDebugSecrets(text) {
243144
243672
  return text.replace(/\b(or|sk|key)-[a-zA-Z0-9]{10,}/g, "$1-****").replace(/Bearer\s+[a-zA-Z0-9._\-]{10,}/gi, "Bearer ****").replace(/(API_KEY|SECRET|TOKEN|PASSWORD)\s*[=:]\s*["']?[^\s"']{5,}/gi, "$1=****");
243145
243673
  }
@@ -243261,10 +243789,81 @@ ${contextSection}${memorySection}
243261
243789
  - **read_image**: Read images for visual analysis (base64).
243262
243790
  - **diff_files**: Compare two files, unified diff format.
243263
243791
 
243792
+ # Tool Usage Guide \u2014 When and How to Use Each Tool
243793
+
243794
+ ## read_file
243795
+ - **Always read before editing.** Never guess file contents.
243796
+ - For large files (>200 lines), use offset/limit to read only the relevant section.
243797
+ Example: read_file(path="src/big.ts", offset=50, limit=30) reads lines 50-80.
243798
+ - For PDFs, just read normally \u2014 PDF text extraction is automatic.
243799
+ - For Jupyter notebooks (.ipynb), read returns all cells with outputs combined.
243800
+ - If you already read a file earlier in this session and it hasn't been modified, you don't need to re-read it.
243801
+ - Prefer read_file over execute_command("cat ...") \u2014 it handles encoding, caching, and large files better.
243802
+
243803
+ ## write_file
243804
+ - **Only use for new files or complete rewrites.** For targeted changes, always use edit_file instead.
243805
+ - write_file shows a diff preview and asks for confirmation before overwriting existing files.
243806
+ - When creating new files, ensure the parent directory exists (use execute_command("mkdir -p ...") if needed).
243807
+ - Never use write_file to append to a file \u2014 read it first, then write the full updated content.
243808
+
243809
+ ## edit_file
243810
+ - For targeted, surgical changes to existing files. Much safer than write_file for modifications.
243811
+ - The old_str parameter must be a **unique** match in the file. If the string appears multiple times:
243812
+ - Add more surrounding context lines to make it unique.
243813
+ - Include the lines before and after the target to create a unique block.
243814
+ - edit_file automatically handles CRLF line endings and Unicode characters.
243815
+ - After editing .ts/.tsx files, a type check (tsc --noEmit) runs automatically.
243816
+ - If the edit fails with "no match found", re-read the file \u2014 it may have been modified since you last read it.
243817
+
243818
+ ## search_files
243819
+ - Use context_lines=3 for meaningful results \u2014 shows surrounding code for each match.
243820
+ - Use offset and limit for pagination when searching large codebases with many matches.
243821
+ - The pattern is a regex \u2014 escape special characters: \\. \\( \\[ \\{ \\* \\+
243822
+ - To search a specific directory: search_files(pattern="TODO", directory="src/components")
243823
+ - Returns results as file:line:content \u2014 parse the file path from each result line.
243824
+ - If 0 results: try a broader pattern, check spelling, or search a parent directory.
243825
+
243826
+ ## execute_command
243827
+ - **Prefer specialized tools over shell commands:**
243828
+ - Use read_file instead of cat/head/tail
243829
+ - Use edit_file instead of sed/awk
243830
+ - Use search_files instead of grep/rg
243831
+ - Use glob instead of find
243832
+ - Use list_directory instead of ls -R
243833
+ - **Do use execute_command for:**
243834
+ - Package managers: npm, pnpm, yarn, pip
243835
+ - Git operations: git status, git diff, git log, git add, git commit
243836
+ - Build tools: tsc, webpack, vite, esbuild
243837
+ - Test runners: vitest, jest, pytest
243838
+ - Linters/formatters: eslint, prettier, biome
243839
+ - Project-specific scripts: pnpm dev, pnpm build
243840
+ - Commands run in the project working directory by default.
243841
+ - Long-running commands have a timeout \u2014 prefer build/test commands over dev servers.
243842
+
243843
+ ## glob
243844
+ - Use for finding files by name pattern across the project.
243845
+ - Respects .gitignore \u2014 won't return files in node_modules, .git, dist, etc.
243846
+ - Common patterns:
243847
+ - "**/*.tsx" \u2014 all React component files
243848
+ - "src/**/*.test.ts" \u2014 all test files in src
243849
+ - "**/package.json" \u2014 all package.json files in monorepo
243850
+ - "src/components/Button*" \u2014 files starting with "Button" in components
243851
+ - Returns file paths sorted by modification time (newest first).
243852
+
243853
+ ## diff_files
243854
+ - Use to compare two files side by side in unified diff format.
243855
+ - Useful for: comparing before/after changes, comparing similar files, reviewing config differences.
243856
+ - Output follows standard unified diff format with +/- prefixes.
243857
+
243264
243858
  # Core Behavior
243265
243859
 
243266
243860
  ## Language
243267
243861
  - Match the user's language. Korean input \u2192 Korean response. English \u2192 English. Mixed \u2192 match dominant.
243862
+ - \uC0AC\uC6A9\uC790\uAC00 \uD55C\uAD6D\uC5B4\uB85C \uC791\uC131\uD558\uBA74, \uD55C\uAD6D\uC5B4\uB85C \uC751\uB2F5\uD569\uB2C8\uB2E4.
243863
+ - \uD504\uB85C\uC81D\uD2B8\uC5D0 \uD55C\uAD6D\uC5B4 \uC8FC\uC11D\uC774 \uC774\uBBF8 \uC788\uC73C\uBA74 \uD55C\uAD6D\uC5B4 \uC8FC\uC11D\uC744 \uC720\uC9C0\uD569\uB2C8\uB2E4.
243864
+ - \uC5D0\uB7EC \uBA54\uC2DC\uC9C0\uC640 \uC124\uBA85\uB3C4 \uD55C\uAD6D\uC5B4\uB85C \uC81C\uACF5\uD569\uB2C8\uB2E4.
243865
+ - \uAE30\uC220 \uC6A9\uC5B4(API, commit, deploy, function, import, export \uB4F1)\uB294 \uC601\uC5B4\uB97C \uC720\uC9C0\uD569\uB2C8\uB2E4.
243866
+ - \uCF54\uB4DC \uB0B4 \uBCC0\uC218\uBA85, \uD568\uC218\uBA85\uC740 \uD56D\uC0C1 \uC601\uC5B4\uB85C \uC791\uC131\uD569\uB2C8\uB2E4.
243268
243867
 
243269
243868
  ## Approach
243270
243869
  - **Conclusion first**: Start with the answer/action, then explain why.
@@ -243277,6 +243876,97 @@ ${contextSection}${memorySection}
243277
243876
  - **Ask first** when: task is ambiguous ("fix the bug" \u2014 which bug?), destructive (deleting files), architecture decisions
243278
243877
  - **Never guess** when: file paths, variable names, API keys, database schemas
243279
243878
 
243879
+ # 5-Stage Failure Recovery
243880
+
243881
+ When a tool call or approach fails, follow this escalation protocol:
243882
+
243883
+ ## Stage 1: Try the Obvious Approach
243884
+ - Execute the most straightforward solution first.
243885
+ - Example: edit_file with the string you expect to find.
243886
+
243887
+ ## Stage 2: Try an Alternative Method
243888
+ - If Stage 1 fails, switch to a different tool or approach.
243889
+ - edit_file failed \u2192 re-read the file with read_file, then retry with the correct string.
243890
+ - search_files returned nothing \u2192 try glob to find the right file first.
243891
+ - execute_command failed \u2192 read the error, check if a dependency is missing.
243892
+
243893
+ ## Stage 3: Expand Context
243894
+ - If Stage 2 also fails, gather more information before retrying.
243895
+ - Read more of the file (expand offset/limit range).
243896
+ - Check related files (imports, configs, package.json).
243897
+ - Search for the function/variable name across the project.
243898
+ - Check git status or git log for recent changes that might explain the issue.
243899
+
243900
+ ## Stage 4: Ask the User
243901
+ - After 3 failed attempts with different approaches, ask the user for clarification.
243902
+ - Explain clearly: what you tried, what failed, and what information you need.
243903
+ - Example: "I tried searching for the handleSubmit function in src/ but found 0 matches. Could you tell me which file contains this function?"
243904
+
243905
+ ## Stage 5: Detailed Failure Report
243906
+ - If truly stuck (rare), provide a comprehensive report:
243907
+ - What the goal was
243908
+ - Each approach tried and why it failed
243909
+ - What information is missing
243910
+ - Suggested next steps the user could try manually
243911
+
243912
+ # Token Budget Management
243913
+
243914
+ ## Response Length Guidelines
243915
+ - Simple questions (what does X do?, where is Y?) \u2192 under 500 tokens. Be direct.
243916
+ - Code changes (fix this, add that) \u2192 under 1500 tokens. Show the change, brief explanation.
243917
+ - Complex analysis (review this file, explain architecture) \u2192 under 2500 tokens. Be thorough but focused.
243918
+ - Multi-step tasks \u2192 break into steps, each step under 1000 tokens.
243919
+
243920
+ ## File Reading Efficiency
243921
+ - Never dump an entire large file into context. Use offset/limit to read only what you need.
243922
+ - For files >200 lines: read the specific section relevant to the task.
243923
+ - For files >500 lines: use search_files to find the exact line first, then read \xB120 lines around it.
243924
+ - Summarize long tool results \u2014 don't echo raw output back to the user verbatim.
243925
+
243926
+ ## Conversation Length Awareness
243927
+ - After ~50K tokens in a conversation, suggest the user run /compact to compress history.
243928
+ - Track what you've already read \u2014 don't re-read the same file sections repeatedly.
243929
+ - If a tool returns very long output, summarize the key findings instead of quoting it all.
243930
+ - Prefer targeted searches (search_files with specific pattern) over broad reads (list_directory with depth=5).
243931
+
243932
+ # Code Style Detection
243933
+
243934
+ Before writing or modifying code, detect and follow the project's existing style:
243935
+
243936
+ ## Detection Steps
243937
+ 1. Check for style config files: .eslintrc*, .prettierrc*, biome.json, .editorconfig
243938
+ 2. Read a few existing files in the same directory to observe patterns.
243939
+ 3. Note: indentation (tabs vs spaces, 2 vs 4), semicolons (yes/no), quotes (single/double).
243940
+ 4. Note: naming conventions \u2014 camelCase vs snake_case, PascalCase for components, UPPER_CASE for constants.
243941
+ 5. Note: import style \u2014 named imports, default imports, path aliases (@/), relative paths.
243942
+
243943
+ ## Rules
243944
+ - Match whatever style the project already uses. Consistency > personal preference.
243945
+ - If the project uses semicolons, add semicolons. If it doesn't, don't.
243946
+ - If the project uses 2-space indentation, use 2-space indentation.
243947
+ - If the project uses single quotes, use single quotes.
243948
+ - Don't change existing code style unless the user explicitly asks you to.
243949
+ - When in doubt, check .prettierrc or .eslintrc for the authoritative answer.
243950
+
243951
+ # Multi-turn Strategy
243952
+
243953
+ ## Session Awareness
243954
+ - Track what files you've read, what changes you've made, and what tools you've used.
243955
+ - Don't re-read files you already read in this session unless they've been modified.
243956
+ - If the user asks about something you already investigated, reference your earlier findings.
243957
+
243958
+ ## Progress Tracking
243959
+ - For multi-step tasks, report progress: "Step 2/4: Writing test file..."
243960
+ - At the end of a multi-step task, summarize: "Done. Fixed 3 files, added 2 tests, all passing."
243961
+ - If a task will span multiple turns, summarize what's been done and what remains at each turn.
243962
+
243963
+ ## Proactive Next Steps
243964
+ - After completing a task, suggest 1-2 logical next steps:
243965
+ - "Want me to run the tests?" (after code changes)
243966
+ - "Should I commit these changes?" (after successful changes)
243967
+ - "Want me to check the other files that import this function?" (after renaming)
243968
+ - Don't suggest more than 2 next steps \u2014 keep it focused.
243969
+
243280
243970
  ## Error Recovery
243281
243971
  - If a tool fails, **don't retry the same thing**. Analyze the error and try a different approach:
243282
243972
  - File not found \u2192 search for similar filenames with glob
@@ -243285,40 +243975,117 @@ ${contextSection}${memorySection}
243285
243975
  - Search returned 0 results \u2192 try broader pattern or different directory
243286
243976
  - Maximum 3 attempts per approach. After that, explain what went wrong and ask for guidance.
243287
243977
 
243288
- ## Code Quality
243978
+ # Code Quality
243979
+
243980
+ ## General Rules
243289
243981
  - Follow existing code style (indentation, naming conventions, patterns)
243290
243982
  - Don't add comments unless the logic is non-obvious
243291
243983
  - Don't add type annotations to code you didn't change
243292
243984
  - Don't refactor or "improve" code you weren't asked to touch
243293
243985
  - When writing new code: handle errors, validate inputs at boundaries, use immutable patterns
243294
243986
 
243295
- ## Git Awareness
243987
+ ## Immutability Principle
243988
+ - Always create new objects instead of mutating existing ones.
243989
+ - Use spread operator: { ...obj, key: newValue } instead of obj.key = newValue.
243990
+ - Use array methods that return new arrays: map, filter, reduce instead of push, splice.
243991
+ - This prevents hard-to-track bugs from shared references.
243992
+
243993
+ ## Function Size
243994
+ - Keep functions under 50 lines. If longer, extract helper functions.
243995
+ - Keep files under 400 lines ideally, 800 lines maximum.
243996
+ - Each function should do one thing well.
243997
+
243998
+ # Git Awareness
243296
243999
  - Before making changes, note the current git state
243297
244000
  - After completing changes, suggest: "I can commit these changes. Want me to run git add + commit?"
243298
244001
  - Write commit messages: imperative mood, explain WHY not WHAT
244002
+ - Format: <type>: <description> (feat, fix, refactor, docs, test, chore)
243299
244003
  - Never force push or amend without explicit user request
244004
+ - Don't commit .env files, credentials, or large binary files
243300
244005
 
243301
- ## File Operations Safety
244006
+ # File Operations Safety
243302
244007
  - **Always confirm** before: deleting files, overwriting files, running destructive commands
243303
244008
  - **Never modify**: .env files (suggest changes instead), node_modules, .git directory
243304
244009
  - **Large files** (>500 lines): use offset/limit to read relevant sections, don't dump entire file
243305
244010
 
243306
- ## Response Format
244011
+ # Response Format
243307
244012
  - Use markdown for readability (headers, code blocks, lists)
243308
244013
  - Code blocks: always specify language (\`\`\`typescript, \`\`\`bash, etc.)
243309
244014
  - Keep responses concise. Lead with action, not explanation.
243310
244015
  - After completing a task, suggest logical next steps (test, commit, review)
243311
244016
 
243312
- ## Task Tracking
243313
- - For multi-step tasks, maintain a mental checklist
243314
- - Report progress: "Step 2/4: Writing test file..."
243315
- - At the end, summarize what was done: "Fixed 3 files, added 2 tests, all passing."
244017
+ # Security Awareness
244018
+
244019
+ ## Secrets and Credentials
244020
+ - **Never** write API keys, tokens, passwords, or secrets into code files.
244021
+ - If you find hardcoded credentials during code review, immediately flag them.
244022
+ - Suggest .env files for secrets and ensure .env is in .gitignore.
244023
+ - When creating new .env files, always add them to .gitignore.
244024
+ - Never output secret values in responses \u2014 mask them with **** if referencing.
244025
+
244026
+ ## Command Safety
244027
+ - Never execute curl/wget piped to sh (curl ... | sh)
244028
+ - Validate that file paths don't escape the project directory (no ../ traversal attacks)
244029
+ - Don't run rm -rf on directories without explicit user confirmation
244030
+ - Don't install packages from unknown/untrusted sources without flagging
244031
+
244032
+ ## Code Review Security
244033
+ - Flag SQL injection vulnerabilities (string concatenation in queries)
244034
+ - Flag XSS vulnerabilities (unsanitized user input in HTML/JSX)
244035
+ - Flag exposed sensitive data in logs or error messages
244036
+ - Flag missing authentication/authorization checks on API routes
244037
+ - Flag hardcoded secrets anywhere in the codebase
244038
+
244039
+ # Auto Import Management
244040
+ - When you create new functions, types, or constants that are used in other files, automatically add the necessary import statements to those files.
244041
+ - When you rename or move exports, update all import references across the project.
244042
+ - Before adding an import, verify the export exists in the source file.
244043
+ - Use the project's existing import style (named vs default, relative vs alias paths).
244044
+
244045
+ # Syntax Error Context (Feature 42)
244046
+ - When you encounter a syntax error, automatically read 20 lines before and after the error line to understand the full context before attempting a fix.
244047
+ - Use read_file with offset=(errorLine - 20) and limit=41 to get surrounding context.
244048
+
244049
+ # Refactoring Suggestions (Feature 44)
244050
+ - When you notice repeated code patterns (3+ similar blocks), proactively suggest extracting them into a shared function.
244051
+ - Mention the duplication, propose a function signature, and ask if the user wants you to refactor.
243316
244052
 
243317
- ## Security
243318
- - Never output API keys, tokens, passwords, or secrets
243319
- - Never execute curl/wget piped to sh
243320
- - Validate that file paths don't escape the project directory
243321
- - Flag potential security issues in code you review`;
244053
+ # Monorepo Awareness
244054
+
244055
+ ## O'Route Project Structure
244056
+ - This is a pnpm monorepo with workspaces: apps/*, packages/*
244057
+ - Shared types and config live in packages/shared \u2014 always import from @oroute/shared
244058
+ - Provider adapters must be in packages/providers \u2014 never inline provider logic in apps/api
244059
+ - Changes to packages/shared require rebuilding: cd packages/shared && pnpm build
244060
+ - The CLI lives in cli/ \u2014 it is a standalone tool with its own build
244061
+
244062
+ ## Cross-Package Changes
244063
+ - When modifying a type in packages/shared, check all consumers (apps/api, apps/web, cli)
244064
+ - When adding a new export to a package, ensure it's re-exported from the package's index.ts
244065
+ - Run pnpm build at the root to verify all packages compile together
244066
+
244067
+ # Testing Guidelines
244068
+
244069
+ ## When to Suggest Tests
244070
+ - After implementing a new function or module \u2014 suggest unit tests
244071
+ - After fixing a bug \u2014 suggest a regression test
244072
+ - After changing API endpoints \u2014 suggest integration tests
244073
+ - Don't suggest tests for trivial changes (typo fixes, comment updates)
244074
+
244075
+ ## Test Patterns
244076
+ - Use vitest for unit and integration tests
244077
+ - Test files: *.test.ts or *.spec.ts alongside the source file
244078
+ - Follow AAA pattern: Arrange, Act, Assert
244079
+ - Mock external dependencies (API calls, file system, databases)
244080
+ - Test edge cases: empty input, null/undefined, boundary values
244081
+
244082
+ # Task Completion Checklist
244083
+ When you finish a task, mentally verify:
244084
+ 1. Did I make all the requested changes?
244085
+ 2. Are there any files I modified that need updated imports?
244086
+ 3. Would this change break anything in related files?
244087
+ 4. Should I suggest running tests or type checking?
244088
+ 5. Is there a logical next step the user might want?`;
243322
244089
  }
243323
244090
  function truncateResult(result) {
243324
244091
  if (result.length <= MAX_TOOL_RESULT_CHARS) return result;
@@ -243329,6 +244096,11 @@ function truncateResult(result) {
243329
244096
  ... (${totalLines - keptLines} lines, ${omittedChars} chars truncated \u2014 showing ${keptLines}/${totalLines} lines)`;
243330
244097
  }
243331
244098
  async function executeTool(tool, cwd, config) {
244099
+ if (config.toolBlacklist && config.toolBlacklist.includes(tool.name)) {
244100
+ const msg = `Tool "${tool.name}" is blacklisted in config. Skipping.`;
244101
+ console.log(`${YELLOW} ${msg}${RESET}`);
244102
+ return JSON.stringify({ error: msg });
244103
+ }
243332
244104
  const confirmWrite = config.skipConfirmations ? false : config.confirmBeforeWrite !== false;
243333
244105
  const confirmExec = config.skipConfirmations ? false : config.confirmBeforeExecute !== false;
243334
244106
  const toolStart = performance.now();
@@ -243346,6 +244118,20 @@ async function executeTool(tool, cwd, config) {
243346
244118
  if (elapsed > 100) {
243347
244119
  console.log(`${DIM} (failed after ${elapsed.toFixed(0)}ms)${RESET}`);
243348
244120
  }
244121
+ if (turnRollbackBuffer.size > 0) {
244122
+ console.log(`${YELLOW} Tool failed. ${turnRollbackBuffer.size} file(s) can be rolled back.${RESET}`);
244123
+ for (const [filePath] of turnRollbackBuffer) {
244124
+ console.log(`${GRAY} - ${filePath}${RESET}`);
244125
+ }
244126
+ for (const [filePath, content] of turnRollbackBuffer) {
244127
+ try {
244128
+ fs17.writeFileSync(filePath, content, "utf-8");
244129
+ console.log(`${GREEN} Rolled back: ${filePath}${RESET}`);
244130
+ } catch {
244131
+ }
244132
+ }
244133
+ turnRollbackBuffer.clear();
244134
+ }
243349
244135
  return JSON.stringify({ error: msg });
243350
244136
  }
243351
244137
  }
@@ -243361,6 +244147,13 @@ async function executeToolInner(tool, cwd, confirmWrite, confirmExec, config) {
243361
244147
  case "write_file": {
243362
244148
  const input = tool.input;
243363
244149
  printToolUse("write_file", input.path);
244150
+ const resolvedForRollback = path16.resolve(cwd, input.path);
244151
+ if (fs17.existsSync(resolvedForRollback) && !turnRollbackBuffer.has(resolvedForRollback)) {
244152
+ try {
244153
+ turnRollbackBuffer.set(resolvedForRollback, fs17.readFileSync(resolvedForRollback, "utf-8"));
244154
+ } catch {
244155
+ }
244156
+ }
243364
244157
  const resolved = path16.resolve(cwd, input.path);
243365
244158
  const dangerPaths = ["/etc", "/usr", "/bin", "/sbin", "/System", "/Windows", "node_modules"];
243366
244159
  if (dangerPaths.some((d) => resolved.startsWith(d) || resolved.includes("node_modules"))) {
@@ -243375,7 +244168,16 @@ async function executeToolInner(tool, cwd, confirmWrite, confirmExec, config) {
243375
244168
  console.log(`${YELLOW} [DRY-RUN] Would write ${input.content.length} chars to ${input.path}${RESET}`);
243376
244169
  return JSON.stringify({ success: true, note: "dry-run \u2014 not written" });
243377
244170
  }
243378
- if (confirmWrite) {
244171
+ const secretWarnings = scanForSecrets(input.content);
244172
+ if (secretWarnings.length > 0) {
244173
+ console.log(`${RED} WARNING: Potential secrets detected in file content:${RESET}`);
244174
+ for (const warning of secretWarnings) {
244175
+ console.log(`${YELLOW} - ${warning}${RESET}`);
244176
+ }
244177
+ const secretOk = await confirm("File contains potential secrets. Write anyway?");
244178
+ if (!secretOk) return JSON.stringify({ success: false, reason: "User declined \u2014 secrets detected" });
244179
+ }
244180
+ if (confirmWrite && secretWarnings.length === 0) {
243379
244181
  const ok = await confirm(`Write to ${input.path}?`);
243380
244182
  if (!ok) return JSON.stringify({ success: false, reason: "User declined" });
243381
244183
  }
@@ -243422,6 +244224,13 @@ async function executeToolInner(tool, cwd, confirmWrite, confirmExec, config) {
243422
244224
  case "edit_file": {
243423
244225
  const input = tool.input;
243424
244226
  printToolUse("edit_file", input.path);
244227
+ const editResolved = path16.resolve(cwd, input.path);
244228
+ if (fs17.existsSync(editResolved) && !turnRollbackBuffer.has(editResolved)) {
244229
+ try {
244230
+ turnRollbackBuffer.set(editResolved, fs17.readFileSync(editResolved, "utf-8"));
244231
+ } catch {
244232
+ }
244233
+ }
243425
244234
  const diff = generateEditDiff(input);
243426
244235
  console.log(`${GRAY}${diff}${RESET}`);
243427
244236
  if (config.planMode || isDryRun()) {
@@ -243477,7 +244286,12 @@ async function executeToolWithHooks(tool, cwd, config, hooks) {
243477
244286
  const result = await executeTool(tool, cwd, config);
243478
244287
  runHooks("PostToolUse", hooks, tool.name, tool.input, cwd);
243479
244288
  const toolFilePath = tool.input["path"] ?? tool.input["file_path"] ?? null;
243480
- appendAuditLog(tool.name, toolFilePath);
244289
+ const command = tool.input["command"];
244290
+ const escalation = command ? detectCommandEscalation(command) : null;
244291
+ appendAuditLog(tool.name, toolFilePath, {
244292
+ command: command ?? void 0,
244293
+ escalation: escalation?.escalation
244294
+ });
243481
244295
  if ((tool.name === "write_file" || tool.name === "edit_file") && toolFilePath) {
243482
244296
  checkTypesAfterEdit(toolFilePath, cwd);
243483
244297
  }
@@ -243821,6 +244635,7 @@ ${mcpSummary}
243821
244635
  if (estimated > 5e4) {
243822
244636
  console.log(`${YELLOW} \u26A0 Context ~${Math.round(estimated / 1e3)}K tokens. Consider /compact to reduce.${RESET}`);
243823
244637
  }
244638
+ turnRollbackBuffer.clear();
243824
244639
  let continueLoop = true;
243825
244640
  let retryCount = 0;
243826
244641
  const maxRetries = 3;
@@ -243831,6 +244646,7 @@ ${mcpSummary}
243831
244646
  const MAX_DUPLICATE_STREAK = 3;
243832
244647
  const toolNameCounts = /* @__PURE__ */ new Map();
243833
244648
  const turnStartTime = Date.now();
244649
+ const userTurnStart = Date.now();
243834
244650
  const TURN_TIMEOUT_MS = 5 * 60 * 1e3;
243835
244651
  while (continueLoop) {
243836
244652
  if (Date.now() - turnStartTime > TURN_TIMEOUT_MS) {
@@ -243849,10 +244665,11 @@ ${mcpSummary}
243849
244665
  }
243850
244666
  const spinner = createSpinner("Thinking...");
243851
244667
  try {
244668
+ const modelDelay = getModelDelay(model);
243852
244669
  const now = Date.now();
243853
244670
  const elapsed = now - lastApiCallTime;
243854
- if (elapsed < MIN_API_DELAY_MS && lastApiCallTime > 0) {
243855
- await new Promise((r) => setTimeout(r, MIN_API_DELAY_MS - elapsed));
244671
+ if (elapsed < modelDelay && lastApiCallTime > 0) {
244672
+ await new Promise((r) => setTimeout(r, modelDelay - elapsed));
243856
244673
  }
243857
244674
  lastApiCallTime = Date.now();
243858
244675
  const abortCtrl = new AbortController();
@@ -243926,16 +244743,20 @@ ${headers.join("\n")}${RESET}
243926
244743
  }
243927
244744
  if (res.status === 429 && retryCount < maxRetries) {
243928
244745
  retryCount++;
243929
- const waitSec = retryCount * 3;
244746
+ const baseDelay = 3e3;
244747
+ const delay = Math.min(baseDelay * Math.pow(2, retryCount - 1) + Math.random() * 1e3, 3e4);
244748
+ const waitSec = (delay / 1e3).toFixed(1);
243930
244749
  console.log(`${YELLOW} Rate limited. Retrying in ${waitSec}s... (${retryCount}/${maxRetries})${RESET}`);
243931
- await new Promise((r) => setTimeout(r, waitSec * 1e3));
244750
+ await new Promise((r) => setTimeout(r, delay));
243932
244751
  continue;
243933
244752
  }
243934
244753
  if (res.status >= 500 && retryCount < maxRetries) {
243935
244754
  retryCount++;
243936
- const waitSec = retryCount * 2;
244755
+ const baseDelay = 2e3;
244756
+ const delay = Math.min(baseDelay * Math.pow(2, retryCount - 1) + Math.random() * 1e3, 3e4);
244757
+ const waitSec = (delay / 1e3).toFixed(1);
243937
244758
  console.log(`${YELLOW} Server error (${res.status}). Retrying in ${waitSec}s... (${retryCount}/${maxRetries})${RESET}`);
243938
- await new Promise((r) => setTimeout(r, waitSec * 1e3));
244759
+ await new Promise((r) => setTimeout(r, delay));
243939
244760
  continue;
243940
244761
  }
243941
244762
  printError(errMsg);
@@ -243946,14 +244767,23 @@ ${headers.join("\n")}${RESET}
243946
244767
  retryCount = 0;
243947
244768
  if (isSSEResponse(res)) {
243948
244769
  let firstText = true;
244770
+ let runningTokens = { input_tokens: 0, output_tokens: 0 };
244771
+ const onTokenUpdate = (tokens) => {
244772
+ runningTokens = tokens;
244773
+ };
243949
244774
  const streamResult = await parseSSEStream(res, (text) => {
243950
244775
  if (firstText) {
243951
244776
  console.log();
243952
244777
  firstText = false;
243953
244778
  }
243954
244779
  process.stdout.write(text);
243955
- });
244780
+ }, onTokenUpdate);
243956
244781
  if (!firstText) {
244782
+ if (runningTokens.input_tokens > 0 || runningTokens.output_tokens > 0) {
244783
+ const total = runningTokens.input_tokens + runningTokens.output_tokens;
244784
+ process.stdout.write(`
244785
+ ${DIM} [tokens: ${total.toLocaleString()}]${RESET}`);
244786
+ }
243957
244787
  console.log();
243958
244788
  }
243959
244789
  sessionStats = updateStats(
@@ -243966,6 +244796,11 @@ ${headers.join("\n")}${RESET}
243966
244796
  const turnCost = estimateCost({ ...sessionStats, inputTokens: u.input_tokens, outputTokens: u.output_tokens, requests: 1, providerCounts: {} });
243967
244797
  console.log(`${DIM} tokens: ${u.input_tokens} in + ${u.output_tokens} out = ${u.input_tokens + u.output_tokens} \xB7 ~$${turnCost.toFixed(4)}${RESET}`);
243968
244798
  }
244799
+ if (config.maxCostPerSession && config.maxCostPerSession > 0) {
244800
+ if (isBudgetExceeded(sessionStats, config.maxCostPerSession)) {
244801
+ printBudgetWarning(sessionStats, config.maxCostPerSession);
244802
+ }
244803
+ }
243969
244804
  const contentBlocksForHistory = [];
243970
244805
  const toolBlocks = [];
243971
244806
  for (const block of streamResult.contentBlocks) {
@@ -244012,6 +244847,9 @@ ${headers.join("\n")}${RESET}
244012
244847
  const toolResults = await executeToolsParallel(toolBlocks, cwd, config, hooks);
244013
244848
  messages.push({ role: "user", content: toolResults });
244014
244849
  } else {
244850
+ if (Date.now() - userTurnStart > 1e4) {
244851
+ process.stdout.write("\x07");
244852
+ }
244015
244853
  const meta = streamResult.routingMetadata;
244016
244854
  if (meta && streamResult.usage) {
244017
244855
  console.log(`${DIM} - ${meta.provider} \xB7 L${meta.taskComplexity} \xB7 ${meta.totalLatencyMs?.toFixed(0) ?? "?"}ms \xB7 ${streamResult.usage.input_tokens}+${streamResult.usage.output_tokens} tokens${RESET}`);
@@ -244180,7 +245018,7 @@ var GRAY4 = "\x1B[90m";
244180
245018
  var BOLD2 = "\x1B[1m";
244181
245019
  var DIM2 = "\x1B[2m";
244182
245020
  var RESET2 = "\x1B[0m";
244183
- var YELLOW3 = "\x1B[33m";
245021
+ var YELLOW2 = "\x1B[33m";
244184
245022
  var WHITE2 = "\x1B[37m";
244185
245023
  var VERSION = "0.2.0";
244186
245024
  var CONFIG_DIR = path18.join(os9.homedir(), ".oroute");
@@ -244250,6 +245088,21 @@ var LOGO = `${GREEN2}${BOLD2}
244250
245088
  | |_| | | _ < (_) | |_| | || __/
244251
245089
  \\___/ |_| \\_\\___/ \\__,_|\\__\\___|${RESET2}
244252
245090
  `;
245091
+ function checkApiKeyAge(config) {
245092
+ if (!config.apiKeyCreatedAt) return;
245093
+ try {
245094
+ const createdAt = new Date(config.apiKeyCreatedAt);
245095
+ const now = /* @__PURE__ */ new Date();
245096
+ const ageMs = now.getTime() - createdAt.getTime();
245097
+ const ageDays = Math.floor(ageMs / (1e3 * 60 * 60 * 24));
245098
+ if (ageDays > 90) {
245099
+ console.log(`${YELLOW2} WARNING: Your API key is ${ageDays} days old. Consider rotating it for security.${RESET2}`);
245100
+ console.log(`${GRAY4} Rotate at: https://oroute.itshin.com/api-keys${RESET2}`);
245101
+ console.log();
245102
+ }
245103
+ } catch {
245104
+ }
245105
+ }
244253
245106
  function loadConfig() {
244254
245107
  try {
244255
245108
  if (fs19.existsSync(CONFIG_FILE)) {
@@ -244259,6 +245112,22 @@ function loadConfig() {
244259
245112
  }
244260
245113
  return {};
244261
245114
  }
245115
+ function loadProjectConfig() {
245116
+ try {
245117
+ const projectConfigPath = path18.join(process.cwd(), ".oroute", "config.json");
245118
+ if (fs19.existsSync(projectConfigPath)) {
245119
+ const raw = JSON.parse(fs19.readFileSync(projectConfigPath, "utf-8"));
245120
+ const result = {};
245121
+ if (raw.model) result.model = raw.model;
245122
+ if (raw.apiUrl) result.apiUrl = raw.apiUrl;
245123
+ if (raw.maxCost !== void 0) result.maxCost = Number(raw.maxCost);
245124
+ if (Array.isArray(raw.toolBlacklist)) result.toolBlacklist = raw.toolBlacklist;
245125
+ return result;
245126
+ }
245127
+ } catch {
245128
+ }
245129
+ return {};
245130
+ }
244262
245131
  function saveConfig(config) {
244263
245132
  if (!fs19.existsSync(CONFIG_DIR)) {
244264
245133
  fs19.mkdirSync(CONFIG_DIR, { recursive: true });
@@ -244294,6 +245163,7 @@ function parseArgs(args) {
244294
245163
  let debug = false;
244295
245164
  let skipConfirmations2 = false;
244296
245165
  let planMode = false;
245166
+ let profile = false;
244297
245167
  for (let i = 0; i < args.length; i++) {
244298
245168
  const arg = args[i];
244299
245169
  if (arg === "--debug") {
@@ -244308,6 +245178,10 @@ function parseArgs(args) {
244308
245178
  planMode = true;
244309
245179
  continue;
244310
245180
  }
245181
+ if (arg === "--profile") {
245182
+ profile = true;
245183
+ continue;
245184
+ }
244311
245185
  if (arg === "-p" && args[i + 1]) {
244312
245186
  prompt = args[++i];
244313
245187
  continue;
@@ -244319,7 +245193,7 @@ function parseArgs(args) {
244319
245193
  if (arg.startsWith("-")) continue;
244320
245194
  targetPath = arg;
244321
245195
  }
244322
- return { command, path: targetPath, prompt, debug, skipConfirmations: skipConfirmations2, planMode };
245196
+ return { command, path: targetPath, prompt, debug, skipConfirmations: skipConfirmations2, planMode, profile };
244323
245197
  }
244324
245198
  async function promptInput(prompt) {
244325
245199
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
@@ -244333,7 +245207,7 @@ async function promptInput(prompt) {
244333
245207
  async function loginWithApiKey(config) {
244334
245208
  const key = await promptInput(`${GREEN2}\u203A${RESET2} Enter your O'Route API Key (or-...): `);
244335
245209
  if (!key.startsWith("or-")) {
244336
- console.log(`${YELLOW3} Invalid key format. O'Route keys start with "or-"${RESET2}`);
245210
+ console.log(`${YELLOW2} Invalid key format. O'Route keys start with "or-"${RESET2}`);
244337
245211
  return;
244338
245212
  }
244339
245213
  const apiUrl = config.apiUrl ?? DEFAULT_API_URL;
@@ -244344,19 +245218,21 @@ async function loginWithApiKey(config) {
244344
245218
  signal: AbortSignal.timeout(5e3)
244345
245219
  });
244346
245220
  config.apiKey = key;
245221
+ config.apiKeyCreatedAt = (/* @__PURE__ */ new Date()).toISOString();
244347
245222
  saveConfig(config);
244348
245223
  if (res.ok) {
244349
245224
  console.log(`${GREEN2} \u2713 API Key verified and saved!${RESET2}`);
244350
245225
  } else {
244351
- console.log(`${YELLOW3} Key saved (server returned ${res.status}).${RESET2}`);
245226
+ console.log(`${YELLOW2} Key saved (server returned ${res.status}).${RESET2}`);
244352
245227
  }
244353
245228
  console.log();
244354
245229
  await chat(config);
244355
245230
  return;
244356
245231
  } catch {
244357
245232
  config.apiKey = key;
245233
+ config.apiKeyCreatedAt = (/* @__PURE__ */ new Date()).toISOString();
244358
245234
  saveConfig(config);
244359
- console.log(`${YELLOW3} Saved (server offline). Starting chat...${RESET2}`);
245235
+ console.log(`${YELLOW2} Saved (server offline). Starting chat...${RESET2}`);
244360
245236
  console.log();
244361
245237
  await chat(config);
244362
245238
  }
@@ -244390,6 +245266,7 @@ async function loginWithGoogle(config) {
244390
245266
  const pollData = await pollRes.json();
244391
245267
  if (pollData.status === "approved" && pollData.apiKey) {
244392
245268
  config.apiKey = pollData.apiKey;
245269
+ config.apiKeyCreatedAt = (/* @__PURE__ */ new Date()).toISOString();
244393
245270
  saveConfig(config);
244394
245271
  console.log(`
244395
245272
  ${GREEN2} \u2713 Logged in!${RESET2} ${GRAY4}(${pollData.email})${RESET2}`);
@@ -244399,20 +245276,20 @@ ${GREEN2} \u2713 Logged in!${RESET2} ${GRAY4}(${pollData.email})${RESET2}`);
244399
245276
  return;
244400
245277
  }
244401
245278
  if (pollData.status === "expired") {
244402
- console.log(`${YELLOW3} \uC778\uC99D \uCF54\uB4DC\uAC00 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.${RESET2}`);
245279
+ console.log(`${YELLOW2} \uC778\uC99D \uCF54\uB4DC\uAC00 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.${RESET2}`);
244403
245280
  return;
244404
245281
  }
244405
245282
  process.stdout.write(`\r${GRAY4} \uB300\uAE30 \uC911${"\xB7".repeat(i % 3 + 1).padEnd(3)}${RESET2}`);
244406
245283
  }
244407
245284
  console.log(`
244408
- ${YELLOW3} \uC2DC\uAC04 \uCD08\uACFC. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.${RESET2}`);
245285
+ ${YELLOW2} \uC2DC\uAC04 \uCD08\uACFC. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.${RESET2}`);
244409
245286
  } catch (err) {
244410
- console.log(`${YELLOW3} \uC11C\uBC84\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. API Key\uB85C \uB85C\uADF8\uC778\uD558\uC138\uC694 (\uC635\uC158 1).${RESET2}`);
245287
+ console.log(`${YELLOW2} \uC11C\uBC84\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. API Key\uB85C \uB85C\uADF8\uC778\uD558\uC138\uC694 (\uC635\uC158 1).${RESET2}`);
244411
245288
  }
244412
245289
  }
244413
245290
  async function chat(config) {
244414
245291
  if (!config.apiKey) {
244415
- console.log(`${YELLOW3} No API Key configured. Run option 1 first.${RESET2}`);
245292
+ console.log(`${YELLOW2} No API Key configured. Run option 1 first.${RESET2}`);
244416
245293
  return;
244417
245294
  }
244418
245295
  const apiUrl = config.apiUrl ?? DEFAULT_API_URL;
@@ -244444,7 +245321,7 @@ async function chat(config) {
244444
245321
  if (!res.ok) {
244445
245322
  const errBody = await res.json().catch(() => ({ error: { message: `HTTP ${res.status}` } }));
244446
245323
  const errMsg = typeof errBody.error === "string" ? errBody.error : errBody.error?.message ?? `HTTP ${res.status}`;
244447
- console.log(`${YELLOW3} Error: ${errMsg}${RESET2}`);
245324
+ console.log(`${YELLOW2} Error: ${errMsg}${RESET2}`);
244448
245325
  messages.pop();
244449
245326
  continue;
244450
245327
  }
@@ -244458,7 +245335,7 @@ async function chat(config) {
244458
245335
  console.log();
244459
245336
  messages.push({ role: "assistant", content: text });
244460
245337
  } catch (err) {
244461
- console.log(`${YELLOW3} Request failed: ${err instanceof Error ? err.message : "unknown"}${RESET2}`);
245338
+ console.log(`${YELLOW2} Request failed: ${err instanceof Error ? err.message : "unknown"}${RESET2}`);
244462
245339
  messages.pop();
244463
245340
  }
244464
245341
  }
@@ -244474,7 +245351,7 @@ async function checkStatus(config) {
244474
245351
  console.log(`${GRAY4} Key: ${config.apiKey ? config.apiKey.slice(0, 11) + "..." : "not set"}${RESET2}`);
244475
245352
  console.log(`${GRAY4} Model: ${config.model ?? "auto"}${RESET2}`);
244476
245353
  } catch {
244477
- console.log(`${YELLOW3} \u2717 Server unreachable at ${apiUrl}${RESET2}`);
245354
+ console.log(`${YELLOW2} \u2717 Server unreachable at ${apiUrl}${RESET2}`);
244478
245355
  }
244479
245356
  }
244480
245357
  async function settings(config) {
@@ -244509,32 +245386,52 @@ async function settings(config) {
244509
245386
  }
244510
245387
  }
244511
245388
  async function main() {
245389
+ const startupStart = performance.now();
244512
245390
  const rawArgs = process.argv.slice(2);
245391
+ const parseStart = performance.now();
244513
245392
  const config = loadConfig();
244514
245393
  const parsed = parseArgs(rawArgs);
245394
+ const configLoadMs = performance.now() - parseStart;
245395
+ checkApiKeyAge(config);
245396
+ const updateStart = performance.now();
244515
245397
  checkForUpdates(VERSION);
245398
+ const updateMs = performance.now() - updateStart;
244516
245399
  if (parsed.debug) {
244517
245400
  console.log(`${GRAY4} Debug mode: config=${JSON.stringify(config)}${RESET2}`);
244518
245401
  }
244519
245402
  if (parsed.path) {
244520
245403
  const resolved = path18.resolve(process.cwd(), parsed.path);
244521
245404
  if (!fs19.existsSync(resolved)) {
244522
- console.log(`${YELLOW3} \uB514\uB809\uD1A0\uB9AC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${resolved}${RESET2}`);
245405
+ console.log(`${YELLOW2} \uB514\uB809\uD1A0\uB9AC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${resolved}${RESET2}`);
244523
245406
  process.exit(1);
244524
245407
  }
244525
245408
  const stat = fs19.statSync(resolved);
244526
245409
  if (!stat.isDirectory()) {
244527
- console.log(`${YELLOW3} \uB514\uB809\uD1A0\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4: ${resolved}${RESET2}`);
245410
+ console.log(`${YELLOW2} \uB514\uB809\uD1A0\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4: ${resolved}${RESET2}`);
244528
245411
  process.exit(1);
244529
245412
  }
244530
245413
  process.chdir(resolved);
244531
245414
  }
245415
+ const projectConfig = loadProjectConfig();
245416
+ const mergedConfig = { ...config, ...projectConfig };
244532
245417
  const agentConfig = {
244533
- ...config,
245418
+ ...mergedConfig,
244534
245419
  skipConfirmations: parsed.skipConfirmations,
244535
245420
  planMode: parsed.planMode,
244536
- debug: parsed.debug
245421
+ debug: parsed.debug,
245422
+ maxCostPerSession: mergedConfig.maxCost,
245423
+ toolBlacklist: mergedConfig.toolBlacklist
244537
245424
  };
245425
+ if (parsed.profile) {
245426
+ const totalMs = performance.now() - startupStart;
245427
+ console.log(`${BOLD2} Startup Profile${RESET2}`);
245428
+ console.log(`${GRAY4} ${"\u2500".repeat(40)}${RESET2}`);
245429
+ console.log(`${WHITE2} Config load: ${configLoadMs.toFixed(1)}ms${RESET2}`);
245430
+ console.log(`${WHITE2} Update check: ${updateMs.toFixed(1)}ms${RESET2}`);
245431
+ console.log(`${WHITE2} Total startup: ${totalMs.toFixed(1)}ms${RESET2}`);
245432
+ console.log(`${GRAY4} (context, MCP, history are loaded in agent loop)${RESET2}`);
245433
+ console.log();
245434
+ }
244538
245435
  if (parsed.command === "login") {
244539
245436
  printWelcome();
244540
245437
  await loginWithApiKey(config);
@@ -244550,7 +245447,7 @@ async function main() {
244550
245447
  }
244551
245448
  if (parsed.prompt) {
244552
245449
  if (!config.apiKey) {
244553
- console.log(`${YELLOW3}No API Key. Run: oroute login${RESET2}`);
245450
+ console.log(`${YELLOW2}No API Key. Run: oroute login${RESET2}`);
244554
245451
  process.exit(1);
244555
245452
  }
244556
245453
  const apiUrl = config.apiUrl ?? DEFAULT_API_URL;
@@ -244565,7 +245462,7 @@ async function main() {
244565
245462
  console.log(data.content[0]?.text ?? "");
244566
245463
  } catch (err) {
244567
245464
  const msg = err instanceof Error ? err.message : String(err);
244568
- console.log(`${YELLOW3} Error: ${msg}${RESET2}`);
245465
+ console.log(`${YELLOW2} Error: ${msg}${RESET2}`);
244569
245466
  }
244570
245467
  return;
244571
245468
  }
@@ -244599,14 +245496,14 @@ async function main() {
244599
245496
  console.log(`${GRAY4} Bye!${RESET2}`);
244600
245497
  process.exit(0);
244601
245498
  default:
244602
- console.log(`${YELLOW3} Unknown option: ${choice}${RESET2}`);
245499
+ console.log(`${YELLOW2} Unknown option: ${choice}${RESET2}`);
244603
245500
  }
244604
245501
  console.log();
244605
245502
  }
244606
245503
  }
244607
245504
  main().catch((err) => {
244608
245505
  const msg = err instanceof Error ? err.message : String(err);
244609
- console.error(`${YELLOW3} Error: ${msg}${RESET2}`);
245506
+ console.error(`${YELLOW2} Error: ${msg}${RESET2}`);
244610
245507
  process.exit(1);
244611
245508
  });
244612
245509
  //# sourceMappingURL=oroute.cjs.map