@cryer/star-cli 0.3.13 → 0.3.14
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/README.md +17 -5
- package/README.zh-CN.md +15 -5
- package/dist/{chunk-6PLZ3FLG.js → chunk-2ISBRSBA.js} +375 -235
- package/dist/chunk-2ISBRSBA.js.map +1 -0
- package/dist/{chunk-QELCMXQX.js → chunk-4HANB3DJ.js} +381 -212
- package/dist/chunk-4HANB3DJ.js.map +1 -0
- package/dist/{chunk-OF42OVM4.js → chunk-54KH4JSO.js} +204 -125
- package/dist/chunk-54KH4JSO.js.map +1 -0
- package/dist/{chunk-RD4S5LKM.js → chunk-CECMCDZG.js} +43 -30
- package/dist/chunk-CECMCDZG.js.map +1 -0
- package/dist/{chunk-MVAMPVTA.js → chunk-KILMI3S5.js} +13 -5
- package/dist/{chunk-MVAMPVTA.js.map → chunk-KILMI3S5.js.map} +1 -1
- package/dist/{chunk-NMB3TNQU.js → chunk-NRLGGA7L.js} +507 -175
- package/dist/chunk-NRLGGA7L.js.map +1 -0
- package/dist/loop-M64D5YII.js +17 -0
- package/dist/main.js +177 -131
- package/dist/main.js.map +1 -1
- package/dist/{provider-EWMUPBLH.js → provider-3Z4B7RMF.js} +2 -2
- package/dist/{repl-ZABBT33D.js → repl-N2H7JDSH.js} +617 -327
- package/dist/repl-N2H7JDSH.js.map +1 -0
- package/dist/{tools-4OLADVDR.js → tools-5RKM7ZI3.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-6PLZ3FLG.js.map +0 -1
- package/dist/chunk-NMB3TNQU.js.map +0 -1
- package/dist/chunk-OF42OVM4.js.map +0 -1
- package/dist/chunk-QELCMXQX.js.map +0 -1
- package/dist/chunk-RD4S5LKM.js.map +0 -1
- package/dist/loop-DWQ5WTPD.js +0 -17
- package/dist/repl-ZABBT33D.js.map +0 -1
- /package/dist/{loop-DWQ5WTPD.js.map → loop-M64D5YII.js.map} +0 -0
- /package/dist/{provider-EWMUPBLH.js.map → provider-3Z4B7RMF.js.map} +0 -0
- /package/dist/{tools-4OLADVDR.js.map → tools-5RKM7ZI3.js.map} +0 -0
|
@@ -125,163 +125,6 @@ function formatAgentTaskUpdate(task) {
|
|
|
125
125
|
return text;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
// src/core/http-error.ts
|
|
129
|
-
function responseBodyOf(error) {
|
|
130
|
-
const body = error.responseBody;
|
|
131
|
-
return typeof body === "string" && body.length > 0 ? body : void 0;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// src/core/image.ts
|
|
135
|
-
var MAX_IMAGE_DIMENSION = 2e3;
|
|
136
|
-
var OVERSIZED_IMAGE_FALLBACK_BYTES = 5 * 1024 * 1024;
|
|
137
|
-
var IMAGE_REMOVED_PLACEHOLDER = "[image removed: too large for the model]";
|
|
138
|
-
var IMAGE_UNSUPPORTED_PLACEHOLDER = "[image removed: the model cannot read images]";
|
|
139
|
-
var PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
140
|
-
function probePng(buf) {
|
|
141
|
-
if (buf.length < 24) return null;
|
|
142
|
-
for (let i = 0; i < PNG_SIGNATURE.length; i++) {
|
|
143
|
-
if (buf[i] !== PNG_SIGNATURE[i]) return null;
|
|
144
|
-
}
|
|
145
|
-
if (buf.toString("ascii", 12, 16) !== "IHDR") return null;
|
|
146
|
-
return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) };
|
|
147
|
-
}
|
|
148
|
-
var JPEG_SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
149
|
-
192,
|
|
150
|
-
193,
|
|
151
|
-
194,
|
|
152
|
-
195,
|
|
153
|
-
197,
|
|
154
|
-
198,
|
|
155
|
-
199,
|
|
156
|
-
201,
|
|
157
|
-
202,
|
|
158
|
-
203,
|
|
159
|
-
205,
|
|
160
|
-
206,
|
|
161
|
-
207
|
|
162
|
-
]);
|
|
163
|
-
function probeJpeg(buf) {
|
|
164
|
-
if (buf.length < 4 || buf[0] !== 255 || buf[1] !== 216) return null;
|
|
165
|
-
let offset = 2;
|
|
166
|
-
while (offset + 3 < buf.length) {
|
|
167
|
-
if (buf[offset] !== 255) return null;
|
|
168
|
-
const marker = buf[offset + 1];
|
|
169
|
-
if (marker === void 0) return null;
|
|
170
|
-
if (marker === 216 || marker === 1 || marker >= 208 && marker <= 215) {
|
|
171
|
-
offset += 2;
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
const length = buf.readUInt16BE(offset + 2);
|
|
175
|
-
if (length < 2) return null;
|
|
176
|
-
if (JPEG_SOF_MARKERS.has(marker)) {
|
|
177
|
-
if (offset + 9 > buf.length) return null;
|
|
178
|
-
return { height: buf.readUInt16BE(offset + 5), width: buf.readUInt16BE(offset + 7) };
|
|
179
|
-
}
|
|
180
|
-
offset += 2 + length;
|
|
181
|
-
}
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
function probeGif(buf) {
|
|
185
|
-
if (buf.length < 10) return null;
|
|
186
|
-
const signature = buf.toString("ascii", 0, 6);
|
|
187
|
-
if (signature !== "GIF87a" && signature !== "GIF89a") return null;
|
|
188
|
-
return { width: buf.readUInt16LE(6), height: buf.readUInt16LE(8) };
|
|
189
|
-
}
|
|
190
|
-
function probeWebp(buf) {
|
|
191
|
-
if (buf.length < 30) return null;
|
|
192
|
-
if (buf.toString("ascii", 0, 4) !== "RIFF" || buf.toString("ascii", 8, 12) !== "WEBP") {
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
const chunk = buf.toString("ascii", 12, 16);
|
|
196
|
-
if (chunk === "VP8X") {
|
|
197
|
-
return { width: 1 + buf.readUIntLE(24, 3), height: 1 + buf.readUIntLE(27, 3) };
|
|
198
|
-
}
|
|
199
|
-
if (chunk === "VP8 ") {
|
|
200
|
-
return {
|
|
201
|
-
width: buf.readUInt16LE(26) & 16383,
|
|
202
|
-
height: buf.readUInt16LE(28) & 16383
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
if (chunk === "VP8L") {
|
|
206
|
-
if (buf[20] !== 47) return null;
|
|
207
|
-
const b1 = buf[21];
|
|
208
|
-
const b2 = buf[22];
|
|
209
|
-
const b3 = buf[23];
|
|
210
|
-
const b4 = buf[24];
|
|
211
|
-
return {
|
|
212
|
-
width: 1 + ((b2 & 63) << 8 | b1),
|
|
213
|
-
height: 1 + ((b4 & 15) << 10 | b3 << 2 | (b2 & 192) >> 6)
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
function probeImageDimensions(buf) {
|
|
219
|
-
return probePng(buf) ?? probeJpeg(buf) ?? probeGif(buf) ?? probeWebp(buf);
|
|
220
|
-
}
|
|
221
|
-
var IMAGE_SIZE_KEYWORDS = /too[\s-]*(large|big)|exceeds?|dimensions?|resolution|size\s*limit|max(?:imum)?[\s-]*size/i;
|
|
222
|
-
function isOversizedImageError(error) {
|
|
223
|
-
const status = error.statusCode;
|
|
224
|
-
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
225
|
-
const text = [error.message, responseBodyOf(error)].filter((part) => typeof part === "string").join("\n");
|
|
226
|
-
return /image/i.test(text) && IMAGE_SIZE_KEYWORDS.test(text);
|
|
227
|
-
}
|
|
228
|
-
var VISION_UNSUPPORTED_KEYWORDS = /vision\s*encoder|can(?:not|'t) (?:read|process|handle|accept) images?|does(?:\s*not|n't) support (?:image|vision|multimodal)|images?(?:\s*input)? (?:are|is) not supported|not a vision|no vision (?:capability|support|encoder)|multimodal(?:\s*input)? (?:is )?not supported/i;
|
|
229
|
-
function isVisionUnsupportedError(error) {
|
|
230
|
-
const status = error.statusCode;
|
|
231
|
-
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
232
|
-
const text = [error.message, responseBodyOf(error)].filter((part) => typeof part === "string").join("\n");
|
|
233
|
-
return /image|vision|multimodal/i.test(text) && VISION_UNSUPPORTED_KEYWORDS.test(text);
|
|
234
|
-
}
|
|
235
|
-
function imagePartBytes(image) {
|
|
236
|
-
if (typeof image === "string") {
|
|
237
|
-
const base64 = image.startsWith("data:") ? image.slice(image.indexOf(",") + 1) : image;
|
|
238
|
-
try {
|
|
239
|
-
return Buffer.from(base64, "base64");
|
|
240
|
-
} catch {
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (image instanceof Uint8Array) return Buffer.from(image);
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
function isOversizedImageData(buf) {
|
|
248
|
-
const dims = probeImageDimensions(buf);
|
|
249
|
-
if (dims) return Math.max(dims.width, dims.height) > MAX_IMAGE_DIMENSION;
|
|
250
|
-
return buf.length > OVERSIZED_IMAGE_FALLBACK_BYTES;
|
|
251
|
-
}
|
|
252
|
-
function stripOversizedImages(messages) {
|
|
253
|
-
let removed = 0;
|
|
254
|
-
const result = messages.map((message) => {
|
|
255
|
-
if (!Array.isArray(message.content)) return message;
|
|
256
|
-
let changed = false;
|
|
257
|
-
const content = message.content.map((part) => {
|
|
258
|
-
if (part.type !== "image") return part;
|
|
259
|
-
const bytes = imagePartBytes(part.image);
|
|
260
|
-
if (!bytes || !isOversizedImageData(bytes)) return part;
|
|
261
|
-
changed = true;
|
|
262
|
-
removed++;
|
|
263
|
-
return { type: "text", text: IMAGE_REMOVED_PLACEHOLDER };
|
|
264
|
-
});
|
|
265
|
-
return changed ? { ...message, content } : message;
|
|
266
|
-
});
|
|
267
|
-
return { messages: removed > 0 ? result : messages, removed };
|
|
268
|
-
}
|
|
269
|
-
function stripAllImages(messages) {
|
|
270
|
-
let removed = 0;
|
|
271
|
-
const result = messages.map((message) => {
|
|
272
|
-
if (!Array.isArray(message.content)) return message;
|
|
273
|
-
let changed = false;
|
|
274
|
-
const content = message.content.map((part) => {
|
|
275
|
-
if (part.type !== "image") return part;
|
|
276
|
-
changed = true;
|
|
277
|
-
removed++;
|
|
278
|
-
return { type: "text", text: IMAGE_UNSUPPORTED_PLACEHOLDER };
|
|
279
|
-
});
|
|
280
|
-
return changed ? { ...message, content } : message;
|
|
281
|
-
});
|
|
282
|
-
return { messages: removed > 0 ? result : messages, removed };
|
|
283
|
-
}
|
|
284
|
-
|
|
285
128
|
// src/config/paths.ts
|
|
286
129
|
import os from "os";
|
|
287
130
|
import path from "path";
|
|
@@ -390,6 +233,29 @@ function registerSensitivePatterns(patterns) {
|
|
|
390
233
|
extraPatterns.length = 0;
|
|
391
234
|
extraPatterns.push(...patterns.map((p) => p.trim()).filter((p) => p.length > 0));
|
|
392
235
|
}
|
|
236
|
+
function sensitiveExcludePatterns() {
|
|
237
|
+
return [
|
|
238
|
+
".env",
|
|
239
|
+
".env.*",
|
|
240
|
+
"!.env.example",
|
|
241
|
+
"!.env.sample",
|
|
242
|
+
"!.env.template",
|
|
243
|
+
"id_rsa",
|
|
244
|
+
"id_dsa",
|
|
245
|
+
"id_ecdsa",
|
|
246
|
+
"id_ed25519",
|
|
247
|
+
".npmrc",
|
|
248
|
+
".netrc",
|
|
249
|
+
".pgpass",
|
|
250
|
+
"*.pem",
|
|
251
|
+
"*.key",
|
|
252
|
+
"*.p12",
|
|
253
|
+
"*.pfx",
|
|
254
|
+
"**/.aws/credentials",
|
|
255
|
+
"**/.kube/config",
|
|
256
|
+
...extraPatterns
|
|
257
|
+
];
|
|
258
|
+
}
|
|
393
259
|
function globToRegExp(pattern) {
|
|
394
260
|
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
395
261
|
return new RegExp(`^${escaped}$`, "i");
|
|
@@ -817,6 +683,163 @@ var TaskManager = class extends EventEmitter2 {
|
|
|
817
683
|
};
|
|
818
684
|
var defaultTaskManager = new TaskManager();
|
|
819
685
|
|
|
686
|
+
// src/core/http-error.ts
|
|
687
|
+
function responseBodyOf(error) {
|
|
688
|
+
const body = error.responseBody;
|
|
689
|
+
return typeof body === "string" && body.length > 0 ? body : void 0;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// src/core/image.ts
|
|
693
|
+
var MAX_IMAGE_DIMENSION = 2e3;
|
|
694
|
+
var OVERSIZED_IMAGE_FALLBACK_BYTES = 5 * 1024 * 1024;
|
|
695
|
+
var IMAGE_REMOVED_PLACEHOLDER = "[image removed: too large for the model]";
|
|
696
|
+
var IMAGE_UNSUPPORTED_PLACEHOLDER = "[image removed: the model cannot read images]";
|
|
697
|
+
var PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
698
|
+
function probePng(buf) {
|
|
699
|
+
if (buf.length < 24) return null;
|
|
700
|
+
for (let i = 0; i < PNG_SIGNATURE.length; i++) {
|
|
701
|
+
if (buf[i] !== PNG_SIGNATURE[i]) return null;
|
|
702
|
+
}
|
|
703
|
+
if (buf.toString("ascii", 12, 16) !== "IHDR") return null;
|
|
704
|
+
return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) };
|
|
705
|
+
}
|
|
706
|
+
var JPEG_SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
707
|
+
192,
|
|
708
|
+
193,
|
|
709
|
+
194,
|
|
710
|
+
195,
|
|
711
|
+
197,
|
|
712
|
+
198,
|
|
713
|
+
199,
|
|
714
|
+
201,
|
|
715
|
+
202,
|
|
716
|
+
203,
|
|
717
|
+
205,
|
|
718
|
+
206,
|
|
719
|
+
207
|
|
720
|
+
]);
|
|
721
|
+
function probeJpeg(buf) {
|
|
722
|
+
if (buf.length < 4 || buf[0] !== 255 || buf[1] !== 216) return null;
|
|
723
|
+
let offset = 2;
|
|
724
|
+
while (offset + 3 < buf.length) {
|
|
725
|
+
if (buf[offset] !== 255) return null;
|
|
726
|
+
const marker = buf[offset + 1];
|
|
727
|
+
if (marker === void 0) return null;
|
|
728
|
+
if (marker === 216 || marker === 1 || marker >= 208 && marker <= 215) {
|
|
729
|
+
offset += 2;
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
const length = buf.readUInt16BE(offset + 2);
|
|
733
|
+
if (length < 2) return null;
|
|
734
|
+
if (JPEG_SOF_MARKERS.has(marker)) {
|
|
735
|
+
if (offset + 9 > buf.length) return null;
|
|
736
|
+
return { height: buf.readUInt16BE(offset + 5), width: buf.readUInt16BE(offset + 7) };
|
|
737
|
+
}
|
|
738
|
+
offset += 2 + length;
|
|
739
|
+
}
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
function probeGif(buf) {
|
|
743
|
+
if (buf.length < 10) return null;
|
|
744
|
+
const signature = buf.toString("ascii", 0, 6);
|
|
745
|
+
if (signature !== "GIF87a" && signature !== "GIF89a") return null;
|
|
746
|
+
return { width: buf.readUInt16LE(6), height: buf.readUInt16LE(8) };
|
|
747
|
+
}
|
|
748
|
+
function probeWebp(buf) {
|
|
749
|
+
if (buf.length < 30) return null;
|
|
750
|
+
if (buf.toString("ascii", 0, 4) !== "RIFF" || buf.toString("ascii", 8, 12) !== "WEBP") {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
const chunk = buf.toString("ascii", 12, 16);
|
|
754
|
+
if (chunk === "VP8X") {
|
|
755
|
+
return { width: 1 + buf.readUIntLE(24, 3), height: 1 + buf.readUIntLE(27, 3) };
|
|
756
|
+
}
|
|
757
|
+
if (chunk === "VP8 ") {
|
|
758
|
+
return {
|
|
759
|
+
width: buf.readUInt16LE(26) & 16383,
|
|
760
|
+
height: buf.readUInt16LE(28) & 16383
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
if (chunk === "VP8L") {
|
|
764
|
+
if (buf[20] !== 47) return null;
|
|
765
|
+
const b1 = buf[21];
|
|
766
|
+
const b2 = buf[22];
|
|
767
|
+
const b3 = buf[23];
|
|
768
|
+
const b4 = buf[24];
|
|
769
|
+
return {
|
|
770
|
+
width: 1 + ((b2 & 63) << 8 | b1),
|
|
771
|
+
height: 1 + ((b4 & 15) << 10 | b3 << 2 | (b2 & 192) >> 6)
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
function probeImageDimensions(buf) {
|
|
777
|
+
return probePng(buf) ?? probeJpeg(buf) ?? probeGif(buf) ?? probeWebp(buf);
|
|
778
|
+
}
|
|
779
|
+
var IMAGE_SIZE_KEYWORDS = /too[\s-]*(large|big)|exceeds?|dimensions?|resolution|size\s*limit|max(?:imum)?[\s-]*size/i;
|
|
780
|
+
function isOversizedImageError(error) {
|
|
781
|
+
const status = error.statusCode;
|
|
782
|
+
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
783
|
+
const text = [error.message, responseBodyOf(error)].filter((part) => typeof part === "string").join("\n");
|
|
784
|
+
return /image/i.test(text) && IMAGE_SIZE_KEYWORDS.test(text);
|
|
785
|
+
}
|
|
786
|
+
var VISION_UNSUPPORTED_KEYWORDS = /vision\s*encoder|can(?:not|'t) (?:read|process|handle|accept) images?|does(?:\s*not|n't) support (?:image|vision|multimodal)|images?(?:\s*input)? (?:are|is) not supported|not a vision|no vision (?:capability|support|encoder)|multimodal(?:\s*input)? (?:is )?not supported/i;
|
|
787
|
+
function isVisionUnsupportedError(error) {
|
|
788
|
+
const status = error.statusCode;
|
|
789
|
+
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
790
|
+
const text = [error.message, responseBodyOf(error)].filter((part) => typeof part === "string").join("\n");
|
|
791
|
+
return /image|vision|multimodal/i.test(text) && VISION_UNSUPPORTED_KEYWORDS.test(text);
|
|
792
|
+
}
|
|
793
|
+
function imagePartBytes(image) {
|
|
794
|
+
if (typeof image === "string") {
|
|
795
|
+
const base64 = image.startsWith("data:") ? image.slice(image.indexOf(",") + 1) : image;
|
|
796
|
+
try {
|
|
797
|
+
return Buffer.from(base64, "base64");
|
|
798
|
+
} catch {
|
|
799
|
+
return null;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (image instanceof Uint8Array) return Buffer.from(image);
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
function isOversizedImageData(buf) {
|
|
806
|
+
const dims = probeImageDimensions(buf);
|
|
807
|
+
if (dims) return Math.max(dims.width, dims.height) > MAX_IMAGE_DIMENSION;
|
|
808
|
+
return buf.length > OVERSIZED_IMAGE_FALLBACK_BYTES;
|
|
809
|
+
}
|
|
810
|
+
function stripOversizedImages(messages) {
|
|
811
|
+
let removed = 0;
|
|
812
|
+
const result = messages.map((message) => {
|
|
813
|
+
if (!Array.isArray(message.content)) return message;
|
|
814
|
+
let changed = false;
|
|
815
|
+
const content = message.content.map((part) => {
|
|
816
|
+
if (part.type !== "image") return part;
|
|
817
|
+
const bytes = imagePartBytes(part.image);
|
|
818
|
+
if (!bytes || !isOversizedImageData(bytes)) return part;
|
|
819
|
+
changed = true;
|
|
820
|
+
removed++;
|
|
821
|
+
return { type: "text", text: IMAGE_REMOVED_PLACEHOLDER };
|
|
822
|
+
});
|
|
823
|
+
return changed ? { ...message, content } : message;
|
|
824
|
+
});
|
|
825
|
+
return { messages: removed > 0 ? result : messages, removed };
|
|
826
|
+
}
|
|
827
|
+
function stripAllImages(messages) {
|
|
828
|
+
let removed = 0;
|
|
829
|
+
const result = messages.map((message) => {
|
|
830
|
+
if (!Array.isArray(message.content)) return message;
|
|
831
|
+
let changed = false;
|
|
832
|
+
const content = message.content.map((part) => {
|
|
833
|
+
if (part.type !== "image") return part;
|
|
834
|
+
changed = true;
|
|
835
|
+
removed++;
|
|
836
|
+
return { type: "text", text: IMAGE_UNSUPPORTED_PLACEHOLDER };
|
|
837
|
+
});
|
|
838
|
+
return changed ? { ...message, content } : message;
|
|
839
|
+
});
|
|
840
|
+
return { messages: removed > 0 ? result : messages, removed };
|
|
841
|
+
}
|
|
842
|
+
|
|
820
843
|
// src/tools/fs/snapshots.ts
|
|
821
844
|
import { randomUUID } from "crypto";
|
|
822
845
|
import { mkdir, readFile, rm, stat, writeFile } from "fs/promises";
|
|
@@ -876,6 +899,7 @@ async function captureSnapshot(filePath, toolName, snapshotContext) {
|
|
|
876
899
|
let content = null;
|
|
877
900
|
let existed = false;
|
|
878
901
|
let contentTooLarge = false;
|
|
902
|
+
let captureFailed = false;
|
|
879
903
|
const st = await stat(filePath).catch(() => null);
|
|
880
904
|
if (st?.isFile()) {
|
|
881
905
|
existed = true;
|
|
@@ -885,7 +909,7 @@ async function captureSnapshot(filePath, toolName, snapshotContext) {
|
|
|
885
909
|
try {
|
|
886
910
|
content = await readFile(filePath);
|
|
887
911
|
} catch {
|
|
888
|
-
|
|
912
|
+
captureFailed = true;
|
|
889
913
|
}
|
|
890
914
|
}
|
|
891
915
|
}
|
|
@@ -895,6 +919,7 @@ async function captureSnapshot(filePath, toolName, snapshotContext) {
|
|
|
895
919
|
existed,
|
|
896
920
|
content,
|
|
897
921
|
contentTooLarge: contentTooLarge || void 0,
|
|
922
|
+
captureFailed: captureFailed || void 0,
|
|
898
923
|
toolName,
|
|
899
924
|
timestamp: Date.now(),
|
|
900
925
|
turn: snapshotContext?.turn ?? activeTurn,
|
|
@@ -919,7 +944,14 @@ async function pushSnapshot(snapshot) {
|
|
|
919
944
|
}
|
|
920
945
|
}
|
|
921
946
|
async function removeFromStore(ids) {
|
|
922
|
-
if (ids.length
|
|
947
|
+
if (ids.length === 0) return;
|
|
948
|
+
try {
|
|
949
|
+
await hooks?.onRemove?.(ids);
|
|
950
|
+
} catch (err) {
|
|
951
|
+
if (process.env.STAR_DEBUG) {
|
|
952
|
+
console.error("[star] failed to remove snapshot checkpoint:", err);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
923
955
|
}
|
|
924
956
|
function listSnapshots() {
|
|
925
957
|
return [...stack];
|
|
@@ -1045,6 +1077,7 @@ async function rewindToSnapshot(id, includeSubagent = false) {
|
|
|
1045
1077
|
}
|
|
1046
1078
|
|
|
1047
1079
|
// src/tools/todo.ts
|
|
1080
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1048
1081
|
import { mkdir as mkdir2, readFile as readFile2, rename, rm as rm2, writeFile as writeFile2 } from "fs/promises";
|
|
1049
1082
|
import path4 from "path";
|
|
1050
1083
|
import { z as z2 } from "zod";
|
|
@@ -1074,10 +1107,16 @@ function setTodoSession(id) {
|
|
|
1074
1107
|
}
|
|
1075
1108
|
var TodoStore = class {
|
|
1076
1109
|
items = /* @__PURE__ */ new Map();
|
|
1110
|
+
persistence;
|
|
1111
|
+
tmpSuffix = `${process.pid}-${randomUUID2()}`;
|
|
1112
|
+
saveQueue = Promise.resolve();
|
|
1077
1113
|
// Bumped on every replace() — the agent loop watches it to detect
|
|
1078
1114
|
// todo_write landings, so a list left untouched for many steps (with open
|
|
1079
1115
|
// items) can be flagged as stale and the model reminded to reconcile it.
|
|
1080
1116
|
revisionValue = 0;
|
|
1117
|
+
constructor(options = {}) {
|
|
1118
|
+
this.persistence = options.persistence ?? "file";
|
|
1119
|
+
}
|
|
1081
1120
|
get revision() {
|
|
1082
1121
|
return this.revisionValue;
|
|
1083
1122
|
}
|
|
@@ -1092,6 +1131,7 @@ var TodoStore = class {
|
|
|
1092
1131
|
}
|
|
1093
1132
|
}
|
|
1094
1133
|
async load(cwd, sessionId) {
|
|
1134
|
+
if (this.persistence === "memory") return;
|
|
1095
1135
|
let raw;
|
|
1096
1136
|
try {
|
|
1097
1137
|
raw = await readFile2(fileFor(cwd), "utf8");
|
|
@@ -1116,23 +1156,27 @@ var TodoStore = class {
|
|
|
1116
1156
|
} catch {
|
|
1117
1157
|
}
|
|
1118
1158
|
}
|
|
1119
|
-
// Atomic write (tmp + rename)
|
|
1120
|
-
//
|
|
1121
|
-
//
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
if (!persistGuard()) {
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1159
|
+
// Atomic write (unique tmp + rename) with per-store serialization: parallel
|
|
1160
|
+
// saves cannot share a temp file or finish out of order. An empty or fully
|
|
1161
|
+
// completed list has no resume value, so the file is deleted instead.
|
|
1162
|
+
save(cwd) {
|
|
1163
|
+
if (this.persistence === "memory" || !persistGuard()) return Promise.resolve();
|
|
1127
1164
|
const items = this.list();
|
|
1165
|
+
const sessionId = boundSessionId;
|
|
1166
|
+
const saving = this.saveQueue.catch(() => {
|
|
1167
|
+
}).then(() => this.saveNow(cwd, items, sessionId));
|
|
1168
|
+
this.saveQueue = saving;
|
|
1169
|
+
return saving;
|
|
1170
|
+
}
|
|
1171
|
+
async saveNow(cwd, items, sessionId) {
|
|
1128
1172
|
const file = fileFor(cwd);
|
|
1129
1173
|
if (items.length === 0 || items.every((it) => it.status === "done")) {
|
|
1130
1174
|
await rm2(file, { force: true });
|
|
1131
1175
|
return;
|
|
1132
1176
|
}
|
|
1133
1177
|
await mkdir2(path4.join(cwd, ".star"), { recursive: true });
|
|
1134
|
-
const tmp = `${file}.tmp`;
|
|
1135
|
-
await writeFile2(tmp, `${JSON.stringify({ sessionId
|
|
1178
|
+
const tmp = `${file}.${this.tmpSuffix}.tmp`;
|
|
1179
|
+
await writeFile2(tmp, `${JSON.stringify({ sessionId, items }, null, 2)}
|
|
1136
1180
|
`);
|
|
1137
1181
|
await rename(tmp, file);
|
|
1138
1182
|
}
|
|
@@ -1209,7 +1253,7 @@ function createTodoTools(store = defaultStore) {
|
|
|
1209
1253
|
|
|
1210
1254
|
// src/core/image-resize.ts
|
|
1211
1255
|
import { execFile } from "child_process";
|
|
1212
|
-
import { randomUUID as
|
|
1256
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
1213
1257
|
import { readFile as readFile3, unlink, writeFile as writeFile3 } from "fs/promises";
|
|
1214
1258
|
import os3 from "os";
|
|
1215
1259
|
import path5 from "path";
|
|
@@ -1298,8 +1342,8 @@ async function downsampleImageIfNeeded(image) {
|
|
|
1298
1342
|
if (!dims || Math.max(dims.width, dims.height) <= MAX_IMAGE_DIMENSION) {
|
|
1299
1343
|
return { image, oversized: false, resized: false };
|
|
1300
1344
|
}
|
|
1301
|
-
const inputFile = path5.join(os3.tmpdir(), `star-image-${
|
|
1302
|
-
const outputFile = path5.join(os3.tmpdir(), `star-image-${
|
|
1345
|
+
const inputFile = path5.join(os3.tmpdir(), `star-image-${randomUUID3()}.src`);
|
|
1346
|
+
const outputFile = path5.join(os3.tmpdir(), `star-image-${randomUUID3()}.png`);
|
|
1303
1347
|
try {
|
|
1304
1348
|
const [hasConvert, hasFfmpeg] = process.platform === "linux" ? await Promise.all([commandExists("convert"), commandExists("ffmpeg")]) : [false, false];
|
|
1305
1349
|
const plan = resizeImagePlan(process.platform, inputFile, outputFile, MAX_IMAGE_DIMENSION, {
|
|
@@ -1377,6 +1421,21 @@ async function walkFiles(root, skipDirs = SKIP_DIRS, options = {}) {
|
|
|
1377
1421
|
const out = [];
|
|
1378
1422
|
const limit = createLimiter(WALK_CONCURRENCY);
|
|
1379
1423
|
const signal = options.signal;
|
|
1424
|
+
let stopped = false;
|
|
1425
|
+
let callbackChain = Promise.resolve();
|
|
1426
|
+
const emitBatch = (files) => {
|
|
1427
|
+
if (!options.onBatch || files.length === 0) return callbackChain;
|
|
1428
|
+
files.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
1429
|
+
callbackChain = callbackChain.then(async () => {
|
|
1430
|
+
if (stopped) return;
|
|
1431
|
+
if (await options.onBatch?.(files) === false) stopped = true;
|
|
1432
|
+
});
|
|
1433
|
+
return callbackChain;
|
|
1434
|
+
};
|
|
1435
|
+
const collect = (file, batch) => {
|
|
1436
|
+
batch.push(file);
|
|
1437
|
+
if (options.collect !== false) out.push(file);
|
|
1438
|
+
};
|
|
1380
1439
|
const caseKey = (p) => process.platform === "win32" ? p.toLowerCase() : p;
|
|
1381
1440
|
const visited = /* @__PURE__ */ new Set();
|
|
1382
1441
|
const rootReal = await realpath(root).catch(() => null);
|
|
@@ -1404,7 +1463,7 @@ async function walkFiles(root, skipDirs = SKIP_DIRS, options = {}) {
|
|
|
1404
1463
|
return realKey === boundaryKey || realKey.startsWith(`${boundaryKey}${path6.sep}`) ? real : null;
|
|
1405
1464
|
}
|
|
1406
1465
|
async function walkDir(dir, relBase, parentLayers) {
|
|
1407
|
-
if (signal?.aborted) {
|
|
1466
|
+
if (signal?.aborted || stopped) {
|
|
1408
1467
|
return;
|
|
1409
1468
|
}
|
|
1410
1469
|
const entries = await limit(() => readdir(dir, { withFileTypes: true })).catch(() => null);
|
|
@@ -1419,8 +1478,9 @@ async function walkFiles(root, skipDirs = SKIP_DIRS, options = {}) {
|
|
|
1419
1478
|
}
|
|
1420
1479
|
}
|
|
1421
1480
|
const subs = [];
|
|
1481
|
+
const batch = [];
|
|
1422
1482
|
for (const entry of entries) {
|
|
1423
|
-
if (signal?.aborted) {
|
|
1483
|
+
if (signal?.aborted || stopped) {
|
|
1424
1484
|
break;
|
|
1425
1485
|
}
|
|
1426
1486
|
const abs = path6.join(dir, entry.name);
|
|
@@ -1463,22 +1523,26 @@ async function walkFiles(root, skipDirs = SKIP_DIRS, options = {}) {
|
|
|
1463
1523
|
continue;
|
|
1464
1524
|
}
|
|
1465
1525
|
if (options.withMtime === false) {
|
|
1466
|
-
|
|
1467
|
-
resolved === void 0 ? { abs, rel, mtimeMs: 0 } : { abs, rel, mtimeMs: 0, resolved }
|
|
1526
|
+
collect(
|
|
1527
|
+
resolved === void 0 ? { abs, rel, mtimeMs: 0 } : { abs, rel, mtimeMs: 0, resolved },
|
|
1528
|
+
batch
|
|
1468
1529
|
);
|
|
1469
1530
|
continue;
|
|
1470
1531
|
}
|
|
1471
1532
|
const st = targetStat ?? await limit(() => stat2(abs)).catch(() => null);
|
|
1472
1533
|
if (st) {
|
|
1473
|
-
|
|
1474
|
-
resolved === void 0 ? { abs, rel, mtimeMs: st.mtimeMs } : { abs, rel, mtimeMs: st.mtimeMs, resolved }
|
|
1534
|
+
collect(
|
|
1535
|
+
resolved === void 0 ? { abs, rel, mtimeMs: st.mtimeMs } : { abs, rel, mtimeMs: st.mtimeMs, resolved },
|
|
1536
|
+
batch
|
|
1475
1537
|
);
|
|
1476
1538
|
}
|
|
1477
1539
|
}
|
|
1478
1540
|
}
|
|
1541
|
+
await emitBatch(batch);
|
|
1479
1542
|
await Promise.all(subs);
|
|
1480
1543
|
}
|
|
1481
1544
|
await walkDir(root, "", []);
|
|
1545
|
+
await callbackChain;
|
|
1482
1546
|
out.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
1483
1547
|
return { files: out, aborted: signal?.aborted ?? false };
|
|
1484
1548
|
}
|
|
@@ -1677,6 +1741,10 @@ function createIgnorePredicate(cwd) {
|
|
|
1677
1741
|
|
|
1678
1742
|
// src/tools/web/fetch.ts
|
|
1679
1743
|
import dns from "dns";
|
|
1744
|
+
import http from "http";
|
|
1745
|
+
import https from "https";
|
|
1746
|
+
import { BlockList, isIPv4, isIPv6 } from "net";
|
|
1747
|
+
import { Readable } from "stream";
|
|
1680
1748
|
import { z as z3 } from "zod";
|
|
1681
1749
|
var DEFAULT_MAX_CHARS = 2e4;
|
|
1682
1750
|
var MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -1696,47 +1764,121 @@ var configuredAllowPrivateHosts = false;
|
|
|
1696
1764
|
function setWebFetchAllowPrivateHosts(allow) {
|
|
1697
1765
|
configuredAllowPrivateHosts = allow;
|
|
1698
1766
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1767
|
+
var reservedIpv4 = new BlockList();
|
|
1768
|
+
for (const [address, prefix] of [
|
|
1769
|
+
["0.0.0.0", 8],
|
|
1770
|
+
["10.0.0.0", 8],
|
|
1771
|
+
["100.64.0.0", 10],
|
|
1772
|
+
["127.0.0.0", 8],
|
|
1773
|
+
["169.254.0.0", 16],
|
|
1774
|
+
["172.16.0.0", 12],
|
|
1775
|
+
["192.0.0.0", 24],
|
|
1776
|
+
["192.0.2.0", 24],
|
|
1777
|
+
["192.88.99.0", 24],
|
|
1778
|
+
["192.168.0.0", 16],
|
|
1779
|
+
["198.18.0.0", 15],
|
|
1780
|
+
["198.51.100.0", 24],
|
|
1781
|
+
["203.0.113.0", 24],
|
|
1782
|
+
["224.0.0.0", 4],
|
|
1783
|
+
["240.0.0.0", 4]
|
|
1784
|
+
]) {
|
|
1785
|
+
reservedIpv4.addSubnet(address, prefix, "ipv4");
|
|
1786
|
+
}
|
|
1787
|
+
var reservedIpv6 = new BlockList();
|
|
1788
|
+
for (const [address, prefix] of [
|
|
1789
|
+
["::", 96],
|
|
1790
|
+
["100::", 64],
|
|
1791
|
+
["64:ff9b::", 96],
|
|
1792
|
+
["64:ff9b:1::", 48],
|
|
1793
|
+
["2001::", 23],
|
|
1794
|
+
["2001:db8::", 32],
|
|
1795
|
+
["2002::", 16],
|
|
1796
|
+
["fc00::", 7],
|
|
1797
|
+
["fe80::", 10],
|
|
1798
|
+
["fec0::", 10],
|
|
1799
|
+
["ff00::", 8]
|
|
1800
|
+
]) {
|
|
1801
|
+
reservedIpv6.addSubnet(address, prefix, "ipv6");
|
|
1802
|
+
}
|
|
1803
|
+
function mappedIpv4(ip) {
|
|
1804
|
+
const dotted = /^(?:::|(?:0:){5})ffff:(\d+\.\d+\.\d+\.\d+)$/i.exec(ip);
|
|
1805
|
+
if (dotted?.[1]) return dotted[1];
|
|
1806
|
+
const hexadecimal = /^(?:::|(?:0:){5})ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(ip);
|
|
1807
|
+
if (!hexadecimal) return null;
|
|
1808
|
+
const value = Number.parseInt(hexadecimal[1] ?? "0", 16) * 65536 + Number.parseInt(hexadecimal[2] ?? "0", 16);
|
|
1809
|
+
return [value >>> 24 & 255, value >>> 16 & 255, value >>> 8 & 255, value & 255].join(".");
|
|
1706
1810
|
}
|
|
1707
1811
|
function isPrivateAddress(address) {
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
if (
|
|
1711
|
-
if (ip
|
|
1712
|
-
if (ip
|
|
1713
|
-
|
|
1714
|
-
return false;
|
|
1812
|
+
const ip = address.replace(/^\[|\]$/g, "").split("%")[0]?.toLowerCase() ?? "";
|
|
1813
|
+
const mapped = mappedIpv4(ip);
|
|
1814
|
+
if (mapped !== null) return !isIPv4(mapped) || reservedIpv4.check(mapped, "ipv4");
|
|
1815
|
+
if (isIPv4(ip)) return reservedIpv4.check(ip, "ipv4");
|
|
1816
|
+
if (isIPv6(ip)) return reservedIpv6.check(ip, "ipv6");
|
|
1817
|
+
return true;
|
|
1715
1818
|
}
|
|
1716
1819
|
function isLocalHostname(hostname) {
|
|
1717
1820
|
const h = hostname.toLowerCase().replace(/\.$/, "");
|
|
1718
1821
|
return h === "localhost" || h.endsWith(".localhost") || h.endsWith(".local") || h.endsWith(".internal");
|
|
1719
1822
|
}
|
|
1720
|
-
async function
|
|
1823
|
+
async function validateTarget(url, resolve) {
|
|
1721
1824
|
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
1722
1825
|
if (isLocalHostname(hostname)) {
|
|
1723
|
-
return `"${hostname}" is a local/internal hostname
|
|
1826
|
+
return { refusal: `"${hostname}" is a local/internal hostname` };
|
|
1724
1827
|
}
|
|
1725
1828
|
let addresses;
|
|
1726
1829
|
try {
|
|
1727
1830
|
addresses = await resolve(hostname);
|
|
1728
1831
|
} catch (err) {
|
|
1729
1832
|
const message = err instanceof Error ? err.message : String(err);
|
|
1730
|
-
return `could not resolve "${hostname}" (${message})
|
|
1833
|
+
return { refusal: `could not resolve "${hostname}" (${message})` };
|
|
1731
1834
|
}
|
|
1732
1835
|
const blocked = addresses.find(isPrivateAddress);
|
|
1733
1836
|
if (blocked !== void 0) {
|
|
1734
|
-
return `"${hostname}" resolves to a private/reserved address (${blocked})
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1837
|
+
return { refusal: `"${hostname}" resolves to a private/reserved address (${blocked})` };
|
|
1838
|
+
}
|
|
1839
|
+
const address = addresses[0];
|
|
1840
|
+
if (address === void 0) {
|
|
1841
|
+
return { refusal: `could not resolve "${hostname}"` };
|
|
1842
|
+
}
|
|
1843
|
+
return { target: { address, family: isIPv4(address) ? 4 : 6 } };
|
|
1844
|
+
}
|
|
1845
|
+
function nativeFetch(url, signal, target) {
|
|
1846
|
+
return new Promise((resolve, reject) => {
|
|
1847
|
+
const transport = url.protocol === "https:" ? https : http;
|
|
1848
|
+
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
1849
|
+
const request = transport.request(url, {
|
|
1850
|
+
method: "GET",
|
|
1851
|
+
signal,
|
|
1852
|
+
servername: isIPv6(hostname) || isIPv4(hostname) ? "" : hostname,
|
|
1853
|
+
lookup: target ? (_hostname, options, callback) => {
|
|
1854
|
+
if (options.all) {
|
|
1855
|
+
callback(null, [{ address: target.address, family: target.family }]);
|
|
1856
|
+
} else {
|
|
1857
|
+
callback(null, target.address, target.family);
|
|
1858
|
+
}
|
|
1859
|
+
} : void 0,
|
|
1860
|
+
headers: { "accept-encoding": "identity" }
|
|
1861
|
+
});
|
|
1862
|
+
request.once("error", reject);
|
|
1863
|
+
request.once("response", (incoming) => {
|
|
1864
|
+
const headers = new Headers();
|
|
1865
|
+
for (const [name, value] of Object.entries(incoming.headers)) {
|
|
1866
|
+
if (Array.isArray(value)) {
|
|
1867
|
+
for (const item of value) headers.append(name, item);
|
|
1868
|
+
} else if (value !== void 0) {
|
|
1869
|
+
headers.set(name, value);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
resolve(
|
|
1873
|
+
new Response(Readable.toWeb(incoming), {
|
|
1874
|
+
status: incoming.statusCode ?? 500,
|
|
1875
|
+
statusText: incoming.statusMessage,
|
|
1876
|
+
headers
|
|
1877
|
+
})
|
|
1878
|
+
);
|
|
1879
|
+
});
|
|
1880
|
+
request.end();
|
|
1881
|
+
});
|
|
1740
1882
|
}
|
|
1741
1883
|
function safeCodePoint(n, raw) {
|
|
1742
1884
|
if (!Number.isInteger(n) || n < 0 || n > 1114111) {
|
|
@@ -1881,7 +2023,7 @@ function truncate(s, maxChars) {
|
|
|
1881
2023
|
}
|
|
1882
2024
|
function createWebFetchTool(options = {}) {
|
|
1883
2025
|
const resolve = options.resolver ?? defaultResolver;
|
|
1884
|
-
const fetchImpl = options.fetchImpl
|
|
2026
|
+
const fetchImpl = options.fetchImpl;
|
|
1885
2027
|
const allowPrivate = () => options.allowPrivateHosts ?? configuredAllowPrivateHosts;
|
|
1886
2028
|
return {
|
|
1887
2029
|
name: "web_fetch",
|
|
@@ -1901,20 +2043,26 @@ function createWebFetchTool(options = {}) {
|
|
|
1901
2043
|
isError: true
|
|
1902
2044
|
};
|
|
1903
2045
|
}
|
|
1904
|
-
if (!allowPrivate()) {
|
|
1905
|
-
const refusal = await privateHostRefusal(url, resolve);
|
|
1906
|
-
if (refusal !== null) {
|
|
1907
|
-
return { content: `ERROR: refused to fetch ${args.url}: ${refusal}`, isError: true };
|
|
1908
|
-
}
|
|
1909
|
-
}
|
|
1910
2046
|
const maxChars = args.maxChars ?? DEFAULT_MAX_CHARS;
|
|
1911
2047
|
const timeoutSignal = AbortSignal.timeout(TIMEOUT_MS);
|
|
1912
2048
|
const signal = ctx.abortSignal ? AbortSignal.any([timeoutSignal, ctx.abortSignal]) : timeoutSignal;
|
|
1913
2049
|
let res;
|
|
1914
2050
|
let current = url;
|
|
1915
2051
|
for (let hops = 0; ; hops += 1) {
|
|
2052
|
+
let target;
|
|
2053
|
+
if (!allowPrivate()) {
|
|
2054
|
+
const validated = await validateTarget(current, resolve);
|
|
2055
|
+
if ("refusal" in validated) {
|
|
2056
|
+
const prefix = hops === 0 ? "refused to fetch" : "refused redirect to";
|
|
2057
|
+
return {
|
|
2058
|
+
content: `ERROR: ${prefix} ${current.href}: ${validated.refusal}`,
|
|
2059
|
+
isError: true
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
target = validated.target;
|
|
2063
|
+
}
|
|
1916
2064
|
try {
|
|
1917
|
-
res = await fetchImpl(current, { signal, redirect: "manual" });
|
|
2065
|
+
res = fetchImpl ? await fetchImpl(current, { signal, redirect: "manual" }) : await nativeFetch(current, signal, target);
|
|
1918
2066
|
} catch (err) {
|
|
1919
2067
|
if (ctx.abortSignal?.aborted) {
|
|
1920
2068
|
return { content: "ERROR: request aborted", isError: true };
|
|
@@ -1944,15 +2092,6 @@ function createWebFetchTool(options = {}) {
|
|
|
1944
2092
|
isError: true
|
|
1945
2093
|
};
|
|
1946
2094
|
}
|
|
1947
|
-
if (!allowPrivate()) {
|
|
1948
|
-
const refusal = await privateHostRefusal(next, resolve);
|
|
1949
|
-
if (refusal !== null) {
|
|
1950
|
-
return {
|
|
1951
|
-
content: `ERROR: refused redirect to ${next.href}: ${refusal}`,
|
|
1952
|
-
isError: true
|
|
1953
|
-
};
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
2095
|
current = next;
|
|
1957
2096
|
continue;
|
|
1958
2097
|
}
|
|
@@ -2006,6 +2145,23 @@ var webFetchTool = createWebFetchTool();
|
|
|
2006
2145
|
export {
|
|
2007
2146
|
defaultAgentTasks,
|
|
2008
2147
|
formatAgentTaskUpdate,
|
|
2148
|
+
starHome,
|
|
2149
|
+
globalConfigPath,
|
|
2150
|
+
sessionsDir,
|
|
2151
|
+
userMemoryPath,
|
|
2152
|
+
gitTreesDir,
|
|
2153
|
+
envFilePath,
|
|
2154
|
+
projectConfigPath,
|
|
2155
|
+
loadEnvFile,
|
|
2156
|
+
upsertEnvContent,
|
|
2157
|
+
registerSensitivePatterns,
|
|
2158
|
+
sensitiveExcludePatterns,
|
|
2159
|
+
isSensitivePath,
|
|
2160
|
+
isSecretEnvName,
|
|
2161
|
+
MAX_OUTPUT,
|
|
2162
|
+
resolveShell,
|
|
2163
|
+
bashTool,
|
|
2164
|
+
defaultTaskManager,
|
|
2009
2165
|
responseBodyOf,
|
|
2010
2166
|
MAX_IMAGE_DIMENSION,
|
|
2011
2167
|
probeImageDimensions,
|
|
@@ -2014,31 +2170,15 @@ export {
|
|
|
2014
2170
|
stripOversizedImages,
|
|
2015
2171
|
stripAllImages,
|
|
2016
2172
|
downsampleImageIfNeeded,
|
|
2017
|
-
registerSensitivePatterns,
|
|
2018
|
-
isSensitivePath,
|
|
2019
|
-
isSecretEnvName,
|
|
2020
2173
|
SKIP_DIRS,
|
|
2021
2174
|
WALK_CONCURRENCY,
|
|
2022
2175
|
realpathForCheck,
|
|
2023
2176
|
walkFiles,
|
|
2024
2177
|
matchesGlob,
|
|
2025
2178
|
createIgnorePredicate,
|
|
2026
|
-
starHome,
|
|
2027
|
-
globalConfigPath,
|
|
2028
|
-
sessionsDir,
|
|
2029
|
-
userMemoryPath,
|
|
2030
|
-
gitTreesDir,
|
|
2031
|
-
envFilePath,
|
|
2032
|
-
projectConfigPath,
|
|
2033
2179
|
setWebFetchAllowPrivateHosts,
|
|
2034
2180
|
decodeEntities,
|
|
2035
2181
|
webFetchTool,
|
|
2036
|
-
loadEnvFile,
|
|
2037
|
-
upsertEnvContent,
|
|
2038
|
-
MAX_OUTPUT,
|
|
2039
|
-
resolveShell,
|
|
2040
|
-
bashTool,
|
|
2041
|
-
defaultTaskManager,
|
|
2042
2182
|
MAX_SNAPSHOT_CONTENT_BYTES,
|
|
2043
2183
|
setSnapshotHooks,
|
|
2044
2184
|
nextSnapshotId,
|
|
@@ -2066,4 +2206,4 @@ export {
|
|
|
2066
2206
|
resetTodos,
|
|
2067
2207
|
createTodoTools
|
|
2068
2208
|
};
|
|
2069
|
-
//# sourceMappingURL=chunk-
|
|
2209
|
+
//# sourceMappingURL=chunk-2ISBRSBA.js.map
|