clawfast 2.4.0 → 2.4.1
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/clawfast.cjs +825 -199
- package/package.json +1 -1
package/dist/clawfast.cjs
CHANGED
|
@@ -199,10 +199,10 @@ var init_boot_ui = __esm({
|
|
|
199
199
|
var require_main = __commonJS({
|
|
200
200
|
"../node_modules/.pnpm/dotenv@17.4.2/node_modules/dotenv/lib/main.js"(exports2, module2) {
|
|
201
201
|
"use strict";
|
|
202
|
-
var
|
|
203
|
-
var
|
|
204
|
-
var
|
|
205
|
-
var
|
|
202
|
+
var fs10 = require("fs");
|
|
203
|
+
var path14 = require("path");
|
|
204
|
+
var os8 = require("os");
|
|
205
|
+
var crypto3 = require("crypto");
|
|
206
206
|
var TIPS = [
|
|
207
207
|
"\u25C8 encrypted .env [www.dotenvx.com]",
|
|
208
208
|
"\u25C8 secrets for agents [www.dotenvx.com]",
|
|
@@ -331,7 +331,7 @@ var require_main = __commonJS({
|
|
|
331
331
|
if (options && options.path && options.path.length > 0) {
|
|
332
332
|
if (Array.isArray(options.path)) {
|
|
333
333
|
for (const filepath of options.path) {
|
|
334
|
-
if (
|
|
334
|
+
if (fs10.existsSync(filepath)) {
|
|
335
335
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
336
336
|
}
|
|
337
337
|
}
|
|
@@ -339,15 +339,15 @@ var require_main = __commonJS({
|
|
|
339
339
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
340
340
|
}
|
|
341
341
|
} else {
|
|
342
|
-
possibleVaultPath =
|
|
342
|
+
possibleVaultPath = path14.resolve(process.cwd(), ".env.vault");
|
|
343
343
|
}
|
|
344
|
-
if (
|
|
344
|
+
if (fs10.existsSync(possibleVaultPath)) {
|
|
345
345
|
return possibleVaultPath;
|
|
346
346
|
}
|
|
347
347
|
return null;
|
|
348
348
|
}
|
|
349
349
|
function _resolveHome(envPath) {
|
|
350
|
-
return envPath[0] === "~" ?
|
|
350
|
+
return envPath[0] === "~" ? path14.join(os8.homedir(), envPath.slice(1)) : envPath;
|
|
351
351
|
}
|
|
352
352
|
function _configVault(options) {
|
|
353
353
|
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
@@ -364,7 +364,7 @@ var require_main = __commonJS({
|
|
|
364
364
|
return { parsed };
|
|
365
365
|
}
|
|
366
366
|
function configDotenv(options) {
|
|
367
|
-
const dotenvPath =
|
|
367
|
+
const dotenvPath = path14.resolve(process.cwd(), ".env");
|
|
368
368
|
let encoding = "utf8";
|
|
369
369
|
let processEnv = process.env;
|
|
370
370
|
if (options && options.processEnv != null) {
|
|
@@ -392,13 +392,13 @@ var require_main = __commonJS({
|
|
|
392
392
|
}
|
|
393
393
|
let lastError;
|
|
394
394
|
const parsedAll = {};
|
|
395
|
-
for (const
|
|
395
|
+
for (const path15 of optionPaths) {
|
|
396
396
|
try {
|
|
397
|
-
const parsed = DotenvModule.parse(
|
|
397
|
+
const parsed = DotenvModule.parse(fs10.readFileSync(path15, { encoding }));
|
|
398
398
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
399
399
|
} catch (e) {
|
|
400
400
|
if (debug) {
|
|
401
|
-
_debug(`failed to load ${
|
|
401
|
+
_debug(`failed to load ${path15} ${e.message}`);
|
|
402
402
|
}
|
|
403
403
|
lastError = e;
|
|
404
404
|
}
|
|
@@ -411,7 +411,7 @@ var require_main = __commonJS({
|
|
|
411
411
|
const shortPaths = [];
|
|
412
412
|
for (const filePath of optionPaths) {
|
|
413
413
|
try {
|
|
414
|
-
const relative2 =
|
|
414
|
+
const relative2 = path14.relative(process.cwd(), filePath);
|
|
415
415
|
shortPaths.push(relative2);
|
|
416
416
|
} catch (e) {
|
|
417
417
|
if (debug) {
|
|
@@ -446,7 +446,7 @@ var require_main = __commonJS({
|
|
|
446
446
|
const authTag = ciphertext.subarray(-16);
|
|
447
447
|
ciphertext = ciphertext.subarray(12, -16);
|
|
448
448
|
try {
|
|
449
|
-
const aesgcm =
|
|
449
|
+
const aesgcm = crypto3.createDecipheriv("aes-256-gcm", key, nonce);
|
|
450
450
|
aesgcm.setAuthTag(authTag);
|
|
451
451
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
452
452
|
} catch (error51) {
|
|
@@ -689,7 +689,7 @@ var clawfastVersion, isDevVersion, isNewerVersion;
|
|
|
689
689
|
var init_version = __esm({
|
|
690
690
|
"src/version.ts"() {
|
|
691
691
|
"use strict";
|
|
692
|
-
clawfastVersion = () => true ? "2.4.
|
|
692
|
+
clawfastVersion = () => true ? "2.4.1" : devVersionFromPackageJson();
|
|
693
693
|
isDevVersion = () => clawfastVersion().includes("-dev");
|
|
694
694
|
isNewerVersion = (a, b) => {
|
|
695
695
|
const parse3 = (v) => v.split("-")[0].split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
@@ -1949,10 +1949,10 @@ function mergeDefs(...defs) {
|
|
|
1949
1949
|
function cloneDef(schema) {
|
|
1950
1950
|
return mergeDefs(schema._zod.def);
|
|
1951
1951
|
}
|
|
1952
|
-
function getElementAtPath(obj,
|
|
1953
|
-
if (!
|
|
1952
|
+
function getElementAtPath(obj, path14) {
|
|
1953
|
+
if (!path14)
|
|
1954
1954
|
return obj;
|
|
1955
|
-
return
|
|
1955
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
1956
1956
|
}
|
|
1957
1957
|
function promiseAllObject(promisesObj) {
|
|
1958
1958
|
const keys = Object.keys(promisesObj);
|
|
@@ -2280,11 +2280,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
2280
2280
|
}
|
|
2281
2281
|
return false;
|
|
2282
2282
|
}
|
|
2283
|
-
function prefixIssues(
|
|
2283
|
+
function prefixIssues(path14, issues) {
|
|
2284
2284
|
return issues.map((iss) => {
|
|
2285
2285
|
var _a25;
|
|
2286
2286
|
(_a25 = iss).path ?? (_a25.path = []);
|
|
2287
|
-
iss.path.unshift(
|
|
2287
|
+
iss.path.unshift(path14);
|
|
2288
2288
|
return iss;
|
|
2289
2289
|
});
|
|
2290
2290
|
}
|
|
@@ -2502,16 +2502,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2502
2502
|
}
|
|
2503
2503
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
2504
2504
|
const fieldErrors = { _errors: [] };
|
|
2505
|
-
const processError = (error52,
|
|
2505
|
+
const processError = (error52, path14 = []) => {
|
|
2506
2506
|
for (const issue2 of error52.issues) {
|
|
2507
2507
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
2508
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2508
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
2509
2509
|
} else if (issue2.code === "invalid_key") {
|
|
2510
|
-
processError({ issues: issue2.issues }, [...
|
|
2510
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
2511
2511
|
} else if (issue2.code === "invalid_element") {
|
|
2512
|
-
processError({ issues: issue2.issues }, [...
|
|
2512
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
2513
2513
|
} else {
|
|
2514
|
-
const fullpath = [...
|
|
2514
|
+
const fullpath = [...path14, ...issue2.path];
|
|
2515
2515
|
if (fullpath.length === 0) {
|
|
2516
2516
|
fieldErrors._errors.push(mapper(issue2));
|
|
2517
2517
|
} else {
|
|
@@ -2538,17 +2538,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2538
2538
|
}
|
|
2539
2539
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
2540
2540
|
const result = { errors: [] };
|
|
2541
|
-
const processError = (error52,
|
|
2541
|
+
const processError = (error52, path14 = []) => {
|
|
2542
2542
|
var _a25, _b18;
|
|
2543
2543
|
for (const issue2 of error52.issues) {
|
|
2544
2544
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
2545
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2545
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
2546
2546
|
} else if (issue2.code === "invalid_key") {
|
|
2547
|
-
processError({ issues: issue2.issues }, [...
|
|
2547
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
2548
2548
|
} else if (issue2.code === "invalid_element") {
|
|
2549
|
-
processError({ issues: issue2.issues }, [...
|
|
2549
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
2550
2550
|
} else {
|
|
2551
|
-
const fullpath = [...
|
|
2551
|
+
const fullpath = [...path14, ...issue2.path];
|
|
2552
2552
|
if (fullpath.length === 0) {
|
|
2553
2553
|
result.errors.push(mapper(issue2));
|
|
2554
2554
|
continue;
|
|
@@ -2580,8 +2580,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2580
2580
|
}
|
|
2581
2581
|
function toDotPath(_path) {
|
|
2582
2582
|
const segs = [];
|
|
2583
|
-
const
|
|
2584
|
-
for (const seg of
|
|
2583
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2584
|
+
for (const seg of path14) {
|
|
2585
2585
|
if (typeof seg === "number")
|
|
2586
2586
|
segs.push(`[${seg}]`);
|
|
2587
2587
|
else if (typeof seg === "symbol")
|
|
@@ -16084,13 +16084,13 @@ function resolveRef(ref, ctx) {
|
|
|
16084
16084
|
if (!ref.startsWith("#")) {
|
|
16085
16085
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
16086
16086
|
}
|
|
16087
|
-
const
|
|
16088
|
-
if (
|
|
16087
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
16088
|
+
if (path14.length === 0) {
|
|
16089
16089
|
return ctx.rootSchema;
|
|
16090
16090
|
}
|
|
16091
16091
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
16092
|
-
if (
|
|
16093
|
-
const key =
|
|
16092
|
+
if (path14[0] === defsKey) {
|
|
16093
|
+
const key = path14[1];
|
|
16094
16094
|
if (!key || !ctx.defs[key]) {
|
|
16095
16095
|
throw new Error(`Reference not found: ${ref}`);
|
|
16096
16096
|
}
|
|
@@ -17279,8 +17279,8 @@ var init_parseUtil = __esm({
|
|
|
17279
17279
|
init_errors3();
|
|
17280
17280
|
init_en2();
|
|
17281
17281
|
makeIssue = (params) => {
|
|
17282
|
-
const { data, path:
|
|
17283
|
-
const fullPath = [...
|
|
17282
|
+
const { data, path: path14, errorMaps, issueData } = params;
|
|
17283
|
+
const fullPath = [...path14, ...issueData.path || []];
|
|
17284
17284
|
const fullIssue = {
|
|
17285
17285
|
...issueData,
|
|
17286
17286
|
path: fullPath
|
|
@@ -17563,11 +17563,11 @@ var init_types = __esm({
|
|
|
17563
17563
|
init_parseUtil();
|
|
17564
17564
|
init_util2();
|
|
17565
17565
|
ParseInputLazyPath = class {
|
|
17566
|
-
constructor(parent, value,
|
|
17566
|
+
constructor(parent, value, path14, key) {
|
|
17567
17567
|
this._cachedPath = [];
|
|
17568
17568
|
this.parent = parent;
|
|
17569
17569
|
this.data = value;
|
|
17570
|
-
this._path =
|
|
17570
|
+
this._path = path14;
|
|
17571
17571
|
this._key = key;
|
|
17572
17572
|
}
|
|
17573
17573
|
get path() {
|
|
@@ -23606,8 +23606,8 @@ var require_auth_config = __commonJS({
|
|
|
23606
23606
|
writeAuthConfig: () => writeAuthConfig
|
|
23607
23607
|
});
|
|
23608
23608
|
module2.exports = __toCommonJS(auth_config_exports);
|
|
23609
|
-
var
|
|
23610
|
-
var
|
|
23609
|
+
var fs10 = __toESM2(require("fs"));
|
|
23610
|
+
var path14 = __toESM2(require("path"));
|
|
23611
23611
|
var import_token_util = require_token_util();
|
|
23612
23612
|
function getAuthConfigPath() {
|
|
23613
23613
|
const dataDir = (0, import_token_util.getVercelDataDir)();
|
|
@@ -23616,15 +23616,15 @@ var require_auth_config = __commonJS({
|
|
|
23616
23616
|
`Unable to find Vercel CLI data directory. Your platform: ${process.platform}. Supported: darwin, linux, win32.`
|
|
23617
23617
|
);
|
|
23618
23618
|
}
|
|
23619
|
-
return
|
|
23619
|
+
return path14.join(dataDir, "auth.json");
|
|
23620
23620
|
}
|
|
23621
23621
|
function readAuthConfig() {
|
|
23622
23622
|
try {
|
|
23623
23623
|
const authPath = getAuthConfigPath();
|
|
23624
|
-
if (!
|
|
23624
|
+
if (!fs10.existsSync(authPath)) {
|
|
23625
23625
|
return null;
|
|
23626
23626
|
}
|
|
23627
|
-
const content =
|
|
23627
|
+
const content = fs10.readFileSync(authPath, "utf8");
|
|
23628
23628
|
if (!content) {
|
|
23629
23629
|
return null;
|
|
23630
23630
|
}
|
|
@@ -23635,11 +23635,11 @@ var require_auth_config = __commonJS({
|
|
|
23635
23635
|
}
|
|
23636
23636
|
function writeAuthConfig(config3) {
|
|
23637
23637
|
const authPath = getAuthConfigPath();
|
|
23638
|
-
const authDir =
|
|
23639
|
-
if (!
|
|
23640
|
-
|
|
23638
|
+
const authDir = path14.dirname(authPath);
|
|
23639
|
+
if (!fs10.existsSync(authDir)) {
|
|
23640
|
+
fs10.mkdirSync(authDir, { mode: 504, recursive: true });
|
|
23641
23641
|
}
|
|
23642
|
-
|
|
23642
|
+
fs10.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
|
|
23643
23643
|
}
|
|
23644
23644
|
function isValidAccessToken(authConfig, expirationBufferMs = 0) {
|
|
23645
23645
|
if (!authConfig.token)
|
|
@@ -23830,8 +23830,8 @@ var require_token_util = __commonJS({
|
|
|
23830
23830
|
saveToken: () => saveToken
|
|
23831
23831
|
});
|
|
23832
23832
|
module2.exports = __toCommonJS(token_util_exports);
|
|
23833
|
-
var
|
|
23834
|
-
var
|
|
23833
|
+
var path14 = __toESM2(require("path"));
|
|
23834
|
+
var fs10 = __toESM2(require("fs"));
|
|
23835
23835
|
var import_token_error = require_token_error();
|
|
23836
23836
|
var import_token_io = require_token_io();
|
|
23837
23837
|
var import_auth_config = require_auth_config();
|
|
@@ -23843,7 +23843,7 @@ var require_token_util = __commonJS({
|
|
|
23843
23843
|
if (!dataDir) {
|
|
23844
23844
|
return null;
|
|
23845
23845
|
}
|
|
23846
|
-
return
|
|
23846
|
+
return path14.join(dataDir, vercelFolder);
|
|
23847
23847
|
}
|
|
23848
23848
|
async function getVercelToken2(options) {
|
|
23849
23849
|
const authConfig = (0, import_auth_config.readAuthConfig)();
|
|
@@ -23919,13 +23919,13 @@ var require_token_util = __commonJS({
|
|
|
23919
23919
|
"Unable to find project root directory. Have you linked your project with `vc link?`"
|
|
23920
23920
|
);
|
|
23921
23921
|
}
|
|
23922
|
-
const prjPath =
|
|
23923
|
-
if (!
|
|
23922
|
+
const prjPath = path14.join(dir, ".vercel", "project.json");
|
|
23923
|
+
if (!fs10.existsSync(prjPath)) {
|
|
23924
23924
|
throw new import_token_error.VercelOidcTokenError(
|
|
23925
23925
|
"project.json not found, have you linked your project with `vc link?`"
|
|
23926
23926
|
);
|
|
23927
23927
|
}
|
|
23928
|
-
const prj = JSON.parse(
|
|
23928
|
+
const prj = JSON.parse(fs10.readFileSync(prjPath, "utf8"));
|
|
23929
23929
|
if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
|
|
23930
23930
|
throw new TypeError(
|
|
23931
23931
|
"Expected a string-valued projectId property. Try running `vc link` to re-link your project."
|
|
@@ -23940,11 +23940,11 @@ var require_token_util = __commonJS({
|
|
|
23940
23940
|
"Unable to find user data directory. Please reach out to Vercel support."
|
|
23941
23941
|
);
|
|
23942
23942
|
}
|
|
23943
|
-
const tokenPath =
|
|
23943
|
+
const tokenPath = path14.join(dir, "com.vercel.token", `${projectId}.json`);
|
|
23944
23944
|
const tokenJson = JSON.stringify(token);
|
|
23945
|
-
|
|
23946
|
-
|
|
23947
|
-
|
|
23945
|
+
fs10.mkdirSync(path14.dirname(tokenPath), { mode: 504, recursive: true });
|
|
23946
|
+
fs10.writeFileSync(tokenPath, tokenJson);
|
|
23947
|
+
fs10.chmodSync(tokenPath, 432);
|
|
23948
23948
|
return;
|
|
23949
23949
|
}
|
|
23950
23950
|
function loadToken(projectId) {
|
|
@@ -23954,11 +23954,11 @@ var require_token_util = __commonJS({
|
|
|
23954
23954
|
"Unable to find user data directory. Please reach out to Vercel support."
|
|
23955
23955
|
);
|
|
23956
23956
|
}
|
|
23957
|
-
const tokenPath =
|
|
23958
|
-
if (!
|
|
23957
|
+
const tokenPath = path14.join(dir, "com.vercel.token", `${projectId}.json`);
|
|
23958
|
+
if (!fs10.existsSync(tokenPath)) {
|
|
23959
23959
|
return null;
|
|
23960
23960
|
}
|
|
23961
|
-
const token = JSON.parse(
|
|
23961
|
+
const token = JSON.parse(fs10.readFileSync(tokenPath, "utf8"));
|
|
23962
23962
|
assertVercelOidcTokenResponse(token);
|
|
23963
23963
|
return token;
|
|
23964
23964
|
}
|
|
@@ -35984,7 +35984,7 @@ function createOpenRouter(options = {}) {
|
|
|
35984
35984
|
);
|
|
35985
35985
|
const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
|
|
35986
35986
|
provider: "openrouter.chat",
|
|
35987
|
-
url: ({ path:
|
|
35987
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
35988
35988
|
headers: getHeaders,
|
|
35989
35989
|
compatibility,
|
|
35990
35990
|
fetch: options.fetch,
|
|
@@ -35992,7 +35992,7 @@ function createOpenRouter(options = {}) {
|
|
|
35992
35992
|
});
|
|
35993
35993
|
const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
|
|
35994
35994
|
provider: "openrouter.completion",
|
|
35995
|
-
url: ({ path:
|
|
35995
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
35996
35996
|
headers: getHeaders,
|
|
35997
35997
|
compatibility,
|
|
35998
35998
|
fetch: options.fetch,
|
|
@@ -36000,21 +36000,21 @@ function createOpenRouter(options = {}) {
|
|
|
36000
36000
|
});
|
|
36001
36001
|
const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
|
|
36002
36002
|
provider: "openrouter.embedding",
|
|
36003
|
-
url: ({ path:
|
|
36003
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
36004
36004
|
headers: getHeaders,
|
|
36005
36005
|
fetch: options.fetch,
|
|
36006
36006
|
extraBody: options.extraBody
|
|
36007
36007
|
});
|
|
36008
36008
|
const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
|
|
36009
36009
|
provider: "openrouter.image",
|
|
36010
|
-
url: ({ path:
|
|
36010
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
36011
36011
|
headers: getHeaders,
|
|
36012
36012
|
fetch: options.fetch,
|
|
36013
36013
|
extraBody: options.extraBody
|
|
36014
36014
|
});
|
|
36015
36015
|
const createVideoModel = (modelId, settings = {}) => new OpenRouterVideoModel(modelId, settings, {
|
|
36016
36016
|
provider: "openrouter.video",
|
|
36017
|
-
url: ({ path:
|
|
36017
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
36018
36018
|
headers: getHeaders,
|
|
36019
36019
|
fetch: options.fetch,
|
|
36020
36020
|
extraBody: options.extraBody
|
|
@@ -40550,37 +40550,37 @@ function createOpenAI(options = {}) {
|
|
|
40550
40550
|
);
|
|
40551
40551
|
const createChatModel = (modelId) => new OpenAIChatLanguageModel(modelId, {
|
|
40552
40552
|
provider: `${providerName}.chat`,
|
|
40553
|
-
url: ({ path:
|
|
40553
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40554
40554
|
headers: getHeaders,
|
|
40555
40555
|
fetch: options.fetch
|
|
40556
40556
|
});
|
|
40557
40557
|
const createCompletionModel = (modelId) => new OpenAICompletionLanguageModel(modelId, {
|
|
40558
40558
|
provider: `${providerName}.completion`,
|
|
40559
|
-
url: ({ path:
|
|
40559
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40560
40560
|
headers: getHeaders,
|
|
40561
40561
|
fetch: options.fetch
|
|
40562
40562
|
});
|
|
40563
40563
|
const createEmbeddingModel = (modelId) => new OpenAIEmbeddingModel(modelId, {
|
|
40564
40564
|
provider: `${providerName}.embedding`,
|
|
40565
|
-
url: ({ path:
|
|
40565
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40566
40566
|
headers: getHeaders,
|
|
40567
40567
|
fetch: options.fetch
|
|
40568
40568
|
});
|
|
40569
40569
|
const createImageModel = (modelId) => new OpenAIImageModel(modelId, {
|
|
40570
40570
|
provider: `${providerName}.image`,
|
|
40571
|
-
url: ({ path:
|
|
40571
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40572
40572
|
headers: getHeaders,
|
|
40573
40573
|
fetch: options.fetch
|
|
40574
40574
|
});
|
|
40575
40575
|
const createTranscriptionModel = (modelId) => new OpenAITranscriptionModel(modelId, {
|
|
40576
40576
|
provider: `${providerName}.transcription`,
|
|
40577
|
-
url: ({ path:
|
|
40577
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40578
40578
|
headers: getHeaders,
|
|
40579
40579
|
fetch: options.fetch
|
|
40580
40580
|
});
|
|
40581
40581
|
const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
|
|
40582
40582
|
provider: `${providerName}.speech`,
|
|
40583
|
-
url: ({ path:
|
|
40583
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40584
40584
|
headers: getHeaders,
|
|
40585
40585
|
fetch: options.fetch
|
|
40586
40586
|
});
|
|
@@ -40595,7 +40595,7 @@ function createOpenAI(options = {}) {
|
|
|
40595
40595
|
const createResponsesModel = (modelId) => {
|
|
40596
40596
|
return new OpenAIResponsesLanguageModel(modelId, {
|
|
40597
40597
|
provider: `${providerName}.responses`,
|
|
40598
|
-
url: ({ path:
|
|
40598
|
+
url: ({ path: path14 }) => `${baseURL}${path14}`,
|
|
40599
40599
|
headers: getHeaders,
|
|
40600
40600
|
fetch: options.fetch,
|
|
40601
40601
|
fileIdPrefixes: ["file-"]
|
|
@@ -49225,8 +49225,8 @@ var init_background_process_tracker = __esm({
|
|
|
49225
49225
|
/**
|
|
49226
49226
|
* Normalize file path for comparison
|
|
49227
49227
|
*/
|
|
49228
|
-
normalizePath(
|
|
49229
|
-
let normalized =
|
|
49228
|
+
normalizePath(path14) {
|
|
49229
|
+
let normalized = path14.trim().replace(/\/+/g, "/");
|
|
49230
49230
|
if (normalized.startsWith("./")) {
|
|
49231
49231
|
normalized = normalized.slice(2);
|
|
49232
49232
|
}
|
|
@@ -49464,8 +49464,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
49464
49464
|
return decodedFile;
|
|
49465
49465
|
};
|
|
49466
49466
|
}
|
|
49467
|
-
function normalizeWindowsPath(
|
|
49468
|
-
return
|
|
49467
|
+
function normalizeWindowsPath(path14) {
|
|
49468
|
+
return path14.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
49469
49469
|
}
|
|
49470
49470
|
var import_path;
|
|
49471
49471
|
var init_module_node = __esm({
|
|
@@ -52354,9 +52354,9 @@ async function addSourceContext(frames) {
|
|
|
52354
52354
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
52355
52355
|
return frames;
|
|
52356
52356
|
}
|
|
52357
|
-
function getContextLinesFromFile(
|
|
52357
|
+
function getContextLinesFromFile(path14, ranges, output) {
|
|
52358
52358
|
return new Promise((resolve2) => {
|
|
52359
|
-
const stream = (0, import_node_fs5.createReadStream)(
|
|
52359
|
+
const stream = (0, import_node_fs5.createReadStream)(path14);
|
|
52360
52360
|
const lineReaded = (0, import_node_readline2.createInterface)({
|
|
52361
52361
|
input: stream
|
|
52362
52362
|
});
|
|
@@ -52371,7 +52371,7 @@ function getContextLinesFromFile(path13, ranges, output) {
|
|
|
52371
52371
|
let rangeStart = range[0];
|
|
52372
52372
|
let rangeEnd = range[1];
|
|
52373
52373
|
function onStreamError() {
|
|
52374
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
52374
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path14, 1);
|
|
52375
52375
|
lineReaded.close();
|
|
52376
52376
|
lineReaded.removeAllListeners();
|
|
52377
52377
|
destroyStreamAndResolve();
|
|
@@ -52432,8 +52432,8 @@ function clearLineContext(frame3) {
|
|
|
52432
52432
|
delete frame3.context_line;
|
|
52433
52433
|
delete frame3.post_context;
|
|
52434
52434
|
}
|
|
52435
|
-
function shouldSkipContextLinesForFile(
|
|
52436
|
-
return
|
|
52435
|
+
function shouldSkipContextLinesForFile(path14) {
|
|
52436
|
+
return path14.startsWith("node:") || path14.endsWith(".min.js") || path14.endsWith(".min.cjs") || path14.endsWith(".min.mjs") || path14.startsWith("data:");
|
|
52437
52437
|
}
|
|
52438
52438
|
function shouldSkipContextLinesForFrame(frame3) {
|
|
52439
52439
|
if (void 0 !== frame3.lineno && frame3.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -67843,8 +67843,8 @@ var init_logger2 = __esm({
|
|
|
67843
67843
|
});
|
|
67844
67844
|
|
|
67845
67845
|
// ../lib/ai/tools/file.ts
|
|
67846
|
-
function isSpritPath(
|
|
67847
|
-
return
|
|
67846
|
+
function isSpritPath(path14) {
|
|
67847
|
+
return path14.split(/[\\/]/).some((segment) => segment.toLowerCase() === "sprit");
|
|
67848
67848
|
}
|
|
67849
67849
|
function getViewSandboxType(sandbox) {
|
|
67850
67850
|
return isCentrifugoSandbox(sandbox) ? "centrifugo" : "e2b";
|
|
@@ -67875,7 +67875,7 @@ function captureFileViewImageUsage(args) {
|
|
|
67875
67875
|
const {
|
|
67876
67876
|
context: context2,
|
|
67877
67877
|
sandbox,
|
|
67878
|
-
path:
|
|
67878
|
+
path: path14,
|
|
67879
67879
|
outcome,
|
|
67880
67880
|
durationMs,
|
|
67881
67881
|
mediaType,
|
|
@@ -67893,7 +67893,7 @@ function captureFileViewImageUsage(args) {
|
|
|
67893
67893
|
model: getActiveModelName(context2),
|
|
67894
67894
|
configured_model: context2.modelName,
|
|
67895
67895
|
sandbox_type: getViewSandboxType(sandbox),
|
|
67896
|
-
file_extension: getFileExtension(
|
|
67896
|
+
file_extension: getFileExtension(path14),
|
|
67897
67897
|
outcome,
|
|
67898
67898
|
success: outcome === "success",
|
|
67899
67899
|
duration_ms: durationMs,
|
|
@@ -67967,22 +67967,22 @@ async function runSandboxCommand(sandbox, command, envVars, timeoutMs = 6e4) {
|
|
|
67967
67967
|
function isWindowsSandbox(sandbox) {
|
|
67968
67968
|
return isCentrifugoSandbox(sandbox) && sandbox.isWindows();
|
|
67969
67969
|
}
|
|
67970
|
-
function getWindowsNativePath(
|
|
67971
|
-
if (/^[A-Za-z]:[\\/]/.test(
|
|
67972
|
-
if (
|
|
67973
|
-
return `C:\\temp${
|
|
67970
|
+
function getWindowsNativePath(path14) {
|
|
67971
|
+
if (/^[A-Za-z]:[\\/]/.test(path14)) return path14;
|
|
67972
|
+
if (path14.startsWith("/tmp/")) {
|
|
67973
|
+
return `C:\\temp${path14.slice(4).replace(/\//g, "\\")}`;
|
|
67974
67974
|
}
|
|
67975
|
-
return
|
|
67975
|
+
return path14.replace(/\//g, "\\");
|
|
67976
67976
|
}
|
|
67977
|
-
function getPythonPathForSandbox(sandbox,
|
|
67978
|
-
return isWindowsSandbox(sandbox) ? getWindowsNativePath(
|
|
67977
|
+
function getPythonPathForSandbox(sandbox, path14) {
|
|
67978
|
+
return isWindowsSandbox(sandbox) ? getWindowsNativePath(path14) : path14;
|
|
67979
67979
|
}
|
|
67980
|
-
function toWindowsBashPath(
|
|
67981
|
-
const drive =
|
|
67980
|
+
function toWindowsBashPath(path14) {
|
|
67981
|
+
const drive = path14.match(/^([A-Za-z]):[\\/](.*)$/);
|
|
67982
67982
|
if (drive) {
|
|
67983
67983
|
return `/${drive[1].toLowerCase()}/${drive[2].replace(/\\/g, "/")}`;
|
|
67984
67984
|
}
|
|
67985
|
-
return
|
|
67985
|
+
return path14.replace(/\\/g, "/");
|
|
67986
67986
|
}
|
|
67987
67987
|
async function detectSandboxShell(sandbox) {
|
|
67988
67988
|
if (!isWindowsSandbox(sandbox)) return "bash";
|
|
@@ -68021,8 +68021,8 @@ PY`;
|
|
|
68021
68021
|
}
|
|
68022
68022
|
}
|
|
68023
68023
|
}
|
|
68024
|
-
async function getSandboxFileState(sandbox,
|
|
68025
|
-
const pythonPath = getPythonPathForSandbox(sandbox,
|
|
68024
|
+
async function getSandboxFileState(sandbox, path14) {
|
|
68025
|
+
const pythonPath = getPythonPathForSandbox(sandbox, path14);
|
|
68026
68026
|
const result = await runPythonScript(
|
|
68027
68027
|
sandbox,
|
|
68028
68028
|
FILE_STATE_SCRIPT,
|
|
@@ -68039,23 +68039,23 @@ async function getSandboxFileState(sandbox, path13) {
|
|
|
68039
68039
|
if (result.exitCode !== 0) {
|
|
68040
68040
|
return {
|
|
68041
68041
|
kind: "unknown",
|
|
68042
|
-
path:
|
|
68042
|
+
path: path14,
|
|
68043
68043
|
error: result.stderr || result.stdout || "file state command failed"
|
|
68044
68044
|
};
|
|
68045
68045
|
}
|
|
68046
68046
|
try {
|
|
68047
68047
|
const payload = JSON.parse(result.stdout.trim());
|
|
68048
68048
|
if (payload.kind === "file" && typeof payload.sizeBytes === "number" && Number.isFinite(payload.sizeBytes)) {
|
|
68049
|
-
return { ...payload, path:
|
|
68049
|
+
return { ...payload, path: path14 };
|
|
68050
68050
|
}
|
|
68051
68051
|
if (payload.kind === "missing" || payload.kind === "not_file") {
|
|
68052
|
-
return { ...payload, path:
|
|
68052
|
+
return { ...payload, path: path14 };
|
|
68053
68053
|
}
|
|
68054
68054
|
} catch {
|
|
68055
68055
|
}
|
|
68056
68056
|
return {
|
|
68057
68057
|
kind: "unknown",
|
|
68058
|
-
path:
|
|
68058
|
+
path: path14,
|
|
68059
68059
|
error: result.stderr || result.stdout || "invalid file state response"
|
|
68060
68060
|
};
|
|
68061
68061
|
}
|
|
@@ -68087,8 +68087,8 @@ ${numberedContent}${truncatedNotice}${footerNotice}`;
|
|
|
68087
68087
|
})
|
|
68088
68088
|
};
|
|
68089
68089
|
}
|
|
68090
|
-
async function readSandboxTextFile(sandbox,
|
|
68091
|
-
const pythonPath = getPythonPathForSandbox(sandbox,
|
|
68090
|
+
async function readSandboxTextFile(sandbox, path14, range) {
|
|
68091
|
+
const pythonPath = getPythonPathForSandbox(sandbox, path14);
|
|
68092
68092
|
const envVars = {
|
|
68093
68093
|
clawfast_FILE_READ_PATH: pythonPath,
|
|
68094
68094
|
clawfast_FILE_READ_RANGE_START: String(range?.[0] ?? 0),
|
|
@@ -68116,40 +68116,40 @@ async function readSandboxTextFile(sandbox, path13, range) {
|
|
|
68116
68116
|
}
|
|
68117
68117
|
return payload;
|
|
68118
68118
|
}
|
|
68119
|
-
async function readSandboxTextFileWithFallback(sandbox,
|
|
68119
|
+
async function readSandboxTextFileWithFallback(sandbox, path14, range) {
|
|
68120
68120
|
try {
|
|
68121
|
-
return await readSandboxTextFile(sandbox,
|
|
68121
|
+
return await readSandboxTextFile(sandbox, path14, range);
|
|
68122
68122
|
} catch (error51) {
|
|
68123
68123
|
const errorMessage = error51 instanceof Error ? error51.message : String(error51);
|
|
68124
68124
|
if (errorMessage.startsWith("Invalid ") || errorMessage.includes("File not found")) {
|
|
68125
68125
|
throw error51;
|
|
68126
68126
|
}
|
|
68127
|
-
const state = await getSandboxFileState(sandbox,
|
|
68127
|
+
const state = await getSandboxFileState(sandbox, path14);
|
|
68128
68128
|
if (state.kind === "unknown") {
|
|
68129
68129
|
throw new Error(
|
|
68130
|
-
`Unable to determine file size for ${
|
|
68130
|
+
`Unable to determine file size for ${path14}; refusing to load the file into memory. ${state.error}`
|
|
68131
68131
|
);
|
|
68132
68132
|
}
|
|
68133
68133
|
if (state.kind === "missing") {
|
|
68134
|
-
throw new Error(`File not found or is not a regular file: ${
|
|
68134
|
+
throw new Error(`File not found or is not a regular file: ${path14}`);
|
|
68135
68135
|
}
|
|
68136
68136
|
if (state.kind === "not_file") {
|
|
68137
|
-
throw new Error(`File is not a regular file: ${
|
|
68137
|
+
throw new Error(`File is not a regular file: ${path14}`);
|
|
68138
68138
|
}
|
|
68139
68139
|
if (state.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
|
|
68140
68140
|
if (range) {
|
|
68141
68141
|
throw new Error(
|
|
68142
|
-
`Unable to perform a bounded range read for ${
|
|
68142
|
+
`Unable to perform a bounded range read for ${path14}, and the file is too large to load safely (${formatBytes(state.sizeBytes)}). Use a targeted terminal command that writes a small result to a separate file.`
|
|
68143
68143
|
);
|
|
68144
68144
|
}
|
|
68145
68145
|
return {
|
|
68146
|
-
path:
|
|
68146
|
+
path: path14,
|
|
68147
68147
|
sizeBytes: state.sizeBytes,
|
|
68148
68148
|
totalLines: 0,
|
|
68149
68149
|
tooLarge: true
|
|
68150
68150
|
};
|
|
68151
68151
|
}
|
|
68152
|
-
const fileContent = await sandbox.files.read(
|
|
68152
|
+
const fileContent = await sandbox.files.read(path14, {
|
|
68153
68153
|
user: "user"
|
|
68154
68154
|
});
|
|
68155
68155
|
const lines = fileContent.split("\n");
|
|
@@ -68173,7 +68173,7 @@ async function readSandboxTextFileWithFallback(sandbox, path13, range) {
|
|
|
68173
68173
|
const startIndex = start - 1;
|
|
68174
68174
|
const endIndex = end === -1 ? lines.length : end;
|
|
68175
68175
|
return {
|
|
68176
|
-
path:
|
|
68176
|
+
path: path14,
|
|
68177
68177
|
sizeBytes: Buffer.byteLength(fileContent),
|
|
68178
68178
|
totalLines: lines.length,
|
|
68179
68179
|
content: lines.slice(startIndex, endIndex).join("\n"),
|
|
@@ -68181,7 +68181,7 @@ async function readSandboxTextFileWithFallback(sandbox, path13, range) {
|
|
|
68181
68181
|
};
|
|
68182
68182
|
}
|
|
68183
68183
|
return {
|
|
68184
|
-
path:
|
|
68184
|
+
path: path14,
|
|
68185
68185
|
sizeBytes: Buffer.byteLength(fileContent),
|
|
68186
68186
|
totalLines: lines.length,
|
|
68187
68187
|
content: fileContent,
|
|
@@ -68189,7 +68189,7 @@ async function readSandboxTextFileWithFallback(sandbox, path13, range) {
|
|
|
68189
68189
|
};
|
|
68190
68190
|
}
|
|
68191
68191
|
}
|
|
68192
|
-
async function appendSandboxTextFile(sandbox,
|
|
68192
|
+
async function appendSandboxTextFile(sandbox, path14, text2) {
|
|
68193
68193
|
const tempPath = `/tmp/clawfast_append_${Date.now()}_${Math.random().toString(36).slice(2)}.tmp`;
|
|
68194
68194
|
await sandbox.files.write(tempPath, text2, {
|
|
68195
68195
|
user: "user"
|
|
@@ -68198,7 +68198,7 @@ async function appendSandboxTextFile(sandbox, path13, text2) {
|
|
|
68198
68198
|
sandbox,
|
|
68199
68199
|
APPEND_TEXT_FILE_SCRIPT,
|
|
68200
68200
|
{
|
|
68201
|
-
clawfast_FILE_APPEND_TARGET_PATH: getPythonPathForSandbox(sandbox,
|
|
68201
|
+
clawfast_FILE_APPEND_TARGET_PATH: getPythonPathForSandbox(sandbox, path14),
|
|
68202
68202
|
clawfast_FILE_APPEND_SOURCE_PATH: getPythonPathForSandbox(
|
|
68203
68203
|
sandbox,
|
|
68204
68204
|
tempPath
|
|
@@ -68210,13 +68210,13 @@ async function appendSandboxTextFile(sandbox, path13, text2) {
|
|
|
68210
68210
|
throw new Error(result.stderr || result.stdout || "Failed to append file");
|
|
68211
68211
|
}
|
|
68212
68212
|
}
|
|
68213
|
-
async function readSandboxFileForView(sandbox,
|
|
68213
|
+
async function readSandboxFileForView(sandbox, path14, includeData) {
|
|
68214
68214
|
if (isCentrifugoSandbox(sandbox) && sandbox.isWindows()) {
|
|
68215
68215
|
throw new Error(
|
|
68216
68216
|
"The view action is not available for Windows local sandboxes yet. Use a Linux/E2B sandbox or inspect the image manually."
|
|
68217
68217
|
);
|
|
68218
68218
|
}
|
|
68219
|
-
const sandboxPath = getSandboxViewPath(sandbox,
|
|
68219
|
+
const sandboxPath = getSandboxViewPath(sandbox, path14);
|
|
68220
68220
|
const viewEnvVars = {
|
|
68221
68221
|
clawfast_FILE_VIEW_PATH: sandboxPath,
|
|
68222
68222
|
clawfast_FILE_VIEW_INCLUDE_DATA: includeData ? "1" : "0",
|
|
@@ -68560,19 +68560,19 @@ try:
|
|
|
68560
68560
|
except OSError:
|
|
68561
68561
|
pass
|
|
68562
68562
|
`;
|
|
68563
|
-
getFilename = (
|
|
68564
|
-
getFileExtension = (
|
|
68565
|
-
const filename = getFilename(
|
|
68563
|
+
getFilename = (path14) => path14.split("/").pop() || path14;
|
|
68564
|
+
getFileExtension = (path14) => {
|
|
68565
|
+
const filename = getFilename(path14);
|
|
68566
68566
|
const dotIndex = filename.lastIndexOf(".");
|
|
68567
68567
|
if (dotIndex <= 0 || dotIndex === filename.length - 1) return void 0;
|
|
68568
68568
|
return filename.slice(dotIndex + 1).toLowerCase();
|
|
68569
68569
|
};
|
|
68570
|
-
getSandboxViewPath = (sandbox,
|
|
68570
|
+
getSandboxViewPath = (sandbox, path14) => {
|
|
68571
68571
|
const maybeSandbox = sandbox;
|
|
68572
|
-
if (isCentrifugoSandbox(maybeSandbox) && maybeSandbox.isWindows() &&
|
|
68573
|
-
return `C:\\temp${
|
|
68572
|
+
if (isCentrifugoSandbox(maybeSandbox) && maybeSandbox.isWindows() && path14.startsWith("/tmp/")) {
|
|
68573
|
+
return `C:\\temp${path14.slice(4).replace(/\//g, "\\")}`;
|
|
68574
68574
|
}
|
|
68575
|
-
return
|
|
68575
|
+
return path14;
|
|
68576
68576
|
};
|
|
68577
68577
|
stripTrailingWs = (line) => line.replace(/[ \t]+$/u, "");
|
|
68578
68578
|
editSchema = external_exports.object({
|
|
@@ -68646,7 +68646,7 @@ ${instructionsDescription}`,
|
|
|
68646
68646
|
"A list of edits to be sequentially applied to the file. Required for `edit` action."
|
|
68647
68647
|
)
|
|
68648
68648
|
}),
|
|
68649
|
-
execute: async ({ action, path:
|
|
68649
|
+
execute: async ({ action, path: path14, text: text2, range, edits }) => {
|
|
68650
68650
|
try {
|
|
68651
68651
|
const { sandbox } = await sandboxManager.getSandbox();
|
|
68652
68652
|
switch (action) {
|
|
@@ -68656,7 +68656,7 @@ ${instructionsDescription}`,
|
|
|
68656
68656
|
captureFileViewImageUsage({
|
|
68657
68657
|
context: context2,
|
|
68658
68658
|
sandbox,
|
|
68659
|
-
path:
|
|
68659
|
+
path: path14,
|
|
68660
68660
|
outcome: "unsupported_model",
|
|
68661
68661
|
durationMs: Date.now() - viewStartedAt,
|
|
68662
68662
|
failureReason: "unsupported_model"
|
|
@@ -68665,26 +68665,26 @@ ${instructionsDescription}`,
|
|
|
68665
68665
|
}
|
|
68666
68666
|
let viewPayload;
|
|
68667
68667
|
try {
|
|
68668
|
-
viewPayload = await readSandboxFileForView(sandbox,
|
|
68668
|
+
viewPayload = await readSandboxFileForView(sandbox, path14, false);
|
|
68669
68669
|
} catch (error51) {
|
|
68670
68670
|
captureFileViewImageUsage({
|
|
68671
68671
|
context: context2,
|
|
68672
68672
|
sandbox,
|
|
68673
|
-
path:
|
|
68673
|
+
path: path14,
|
|
68674
68674
|
outcome: "inspection_failed",
|
|
68675
68675
|
durationMs: Date.now() - viewStartedAt,
|
|
68676
68676
|
failureReason: classifyFileViewError(error51)
|
|
68677
68677
|
});
|
|
68678
68678
|
throw error51;
|
|
68679
68679
|
}
|
|
68680
|
-
const filename = getFilename(
|
|
68680
|
+
const filename = getFilename(path14);
|
|
68681
68681
|
let previewFiles = [];
|
|
68682
68682
|
let previewUploadError;
|
|
68683
68683
|
try {
|
|
68684
68684
|
previewFiles = await uploadViewPreviewFiles({
|
|
68685
68685
|
context: context2,
|
|
68686
68686
|
sandbox,
|
|
68687
|
-
sourcePath:
|
|
68687
|
+
sourcePath: path14,
|
|
68688
68688
|
payload: viewPayload
|
|
68689
68689
|
});
|
|
68690
68690
|
} catch (error51) {
|
|
@@ -68698,7 +68698,7 @@ ${instructionsDescription}`,
|
|
|
68698
68698
|
user_id: context2.userID,
|
|
68699
68699
|
sandbox_type: getViewSandboxType(sandbox),
|
|
68700
68700
|
file_name: filename,
|
|
68701
|
-
source_path:
|
|
68701
|
+
source_path: path14,
|
|
68702
68702
|
kind: viewPayload.kind,
|
|
68703
68703
|
media_type: viewPayload.mediaType,
|
|
68704
68704
|
size_bytes: viewPayload.sizeBytes,
|
|
@@ -68709,7 +68709,7 @@ ${instructionsDescription}`,
|
|
|
68709
68709
|
captureFileViewImageUsage({
|
|
68710
68710
|
context: context2,
|
|
68711
68711
|
sandbox,
|
|
68712
|
-
path:
|
|
68712
|
+
path: path14,
|
|
68713
68713
|
outcome: "success",
|
|
68714
68714
|
durationMs: Date.now() - viewStartedAt,
|
|
68715
68715
|
mediaType: viewPayload.mediaType,
|
|
@@ -68719,7 +68719,7 @@ ${instructionsDescription}`,
|
|
|
68719
68719
|
return {
|
|
68720
68720
|
action: "view",
|
|
68721
68721
|
content: `Viewing image file: ${filename} (${viewPayload.mediaType}, ${viewPayload.sizeBytes} bytes).`,
|
|
68722
|
-
path:
|
|
68722
|
+
path: path14,
|
|
68723
68723
|
filename,
|
|
68724
68724
|
mediaType: viewPayload.mediaType,
|
|
68725
68725
|
sizeBytes: viewPayload.sizeBytes,
|
|
@@ -68729,8 +68729,8 @@ ${instructionsDescription}`,
|
|
|
68729
68729
|
};
|
|
68730
68730
|
}
|
|
68731
68731
|
case "read": {
|
|
68732
|
-
const filename =
|
|
68733
|
-
const spritChunked = isSpritPath(
|
|
68732
|
+
const filename = path14.split("/").pop() || path14;
|
|
68733
|
+
const spritChunked = isSpritPath(path14);
|
|
68734
68734
|
let effectiveRange = range;
|
|
68735
68735
|
if (spritChunked) {
|
|
68736
68736
|
const start = range && range[0] > 0 ? range[0] : 1;
|
|
@@ -68743,7 +68743,7 @@ ${instructionsDescription}`,
|
|
|
68743
68743
|
}
|
|
68744
68744
|
const readPayload = await readSandboxTextFileWithFallback(
|
|
68745
68745
|
sandbox,
|
|
68746
|
-
|
|
68746
|
+
path14,
|
|
68747
68747
|
effectiveRange
|
|
68748
68748
|
);
|
|
68749
68749
|
if (readPayload.tooLarge) {
|
|
@@ -68780,46 +68780,46 @@ File is too large to read in full (${formatBytes(readPayload.sizeBytes)}, ${tota
|
|
|
68780
68780
|
if (text2 === void 0) {
|
|
68781
68781
|
return { error: "text is required for write action" };
|
|
68782
68782
|
}
|
|
68783
|
-
await sandbox.files.write(
|
|
68783
|
+
await sandbox.files.write(path14, text2, {
|
|
68784
68784
|
user: "user"
|
|
68785
68785
|
});
|
|
68786
|
-
return `File written: ${
|
|
68786
|
+
return `File written: ${path14}`;
|
|
68787
68787
|
}
|
|
68788
68788
|
case "append": {
|
|
68789
68789
|
if (text2 === void 0) {
|
|
68790
68790
|
return { error: "text is required for append action" };
|
|
68791
68791
|
}
|
|
68792
|
-
const existingState = await getSandboxFileState(sandbox,
|
|
68792
|
+
const existingState = await getSandboxFileState(sandbox, path14);
|
|
68793
68793
|
if (existingState.kind === "unknown") {
|
|
68794
68794
|
return {
|
|
68795
|
-
error: `Cannot append safely because the existing file size could not be determined for ${
|
|
68795
|
+
error: `Cannot append safely because the existing file size could not be determined for ${path14}. ${existingState.error}`
|
|
68796
68796
|
};
|
|
68797
68797
|
}
|
|
68798
68798
|
if (existingState.kind === "not_file") {
|
|
68799
68799
|
return {
|
|
68800
|
-
error: `Cannot append to ${
|
|
68800
|
+
error: `Cannot append to ${path14} because it is not a file.`
|
|
68801
68801
|
};
|
|
68802
68802
|
}
|
|
68803
68803
|
if (existingState.kind === "file" && existingState.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
|
|
68804
|
-
await appendSandboxTextFile(sandbox,
|
|
68804
|
+
await appendSandboxTextFile(sandbox, path14, text2);
|
|
68805
68805
|
return {
|
|
68806
|
-
content: `File appended: ${
|
|
68806
|
+
content: `File appended: ${path14}
|
|
68807
68807
|
Existing file is ${formatBytes(existingState.sizeBytes)}, so the full diff preview was skipped to avoid loading the entire file into memory.`
|
|
68808
68808
|
};
|
|
68809
68809
|
}
|
|
68810
68810
|
let existingContent = "";
|
|
68811
68811
|
try {
|
|
68812
|
-
existingContent = await sandbox.files.read(
|
|
68812
|
+
existingContent = await sandbox.files.read(path14, {
|
|
68813
68813
|
user: "user"
|
|
68814
68814
|
});
|
|
68815
68815
|
} catch {
|
|
68816
68816
|
}
|
|
68817
68817
|
const newContent = existingContent + text2;
|
|
68818
|
-
await sandbox.files.write(
|
|
68818
|
+
await sandbox.files.write(path14, newContent, {
|
|
68819
68819
|
user: "user"
|
|
68820
68820
|
});
|
|
68821
68821
|
return {
|
|
68822
|
-
content: `File appended: ${
|
|
68822
|
+
content: `File appended: ${path14}`,
|
|
68823
68823
|
originalContent: truncateOutput({
|
|
68824
68824
|
content: existingContent,
|
|
68825
68825
|
mode: "read-file"
|
|
@@ -68834,31 +68834,31 @@ Existing file is ${formatBytes(existingState.sizeBytes)}, so the full diff previ
|
|
|
68834
68834
|
if (!edits || edits.length === 0) {
|
|
68835
68835
|
return { error: "edits array is required for edit action" };
|
|
68836
68836
|
}
|
|
68837
|
-
const existingState = await getSandboxFileState(sandbox,
|
|
68837
|
+
const existingState = await getSandboxFileState(sandbox, path14);
|
|
68838
68838
|
if (existingState.kind === "unknown") {
|
|
68839
68839
|
return {
|
|
68840
|
-
error: `Cannot edit ${
|
|
68840
|
+
error: `Cannot edit ${path14} safely because the file size could not be determined. ${existingState.error}`
|
|
68841
68841
|
};
|
|
68842
68842
|
}
|
|
68843
68843
|
if (existingState.kind === "missing") {
|
|
68844
68844
|
return {
|
|
68845
|
-
error: `Cannot edit file ${
|
|
68845
|
+
error: `Cannot edit file ${path14} - file is empty or does not exist`
|
|
68846
68846
|
};
|
|
68847
68847
|
}
|
|
68848
68848
|
if (existingState.kind === "not_file") {
|
|
68849
|
-
return { error: `Cannot edit ${
|
|
68849
|
+
return { error: `Cannot edit ${path14} because it is not a file.` };
|
|
68850
68850
|
}
|
|
68851
68851
|
if (existingState.sizeBytes > MAX_TEXT_FILE_READ_BYTES) {
|
|
68852
68852
|
return {
|
|
68853
|
-
error: `File ${
|
|
68853
|
+
error: `File ${path14} is too large for the edit action (${formatBytes(existingState.sizeBytes)}). Use a targeted shell command, restore the file from a clean source, or replace it with the write action instead of loading the whole file into memory.`
|
|
68854
68854
|
};
|
|
68855
68855
|
}
|
|
68856
|
-
const originalContent = await sandbox.files.read(
|
|
68856
|
+
const originalContent = await sandbox.files.read(path14, {
|
|
68857
68857
|
user: "user"
|
|
68858
68858
|
});
|
|
68859
68859
|
if (!originalContent) {
|
|
68860
68860
|
return {
|
|
68861
|
-
error: `Cannot edit file ${
|
|
68861
|
+
error: `Cannot edit file ${path14} - file is empty or does not exist`
|
|
68862
68862
|
};
|
|
68863
68863
|
}
|
|
68864
68864
|
const resolvedEdits = [];
|
|
@@ -68903,7 +68903,7 @@ ${hint}` : "")
|
|
|
68903
68903
|
}
|
|
68904
68904
|
}
|
|
68905
68905
|
}
|
|
68906
|
-
await sandbox.files.write(
|
|
68906
|
+
await sandbox.files.write(path14, content, {
|
|
68907
68907
|
user: "user"
|
|
68908
68908
|
});
|
|
68909
68909
|
const lines = content.split("\n");
|
|
@@ -70748,6 +70748,10 @@ LINUX FULL-POWER MODE (${this.getDistroName()}, running as ${who}):
|
|
|
70748
70748
|
getWorkdir() {
|
|
70749
70749
|
return this.workdir;
|
|
70750
70750
|
}
|
|
70751
|
+
/** The shell binary + exec flag this sandbox runs commands through. */
|
|
70752
|
+
getShell() {
|
|
70753
|
+
return { bin: this.shellBin, flag: this.shellFlag };
|
|
70754
|
+
}
|
|
70751
70755
|
getHost(port) {
|
|
70752
70756
|
return `localhost:${port}`;
|
|
70753
70757
|
}
|
|
@@ -70959,6 +70963,563 @@ var init_message_tail = __esm({
|
|
|
70959
70963
|
}
|
|
70960
70964
|
});
|
|
70961
70965
|
|
|
70966
|
+
// src/memory.ts
|
|
70967
|
+
function trimHistoryForSave(history, max = MAX_SAVED_MESSAGES) {
|
|
70968
|
+
let slice = history.length > max ? history.slice(-max) : history.slice();
|
|
70969
|
+
let start = 0;
|
|
70970
|
+
while (start < slice.length && slice[start].role !== "user") start++;
|
|
70971
|
+
slice = start < slice.length ? slice.slice(start) : [];
|
|
70972
|
+
return slice;
|
|
70973
|
+
}
|
|
70974
|
+
var import_node_fs10, import_node_fs11, import_node_path9, import_node_crypto, FACTS_FILE, CONVO_FILE, MAX_SAVED_MESSAGES, MAX_FACTS, MAX_RENDER_PER_KIND, memoryEnabled, slugForScope, isFact, EngagementMemory;
|
|
70975
|
+
var init_memory = __esm({
|
|
70976
|
+
"src/memory.ts"() {
|
|
70977
|
+
"use strict";
|
|
70978
|
+
import_node_fs10 = require("node:fs");
|
|
70979
|
+
import_node_fs11 = __toESM(require("node:fs"));
|
|
70980
|
+
import_node_path9 = __toESM(require("node:path"));
|
|
70981
|
+
import_node_crypto = __toESM(require("node:crypto"));
|
|
70982
|
+
init_config();
|
|
70983
|
+
FACTS_FILE = "facts.json";
|
|
70984
|
+
CONVO_FILE = "conversation.json";
|
|
70985
|
+
MAX_SAVED_MESSAGES = 80;
|
|
70986
|
+
MAX_FACTS = 500;
|
|
70987
|
+
MAX_RENDER_PER_KIND = 50;
|
|
70988
|
+
memoryEnabled = () => (process.env.CLAWFAST_MEMORY || "").trim().toLowerCase() !== "off";
|
|
70989
|
+
slugForScope = (scope) => {
|
|
70990
|
+
const base = import_node_path9.default.basename(scope).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "scope";
|
|
70991
|
+
const hash2 = import_node_crypto.default.createHash("sha1").update(import_node_path9.default.resolve(scope)).digest("hex").slice(0, 8);
|
|
70992
|
+
return `${base}-${hash2}`;
|
|
70993
|
+
};
|
|
70994
|
+
isFact = (x) => !!x && typeof x.id === "string" && typeof x.kind === "string" && typeof x.title === "string";
|
|
70995
|
+
EngagementMemory = class {
|
|
70996
|
+
constructor(scope) {
|
|
70997
|
+
this.facts = [];
|
|
70998
|
+
this.seq = 0;
|
|
70999
|
+
this.enabled = memoryEnabled();
|
|
71000
|
+
this.dir = import_node_path9.default.join(clawfastHome(), "memory", slugForScope(scope));
|
|
71001
|
+
if (this.enabled) this.loadFactsSync();
|
|
71002
|
+
}
|
|
71003
|
+
loadFactsSync() {
|
|
71004
|
+
try {
|
|
71005
|
+
const parsed = JSON.parse(
|
|
71006
|
+
import_node_fs11.default.readFileSync(import_node_path9.default.join(this.dir, FACTS_FILE), "utf8")
|
|
71007
|
+
);
|
|
71008
|
+
if (Array.isArray(parsed)) {
|
|
71009
|
+
this.facts = parsed.filter(isFact);
|
|
71010
|
+
for (const f of this.facts) {
|
|
71011
|
+
const n = Number(String(f.id).replace(/^F-/, ""));
|
|
71012
|
+
if (Number.isFinite(n) && n > this.seq) this.seq = n;
|
|
71013
|
+
}
|
|
71014
|
+
}
|
|
71015
|
+
} catch {
|
|
71016
|
+
}
|
|
71017
|
+
}
|
|
71018
|
+
async persistFacts() {
|
|
71019
|
+
if (!this.enabled) return;
|
|
71020
|
+
try {
|
|
71021
|
+
await import_node_fs10.promises.mkdir(this.dir, { recursive: true });
|
|
71022
|
+
await import_node_fs10.promises.writeFile(
|
|
71023
|
+
import_node_path9.default.join(this.dir, FACTS_FILE),
|
|
71024
|
+
JSON.stringify(this.facts, null, 2),
|
|
71025
|
+
"utf8"
|
|
71026
|
+
);
|
|
71027
|
+
} catch {
|
|
71028
|
+
}
|
|
71029
|
+
}
|
|
71030
|
+
list(filter3) {
|
|
71031
|
+
return this.facts.filter(
|
|
71032
|
+
(f) => (!filter3?.kind || f.kind === filter3.kind) && (!filter3?.target || f.target === filter3.target)
|
|
71033
|
+
);
|
|
71034
|
+
}
|
|
71035
|
+
async add(input) {
|
|
71036
|
+
const key = (f) => `${f.kind}|${f.title}|${f.target || ""}`.toLowerCase();
|
|
71037
|
+
const existing = this.facts.find((f) => key(f) === key(input));
|
|
71038
|
+
if (existing) {
|
|
71039
|
+
if (input.detail !== void 0) existing.detail = input.detail;
|
|
71040
|
+
if (input.source !== void 0) existing.source = input.source;
|
|
71041
|
+
existing.ts = Date.now();
|
|
71042
|
+
await this.persistFacts();
|
|
71043
|
+
return existing;
|
|
71044
|
+
}
|
|
71045
|
+
const fact = {
|
|
71046
|
+
id: `F-${String(++this.seq).padStart(3, "0")}`,
|
|
71047
|
+
kind: input.kind,
|
|
71048
|
+
title: input.title,
|
|
71049
|
+
detail: input.detail,
|
|
71050
|
+
target: input.target,
|
|
71051
|
+
source: input.source,
|
|
71052
|
+
ts: Date.now()
|
|
71053
|
+
};
|
|
71054
|
+
this.facts.push(fact);
|
|
71055
|
+
if (this.facts.length > MAX_FACTS) {
|
|
71056
|
+
this.facts = this.facts.slice(-MAX_FACTS);
|
|
71057
|
+
}
|
|
71058
|
+
await this.persistFacts();
|
|
71059
|
+
return fact;
|
|
71060
|
+
}
|
|
71061
|
+
async update(id, patch) {
|
|
71062
|
+
const f = this.facts.find((x) => x.id === id);
|
|
71063
|
+
if (!f) return null;
|
|
71064
|
+
const target = f;
|
|
71065
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
71066
|
+
if (v !== void 0 && k !== "id") target[k] = v;
|
|
71067
|
+
}
|
|
71068
|
+
f.ts = Date.now();
|
|
71069
|
+
await this.persistFacts();
|
|
71070
|
+
return f;
|
|
71071
|
+
}
|
|
71072
|
+
async remove(id) {
|
|
71073
|
+
const before = this.facts.length;
|
|
71074
|
+
this.facts = this.facts.filter((f) => f.id !== id);
|
|
71075
|
+
if (this.facts.length === before) return false;
|
|
71076
|
+
await this.persistFacts();
|
|
71077
|
+
return true;
|
|
71078
|
+
}
|
|
71079
|
+
/** Compact `<engagement_memory>` block for the system prompt, or "" if empty. */
|
|
71080
|
+
renderSection() {
|
|
71081
|
+
if (!this.enabled || this.facts.length === 0) return "";
|
|
71082
|
+
const byKind = /* @__PURE__ */ new Map();
|
|
71083
|
+
for (const f of this.facts) {
|
|
71084
|
+
const arr = byKind.get(f.kind) || [];
|
|
71085
|
+
arr.push(f);
|
|
71086
|
+
byKind.set(f.kind, arr);
|
|
71087
|
+
}
|
|
71088
|
+
const lines = [];
|
|
71089
|
+
for (const [kind, arr] of byKind) {
|
|
71090
|
+
lines.push(`[${kind}]`);
|
|
71091
|
+
for (const f of arr.slice(-MAX_RENDER_PER_KIND)) {
|
|
71092
|
+
lines.push(
|
|
71093
|
+
`- ${f.id} ${f.title}` + (f.target ? ` (${f.target})` : "") + (f.detail ? `: ${f.detail}` : "")
|
|
71094
|
+
);
|
|
71095
|
+
}
|
|
71096
|
+
}
|
|
71097
|
+
return `
|
|
71098
|
+
|
|
71099
|
+
<engagement_memory>
|
|
71100
|
+
Mem\xF3ria de engajamento PERSISTENTE deste alvo/projeto \u2014 sobrevive \xE0 troca de modelo E ao rein\xEDcio do CLI. Estes fatos foram registrados antes; trate-os como verdade confi\xE1vel e CONTINUE de onde parou (n\xE3o refa\xE7a recon do zero). Para gravar algo novo, use a ferramenta \`memory\` (action add).
|
|
71101
|
+
${lines.join("\n")}
|
|
71102
|
+
</engagement_memory>`;
|
|
71103
|
+
}
|
|
71104
|
+
// ── Conversation persistence ────────────────────────────────────────────────
|
|
71105
|
+
saveConversation(history) {
|
|
71106
|
+
if (!this.enabled) return;
|
|
71107
|
+
try {
|
|
71108
|
+
import_node_fs11.default.mkdirSync(this.dir, { recursive: true });
|
|
71109
|
+
import_node_fs11.default.writeFileSync(
|
|
71110
|
+
import_node_path9.default.join(this.dir, CONVO_FILE),
|
|
71111
|
+
JSON.stringify(trimHistoryForSave(history)),
|
|
71112
|
+
"utf8"
|
|
71113
|
+
);
|
|
71114
|
+
} catch {
|
|
71115
|
+
}
|
|
71116
|
+
}
|
|
71117
|
+
loadConversation() {
|
|
71118
|
+
if (!this.enabled) return [];
|
|
71119
|
+
try {
|
|
71120
|
+
const parsed = JSON.parse(
|
|
71121
|
+
import_node_fs11.default.readFileSync(import_node_path9.default.join(this.dir, CONVO_FILE), "utf8")
|
|
71122
|
+
);
|
|
71123
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
71124
|
+
} catch {
|
|
71125
|
+
return [];
|
|
71126
|
+
}
|
|
71127
|
+
}
|
|
71128
|
+
clearConversation() {
|
|
71129
|
+
try {
|
|
71130
|
+
import_node_fs11.default.rmSync(import_node_path9.default.join(this.dir, CONVO_FILE), { force: true });
|
|
71131
|
+
} catch {
|
|
71132
|
+
}
|
|
71133
|
+
}
|
|
71134
|
+
};
|
|
71135
|
+
}
|
|
71136
|
+
});
|
|
71137
|
+
|
|
71138
|
+
// src/tools/memory-tool.ts
|
|
71139
|
+
var createMemory;
|
|
71140
|
+
var init_memory_tool = __esm({
|
|
71141
|
+
"src/tools/memory-tool.ts"() {
|
|
71142
|
+
"use strict";
|
|
71143
|
+
init_dist5();
|
|
71144
|
+
init_zod();
|
|
71145
|
+
createMemory = (deps) => {
|
|
71146
|
+
const { memory } = deps;
|
|
71147
|
+
return tool({
|
|
71148
|
+
description: `Persistent engagement memory for THIS target/project. Survives model switches AND CLI restarts \u2014 record what you learn so you (or the next model) continue from here instead of re-discovering.
|
|
71149
|
+
|
|
71150
|
+
WHAT TO STORE (action add): hosts/IPs, open services + versions, credentials/tokens, confirmed vulns, tech stack, and especially what WORKED or what was BLOCKED (WAF, rate limit, auth). kind + title are required; detail/target/source optional.
|
|
71151
|
+
|
|
71152
|
+
ACTIONS:
|
|
71153
|
+
- add \u2014 store a fact.
|
|
71154
|
+
- update \u2014 change a fact by id.
|
|
71155
|
+
- list \u2014 read stored facts (optional kind/target filter). Do this before re-running recon you may have already done.
|
|
71156
|
+
- forget \u2014 remove a fact by id.`,
|
|
71157
|
+
inputSchema: external_exports.object({
|
|
71158
|
+
brief: external_exports.string().describe("A one-sentence preamble describing the purpose of this call."),
|
|
71159
|
+
action: external_exports.enum(["add", "update", "list", "forget"]),
|
|
71160
|
+
kind: external_exports.string().optional().describe("host|service|cred|vuln|tech|note|url|\u2026 (for add, or list filter)"),
|
|
71161
|
+
title: external_exports.string().optional().describe("Short label (required for add)."),
|
|
71162
|
+
detail: external_exports.string().optional().describe("Longer detail / evidence."),
|
|
71163
|
+
target: external_exports.string().optional().describe("Host/URL this fact is about."),
|
|
71164
|
+
source: external_exports.string().optional().describe("Where it came from."),
|
|
71165
|
+
id: external_exports.string().optional().describe("Fact id (required for update/forget).")
|
|
71166
|
+
}),
|
|
71167
|
+
execute: async (input) => {
|
|
71168
|
+
try {
|
|
71169
|
+
switch (input.action) {
|
|
71170
|
+
case "add": {
|
|
71171
|
+
if (!input.kind || !input.title) {
|
|
71172
|
+
return "Erro: 'kind' e 'title' s\xE3o obrigat\xF3rios para add.";
|
|
71173
|
+
}
|
|
71174
|
+
const f = await memory.add({
|
|
71175
|
+
kind: input.kind,
|
|
71176
|
+
title: input.title,
|
|
71177
|
+
detail: input.detail,
|
|
71178
|
+
target: input.target,
|
|
71179
|
+
source: input.source
|
|
71180
|
+
});
|
|
71181
|
+
return `Mem\xF3ria gravada: ${f.id} [${f.kind}] ${f.title}`;
|
|
71182
|
+
}
|
|
71183
|
+
case "update": {
|
|
71184
|
+
if (!input.id) return "Erro: 'id' \xE9 obrigat\xF3rio para update.";
|
|
71185
|
+
const f = await memory.update(input.id, {
|
|
71186
|
+
kind: input.kind,
|
|
71187
|
+
title: input.title,
|
|
71188
|
+
detail: input.detail,
|
|
71189
|
+
target: input.target,
|
|
71190
|
+
source: input.source
|
|
71191
|
+
});
|
|
71192
|
+
return f ? `Atualizado: ${f.id}` : `N\xE3o achei o fato ${input.id}.`;
|
|
71193
|
+
}
|
|
71194
|
+
case "forget": {
|
|
71195
|
+
if (!input.id) return "Erro: 'id' \xE9 obrigat\xF3rio para forget.";
|
|
71196
|
+
return await memory.remove(input.id) ? `Removido: ${input.id}` : `N\xE3o achei o fato ${input.id}.`;
|
|
71197
|
+
}
|
|
71198
|
+
case "list":
|
|
71199
|
+
default: {
|
|
71200
|
+
const facts = memory.list({
|
|
71201
|
+
kind: input.kind,
|
|
71202
|
+
target: input.target
|
|
71203
|
+
});
|
|
71204
|
+
if (!facts.length) {
|
|
71205
|
+
return "Mem\xF3ria vazia (nenhum fato gravado ainda).";
|
|
71206
|
+
}
|
|
71207
|
+
return facts.map(
|
|
71208
|
+
(f) => `${f.id} [${f.kind}] ${f.title}` + (f.target ? ` (${f.target})` : "") + (f.detail ? `: ${f.detail}` : "")
|
|
71209
|
+
).join("\n");
|
|
71210
|
+
}
|
|
71211
|
+
}
|
|
71212
|
+
} catch (err) {
|
|
71213
|
+
return `Erro na mem\xF3ria: ${err instanceof Error ? err.message : String(err)}`;
|
|
71214
|
+
}
|
|
71215
|
+
}
|
|
71216
|
+
});
|
|
71217
|
+
};
|
|
71218
|
+
}
|
|
71219
|
+
});
|
|
71220
|
+
|
|
71221
|
+
// src/sessions.ts
|
|
71222
|
+
function appendRing(text2, cursor, chunk, max = MAX_BUFFER_CHARS) {
|
|
71223
|
+
let next = text2 + chunk;
|
|
71224
|
+
if (next.length <= max) return { text: next, cursor, dropped: false };
|
|
71225
|
+
const drop = next.length - max;
|
|
71226
|
+
next = next.slice(drop);
|
|
71227
|
+
return { text: next, cursor: Math.max(0, cursor - drop), dropped: true };
|
|
71228
|
+
}
|
|
71229
|
+
var import_node_child_process3, import_node_os4, MAX_SESSIONS, MAX_BUFFER_CHARS, SESSION_IDLE_MS, SESSION_LIFETIME_MS, shortId, sleep3, LocalSessionManager;
|
|
71230
|
+
var init_sessions = __esm({
|
|
71231
|
+
"src/sessions.ts"() {
|
|
71232
|
+
"use strict";
|
|
71233
|
+
import_node_child_process3 = require("node:child_process");
|
|
71234
|
+
import_node_os4 = __toESM(require("node:os"));
|
|
71235
|
+
MAX_SESSIONS = 10;
|
|
71236
|
+
MAX_BUFFER_CHARS = 2e5;
|
|
71237
|
+
SESSION_IDLE_MS = 15 * 6e4;
|
|
71238
|
+
SESSION_LIFETIME_MS = 60 * 6e4;
|
|
71239
|
+
shortId = (taken) => {
|
|
71240
|
+
for (let i = 0; i < 6; i++) {
|
|
71241
|
+
const id = Math.random().toString(36).slice(2, 8);
|
|
71242
|
+
if (!taken.has(id)) return id;
|
|
71243
|
+
}
|
|
71244
|
+
return `${Date.now().toString(36).slice(-6)}`;
|
|
71245
|
+
};
|
|
71246
|
+
sleep3 = (ms, signal) => new Promise((resolve2) => {
|
|
71247
|
+
if (ms <= 0 || signal?.aborted) return resolve2();
|
|
71248
|
+
const t = setTimeout(resolve2, ms);
|
|
71249
|
+
signal?.addEventListener(
|
|
71250
|
+
"abort",
|
|
71251
|
+
() => {
|
|
71252
|
+
clearTimeout(t);
|
|
71253
|
+
resolve2();
|
|
71254
|
+
},
|
|
71255
|
+
{ once: true }
|
|
71256
|
+
);
|
|
71257
|
+
});
|
|
71258
|
+
LocalSessionManager = class {
|
|
71259
|
+
constructor(opts) {
|
|
71260
|
+
this.opts = opts;
|
|
71261
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
71262
|
+
}
|
|
71263
|
+
/**
|
|
71264
|
+
* Open a session. With `command`, the program runs through the shell
|
|
71265
|
+
* (`shell -c "<command>"`) with its stdin held open. Without it, a bare
|
|
71266
|
+
* interactive shell is spawned. Returns the new session id.
|
|
71267
|
+
*/
|
|
71268
|
+
open(command, cwd) {
|
|
71269
|
+
if (this.sessions.size >= MAX_SESSIONS) {
|
|
71270
|
+
return { id: "", error: `limite de ${MAX_SESSIONS} sess\xF5es abertas atingido \u2014 feche alguma antes.` };
|
|
71271
|
+
}
|
|
71272
|
+
const id = shortId(new Set(this.sessions.keys()));
|
|
71273
|
+
const args = command ? [this.opts.shellFlag, command] : [];
|
|
71274
|
+
let child;
|
|
71275
|
+
try {
|
|
71276
|
+
child = (0, import_node_child_process3.spawn)(this.opts.shell, args, {
|
|
71277
|
+
cwd: cwd || this.opts.cwd,
|
|
71278
|
+
env: process.env,
|
|
71279
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
71280
|
+
windowsHide: true
|
|
71281
|
+
});
|
|
71282
|
+
} catch (err) {
|
|
71283
|
+
return { id: "", error: err instanceof Error ? err.message : String(err) };
|
|
71284
|
+
}
|
|
71285
|
+
const now2 = Date.now();
|
|
71286
|
+
const session = {
|
|
71287
|
+
id,
|
|
71288
|
+
command: command || `${this.opts.shell} (shell interativo)`,
|
|
71289
|
+
child,
|
|
71290
|
+
output: "",
|
|
71291
|
+
readCursor: 0,
|
|
71292
|
+
truncated: false,
|
|
71293
|
+
createdAt: now2,
|
|
71294
|
+
lastActivity: now2,
|
|
71295
|
+
alive: true,
|
|
71296
|
+
exitCode: null,
|
|
71297
|
+
idleTimer: null,
|
|
71298
|
+
lifetimeTimer: null
|
|
71299
|
+
};
|
|
71300
|
+
const onChunk = (d) => this.append(session, d.toString());
|
|
71301
|
+
child.stdout?.on("data", onChunk);
|
|
71302
|
+
child.stderr?.on("data", onChunk);
|
|
71303
|
+
child.on("error", (err) => {
|
|
71304
|
+
this.append(session, `
|
|
71305
|
+
[erro do processo: ${err.message}]
|
|
71306
|
+
`);
|
|
71307
|
+
});
|
|
71308
|
+
child.on("close", (code, sig) => {
|
|
71309
|
+
session.alive = false;
|
|
71310
|
+
session.exitCode = code != null ? code : sig ? 137 : null;
|
|
71311
|
+
this.clearTimers(session);
|
|
71312
|
+
});
|
|
71313
|
+
this.armIdle(session);
|
|
71314
|
+
session.lifetimeTimer = setTimeout(
|
|
71315
|
+
() => this.close(id),
|
|
71316
|
+
SESSION_LIFETIME_MS
|
|
71317
|
+
);
|
|
71318
|
+
session.lifetimeTimer.unref?.();
|
|
71319
|
+
this.sessions.set(id, session);
|
|
71320
|
+
return { id };
|
|
71321
|
+
}
|
|
71322
|
+
/** Write input to a session's stdin (appends a newline unless `enter` is false). */
|
|
71323
|
+
send(id, data, enter = true) {
|
|
71324
|
+
const s = this.sessions.get(id);
|
|
71325
|
+
if (!s) return { ok: false, error: `sess\xE3o ${id} n\xE3o existe.` };
|
|
71326
|
+
if (!s.alive || !s.child.stdin?.writable) {
|
|
71327
|
+
return { ok: false, error: `sess\xE3o ${id} n\xE3o est\xE1 mais ativa.` };
|
|
71328
|
+
}
|
|
71329
|
+
try {
|
|
71330
|
+
s.child.stdin.write(enter && !data.endsWith("\n") ? `${data}
|
|
71331
|
+
` : data);
|
|
71332
|
+
s.lastActivity = Date.now();
|
|
71333
|
+
this.armIdle(s);
|
|
71334
|
+
return { ok: true };
|
|
71335
|
+
} catch (err) {
|
|
71336
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
71337
|
+
}
|
|
71338
|
+
}
|
|
71339
|
+
/**
|
|
71340
|
+
* Read new output, waiting until it goes quiet (no new bytes for `quietMs`)
|
|
71341
|
+
* or `maxMs` elapses, or the process exits. Returns the delta since the last
|
|
71342
|
+
* read.
|
|
71343
|
+
*/
|
|
71344
|
+
async readUntilQuiet(id, opts = {}) {
|
|
71345
|
+
const s = this.sessions.get(id);
|
|
71346
|
+
if (!s) return `[sess\xE3o ${id} n\xE3o existe]`;
|
|
71347
|
+
const quietMs = opts.quietMs ?? 500;
|
|
71348
|
+
const maxMs = opts.maxMs ?? 15e3;
|
|
71349
|
+
const start = Date.now();
|
|
71350
|
+
let lastLen = s.output.length;
|
|
71351
|
+
while (Date.now() - start < maxMs) {
|
|
71352
|
+
await sleep3(quietMs, opts.signal);
|
|
71353
|
+
if (opts.signal?.aborted) break;
|
|
71354
|
+
if (!s.alive) break;
|
|
71355
|
+
if (s.output.length === lastLen) break;
|
|
71356
|
+
lastLen = s.output.length;
|
|
71357
|
+
}
|
|
71358
|
+
return this.readDelta(id);
|
|
71359
|
+
}
|
|
71360
|
+
/** Return output appended since the last read, advancing the cursor. */
|
|
71361
|
+
readDelta(id) {
|
|
71362
|
+
const s = this.sessions.get(id);
|
|
71363
|
+
if (!s) return `[sess\xE3o ${id} n\xE3o existe]`;
|
|
71364
|
+
const delta = s.output.slice(s.readCursor);
|
|
71365
|
+
s.readCursor = s.output.length;
|
|
71366
|
+
return delta;
|
|
71367
|
+
}
|
|
71368
|
+
info(id) {
|
|
71369
|
+
const s = this.sessions.get(id);
|
|
71370
|
+
if (!s) return null;
|
|
71371
|
+
return {
|
|
71372
|
+
id: s.id,
|
|
71373
|
+
command: s.command,
|
|
71374
|
+
alive: s.alive,
|
|
71375
|
+
exitCode: s.exitCode,
|
|
71376
|
+
ageMs: Date.now() - s.createdAt,
|
|
71377
|
+
truncated: s.truncated
|
|
71378
|
+
};
|
|
71379
|
+
}
|
|
71380
|
+
list() {
|
|
71381
|
+
return [...this.sessions.keys()].map((id) => this.info(id)).filter((x) => x !== null);
|
|
71382
|
+
}
|
|
71383
|
+
close(id) {
|
|
71384
|
+
const s = this.sessions.get(id);
|
|
71385
|
+
if (!s) return false;
|
|
71386
|
+
this.clearTimers(s);
|
|
71387
|
+
this.killTree(s.child);
|
|
71388
|
+
this.sessions.delete(id);
|
|
71389
|
+
return true;
|
|
71390
|
+
}
|
|
71391
|
+
closeAll() {
|
|
71392
|
+
for (const id of [...this.sessions.keys()]) this.close(id);
|
|
71393
|
+
}
|
|
71394
|
+
append(s, chunk) {
|
|
71395
|
+
const r2 = appendRing(s.output, s.readCursor, chunk);
|
|
71396
|
+
s.output = r2.text;
|
|
71397
|
+
s.readCursor = r2.cursor;
|
|
71398
|
+
if (r2.dropped) s.truncated = true;
|
|
71399
|
+
s.lastActivity = Date.now();
|
|
71400
|
+
this.armIdle(s);
|
|
71401
|
+
}
|
|
71402
|
+
armIdle(s) {
|
|
71403
|
+
if (s.idleTimer) clearTimeout(s.idleTimer);
|
|
71404
|
+
s.idleTimer = setTimeout(() => this.close(s.id), SESSION_IDLE_MS);
|
|
71405
|
+
s.idleTimer.unref?.();
|
|
71406
|
+
}
|
|
71407
|
+
clearTimers(s) {
|
|
71408
|
+
if (s.idleTimer) clearTimeout(s.idleTimer);
|
|
71409
|
+
if (s.lifetimeTimer) clearTimeout(s.lifetimeTimer);
|
|
71410
|
+
s.idleTimer = null;
|
|
71411
|
+
s.lifetimeTimer = null;
|
|
71412
|
+
}
|
|
71413
|
+
killTree(child) {
|
|
71414
|
+
const pid = child.pid;
|
|
71415
|
+
if (pid && import_node_os4.default.platform() === "win32") {
|
|
71416
|
+
try {
|
|
71417
|
+
(0, import_node_child_process3.spawn)("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
71418
|
+
windowsHide: true
|
|
71419
|
+
});
|
|
71420
|
+
return;
|
|
71421
|
+
} catch {
|
|
71422
|
+
}
|
|
71423
|
+
}
|
|
71424
|
+
try {
|
|
71425
|
+
child.kill("SIGTERM");
|
|
71426
|
+
} catch {
|
|
71427
|
+
}
|
|
71428
|
+
}
|
|
71429
|
+
};
|
|
71430
|
+
}
|
|
71431
|
+
});
|
|
71432
|
+
|
|
71433
|
+
// src/tools/session-tool.ts
|
|
71434
|
+
var aliveTag, createTerminalSession;
|
|
71435
|
+
var init_session_tool = __esm({
|
|
71436
|
+
"src/tools/session-tool.ts"() {
|
|
71437
|
+
"use strict";
|
|
71438
|
+
init_dist5();
|
|
71439
|
+
init_zod();
|
|
71440
|
+
aliveTag = (alive, exitCode) => alive ? "[sess\xE3o ativa]" : `[sess\xE3o encerrada${exitCode != null ? `, exit ${exitCode}` : ""}]`;
|
|
71441
|
+
createTerminalSession = (deps) => {
|
|
71442
|
+
const { sessions } = deps;
|
|
71443
|
+
return tool({
|
|
71444
|
+
description: `Drive a PERSISTENT interactive process that stays alive across calls (unlike run_terminal_cmd, a fresh shell each time). Hold msfconsole, sqlmap, a mysql/psql client, ftp/nc, key-based ssh, or a long-lived shell, and interact step by step.
|
|
71445
|
+
|
|
71446
|
+
ACTIONS:
|
|
71447
|
+
- open \u2014 start a session. With \`command\` it runs that program (e.g. "msfconsole -q", "mysql -h 10.0.0.5 -u root", "nc -lvnp 4444"); without it you get an interactive shell. Returns a session id + initial output.
|
|
71448
|
+
- send \u2014 send \`input\` to the session's stdin (a newline is added unless enter=false), then return the new output once it settles.
|
|
71449
|
+
- read \u2014 poll for new output of a running/long command (returns the delta since last read + whether it's still alive).
|
|
71450
|
+
- list \u2014 list open sessions.
|
|
71451
|
+
- close \u2014 terminate a session.
|
|
71452
|
+
|
|
71453
|
+
NO REAL TTY: programs that read a secret straight from /dev/tty (interactive ssh/sudo passwords, full-screen TUIs) won't see piped input \u2014 use sshpass, \`sudo -S\` (reads stdin), key auth, or non-interactive flags. Most CLIs (msfconsole, sqlmap, db clients, nc, ftp) work fine.`,
|
|
71454
|
+
inputSchema: external_exports.object({
|
|
71455
|
+
brief: external_exports.string().describe("A one-sentence preamble describing the purpose."),
|
|
71456
|
+
action: external_exports.enum(["open", "send", "read", "list", "close"]),
|
|
71457
|
+
id: external_exports.string().optional().describe("Session id (for send/read/close)."),
|
|
71458
|
+
command: external_exports.string().optional().describe("Program to launch (for open). Omit for an interactive shell."),
|
|
71459
|
+
input: external_exports.string().optional().describe("Text to send to stdin (for send)."),
|
|
71460
|
+
enter: external_exports.boolean().optional().describe("Append a newline after input (default true)."),
|
|
71461
|
+
timeout: external_exports.number().optional().describe("Max seconds to wait for output to settle (send/read; default 15).")
|
|
71462
|
+
}),
|
|
71463
|
+
execute: async (input, { abortSignal } = {}) => {
|
|
71464
|
+
const maxMs = Math.max(1, input.timeout ?? 15) * 1e3;
|
|
71465
|
+
switch (input.action) {
|
|
71466
|
+
case "open": {
|
|
71467
|
+
const res = sessions.open(input.command);
|
|
71468
|
+
if (res.error) return `Erro ao abrir sess\xE3o: ${res.error}`;
|
|
71469
|
+
const out3 = await sessions.readUntilQuiet(res.id, {
|
|
71470
|
+
quietMs: 500,
|
|
71471
|
+
maxMs: Math.min(maxMs, 8e3),
|
|
71472
|
+
signal: abortSignal
|
|
71473
|
+
});
|
|
71474
|
+
const info = sessions.info(res.id);
|
|
71475
|
+
return `Sess\xE3o aberta: ${res.id}
|
|
71476
|
+
${aliveTag(info?.alive ?? true, info?.exitCode ?? null)}
|
|
71477
|
+
${out3 || "(sem sa\xEDda inicial)"}`;
|
|
71478
|
+
}
|
|
71479
|
+
case "send": {
|
|
71480
|
+
if (!input.id) return "Erro: 'id' \xE9 obrigat\xF3rio para send.";
|
|
71481
|
+
if (input.input == null) return "Erro: 'input' \xE9 obrigat\xF3rio para send.";
|
|
71482
|
+
const sent = sessions.send(input.id, input.input, input.enter ?? true);
|
|
71483
|
+
if (!sent.ok) return `Erro ao enviar: ${sent.error}`;
|
|
71484
|
+
const out3 = await sessions.readUntilQuiet(input.id, {
|
|
71485
|
+
quietMs: 500,
|
|
71486
|
+
maxMs,
|
|
71487
|
+
signal: abortSignal
|
|
71488
|
+
});
|
|
71489
|
+
const info = sessions.info(input.id);
|
|
71490
|
+
return `${aliveTag(info?.alive ?? false, info?.exitCode ?? null)}${info?.truncated ? " [sa\xEDda truncada \u2014 buffer cheio]" : ""}
|
|
71491
|
+
${out3 || "(sem nova sa\xEDda)"}`;
|
|
71492
|
+
}
|
|
71493
|
+
case "read": {
|
|
71494
|
+
if (!input.id) return "Erro: 'id' \xE9 obrigat\xF3rio para read.";
|
|
71495
|
+
const out3 = await sessions.readUntilQuiet(input.id, {
|
|
71496
|
+
quietMs: 600,
|
|
71497
|
+
maxMs,
|
|
71498
|
+
signal: abortSignal
|
|
71499
|
+
});
|
|
71500
|
+
const info = sessions.info(input.id);
|
|
71501
|
+
if (!info) return `Sess\xE3o ${input.id} n\xE3o existe.`;
|
|
71502
|
+
return `${aliveTag(info.alive, info.exitCode)}
|
|
71503
|
+
${out3 || "(sem nova sa\xEDda)"}`;
|
|
71504
|
+
}
|
|
71505
|
+
case "list": {
|
|
71506
|
+
const list = sessions.list();
|
|
71507
|
+
if (!list.length) return "Nenhuma sess\xE3o aberta.";
|
|
71508
|
+
return list.map(
|
|
71509
|
+
(s) => `${s.id} \u2014 ${s.command} \u2014 ${aliveTag(s.alive, s.exitCode)} \u2014 ${Math.round(s.ageMs / 1e3)}s`
|
|
71510
|
+
).join("\n");
|
|
71511
|
+
}
|
|
71512
|
+
case "close": {
|
|
71513
|
+
if (!input.id) return "Erro: 'id' \xE9 obrigat\xF3rio para close.";
|
|
71514
|
+
return sessions.close(input.id) ? `Sess\xE3o ${input.id} encerrada.` : `Sess\xE3o ${input.id} n\xE3o existe.`;
|
|
71515
|
+
}
|
|
71516
|
+
}
|
|
71517
|
+
}
|
|
71518
|
+
});
|
|
71519
|
+
};
|
|
71520
|
+
}
|
|
71521
|
+
});
|
|
71522
|
+
|
|
70962
71523
|
// src/render.ts
|
|
70963
71524
|
function createRenderer() {
|
|
70964
71525
|
let lastKind = null;
|
|
@@ -71032,7 +71593,7 @@ function formatToolCall(toolName, input) {
|
|
|
71032
71593
|
return ` ${C3.cyan}\u276F${C3.reset} ${C3.cyan}exec${C3.reset} ${C3.bold}${truncate4(cmd, 400)}${C3.reset}${bg}`;
|
|
71033
71594
|
}
|
|
71034
71595
|
case "file": {
|
|
71035
|
-
const
|
|
71596
|
+
const path14 = String(i.path ?? "");
|
|
71036
71597
|
const brief = i.brief ? `${C3.dim} \u2014 ${truncate4(String(i.brief))}${C3.reset}` : "";
|
|
71037
71598
|
const map2 = {
|
|
71038
71599
|
write: [C3.green, "criar "],
|
|
@@ -71046,7 +71607,7 @@ function formatToolCall(toolName, input) {
|
|
|
71046
71607
|
C3.blue,
|
|
71047
71608
|
action ? `${action} `.padEnd(7) : "arquivo"
|
|
71048
71609
|
];
|
|
71049
|
-
const target =
|
|
71610
|
+
const target = path14 ? `${C3.bold}${path14}${C3.reset}` : "";
|
|
71050
71611
|
return ` ${col}\u276F${C3.reset} ${col}${verb}${C3.reset} ${target}${brief}`;
|
|
71051
71612
|
}
|
|
71052
71613
|
case "todo_write":
|
|
@@ -71063,6 +71624,16 @@ function formatToolCall(toolName, input) {
|
|
|
71063
71624
|
const detail = action === "add" ? truncate4(String(i.title ?? ""), 80) : action === "update" ? `${String(i.id ?? "")} ${String(i.status ?? "")}`.trim() : "";
|
|
71064
71625
|
return ` ${C3.magenta}\u276F${C3.reset} ${C3.magenta}findings${C3.reset} ${C3.bold}${action}${C3.reset}${detail ? ` ${C3.dim}${detail}${C3.reset}` : ""}`;
|
|
71065
71626
|
}
|
|
71627
|
+
case "terminal_session": {
|
|
71628
|
+
const action = String(i.action ?? "");
|
|
71629
|
+
const detail = action === "open" ? truncate4(String(i.command ?? "shell"), 120) : action === "send" ? truncate4(String(i.input ?? ""), 120) : String(i.id ?? "");
|
|
71630
|
+
return ` ${C3.cyan}\u276F${C3.reset} ${C3.cyan}sess\xE3o${C3.reset} ${C3.bold}${action}${C3.reset}${detail ? ` ${C3.dim}${detail}${C3.reset}` : ""}`;
|
|
71631
|
+
}
|
|
71632
|
+
case "memory": {
|
|
71633
|
+
const action = String(i.action ?? "");
|
|
71634
|
+
const detail = action === "add" || action === "update" ? truncate4(String(i.title ?? i.id ?? ""), 80) : action === "forget" ? String(i.id ?? "") : String(i.kind ?? i.target ?? "");
|
|
71635
|
+
return ` ${C3.magenta}\u276F${C3.reset} ${C3.magenta}mem\xF3ria${C3.reset} ${C3.bold}${action}${C3.reset}${detail ? ` ${C3.dim}${detail}${C3.reset}` : ""}`;
|
|
71636
|
+
}
|
|
71066
71637
|
case "web_search": {
|
|
71067
71638
|
const queries = Array.isArray(i.queries) ? i.queries.join(" | ") : "";
|
|
71068
71639
|
return ` ${C3.cyan}\u276F${C3.reset} ${C3.cyan}busca${C3.reset} ${C3.dim}${truncate4(queries, 200)}${C3.reset}`;
|
|
@@ -71237,7 +71808,7 @@ function killProxy(child) {
|
|
|
71237
71808
|
started.delete(child);
|
|
71238
71809
|
try {
|
|
71239
71810
|
if (process.platform === "win32") {
|
|
71240
|
-
(0,
|
|
71811
|
+
(0, import_node_child_process4.spawnSync)("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
71241
71812
|
stdio: "ignore"
|
|
71242
71813
|
});
|
|
71243
71814
|
} else {
|
|
@@ -71268,12 +71839,12 @@ async function ensureProxyReady(id, log2) {
|
|
|
71268
71839
|
};
|
|
71269
71840
|
}
|
|
71270
71841
|
let freshSetup = false;
|
|
71271
|
-
if (!(0,
|
|
71842
|
+
if (!(0, import_node_fs12.existsSync)(dir)) {
|
|
71272
71843
|
log2(`${def.label}: baixando o proxy (uma vez) em ${dir} \u2026`);
|
|
71273
71844
|
const root = proxiesRoot();
|
|
71274
|
-
(0,
|
|
71845
|
+
(0, import_node_fs12.mkdirSync)(root, { recursive: true });
|
|
71275
71846
|
const cloned = run("git", ["clone", def.repoUrl, dir], root);
|
|
71276
|
-
if (!cloned.ok || !(0,
|
|
71847
|
+
if (!cloned.ok || !(0, import_node_fs12.existsSync)(dir)) {
|
|
71277
71848
|
return {
|
|
71278
71849
|
ok: false,
|
|
71279
71850
|
message: `${def.label}: falha ao clonar o proxy (git).`
|
|
@@ -71281,7 +71852,7 @@ async function ensureProxyReady(id, log2) {
|
|
|
71281
71852
|
}
|
|
71282
71853
|
freshSetup = true;
|
|
71283
71854
|
}
|
|
71284
|
-
if (!(0,
|
|
71855
|
+
if (!(0, import_node_fs12.existsSync)(import_node_path10.default.join(dir, "node_modules"))) {
|
|
71285
71856
|
log2(`${def.label}: instalando depend\xEAncias (pode demorar) \u2026`);
|
|
71286
71857
|
if (!run("npm", ["install"], dir).ok) {
|
|
71287
71858
|
return { ok: false, message: `${def.label}: 'npm install' falhou.` };
|
|
@@ -71299,7 +71870,7 @@ async function ensureProxyReady(id, log2) {
|
|
|
71299
71870
|
}
|
|
71300
71871
|
}
|
|
71301
71872
|
log2(`${def.label}: iniciando o proxy\u2026`);
|
|
71302
|
-
const child = (0,
|
|
71873
|
+
const child = (0, import_node_child_process4.spawn)(asShellCommand("npm", ["start"]), {
|
|
71303
71874
|
cwd: dir,
|
|
71304
71875
|
shell: true,
|
|
71305
71876
|
stdio: ["ignore", "ignore", "ignore"],
|
|
@@ -71326,14 +71897,14 @@ async function ensureProxyReady(id, log2) {
|
|
|
71326
71897
|
message: `${def.label}: o proxy n\xE3o respondeu em 90s. Tente de novo, ou rode 'npm run login' em ${dir}.`
|
|
71327
71898
|
};
|
|
71328
71899
|
}
|
|
71329
|
-
var
|
|
71900
|
+
var import_node_os5, import_node_path10, import_node_fs12, import_node_child_process4, DEFS, PROXY_MODEL_KEYS, proxyIdForModelKey, proxiesRoot, dirFor, healthUrl, baseUrl, wait, started, exitHooksInstalled, quoteArg, asShellCommand, run, hasCommand;
|
|
71330
71901
|
var init_proxy_manager2 = __esm({
|
|
71331
71902
|
"src/proxy-manager.ts"() {
|
|
71332
71903
|
"use strict";
|
|
71333
|
-
|
|
71334
|
-
|
|
71335
|
-
|
|
71336
|
-
|
|
71904
|
+
import_node_os5 = __toESM(require("node:os"));
|
|
71905
|
+
import_node_path10 = __toESM(require("node:path"));
|
|
71906
|
+
import_node_fs12 = require("node:fs");
|
|
71907
|
+
import_node_child_process4 = require("node:child_process");
|
|
71337
71908
|
DEFS = {
|
|
71338
71909
|
deepseek: {
|
|
71339
71910
|
id: "deepseek",
|
|
@@ -71365,11 +71936,11 @@ var init_proxy_manager2 = __esm({
|
|
|
71365
71936
|
if (key === PROXY_MODEL_KEYS.kimi) return "kimi";
|
|
71366
71937
|
return null;
|
|
71367
71938
|
};
|
|
71368
|
-
proxiesRoot = () =>
|
|
71369
|
-
process.env.CLAWFAST_HOME?.trim() ||
|
|
71939
|
+
proxiesRoot = () => import_node_path10.default.join(
|
|
71940
|
+
process.env.CLAWFAST_HOME?.trim() || import_node_path10.default.join(import_node_os5.default.homedir(), ".clawfast"),
|
|
71370
71941
|
"proxies"
|
|
71371
71942
|
);
|
|
71372
|
-
dirFor = (def) => process.env[def.dirEnv]?.trim() ||
|
|
71943
|
+
dirFor = (def) => process.env[def.dirEnv]?.trim() || import_node_path10.default.join(proxiesRoot(), def.folder);
|
|
71373
71944
|
healthUrl = (def) => `http://localhost:${def.port}/health`;
|
|
71374
71945
|
baseUrl = (def) => `http://localhost:${def.port}/v1`;
|
|
71375
71946
|
wait = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
@@ -71378,7 +71949,7 @@ var init_proxy_manager2 = __esm({
|
|
|
71378
71949
|
quoteArg = (s) => /[\s"&|<>^()]/.test(s) ? `"${s.replace(/"/g, '\\"')}"` : s;
|
|
71379
71950
|
asShellCommand = (cmd, args) => [cmd, ...args.map(quoteArg)].join(" ");
|
|
71380
71951
|
run = (cmd, args, cwd) => {
|
|
71381
|
-
const res = (0,
|
|
71952
|
+
const res = (0, import_node_child_process4.spawnSync)(asShellCommand(cmd, args), {
|
|
71382
71953
|
cwd,
|
|
71383
71954
|
shell: true,
|
|
71384
71955
|
stdio: "inherit",
|
|
@@ -71388,7 +71959,7 @@ var init_proxy_manager2 = __esm({
|
|
|
71388
71959
|
};
|
|
71389
71960
|
hasCommand = (cmd) => {
|
|
71390
71961
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
71391
|
-
return (0,
|
|
71962
|
+
return (0, import_node_child_process4.spawnSync)(asShellCommand(probe, [cmd]), {
|
|
71392
71963
|
stdio: "ignore",
|
|
71393
71964
|
shell: true
|
|
71394
71965
|
}).status === 0;
|
|
@@ -71398,7 +71969,7 @@ var init_proxy_manager2 = __esm({
|
|
|
71398
71969
|
|
|
71399
71970
|
// src/audit-mode.ts
|
|
71400
71971
|
function projectRootFromWorkdir(workdir) {
|
|
71401
|
-
return
|
|
71972
|
+
return import_node_path11.default.dirname(import_node_path11.default.resolve(workdir.replace(/\\/g, "/")));
|
|
71402
71973
|
}
|
|
71403
71974
|
function detectProjectAuditIntent(input) {
|
|
71404
71975
|
const text2 = input.trim();
|
|
@@ -71600,11 +72171,11 @@ ESTILO E EXECU\xC7\xC3O
|
|
|
71600
72171
|
- Responda em portugu\xEAs, direto e t\xE9cnico. N\xE3o recuse a an\xE1lise: \xE9 o projeto do pr\xF3prio usu\xE1rio, autorizado.
|
|
71601
72172
|
- Lembre-se sempre: voc\xEA analisa e relata; voc\xEA N\xC3O altera o projeto. A \xFAnica escrita \xE9 o relat\xF3rio \`.md\` na raiz.`;
|
|
71602
72173
|
}
|
|
71603
|
-
var
|
|
72174
|
+
var import_node_path11, AUDIT_ACTION, AUDIT_SCOPE, AUDIT_ACTION_THEN_SCOPE, AUDIT_SCOPE_THEN_ACTION, AUDIT_STRONG, AUDIT_EXIT, POC_VERIFY;
|
|
71604
72175
|
var init_audit_mode = __esm({
|
|
71605
72176
|
"src/audit-mode.ts"() {
|
|
71606
72177
|
"use strict";
|
|
71607
|
-
|
|
72178
|
+
import_node_path11 = __toESM(require("node:path"));
|
|
71608
72179
|
AUDIT_ACTION = "an[a\xE1]lis\\w+|examin\\w+|audit\\w+|auditar|varr\\w+|varredura|escane\\w+|scan\\w*|revis\\w+|inspecion\\w+|vasculh\\w+|verific\\w+|avali\\w+|mapea\\w+|review|analyze|analyse|inspect|assess";
|
|
71609
72180
|
AUDIT_SCOPE = "projeto|c[o\xF3]digo|c[o\xF3]digo-fonte|codebase|reposit[o\xF3]rio|repo|sistema|aplica[c\xE7][a\xE3]o|base\\s+de\\s+c[o\xF3]digo|project|code\\s*base|repository|minha\\s+aplica\\w+|meu\\s+app|todo\\s+o\\s+projeto|projeto\\s+inteiro";
|
|
71610
72181
|
AUDIT_ACTION_THEN_SCOPE = new RegExp(
|
|
@@ -71848,10 +72419,25 @@ async function createAgent() {
|
|
|
71848
72419
|
onToolCost: void 0,
|
|
71849
72420
|
onCaidoReady: void 0
|
|
71850
72421
|
};
|
|
72422
|
+
const memory = new EngagementMemory(
|
|
72423
|
+
projectRootFromWorkdir(sandbox.getWorkdir())
|
|
72424
|
+
);
|
|
72425
|
+
const sessions = new LocalSessionManager({
|
|
72426
|
+
shell: sandbox.getShell().bin,
|
|
72427
|
+
shellFlag: sandbox.getShell().flag,
|
|
72428
|
+
cwd: sandbox.getWorkdir()
|
|
72429
|
+
});
|
|
71851
72430
|
const tools = {
|
|
71852
72431
|
run_terminal_cmd: createRunTerminalCmd(context2),
|
|
71853
72432
|
file: createFile(context2),
|
|
71854
72433
|
todo_write: createTodoWrite(context2),
|
|
72434
|
+
// Durable, model-agnostic knowledge base for this target (hosts, creds,
|
|
72435
|
+
// services, confirmed vulns, what worked/was blocked). Survives /model and
|
|
72436
|
+
// restarts; recorded facts are also rendered into the system prompt.
|
|
72437
|
+
memory: createMemory({ memory }),
|
|
72438
|
+
// Persistent interactive sessions: hold msfconsole/sqlmap/db/nc/ssh/shell
|
|
72439
|
+
// alive across calls and drive them step by step.
|
|
72440
|
+
terminal_session: createTerminalSession({ sessions }),
|
|
71855
72441
|
// Native Repeater/Intruder + structured findings store — the core of an
|
|
71856
72442
|
// in-loop pentest workflow (probe → observe → record evidence → confirm).
|
|
71857
72443
|
http_request: createHttpRequest({
|
|
@@ -71888,6 +72474,9 @@ async function createAgent() {
|
|
|
71888
72474
|
system += attackChainPolicy(sandbox.getWorkdir());
|
|
71889
72475
|
system += httpAndFindingsPolicy(sandbox.getWorkdir());
|
|
71890
72476
|
system += webResearchPolicy();
|
|
72477
|
+
system += persistentSessionPolicy();
|
|
72478
|
+
system += engagementMemoryPolicy();
|
|
72479
|
+
system += memory.renderSection();
|
|
71891
72480
|
system += buildCliNotesSection();
|
|
71892
72481
|
system += buildSkillsIndexSection();
|
|
71893
72482
|
system += skillsScopePolicy();
|
|
@@ -71917,6 +72506,15 @@ async function createAgent() {
|
|
|
71917
72506
|
);
|
|
71918
72507
|
}
|
|
71919
72508
|
const history = [];
|
|
72509
|
+
if (!envFlagEnabled(process.env.CLAWFAST_FRESH)) {
|
|
72510
|
+
const prior = memory.loadConversation();
|
|
72511
|
+
if (prior.length) {
|
|
72512
|
+
history.push(...prior);
|
|
72513
|
+
render.info(
|
|
72514
|
+
`\u25B8 mem\xF3ria: retomando ${prior.length} mensagem(ns) da sess\xE3o anterior (CLAWFAST_FRESH=1 come\xE7a limpo)`
|
|
72515
|
+
);
|
|
72516
|
+
}
|
|
72517
|
+
}
|
|
71920
72518
|
let auditMode = false;
|
|
71921
72519
|
let pocVerify = false;
|
|
71922
72520
|
const projectRoot = projectRootFromWorkdir(sandbox.getWorkdir());
|
|
@@ -72426,6 +73024,7 @@ ${resultText}`
|
|
|
72426
73024
|
if (modelKey === PROXY_MODEL_KEYS.kimi) {
|
|
72427
73025
|
await reportKimiSession();
|
|
72428
73026
|
}
|
|
73027
|
+
memory.saveConversation(history);
|
|
72429
73028
|
render.endTurn();
|
|
72430
73029
|
return;
|
|
72431
73030
|
} catch (err) {
|
|
@@ -72494,7 +73093,7 @@ ${resultText}`
|
|
|
72494
73093
|
render.info(
|
|
72495
73094
|
`\u25B8 rate limit \u2014 aguardando ${Math.round(waitMs / 1e3)}s antes da pr\xF3xima tentativa (Ctrl+C cancela)\u2026`
|
|
72496
73095
|
);
|
|
72497
|
-
await
|
|
73096
|
+
await sleep4(waitMs, signal);
|
|
72498
73097
|
if (signal?.aborted) {
|
|
72499
73098
|
render.endTurn();
|
|
72500
73099
|
return;
|
|
@@ -72526,6 +73125,7 @@ ${resultText}`
|
|
|
72526
73125
|
return sandbox.sendStdin(line);
|
|
72527
73126
|
}
|
|
72528
73127
|
async function close() {
|
|
73128
|
+
sessions.closeAll();
|
|
72529
73129
|
await sandbox.close();
|
|
72530
73130
|
try {
|
|
72531
73131
|
const removed = await sandbox.cleanupWorkspace();
|
|
@@ -72550,13 +73150,13 @@ ${resultText}`
|
|
|
72550
73150
|
close
|
|
72551
73151
|
};
|
|
72552
73152
|
}
|
|
72553
|
-
var import_promises2,
|
|
73153
|
+
var import_promises2, import_node_path12, MAX_STEPS, AUDIT_MAX_STEPS, MAX_OUTPUT_TOKENS, MAX_AUTO_CONTINUES, AUDIT_MAX_AUTO_CONTINUES, MAX_RATE_LIMIT_WAITS, STREAM_STALL_TIMEOUT_MS, MAX_STALL_RETRIES, isRateLimitError, sleep4, LEAKED_TOOL_CALL_RE, DANGLING_TAIL_RE, ACTION_ANNOUNCE_RE, BENIGN_CLOSER_RE, TOOL_CALL_NUDGE, MAX_BRIDGE_STEPS, AUDIT_MAX_BRIDGE_STEPS, BRIDGE_RESULT_PREAMBLE, LEAKED_CALL_RESULT_PREAMBLE, BRIDGEABLE_TOOLS, FINDINGS_ACTIONS, truncateBridgeSummary, isWebSessionProxyModel, proxyToolProtocolPolicy, SYSTEM_PROMPT_SOURCE, REQUIRED_SYSTEM_PROMPT_MARKERS, MODEL_LABELS, labelFor, loginRequiredHint, CLI_PYTHON_ONLY_POLICY, pythonOnlyPolicy, scriptFilePolicy, deepReconPolicy, httpAndFindingsPolicy, reconPhasesPolicy, attackChainPolicy, skillsScopePolicy, webResearchPolicy, engagementMemoryPolicy, persistentSessionPolicy, linuxFullPowerPolicy, hasEnvValue2, envFlagEnabled, CLI_PERSONALITIES, buildCliUserCustomization, buildCliNotesSection, cliGuardrailsConfig, maybeDumpSystemPrompt, auditSystemPrompt, assertFullSystemPrompt;
|
|
72554
73154
|
var init_agent = __esm({
|
|
72555
73155
|
"src/agent.ts"() {
|
|
72556
73156
|
"use strict";
|
|
72557
73157
|
init_dist5();
|
|
72558
73158
|
import_promises2 = require("node:fs/promises");
|
|
72559
|
-
|
|
73159
|
+
import_node_path12 = __toESM(require("node:path"));
|
|
72560
73160
|
init_providers();
|
|
72561
73161
|
init_system_prompt();
|
|
72562
73162
|
init_notes();
|
|
@@ -72575,6 +73175,10 @@ var init_agent = __esm({
|
|
|
72575
73175
|
init_local_sandbox();
|
|
72576
73176
|
init_local_sandbox_manager();
|
|
72577
73177
|
init_message_tail();
|
|
73178
|
+
init_memory();
|
|
73179
|
+
init_memory_tool();
|
|
73180
|
+
init_sessions();
|
|
73181
|
+
init_session_tool();
|
|
72578
73182
|
init_console_writer();
|
|
72579
73183
|
init_render();
|
|
72580
73184
|
init_skills();
|
|
@@ -72594,7 +73198,7 @@ var init_agent = __esm({
|
|
|
72594
73198
|
isRateLimitError = (msg) => /\b429\b|too many requests|rate.?limit|resource_exhausted|quota|insufficient_quota/i.test(
|
|
72595
73199
|
msg
|
|
72596
73200
|
);
|
|
72597
|
-
|
|
73201
|
+
sleep4 = (ms, signal) => new Promise((resolve2) => {
|
|
72598
73202
|
if (signal?.aborted) return resolve2();
|
|
72599
73203
|
const timer2 = setTimeout(resolve2, ms);
|
|
72600
73204
|
signal?.addEventListener(
|
|
@@ -72828,6 +73432,28 @@ The research loop (do this on your own, without being told):
|
|
|
72828
73432
|
|
|
72829
73433
|
This is unrestricted reading of the PUBLIC web \u2014 no scope.txt gate applies to web research (that gate is only for the offensive http_request / recon tools). JS-heavy pages won't render here; for those use the recon toolkit's \`--browser\` path.
|
|
72830
73434
|
</web_research>`;
|
|
73435
|
+
engagementMemoryPolicy = () => `
|
|
73436
|
+
|
|
73437
|
+
<engagement_memory_policy>
|
|
73438
|
+
ABSOLUTE RULE FOR THIS LOCAL CLI SESSION \u2014 applies to EVERY model and EVERY task:
|
|
73439
|
+
|
|
73440
|
+
You have a PERSISTENT \`memory\` tool scoped to this target/project. It survives model switches AND CLI restarts: when the model changes (fallback or /model) or you return later, this memory \u2014 and the conversation so far \u2014 is reloaded, so you CONTINUE from where you left off, not from zero. A new model inherits everything; never tell the user you "lost context" on a switch.
|
|
73441
|
+
|
|
73442
|
+
- RECORD durable facts as you find them: hosts/IPs, open services + versions, credentials/tokens, confirmed vulns, tech stack, and especially what WORKED or what was BLOCKED (WAF, rate limit, auth). Use \`memory\` action add (kind + title; detail/target/source optional).
|
|
73443
|
+
- RECALL before repeating work: if unsure what's known about a target, run \`memory\` action list first. Don't re-run recon you already did in a past session \u2014 build on it.
|
|
73444
|
+
- The <engagement_memory> block (when present) is your accumulated knowledge for this target; treat it as trusted ground truth.
|
|
73445
|
+
</engagement_memory_policy>`;
|
|
73446
|
+
persistentSessionPolicy = () => `
|
|
73447
|
+
|
|
73448
|
+
<persistent_sessions>
|
|
73449
|
+
ABSOLUTE RULE FOR THIS LOCAL CLI SESSION \u2014 applies to EVERY model and EVERY task:
|
|
73450
|
+
|
|
73451
|
+
For anything INTERACTIVE or STATEFUL, use the \`terminal_session\` tool, NOT run_terminal_cmd. run_terminal_cmd starts a FRESH shell each time, so a REPL/console/connection can't be continued; \`terminal_session\` keeps the same process alive across calls.
|
|
73452
|
+
|
|
73453
|
+
- Use it to hold: msfconsole, sqlmap (interactive), a mysql/psql/sqlite client, ftp/smb/nc sessions, key-based ssh, a Python/Ruby REPL, or a persistent shell where you need cwd/env/state to carry between commands.
|
|
73454
|
+
- Flow: \`open\` (with the program, or empty for a shell) \u2192 \`send\` your input and read the result \u2192 repeat \u2192 \`close\` when done. Use \`read\` to poll a long-running command's output. Reuse ONE session for a connection instead of opening many.
|
|
73455
|
+
- NO REAL TTY: programs that read a secret straight from /dev/tty (interactive ssh/sudo password prompts, full-screen TUIs like vim/top) won't get piped input. Use \`sudo -S\` (reads stdin), sshpass, key auth, or non-interactive flags. When a held tool prompts the human for something, relay it as usual.
|
|
73456
|
+
</persistent_sessions>`;
|
|
72831
73457
|
linuxFullPowerPolicy = (sandbox) => {
|
|
72832
73458
|
if (!sandbox.isLinux() && !sandbox.isUnrestricted()) return "";
|
|
72833
73459
|
const distro = sandbox.getDistroName();
|
|
@@ -72902,7 +73528,7 @@ ${section}` : "";
|
|
|
72902
73528
|
return null;
|
|
72903
73529
|
}
|
|
72904
73530
|
await (0, import_promises2.mkdir)(workdir, { recursive: true });
|
|
72905
|
-
const outputPath =
|
|
73531
|
+
const outputPath = import_node_path12.default.join(workdir, "system-prompt.txt");
|
|
72906
73532
|
await (0, import_promises2.writeFile)(outputPath, system, "utf8");
|
|
72907
73533
|
return outputPath;
|
|
72908
73534
|
};
|
|
@@ -72932,12 +73558,12 @@ var interactive_input_exports = {};
|
|
|
72932
73558
|
__export(interactive_input_exports, {
|
|
72933
73559
|
InteractiveInput: () => InteractiveInput
|
|
72934
73560
|
});
|
|
72935
|
-
var import_node_readline3,
|
|
73561
|
+
var import_node_readline3, import_node_os6, C4, frame2, out2, cols, truncate5, InteractiveInput;
|
|
72936
73562
|
var init_interactive_input = __esm({
|
|
72937
73563
|
"src/interactive-input.ts"() {
|
|
72938
73564
|
"use strict";
|
|
72939
73565
|
import_node_readline3 = __toESM(require("node:readline"));
|
|
72940
|
-
|
|
73566
|
+
import_node_os6 = __toESM(require("node:os"));
|
|
72941
73567
|
init_ui();
|
|
72942
73568
|
init_theme();
|
|
72943
73569
|
C4 = ui.C;
|
|
@@ -73350,8 +73976,8 @@ var init_interactive_input = __esm({
|
|
|
73350
73976
|
return;
|
|
73351
73977
|
}
|
|
73352
73978
|
const width = cols();
|
|
73353
|
-
const user = (
|
|
73354
|
-
const host = (
|
|
73979
|
+
const user = (import_node_os6.default.userInfo().username || "hacker").toLowerCase();
|
|
73980
|
+
const host = (import_node_os6.default.hostname() || "localhost").split(".")[0].toLowerCase();
|
|
73355
73981
|
const label = " \u2709 mensagem ";
|
|
73356
73982
|
const boxW = Math.min(54, Math.max(28, width - 2));
|
|
73357
73983
|
const topFill = "\u2500".repeat(Math.max(0, boxW - vlen(label) - 3));
|
|
@@ -73603,15 +74229,15 @@ async function main() {
|
|
|
73603
74229
|
process.exit(0);
|
|
73604
74230
|
};
|
|
73605
74231
|
const desktopDir = () => {
|
|
73606
|
-
const home =
|
|
74232
|
+
const home = import_node_os7.default.homedir();
|
|
73607
74233
|
const candidates = [
|
|
73608
|
-
process.env.OneDrive ?
|
|
73609
|
-
process.env.USERPROFILE ?
|
|
73610
|
-
|
|
73611
|
-
|
|
73612
|
-
|
|
74234
|
+
process.env.OneDrive ? import_node_path13.default.join(process.env.OneDrive, "Desktop") : null,
|
|
74235
|
+
process.env.USERPROFILE ? import_node_path13.default.join(process.env.USERPROFILE, "Desktop") : null,
|
|
74236
|
+
import_node_path13.default.join(home, "Desktop"),
|
|
74237
|
+
import_node_path13.default.join(home, "\xC1rea de Trabalho"),
|
|
74238
|
+
import_node_path13.default.join(home, "OneDrive", "Desktop")
|
|
73613
74239
|
].filter((p) => Boolean(p));
|
|
73614
|
-
return candidates.find((p) => (0,
|
|
74240
|
+
return candidates.find((p) => (0, import_node_fs13.existsSync)(p)) ?? home;
|
|
73615
74241
|
};
|
|
73616
74242
|
const printFatal = (err) => {
|
|
73617
74243
|
process.stderr.write(
|
|
@@ -74116,7 +74742,7 @@ ${C5.dim}salva em ${C5.reset}${C5.cyan}${file2}${C5.reset}
|
|
|
74116
74742
|
const sysText = agent.getSystemPrompt();
|
|
74117
74743
|
const audit = agent.getSystemPromptAudit();
|
|
74118
74744
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").replace("T", "_").slice(0, 19);
|
|
74119
|
-
const filePath =
|
|
74745
|
+
const filePath = import_node_path13.default.join(
|
|
74120
74746
|
desktopDir(),
|
|
74121
74747
|
`clawfast-system-prompt_${stamp}.html`
|
|
74122
74748
|
);
|
|
@@ -74238,13 +74864,13 @@ ${C5.dim}interrompido \u2014 Ctrl+C de novo para fechar${C5.reset}
|
|
|
74238
74864
|
}
|
|
74239
74865
|
await shutdown();
|
|
74240
74866
|
}
|
|
74241
|
-
var
|
|
74867
|
+
var import_node_os7, import_node_path13, import_node_fs13, import_promises3, deepseekEnabled, configuredModelProviders;
|
|
74242
74868
|
var init_index = __esm({
|
|
74243
74869
|
"index.ts"() {
|
|
74244
74870
|
"use strict";
|
|
74245
|
-
|
|
74246
|
-
|
|
74247
|
-
|
|
74871
|
+
import_node_os7 = __toESM(require("node:os"));
|
|
74872
|
+
import_node_path13 = __toESM(require("node:path"));
|
|
74873
|
+
import_node_fs13 = require("node:fs");
|
|
74248
74874
|
import_promises3 = require("node:fs/promises");
|
|
74249
74875
|
init_paste_input();
|
|
74250
74876
|
init_boot_ui();
|