@todoforai/cli 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/todoai.js +1558 -508
- 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(
|
|
2028
|
-
return expandOrCloneMode(
|
|
2027
|
+
mode.contains = [].concat(...mode.contains.map(function(c2) {
|
|
2028
|
+
return expandOrCloneMode(c2 === "self" ? mode : c2);
|
|
2029
2029
|
}));
|
|
2030
|
-
mode.contains.forEach(function(
|
|
2031
|
-
compileMode(
|
|
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
|
|
2689
|
-
|
|
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
|
|
2702
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
15886
|
+
const STRING_MODE = function(c2) {
|
|
15887
15887
|
return {
|
|
15888
15888
|
className: "string",
|
|
15889
|
-
begin: "~?" +
|
|
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:
|
|
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(
|
|
41185
|
-
return (v -
|
|
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
|
|
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 [
|
|
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
|
|
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,
|
|
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
|
|
41507
|
-
return [l,
|
|
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
|
|
41511
|
+
const c2 = lch[1];
|
|
41512
41512
|
const h = lch[2];
|
|
41513
41513
|
const hr = h / 360 * 2 * Math.PI;
|
|
41514
|
-
const a =
|
|
41515
|
-
const b =
|
|
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
|
|
41568
|
-
return [
|
|
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
|
|
41629
|
+
const c2 = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
|
|
41630
41630
|
let f = 0;
|
|
41631
|
-
if (
|
|
41632
|
-
f = (l - 0.5 *
|
|
41631
|
+
if (c2 < 1) {
|
|
41632
|
+
f = (l - 0.5 * c2) / (1 - c2);
|
|
41633
41633
|
}
|
|
41634
|
-
return [hsl[0],
|
|
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
|
|
41639
|
+
const c2 = s * v;
|
|
41640
41640
|
let f = 0;
|
|
41641
|
-
if (
|
|
41642
|
-
f = (v -
|
|
41641
|
+
if (c2 < 1) {
|
|
41642
|
+
f = (v - c2) / (1 - c2);
|
|
41643
41643
|
}
|
|
41644
|
-
return [hsv[0],
|
|
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
|
|
41648
|
+
const c2 = hcg[1] / 100;
|
|
41649
41649
|
const g = hcg[2] / 100;
|
|
41650
|
-
if (
|
|
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 -
|
|
41689
|
+
mg = (1 - c2) * g;
|
|
41690
41690
|
return [
|
|
41691
|
-
(
|
|
41692
|
-
(
|
|
41693
|
-
(
|
|
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
|
|
41697
|
+
const c2 = hcg[1] / 100;
|
|
41698
41698
|
const g = hcg[2] / 100;
|
|
41699
|
-
const v =
|
|
41699
|
+
const v = c2 + g * (1 - c2);
|
|
41700
41700
|
let f = 0;
|
|
41701
41701
|
if (v > 0) {
|
|
41702
|
-
f =
|
|
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
|
|
41707
|
+
const c2 = hcg[1] / 100;
|
|
41708
41708
|
const g = hcg[2] / 100;
|
|
41709
|
-
const l = g * (1 -
|
|
41709
|
+
const l = g * (1 - c2) + 0.5 * c2;
|
|
41710
41710
|
let s = 0;
|
|
41711
41711
|
if (l > 0 && l < 0.5) {
|
|
41712
|
-
s =
|
|
41712
|
+
s = c2 / (2 * l);
|
|
41713
41713
|
} else if (l >= 0.5 && l < 1) {
|
|
41714
|
-
s =
|
|
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
|
|
41719
|
+
const c2 = hcg[1] / 100;
|
|
41720
41720
|
const g = hcg[2] / 100;
|
|
41721
|
-
const v =
|
|
41722
|
-
return [hcg[0], (v -
|
|
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
|
|
41728
|
+
const c2 = v - w;
|
|
41729
41729
|
let g = 0;
|
|
41730
|
-
if (
|
|
41731
|
-
g = (v -
|
|
41730
|
+
if (c2 < 1) {
|
|
41731
|
+
g = (v - c2) / (1 - c2);
|
|
41732
41732
|
}
|
|
41733
|
-
return [hwb[0],
|
|
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(
|
|
42198
|
-
const u =
|
|
42199
|
-
const bracket =
|
|
42200
|
-
if (u && !bracket &&
|
|
42201
|
-
return String.fromCharCode(parseInt(
|
|
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(
|
|
42204
|
+
return String.fromCodePoint(parseInt(c2.slice(2, -1), 16));
|
|
42205
42205
|
}
|
|
42206
|
-
return ESCAPES.get(
|
|
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("
|
|
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,802 @@ 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
|
+
var SCOPE_BUILTIN = "builtin";
|
|
43711
|
+
var SCOPE_DEVICE = "device";
|
|
43712
|
+
var SCOPE_CLOUD = "cloud";
|
|
43713
|
+
var isDeviceId = (s) => s !== "*" && s !== SCOPE_BUILTIN && s !== SCOPE_DEVICE && s !== SCOPE_CLOUD && !s.includes("*");
|
|
43714
|
+
function serverIdMatches(ruleServerId, targetServerId, ctx) {
|
|
43715
|
+
if (ruleServerId === targetServerId)
|
|
43716
|
+
return true;
|
|
43717
|
+
if (ruleServerId === "*")
|
|
43718
|
+
return true;
|
|
43719
|
+
if (ruleServerId === SCOPE_DEVICE)
|
|
43720
|
+
return isDeviceId(targetServerId);
|
|
43721
|
+
if (ruleServerId === SCOPE_CLOUD)
|
|
43722
|
+
return !!ctx?.primaryCloudId && targetServerId === ctx.primaryCloudId;
|
|
43723
|
+
if (ruleServerId.includes("*")) {
|
|
43724
|
+
const escaped = ruleServerId.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
43725
|
+
const regex = new RegExp("^" + escaped.replace(/\*/g, "[^:]*") + "$");
|
|
43726
|
+
return regex.test(targetServerId);
|
|
43727
|
+
}
|
|
43728
|
+
if (targetServerId.startsWith(ruleServerId + "_"))
|
|
43729
|
+
return true;
|
|
43730
|
+
return false;
|
|
43731
|
+
}
|
|
43732
|
+
function patternMatches(rulePattern, targetPattern, ctx) {
|
|
43733
|
+
const rule = parsePattern(rulePattern);
|
|
43734
|
+
const target = parsePattern(targetPattern);
|
|
43735
|
+
if (!rule || !target)
|
|
43736
|
+
return rulePattern === targetPattern;
|
|
43737
|
+
if (!serverIdMatches(rule.serverId, target.serverId, ctx))
|
|
43738
|
+
return false;
|
|
43739
|
+
if (rule.toolName === target.toolName)
|
|
43740
|
+
return true;
|
|
43741
|
+
if (rule.toolName === "*")
|
|
43742
|
+
return true;
|
|
43743
|
+
if (rule.toolName.endsWith(" *)")) {
|
|
43744
|
+
const rulePrefix = rule.toolName.slice(0, -2);
|
|
43745
|
+
return target.toolName.startsWith(rulePrefix);
|
|
43746
|
+
}
|
|
43747
|
+
return false;
|
|
43748
|
+
}
|
|
43749
|
+
function bashRuleMatchesCmd(rulePattern, serverId, cmd) {
|
|
43750
|
+
const rule = parsePattern(rulePattern);
|
|
43751
|
+
if (!rule)
|
|
43752
|
+
return false;
|
|
43753
|
+
if (!serverIdMatches(rule.serverId, serverId))
|
|
43754
|
+
return false;
|
|
43755
|
+
if (rule.toolName === "*" || rule.toolName === "BASH")
|
|
43756
|
+
return true;
|
|
43757
|
+
const m = rule.toolName.match(/^BASH\(cmd:\s*(.*)\)$/);
|
|
43758
|
+
if (!m)
|
|
43759
|
+
return false;
|
|
43760
|
+
let body = m[1];
|
|
43761
|
+
const isPrefix = body.endsWith(" *") || body.endsWith("*");
|
|
43762
|
+
if (isPrefix)
|
|
43763
|
+
body = body.replace(/\s*\*$/, "");
|
|
43764
|
+
const subs = splitShellCommands(cmd);
|
|
43765
|
+
if (subs.length === 0)
|
|
43766
|
+
return false;
|
|
43767
|
+
return subs.every((sub) => isPrefix ? sub === body || sub.startsWith(body + " ") : sub === body);
|
|
43768
|
+
}
|
|
43769
|
+
function isPatternInList(list, pattern) {
|
|
43770
|
+
if (!list)
|
|
43771
|
+
return false;
|
|
43772
|
+
return list.some((p) => patternMatches(p, pattern));
|
|
43773
|
+
}
|
|
43774
|
+
function isPatternAllowed(permissions, pattern) {
|
|
43775
|
+
return isPatternInList(permissions?.allow, pattern);
|
|
43776
|
+
}
|
|
43777
|
+
function getNewPatterns(patterns, permissions) {
|
|
43778
|
+
return patterns.filter((p) => !isPatternAllowed(permissions, p));
|
|
43779
|
+
}
|
|
43780
|
+
function getBlockNewPatterns(block, permissions) {
|
|
43781
|
+
const allow = permissions?.allow ?? [];
|
|
43782
|
+
if (Array.isArray(block.generalized_pattern)) {
|
|
43783
|
+
return getNewPatterns(block.generalized_pattern, permissions);
|
|
43784
|
+
}
|
|
43785
|
+
const agentPattern = typeof block.generalized_pattern === "string" ? block.generalized_pattern : "";
|
|
43786
|
+
const isBash = (block.type.toLowerCase() === "bash" || agentPattern.includes(":BASH(")) && !!block.cmd;
|
|
43787
|
+
if (!isBash) {
|
|
43788
|
+
return getBlockPatterns(block).filter((p) => !isPatternAllowed(permissions, p));
|
|
43789
|
+
}
|
|
43790
|
+
const serverId = getBlockServerId(block);
|
|
43791
|
+
const prefix = serverId === "*" ? "" : `${serverId}:`;
|
|
43792
|
+
const rawSubs = splitShellCommands(block.cmd);
|
|
43793
|
+
const pairs = [];
|
|
43794
|
+
for (const raw of rawSubs) {
|
|
43795
|
+
const parsed = parseBashCmd(raw);
|
|
43796
|
+
if (parsed.length === 0)
|
|
43797
|
+
continue;
|
|
43798
|
+
pairs.push({ raw, pattern: prefix + buildBashPattern(parsed[0]) });
|
|
43799
|
+
}
|
|
43800
|
+
return pairs.filter(({ raw, pattern }) => !isPatternAllowed(permissions, pattern) && !allow.some((rule) => bashRuleMatchesCmd(rule, serverId, raw))).map(({ pattern }) => pattern);
|
|
43801
|
+
}
|
|
43802
|
+
// ../packages/shared-fbe/src/outputLimits.ts
|
|
43803
|
+
var MAX_LINE_LEN = 300;
|
|
43804
|
+
var STREAM_FIRST = 1e4;
|
|
43805
|
+
var STREAM_LAST = 1e4;
|
|
43806
|
+
var RUN_OUTPUT_CAP = 256 * 1024;
|
|
43807
|
+
var OUTPUT_POLICIES = {
|
|
43808
|
+
safe: { firstLimit: STREAM_FIRST, lastLimit: STREAM_LAST, hardCap: STREAM_FIRST + STREAM_LAST, lineLimit: MAX_LINE_LEN },
|
|
43809
|
+
wide: { firstLimit: STREAM_FIRST, lastLimit: STREAM_LAST, hardCap: STREAM_FIRST + STREAM_LAST, lineLimit: Infinity },
|
|
43810
|
+
full: { firstLimit: Infinity, lastLimit: 0, hardCap: RUN_OUTPUT_CAP, lineLimit: MAX_LINE_LEN },
|
|
43811
|
+
raw: { firstLimit: Infinity, lastLimit: 0, hardCap: Infinity, lineLimit: Infinity }
|
|
43812
|
+
};
|
|
43813
|
+
// ../packages/shared-fbe/src/realtime/topics.ts
|
|
43814
|
+
var TOPICS = {
|
|
43815
|
+
["todo:new" /* NEW_TODO */]: {
|
|
43816
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.new_todo(p.projectId),
|
|
43817
|
+
audience: "frontend"
|
|
43818
|
+
},
|
|
43819
|
+
["todo:new_message" /* TODO_NEW_MESSAGE */]: {
|
|
43820
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.new_message(p.projectId),
|
|
43821
|
+
audience: "frontend"
|
|
43822
|
+
},
|
|
43823
|
+
["todo:new_message_created" /* TODO_NEW_MESSAGE_CREATED */]: {
|
|
43824
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.new_message(p.todoId),
|
|
43825
|
+
audience: "frontend"
|
|
43826
|
+
},
|
|
43827
|
+
["business_context:updated" /* BUSINESS_CONTEXT_UPDATED */]: {
|
|
43828
|
+
channel: (p) => SERVER_TO_FRONTENDS.businessContext.updated(p.userId),
|
|
43829
|
+
audience: "frontend"
|
|
43830
|
+
},
|
|
43831
|
+
["resource:content_updated" /* RESOURCE_CONTENT_UPDATED */]: {
|
|
43832
|
+
channel: (p) => SERVER_TO_FRONTENDS.resource.contentUpdated(p.userId),
|
|
43833
|
+
audience: "frontend"
|
|
43834
|
+
},
|
|
43835
|
+
["hexgrid:updated" /* HEXGRID_UPDATED */]: {
|
|
43836
|
+
channel: (p) => SERVER_TO_FRONTENDS.hexGrid.updated(p.projectId),
|
|
43837
|
+
audience: "frontend"
|
|
43838
|
+
},
|
|
43839
|
+
["sandbox:state" /* SANDBOX_STATE */]: {
|
|
43840
|
+
channel: (p) => SERVER_TO_FRONTENDS.sandbox.state(p.userId),
|
|
43841
|
+
audience: "frontend"
|
|
43842
|
+
},
|
|
43843
|
+
["device:status" /* DEVICE_STATUS */]: {
|
|
43844
|
+
channel: (p) => SERVER_TO_FRONTENDS.device.status(p.userId),
|
|
43845
|
+
audience: "frontend"
|
|
43846
|
+
},
|
|
43847
|
+
["NOTIFY" /* NOTIFY */]: {
|
|
43848
|
+
channel: (p) => p.userId ? SERVER_TO_FRONTENDS.notify.user(p.userId) : SERVER_TO_FRONTENDS.todo.notify(p.todoId),
|
|
43849
|
+
audience: "frontend"
|
|
43850
|
+
},
|
|
43851
|
+
["todo:msg_done" /* TODO_MSG_DONE */]: {
|
|
43852
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.msgDone(p.todoId),
|
|
43853
|
+
audience: "frontend"
|
|
43854
|
+
},
|
|
43855
|
+
["block:start_universal" /* BLOCK_START_UNIVERSAL */]: {
|
|
43856
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.start_universal(p.todoId),
|
|
43857
|
+
audience: "frontend"
|
|
43858
|
+
},
|
|
43859
|
+
["block:message" /* BLOCK_MESSAGE */]: {
|
|
43860
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.message(p.todoId),
|
|
43861
|
+
audience: "frontend"
|
|
43862
|
+
},
|
|
43863
|
+
["BLOCK_UPDATE" /* BLOCK_UPDATE */]: {
|
|
43864
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.block_update(p.todoId),
|
|
43865
|
+
audience: "frontend"
|
|
43866
|
+
},
|
|
43867
|
+
["block:end" /* BLOCK_END */]: {
|
|
43868
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.end(p.todoId),
|
|
43869
|
+
audience: "frontend"
|
|
43870
|
+
},
|
|
43871
|
+
["todo:msg_start" /* TODO_MSG_START */]: {
|
|
43872
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.msgStart(p.todoId),
|
|
43873
|
+
audience: "frontend"
|
|
43874
|
+
},
|
|
43875
|
+
["todo:msg_meta_ai" /* TODO_MSG_META_AI */]: {
|
|
43876
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.msgMetaAi(p.todoId),
|
|
43877
|
+
audience: "frontend"
|
|
43878
|
+
},
|
|
43879
|
+
["todo:msg_meta_usr" /* TODO_MSG_META_USR */]: {
|
|
43880
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.msgMetaUsr(p.todoId),
|
|
43881
|
+
audience: "frontend"
|
|
43882
|
+
},
|
|
43883
|
+
["todo:msg_stop_sequence" /* TODO_MSG_STOP_SEQUENCE */]: {
|
|
43884
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.msgStopSequence(p.todoId),
|
|
43885
|
+
audience: "frontend"
|
|
43886
|
+
},
|
|
43887
|
+
["block:diff_result" /* BLOCK_DIFF_RESULT */]: {
|
|
43888
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.diff_result(p.todoId),
|
|
43889
|
+
audience: "frontend"
|
|
43890
|
+
},
|
|
43891
|
+
["frontend:file_chunk_result" /* FRONTEND_FILE_CHUNK_RESULT */]: {
|
|
43892
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.frontend_file_chunk_result(p.todoId),
|
|
43893
|
+
audience: "frontend"
|
|
43894
|
+
},
|
|
43895
|
+
["block:save_result" /* BLOCK_SAVE_RESULT */]: {
|
|
43896
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.save_result(p.todoId),
|
|
43897
|
+
audience: "frontend"
|
|
43898
|
+
},
|
|
43899
|
+
["block:sh_msg_start" /* BLOCK_SH_MSG_START */]: {
|
|
43900
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_start_result(p.todoId),
|
|
43901
|
+
audience: "frontend"
|
|
43902
|
+
},
|
|
43903
|
+
["block:sh_msg_result" /* BLOCK_SH_MSG_RESULT */]: {
|
|
43904
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_result(p.todoId),
|
|
43905
|
+
audience: "frontend"
|
|
43906
|
+
},
|
|
43907
|
+
["block:sh_done" /* BLOCK_SH_DONE */]: {
|
|
43908
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.sh_msg_done_result(p.todoId),
|
|
43909
|
+
audience: "frontend"
|
|
43910
|
+
},
|
|
43911
|
+
["edge:status" /* EDGE_STATUS */]: {
|
|
43912
|
+
channel: (p) => SERVER_TO_FRONTENDS.edge.status(p.userId),
|
|
43913
|
+
audience: "frontend"
|
|
43914
|
+
},
|
|
43915
|
+
["EDGE_CONFIG_UPDATE" /* EDGE_CONFIG_UPDATE */]: {
|
|
43916
|
+
channel: (p) => SERVER_TO_FRONTENDS.edge.configUpdate(p.ownerId),
|
|
43917
|
+
audience: "frontend"
|
|
43918
|
+
},
|
|
43919
|
+
["project:status" /* PROJECT_STATUS */]: {
|
|
43920
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.status(p.projectId),
|
|
43921
|
+
audience: "frontend"
|
|
43922
|
+
},
|
|
43923
|
+
["todo:status" /* TODO_STATUS */]: {
|
|
43924
|
+
channel: (p) => SERVER_TO_FRONTENDS.todo.status(p.todoId),
|
|
43925
|
+
audience: "frontend"
|
|
43926
|
+
},
|
|
43927
|
+
["payment:status" /* PAYMENT_STATUS */]: {
|
|
43928
|
+
channel: (p) => SERVER_TO_FRONTENDS.payment.status(p.userId),
|
|
43929
|
+
audience: "frontend"
|
|
43930
|
+
},
|
|
43931
|
+
["payment:webhook" /* PAYMENT_WEBHOOK */]: {
|
|
43932
|
+
channel: (p) => SERVER_TO_FRONTENDS.payment.status(p.userId),
|
|
43933
|
+
audience: "frontend"
|
|
43934
|
+
}
|
|
43935
|
+
};
|
|
43138
43936
|
// src/args.ts
|
|
43139
43937
|
var DEFAULT_API_URL = "https://api.todofor.ai";
|
|
43140
43938
|
var VERSION = package_default.version;
|
|
@@ -43151,12 +43949,16 @@ Usage:
|
|
|
43151
43949
|
todoai -n "Quick task" # Non-interactive (run and exit)
|
|
43152
43950
|
echo "content" | todoai # Pipe from stdin
|
|
43153
43951
|
todoai --path /my/project "Fix bug" # Explicit workspace path
|
|
43154
|
-
todoai -c
|
|
43155
|
-
todoai --resume <todo-id>
|
|
43156
|
-
todoai --inspect <todo-id>[
|
|
43157
|
-
todoai --inspect :<msg-id> # Same, using $TODOFORAI_TODO_ID from edge env
|
|
43952
|
+
todoai -c ["prompt"] # Resume last todo (optional prompt sent on attach)
|
|
43953
|
+
todoai --resume <todo-id> ["prompt"] # Resume specific todo (optional prompt sent on attach)
|
|
43954
|
+
todoai --inspect <todo-id>[@<slice>] # Read chat log. <slice> = -3:, :1, 5:10, 7 (Python-style)
|
|
43158
43955
|
todoai --template <id> [--input k=v] # Start from a registry template
|
|
43159
43956
|
todoai --list-agents # List available agents and exit
|
|
43957
|
+
todoai agent update <agent> model=<model> # Update agent settings (see 'agent --help')
|
|
43958
|
+
todoai list [-n 30] [--all] [--status S] # List todos (open + recent first); see 'list --help'
|
|
43959
|
+
todoai status <todo-id> <STATUS> # Update a todo's status (run 'status --help' for the full list)
|
|
43960
|
+
todoai delete <todo-id> # Permanently delete a todo
|
|
43961
|
+
todoai addmessage <todo-id> "text" # Add a message to an existing todo
|
|
43160
43962
|
|
|
43161
43963
|
Options:
|
|
43162
43964
|
--path <dir> Workspace path (default: cwd)
|
|
@@ -43165,7 +43967,7 @@ Options:
|
|
|
43165
43967
|
--list-agents List available agents (name, id, workspace paths) and exit
|
|
43166
43968
|
--api-url <url> API URL
|
|
43167
43969
|
--api-key <key> API key
|
|
43168
|
-
--inspect, -i
|
|
43970
|
+
--inspect, -i <todo-id>[@<slice>] Print chat log (read-only)
|
|
43169
43971
|
--template, -t <id> Start from a registry template
|
|
43170
43972
|
--input <key=value> Template input (repeatable)
|
|
43171
43973
|
--resume, -r [todo-id] Resume existing todo
|
|
@@ -43176,6 +43978,8 @@ Options:
|
|
|
43176
43978
|
--no-watch Create todo and exit
|
|
43177
43979
|
--no-edge Do not auto-spawn edge daemon
|
|
43178
43980
|
--json Output as JSON
|
|
43981
|
+
--detailed 'inspect --json': keep ids, timestamps, agentSettingsId, scheduledTimestamp
|
|
43982
|
+
--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
43983
|
--safe Validate API key upfront
|
|
43180
43984
|
--debug, -d Debug output
|
|
43181
43985
|
--show-config Show config
|
|
@@ -43184,6 +43988,27 @@ Options:
|
|
|
43184
43988
|
--help, -h Show this help
|
|
43185
43989
|
`);
|
|
43186
43990
|
}
|
|
43991
|
+
var STATUS_HELP = {
|
|
43992
|
+
["READY" /* READY */]: "AI finished the work on the TODO",
|
|
43993
|
+
["READY_CHECKED" /* READY_CHECKED */]: "AI finished and the user reviewed it",
|
|
43994
|
+
["DONE" /* DONE */]: "Completed and finalized",
|
|
43995
|
+
["REVIEW_REQUESTED" /* REVIEW_REQUESTED */]: "Asks the user to review",
|
|
43996
|
+
["POSTPONED" /* POSTPONED */]: "Put off for later",
|
|
43997
|
+
["ARCHIVED" /* ARCHIVED */]: "Archived (hidden from active list)",
|
|
43998
|
+
["DELETED" /* DELETED */]: "Marked for deletion"
|
|
43999
|
+
};
|
|
44000
|
+
function printStatusHelp() {
|
|
44001
|
+
process.stderr.write(`
|
|
44002
|
+
todoai status <todo-id> <STATUS>
|
|
44003
|
+
|
|
44004
|
+
Common statuses:
|
|
44005
|
+
${Object.entries(STATUS_HELP).map(([s, d]) => ` ${s.padEnd(18)}${d}`).join(`
|
|
44006
|
+
`)}
|
|
44007
|
+
|
|
44008
|
+
All valid statuses:
|
|
44009
|
+
${Object.values(TodoStatus).join(", ")}
|
|
44010
|
+
`);
|
|
44011
|
+
}
|
|
43187
44012
|
function parseCliArgs() {
|
|
43188
44013
|
const { values, positionals } = parseArgs({
|
|
43189
44014
|
args: process.argv.slice(2),
|
|
@@ -43191,6 +44016,7 @@ function parseCliArgs() {
|
|
|
43191
44016
|
path: { type: "string", default: "." },
|
|
43192
44017
|
project: { type: "string" },
|
|
43193
44018
|
agent: { type: "string", short: "a" },
|
|
44019
|
+
model: { type: "string" },
|
|
43194
44020
|
"list-agents": { type: "boolean", default: false },
|
|
43195
44021
|
"api-url": { type: "string" },
|
|
43196
44022
|
"api-key": { type: "string" },
|
|
@@ -43205,6 +44031,8 @@ function parseCliArgs() {
|
|
|
43205
44031
|
"no-watch": { type: "boolean", default: false },
|
|
43206
44032
|
"no-edge": { type: "boolean", default: false },
|
|
43207
44033
|
json: { type: "boolean", default: false },
|
|
44034
|
+
detailed: { type: "boolean", default: false },
|
|
44035
|
+
"format-anthropic": { type: "boolean", default: false },
|
|
43208
44036
|
safe: { type: "boolean", default: false },
|
|
43209
44037
|
debug: { type: "boolean", short: "d", default: false },
|
|
43210
44038
|
"show-config": { type: "boolean", default: false },
|
|
@@ -43223,21 +44051,23 @@ function parseCliArgs() {
|
|
|
43223
44051
|
import { createInterface } from "readline";
|
|
43224
44052
|
|
|
43225
44053
|
// src/colors.ts
|
|
43226
|
-
var
|
|
43227
|
-
var
|
|
43228
|
-
var
|
|
43229
|
-
var
|
|
43230
|
-
var
|
|
43231
|
-
var
|
|
43232
|
-
var
|
|
43233
|
-
var
|
|
43234
|
-
var
|
|
43235
|
-
var
|
|
43236
|
-
var
|
|
43237
|
-
var
|
|
43238
|
-
var
|
|
43239
|
-
var
|
|
43240
|
-
var
|
|
44054
|
+
var on = !process.env.NO_COLOR && !!process.stdout.isTTY;
|
|
44055
|
+
var c = (seq) => on ? seq : "";
|
|
44056
|
+
var YELLOW = c("\x1B[33m");
|
|
44057
|
+
var GREEN = c("\x1B[32m");
|
|
44058
|
+
var RED = c("\x1B[31m");
|
|
44059
|
+
var DIM = c("\x1B[90m");
|
|
44060
|
+
var CYAN = c("\x1B[36m");
|
|
44061
|
+
var BOLD = c("\x1B[1m");
|
|
44062
|
+
var WHITE = c("\x1B[38;2;255;255;255m");
|
|
44063
|
+
var BRIGHT_WHITE = c("\x1B[97m");
|
|
44064
|
+
var BRAND = c("\x1B[38;2;249;110;46m");
|
|
44065
|
+
var RESET = c("\x1B[0m");
|
|
44066
|
+
var DIM_ATTR = c("\x1B[2m");
|
|
44067
|
+
var BG_RED = c("\x1B[48;2;55;20;20m");
|
|
44068
|
+
var BG_GREEN = c("\x1B[48;2;20;45;20m");
|
|
44069
|
+
var BG_RED_HL = c("\x1B[48;2;100;35;35m");
|
|
44070
|
+
var BG_GREEN_HL = c("\x1B[48;2;35;85;35m");
|
|
43241
44071
|
|
|
43242
44072
|
// src/input.ts
|
|
43243
44073
|
function readLine(prompt) {
|
|
@@ -43475,26 +44305,26 @@ function readMultiline(prompt, history) {
|
|
|
43475
44305
|
const ps = s.indexOf("\x1B[200~");
|
|
43476
44306
|
const chunk = ps >= 0 ? s.slice(0, ps) : s;
|
|
43477
44307
|
for (let i = 0;i < chunk.length && !done; i++) {
|
|
43478
|
-
const
|
|
43479
|
-
if (
|
|
44308
|
+
const c2 = chunk.charCodeAt(i);
|
|
44309
|
+
if (c2 === 3) {
|
|
43480
44310
|
finish(true);
|
|
43481
44311
|
return;
|
|
43482
44312
|
}
|
|
43483
|
-
if (
|
|
44313
|
+
if (c2 === 13 || c2 === 10) {
|
|
43484
44314
|
finish(false);
|
|
43485
44315
|
return;
|
|
43486
44316
|
}
|
|
43487
|
-
if (
|
|
44317
|
+
if (c2 === 23) {
|
|
43488
44318
|
deleteWordBack();
|
|
43489
|
-
} else if (
|
|
44319
|
+
} else if (c2 === 11) {
|
|
43490
44320
|
killToEnd();
|
|
43491
|
-
} else if (
|
|
44321
|
+
} else if (c2 === 127 || c2 === 8) {
|
|
43492
44322
|
if (cursor > 0) {
|
|
43493
44323
|
buf = buf.slice(0, cursor - 1) + buf.slice(cursor);
|
|
43494
44324
|
cursor--;
|
|
43495
44325
|
redraw();
|
|
43496
44326
|
}
|
|
43497
|
-
} else if (
|
|
44327
|
+
} else if (c2 === 27) {
|
|
43498
44328
|
if (i + 1 < chunk.length && chunk.charCodeAt(i + 1) === 13) {
|
|
43499
44329
|
buf = buf.slice(0, cursor) + `
|
|
43500
44330
|
` + buf.slice(cursor);
|
|
@@ -43504,13 +44334,13 @@ function readMultiline(prompt, history) {
|
|
|
43504
44334
|
} else {
|
|
43505
44335
|
i = handleCSI(chunk, i) - 1;
|
|
43506
44336
|
}
|
|
43507
|
-
} else if (
|
|
44337
|
+
} else if (c2 === 1) {
|
|
43508
44338
|
cursor = 0;
|
|
43509
44339
|
redraw();
|
|
43510
|
-
} else if (
|
|
44340
|
+
} else if (c2 === 5) {
|
|
43511
44341
|
cursor = buf.length;
|
|
43512
44342
|
redraw();
|
|
43513
|
-
} else if (
|
|
44343
|
+
} else if (c2 >= 32) {
|
|
43514
44344
|
buf = buf.slice(0, cursor) + chunk[i] + buf.slice(cursor);
|
|
43515
44345
|
cursor++;
|
|
43516
44346
|
redraw();
|
|
@@ -43787,11 +44617,11 @@ var LETTERS = {
|
|
|
43787
44617
|
var GAP = " ";
|
|
43788
44618
|
var WORD = "todo4ai";
|
|
43789
44619
|
function renderHalfBlock(top, bot) {
|
|
43790
|
-
const W = "\x1B[38;2;249;110;46m";
|
|
43791
|
-
const G = "\x1B[38;2;140;60;20m";
|
|
43792
|
-
const BW = "\x1B[48;2;249;110;46m";
|
|
43793
|
-
const BG = "\x1B[48;2;140;60;20m";
|
|
43794
|
-
const R = "\x1B[0m";
|
|
44620
|
+
const W = c("\x1B[38;2;249;110;46m");
|
|
44621
|
+
const G = c("\x1B[38;2;140;60;20m");
|
|
44622
|
+
const BW = c("\x1B[48;2;249;110;46m");
|
|
44623
|
+
const BG = c("\x1B[48;2;140;60;20m");
|
|
44624
|
+
const R = c("\x1B[0m");
|
|
43795
44625
|
if (top === " " && bot === " ")
|
|
43796
44626
|
return " ";
|
|
43797
44627
|
if (top === bot) {
|
|
@@ -43846,7 +44676,232 @@ function printLogo() {
|
|
|
43846
44676
|
}
|
|
43847
44677
|
|
|
43848
44678
|
// src/inspect.ts
|
|
43849
|
-
|
|
44679
|
+
var xmlAttr = (v) => JSON.stringify(String(v));
|
|
44680
|
+
var DROP_IF_EMPTY = new Set(["runMeta", "meta", "attachments", "blocks"]);
|
|
44681
|
+
var ALWAYS_DROP = new Set(["messageIds", "data"]);
|
|
44682
|
+
var DETAILED_ONLY = new Set([
|
|
44683
|
+
"id",
|
|
44684
|
+
"createdAt",
|
|
44685
|
+
"lastActivityAt",
|
|
44686
|
+
"modifiedAt",
|
|
44687
|
+
"agentSettingsId",
|
|
44688
|
+
"scheduledTimestamp",
|
|
44689
|
+
"workflowVersion",
|
|
44690
|
+
"todoId",
|
|
44691
|
+
"blockId",
|
|
44692
|
+
"parentBlockId",
|
|
44693
|
+
"stop_sequence",
|
|
44694
|
+
"permissions",
|
|
44695
|
+
"isPublic",
|
|
44696
|
+
"metadata"
|
|
44697
|
+
]);
|
|
44698
|
+
var DEBUG_ONLY = new Set([
|
|
44699
|
+
"runMeta",
|
|
44700
|
+
"generationCompleted",
|
|
44701
|
+
"userId",
|
|
44702
|
+
"deviceId",
|
|
44703
|
+
"runMode"
|
|
44704
|
+
]);
|
|
44705
|
+
var isEmpty = (x) => Array.isArray(x) && x.length === 0 || x && typeof x === "object" && !Array.isArray(x) && Object.keys(x).length === 0;
|
|
44706
|
+
function pruneEmpty(v, mode = "default") {
|
|
44707
|
+
if (Array.isArray(v))
|
|
44708
|
+
return v.map((x) => pruneEmpty(x, mode));
|
|
44709
|
+
if (v && typeof v === "object") {
|
|
44710
|
+
const o = {};
|
|
44711
|
+
for (const [k, raw] of Object.entries(v)) {
|
|
44712
|
+
if (ALWAYS_DROP.has(k))
|
|
44713
|
+
continue;
|
|
44714
|
+
if (DEBUG_ONLY.has(k) && mode !== "debug")
|
|
44715
|
+
continue;
|
|
44716
|
+
if (DETAILED_ONLY.has(k) && mode === "default")
|
|
44717
|
+
continue;
|
|
44718
|
+
if (raw === "")
|
|
44719
|
+
continue;
|
|
44720
|
+
if (k === "scheduledTimestamp" && (raw === 0 || raw === 1))
|
|
44721
|
+
continue;
|
|
44722
|
+
if (DROP_IF_EMPTY.has(k) && isEmpty(raw))
|
|
44723
|
+
continue;
|
|
44724
|
+
o[k] = pruneEmpty(raw, mode);
|
|
44725
|
+
}
|
|
44726
|
+
return o;
|
|
44727
|
+
}
|
|
44728
|
+
return v;
|
|
44729
|
+
}
|
|
44730
|
+
var BLOCK_META_KEYS = new Set([
|
|
44731
|
+
"type",
|
|
44732
|
+
"id",
|
|
44733
|
+
"parentBlockId",
|
|
44734
|
+
"toolCallId",
|
|
44735
|
+
"status",
|
|
44736
|
+
"results",
|
|
44737
|
+
"content",
|
|
44738
|
+
"modifiedContent",
|
|
44739
|
+
"originalContent",
|
|
44740
|
+
"error_message",
|
|
44741
|
+
"stacktrace",
|
|
44742
|
+
"runMeta",
|
|
44743
|
+
"runMode",
|
|
44744
|
+
"generationCompleted",
|
|
44745
|
+
"userId",
|
|
44746
|
+
"deviceId"
|
|
44747
|
+
]);
|
|
44748
|
+
function blockToAnthropic(block, mode, format) {
|
|
44749
|
+
const t = block.type;
|
|
44750
|
+
if (t === "text")
|
|
44751
|
+
return [{ type: "text", text: block.content ?? "" }];
|
|
44752
|
+
if (t === "reason")
|
|
44753
|
+
return [{ type: "thinking", thinking: block.content ?? "" }];
|
|
44754
|
+
if (t === "error") {
|
|
44755
|
+
const msg = block.error_message || block.content || "(unknown error)";
|
|
44756
|
+
return [{ type: "text", text: `[error] ${msg}` }];
|
|
44757
|
+
}
|
|
44758
|
+
const inputFields = [];
|
|
44759
|
+
for (const [k, v] of Object.entries(block)) {
|
|
44760
|
+
if (BLOCK_META_KEYS.has(k))
|
|
44761
|
+
continue;
|
|
44762
|
+
if (v === undefined || v === null || v === "")
|
|
44763
|
+
continue;
|
|
44764
|
+
inputFields.push([k, v]);
|
|
44765
|
+
}
|
|
44766
|
+
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("")}/>` };
|
|
44767
|
+
if (format === "compact" && mode !== "default")
|
|
44768
|
+
use.id = block.id;
|
|
44769
|
+
const items = [use];
|
|
44770
|
+
if (block.results?.length) {
|
|
44771
|
+
if (format === "anthropic") {
|
|
44772
|
+
const content = block.results.flatMap((r) => {
|
|
44773
|
+
const parts = [];
|
|
44774
|
+
for (const att of r.attachments ?? []) {
|
|
44775
|
+
const isImage = (att.mimeType || "").startsWith("image/");
|
|
44776
|
+
const isAutoName = /^(bash|read|list|explore|edit|write|grep):/.test(att.originalName ?? "");
|
|
44777
|
+
const source = { type: "uri", uri: att.uri, mimeType: att.mimeType, size: att.fileSize };
|
|
44778
|
+
if (att.originalName && !isAutoName)
|
|
44779
|
+
source.name = att.originalName;
|
|
44780
|
+
parts.push({ type: isImage ? "image" : "document", source });
|
|
44781
|
+
}
|
|
44782
|
+
if (typeof r.content === "string" && r.content)
|
|
44783
|
+
parts.push({ type: "text", text: r.content });
|
|
44784
|
+
return parts;
|
|
44785
|
+
});
|
|
44786
|
+
const result = { type: "tool_result", tool_use_id: block.id };
|
|
44787
|
+
if (content.length)
|
|
44788
|
+
result.content = content;
|
|
44789
|
+
if (block.status && block.status !== "COMPLETED")
|
|
44790
|
+
result.is_error = true;
|
|
44791
|
+
items.push(result);
|
|
44792
|
+
} else {
|
|
44793
|
+
const parts = [];
|
|
44794
|
+
for (const r of block.results) {
|
|
44795
|
+
for (const att of r.attachments ?? []) {
|
|
44796
|
+
const isAutoName = /^(bash|read|list|explore|edit|write|grep):/.test(att.originalName ?? "");
|
|
44797
|
+
const nameAttr = att.originalName && !isAutoName ? ` name=${xmlAttr(att.originalName)}` : "";
|
|
44798
|
+
parts.push(`<attachment uri=${xmlAttr(att.uri)}${nameAttr} size=${att.fileSize}/>`);
|
|
44799
|
+
}
|
|
44800
|
+
if (typeof r.content === "string" && r.content)
|
|
44801
|
+
parts.push(r.content);
|
|
44802
|
+
}
|
|
44803
|
+
const result = { type: "tool_result", content: parts.join(`
|
|
44804
|
+
`) };
|
|
44805
|
+
if (mode !== "default")
|
|
44806
|
+
result.tool_use_id = block.id;
|
|
44807
|
+
if (block.status && block.status !== "COMPLETED")
|
|
44808
|
+
result.status = block.status;
|
|
44809
|
+
items.push(result);
|
|
44810
|
+
}
|
|
44811
|
+
}
|
|
44812
|
+
return items;
|
|
44813
|
+
}
|
|
44814
|
+
function toAnthropicShape(messages, mode = "default", format = "compact") {
|
|
44815
|
+
const out = [];
|
|
44816
|
+
let prevToolAttachmentIds = new Set;
|
|
44817
|
+
for (const m of messages) {
|
|
44818
|
+
const msg = { role: m.role };
|
|
44819
|
+
if (mode !== "default") {
|
|
44820
|
+
if (m.id)
|
|
44821
|
+
msg.id = m.id;
|
|
44822
|
+
if (m.createdAt)
|
|
44823
|
+
msg.createdAt = m.createdAt;
|
|
44824
|
+
}
|
|
44825
|
+
if (m.role === "user") {
|
|
44826
|
+
const atts = (m.attachments ?? []).filter((a) => !prevToolAttachmentIds.has(a.id)).map((a) => {
|
|
44827
|
+
const isImage = (a.mimeType || "").startsWith("image/");
|
|
44828
|
+
return {
|
|
44829
|
+
type: isImage ? "image" : "document",
|
|
44830
|
+
source: { type: "uri", uri: a.uri, name: a.originalName, mimeType: a.mimeType, size: a.fileSize }
|
|
44831
|
+
};
|
|
44832
|
+
});
|
|
44833
|
+
const hadAttachments = (m.attachments ?? []).length > 0;
|
|
44834
|
+
if (!m.content && hadAttachments && atts.length === 0 && mode === "default") {
|
|
44835
|
+
prevToolAttachmentIds = new Set;
|
|
44836
|
+
continue;
|
|
44837
|
+
}
|
|
44838
|
+
if (atts.length === 0) {
|
|
44839
|
+
msg.content = m.content ?? "";
|
|
44840
|
+
} else {
|
|
44841
|
+
msg.content = [
|
|
44842
|
+
...m.content ? [{ type: "text", text: m.content }] : [],
|
|
44843
|
+
...atts
|
|
44844
|
+
];
|
|
44845
|
+
}
|
|
44846
|
+
out.push(pruneEmpty(msg, mode));
|
|
44847
|
+
prevToolAttachmentIds = new Set;
|
|
44848
|
+
continue;
|
|
44849
|
+
}
|
|
44850
|
+
const content = [];
|
|
44851
|
+
if (m.content)
|
|
44852
|
+
content.push({ type: "text", text: m.content });
|
|
44853
|
+
for (const b of m.blocks ?? []) {
|
|
44854
|
+
for (const r of b.results ?? []) {
|
|
44855
|
+
for (const a of r.attachments ?? [])
|
|
44856
|
+
if (a.id)
|
|
44857
|
+
prevToolAttachmentIds.add(a.id);
|
|
44858
|
+
}
|
|
44859
|
+
}
|
|
44860
|
+
for (const b of m.blocks ?? [])
|
|
44861
|
+
content.push(...blockToAnthropic(b, mode, format));
|
|
44862
|
+
if (format === "anthropic") {
|
|
44863
|
+
const useItems = content.filter((c2) => c2.type !== "tool_result");
|
|
44864
|
+
const resultItems = content.filter((c2) => c2.type === "tool_result");
|
|
44865
|
+
msg.content = useItems;
|
|
44866
|
+
if (mode === "debug" && m.runMeta?.length)
|
|
44867
|
+
msg.runMeta = m.runMeta;
|
|
44868
|
+
out.push(pruneEmpty(msg, mode));
|
|
44869
|
+
if (resultItems.length) {
|
|
44870
|
+
out.push(pruneEmpty({ role: "user", content: resultItems }, mode));
|
|
44871
|
+
}
|
|
44872
|
+
} else {
|
|
44873
|
+
msg.content = content;
|
|
44874
|
+
if (mode === "debug" && m.runMeta?.length)
|
|
44875
|
+
msg.runMeta = m.runMeta;
|
|
44876
|
+
out.push(pruneEmpty(msg, mode));
|
|
44877
|
+
}
|
|
44878
|
+
}
|
|
44879
|
+
return out;
|
|
44880
|
+
}
|
|
44881
|
+
function applySlice(arr, spec) {
|
|
44882
|
+
if (!spec.includes(":")) {
|
|
44883
|
+
const i = Number(spec);
|
|
44884
|
+
if (!Number.isInteger(i))
|
|
44885
|
+
throw new Error(`Bad slice: '${spec}'`);
|
|
44886
|
+
const r = arr.at(i);
|
|
44887
|
+
return r === undefined ? [] : [r];
|
|
44888
|
+
}
|
|
44889
|
+
const parts = spec.split(":");
|
|
44890
|
+
if (parts.length !== 2)
|
|
44891
|
+
throw new Error(`Bad slice: '${spec}' (use N, N:, :N, or N:M)`);
|
|
44892
|
+
const [a, b] = parts;
|
|
44893
|
+
const start = a === "" ? 0 : Number(a);
|
|
44894
|
+
const end = b === "" ? arr.length : Number(b);
|
|
44895
|
+
if (!Number.isInteger(start) || !Number.isInteger(end))
|
|
44896
|
+
throw new Error(`Bad slice: '${spec}'`);
|
|
44897
|
+
return arr.slice(start, end);
|
|
44898
|
+
}
|
|
44899
|
+
var trunc = (s, n) => s.length > n ? s.slice(0, n) + `
|
|
44900
|
+
${DIM}... (${s.length} chars)${RESET}` : s;
|
|
44901
|
+
var indent = (s, pre) => s.split(`
|
|
44902
|
+
`).join(`
|
|
44903
|
+
${pre}`);
|
|
44904
|
+
function printFullChat(todo, frontendUrl, slice, mode = "default", format = "compact") {
|
|
43850
44905
|
const statusColors = {
|
|
43851
44906
|
DONE: GREEN,
|
|
43852
44907
|
READY: GREEN,
|
|
@@ -43871,69 +44926,83 @@ function printFullChat(todo, frontendUrl, untilMessageId) {
|
|
|
43871
44926
|
if (todo.agentSettingsId)
|
|
43872
44927
|
process.stderr.write(`${DIM}Agent:${RESET} ${todo.agentSettingsId}
|
|
43873
44928
|
`);
|
|
43874
|
-
if (
|
|
43875
|
-
process.stderr.write(`${DIM}
|
|
44929
|
+
if (slice)
|
|
44930
|
+
process.stderr.write(`${DIM}Slice:${RESET} [${slice}]
|
|
43876
44931
|
`);
|
|
43877
44932
|
process.stderr.write("\u2500".repeat(60) + `
|
|
43878
44933
|
`);
|
|
43879
44934
|
let messages = todo.messages || [];
|
|
43880
|
-
if (
|
|
43881
|
-
|
|
43882
|
-
|
|
43883
|
-
|
|
44935
|
+
if (slice) {
|
|
44936
|
+
try {
|
|
44937
|
+
messages = applySlice(messages, slice);
|
|
44938
|
+
} catch (e) {
|
|
44939
|
+
process.stderr.write(`${RED}${e.message}${RESET}
|
|
43884
44940
|
`);
|
|
43885
44941
|
process.exit(2);
|
|
43886
44942
|
}
|
|
43887
|
-
messages = messages.slice(0, idx + 1);
|
|
43888
44943
|
}
|
|
43889
44944
|
if (!messages.length) {
|
|
43890
44945
|
process.stderr.write(`${DIM}(no messages)${RESET}
|
|
43891
44946
|
`);
|
|
43892
44947
|
return;
|
|
43893
44948
|
}
|
|
43894
|
-
|
|
43895
|
-
|
|
44949
|
+
const shaped = toAnthropicShape(messages, mode, format);
|
|
44950
|
+
let toolUseCount = 0, errorCount = 0;
|
|
44951
|
+
for (let i = 0;i < shaped.length; i++) {
|
|
44952
|
+
const msg = shaped[i];
|
|
44953
|
+
const orig = messages[i];
|
|
44954
|
+
const ts = mode !== "default" && orig?.createdAt ? ` ${DIM}${new Date(orig.createdAt).toLocaleTimeString()}${RESET}` : "";
|
|
44955
|
+
const label = msg.role === "user" ? `${CYAN}\u25B6 USER${RESET}` : `${GREEN}\u25C0 ASSISTANT${RESET}`;
|
|
43896
44956
|
process.stderr.write(`
|
|
43897
|
-
${
|
|
44957
|
+
${label}${ts}
|
|
43898
44958
|
`);
|
|
43899
|
-
|
|
43900
|
-
|
|
43901
|
-
|
|
43902
|
-
|
|
44959
|
+
const items = Array.isArray(msg.content) ? msg.content : [{ type: "text", text: msg.content }];
|
|
44960
|
+
for (const it of items) {
|
|
44961
|
+
if (it.type === "text") {
|
|
44962
|
+
if (it.text)
|
|
44963
|
+
process.stdout.write(trunc(it.text, 2000) + `
|
|
43903
44964
|
`);
|
|
43904
|
-
|
|
43905
|
-
|
|
43906
|
-
|
|
43907
|
-
|
|
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(`
|
|
44965
|
+
} else if (it.type === "image" || it.type === "document") {
|
|
44966
|
+
const s = it.source ?? {};
|
|
44967
|
+
process.stderr.write(` ${YELLOW}[${it.type}]${RESET} ${DIM}${s.mimeType ?? ""}${RESET} ${s.name ?? ""} ${DIM}(${s.size ?? "?"} bytes)${RESET}
|
|
44968
|
+
${DIM}${s.uri ?? ""}${RESET}
|
|
43914
44969
|
`);
|
|
43915
|
-
if (
|
|
43916
|
-
|
|
43917
|
-
|
|
43918
|
-
process.stdout.write(` ${DIM}\u2502${RESET} ${content.split(`
|
|
43919
|
-
`).join(`
|
|
43920
|
-
${DIM}\u2502${RESET} `)}
|
|
44970
|
+
} else if (it.type === "thinking") {
|
|
44971
|
+
if (it.thinking)
|
|
44972
|
+
process.stderr.write(`${DIM}[thinking]${RESET} ${trunc(it.thinking, 500)}
|
|
43921
44973
|
`);
|
|
43922
|
-
}
|
|
43923
|
-
|
|
43924
|
-
|
|
43925
|
-
${
|
|
43926
|
-
process.stderr.write(` ${DIM}\u2514\u2500 result:${RESET} ${result.split(`
|
|
43927
|
-
`).join(`
|
|
43928
|
-
${DIM}\u2502${RESET} `)}
|
|
44974
|
+
} else if (it.type === "tool_use") {
|
|
44975
|
+
toolUseCount++;
|
|
44976
|
+
if (it.content) {
|
|
44977
|
+
process.stderr.write(` ${YELLOW}${trunc(it.content, 200)}${RESET}
|
|
43929
44978
|
`);
|
|
43930
|
-
|
|
43931
|
-
|
|
43932
|
-
|
|
44979
|
+
} else {
|
|
44980
|
+
const argStr = Object.entries(it.input || {}).map(([k, v]) => `${DIM}${k}=${RESET}${String(v).split(`
|
|
44981
|
+
`)[0].slice(0, 80)}`).join(" ");
|
|
44982
|
+
process.stderr.write(` ${YELLOW}[${it.name}]${RESET} ${argStr}
|
|
43933
44983
|
`);
|
|
43934
|
-
|
|
43935
|
-
if (
|
|
43936
|
-
|
|
44984
|
+
}
|
|
44985
|
+
} else if (it.type === "tool_result") {
|
|
44986
|
+
const errLabel = it.is_error ? ` ${RED}ERROR${RESET}` : it.status && it.status !== "COMPLETED" ? ` ${RED}${it.status}${RESET}` : "";
|
|
44987
|
+
if (errLabel)
|
|
44988
|
+
errorCount++;
|
|
44989
|
+
const status = errLabel;
|
|
44990
|
+
let bodyStr;
|
|
44991
|
+
if (typeof it.content === "string")
|
|
44992
|
+
bodyStr = it.content;
|
|
44993
|
+
else {
|
|
44994
|
+
bodyStr = (it.content || []).map((c2) => {
|
|
44995
|
+
if (c2.type === "text")
|
|
44996
|
+
return c2.text ?? "";
|
|
44997
|
+
if (c2.type === "image" || c2.type === "document") {
|
|
44998
|
+
const s = c2.source ?? {};
|
|
44999
|
+
return `[${c2.type}] ${s.mimeType ?? ""}${s.name ? " " + s.name : ""} (${s.size ?? "?"} B) ${s.uri ?? ""}`;
|
|
45000
|
+
}
|
|
45001
|
+
return "";
|
|
45002
|
+
}).join(`
|
|
45003
|
+
`);
|
|
45004
|
+
}
|
|
45005
|
+
process.stderr.write(` ${DIM}\u2514\u2500 result:${RESET}${status} ${indent(trunc(bodyStr, 500), ` ${DIM}\u2502${RESET} `)}
|
|
43937
45006
|
`);
|
|
43938
45007
|
}
|
|
43939
45008
|
}
|
|
@@ -43941,9 +45010,7 @@ ${DIM}... (${block.result.length} chars)${RESET}` : block.result;
|
|
|
43941
45010
|
process.stderr.write(`
|
|
43942
45011
|
` + "\u2500".repeat(60) + `
|
|
43943
45012
|
`);
|
|
43944
|
-
|
|
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}
|
|
45013
|
+
process.stderr.write(`${DIM}Messages: ${shaped.length} | Tool calls: ${toolUseCount} | Tool errors: ${errorCount}${RESET}
|
|
43947
45014
|
`);
|
|
43948
45015
|
}
|
|
43949
45016
|
|
|
@@ -44093,347 +45160,6 @@ Please choose an agent:
|
|
|
44093
45160
|
})();
|
|
44094
45161
|
}
|
|
44095
45162
|
|
|
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
45163
|
// src/diff-view.ts
|
|
44438
45164
|
var import_diff_match_patch = __toESM(require_diff_match_patch(), 1);
|
|
44439
45165
|
var import_cli_highlight = __toESM(require_dist(), 1);
|
|
@@ -44635,8 +45361,8 @@ function renderDiff(originalContent, modifiedContent, filePath) {
|
|
|
44635
45361
|
return "";
|
|
44636
45362
|
const visible = new Set;
|
|
44637
45363
|
for (const idx of changed) {
|
|
44638
|
-
for (let
|
|
44639
|
-
visible.add(
|
|
45364
|
+
for (let c2 = Math.max(0, idx - CONTEXT_LINES);c2 <= Math.min(lines.length - 1, idx + CONTEXT_LINES); c2++) {
|
|
45365
|
+
visible.add(c2);
|
|
44640
45366
|
}
|
|
44641
45367
|
}
|
|
44642
45368
|
const parts = [`${CYAN}\u2500\u2500 ${filePath} \u2500\u2500${RESET}
|
|
@@ -44799,12 +45525,12 @@ ${YELLOW}Interrupting... (Ctrl+C again to force exit)${RESET}
|
|
|
44799
45525
|
if (approvalPromptActive || pendingBlocks.length === 0)
|
|
44800
45526
|
return;
|
|
44801
45527
|
approvalPromptActive = true;
|
|
44802
|
-
const
|
|
45528
|
+
const blocks3 = pendingBlocks.splice(0).map((bi) => {
|
|
44803
45529
|
const latest = bi?.blockId ? blocksStore.get(bi.blockId) || {} : {};
|
|
44804
45530
|
return { ...latest, ...bi };
|
|
44805
45531
|
});
|
|
44806
45532
|
if (approveAll) {
|
|
44807
|
-
for (const bi of
|
|
45533
|
+
for (const bi of blocks3) {
|
|
44808
45534
|
const [tl, disp] = blockDisplay(bi);
|
|
44809
45535
|
process.stderr.write(`
|
|
44810
45536
|
${YELLOW}\u26A0 Auto-approving [${tl}]${RESET} ${disp}
|
|
@@ -44817,14 +45543,14 @@ ${YELLOW}\u26A0 Auto-approving [${tl}]${RESET} ${disp}
|
|
|
44817
45543
|
}
|
|
44818
45544
|
return;
|
|
44819
45545
|
}
|
|
44820
|
-
activeApprovalBlocks =
|
|
44821
|
-
const hasFileBlocks =
|
|
45546
|
+
activeApprovalBlocks = blocks3;
|
|
45547
|
+
const hasFileBlocks = blocks3.some((bi) => ["create", "edit"].includes(classifyBlock(bi)));
|
|
44822
45548
|
if (hasFileBlocks)
|
|
44823
45549
|
await new Promise((r) => setTimeout(r, 1500));
|
|
44824
45550
|
process.stderr.write(`
|
|
44825
|
-
${YELLOW}\u26A0 ${
|
|
45551
|
+
${YELLOW}\u26A0 ${blocks3.length} action(s) awaiting approval:${RESET}
|
|
44826
45552
|
`);
|
|
44827
|
-
for (const bi of
|
|
45553
|
+
for (const bi of blocks3) {
|
|
44828
45554
|
const [tl, disp] = blockDisplay(bi);
|
|
44829
45555
|
process.stderr.write(` ${YELLOW}[${tl}]${RESET} ${disp}
|
|
44830
45556
|
`);
|
|
@@ -44841,7 +45567,7 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
|
|
|
44841
45567
|
process.stderr.write(renderDiff(diff.originalContent, diff.modifiedContent, filePath));
|
|
44842
45568
|
}
|
|
44843
45569
|
}
|
|
44844
|
-
const newPatterns =
|
|
45570
|
+
const newPatterns = blocks3.flatMap((bi) => getBlockNewPatterns({
|
|
44845
45571
|
type: bi.block_type || "unknown",
|
|
44846
45572
|
generalized_pattern: bi.generalized_pattern,
|
|
44847
45573
|
cmd: bi.cmd
|
|
@@ -44855,7 +45581,7 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
|
|
|
44855
45581
|
}
|
|
44856
45582
|
if (response === "a" || response === "y" || response === "" || response === "r") {
|
|
44857
45583
|
const decision = response === "r" ? "allow_remember" : "allow_once";
|
|
44858
|
-
for (const bi of
|
|
45584
|
+
for (const bi of blocks3) {
|
|
44859
45585
|
let patterns;
|
|
44860
45586
|
if (response === "r") {
|
|
44861
45587
|
patterns = getBlockNewPatterns({
|
|
@@ -44871,14 +45597,14 @@ ${YELLOW}\u26A0 ${blocks.length} action(s) awaiting approval:${RESET}
|
|
|
44871
45597
|
sendApproval(ws, bi.blockId, bi.messageId, todoId, decision, patterns);
|
|
44872
45598
|
}
|
|
44873
45599
|
} else {
|
|
44874
|
-
for (const bi of
|
|
45600
|
+
for (const bi of blocks3) {
|
|
44875
45601
|
ws.sendBlockDeny(todoId, bi.messageId, bi.blockId);
|
|
44876
45602
|
}
|
|
44877
45603
|
process.stderr.write(` ${RED}\u2717 Denied${RESET}
|
|
44878
45604
|
`);
|
|
44879
45605
|
}
|
|
44880
45606
|
} catch {
|
|
44881
|
-
for (const bi of
|
|
45607
|
+
for (const bi of blocks3) {
|
|
44882
45608
|
sendApproval(ws, bi.blockId, bi.messageId, todoId);
|
|
44883
45609
|
}
|
|
44884
45610
|
}
|
|
@@ -45028,6 +45754,239 @@ async function listAgentsCommand(api, opts) {
|
|
|
45028
45754
|
}
|
|
45029
45755
|
}
|
|
45030
45756
|
|
|
45757
|
+
// src/agent-command.ts
|
|
45758
|
+
function printAgentHelp() {
|
|
45759
|
+
process.stderr.write(`
|
|
45760
|
+
todoai agent \u2014 inspect and update agent settings
|
|
45761
|
+
|
|
45762
|
+
Usage:
|
|
45763
|
+
todoai agent list List agents (name, model, id, paths)
|
|
45764
|
+
todoai agent get <agent> Show a single agent's settings
|
|
45765
|
+
todoai agent update <agent> <field=value>\u2026 Update one or more settings
|
|
45766
|
+
|
|
45767
|
+
<agent> is a name or id (unique partial name also works).
|
|
45768
|
+
Fields map directly to agent settings; values are parsed as JSON when possible
|
|
45769
|
+
(numbers, booleans), otherwise treated as strings. Common fields:
|
|
45770
|
+
model e.g. claude | anthropic:anthropic/claude-opus-4.8
|
|
45771
|
+
('claude' is the rolling alias \u2192 latest Claude Opus)
|
|
45772
|
+
systemMessage freeform prompt text (alias: sysmsg)
|
|
45773
|
+
temperature number, e.g. 0.7
|
|
45774
|
+
thinkingLevel low | medium | high | xhigh | max
|
|
45775
|
+
name agent display name
|
|
45776
|
+
|
|
45777
|
+
Examples:
|
|
45778
|
+
todoai agent update <agent> model=claude
|
|
45779
|
+
todoai agent update <agent> model=anthropic:anthropic/claude-opus-4.8 temperature=0.5
|
|
45780
|
+
todoai agent update <agent> sysmsg="You are a terse video editor."
|
|
45781
|
+
`);
|
|
45782
|
+
}
|
|
45783
|
+
var FIELD_ALIASES = {
|
|
45784
|
+
sysmsg: "systemMessage",
|
|
45785
|
+
prompt: "systemMessage",
|
|
45786
|
+
temp: "temperature",
|
|
45787
|
+
thinking: "thinkingLevel"
|
|
45788
|
+
};
|
|
45789
|
+
function parseAssignment(arg) {
|
|
45790
|
+
const eq = arg.indexOf("=");
|
|
45791
|
+
if (eq < 1) {
|
|
45792
|
+
process.stderr.write(`${RED}Invalid field assignment '${arg}', expected field=value${RESET}
|
|
45793
|
+
`);
|
|
45794
|
+
process.exit(2);
|
|
45795
|
+
}
|
|
45796
|
+
const rawKey = arg.slice(0, eq);
|
|
45797
|
+
const key = FIELD_ALIASES[rawKey] || rawKey;
|
|
45798
|
+
const raw = arg.slice(eq + 1);
|
|
45799
|
+
try {
|
|
45800
|
+
return [key, JSON.parse(raw)];
|
|
45801
|
+
} catch {
|
|
45802
|
+
return [key, raw];
|
|
45803
|
+
}
|
|
45804
|
+
}
|
|
45805
|
+
function resolveAgent(agents, query) {
|
|
45806
|
+
const byId = agents.find((a) => getItemId(a) === query);
|
|
45807
|
+
if (byId)
|
|
45808
|
+
return byId;
|
|
45809
|
+
const q = query.toLowerCase();
|
|
45810
|
+
const exact = agents.filter((a) => getDisplayName(a).toLowerCase() === q);
|
|
45811
|
+
if (exact.length === 1)
|
|
45812
|
+
return exact[0];
|
|
45813
|
+
const partial = agents.filter((a) => getDisplayName(a).toLowerCase().includes(q));
|
|
45814
|
+
if (partial.length === 1)
|
|
45815
|
+
return partial[0];
|
|
45816
|
+
if (partial.length > 1) {
|
|
45817
|
+
process.stderr.write(`${RED}Ambiguous agent '${query}', matches:${RESET}
|
|
45818
|
+
`);
|
|
45819
|
+
for (const a of partial)
|
|
45820
|
+
process.stderr.write(` ${getDisplayName(a)} ${DIM}${getItemId(a)}${RESET}
|
|
45821
|
+
`);
|
|
45822
|
+
process.exit(2);
|
|
45823
|
+
}
|
|
45824
|
+
process.stderr.write(`${RED}No agent matching '${query}'${RESET}
|
|
45825
|
+
`);
|
|
45826
|
+
process.exit(2);
|
|
45827
|
+
}
|
|
45828
|
+
async function agentCommand(api, positionals, args, formatPath) {
|
|
45829
|
+
const sub = positionals[1];
|
|
45830
|
+
if (!sub || sub === "list" || sub === "ls") {
|
|
45831
|
+
await listAgentsCommand(api, { json: !!args.json, formatPath });
|
|
45832
|
+
return;
|
|
45833
|
+
}
|
|
45834
|
+
if (sub === "get") {
|
|
45835
|
+
const agents = await api.listAgentSettings();
|
|
45836
|
+
const agent = resolveAgent(agents, positionals[2] || "");
|
|
45837
|
+
if (args.json) {
|
|
45838
|
+
console.log(JSON.stringify(agent, null, 2));
|
|
45839
|
+
return;
|
|
45840
|
+
}
|
|
45841
|
+
process.stderr.write(`${BRAND}${getDisplayName(agent)}${RESET} ${DIM}${getItemId(agent)}${RESET}
|
|
45842
|
+
`);
|
|
45843
|
+
process.stderr.write(` ${DIM}model:${RESET} ${CYAN}${agent.model || "(default)"}${RESET}
|
|
45844
|
+
`);
|
|
45845
|
+
const paths = getAgentWorkspacePaths(agent).map(formatPath);
|
|
45846
|
+
if (paths.length)
|
|
45847
|
+
process.stderr.write(` ${DIM}paths:${RESET} ${paths.join(", ")}
|
|
45848
|
+
`);
|
|
45849
|
+
return;
|
|
45850
|
+
}
|
|
45851
|
+
if (sub === "update") {
|
|
45852
|
+
const query = positionals[2];
|
|
45853
|
+
const assignments = positionals.slice(3);
|
|
45854
|
+
if (!query || !assignments.length) {
|
|
45855
|
+
process.stderr.write(`${RED}Usage: todoai agent update <name|id> <field=value>\u2026${RESET}
|
|
45856
|
+
`);
|
|
45857
|
+
process.exit(2);
|
|
45858
|
+
}
|
|
45859
|
+
const updates = Object.fromEntries(assignments.map(parseAssignment));
|
|
45860
|
+
const agents = await api.listAgentSettings();
|
|
45861
|
+
const agent = resolveAgent(agents, query);
|
|
45862
|
+
const id = getItemId(agent);
|
|
45863
|
+
const updated = await api.updateAgentSettings(id, id, updates);
|
|
45864
|
+
if (args.json) {
|
|
45865
|
+
console.log(JSON.stringify(updated, null, 2));
|
|
45866
|
+
return;
|
|
45867
|
+
}
|
|
45868
|
+
const summary = Object.keys(updates).map((k) => `${k}=${JSON.stringify(updated[k])}`).join(" ");
|
|
45869
|
+
process.stderr.write(`${GREEN}\u2705 ${getDisplayName(agent)} updated: ${summary}${RESET}
|
|
45870
|
+
`);
|
|
45871
|
+
return;
|
|
45872
|
+
}
|
|
45873
|
+
process.stderr.write(`${RED}Unknown 'agent' subcommand: ${sub}${RESET}
|
|
45874
|
+
`);
|
|
45875
|
+
printAgentHelp();
|
|
45876
|
+
process.exit(2);
|
|
45877
|
+
}
|
|
45878
|
+
|
|
45879
|
+
// src/list-todos.ts
|
|
45880
|
+
import { parseArgs as parseArgs2 } from "util";
|
|
45881
|
+
var STATUS_COLOR = {
|
|
45882
|
+
DONE: GREEN,
|
|
45883
|
+
READY: GREEN,
|
|
45884
|
+
READY_CHECKED: GREEN,
|
|
45885
|
+
ERROR: RED,
|
|
45886
|
+
ERROR_CHECKED: RED,
|
|
45887
|
+
CANCELLED: RED,
|
|
45888
|
+
CANCELLED_CHECKED: RED,
|
|
45889
|
+
RUNNING: YELLOW,
|
|
45890
|
+
STOPPING: YELLOW,
|
|
45891
|
+
COMPACTING: YELLOW,
|
|
45892
|
+
REVIEW_REQUESTED: YELLOW,
|
|
45893
|
+
TODO: CYAN,
|
|
45894
|
+
SCHEDULED: CYAN,
|
|
45895
|
+
POSTPONED: CYAN,
|
|
45896
|
+
PAUSED: CYAN
|
|
45897
|
+
};
|
|
45898
|
+
var CLOSED = new Set([
|
|
45899
|
+
"DONE",
|
|
45900
|
+
"READY_CHECKED",
|
|
45901
|
+
"CANCELLED",
|
|
45902
|
+
"CANCELLED_CHECKED",
|
|
45903
|
+
"ERROR_CHECKED",
|
|
45904
|
+
"ARCHIVED",
|
|
45905
|
+
"DELETED"
|
|
45906
|
+
]);
|
|
45907
|
+
var VALID_STATUS = new Set(Object.values(TodoStatus));
|
|
45908
|
+
var isOpen = (s) => !CLOSED.has(s);
|
|
45909
|
+
function printHelp() {
|
|
45910
|
+
process.stderr.write(`
|
|
45911
|
+
todoai list \u2014 list todos in a project (recent first)
|
|
45912
|
+
|
|
45913
|
+
Usage:
|
|
45914
|
+
todoai list [flags]
|
|
45915
|
+
|
|
45916
|
+
Flags:
|
|
45917
|
+
-n, --limit <n> Max rows to show (default: 30)
|
|
45918
|
+
-s, --status <S[,S2]> Filter by status (comma-separated, union).
|
|
45919
|
+
-A, --all Include DONE (also CANCELLED, ARCHIVED, \u2026)
|
|
45920
|
+
--project <id> Project ID (default: current default project)
|
|
45921
|
+
--json Output raw JSON
|
|
45922
|
+
-h, --help Show this help
|
|
45923
|
+
|
|
45924
|
+
Examples:
|
|
45925
|
+
todoai list # 30 most recent open todos
|
|
45926
|
+
todoai list -n 50 # last 50 open
|
|
45927
|
+
todoai list --all # include DONE
|
|
45928
|
+
todoai list -s RUNNING,REVIEW_REQUESTED
|
|
45929
|
+
todoai list --json | jq '.[].id'
|
|
45930
|
+
`);
|
|
45931
|
+
}
|
|
45932
|
+
async function listTodosCommand(api, defaultProjectId, argv) {
|
|
45933
|
+
const { values } = parseArgs2({
|
|
45934
|
+
args: argv,
|
|
45935
|
+
options: {
|
|
45936
|
+
limit: { type: "string", short: "n" },
|
|
45937
|
+
status: { type: "string", short: "s" },
|
|
45938
|
+
all: { type: "boolean", short: "A", default: false },
|
|
45939
|
+
project: { type: "string" },
|
|
45940
|
+
json: { type: "boolean", default: false },
|
|
45941
|
+
help: { type: "boolean", short: "h", default: false }
|
|
45942
|
+
},
|
|
45943
|
+
strict: true
|
|
45944
|
+
});
|
|
45945
|
+
if (values.help) {
|
|
45946
|
+
printHelp();
|
|
45947
|
+
return;
|
|
45948
|
+
}
|
|
45949
|
+
const projectId = values.project || defaultProjectId;
|
|
45950
|
+
if (!projectId) {
|
|
45951
|
+
process.stderr.write(`${RED}Error: no project (pass --project <id> or set a default)${RESET}
|
|
45952
|
+
`);
|
|
45953
|
+
process.exit(1);
|
|
45954
|
+
}
|
|
45955
|
+
const limit = values.limit ? Math.max(1, Number(values.limit)) : 30;
|
|
45956
|
+
const requested = values.status ? String(values.status).split(",").map((s) => s.trim().toUpperCase()).filter(Boolean) : null;
|
|
45957
|
+
const wantOpen = !!requested?.some((s) => s === "OPEN" || !VALID_STATUS.has(s));
|
|
45958
|
+
const wanted = requested ? new Set(requested.filter((s) => VALID_STATUS.has(s))) : null;
|
|
45959
|
+
const includeClosed = !!values.all || !!wanted && wanted.size > 0;
|
|
45960
|
+
const todos = await api.listTodos(projectId);
|
|
45961
|
+
let rows = todos.filter((t) => includeClosed || !CLOSED.has(String(t.status).toUpperCase())).filter((t) => {
|
|
45962
|
+
if (!requested)
|
|
45963
|
+
return true;
|
|
45964
|
+
const s = String(t.status).toUpperCase();
|
|
45965
|
+
return wantOpen && isOpen(s) || (wanted?.has(s) ?? false);
|
|
45966
|
+
}).sort((a, b) => (b.lastActivityAt ?? b.createdAt ?? 0) - (a.lastActivityAt ?? a.createdAt ?? 0)).slice(0, limit);
|
|
45967
|
+
if (values.json) {
|
|
45968
|
+
process.stdout.write(JSON.stringify(rows, null, 2) + `
|
|
45969
|
+
`);
|
|
45970
|
+
return;
|
|
45971
|
+
}
|
|
45972
|
+
if (!rows.length) {
|
|
45973
|
+
process.stderr.write(`${DIM}(no todos)${RESET}
|
|
45974
|
+
`);
|
|
45975
|
+
return;
|
|
45976
|
+
}
|
|
45977
|
+
const statusW = rows.reduce((n, r) => Math.max(n, String(r.status).length), 0);
|
|
45978
|
+
for (const t of rows) {
|
|
45979
|
+
const sc = STATUS_COLOR[t.status] || DIM;
|
|
45980
|
+
const ts = new Date(t.lastActivityAt ?? t.createdAt).toISOString().slice(0, 16).replace("T", " ");
|
|
45981
|
+
const title = String(t.content ?? "").split(`
|
|
45982
|
+
`)[0].slice(0, 100);
|
|
45983
|
+
process.stdout.write(`${sc}${String(t.status).padEnd(statusW)}${RESET} ${DIM}${ts}${RESET} ${t.id} ${title}
|
|
45984
|
+
`);
|
|
45985
|
+
}
|
|
45986
|
+
process.stderr.write(`${DIM}${rows.length} todo(s)${RESET}
|
|
45987
|
+
`);
|
|
45988
|
+
}
|
|
45989
|
+
|
|
45031
45990
|
// src/ensure-edge.ts
|
|
45032
45991
|
import { spawn, spawnSync } from "child_process";
|
|
45033
45992
|
import fs2 from "fs";
|
|
@@ -45171,7 +46130,15 @@ Cancelled by user (Ctrl+C)
|
|
|
45171
46130
|
console.log(VERSION);
|
|
45172
46131
|
process.exit(0);
|
|
45173
46132
|
}
|
|
45174
|
-
if (args.help) {
|
|
46133
|
+
if (positionals[0] === "status" && args.help) {
|
|
46134
|
+
printStatusHelp();
|
|
46135
|
+
process.exit(0);
|
|
46136
|
+
}
|
|
46137
|
+
if (positionals[0] === "agent" && args.help) {
|
|
46138
|
+
printAgentHelp();
|
|
46139
|
+
process.exit(0);
|
|
46140
|
+
}
|
|
46141
|
+
if (args.help && !["list", "ls", "agent"].includes(positionals[0])) {
|
|
45175
46142
|
printUsage();
|
|
45176
46143
|
process.exit(0);
|
|
45177
46144
|
}
|
|
@@ -45194,7 +46161,7 @@ Cancelled by user (Ctrl+C)
|
|
|
45194
46161
|
const cfgScope = cfg.scope(apiUrl);
|
|
45195
46162
|
async function deviceLogin() {
|
|
45196
46163
|
const loginApi = new ApiClient(apiUrl, "");
|
|
45197
|
-
const { code, url, expiresIn } = await loginApi.initDeviceLogin("
|
|
46164
|
+
const { code, url, expiresIn } = await loginApi.initDeviceLogin("edge");
|
|
45198
46165
|
const userCode = new URL(url).searchParams.get("user_code") || code.slice(-8).toUpperCase();
|
|
45199
46166
|
const formattedCode = userCode.length === 8 ? `${userCode.slice(0, 4)}-${userCode.slice(4)}` : userCode;
|
|
45200
46167
|
process.stderr.write(`
|
|
@@ -45247,26 +46214,100 @@ Cancelled by user (Ctrl+C)
|
|
|
45247
46214
|
await deviceLogin();
|
|
45248
46215
|
return;
|
|
45249
46216
|
}
|
|
45250
|
-
let apiKey = args["api-key"] ||
|
|
46217
|
+
let apiKey = args["api-key"] || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
|
|
45251
46218
|
if (!apiKey) {
|
|
45252
46219
|
apiKey = await deviceLogin();
|
|
45253
46220
|
}
|
|
45254
46221
|
const api = new ApiClient(apiUrl, apiKey);
|
|
46222
|
+
if (positionals[0] === "status") {
|
|
46223
|
+
const [, todoId, status] = positionals;
|
|
46224
|
+
if (!todoId || !status) {
|
|
46225
|
+
printStatusHelp();
|
|
46226
|
+
process.exit(2);
|
|
46227
|
+
}
|
|
46228
|
+
await api.updateTodoStatus(todoId, status);
|
|
46229
|
+
process.stderr.write(`${GREEN}\u2705 Status of ${todoId} set to ${status}${RESET}
|
|
46230
|
+
`);
|
|
46231
|
+
return;
|
|
46232
|
+
}
|
|
46233
|
+
if (positionals[0] === "delete") {
|
|
46234
|
+
const todoId = positionals[1];
|
|
46235
|
+
if (!todoId) {
|
|
46236
|
+
process.stderr.write(`${RED}Usage: todoai delete <todo-id>${RESET}
|
|
46237
|
+
`);
|
|
46238
|
+
process.exit(2);
|
|
46239
|
+
}
|
|
46240
|
+
await api.deleteTodo(todoId);
|
|
46241
|
+
process.stderr.write(`${GREEN}\u2705 Deleted ${todoId}${RESET}
|
|
46242
|
+
`);
|
|
46243
|
+
return;
|
|
46244
|
+
}
|
|
46245
|
+
if (positionals[0] === "addmessage") {
|
|
46246
|
+
const [, todoId, ...rest] = positionals;
|
|
46247
|
+
const content2 = rest.join(" ") || await readStdin();
|
|
46248
|
+
if (!todoId || !content2) {
|
|
46249
|
+
process.stderr.write(`${RED}Usage: todoai addmessage <todo-id> "content"${RESET}
|
|
46250
|
+
`);
|
|
46251
|
+
process.exit(2);
|
|
46252
|
+
}
|
|
46253
|
+
const todo2 = await api.getTodo(todoId);
|
|
46254
|
+
const msg = await api.addMessage(todo2.projectId, content2, todo2.agentSettings || { id: todo2.agentSettingsId }, todoId);
|
|
46255
|
+
if (args.json)
|
|
46256
|
+
console.log(JSON.stringify(msg, null, 2));
|
|
46257
|
+
else
|
|
46258
|
+
process.stderr.write(`${GREEN}\u2705 Message added to ${todoId}${RESET}
|
|
46259
|
+
`);
|
|
46260
|
+
return;
|
|
46261
|
+
}
|
|
45255
46262
|
if (args["list-agents"]) {
|
|
45256
46263
|
await listAgentsCommand(api, { json: !!args.json, formatPath: formatPathWithTilde });
|
|
45257
46264
|
return;
|
|
45258
46265
|
}
|
|
46266
|
+
if (positionals[0] === "agent") {
|
|
46267
|
+
await agentCommand(api, positionals, args, formatPathWithTilde);
|
|
46268
|
+
return;
|
|
46269
|
+
}
|
|
46270
|
+
if (positionals[0] === "list" || positionals[0] === "ls") {
|
|
46271
|
+
let defaultProjectId = args.project || cfgScope.data.default_project_id;
|
|
46272
|
+
if (!defaultProjectId) {
|
|
46273
|
+
const projects2 = await api.listProjects();
|
|
46274
|
+
defaultProjectId = projects2.find((p) => p.project?.isDefault)?.project?.id || projects2[0]?.project?.id;
|
|
46275
|
+
}
|
|
46276
|
+
const sub = process.argv.slice(process.argv.indexOf(positionals[0]) + 1);
|
|
46277
|
+
await listTodosCommand(api, defaultProjectId ?? undefined, sub);
|
|
46278
|
+
return;
|
|
46279
|
+
}
|
|
45259
46280
|
if (args.inspect !== undefined) {
|
|
45260
46281
|
const raw = String(args.inspect);
|
|
45261
|
-
const
|
|
45262
|
-
const todoId =
|
|
46282
|
+
const at = raw.indexOf("@");
|
|
46283
|
+
const todoId = at < 0 ? raw : raw.slice(0, at);
|
|
46284
|
+
const slice = at < 0 ? undefined : raw.slice(at + 1);
|
|
45263
46285
|
if (!todoId) {
|
|
45264
|
-
process.stderr.write(`${RED}Error: --inspect requires a todoId
|
|
46286
|
+
process.stderr.write(`${RED}Error: --inspect requires a todoId${RESET}
|
|
45265
46287
|
`);
|
|
45266
46288
|
process.exit(2);
|
|
45267
46289
|
}
|
|
45268
46290
|
const todo2 = await api.getTodo(todoId);
|
|
45269
|
-
|
|
46291
|
+
if (args.json) {
|
|
46292
|
+
let messages = todo2.messages || [];
|
|
46293
|
+
if (slice) {
|
|
46294
|
+
try {
|
|
46295
|
+
messages = applySlice(messages, slice);
|
|
46296
|
+
} catch (e) {
|
|
46297
|
+
process.stderr.write(`${RED}${e.message}${RESET}
|
|
46298
|
+
`);
|
|
46299
|
+
process.exit(2);
|
|
46300
|
+
}
|
|
46301
|
+
}
|
|
46302
|
+
const mode2 = args.debug ? "debug" : args.detailed ? "detailed" : "default";
|
|
46303
|
+
const format2 = args["format-anthropic"] ? "anthropic" : "compact";
|
|
46304
|
+
process.stdout.write(JSON.stringify(toAnthropicShape(messages, mode2, format2), null, 2) + `
|
|
46305
|
+
`);
|
|
46306
|
+
return;
|
|
46307
|
+
}
|
|
46308
|
+
const mode = args.debug ? "debug" : args.detailed ? "detailed" : "default";
|
|
46309
|
+
const format = args["format-anthropic"] ? "anthropic" : "compact";
|
|
46310
|
+
printFullChat(todo2, getFrontendUrl(apiUrl, todo2.projectId, todoId), slice, mode, format);
|
|
45270
46311
|
return;
|
|
45271
46312
|
}
|
|
45272
46313
|
if (process.stderr.isTTY)
|
|
@@ -45370,7 +46411,7 @@ ${"\u2500".repeat(40)}
|
|
|
45370
46411
|
}
|
|
45371
46412
|
const todo2 = await api.getTodo(todoId);
|
|
45372
46413
|
const projectId2 = todo2.projectId;
|
|
45373
|
-
const agent2 = todo2.agentSettings ||
|
|
46414
|
+
const agent2 = todo2.agentSettings || await api.getAgentSettings(todo2.agentSettingsId);
|
|
45374
46415
|
for (const msg of todo2.messages || []) {
|
|
45375
46416
|
const role = msg.role === "user" ? `${CYAN}You${RESET}` : `${GREEN}AI${RESET}`;
|
|
45376
46417
|
process.stderr.write(`${role}: ${(msg.content || "").slice(0, 200)}
|
|
@@ -45378,11 +46419,20 @@ ${"\u2500".repeat(40)}
|
|
|
45378
46419
|
}
|
|
45379
46420
|
process.stderr.write(`
|
|
45380
46421
|
${"\u2500".repeat(40)}
|
|
45381
|
-
Resumed
|
|
46422
|
+
Resumed: ${CYAN}${getFrontendUrl(apiUrl, projectId2, todoId)}${RESET}
|
|
45382
46423
|
`);
|
|
45383
46424
|
const ws2 = new FrontendWebSocket(apiUrl, apiKey);
|
|
45384
46425
|
await ws2.connect();
|
|
45385
|
-
|
|
46426
|
+
const autoApprove = !!args["dangerously-skip-permissions"];
|
|
46427
|
+
const followUp = positionals.length > 0 ? positionals.join(" ") : process.stdin.isTTY ? "" : await readStdin();
|
|
46428
|
+
if (followUp) {
|
|
46429
|
+
cfg.addToHistory(followUp);
|
|
46430
|
+
await api.addMessage(projectId2, followUp, agent2, todoId);
|
|
46431
|
+
await watchTodo(ws2, todoId, projectId2, { json: !!args.json, autoApprove, agentSettings: agent2 });
|
|
46432
|
+
}
|
|
46433
|
+
if (!args["non-interactive"]) {
|
|
46434
|
+
await interactiveLoop(ws2, api, todoId, projectId2, agent2, !!args.json, autoApprove, cfg);
|
|
46435
|
+
}
|
|
45386
46436
|
await ws2.close();
|
|
45387
46437
|
return;
|
|
45388
46438
|
}
|