@todoforai/cli 0.1.10 → 0.1.11

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/todoai.js +1533 -502
  2. package/package.json +1 -1
package/dist/todoai.js CHANGED
@@ -2024,11 +2024,11 @@ var require_core = __commonJS((exports, module) => {
2024
2024
  cmode.illegalRe = langRe(mode.illegal);
2025
2025
  if (!mode.contains)
2026
2026
  mode.contains = [];
2027
- mode.contains = [].concat(...mode.contains.map(function(c) {
2028
- return expandOrCloneMode(c === "self" ? mode : c);
2027
+ mode.contains = [].concat(...mode.contains.map(function(c2) {
2028
+ return expandOrCloneMode(c2 === "self" ? mode : c2);
2029
2029
  }));
2030
- mode.contains.forEach(function(c) {
2031
- compileMode(c, cmode);
2030
+ mode.contains.forEach(function(c2) {
2031
+ compileMode(c2, cmode);
2032
2032
  });
2033
2033
  if (mode.starts) {
2034
2034
  compileMode(mode.starts, parent);
@@ -2685,8 +2685,8 @@ https://github.com/highlightjs/highlight.js/issues/2277`);
2685
2685
  return;
2686
2686
  initHighlighting.called = true;
2687
2687
  deprecated("10.6.0", "initHighlighting() is deprecated. Use highlightAll() instead.");
2688
- const blocks = document.querySelectorAll("pre code");
2689
- blocks.forEach(highlightElement);
2688
+ const blocks3 = document.querySelectorAll("pre code");
2689
+ blocks3.forEach(highlightElement);
2690
2690
  };
2691
2691
  function initHighlightingOnLoad() {
2692
2692
  deprecated("10.6.0", "initHighlightingOnLoad() is deprecated. Use highlightAll() instead.");
@@ -2698,8 +2698,8 @@ https://github.com/highlightjs/highlight.js/issues/2277`);
2698
2698
  wantsHighlight = true;
2699
2699
  return;
2700
2700
  }
2701
- const blocks = document.querySelectorAll("pre code");
2702
- blocks.forEach(highlightElement);
2701
+ const blocks3 = document.querySelectorAll("pre code");
2702
+ blocks3.forEach(highlightElement);
2703
2703
  }
2704
2704
  function boot() {
2705
2705
  if (wantsHighlight)
@@ -6049,7 +6049,7 @@ var require_c = __commonJS((exports, module) => {
6049
6049
  const joined = args.map((x) => source(x)).join("");
6050
6050
  return joined;
6051
6051
  }
6052
- function c(hljs) {
6052
+ function c2(hljs) {
6053
6053
  const C_LINE_COMMENT_MODE = hljs.COMMENT("//", "$", {
6054
6054
  contains: [
6055
6055
  {
@@ -6266,7 +6266,7 @@ var require_c = __commonJS((exports, module) => {
6266
6266
  }
6267
6267
  };
6268
6268
  }
6269
- module.exports = c;
6269
+ module.exports = c2;
6270
6270
  });
6271
6271
 
6272
6272
  // node_modules/highlight.js/lib/languages/cal.js
@@ -15883,10 +15883,10 @@ var require_less = __commonJS((exports, module) => {
15883
15883
  const INTERP_IDENT_RE = "(" + IDENT_RE + "|@\\{" + IDENT_RE + "\\})";
15884
15884
  const RULES = [];
15885
15885
  const VALUE_MODES = [];
15886
- const STRING_MODE = function(c) {
15886
+ const STRING_MODE = function(c2) {
15887
15887
  return {
15888
15888
  className: "string",
15889
- begin: "~?" + c + ".*?" + c
15889
+ begin: "~?" + c2 + ".*?" + c2
15890
15890
  };
15891
15891
  };
15892
15892
  const IDENT_MODE = function(name, begin, relevance) {
@@ -41132,10 +41132,10 @@ var require_conversions = __commonJS((exports, module) => {
41132
41132
  if (convert[model].labels.length !== convert[model].channels) {
41133
41133
  throw new Error("channel and label counts mismatch: " + model);
41134
41134
  }
41135
- const { channels, labels } = convert[model];
41135
+ const { channels: channels2, labels } = convert[model];
41136
41136
  delete convert[model].channels;
41137
41137
  delete convert[model].labels;
41138
- Object.defineProperty(convert[model], "channels", { value: channels });
41138
+ Object.defineProperty(convert[model], "channels", { value: channels2 });
41139
41139
  Object.defineProperty(convert[model], "labels", { value: labels });
41140
41140
  }
41141
41141
  convert.rgb.hsl = function(rgb) {
@@ -41181,8 +41181,8 @@ var require_conversions = __commonJS((exports, module) => {
41181
41181
  const b = rgb[2] / 255;
41182
41182
  const v = Math.max(r, g, b);
41183
41183
  const diff = v - Math.min(r, g, b);
41184
- const diffc = function(c) {
41185
- return (v - c) / 6 / diff + 1 / 2;
41184
+ const diffc = function(c2) {
41185
+ return (v - c2) / 6 / diff + 1 / 2;
41186
41186
  };
41187
41187
  if (diff === 0) {
41188
41188
  h = 0;
@@ -41225,10 +41225,10 @@ var require_conversions = __commonJS((exports, module) => {
41225
41225
  const g = rgb[1] / 255;
41226
41226
  const b = rgb[2] / 255;
41227
41227
  const k = Math.min(1 - r, 1 - g, 1 - b);
41228
- const c = (1 - r - k) / (1 - k) || 0;
41228
+ const c2 = (1 - r - k) / (1 - k) || 0;
41229
41229
  const m = (1 - g - k) / (1 - k) || 0;
41230
41230
  const y = (1 - b - k) / (1 - k) || 0;
41231
- return [c * 100, m * 100, y * 100, k * 100];
41231
+ return [c2 * 100, m * 100, y * 100, k * 100];
41232
41232
  };
41233
41233
  function comparativeDistance(x, y) {
41234
41234
  return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
@@ -41430,11 +41430,11 @@ var require_conversions = __commonJS((exports, module) => {
41430
41430
  return [r * 255, g * 255, b * 255];
41431
41431
  };
41432
41432
  convert.cmyk.rgb = function(cmyk) {
41433
- const c = cmyk[0] / 100;
41433
+ const c2 = cmyk[0] / 100;
41434
41434
  const m = cmyk[1] / 100;
41435
41435
  const y = cmyk[2] / 100;
41436
41436
  const k = cmyk[3] / 100;
41437
- const r = 1 - Math.min(1, c * (1 - k) + k);
41437
+ const r = 1 - Math.min(1, c2 * (1 - k) + k);
41438
41438
  const g = 1 - Math.min(1, m * (1 - k) + k);
41439
41439
  const b = 1 - Math.min(1, y * (1 - k) + k);
41440
41440
  return [r * 255, g * 255, b * 255];
@@ -41503,16 +41503,16 @@ var require_conversions = __commonJS((exports, module) => {
41503
41503
  if (h < 0) {
41504
41504
  h += 360;
41505
41505
  }
41506
- const c = Math.sqrt(a * a + b * b);
41507
- return [l, c, h];
41506
+ const c2 = Math.sqrt(a * a + b * b);
41507
+ return [l, c2, h];
41508
41508
  };
41509
41509
  convert.lch.lab = function(lch) {
41510
41510
  const l = lch[0];
41511
- const c = lch[1];
41511
+ const c2 = lch[1];
41512
41512
  const h = lch[2];
41513
41513
  const hr = h / 360 * 2 * Math.PI;
41514
- const a = c * Math.cos(hr);
41515
- const b = c * Math.sin(hr);
41514
+ const a = c2 * Math.cos(hr);
41515
+ const b = c2 * Math.sin(hr);
41516
41516
  return [l, a, b];
41517
41517
  };
41518
41518
  convert.rgb.ansi16 = function(args, saturation = null) {
@@ -41564,8 +41564,8 @@ var require_conversions = __commonJS((exports, module) => {
41564
41564
  };
41565
41565
  convert.ansi256.rgb = function(args) {
41566
41566
  if (args >= 232) {
41567
- const c = (args - 232) * 10 + 8;
41568
- return [c, c, c];
41567
+ const c2 = (args - 232) * 10 + 8;
41568
+ return [c2, c2, c2];
41569
41569
  }
41570
41570
  args -= 16;
41571
41571
  let rem;
@@ -41626,28 +41626,28 @@ var require_conversions = __commonJS((exports, module) => {
41626
41626
  convert.hsl.hcg = function(hsl) {
41627
41627
  const s = hsl[1] / 100;
41628
41628
  const l = hsl[2] / 100;
41629
- const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
41629
+ const c2 = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
41630
41630
  let f = 0;
41631
- if (c < 1) {
41632
- f = (l - 0.5 * c) / (1 - c);
41631
+ if (c2 < 1) {
41632
+ f = (l - 0.5 * c2) / (1 - c2);
41633
41633
  }
41634
- return [hsl[0], c * 100, f * 100];
41634
+ return [hsl[0], c2 * 100, f * 100];
41635
41635
  };
41636
41636
  convert.hsv.hcg = function(hsv) {
41637
41637
  const s = hsv[1] / 100;
41638
41638
  const v = hsv[2] / 100;
41639
- const c = s * v;
41639
+ const c2 = s * v;
41640
41640
  let f = 0;
41641
- if (c < 1) {
41642
- f = (v - c) / (1 - c);
41641
+ if (c2 < 1) {
41642
+ f = (v - c2) / (1 - c2);
41643
41643
  }
41644
- return [hsv[0], c * 100, f * 100];
41644
+ return [hsv[0], c2 * 100, f * 100];
41645
41645
  };
41646
41646
  convert.hcg.rgb = function(hcg) {
41647
41647
  const h = hcg[0] / 360;
41648
- const c = hcg[1] / 100;
41648
+ const c2 = hcg[1] / 100;
41649
41649
  const g = hcg[2] / 100;
41650
- if (c === 0) {
41650
+ if (c2 === 0) {
41651
41651
  return [g * 255, g * 255, g * 255];
41652
41652
  }
41653
41653
  const pure = [0, 0, 0];
@@ -41686,51 +41686,51 @@ var require_conversions = __commonJS((exports, module) => {
41686
41686
  pure[1] = 0;
41687
41687
  pure[2] = w;
41688
41688
  }
41689
- mg = (1 - c) * g;
41689
+ mg = (1 - c2) * g;
41690
41690
  return [
41691
- (c * pure[0] + mg) * 255,
41692
- (c * pure[1] + mg) * 255,
41693
- (c * pure[2] + mg) * 255
41691
+ (c2 * pure[0] + mg) * 255,
41692
+ (c2 * pure[1] + mg) * 255,
41693
+ (c2 * pure[2] + mg) * 255
41694
41694
  ];
41695
41695
  };
41696
41696
  convert.hcg.hsv = function(hcg) {
41697
- const c = hcg[1] / 100;
41697
+ const c2 = hcg[1] / 100;
41698
41698
  const g = hcg[2] / 100;
41699
- const v = c + g * (1 - c);
41699
+ const v = c2 + g * (1 - c2);
41700
41700
  let f = 0;
41701
41701
  if (v > 0) {
41702
- f = c / v;
41702
+ f = c2 / v;
41703
41703
  }
41704
41704
  return [hcg[0], f * 100, v * 100];
41705
41705
  };
41706
41706
  convert.hcg.hsl = function(hcg) {
41707
- const c = hcg[1] / 100;
41707
+ const c2 = hcg[1] / 100;
41708
41708
  const g = hcg[2] / 100;
41709
- const l = g * (1 - c) + 0.5 * c;
41709
+ const l = g * (1 - c2) + 0.5 * c2;
41710
41710
  let s = 0;
41711
41711
  if (l > 0 && l < 0.5) {
41712
- s = c / (2 * l);
41712
+ s = c2 / (2 * l);
41713
41713
  } else if (l >= 0.5 && l < 1) {
41714
- s = c / (2 * (1 - l));
41714
+ s = c2 / (2 * (1 - l));
41715
41715
  }
41716
41716
  return [hcg[0], s * 100, l * 100];
41717
41717
  };
41718
41718
  convert.hcg.hwb = function(hcg) {
41719
- const c = hcg[1] / 100;
41719
+ const c2 = hcg[1] / 100;
41720
41720
  const g = hcg[2] / 100;
41721
- const v = c + g * (1 - c);
41722
- return [hcg[0], (v - c) * 100, (1 - v) * 100];
41721
+ const v = c2 + g * (1 - c2);
41722
+ return [hcg[0], (v - c2) * 100, (1 - v) * 100];
41723
41723
  };
41724
41724
  convert.hwb.hcg = function(hwb) {
41725
41725
  const w = hwb[1] / 100;
41726
41726
  const b = hwb[2] / 100;
41727
41727
  const v = 1 - b;
41728
- const c = v - w;
41728
+ const c2 = v - w;
41729
41729
  let g = 0;
41730
- if (c < 1) {
41731
- g = (v - c) / (1 - c);
41730
+ if (c2 < 1) {
41731
+ g = (v - c2) / (1 - c2);
41732
41732
  }
41733
- return [hwb[0], c * 100, g * 100];
41733
+ return [hwb[0], c2 * 100, g * 100];
41734
41734
  };
41735
41735
  convert.apple.rgb = function(apple) {
41736
41736
  return [apple[0] / 65535 * 255, apple[1] / 65535 * 255, apple[2] / 65535 * 255];
@@ -42194,16 +42194,16 @@ var require_templates = __commonJS((exports, module) => {
42194
42194
  ["e", "\x1B"],
42195
42195
  ["a", "\x07"]
42196
42196
  ]);
42197
- function unescape(c) {
42198
- const u = c[0] === "u";
42199
- const bracket = c[1] === "{";
42200
- if (u && !bracket && c.length === 5 || c[0] === "x" && c.length === 3) {
42201
- return String.fromCharCode(parseInt(c.slice(1), 16));
42197
+ function unescape(c2) {
42198
+ const u = c2[0] === "u";
42199
+ const bracket = c2[1] === "{";
42200
+ if (u && !bracket && c2.length === 5 || c2[0] === "x" && c2.length === 3) {
42201
+ return String.fromCharCode(parseInt(c2.slice(1), 16));
42202
42202
  }
42203
42203
  if (u && bracket) {
42204
- return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
42204
+ return String.fromCodePoint(parseInt(c2.slice(2, -1), 16));
42205
42205
  }
42206
- return ESCAPES.get(c) || c;
42206
+ return ESCAPES.get(c2) || c2;
42207
42207
  }
42208
42208
  function parseArguments(name, arguments_) {
42209
42209
  const results = [];
@@ -42798,7 +42798,10 @@ class ApiClient {
42798
42798
  return this.request("GET", `/api/v1/todos/${todoId}`);
42799
42799
  }
42800
42800
  updateTodoStatus(todoId, status) {
42801
- return this.request("PUT", `/api/v1/todos/${todoId}`, { status });
42801
+ return this.request("PATCH", `/api/v1/todos/${todoId}/status`, { status });
42802
+ }
42803
+ deleteTodo(todoId) {
42804
+ return this.request("DELETE", `/api/v1/todos/${todoId}`);
42802
42805
  }
42803
42806
  listAgentSettings(filters) {
42804
42807
  const params = new URLSearchParams;
@@ -43134,7 +43137,783 @@ var package_default = {
43134
43137
  typescript: "^5.7.0"
43135
43138
  }
43136
43139
  };
43140
+ // ../packages/shared-fbe/src/enums.ts
43141
+ var TodoStatus;
43142
+ ((TodoStatus2) => {
43143
+ TodoStatus2["TODO"] = "TODO";
43144
+ TodoStatus2["SCHEDULED"] = "SCHEDULED";
43145
+ TodoStatus2["PAUSED"] = "PAUSED";
43146
+ TodoStatus2["POSTPONED"] = "POSTPONED";
43147
+ TodoStatus2["REVIEW_REQUESTED"] = "REVIEW_REQUESTED";
43148
+ TodoStatus2["RUNNING"] = "RUNNING";
43149
+ TodoStatus2["COMPACTING"] = "COMPACTING";
43150
+ TodoStatus2["STOPPING"] = "STOPPING";
43151
+ TodoStatus2["READY"] = "READY";
43152
+ TodoStatus2["READY_CHECKED"] = "READY_CHECKED";
43153
+ TodoStatus2["DONE"] = "DONE";
43154
+ TodoStatus2["CANCELLED"] = "CANCELLED";
43155
+ TodoStatus2["CANCELLED_CHECKED"] = "CANCELLED_CHECKED";
43156
+ TodoStatus2["ERROR"] = "ERROR";
43157
+ TodoStatus2["ERROR_CHECKED"] = "ERROR_CHECKED";
43158
+ TodoStatus2["ARCHIVED"] = "ARCHIVED";
43159
+ TodoStatus2["DELETED"] = "DELETED";
43160
+ })(TodoStatus ||= {});
43161
+ // ../packages/shared-fbe/src/mimetypes.json
43162
+ var mimetypes_default = {
43163
+ conversionProfiles: {
43164
+ to_jpeg_90: { toMime: "image/jpeg", toExt: "jpg", quality: 0.9 }
43165
+ },
43166
+ types: {
43167
+ image: { icon: "mdi:file-image", color: "yellow", prefixRule: "image/", needsObjectUrl: true },
43168
+ audio: { icon: "mdi:file-music", color: "grey", prefixRule: "audio/", needsObjectUrl: true },
43169
+ video: { icon: "mdi:file-video", color: "yellow", prefixRule: "video/", needsObjectUrl: true },
43170
+ pdf: { icon: "mdi:pdf-box", color: "red", needsObjectUrl: true },
43171
+ document: { icon: "mdi:file-word", color: "lightblue" },
43172
+ spreadsheet: { icon: "mdi:file-excel", color: "green" },
43173
+ text: { icon: "mdi:file", color: "white", prefixRule: "text/" },
43174
+ archive: { icon: "mdi:folder-zip", color: "purple" },
43175
+ unknown: { icon: "mdi:file", color: "grey" },
43176
+ mcp_text: { icon: "mdi:robot", color: "purple" },
43177
+ mcp_image: { icon: "mdi:robot", color: "purple", needsObjectUrl: true },
43178
+ mcp_audio: { icon: "mdi:robot", color: "purple", needsObjectUrl: true },
43179
+ mcp_resource: { icon: "mdi:cloud", color: "purple" }
43180
+ },
43181
+ extensions: {
43182
+ txt: { mime: "text/plain", type: "text" },
43183
+ md: { mime: "text/markdown", type: "text" },
43184
+ json: { mime: "application/json", type: "text" },
43185
+ js: { mime: "text/javascript", type: "text" },
43186
+ ts: { mime: "text/typescript", type: "text" },
43187
+ html: { mime: "text/html", type: "text" },
43188
+ css: { mime: "text/css", type: "text" },
43189
+ xml: { mime: "text/xml", type: "text" },
43190
+ py: { mime: "text/x-python", type: "text" },
43191
+ java: { mime: "text/x-java-source", type: "text" },
43192
+ cpp: { mime: "text/x-c++src", type: "text" },
43193
+ c: { mime: "text/x-csrc", type: "text" },
43194
+ h: { mime: "text/x-chdr", type: "text" },
43195
+ yml: { mime: "text/yaml", type: "text" },
43196
+ yaml: { mime: "text/yaml", type: "text" },
43197
+ csv: { mime: "text/csv", type: "spreadsheet" },
43198
+ png: { mime: "image/png", type: "image" },
43199
+ jpg: { mime: "image/jpeg", type: "image" },
43200
+ jpeg: { mime: "image/jpeg", type: "image" },
43201
+ gif: { mime: "image/gif", type: "image" },
43202
+ webp: { mime: "image/webp", type: "image" },
43203
+ bmp: { mime: "image/bmp", type: "image" },
43204
+ svg: { mime: "image/svg+xml", type: "text" },
43205
+ heic: { mime: "image/heic", type: "image", conversionProfile: "to_jpeg_90" },
43206
+ heif: { mime: "image/heif", type: "image", conversionProfile: "to_jpeg_90" },
43207
+ mp3: { mime: "audio/mpeg", type: "audio" },
43208
+ wav: { mime: "audio/wav", type: "audio" },
43209
+ ogg: { mime: "audio/ogg", type: "audio" },
43210
+ flac: { mime: "audio/flac", type: "audio" },
43211
+ aac: { mime: "audio/aac", type: "audio" },
43212
+ m4a: { mime: "audio/mp4", type: "audio" },
43213
+ wma: { mime: "audio/x-ms-wma", type: "audio" },
43214
+ mp4: { mime: "video/mp4", type: "video" },
43215
+ webm: { mime: "video/webm", type: "video" },
43216
+ avi: { mime: "video/x-msvideo", type: "video" },
43217
+ mkv: { mime: "video/x-matroska", type: "video" },
43218
+ mov: { mime: "video/quicktime", type: "video" },
43219
+ wmv: { mime: "video/x-ms-wmv", type: "video" },
43220
+ flv: { mime: "video/x-flv", type: "video" },
43221
+ pdf: { mime: "application/pdf", type: "pdf" },
43222
+ doc: { mime: "application/msword", type: "document" },
43223
+ docx: { mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", type: "document", tags: ["docx"] },
43224
+ ppt: { mime: "application/vnd.ms-powerpoint", type: "document" },
43225
+ pptx: { mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation", type: "document" },
43226
+ xls: { mime: "application/vnd.ms-excel", type: "spreadsheet" },
43227
+ xlsx: { mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", type: "spreadsheet" },
43228
+ zip: { mime: "application/zip", type: "archive" },
43229
+ rar: { mime: "application/vnd.rar", type: "archive" },
43230
+ tar: { mime: "application/x-tar", type: "archive" },
43231
+ gz: { mime: "application/gzip", type: "archive" },
43232
+ "7z": { mime: "application/x-7z-compressed", type: "archive" }
43233
+ },
43234
+ aliases: {
43235
+ "application/xml": "text",
43236
+ "application/javascript": "text",
43237
+ "application/x-javascript": "text",
43238
+ "application/typescript": "text",
43239
+ "application/x-typescript": "text",
43240
+ "application/yaml": "text",
43241
+ "application/x-yaml": "text",
43242
+ "application/x-python": "text",
43243
+ "application/x-java-source": "text",
43244
+ "application/x-c++src": "text",
43245
+ "application/x-csrc": "text",
43246
+ "application/x-chdr": "text",
43247
+ "application/octet-stream": "unknown",
43248
+ "text/mcp": "mcp_text",
43249
+ "image/mcp": "mcp_image",
43250
+ "audio/mcp": "mcp_audio"
43251
+ }
43252
+ };
43137
43253
 
43254
+ // ../packages/shared-fbe/src/attachmentUtils.ts
43255
+ var MCP_TEXT_MIME = Object.entries(mimetypes_default.aliases).find(([, type]) => type === "mcp_text")[0];
43256
+ var MCP_AUDIO_MIME = Object.entries(mimetypes_default.aliases).find(([, type]) => type === "mcp_audio")[0];
43257
+ var AttachmentType = Object.fromEntries(Object.keys(mimetypes_default.types).map((k) => [k.toUpperCase(), k]));
43258
+ var EXT_TO_MIME = {};
43259
+ var MIME_TO_TYPE = {};
43260
+ var PREFIX_RULES = [];
43261
+ for (const [ext, entry] of Object.entries(mimetypes_default.extensions)) {
43262
+ const { mime, type } = entry;
43263
+ EXT_TO_MIME[ext] = mime;
43264
+ MIME_TO_TYPE[mime] = type;
43265
+ }
43266
+ for (const [mime, type] of Object.entries(mimetypes_default.aliases)) {
43267
+ MIME_TO_TYPE[mime] = type;
43268
+ }
43269
+ for (const [type, meta] of Object.entries(mimetypes_default.types)) {
43270
+ const { prefixRule } = meta;
43271
+ if (prefixRule)
43272
+ PREFIX_RULES.push([prefixRule, type]);
43273
+ }
43274
+ var TAG_TO_MIMES = {};
43275
+ for (const [, entry] of Object.entries(mimetypes_default.extensions)) {
43276
+ const { mime, tags } = entry;
43277
+ if (tags) {
43278
+ for (const tag of tags) {
43279
+ (TAG_TO_MIMES[tag] ??= new Set).add(mime);
43280
+ }
43281
+ }
43282
+ }
43283
+ var NEEDS_OBJECT_URL = new Set(Object.entries(mimetypes_default.types).filter(([, meta]) => meta.needsObjectUrl).map(([type]) => type));
43284
+ var MIME_TO_EXT = {};
43285
+ for (const [ext, entry] of Object.entries(mimetypes_default.extensions)) {
43286
+ const { mime } = entry;
43287
+ if (!MIME_TO_EXT[mime])
43288
+ MIME_TO_EXT[mime] = ext;
43289
+ }
43290
+ // ../packages/shared-fbe/src/blocks/index.ts
43291
+ var USER_INPUT_BLOCK_TYPES = new Set([
43292
+ "question" /* Question */,
43293
+ "login_prompt" /* Login */,
43294
+ "business_onboarding" /* BusinessOnboarding */
43295
+ ]);
43296
+ var EDGE_TOOL_TYPES = new Set([
43297
+ "read" /* Read */,
43298
+ "create" /* Create */,
43299
+ "write" /* Write */,
43300
+ "edit" /* Edit */,
43301
+ "modify_file" /* ModifyFile */,
43302
+ "bash" /* Bash */,
43303
+ "search" /* Search */,
43304
+ "grep" /* Grep */,
43305
+ "list" /* List */
43306
+ ]);
43307
+ var BROWSER_TOOL_TYPES = new Set([
43308
+ "browser_interactable" /* BrowserInteractable */,
43309
+ "browser_dom_tree" /* BrowserDomTree */,
43310
+ "browser_navigate" /* BrowserNavigate */,
43311
+ "browser_screenshot" /* BrowserScreenshot */,
43312
+ "browser_click" /* BrowserClick */,
43313
+ "browser_type" /* BrowserType */,
43314
+ "browser_fill" /* BrowserFill */,
43315
+ "browser_scroll" /* BrowserScroll */,
43316
+ "browser_mouse_move" /* BrowserMouseMove */,
43317
+ "browser_key" /* BrowserKey */,
43318
+ "browser_evaluate" /* BrowserEvaluate */,
43319
+ "browser_select" /* BrowserSelect */,
43320
+ "browser_hover" /* BrowserHover */,
43321
+ "browser_text_content" /* BrowserTextContent */,
43322
+ "browser_back" /* BrowserBack */,
43323
+ "browser_forward" /* BrowserForward */,
43324
+ "browser_reload" /* BrowserReload */,
43325
+ "browser_upload_file" /* BrowserUploadFile */,
43326
+ "browser_find_text" /* BrowserFindText */,
43327
+ "browser_find_role" /* BrowserFindRole */,
43328
+ "browser_find_label" /* BrowserFindLabel */,
43329
+ "browser_find_placeholder" /* BrowserFindPlaceholder */,
43330
+ "browser_wait" /* BrowserWait */,
43331
+ "browser_drag" /* BrowserDrag */,
43332
+ "browser_dialog" /* BrowserDialog */,
43333
+ "browser_network_wait" /* BrowserNetworkWait */,
43334
+ "browser_check" /* BrowserCheck */,
43335
+ "browser_uncheck" /* BrowserUncheck */,
43336
+ "browser_focus" /* BrowserFocus */,
43337
+ "browser_find_test_id" /* BrowserFindTestId */,
43338
+ "browser_cookies" /* BrowserCookies */,
43339
+ "browser_storage" /* BrowserStorage */,
43340
+ "browser_pdf" /* BrowserPdf */,
43341
+ "browser_clipboard_read" /* BrowserClipboardRead */,
43342
+ "browser_clipboard_write" /* BrowserClipboardWrite */,
43343
+ "browser_snapshot" /* BrowserSnapshot */,
43344
+ "browser_iframe" /* BrowserIframe */,
43345
+ "browser_console" /* BrowserConsole */,
43346
+ "browser_scroll_into_view" /* BrowserScrollIntoView */,
43347
+ "browser_network_requests" /* BrowserNetworkRequests */,
43348
+ "browser_tap" /* BrowserTap */,
43349
+ "browser_swipe" /* BrowserSwipe */
43350
+ ]);
43351
+ var API_TOOL_TYPES = new Set([
43352
+ "api_get_current_context" /* ApiGetCurrentContext */,
43353
+ "api_get_todo" /* ApiGetTodo */,
43354
+ "api_add_todo_message" /* ApiAddTodoMessage */,
43355
+ "api_update_todo_status" /* ApiUpdateTodoStatus */,
43356
+ "api_delete_todo" /* ApiDeleteTodo */,
43357
+ "api_list_projects" /* ApiListProjects */,
43358
+ "api_get_project" /* ApiGetProject */,
43359
+ "api_create_project" /* ApiCreateProject */,
43360
+ "api_list_project_todos" /* ApiListProjectTodos */,
43361
+ "api_create_todo" /* ApiCreateTodo */,
43362
+ "api_list_agents" /* ApiListAgents */,
43363
+ "api_get_agent" /* ApiGetAgent */,
43364
+ "api_update_agent" /* ApiUpdateAgent */,
43365
+ "api_list_business_contexts" /* ApiListBusinessContexts */,
43366
+ "api_get_business_context" /* ApiGetBusinessContext */,
43367
+ "api_get_context_item" /* ApiGetContextItem */,
43368
+ "api_create_context_item" /* ApiCreateContextItem */,
43369
+ "api_update_context_item" /* ApiUpdateContextItem */,
43370
+ "api_delete_context_item" /* ApiDeleteContextItem */,
43371
+ "api_list_edges" /* ApiListEdges */,
43372
+ "api_get_edge" /* ApiGetEdge */,
43373
+ "api_list_mcps" /* ApiListMcps */,
43374
+ "api_get_usage" /* ApiGetUsage */,
43375
+ "api_get_balance" /* ApiGetBalance */,
43376
+ "api_get_api_schema" /* ApiGetApiSchema */
43377
+ ]);
43378
+ var FILE_TOOL_TYPES = new Set([
43379
+ "read" /* Read */,
43380
+ "create" /* Create */,
43381
+ "write" /* Write */,
43382
+ "edit" /* Edit */,
43383
+ "modify_file" /* ModifyFile */
43384
+ ]);
43385
+ // ../packages/shared-fbe/src/channels.ts
43386
+ var SERVER_TO_FRONTENDS = {
43387
+ task: {
43388
+ actionUpdate: (userId) => `${"task_action:update" /* TASK_ACTION_UPDATE */}:${userId}`
43389
+ },
43390
+ businessContext: {
43391
+ updated: (userId) => `${"business_context:updated" /* BUSINESS_CONTEXT_UPDATED */}:${userId}`
43392
+ },
43393
+ resource: {
43394
+ contentUpdated: (userId) => `${"resource:content_updated" /* RESOURCE_CONTENT_UPDATED */}:${userId}`
43395
+ },
43396
+ hexGrid: {
43397
+ updated: (projectId) => `${"hexgrid:updated" /* HEXGRID_UPDATED */}:${projectId}`
43398
+ },
43399
+ sandbox: {
43400
+ state: (userId) => `${"sandbox:state" /* SANDBOX_STATE */}:${userId}`
43401
+ },
43402
+ device: {
43403
+ status: (userId) => `${"device:status" /* DEVICE_STATUS */}:${userId}`
43404
+ },
43405
+ agent: {
43406
+ status: (userId) => `${"agent:status" /* AGENT_STATUS */}:${userId}`,
43407
+ mcpList: () => `${"agent:mcp_list" /* AGENT_MCP_LIST */}:ALL`
43408
+ },
43409
+ edge: {
43410
+ status: (userId) => `${"edge:status" /* EDGE_STATUS */}:${userId}`,
43411
+ configUpdate: (userId) => `${"EDGE_CONFIG_UPDATE" /* EDGE_CONFIG_UPDATE */}:${userId}`,
43412
+ cdResult: (edgeId) => `${"edge:cd_response" /* EDGE_CD_RESPONSE */}:${edgeId}`,
43413
+ getFoldersResult: (edgeId) => `${"edge:get_folders_response" /* EDGE_GET_FOLDERS_RESPONSE */}:${edgeId}`,
43414
+ createFolderResult: (edgeId) => `${"edge:create_folder_response" /* EDGE_CREATE_FOLDER_RESPONSE */}:${edgeId}`,
43415
+ deletePathResult: (edgeId) => `${"edge:delete_path_response" /* EDGE_DELETE_PATH_RESPONSE */}:${edgeId}`,
43416
+ writeFileResult: (edgeId) => `${"edge:write_file_response" /* EDGE_WRITE_FILE_RESPONSE */}:${edgeId}`
43417
+ },
43418
+ project: {
43419
+ new_message: (projectId) => `${"task:new_update" /* TASK_NEW */}:${projectId}`,
43420
+ new_todo: (projectId) => `${"todo:new" /* NEW_TODO */}:${projectId}`,
43421
+ status: (projectId) => `${"project:status" /* PROJECT_STATUS */}:${projectId}`
43422
+ },
43423
+ todo: {
43424
+ msgStart: (todoId) => `${"todo:msg_start" /* TODO_MSG_START */}:${todoId}`,
43425
+ msgDone: (todoId) => `${"todo:msg_done" /* TODO_MSG_DONE */}:${todoId}`,
43426
+ msgStopSequence: (todoId) => `${"todo:msg_stop_sequence" /* TODO_MSG_STOP_SEQUENCE */}:${todoId}`,
43427
+ msgMetaUsr: (todoId) => `${"todo:msg_meta_usr" /* TODO_MSG_META_USR */}:${todoId}`,
43428
+ msgMetaAi: (todoId) => `${"todo:msg_meta_ai" /* TODO_MSG_META_AI */}:${todoId}`,
43429
+ start_universal: (todoId) => `${"block:start_universal" /* BLOCK_START_UNIVERSAL */}:${todoId}`,
43430
+ message: (todoId) => `${"block:message" /* BLOCK_MESSAGE */}:${todoId}`,
43431
+ end: (todoId) => `${"block:end" /* BLOCK_END */}:${todoId}`,
43432
+ new_message: (todoId) => `${"todo:new_message" /* TODO_NEW_MESSAGE */}:${todoId}`,
43433
+ sh_msg_result: (todoId) => `${"block:sh_msg_result" /* BLOCK_SH_MSG_RESULT */}:${todoId}`,
43434
+ sh_msg_start_result: (todoId) => `${"block:sh_msg_start" /* BLOCK_SH_MSG_START */}:${todoId}`,
43435
+ sh_msg_done_result: (todoId) => `${"block:sh_done" /* BLOCK_SH_DONE */}:${todoId}`,
43436
+ save_result: (todoId) => `${"block:save_result" /* BLOCK_SAVE_RESULT */}:${todoId}`,
43437
+ diff_result: (todoId) => `${"block:diff_result" /* BLOCK_DIFF_RESULT */}:${todoId}`,
43438
+ frontend_file_chunk_result: (todoId) => `${"frontend:file_chunk_result" /* FRONTEND_FILE_CHUNK_RESULT */}:${todoId}`,
43439
+ status: (todoId) => `todo:${todoId}:status`,
43440
+ block_update: (todoId) => `todo:${todoId}:block_update`,
43441
+ error_result: (todoId) => `${"block:error_result" /* BLOCK_ERROR_RESULT */}:${todoId}`,
43442
+ meta_result: (todoId) => `${"block:meta_result" /* BLOCK_META_RESULT */}:${todoId}`,
43443
+ file_changed: (edgeId, path3) => `${"block:file_changed" /* BLOCK_FILE_CHANGED */}:${edgeId}:${path3}`,
43444
+ notify: (todoId) => `${"NOTIFY" /* NOTIFY */}:${todoId}`
43445
+ },
43446
+ notify: {
43447
+ user: (userId) => `${"NOTIFY" /* NOTIFY */}:user:${userId}`
43448
+ },
43449
+ payment: {
43450
+ status: (userId) => `${"payment:status" /* PAYMENT_STATUS */}:${userId}`
43451
+ },
43452
+ functions: {}
43453
+ };
43454
+ // ../packages/shared-fbe/src/bashPatterns.ts
43455
+ function splitShellCommands(input) {
43456
+ const parts = [];
43457
+ let current = "";
43458
+ let i = 0;
43459
+ const len = input.length;
43460
+ while (i < len) {
43461
+ const ch = input[i];
43462
+ if (ch === "\\" && i + 1 < len && input[i + 1] === `
43463
+ `) {
43464
+ current += " ";
43465
+ i += 2;
43466
+ continue;
43467
+ }
43468
+ if (ch === "\\" && i + 1 < len) {
43469
+ current += ch + input[i + 1];
43470
+ i += 2;
43471
+ continue;
43472
+ }
43473
+ if (ch === "<" && i + 1 < len && input[i + 1] === "<") {
43474
+ i += 2;
43475
+ if (i < len && input[i] === "-")
43476
+ i++;
43477
+ while (i < len && (input[i] === " " || input[i] === "\t"))
43478
+ i++;
43479
+ let delim = "";
43480
+ if (i < len && (input[i] === "'" || input[i] === '"')) {
43481
+ const q = input[i];
43482
+ i++;
43483
+ while (i < len && input[i] !== q) {
43484
+ delim += input[i];
43485
+ i++;
43486
+ }
43487
+ if (i < len)
43488
+ i++;
43489
+ } else {
43490
+ while (i < len && /\w/.test(input[i])) {
43491
+ delim += input[i];
43492
+ i++;
43493
+ }
43494
+ }
43495
+ if (delim) {
43496
+ const rest = input.slice(i);
43497
+ const m = rest.match(new RegExp(`^${delim}$`, "m"));
43498
+ if (m && m.index !== undefined) {
43499
+ i += m.index + delim.length;
43500
+ } else {
43501
+ i = len;
43502
+ }
43503
+ }
43504
+ continue;
43505
+ }
43506
+ if (ch === "#" && (current.length === 0 || /\s$/.test(current))) {
43507
+ while (i < len && input[i] !== `
43508
+ `)
43509
+ i++;
43510
+ continue;
43511
+ }
43512
+ if (ch === '"' || ch === "'") {
43513
+ const quote = ch;
43514
+ current += ch;
43515
+ i++;
43516
+ while (i < len && input[i] !== quote) {
43517
+ if (input[i] === "\\" && quote === '"' && i + 1 < len) {
43518
+ current += input[i] + input[i + 1];
43519
+ i += 2;
43520
+ } else {
43521
+ current += input[i];
43522
+ i++;
43523
+ }
43524
+ }
43525
+ if (i < len)
43526
+ current += input[i];
43527
+ i++;
43528
+ continue;
43529
+ }
43530
+ if (ch === "|" && i + 1 < len && input[i + 1] === "|") {
43531
+ parts.push(current);
43532
+ current = "";
43533
+ i += 2;
43534
+ } else if (ch === "&" && i + 1 < len && input[i + 1] === "&") {
43535
+ parts.push(current);
43536
+ current = "";
43537
+ i += 2;
43538
+ } else if (ch === "|") {
43539
+ parts.push(current);
43540
+ current = "";
43541
+ i++;
43542
+ } else if (ch === ";" || ch === `
43543
+ `) {
43544
+ parts.push(current);
43545
+ current = "";
43546
+ i++;
43547
+ } else {
43548
+ current += ch;
43549
+ i++;
43550
+ }
43551
+ }
43552
+ parts.push(current);
43553
+ return parts.map((s) => s.trim()).filter(Boolean);
43554
+ }
43555
+ function generalizeToken(token) {
43556
+ if (/^\d+$/.test(token))
43557
+ return "*";
43558
+ if (/^[0-9a-f]{4,}$/i.test(token) && /\d/.test(token))
43559
+ return "*";
43560
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(token))
43561
+ return "*";
43562
+ if (/^https?:\/\//i.test(token)) {
43563
+ try {
43564
+ const u = new URL(token);
43565
+ return `${u.protocol}//${u.host}/*`;
43566
+ } catch {
43567
+ return token;
43568
+ }
43569
+ }
43570
+ return token;
43571
+ }
43572
+ var SAFE_FLAGS = new Set(["--help", "-h", "--version", "-V", "-v"]);
43573
+ function splitTokens(cmd) {
43574
+ const tokens = [];
43575
+ let current = "";
43576
+ let i = 0;
43577
+ const len = cmd.length;
43578
+ while (i < len) {
43579
+ const ch = cmd[i];
43580
+ if (ch === "\\" && i + 1 < len && cmd[i + 1] === `
43581
+ `) {
43582
+ i += 2;
43583
+ continue;
43584
+ }
43585
+ if (ch === "\\" && i + 1 < len) {
43586
+ current += ch + cmd[i + 1];
43587
+ i += 2;
43588
+ continue;
43589
+ }
43590
+ if (ch === '"' || ch === "'") {
43591
+ const q = ch;
43592
+ current += ch;
43593
+ i++;
43594
+ while (i < len && cmd[i] !== q) {
43595
+ if (cmd[i] === "\\" && q === '"' && i + 1 < len) {
43596
+ current += cmd[i] + cmd[i + 1];
43597
+ i += 2;
43598
+ } else {
43599
+ current += cmd[i];
43600
+ i++;
43601
+ }
43602
+ }
43603
+ if (i < len) {
43604
+ current += cmd[i];
43605
+ i++;
43606
+ }
43607
+ continue;
43608
+ }
43609
+ if (/\s/.test(ch)) {
43610
+ if (current) {
43611
+ tokens.push(current);
43612
+ current = "";
43613
+ }
43614
+ i++;
43615
+ continue;
43616
+ }
43617
+ current += ch;
43618
+ i++;
43619
+ }
43620
+ if (current)
43621
+ tokens.push(current);
43622
+ return tokens;
43623
+ }
43624
+ function parseSingle(cmd) {
43625
+ const tokens = splitTokens(cmd);
43626
+ while (tokens.length && /^[A-Za-z_]\w*=/.test(tokens[0])) {
43627
+ const val = tokens[0].slice(tokens[0].indexOf("=") + 1);
43628
+ if (/\$\(|`/.test(val))
43629
+ return { tokens: [], defaultKeep: 0 };
43630
+ tokens.shift();
43631
+ }
43632
+ if (tokens.length === 0)
43633
+ return { tokens: [], defaultKeep: 0 };
43634
+ if (tokens[0].startsWith("#"))
43635
+ return { tokens: [], defaultKeep: 0 };
43636
+ const positionals = [tokens[0]];
43637
+ let hitFlag = false;
43638
+ let defaultKeep = -1;
43639
+ for (let t = 1;t < tokens.length; t++) {
43640
+ if (!hitFlag && SAFE_FLAGS.has(tokens[t])) {
43641
+ positionals.push(tokens[t]);
43642
+ return { tokens: positionals, defaultKeep: positionals.length };
43643
+ }
43644
+ if (tokens[t].startsWith("-")) {
43645
+ if (!hitFlag) {
43646
+ hitFlag = true;
43647
+ defaultKeep = Math.min(3, positionals.length);
43648
+ }
43649
+ positionals.push(tokens[t]);
43650
+ continue;
43651
+ }
43652
+ const g = generalizeToken(tokens[t]);
43653
+ positionals.push(g);
43654
+ if (g !== tokens[t])
43655
+ break;
43656
+ }
43657
+ if (defaultKeep < 0)
43658
+ defaultKeep = Math.min(3, positionals.length);
43659
+ return { tokens: positionals, defaultKeep };
43660
+ }
43661
+ function buildBashPattern(parsed, keep) {
43662
+ if (parsed.tokens.length === 0)
43663
+ return "BASH(cmd: *)";
43664
+ const k = Math.max(1, Math.min(keep ?? parsed.defaultKeep, parsed.tokens.length));
43665
+ const kept = parsed.tokens.slice(0, k);
43666
+ const suffix = kept[kept.length - 1] === "*" ? "" : " *";
43667
+ return `BASH(cmd: ${kept.join(" ")}${suffix})`;
43668
+ }
43669
+ function parseBashCmd(fullCmd) {
43670
+ return splitShellCommands(fullCmd).map(parseSingle).filter((p) => p.tokens.length > 0);
43671
+ }
43672
+ function generalizeBashCmd(fullCmd) {
43673
+ return parseBashCmd(fullCmd).map((p) => buildBashPattern(p));
43674
+ }
43675
+ function getBlockServerPrefix(block) {
43676
+ const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
43677
+ const prefixMatch = agentPattern.match(/^(.*?:)BASH(?:\(|$)/);
43678
+ return prefixMatch ? prefixMatch[1] : "";
43679
+ }
43680
+ var BASH_LIKE_BLOCK_TYPES = new Set(["bash", "machine_exec"]);
43681
+ function getBlockPatterns(block) {
43682
+ if (Array.isArray(block.generalized_pattern))
43683
+ return block.generalized_pattern;
43684
+ const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
43685
+ const isBashLike = BASH_LIKE_BLOCK_TYPES.has(block.type.toLowerCase()) || /:BASH(\(|$)/.test(agentPattern);
43686
+ if (isBashLike && block.cmd) {
43687
+ const prefix = getBlockServerPrefix(block);
43688
+ return generalizeBashCmd(block.cmd).map((p) => prefix + p);
43689
+ }
43690
+ if (block.generalized_pattern)
43691
+ return [block.generalized_pattern];
43692
+ return [`${block.type}(*)`];
43693
+ }
43694
+ function getBlockServerId(block) {
43695
+ const prefix = getBlockServerPrefix(block);
43696
+ return prefix ? prefix.slice(0, -1) : "*";
43697
+ }
43698
+
43699
+ // ../packages/shared-fbe/src/permissionUtils.ts
43700
+ function parsePattern(pattern) {
43701
+ const colonIndex = pattern.indexOf(":");
43702
+ if (colonIndex === -1)
43703
+ return null;
43704
+ const serverId = pattern.slice(0, colonIndex);
43705
+ if (!/^[A-Za-z0-9_*-]+$/.test(serverId)) {
43706
+ return { serverId: "*", toolName: pattern };
43707
+ }
43708
+ return { serverId, toolName: pattern.slice(colonIndex + 1) };
43709
+ }
43710
+ function serverIdMatches(ruleServerId, targetServerId) {
43711
+ if (ruleServerId === targetServerId)
43712
+ return true;
43713
+ if (ruleServerId === "*")
43714
+ return true;
43715
+ if (ruleServerId.includes("*")) {
43716
+ const escaped = ruleServerId.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
43717
+ const regex = new RegExp("^" + escaped.replace(/\*/g, "[^:]*") + "$");
43718
+ return regex.test(targetServerId);
43719
+ }
43720
+ if (targetServerId.startsWith(ruleServerId + "_"))
43721
+ return true;
43722
+ return false;
43723
+ }
43724
+ function patternMatches(rulePattern, targetPattern) {
43725
+ const rule = parsePattern(rulePattern);
43726
+ const target = parsePattern(targetPattern);
43727
+ if (!rule || !target)
43728
+ return rulePattern === targetPattern;
43729
+ if (!serverIdMatches(rule.serverId, target.serverId))
43730
+ return false;
43731
+ if (rule.toolName === target.toolName)
43732
+ return true;
43733
+ if (rule.toolName === "*")
43734
+ return true;
43735
+ if (rule.toolName.endsWith(" *)")) {
43736
+ const rulePrefix = rule.toolName.slice(0, -2);
43737
+ return target.toolName.startsWith(rulePrefix);
43738
+ }
43739
+ return false;
43740
+ }
43741
+ function bashRuleMatchesCmd(rulePattern, serverId, cmd) {
43742
+ const rule = parsePattern(rulePattern);
43743
+ if (!rule)
43744
+ return false;
43745
+ if (!serverIdMatches(rule.serverId, serverId))
43746
+ return false;
43747
+ if (rule.toolName === "*" || rule.toolName === "BASH")
43748
+ return true;
43749
+ const m = rule.toolName.match(/^BASH\(cmd:\s*(.*)\)$/);
43750
+ if (!m)
43751
+ return false;
43752
+ let body = m[1];
43753
+ const isPrefix = body.endsWith(" *") || body.endsWith("*");
43754
+ if (isPrefix)
43755
+ body = body.replace(/\s*\*$/, "");
43756
+ const subs = splitShellCommands(cmd);
43757
+ if (subs.length === 0)
43758
+ return false;
43759
+ return subs.every((sub) => isPrefix ? sub === body || sub.startsWith(body + " ") : sub === body);
43760
+ }
43761
+ function isPatternInList(list, pattern) {
43762
+ if (!list)
43763
+ return false;
43764
+ return list.some((p) => patternMatches(p, pattern));
43765
+ }
43766
+ function isPatternAllowed(permissions, pattern) {
43767
+ return isPatternInList(permissions?.allow, pattern);
43768
+ }
43769
+ function getNewPatterns(patterns, permissions) {
43770
+ return patterns.filter((p) => !isPatternAllowed(permissions, p));
43771
+ }
43772
+ function getBlockNewPatterns(block, permissions) {
43773
+ const allow = permissions?.allow ?? [];
43774
+ if (Array.isArray(block.generalized_pattern)) {
43775
+ return getNewPatterns(block.generalized_pattern, permissions);
43776
+ }
43777
+ const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
43778
+ const isBash = (block.type.toLowerCase() === "bash" || agentPattern.includes(":BASH(")) && !!block.cmd;
43779
+ if (!isBash) {
43780
+ return getBlockPatterns(block).filter((p) => !isPatternAllowed(permissions, p));
43781
+ }
43782
+ const serverId = getBlockServerId(block);
43783
+ const prefix = serverId === "*" ? "" : `${serverId}:`;
43784
+ const rawSubs = splitShellCommands(block.cmd);
43785
+ const pairs = [];
43786
+ for (const raw of rawSubs) {
43787
+ const parsed = parseBashCmd(raw);
43788
+ if (parsed.length === 0)
43789
+ continue;
43790
+ pairs.push({ raw, pattern: prefix + buildBashPattern(parsed[0]) });
43791
+ }
43792
+ return pairs.filter(({ raw, pattern }) => !isPatternAllowed(permissions, pattern) && !allow.some((rule) => bashRuleMatchesCmd(rule, serverId, raw))).map(({ pattern }) => pattern);
43793
+ }
43794
+ // ../packages/shared-fbe/src/realtime/topics.ts
43795
+ var TOPICS = {
43796
+ ["todo:new" /* NEW_TODO */]: {
43797
+ channel: (p) => SERVER_TO_FRONTENDS.project.new_todo(p.projectId),
43798
+ audience: "frontend"
43799
+ },
43800
+ ["todo:new_message" /* TODO_NEW_MESSAGE */]: {
43801
+ channel: (p) => SERVER_TO_FRONTENDS.project.new_message(p.projectId),
43802
+ audience: "frontend"
43803
+ },
43804
+ ["todo:new_message_created" /* TODO_NEW_MESSAGE_CREATED */]: {
43805
+ channel: (p) => SERVER_TO_FRONTENDS.todo.new_message(p.todoId),
43806
+ audience: "frontend"
43807
+ },
43808
+ ["business_context:updated" /* BUSINESS_CONTEXT_UPDATED */]: {
43809
+ channel: (p) => SERVER_TO_FRONTENDS.businessContext.updated(p.userId),
43810
+ audience: "frontend"
43811
+ },
43812
+ ["resource:content_updated" /* RESOURCE_CONTENT_UPDATED */]: {
43813
+ channel: (p) => SERVER_TO_FRONTENDS.resource.contentUpdated(p.userId),
43814
+ audience: "frontend"
43815
+ },
43816
+ ["hexgrid:updated" /* HEXGRID_UPDATED */]: {
43817
+ channel: (p) => SERVER_TO_FRONTENDS.hexGrid.updated(p.projectId),
43818
+ audience: "frontend"
43819
+ },
43820
+ ["sandbox:state" /* SANDBOX_STATE */]: {
43821
+ channel: (p) => SERVER_TO_FRONTENDS.sandbox.state(p.userId),
43822
+ audience: "frontend"
43823
+ },
43824
+ ["device:status" /* DEVICE_STATUS */]: {
43825
+ channel: (p) => SERVER_TO_FRONTENDS.device.status(p.userId),
43826
+ audience: "frontend"
43827
+ },
43828
+ ["NOTIFY" /* NOTIFY */]: {
43829
+ channel: (p) => p.userId ? SERVER_TO_FRONTENDS.notify.user(p.userId) : SERVER_TO_FRONTENDS.todo.notify(p.todoId),
43830
+ audience: "frontend"
43831
+ },
43832
+ ["todo:msg_done" /* TODO_MSG_DONE */]: {
43833
+ channel: (p) => SERVER_TO_FRONTENDS.todo.msgDone(p.todoId),
43834
+ audience: "frontend"
43835
+ },
43836
+ ["block:start_universal" /* BLOCK_START_UNIVERSAL */]: {
43837
+ channel: (p) => SERVER_TO_FRONTENDS.todo.start_universal(p.todoId),
43838
+ audience: "frontend"
43839
+ },
43840
+ ["block:message" /* BLOCK_MESSAGE */]: {
43841
+ channel: (p) => SERVER_TO_FRONTENDS.todo.message(p.todoId),
43842
+ audience: "frontend"
43843
+ },
43844
+ ["BLOCK_UPDATE" /* BLOCK_UPDATE */]: {
43845
+ channel: (p) => SERVER_TO_FRONTENDS.todo.block_update(p.todoId),
43846
+ audience: "frontend"
43847
+ },
43848
+ ["block:end" /* BLOCK_END */]: {
43849
+ channel: (p) => SERVER_TO_FRONTENDS.todo.end(p.todoId),
43850
+ audience: "frontend"
43851
+ },
43852
+ ["todo:msg_start" /* TODO_MSG_START */]: {
43853
+ channel: (p) => SERVER_TO_FRONTENDS.todo.msgStart(p.todoId),
43854
+ audience: "frontend"
43855
+ },
43856
+ ["todo:msg_meta_ai" /* TODO_MSG_META_AI */]: {
43857
+ channel: (p) => SERVER_TO_FRONTENDS.todo.msgMetaAi(p.todoId),
43858
+ audience: "frontend"
43859
+ },
43860
+ ["todo:msg_meta_usr" /* TODO_MSG_META_USR */]: {
43861
+ channel: (p) => SERVER_TO_FRONTENDS.todo.msgMetaUsr(p.todoId),
43862
+ audience: "frontend"
43863
+ },
43864
+ ["todo:msg_stop_sequence" /* TODO_MSG_STOP_SEQUENCE */]: {
43865
+ channel: (p) => SERVER_TO_FRONTENDS.todo.msgStopSequence(p.todoId),
43866
+ audience: "frontend"
43867
+ },
43868
+ ["block:diff_result" /* BLOCK_DIFF_RESULT */]: {
43869
+ channel: (p) => SERVER_TO_FRONTENDS.todo.diff_result(p.todoId),
43870
+ audience: "frontend"
43871
+ },
43872
+ ["frontend:file_chunk_result" /* FRONTEND_FILE_CHUNK_RESULT */]: {
43873
+ channel: (p) => SERVER_TO_FRONTENDS.todo.frontend_file_chunk_result(p.todoId),
43874
+ audience: "frontend"
43875
+ },
43876
+ ["block:save_result" /* BLOCK_SAVE_RESULT */]: {
43877
+ channel: (p) => SERVER_TO_FRONTENDS.todo.save_result(p.todoId),
43878
+ audience: "frontend"
43879
+ },
43880
+ ["block:sh_msg_start" /* BLOCK_SH_MSG_START */]: {
43881
+ channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_start_result(p.todoId),
43882
+ audience: "frontend"
43883
+ },
43884
+ ["block:sh_msg_result" /* BLOCK_SH_MSG_RESULT */]: {
43885
+ channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_result(p.todoId),
43886
+ audience: "frontend"
43887
+ },
43888
+ ["block:sh_done" /* BLOCK_SH_DONE */]: {
43889
+ channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_done_result(p.todoId),
43890
+ audience: "frontend"
43891
+ },
43892
+ ["edge:status" /* EDGE_STATUS */]: {
43893
+ channel: (p) => SERVER_TO_FRONTENDS.edge.status(p.userId),
43894
+ audience: "frontend"
43895
+ },
43896
+ ["EDGE_CONFIG_UPDATE" /* EDGE_CONFIG_UPDATE */]: {
43897
+ channel: (p) => SERVER_TO_FRONTENDS.edge.configUpdate(p.ownerId),
43898
+ audience: "frontend"
43899
+ },
43900
+ ["project:status" /* PROJECT_STATUS */]: {
43901
+ channel: (p) => SERVER_TO_FRONTENDS.project.status(p.projectId),
43902
+ audience: "frontend"
43903
+ },
43904
+ ["todo:status" /* TODO_STATUS */]: {
43905
+ channel: (p) => SERVER_TO_FRONTENDS.todo.status(p.todoId),
43906
+ audience: "frontend"
43907
+ },
43908
+ ["payment:status" /* PAYMENT_STATUS */]: {
43909
+ channel: (p) => SERVER_TO_FRONTENDS.payment.status(p.userId),
43910
+ audience: "frontend"
43911
+ },
43912
+ ["payment:webhook" /* PAYMENT_WEBHOOK */]: {
43913
+ channel: (p) => SERVER_TO_FRONTENDS.payment.status(p.userId),
43914
+ audience: "frontend"
43915
+ }
43916
+ };
43138
43917
  // src/args.ts
43139
43918
  var DEFAULT_API_URL = "https://api.todofor.ai";
43140
43919
  var VERSION = package_default.version;
@@ -43151,12 +43930,16 @@ Usage:
43151
43930
  todoai -n "Quick task" # Non-interactive (run and exit)
43152
43931
  echo "content" | todoai # Pipe from stdin
43153
43932
  todoai --path /my/project "Fix bug" # Explicit workspace path
43154
- todoai -c # Resume last todo
43155
- todoai --resume <todo-id> # Resume specific todo
43156
- todoai --inspect <todo-id>[:<msg-id>] # Print full chat log (read-only); :<msg-id> truncates inclusive
43157
- todoai --inspect :<msg-id> # Same, using $TODOFORAI_TODO_ID from edge env
43933
+ todoai -c ["prompt"] # Resume last todo (optional prompt sent on attach)
43934
+ todoai --resume <todo-id> ["prompt"] # Resume specific todo (optional prompt sent on attach)
43935
+ todoai --inspect <todo-id>[@<slice>] # Read chat log. <slice> = -3:, :1, 5:10, 7 (Python-style)
43158
43936
  todoai --template <id> [--input k=v] # Start from a registry template
43159
43937
  todoai --list-agents # List available agents and exit
43938
+ todoai agent update <agent> model=<model> # Update agent settings (see 'agent --help')
43939
+ todoai list [-n 30] [--all] [--status S] # List todos (open + recent first); see 'list --help'
43940
+ todoai status <todo-id> <STATUS> # Update a todo's status (run 'status --help' for the full list)
43941
+ todoai delete <todo-id> # Permanently delete a todo
43942
+ todoai addmessage <todo-id> "text" # Add a message to an existing todo
43160
43943
 
43161
43944
  Options:
43162
43945
  --path <dir> Workspace path (default: cwd)
@@ -43165,7 +43948,7 @@ Options:
43165
43948
  --list-agents List available agents (name, id, workspace paths) and exit
43166
43949
  --api-url <url> API URL
43167
43950
  --api-key <key> API key
43168
- --inspect, -i [<todo-id>][:<msg-id>] Print full chat log; empty todo-id uses $TODOFORAI_TODO_ID
43951
+ --inspect, -i <todo-id>[@<slice>] Print chat log (read-only)
43169
43952
  --template, -t <id> Start from a registry template
43170
43953
  --input <key=value> Template input (repeatable)
43171
43954
  --resume, -r [todo-id] Resume existing todo
@@ -43176,6 +43959,8 @@ Options:
43176
43959
  --no-watch Create todo and exit
43177
43960
  --no-edge Do not auto-spawn edge daemon
43178
43961
  --json Output as JSON
43962
+ --detailed 'inspect --json': keep ids, timestamps, agentSettingsId, scheduledTimestamp
43963
+ --format-anthropic 'inspect --json': Anthropic-style shape (tool_result in next user msg); attachment sources are uri-typed, so not a 1:1 messages.create input
43179
43964
  --safe Validate API key upfront
43180
43965
  --debug, -d Debug output
43181
43966
  --show-config Show config
@@ -43184,6 +43969,27 @@ Options:
43184
43969
  --help, -h Show this help
43185
43970
  `);
43186
43971
  }
43972
+ var STATUS_HELP = {
43973
+ ["READY" /* READY */]: "AI finished the work on the TODO",
43974
+ ["READY_CHECKED" /* READY_CHECKED */]: "AI finished and the user reviewed it",
43975
+ ["DONE" /* DONE */]: "Completed and finalized",
43976
+ ["REVIEW_REQUESTED" /* REVIEW_REQUESTED */]: "Asks the user to review",
43977
+ ["POSTPONED" /* POSTPONED */]: "Put off for later",
43978
+ ["ARCHIVED" /* ARCHIVED */]: "Archived (hidden from active list)",
43979
+ ["DELETED" /* DELETED */]: "Marked for deletion"
43980
+ };
43981
+ function printStatusHelp() {
43982
+ process.stderr.write(`
43983
+ todoai status <todo-id> <STATUS>
43984
+
43985
+ Common statuses:
43986
+ ${Object.entries(STATUS_HELP).map(([s, d]) => ` ${s.padEnd(18)}${d}`).join(`
43987
+ `)}
43988
+
43989
+ All valid statuses:
43990
+ ${Object.values(TodoStatus).join(", ")}
43991
+ `);
43992
+ }
43187
43993
  function parseCliArgs() {
43188
43994
  const { values, positionals } = parseArgs({
43189
43995
  args: process.argv.slice(2),
@@ -43191,6 +43997,7 @@ function parseCliArgs() {
43191
43997
  path: { type: "string", default: "." },
43192
43998
  project: { type: "string" },
43193
43999
  agent: { type: "string", short: "a" },
44000
+ model: { type: "string" },
43194
44001
  "list-agents": { type: "boolean", default: false },
43195
44002
  "api-url": { type: "string" },
43196
44003
  "api-key": { type: "string" },
@@ -43205,6 +44012,8 @@ function parseCliArgs() {
43205
44012
  "no-watch": { type: "boolean", default: false },
43206
44013
  "no-edge": { type: "boolean", default: false },
43207
44014
  json: { type: "boolean", default: false },
44015
+ detailed: { type: "boolean", default: false },
44016
+ "format-anthropic": { type: "boolean", default: false },
43208
44017
  safe: { type: "boolean", default: false },
43209
44018
  debug: { type: "boolean", short: "d", default: false },
43210
44019
  "show-config": { type: "boolean", default: false },
@@ -43223,21 +44032,23 @@ function parseCliArgs() {
43223
44032
  import { createInterface } from "readline";
43224
44033
 
43225
44034
  // src/colors.ts
43226
- var YELLOW = "\x1B[33m";
43227
- var GREEN = "\x1B[32m";
43228
- var RED = "\x1B[31m";
43229
- var DIM = "\x1B[90m";
43230
- var CYAN = "\x1B[36m";
43231
- var BOLD = "\x1B[1m";
43232
- var WHITE = "\x1B[38;2;255;255;255m";
43233
- var BRIGHT_WHITE = "\x1B[97m";
43234
- var BRAND = "\x1B[38;2;249;110;46m";
43235
- var RESET = "\x1B[0m";
43236
- var DIM_ATTR = "\x1B[2m";
43237
- var BG_RED = "\x1B[48;2;55;20;20m";
43238
- var BG_GREEN = "\x1B[48;2;20;45;20m";
43239
- var BG_RED_HL = "\x1B[48;2;100;35;35m";
43240
- var BG_GREEN_HL = "\x1B[48;2;35;85;35m";
44035
+ var on = !process.env.NO_COLOR && !!process.stdout.isTTY;
44036
+ var c = (seq) => on ? seq : "";
44037
+ var YELLOW = c("\x1B[33m");
44038
+ var GREEN = c("\x1B[32m");
44039
+ var RED = c("\x1B[31m");
44040
+ var DIM = c("\x1B[90m");
44041
+ var CYAN = c("\x1B[36m");
44042
+ var BOLD = c("\x1B[1m");
44043
+ var WHITE = c("\x1B[38;2;255;255;255m");
44044
+ var BRIGHT_WHITE = c("\x1B[97m");
44045
+ var BRAND = c("\x1B[38;2;249;110;46m");
44046
+ var RESET = c("\x1B[0m");
44047
+ var DIM_ATTR = c("\x1B[2m");
44048
+ var BG_RED = c("\x1B[48;2;55;20;20m");
44049
+ var BG_GREEN = c("\x1B[48;2;20;45;20m");
44050
+ var BG_RED_HL = c("\x1B[48;2;100;35;35m");
44051
+ var BG_GREEN_HL = c("\x1B[48;2;35;85;35m");
43241
44052
 
43242
44053
  // src/input.ts
43243
44054
  function readLine(prompt) {
@@ -43475,26 +44286,26 @@ function readMultiline(prompt, history) {
43475
44286
  const ps = s.indexOf("\x1B[200~");
43476
44287
  const chunk = ps >= 0 ? s.slice(0, ps) : s;
43477
44288
  for (let i = 0;i < chunk.length && !done; i++) {
43478
- const c = chunk.charCodeAt(i);
43479
- if (c === 3) {
44289
+ const c2 = chunk.charCodeAt(i);
44290
+ if (c2 === 3) {
43480
44291
  finish(true);
43481
44292
  return;
43482
44293
  }
43483
- if (c === 13 || c === 10) {
44294
+ if (c2 === 13 || c2 === 10) {
43484
44295
  finish(false);
43485
44296
  return;
43486
44297
  }
43487
- if (c === 23) {
44298
+ if (c2 === 23) {
43488
44299
  deleteWordBack();
43489
- } else if (c === 11) {
44300
+ } else if (c2 === 11) {
43490
44301
  killToEnd();
43491
- } else if (c === 127 || c === 8) {
44302
+ } else if (c2 === 127 || c2 === 8) {
43492
44303
  if (cursor > 0) {
43493
44304
  buf = buf.slice(0, cursor - 1) + buf.slice(cursor);
43494
44305
  cursor--;
43495
44306
  redraw();
43496
44307
  }
43497
- } else if (c === 27) {
44308
+ } else if (c2 === 27) {
43498
44309
  if (i + 1 < chunk.length && chunk.charCodeAt(i + 1) === 13) {
43499
44310
  buf = buf.slice(0, cursor) + `
43500
44311
  ` + buf.slice(cursor);
@@ -43504,13 +44315,13 @@ function readMultiline(prompt, history) {
43504
44315
  } else {
43505
44316
  i = handleCSI(chunk, i) - 1;
43506
44317
  }
43507
- } else if (c === 1) {
44318
+ } else if (c2 === 1) {
43508
44319
  cursor = 0;
43509
44320
  redraw();
43510
- } else if (c === 5) {
44321
+ } else if (c2 === 5) {
43511
44322
  cursor = buf.length;
43512
44323
  redraw();
43513
- } else if (c >= 32) {
44324
+ } else if (c2 >= 32) {
43514
44325
  buf = buf.slice(0, cursor) + chunk[i] + buf.slice(cursor);
43515
44326
  cursor++;
43516
44327
  redraw();
@@ -43846,7 +44657,232 @@ function printLogo() {
43846
44657
  }
43847
44658
 
43848
44659
  // src/inspect.ts
43849
- function printFullChat(todo, frontendUrl, untilMessageId) {
44660
+ var xmlAttr = (v) => JSON.stringify(String(v));
44661
+ var DROP_IF_EMPTY = new Set(["runMeta", "meta", "attachments", "blocks"]);
44662
+ var ALWAYS_DROP = new Set(["messageIds", "data"]);
44663
+ var DETAILED_ONLY = new Set([
44664
+ "id",
44665
+ "createdAt",
44666
+ "lastActivityAt",
44667
+ "modifiedAt",
44668
+ "agentSettingsId",
44669
+ "scheduledTimestamp",
44670
+ "workflowVersion",
44671
+ "todoId",
44672
+ "blockId",
44673
+ "parentBlockId",
44674
+ "stop_sequence",
44675
+ "permissions",
44676
+ "isPublic",
44677
+ "metadata"
44678
+ ]);
44679
+ var DEBUG_ONLY = new Set([
44680
+ "runMeta",
44681
+ "generationCompleted",
44682
+ "userId",
44683
+ "deviceId",
44684
+ "runMode"
44685
+ ]);
44686
+ var isEmpty = (x) => Array.isArray(x) && x.length === 0 || x && typeof x === "object" && !Array.isArray(x) && Object.keys(x).length === 0;
44687
+ function pruneEmpty(v, mode = "default") {
44688
+ if (Array.isArray(v))
44689
+ return v.map((x) => pruneEmpty(x, mode));
44690
+ if (v && typeof v === "object") {
44691
+ const o = {};
44692
+ for (const [k, raw] of Object.entries(v)) {
44693
+ if (ALWAYS_DROP.has(k))
44694
+ continue;
44695
+ if (DEBUG_ONLY.has(k) && mode !== "debug")
44696
+ continue;
44697
+ if (DETAILED_ONLY.has(k) && mode === "default")
44698
+ continue;
44699
+ if (raw === "")
44700
+ continue;
44701
+ if (k === "scheduledTimestamp" && (raw === 0 || raw === 1))
44702
+ continue;
44703
+ if (DROP_IF_EMPTY.has(k) && isEmpty(raw))
44704
+ continue;
44705
+ o[k] = pruneEmpty(raw, mode);
44706
+ }
44707
+ return o;
44708
+ }
44709
+ return v;
44710
+ }
44711
+ var BLOCK_META_KEYS = new Set([
44712
+ "type",
44713
+ "id",
44714
+ "parentBlockId",
44715
+ "toolCallId",
44716
+ "status",
44717
+ "results",
44718
+ "content",
44719
+ "modifiedContent",
44720
+ "originalContent",
44721
+ "error_message",
44722
+ "stacktrace",
44723
+ "runMeta",
44724
+ "runMode",
44725
+ "generationCompleted",
44726
+ "userId",
44727
+ "deviceId"
44728
+ ]);
44729
+ function blockToAnthropic(block, mode, format) {
44730
+ const t = block.type;
44731
+ if (t === "text")
44732
+ return [{ type: "text", text: block.content ?? "" }];
44733
+ if (t === "reason")
44734
+ return [{ type: "thinking", thinking: block.content ?? "" }];
44735
+ if (t === "error") {
44736
+ const msg = block.error_message || block.content || "(unknown error)";
44737
+ return [{ type: "text", text: `[error] ${msg}` }];
44738
+ }
44739
+ const inputFields = [];
44740
+ for (const [k, v] of Object.entries(block)) {
44741
+ if (BLOCK_META_KEYS.has(k))
44742
+ continue;
44743
+ if (v === undefined || v === null || v === "")
44744
+ continue;
44745
+ inputFields.push([k, v]);
44746
+ }
44747
+ const use = format === "anthropic" ? { type: "tool_use", id: block.id, name: t, input: Object.fromEntries(inputFields) } : { type: "tool_use", content: `<${t}${inputFields.map(([k, v]) => ` ${k}=${xmlAttr(v)}`).join("")}/>` };
44748
+ if (format === "compact" && mode !== "default")
44749
+ use.id = block.id;
44750
+ const items = [use];
44751
+ if (block.results?.length) {
44752
+ if (format === "anthropic") {
44753
+ const content = block.results.flatMap((r) => {
44754
+ const parts = [];
44755
+ for (const att of r.attachments ?? []) {
44756
+ const isImage = (att.mimeType || "").startsWith("image/");
44757
+ const isAutoName = /^(bash|read|list|explore|edit|write|grep):/.test(att.originalName ?? "");
44758
+ const source = { type: "uri", uri: att.uri, mimeType: att.mimeType, size: att.fileSize };
44759
+ if (att.originalName && !isAutoName)
44760
+ source.name = att.originalName;
44761
+ parts.push({ type: isImage ? "image" : "document", source });
44762
+ }
44763
+ if (typeof r.content === "string" && r.content)
44764
+ parts.push({ type: "text", text: r.content });
44765
+ return parts;
44766
+ });
44767
+ const result = { type: "tool_result", tool_use_id: block.id };
44768
+ if (content.length)
44769
+ result.content = content;
44770
+ if (block.status && block.status !== "COMPLETED")
44771
+ result.is_error = true;
44772
+ items.push(result);
44773
+ } else {
44774
+ const parts = [];
44775
+ for (const r of block.results) {
44776
+ for (const att of r.attachments ?? []) {
44777
+ const isAutoName = /^(bash|read|list|explore|edit|write|grep):/.test(att.originalName ?? "");
44778
+ const nameAttr = att.originalName && !isAutoName ? ` name=${xmlAttr(att.originalName)}` : "";
44779
+ parts.push(`<attachment uri=${xmlAttr(att.uri)}${nameAttr} size=${att.fileSize}/>`);
44780
+ }
44781
+ if (typeof r.content === "string" && r.content)
44782
+ parts.push(r.content);
44783
+ }
44784
+ const result = { type: "tool_result", content: parts.join(`
44785
+ `) };
44786
+ if (mode !== "default")
44787
+ result.tool_use_id = block.id;
44788
+ if (block.status && block.status !== "COMPLETED")
44789
+ result.status = block.status;
44790
+ items.push(result);
44791
+ }
44792
+ }
44793
+ return items;
44794
+ }
44795
+ function toAnthropicShape(messages, mode = "default", format = "compact") {
44796
+ const out = [];
44797
+ let prevToolAttachmentIds = new Set;
44798
+ for (const m of messages) {
44799
+ const msg = { role: m.role };
44800
+ if (mode !== "default") {
44801
+ if (m.id)
44802
+ msg.id = m.id;
44803
+ if (m.createdAt)
44804
+ msg.createdAt = m.createdAt;
44805
+ }
44806
+ if (m.role === "user") {
44807
+ const atts = (m.attachments ?? []).filter((a) => !prevToolAttachmentIds.has(a.id)).map((a) => {
44808
+ const isImage = (a.mimeType || "").startsWith("image/");
44809
+ return {
44810
+ type: isImage ? "image" : "document",
44811
+ source: { type: "uri", uri: a.uri, name: a.originalName, mimeType: a.mimeType, size: a.fileSize }
44812
+ };
44813
+ });
44814
+ const hadAttachments = (m.attachments ?? []).length > 0;
44815
+ if (!m.content && hadAttachments && atts.length === 0 && mode === "default") {
44816
+ prevToolAttachmentIds = new Set;
44817
+ continue;
44818
+ }
44819
+ if (atts.length === 0) {
44820
+ msg.content = m.content ?? "";
44821
+ } else {
44822
+ msg.content = [
44823
+ ...m.content ? [{ type: "text", text: m.content }] : [],
44824
+ ...atts
44825
+ ];
44826
+ }
44827
+ out.push(pruneEmpty(msg, mode));
44828
+ prevToolAttachmentIds = new Set;
44829
+ continue;
44830
+ }
44831
+ const content = [];
44832
+ if (m.content)
44833
+ content.push({ type: "text", text: m.content });
44834
+ for (const b of m.blocks ?? []) {
44835
+ for (const r of b.results ?? []) {
44836
+ for (const a of r.attachments ?? [])
44837
+ if (a.id)
44838
+ prevToolAttachmentIds.add(a.id);
44839
+ }
44840
+ }
44841
+ for (const b of m.blocks ?? [])
44842
+ content.push(...blockToAnthropic(b, mode, format));
44843
+ if (format === "anthropic") {
44844
+ const useItems = content.filter((c2) => c2.type !== "tool_result");
44845
+ const resultItems = content.filter((c2) => c2.type === "tool_result");
44846
+ msg.content = useItems;
44847
+ if (mode === "debug" && m.runMeta?.length)
44848
+ msg.runMeta = m.runMeta;
44849
+ out.push(pruneEmpty(msg, mode));
44850
+ if (resultItems.length) {
44851
+ out.push(pruneEmpty({ role: "user", content: resultItems }, mode));
44852
+ }
44853
+ } else {
44854
+ msg.content = content;
44855
+ if (mode === "debug" && m.runMeta?.length)
44856
+ msg.runMeta = m.runMeta;
44857
+ out.push(pruneEmpty(msg, mode));
44858
+ }
44859
+ }
44860
+ return out;
44861
+ }
44862
+ function applySlice(arr, spec) {
44863
+ if (!spec.includes(":")) {
44864
+ const i = Number(spec);
44865
+ if (!Number.isInteger(i))
44866
+ throw new Error(`Bad slice: '${spec}'`);
44867
+ const r = arr.at(i);
44868
+ return r === undefined ? [] : [r];
44869
+ }
44870
+ const parts = spec.split(":");
44871
+ if (parts.length !== 2)
44872
+ throw new Error(`Bad slice: '${spec}' (use N, N:, :N, or N:M)`);
44873
+ const [a, b] = parts;
44874
+ const start = a === "" ? 0 : Number(a);
44875
+ const end = b === "" ? arr.length : Number(b);
44876
+ if (!Number.isInteger(start) || !Number.isInteger(end))
44877
+ throw new Error(`Bad slice: '${spec}'`);
44878
+ return arr.slice(start, end);
44879
+ }
44880
+ var trunc = (s, n) => s.length > n ? s.slice(0, n) + `
44881
+ ${DIM}... (${s.length} chars)${RESET}` : s;
44882
+ var indent = (s, pre) => s.split(`
44883
+ `).join(`
44884
+ ${pre}`);
44885
+ function printFullChat(todo, frontendUrl, slice, mode = "default", format = "compact") {
43850
44886
  const statusColors = {
43851
44887
  DONE: GREEN,
43852
44888
  READY: GREEN,
@@ -43871,69 +44907,83 @@ function printFullChat(todo, frontendUrl, untilMessageId) {
43871
44907
  if (todo.agentSettingsId)
43872
44908
  process.stderr.write(`${DIM}Agent:${RESET} ${todo.agentSettingsId}
43873
44909
  `);
43874
- if (untilMessageId)
43875
- process.stderr.write(`${DIM}Until:${RESET} ${untilMessageId}
44910
+ if (slice)
44911
+ process.stderr.write(`${DIM}Slice:${RESET} [${slice}]
43876
44912
  `);
43877
44913
  process.stderr.write("\u2500".repeat(60) + `
43878
44914
  `);
43879
44915
  let messages = todo.messages || [];
43880
- if (untilMessageId) {
43881
- const idx = messages.findIndex((m) => m.id === untilMessageId);
43882
- if (idx < 0) {
43883
- process.stderr.write(`${RED}Error: message ${untilMessageId} not found in todo${RESET}
44916
+ if (slice) {
44917
+ try {
44918
+ messages = applySlice(messages, slice);
44919
+ } catch (e) {
44920
+ process.stderr.write(`${RED}${e.message}${RESET}
43884
44921
  `);
43885
44922
  process.exit(2);
43886
44923
  }
43887
- messages = messages.slice(0, idx + 1);
43888
44924
  }
43889
44925
  if (!messages.length) {
43890
44926
  process.stderr.write(`${DIM}(no messages)${RESET}
43891
44927
  `);
43892
44928
  return;
43893
44929
  }
43894
- for (const msg of messages) {
43895
- const roleLabel = msg.role === "user" ? `${CYAN}\u25B6 USER${RESET}` : `${GREEN}\u25C0 ASSISTANT${RESET}`;
44930
+ const shaped = toAnthropicShape(messages, mode, format);
44931
+ let toolUseCount = 0, errorCount = 0;
44932
+ for (let i = 0;i < shaped.length; i++) {
44933
+ const msg = shaped[i];
44934
+ const orig = messages[i];
44935
+ const ts = mode !== "default" && orig?.createdAt ? ` ${DIM}${new Date(orig.createdAt).toLocaleTimeString()}${RESET}` : "";
44936
+ const label = msg.role === "user" ? `${CYAN}\u25B6 USER${RESET}` : `${GREEN}\u25C0 ASSISTANT${RESET}`;
43896
44937
  process.stderr.write(`
43897
- ${roleLabel} ${DIM}${new Date(msg.createdAt).toLocaleTimeString()}${RESET}
44938
+ ${label}${ts}
43898
44939
  `);
43899
- if (msg.content) {
43900
- const content = msg.content.length > 2000 ? msg.content.slice(0, 2000) + `
43901
- ${DIM}... (${msg.content.length} chars total)${RESET}` : msg.content;
43902
- process.stdout.write(content + `
44940
+ const items = Array.isArray(msg.content) ? msg.content : [{ type: "text", text: msg.content }];
44941
+ for (const it of items) {
44942
+ if (it.type === "text") {
44943
+ if (it.text)
44944
+ process.stdout.write(trunc(it.text, 2000) + `
43903
44945
  `);
43904
- }
43905
- for (const block of msg.blocks || []) {
43906
- const blockStatusColor = block.status === "COMPLETED" ? GREEN : block.status === "ERROR" || block.status === "DENIED" ? RED : YELLOW;
43907
- process.stderr.write(`
43908
- ${YELLOW}[${block.type}]${RESET} ${blockStatusColor}${block.status}${RESET}`);
43909
- for (const key of ["path", "cmd", "name", "server_name", "tool_name"]) {
43910
- if (block[key])
43911
- process.stderr.write(` ${DIM}${key}=${RESET}${block[key]}`);
43912
- }
43913
- process.stderr.write(`
44946
+ } else if (it.type === "image" || it.type === "document") {
44947
+ const s = it.source ?? {};
44948
+ process.stderr.write(` ${YELLOW}[${it.type}]${RESET} ${DIM}${s.mimeType ?? ""}${RESET} ${s.name ?? ""} ${DIM}(${s.size ?? "?"} bytes)${RESET}
44949
+ ${DIM}${s.uri ?? ""}${RESET}
43914
44950
  `);
43915
- if (block.content) {
43916
- const content = block.content.length > 500 ? block.content.slice(0, 500) + `
43917
- ${DIM}... (${block.content.length} chars)${RESET}` : block.content;
43918
- process.stdout.write(` ${DIM}\u2502${RESET} ${content.split(`
43919
- `).join(`
43920
- ${DIM}\u2502${RESET} `)}
44951
+ } else if (it.type === "thinking") {
44952
+ if (it.thinking)
44953
+ process.stderr.write(`${DIM}[thinking]${RESET} ${trunc(it.thinking, 500)}
43921
44954
  `);
43922
- }
43923
- if (block.result) {
43924
- const result = block.result.length > 500 ? block.result.slice(0, 500) + `
43925
- ${DIM}... (${block.result.length} chars)${RESET}` : block.result;
43926
- process.stderr.write(` ${DIM}\u2514\u2500 result:${RESET} ${result.split(`
43927
- `).join(`
43928
- ${DIM}\u2502${RESET} `)}
44955
+ } else if (it.type === "tool_use") {
44956
+ toolUseCount++;
44957
+ if (it.content) {
44958
+ process.stderr.write(` ${YELLOW}${trunc(it.content, 200)}${RESET}
43929
44959
  `);
43930
- }
43931
- if (block.error_message) {
43932
- process.stderr.write(` ${RED}\u2514\u2500 error: ${block.error_message}${RESET}
44960
+ } else {
44961
+ const argStr = Object.entries(it.input || {}).map(([k, v]) => `${DIM}${k}=${RESET}${String(v).split(`
44962
+ `)[0].slice(0, 80)}`).join(" ");
44963
+ process.stderr.write(` ${YELLOW}[${it.name}]${RESET} ${argStr}
43933
44964
  `);
43934
- }
43935
- if (block.stacktrace) {
43936
- process.stderr.write(` ${DIM}${block.stacktrace.slice(0, 300)}${block.stacktrace.length > 300 ? "..." : ""}${RESET}
44965
+ }
44966
+ } else if (it.type === "tool_result") {
44967
+ const errLabel = it.is_error ? ` ${RED}ERROR${RESET}` : it.status && it.status !== "COMPLETED" ? ` ${RED}${it.status}${RESET}` : "";
44968
+ if (errLabel)
44969
+ errorCount++;
44970
+ const status = errLabel;
44971
+ let bodyStr;
44972
+ if (typeof it.content === "string")
44973
+ bodyStr = it.content;
44974
+ else {
44975
+ bodyStr = (it.content || []).map((c2) => {
44976
+ if (c2.type === "text")
44977
+ return c2.text ?? "";
44978
+ if (c2.type === "image" || c2.type === "document") {
44979
+ const s = c2.source ?? {};
44980
+ return `[${c2.type}] ${s.mimeType ?? ""}${s.name ? " " + s.name : ""} (${s.size ?? "?"} B) ${s.uri ?? ""}`;
44981
+ }
44982
+ return "";
44983
+ }).join(`
44984
+ `);
44985
+ }
44986
+ process.stderr.write(` ${DIM}\u2514\u2500 result:${RESET}${status} ${indent(trunc(bodyStr, 500), ` ${DIM}\u2502${RESET} `)}
43937
44987
  `);
43938
44988
  }
43939
44989
  }
@@ -43941,9 +44991,7 @@ ${DIM}... (${block.result.length} chars)${RESET}` : block.result;
43941
44991
  process.stderr.write(`
43942
44992
  ` + "\u2500".repeat(60) + `
43943
44993
  `);
43944
- const blockCount = messages.reduce((n, m) => n + (m.blocks?.length || 0), 0);
43945
- const errorBlocks = messages.reduce((n, m) => n + (m.blocks || []).filter((b) => b.status === "ERROR" || b.type === "error").length, 0);
43946
- process.stderr.write(`${DIM}Messages: ${messages.length} | Blocks: ${blockCount} | Errors: ${errorBlocks}${RESET}
44994
+ process.stderr.write(`${DIM}Messages: ${shaped.length} | Tool calls: ${toolUseCount} | Tool errors: ${errorCount}${RESET}
43947
44995
  `);
43948
44996
  }
43949
44997
 
@@ -44093,347 +45141,6 @@ Please choose an agent:
44093
45141
  })();
44094
45142
  }
44095
45143
 
44096
- // ../packages/shared-fbe/src/bashPatterns.ts
44097
- function splitShellCommands(input) {
44098
- const parts = [];
44099
- let current = "";
44100
- let i = 0;
44101
- const len = input.length;
44102
- while (i < len) {
44103
- const ch = input[i];
44104
- if (ch === "\\" && i + 1 < len && input[i + 1] === `
44105
- `) {
44106
- current += " ";
44107
- i += 2;
44108
- continue;
44109
- }
44110
- if (ch === "\\" && i + 1 < len) {
44111
- current += ch + input[i + 1];
44112
- i += 2;
44113
- continue;
44114
- }
44115
- if (ch === "<" && i + 1 < len && input[i + 1] === "<") {
44116
- i += 2;
44117
- if (i < len && input[i] === "-")
44118
- i++;
44119
- while (i < len && (input[i] === " " || input[i] === "\t"))
44120
- i++;
44121
- let delim = "";
44122
- if (i < len && (input[i] === "'" || input[i] === '"')) {
44123
- const q = input[i];
44124
- i++;
44125
- while (i < len && input[i] !== q) {
44126
- delim += input[i];
44127
- i++;
44128
- }
44129
- if (i < len)
44130
- i++;
44131
- } else {
44132
- while (i < len && /\w/.test(input[i])) {
44133
- delim += input[i];
44134
- i++;
44135
- }
44136
- }
44137
- if (delim) {
44138
- const rest = input.slice(i);
44139
- const m = rest.match(new RegExp(`^${delim}$`, "m"));
44140
- if (m && m.index !== undefined) {
44141
- i += m.index + delim.length;
44142
- } else {
44143
- i = len;
44144
- }
44145
- }
44146
- continue;
44147
- }
44148
- if (ch === "#" && (current.length === 0 || /\s$/.test(current))) {
44149
- while (i < len && input[i] !== `
44150
- `)
44151
- i++;
44152
- continue;
44153
- }
44154
- if (ch === '"' || ch === "'") {
44155
- const quote = ch;
44156
- current += ch;
44157
- i++;
44158
- while (i < len && input[i] !== quote) {
44159
- if (input[i] === "\\" && quote === '"' && i + 1 < len) {
44160
- current += input[i] + input[i + 1];
44161
- i += 2;
44162
- } else {
44163
- current += input[i];
44164
- i++;
44165
- }
44166
- }
44167
- if (i < len)
44168
- current += input[i];
44169
- i++;
44170
- continue;
44171
- }
44172
- if (ch === "|" && i + 1 < len && input[i + 1] === "|") {
44173
- parts.push(current);
44174
- current = "";
44175
- i += 2;
44176
- } else if (ch === "&" && i + 1 < len && input[i + 1] === "&") {
44177
- parts.push(current);
44178
- current = "";
44179
- i += 2;
44180
- } else if (ch === "|") {
44181
- parts.push(current);
44182
- current = "";
44183
- i++;
44184
- } else if (ch === ";" || ch === `
44185
- `) {
44186
- parts.push(current);
44187
- current = "";
44188
- i++;
44189
- } else {
44190
- current += ch;
44191
- i++;
44192
- }
44193
- }
44194
- parts.push(current);
44195
- return parts.map((s) => s.trim()).filter(Boolean);
44196
- }
44197
- function generalizeToken(token) {
44198
- if (/^\d+$/.test(token))
44199
- return "*";
44200
- if (/^[0-9a-f]{4,}$/i.test(token) && /\d/.test(token))
44201
- return "*";
44202
- if (/^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(token))
44203
- return "*";
44204
- if (/^https?:\/\//i.test(token)) {
44205
- try {
44206
- const u = new URL(token);
44207
- return `${u.protocol}//${u.host}/*`;
44208
- } catch {
44209
- return token;
44210
- }
44211
- }
44212
- return token;
44213
- }
44214
- var SAFE_FLAGS = new Set(["--help", "-h", "--version", "-V", "-v"]);
44215
- function splitTokens(cmd) {
44216
- const tokens = [];
44217
- let current = "";
44218
- let i = 0;
44219
- const len = cmd.length;
44220
- while (i < len) {
44221
- const ch = cmd[i];
44222
- if (ch === "\\" && i + 1 < len && cmd[i + 1] === `
44223
- `) {
44224
- i += 2;
44225
- continue;
44226
- }
44227
- if (ch === "\\" && i + 1 < len) {
44228
- current += ch + cmd[i + 1];
44229
- i += 2;
44230
- continue;
44231
- }
44232
- if (ch === '"' || ch === "'") {
44233
- const q = ch;
44234
- current += ch;
44235
- i++;
44236
- while (i < len && cmd[i] !== q) {
44237
- if (cmd[i] === "\\" && q === '"' && i + 1 < len) {
44238
- current += cmd[i] + cmd[i + 1];
44239
- i += 2;
44240
- } else {
44241
- current += cmd[i];
44242
- i++;
44243
- }
44244
- }
44245
- if (i < len) {
44246
- current += cmd[i];
44247
- i++;
44248
- }
44249
- continue;
44250
- }
44251
- if (/\s/.test(ch)) {
44252
- if (current) {
44253
- tokens.push(current);
44254
- current = "";
44255
- }
44256
- i++;
44257
- continue;
44258
- }
44259
- current += ch;
44260
- i++;
44261
- }
44262
- if (current)
44263
- tokens.push(current);
44264
- return tokens;
44265
- }
44266
- function parseSingle(cmd) {
44267
- const tokens = splitTokens(cmd);
44268
- while (tokens.length && /^[A-Za-z_]\w*=/.test(tokens[0])) {
44269
- const val = tokens[0].slice(tokens[0].indexOf("=") + 1);
44270
- if (/\$\(|`/.test(val))
44271
- return { tokens: [], defaultKeep: 0 };
44272
- tokens.shift();
44273
- }
44274
- if (tokens.length === 0)
44275
- return { tokens: [], defaultKeep: 0 };
44276
- if (tokens[0].startsWith("#"))
44277
- return { tokens: [], defaultKeep: 0 };
44278
- const positionals = [tokens[0]];
44279
- let hitFlag = false;
44280
- let defaultKeep = -1;
44281
- for (let t = 1;t < tokens.length; t++) {
44282
- if (!hitFlag && SAFE_FLAGS.has(tokens[t])) {
44283
- positionals.push(tokens[t]);
44284
- return { tokens: positionals, defaultKeep: positionals.length };
44285
- }
44286
- if (tokens[t].startsWith("-")) {
44287
- if (!hitFlag) {
44288
- hitFlag = true;
44289
- defaultKeep = Math.min(3, positionals.length);
44290
- }
44291
- positionals.push(tokens[t]);
44292
- continue;
44293
- }
44294
- const g = generalizeToken(tokens[t]);
44295
- positionals.push(g);
44296
- if (g !== tokens[t])
44297
- break;
44298
- }
44299
- if (defaultKeep < 0)
44300
- defaultKeep = Math.min(3, positionals.length);
44301
- return { tokens: positionals, defaultKeep };
44302
- }
44303
- function buildBashPattern(parsed, keep) {
44304
- if (parsed.tokens.length === 0)
44305
- return "BASH(cmd: *)";
44306
- const k = Math.max(1, Math.min(keep ?? parsed.defaultKeep, parsed.tokens.length));
44307
- const kept = parsed.tokens.slice(0, k);
44308
- const suffix = kept[kept.length - 1] === "*" ? "" : " *";
44309
- return `BASH(cmd: ${kept.join(" ")}${suffix})`;
44310
- }
44311
- function parseBashCmd(fullCmd) {
44312
- return splitShellCommands(fullCmd).map(parseSingle).filter((p) => p.tokens.length > 0);
44313
- }
44314
- function generalizeBashCmd(fullCmd) {
44315
- return parseBashCmd(fullCmd).map((p) => buildBashPattern(p));
44316
- }
44317
- function getBlockServerPrefix(block) {
44318
- const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
44319
- const prefixMatch = agentPattern.match(/^(.*?:)BASH(?:\(|$)/);
44320
- return prefixMatch ? prefixMatch[1] : "";
44321
- }
44322
- var BASH_LIKE_BLOCK_TYPES = new Set(["bash", "machine_exec"]);
44323
- function getBlockPatterns(block) {
44324
- if (Array.isArray(block.generalized_pattern))
44325
- return block.generalized_pattern;
44326
- const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
44327
- const isBashLike = BASH_LIKE_BLOCK_TYPES.has(block.type.toLowerCase()) || /:BASH(\(|$)/.test(agentPattern);
44328
- if (isBashLike && block.cmd) {
44329
- const prefix = getBlockServerPrefix(block);
44330
- return generalizeBashCmd(block.cmd).map((p) => prefix + p);
44331
- }
44332
- if (block.generalized_pattern)
44333
- return [block.generalized_pattern];
44334
- return [`${block.type}(*)`];
44335
- }
44336
- function getBlockServerId(block) {
44337
- const prefix = getBlockServerPrefix(block);
44338
- return prefix ? prefix.slice(0, -1) : "*";
44339
- }
44340
-
44341
- // ../packages/shared-fbe/src/permissionUtils.ts
44342
- function parsePattern(pattern) {
44343
- const colonIndex = pattern.indexOf(":");
44344
- if (colonIndex === -1)
44345
- return null;
44346
- const serverId = pattern.slice(0, colonIndex);
44347
- if (!/^[A-Za-z0-9_*-]+$/.test(serverId)) {
44348
- return { serverId: "*", toolName: pattern };
44349
- }
44350
- return { serverId, toolName: pattern.slice(colonIndex + 1) };
44351
- }
44352
- function serverIdMatches(ruleServerId, targetServerId) {
44353
- if (ruleServerId === targetServerId)
44354
- return true;
44355
- if (ruleServerId === "*")
44356
- return true;
44357
- if (ruleServerId.includes("*")) {
44358
- const escaped = ruleServerId.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
44359
- const regex = new RegExp("^" + escaped.replace(/\*/g, "[^:]*") + "$");
44360
- return regex.test(targetServerId);
44361
- }
44362
- if (targetServerId.startsWith(ruleServerId + "_"))
44363
- return true;
44364
- return false;
44365
- }
44366
- function patternMatches(rulePattern, targetPattern) {
44367
- const rule = parsePattern(rulePattern);
44368
- const target = parsePattern(targetPattern);
44369
- if (!rule || !target)
44370
- return rulePattern === targetPattern;
44371
- if (!serverIdMatches(rule.serverId, target.serverId))
44372
- return false;
44373
- if (rule.toolName === target.toolName)
44374
- return true;
44375
- if (rule.toolName === "*")
44376
- return true;
44377
- if (rule.toolName.endsWith(" *)")) {
44378
- const rulePrefix = rule.toolName.slice(0, -2);
44379
- return target.toolName.startsWith(rulePrefix);
44380
- }
44381
- return false;
44382
- }
44383
- function bashRuleMatchesCmd(rulePattern, serverId, cmd) {
44384
- const rule = parsePattern(rulePattern);
44385
- if (!rule)
44386
- return false;
44387
- if (!serverIdMatches(rule.serverId, serverId))
44388
- return false;
44389
- if (rule.toolName === "*" || rule.toolName === "BASH")
44390
- return true;
44391
- const m = rule.toolName.match(/^BASH\(cmd:\s*(.*)\)$/);
44392
- if (!m)
44393
- return false;
44394
- let body = m[1];
44395
- const isPrefix = body.endsWith(" *") || body.endsWith("*");
44396
- if (isPrefix)
44397
- body = body.replace(/\s*\*$/, "");
44398
- const subs = splitShellCommands(cmd);
44399
- if (subs.length === 0)
44400
- return false;
44401
- return subs.every((sub) => isPrefix ? sub === body || sub.startsWith(body + " ") : sub === body);
44402
- }
44403
- function isPatternInList(list, pattern) {
44404
- if (!list)
44405
- return false;
44406
- return list.some((p) => patternMatches(p, pattern));
44407
- }
44408
- function isPatternAllowed(permissions, pattern) {
44409
- return isPatternInList(permissions?.allow, pattern);
44410
- }
44411
- function getNewPatterns(patterns, permissions) {
44412
- return patterns.filter((p) => !isPatternAllowed(permissions, p));
44413
- }
44414
- function getBlockNewPatterns(block, permissions) {
44415
- const allow = permissions?.allow ?? [];
44416
- if (Array.isArray(block.generalized_pattern)) {
44417
- return getNewPatterns(block.generalized_pattern, permissions);
44418
- }
44419
- const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
44420
- const isBash = (block.type.toLowerCase() === "bash" || agentPattern.includes(":BASH(")) && !!block.cmd;
44421
- if (!isBash) {
44422
- return getBlockPatterns(block).filter((p) => !isPatternAllowed(permissions, p));
44423
- }
44424
- const serverId = getBlockServerId(block);
44425
- const prefix = serverId === "*" ? "" : `${serverId}:`;
44426
- const rawSubs = splitShellCommands(block.cmd);
44427
- const pairs = [];
44428
- for (const raw of rawSubs) {
44429
- const parsed = parseBashCmd(raw);
44430
- if (parsed.length === 0)
44431
- continue;
44432
- pairs.push({ raw, pattern: prefix + buildBashPattern(parsed[0]) });
44433
- }
44434
- return pairs.filter(({ raw, pattern }) => !isPatternAllowed(permissions, pattern) && !allow.some((rule) => bashRuleMatchesCmd(rule, serverId, raw))).map(({ pattern }) => pattern);
44435
- }
44436
-
44437
45144
  // src/diff-view.ts
44438
45145
  var import_diff_match_patch = __toESM(require_diff_match_patch(), 1);
44439
45146
  var import_cli_highlight = __toESM(require_dist(), 1);
@@ -44635,8 +45342,8 @@ function renderDiff(originalContent, modifiedContent, filePath) {
44635
45342
  return "";
44636
45343
  const visible = new Set;
44637
45344
  for (const idx of changed) {
44638
- for (let c = Math.max(0, idx - CONTEXT_LINES);c <= Math.min(lines.length - 1, idx + CONTEXT_LINES); c++) {
44639
- visible.add(c);
45345
+ for (let c2 = Math.max(0, idx - CONTEXT_LINES);c2 <= Math.min(lines.length - 1, idx + CONTEXT_LINES); c2++) {
45346
+ visible.add(c2);
44640
45347
  }
44641
45348
  }
44642
45349
  const parts = [`${CYAN}\u2500\u2500 ${filePath} \u2500\u2500${RESET}
@@ -44799,12 +45506,12 @@ ${YELLOW}Interrupting... (Ctrl+C again to force exit)${RESET}
44799
45506
  if (approvalPromptActive || pendingBlocks.length === 0)
44800
45507
  return;
44801
45508
  approvalPromptActive = true;
44802
- const blocks = pendingBlocks.splice(0).map((bi) => {
45509
+ const blocks3 = pendingBlocks.splice(0).map((bi) => {
44803
45510
  const latest = bi?.blockId ? blocksStore.get(bi.blockId) || {} : {};
44804
45511
  return { ...latest, ...bi };
44805
45512
  });
44806
45513
  if (approveAll) {
44807
- for (const bi of blocks) {
45514
+ for (const bi of blocks3) {
44808
45515
  const [tl, disp] = blockDisplay(bi);
44809
45516
  process.stderr.write(`
44810
45517
  ${YELLOW}\u26A0 Auto-approving [${tl}]${RESET} ${disp}
@@ -44817,14 +45524,14 @@ ${YELLOW}\u26A0 Auto-approving [${tl}]${RESET} ${disp}
44817
45524
  }
44818
45525
  return;
44819
45526
  }
44820
- activeApprovalBlocks = blocks;
44821
- const hasFileBlocks = blocks.some((bi) => ["create", "edit"].includes(classifyBlock(bi)));
45527
+ activeApprovalBlocks = blocks3;
45528
+ const hasFileBlocks = blocks3.some((bi) => ["create", "edit"].includes(classifyBlock(bi)));
44822
45529
  if (hasFileBlocks)
44823
45530
  await new Promise((r) => setTimeout(r, 1500));
44824
45531
  process.stderr.write(`
44825
- ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
45532
+ ${YELLOW}\u26A0 ${blocks3.length} action(s) awaiting approval:${RESET}
44826
45533
  `);
44827
- for (const bi of blocks) {
45534
+ for (const bi of blocks3) {
44828
45535
  const [tl, disp] = blockDisplay(bi);
44829
45536
  process.stderr.write(` ${YELLOW}[${tl}]${RESET} ${disp}
44830
45537
  `);
@@ -44841,7 +45548,7 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
44841
45548
  process.stderr.write(renderDiff(diff.originalContent, diff.modifiedContent, filePath));
44842
45549
  }
44843
45550
  }
44844
- const newPatterns = blocks.flatMap((bi) => getBlockNewPatterns({
45551
+ const newPatterns = blocks3.flatMap((bi) => getBlockNewPatterns({
44845
45552
  type: bi.block_type || "unknown",
44846
45553
  generalized_pattern: bi.generalized_pattern,
44847
45554
  cmd: bi.cmd
@@ -44855,7 +45562,7 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
44855
45562
  }
44856
45563
  if (response === "a" || response === "y" || response === "" || response === "r") {
44857
45564
  const decision = response === "r" ? "allow_remember" : "allow_once";
44858
- for (const bi of blocks) {
45565
+ for (const bi of blocks3) {
44859
45566
  let patterns;
44860
45567
  if (response === "r") {
44861
45568
  patterns = getBlockNewPatterns({
@@ -44871,14 +45578,14 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
44871
45578
  sendApproval(ws, bi.blockId, bi.messageId, todoId, decision, patterns);
44872
45579
  }
44873
45580
  } else {
44874
- for (const bi of blocks) {
45581
+ for (const bi of blocks3) {
44875
45582
  ws.sendBlockDeny(todoId, bi.messageId, bi.blockId);
44876
45583
  }
44877
45584
  process.stderr.write(` ${RED}\u2717 Denied${RESET}
44878
45585
  `);
44879
45586
  }
44880
45587
  } catch {
44881
- for (const bi of blocks) {
45588
+ for (const bi of blocks3) {
44882
45589
  sendApproval(ws, bi.blockId, bi.messageId, todoId);
44883
45590
  }
44884
45591
  }
@@ -45028,6 +45735,239 @@ async function listAgentsCommand(api, opts) {
45028
45735
  }
45029
45736
  }
45030
45737
 
45738
+ // src/agent-command.ts
45739
+ function printAgentHelp() {
45740
+ process.stderr.write(`
45741
+ todoai agent \u2014 inspect and update agent settings
45742
+
45743
+ Usage:
45744
+ todoai agent list List agents (name, model, id, paths)
45745
+ todoai agent get <agent> Show a single agent's settings
45746
+ todoai agent update <agent> <field=value>\u2026 Update one or more settings
45747
+
45748
+ <agent> is a name or id (unique partial name also works).
45749
+ Fields map directly to agent settings; values are parsed as JSON when possible
45750
+ (numbers, booleans), otherwise treated as strings. Common fields:
45751
+ model e.g. claude | anthropic:anthropic/claude-opus-4.8
45752
+ ('claude' is the rolling alias \u2192 latest Claude Opus)
45753
+ systemMessage freeform prompt text (alias: sysmsg)
45754
+ temperature number, e.g. 0.7
45755
+ thinkingLevel low | medium | high | xhigh | max
45756
+ name agent display name
45757
+
45758
+ Examples:
45759
+ todoai agent update <agent> model=claude
45760
+ todoai agent update <agent> model=anthropic:anthropic/claude-opus-4.8 temperature=0.5
45761
+ todoai agent update <agent> sysmsg="You are a terse video editor."
45762
+ `);
45763
+ }
45764
+ var FIELD_ALIASES = {
45765
+ sysmsg: "systemMessage",
45766
+ prompt: "systemMessage",
45767
+ temp: "temperature",
45768
+ thinking: "thinkingLevel"
45769
+ };
45770
+ function parseAssignment(arg) {
45771
+ const eq = arg.indexOf("=");
45772
+ if (eq < 1) {
45773
+ process.stderr.write(`${RED}Invalid field assignment '${arg}', expected field=value${RESET}
45774
+ `);
45775
+ process.exit(2);
45776
+ }
45777
+ const rawKey = arg.slice(0, eq);
45778
+ const key = FIELD_ALIASES[rawKey] || rawKey;
45779
+ const raw = arg.slice(eq + 1);
45780
+ try {
45781
+ return [key, JSON.parse(raw)];
45782
+ } catch {
45783
+ return [key, raw];
45784
+ }
45785
+ }
45786
+ function resolveAgent(agents, query) {
45787
+ const byId = agents.find((a) => getItemId(a) === query);
45788
+ if (byId)
45789
+ return byId;
45790
+ const q = query.toLowerCase();
45791
+ const exact = agents.filter((a) => getDisplayName(a).toLowerCase() === q);
45792
+ if (exact.length === 1)
45793
+ return exact[0];
45794
+ const partial = agents.filter((a) => getDisplayName(a).toLowerCase().includes(q));
45795
+ if (partial.length === 1)
45796
+ return partial[0];
45797
+ if (partial.length > 1) {
45798
+ process.stderr.write(`${RED}Ambiguous agent '${query}', matches:${RESET}
45799
+ `);
45800
+ for (const a of partial)
45801
+ process.stderr.write(` ${getDisplayName(a)} ${DIM}${getItemId(a)}${RESET}
45802
+ `);
45803
+ process.exit(2);
45804
+ }
45805
+ process.stderr.write(`${RED}No agent matching '${query}'${RESET}
45806
+ `);
45807
+ process.exit(2);
45808
+ }
45809
+ async function agentCommand(api, positionals, args, formatPath) {
45810
+ const sub = positionals[1];
45811
+ if (!sub || sub === "list" || sub === "ls") {
45812
+ await listAgentsCommand(api, { json: !!args.json, formatPath });
45813
+ return;
45814
+ }
45815
+ if (sub === "get") {
45816
+ const agents = await api.listAgentSettings();
45817
+ const agent = resolveAgent(agents, positionals[2] || "");
45818
+ if (args.json) {
45819
+ console.log(JSON.stringify(agent, null, 2));
45820
+ return;
45821
+ }
45822
+ process.stderr.write(`${BRAND}${getDisplayName(agent)}${RESET} ${DIM}${getItemId(agent)}${RESET}
45823
+ `);
45824
+ process.stderr.write(` ${DIM}model:${RESET} ${CYAN}${agent.model || "(default)"}${RESET}
45825
+ `);
45826
+ const paths = getAgentWorkspacePaths(agent).map(formatPath);
45827
+ if (paths.length)
45828
+ process.stderr.write(` ${DIM}paths:${RESET} ${paths.join(", ")}
45829
+ `);
45830
+ return;
45831
+ }
45832
+ if (sub === "update") {
45833
+ const query = positionals[2];
45834
+ const assignments = positionals.slice(3);
45835
+ if (!query || !assignments.length) {
45836
+ process.stderr.write(`${RED}Usage: todoai agent update <name|id> <field=value>\u2026${RESET}
45837
+ `);
45838
+ process.exit(2);
45839
+ }
45840
+ const updates = Object.fromEntries(assignments.map(parseAssignment));
45841
+ const agents = await api.listAgentSettings();
45842
+ const agent = resolveAgent(agents, query);
45843
+ const id = getItemId(agent);
45844
+ const updated = await api.updateAgentSettings(id, id, updates);
45845
+ if (args.json) {
45846
+ console.log(JSON.stringify(updated, null, 2));
45847
+ return;
45848
+ }
45849
+ const summary = Object.keys(updates).map((k) => `${k}=${JSON.stringify(updated[k])}`).join(" ");
45850
+ process.stderr.write(`${GREEN}\u2705 ${getDisplayName(agent)} updated: ${summary}${RESET}
45851
+ `);
45852
+ return;
45853
+ }
45854
+ process.stderr.write(`${RED}Unknown 'agent' subcommand: ${sub}${RESET}
45855
+ `);
45856
+ printAgentHelp();
45857
+ process.exit(2);
45858
+ }
45859
+
45860
+ // src/list-todos.ts
45861
+ import { parseArgs as parseArgs2 } from "util";
45862
+ var STATUS_COLOR = {
45863
+ DONE: GREEN,
45864
+ READY: GREEN,
45865
+ READY_CHECKED: GREEN,
45866
+ ERROR: RED,
45867
+ ERROR_CHECKED: RED,
45868
+ CANCELLED: RED,
45869
+ CANCELLED_CHECKED: RED,
45870
+ RUNNING: YELLOW,
45871
+ STOPPING: YELLOW,
45872
+ COMPACTING: YELLOW,
45873
+ REVIEW_REQUESTED: YELLOW,
45874
+ TODO: CYAN,
45875
+ SCHEDULED: CYAN,
45876
+ POSTPONED: CYAN,
45877
+ PAUSED: CYAN
45878
+ };
45879
+ var CLOSED = new Set([
45880
+ "DONE",
45881
+ "READY_CHECKED",
45882
+ "CANCELLED",
45883
+ "CANCELLED_CHECKED",
45884
+ "ERROR_CHECKED",
45885
+ "ARCHIVED",
45886
+ "DELETED"
45887
+ ]);
45888
+ var VALID_STATUS = new Set(Object.values(TodoStatus));
45889
+ var isOpen = (s) => !CLOSED.has(s);
45890
+ function printHelp() {
45891
+ process.stderr.write(`
45892
+ todoai list \u2014 list todos in a project (recent first)
45893
+
45894
+ Usage:
45895
+ todoai list [flags]
45896
+
45897
+ Flags:
45898
+ -n, --limit <n> Max rows to show (default: 30)
45899
+ -s, --status <S[,S2]> Filter by status (comma-separated, union).
45900
+ -A, --all Include DONE (also CANCELLED, ARCHIVED, \u2026)
45901
+ --project <id> Project ID (default: current default project)
45902
+ --json Output raw JSON
45903
+ -h, --help Show this help
45904
+
45905
+ Examples:
45906
+ todoai list # 30 most recent open todos
45907
+ todoai list -n 50 # last 50 open
45908
+ todoai list --all # include DONE
45909
+ todoai list -s RUNNING,REVIEW_REQUESTED
45910
+ todoai list --json | jq '.[].id'
45911
+ `);
45912
+ }
45913
+ async function listTodosCommand(api, defaultProjectId, argv) {
45914
+ const { values } = parseArgs2({
45915
+ args: argv,
45916
+ options: {
45917
+ limit: { type: "string", short: "n" },
45918
+ status: { type: "string", short: "s" },
45919
+ all: { type: "boolean", short: "A", default: false },
45920
+ project: { type: "string" },
45921
+ json: { type: "boolean", default: false },
45922
+ help: { type: "boolean", short: "h", default: false }
45923
+ },
45924
+ strict: true
45925
+ });
45926
+ if (values.help) {
45927
+ printHelp();
45928
+ return;
45929
+ }
45930
+ const projectId = values.project || defaultProjectId;
45931
+ if (!projectId) {
45932
+ process.stderr.write(`${RED}Error: no project (pass --project <id> or set a default)${RESET}
45933
+ `);
45934
+ process.exit(1);
45935
+ }
45936
+ const limit = values.limit ? Math.max(1, Number(values.limit)) : 30;
45937
+ const requested = values.status ? String(values.status).split(",").map((s) => s.trim().toUpperCase()).filter(Boolean) : null;
45938
+ const wantOpen = !!requested?.some((s) => s === "OPEN" || !VALID_STATUS.has(s));
45939
+ const wanted = requested ? new Set(requested.filter((s) => VALID_STATUS.has(s))) : null;
45940
+ const includeClosed = !!values.all || !!wanted && wanted.size > 0;
45941
+ const todos = await api.listTodos(projectId);
45942
+ let rows = todos.filter((t) => includeClosed || !CLOSED.has(String(t.status).toUpperCase())).filter((t) => {
45943
+ if (!requested)
45944
+ return true;
45945
+ const s = String(t.status).toUpperCase();
45946
+ return wantOpen && isOpen(s) || (wanted?.has(s) ?? false);
45947
+ }).sort((a, b) => (b.lastActivityAt ?? b.createdAt ?? 0) - (a.lastActivityAt ?? a.createdAt ?? 0)).slice(0, limit);
45948
+ if (values.json) {
45949
+ process.stdout.write(JSON.stringify(rows, null, 2) + `
45950
+ `);
45951
+ return;
45952
+ }
45953
+ if (!rows.length) {
45954
+ process.stderr.write(`${DIM}(no todos)${RESET}
45955
+ `);
45956
+ return;
45957
+ }
45958
+ const statusW = rows.reduce((n, r) => Math.max(n, String(r.status).length), 0);
45959
+ for (const t of rows) {
45960
+ const sc = STATUS_COLOR[t.status] || DIM;
45961
+ const ts = new Date(t.lastActivityAt ?? t.createdAt).toISOString().slice(0, 16).replace("T", " ");
45962
+ const title = String(t.content ?? "").split(`
45963
+ `)[0].slice(0, 100);
45964
+ process.stdout.write(`${sc}${String(t.status).padEnd(statusW)}${RESET} ${DIM}${ts}${RESET} ${t.id} ${title}
45965
+ `);
45966
+ }
45967
+ process.stderr.write(`${DIM}${rows.length} todo(s)${RESET}
45968
+ `);
45969
+ }
45970
+
45031
45971
  // src/ensure-edge.ts
45032
45972
  import { spawn, spawnSync } from "child_process";
45033
45973
  import fs2 from "fs";
@@ -45171,7 +46111,15 @@ Cancelled by user (Ctrl+C)
45171
46111
  console.log(VERSION);
45172
46112
  process.exit(0);
45173
46113
  }
45174
- if (args.help) {
46114
+ if (positionals[0] === "status" && args.help) {
46115
+ printStatusHelp();
46116
+ process.exit(0);
46117
+ }
46118
+ if (positionals[0] === "agent" && args.help) {
46119
+ printAgentHelp();
46120
+ process.exit(0);
46121
+ }
46122
+ if (args.help && !["list", "ls", "agent"].includes(positionals[0])) {
45175
46123
  printUsage();
45176
46124
  process.exit(0);
45177
46125
  }
@@ -45247,26 +46195,100 @@ Cancelled by user (Ctrl+C)
45247
46195
  await deviceLogin();
45248
46196
  return;
45249
46197
  }
45250
- let apiKey = args["api-key"] || getEnv("API_TOKEN") || getEnv("API_KEY") || readCredential(apiUrl) || "";
46198
+ let apiKey = args["api-key"] || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
45251
46199
  if (!apiKey) {
45252
46200
  apiKey = await deviceLogin();
45253
46201
  }
45254
46202
  const api = new ApiClient(apiUrl, apiKey);
46203
+ if (positionals[0] === "status") {
46204
+ const [, todoId, status] = positionals;
46205
+ if (!todoId || !status) {
46206
+ printStatusHelp();
46207
+ process.exit(2);
46208
+ }
46209
+ await api.updateTodoStatus(todoId, status);
46210
+ process.stderr.write(`${GREEN}\u2705 Status of ${todoId} set to ${status}${RESET}
46211
+ `);
46212
+ return;
46213
+ }
46214
+ if (positionals[0] === "delete") {
46215
+ const todoId = positionals[1];
46216
+ if (!todoId) {
46217
+ process.stderr.write(`${RED}Usage: todoai delete <todo-id>${RESET}
46218
+ `);
46219
+ process.exit(2);
46220
+ }
46221
+ await api.deleteTodo(todoId);
46222
+ process.stderr.write(`${GREEN}\u2705 Deleted ${todoId}${RESET}
46223
+ `);
46224
+ return;
46225
+ }
46226
+ if (positionals[0] === "addmessage") {
46227
+ const [, todoId, ...rest] = positionals;
46228
+ const content2 = rest.join(" ") || await readStdin();
46229
+ if (!todoId || !content2) {
46230
+ process.stderr.write(`${RED}Usage: todoai addmessage <todo-id> "content"${RESET}
46231
+ `);
46232
+ process.exit(2);
46233
+ }
46234
+ const todo2 = await api.getTodo(todoId);
46235
+ const msg = await api.addMessage(todo2.projectId, content2, todo2.agentSettings || { id: todo2.agentSettingsId }, todoId);
46236
+ if (args.json)
46237
+ console.log(JSON.stringify(msg, null, 2));
46238
+ else
46239
+ process.stderr.write(`${GREEN}\u2705 Message added to ${todoId}${RESET}
46240
+ `);
46241
+ return;
46242
+ }
45255
46243
  if (args["list-agents"]) {
45256
46244
  await listAgentsCommand(api, { json: !!args.json, formatPath: formatPathWithTilde });
45257
46245
  return;
45258
46246
  }
46247
+ if (positionals[0] === "agent") {
46248
+ await agentCommand(api, positionals, args, formatPathWithTilde);
46249
+ return;
46250
+ }
46251
+ if (positionals[0] === "list" || positionals[0] === "ls") {
46252
+ let defaultProjectId = args.project || cfgScope.data.default_project_id;
46253
+ if (!defaultProjectId) {
46254
+ const projects2 = await api.listProjects();
46255
+ defaultProjectId = projects2.find((p) => p.project?.isDefault)?.project?.id || projects2[0]?.project?.id;
46256
+ }
46257
+ const sub = process.argv.slice(process.argv.indexOf(positionals[0]) + 1);
46258
+ await listTodosCommand(api, defaultProjectId ?? undefined, sub);
46259
+ return;
46260
+ }
45259
46261
  if (args.inspect !== undefined) {
45260
46262
  const raw = String(args.inspect);
45261
- const [rawTodoId, untilMessageId] = raw.includes(":") ? raw.split(":", 2) : [raw, undefined];
45262
- const todoId = rawTodoId || getEnv("TODO_ID");
46263
+ const at = raw.indexOf("@");
46264
+ const todoId = at < 0 ? raw : raw.slice(0, at);
46265
+ const slice = at < 0 ? undefined : raw.slice(at + 1);
45263
46266
  if (!todoId) {
45264
- process.stderr.write(`${RED}Error: --inspect requires a todoId (or $TODOFORAI_TODO_ID env var)${RESET}
46267
+ process.stderr.write(`${RED}Error: --inspect requires a todoId${RESET}
45265
46268
  `);
45266
46269
  process.exit(2);
45267
46270
  }
45268
46271
  const todo2 = await api.getTodo(todoId);
45269
- printFullChat(todo2, getFrontendUrl(apiUrl, todo2.projectId, todoId), untilMessageId || undefined);
46272
+ if (args.json) {
46273
+ let messages = todo2.messages || [];
46274
+ if (slice) {
46275
+ try {
46276
+ messages = applySlice(messages, slice);
46277
+ } catch (e) {
46278
+ process.stderr.write(`${RED}${e.message}${RESET}
46279
+ `);
46280
+ process.exit(2);
46281
+ }
46282
+ }
46283
+ const mode2 = args.debug ? "debug" : args.detailed ? "detailed" : "default";
46284
+ const format2 = args["format-anthropic"] ? "anthropic" : "compact";
46285
+ process.stdout.write(JSON.stringify(toAnthropicShape(messages, mode2, format2), null, 2) + `
46286
+ `);
46287
+ return;
46288
+ }
46289
+ const mode = args.debug ? "debug" : args.detailed ? "detailed" : "default";
46290
+ const format = args["format-anthropic"] ? "anthropic" : "compact";
46291
+ printFullChat(todo2, getFrontendUrl(apiUrl, todo2.projectId, todoId), slice, mode, format);
45270
46292
  return;
45271
46293
  }
45272
46294
  if (process.stderr.isTTY)
@@ -45370,7 +46392,7 @@ ${"\u2500".repeat(40)}
45370
46392
  }
45371
46393
  const todo2 = await api.getTodo(todoId);
45372
46394
  const projectId2 = todo2.projectId;
45373
- const agent2 = todo2.agentSettings || { name: "default" };
46395
+ const agent2 = todo2.agentSettings || await api.getAgentSettings(todo2.agentSettingsId);
45374
46396
  for (const msg of todo2.messages || []) {
45375
46397
  const role = msg.role === "user" ? `${CYAN}You${RESET}` : `${GREEN}AI${RESET}`;
45376
46398
  process.stderr.write(`${role}: ${(msg.content || "").slice(0, 200)}
@@ -45378,11 +46400,20 @@ ${"\u2500".repeat(40)}
45378
46400
  }
45379
46401
  process.stderr.write(`
45380
46402
  ${"\u2500".repeat(40)}
45381
- Resumed todo: ${todoId}
46403
+ Resumed: ${CYAN}${getFrontendUrl(apiUrl, projectId2, todoId)}${RESET}
45382
46404
  `);
45383
46405
  const ws2 = new FrontendWebSocket(apiUrl, apiKey);
45384
46406
  await ws2.connect();
45385
- await interactiveLoop(ws2, api, todoId, projectId2, agent2, !!args.json, false, cfg);
46407
+ const autoApprove = !!args["dangerously-skip-permissions"];
46408
+ const followUp = positionals.length > 0 ? positionals.join(" ") : process.stdin.isTTY ? "" : await readStdin();
46409
+ if (followUp) {
46410
+ cfg.addToHistory(followUp);
46411
+ await api.addMessage(projectId2, followUp, agent2, todoId);
46412
+ await watchTodo(ws2, todoId, projectId2, { json: !!args.json, autoApprove, agentSettings: agent2 });
46413
+ }
46414
+ if (!args["non-interactive"]) {
46415
+ await interactiveLoop(ws2, api, todoId, projectId2, agent2, !!args.json, autoApprove, cfg);
46416
+ }
45386
46417
  await ws2.close();
45387
46418
  return;
45388
46419
  }