autopilot-ai 1.25.0 → 1.25.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/index.js +568 -647
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.js +301 -445
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
3
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
4
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
5
|
}) : x)(function(x) {
|
|
@@ -18,33 +14,10 @@ var __esm = (fn, res, err) => function __init() {
|
|
|
18
14
|
throw err = [e], e;
|
|
19
15
|
}
|
|
20
16
|
};
|
|
21
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
22
|
-
try {
|
|
23
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
24
|
-
} catch (e) {
|
|
25
|
-
throw mod = 0, e;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
17
|
var __export = (target, all) => {
|
|
29
18
|
for (var name in all)
|
|
30
19
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
31
20
|
};
|
|
32
|
-
var __copyProps = (to, from, except, desc) => {
|
|
33
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
34
|
-
for (let key of __getOwnPropNames(from))
|
|
35
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
36
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
37
|
-
}
|
|
38
|
-
return to;
|
|
39
|
-
};
|
|
40
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
41
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
42
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
43
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
44
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
45
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
46
|
-
mod
|
|
47
|
-
));
|
|
48
21
|
|
|
49
22
|
// src/util/log-sink.ts
|
|
50
23
|
var log_sink_exports = {};
|
|
@@ -1289,13 +1262,13 @@ async function checkDeployStatus() {
|
|
|
1289
1262
|
}
|
|
1290
1263
|
return { wrangler, wranglerAuth, docker, workerUrl };
|
|
1291
1264
|
}
|
|
1292
|
-
var
|
|
1265
|
+
var __dirname, REMOTE_DIR, WORKER_DIR;
|
|
1293
1266
|
var init_deploy = __esm({
|
|
1294
1267
|
"src/remote/deploy.ts"() {
|
|
1295
1268
|
"use strict";
|
|
1296
1269
|
init_config();
|
|
1297
|
-
|
|
1298
|
-
REMOTE_DIR = join7(
|
|
1270
|
+
__dirname = dirname4(fileURLToPath3(import.meta.url));
|
|
1271
|
+
REMOTE_DIR = join7(__dirname, "..", "..", "..", "remote");
|
|
1299
1272
|
WORKER_DIR = join7(REMOTE_DIR, "worker");
|
|
1300
1273
|
}
|
|
1301
1274
|
});
|
|
@@ -2994,7 +2967,7 @@ async function pruneFiles(files, maxAgeDays, maxCount) {
|
|
|
2994
2967
|
return removed;
|
|
2995
2968
|
}
|
|
2996
2969
|
async function rotateJsonl(path, maxBytes, rotations) {
|
|
2997
|
-
const { rename:
|
|
2970
|
+
const { rename: rename4 } = await import("fs/promises");
|
|
2998
2971
|
let s;
|
|
2999
2972
|
try {
|
|
3000
2973
|
s = await stat2(path);
|
|
@@ -3006,7 +2979,7 @@ async function rotateJsonl(path, maxBytes, rotations) {
|
|
|
3006
2979
|
const src = i === 1 ? path : `${path}.${i - 1}`;
|
|
3007
2980
|
const dst = `${path}.${i}`;
|
|
3008
2981
|
try {
|
|
3009
|
-
await
|
|
2982
|
+
await rename4(src, dst);
|
|
3010
2983
|
} catch {
|
|
3011
2984
|
}
|
|
3012
2985
|
}
|
|
@@ -3575,197 +3548,6 @@ var init_api_generator = __esm({
|
|
|
3575
3548
|
}
|
|
3576
3549
|
});
|
|
3577
3550
|
|
|
3578
|
-
// node_modules/node-gyp-build/node-gyp-build.js
|
|
3579
|
-
var require_node_gyp_build = __commonJS({
|
|
3580
|
-
"node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
|
|
3581
|
-
"use strict";
|
|
3582
|
-
var fs = __require("fs");
|
|
3583
|
-
var path = __require("path");
|
|
3584
|
-
var os2 = __require("os");
|
|
3585
|
-
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
3586
|
-
var vars = process.config && process.config.variables || {};
|
|
3587
|
-
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
3588
|
-
var abi = process.versions.modules;
|
|
3589
|
-
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
3590
|
-
var arch = process.env.npm_config_arch || os2.arch();
|
|
3591
|
-
var platform8 = process.env.npm_config_platform || os2.platform();
|
|
3592
|
-
var libc = process.env.LIBC || (isAlpine(platform8) ? "musl" : "glibc");
|
|
3593
|
-
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
3594
|
-
var uv = (process.versions.uv || "").split(".")[0];
|
|
3595
|
-
module.exports = load;
|
|
3596
|
-
function load(dir) {
|
|
3597
|
-
return runtimeRequire(load.resolve(dir));
|
|
3598
|
-
}
|
|
3599
|
-
load.resolve = load.path = function(dir) {
|
|
3600
|
-
dir = path.resolve(dir || ".");
|
|
3601
|
-
try {
|
|
3602
|
-
var name = runtimeRequire(path.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
|
|
3603
|
-
if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
|
|
3604
|
-
} catch (err) {
|
|
3605
|
-
}
|
|
3606
|
-
if (!prebuildsOnly) {
|
|
3607
|
-
var release2 = getFirst(path.join(dir, "build/Release"), matchBuild);
|
|
3608
|
-
if (release2) return release2;
|
|
3609
|
-
var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
|
|
3610
|
-
if (debug) return debug;
|
|
3611
|
-
}
|
|
3612
|
-
var prebuild = resolve20(dir);
|
|
3613
|
-
if (prebuild) return prebuild;
|
|
3614
|
-
var nearby = resolve20(path.dirname(process.execPath));
|
|
3615
|
-
if (nearby) return nearby;
|
|
3616
|
-
var target = [
|
|
3617
|
-
"platform=" + platform8,
|
|
3618
|
-
"arch=" + arch,
|
|
3619
|
-
"runtime=" + runtime,
|
|
3620
|
-
"abi=" + abi,
|
|
3621
|
-
"uv=" + uv,
|
|
3622
|
-
armv ? "armv=" + armv : "",
|
|
3623
|
-
"libc=" + libc,
|
|
3624
|
-
"node=" + process.versions.node,
|
|
3625
|
-
process.versions.electron ? "electron=" + process.versions.electron : "",
|
|
3626
|
-
typeof __webpack_require__ === "function" ? "webpack=true" : ""
|
|
3627
|
-
// eslint-disable-line
|
|
3628
|
-
].filter(Boolean).join(" ");
|
|
3629
|
-
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
3630
|
-
function resolve20(dir2) {
|
|
3631
|
-
var tuples = readdirSync2(path.join(dir2, "prebuilds")).map(parseTuple);
|
|
3632
|
-
var tuple = tuples.filter(matchTuple(platform8, arch)).sort(compareTuples)[0];
|
|
3633
|
-
if (!tuple) return;
|
|
3634
|
-
var prebuilds = path.join(dir2, "prebuilds", tuple.name);
|
|
3635
|
-
var parsed = readdirSync2(prebuilds).map(parseTags);
|
|
3636
|
-
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
3637
|
-
var winner = candidates.sort(compareTags(runtime))[0];
|
|
3638
|
-
if (winner) return path.join(prebuilds, winner.file);
|
|
3639
|
-
}
|
|
3640
|
-
};
|
|
3641
|
-
function readdirSync2(dir) {
|
|
3642
|
-
try {
|
|
3643
|
-
return fs.readdirSync(dir);
|
|
3644
|
-
} catch (err) {
|
|
3645
|
-
return [];
|
|
3646
|
-
}
|
|
3647
|
-
}
|
|
3648
|
-
function getFirst(dir, filter) {
|
|
3649
|
-
var files = readdirSync2(dir).filter(filter);
|
|
3650
|
-
return files[0] && path.join(dir, files[0]);
|
|
3651
|
-
}
|
|
3652
|
-
function matchBuild(name) {
|
|
3653
|
-
return /\.node$/.test(name);
|
|
3654
|
-
}
|
|
3655
|
-
function parseTuple(name) {
|
|
3656
|
-
var arr = name.split("-");
|
|
3657
|
-
if (arr.length !== 2) return;
|
|
3658
|
-
var platform9 = arr[0];
|
|
3659
|
-
var architectures = arr[1].split("+");
|
|
3660
|
-
if (!platform9) return;
|
|
3661
|
-
if (!architectures.length) return;
|
|
3662
|
-
if (!architectures.every(Boolean)) return;
|
|
3663
|
-
return { name, platform: platform9, architectures };
|
|
3664
|
-
}
|
|
3665
|
-
function matchTuple(platform9, arch2) {
|
|
3666
|
-
return function(tuple) {
|
|
3667
|
-
if (tuple == null) return false;
|
|
3668
|
-
if (tuple.platform !== platform9) return false;
|
|
3669
|
-
return tuple.architectures.includes(arch2);
|
|
3670
|
-
};
|
|
3671
|
-
}
|
|
3672
|
-
function compareTuples(a, b) {
|
|
3673
|
-
return a.architectures.length - b.architectures.length;
|
|
3674
|
-
}
|
|
3675
|
-
function parseTags(file) {
|
|
3676
|
-
var arr = file.split(".");
|
|
3677
|
-
var extension = arr.pop();
|
|
3678
|
-
var tags = { file, specificity: 0 };
|
|
3679
|
-
if (extension !== "node") return;
|
|
3680
|
-
for (var i = 0; i < arr.length; i++) {
|
|
3681
|
-
var tag2 = arr[i];
|
|
3682
|
-
if (tag2 === "node" || tag2 === "electron" || tag2 === "node-webkit") {
|
|
3683
|
-
tags.runtime = tag2;
|
|
3684
|
-
} else if (tag2 === "napi") {
|
|
3685
|
-
tags.napi = true;
|
|
3686
|
-
} else if (tag2.slice(0, 3) === "abi") {
|
|
3687
|
-
tags.abi = tag2.slice(3);
|
|
3688
|
-
} else if (tag2.slice(0, 2) === "uv") {
|
|
3689
|
-
tags.uv = tag2.slice(2);
|
|
3690
|
-
} else if (tag2.slice(0, 4) === "armv") {
|
|
3691
|
-
tags.armv = tag2.slice(4);
|
|
3692
|
-
} else if (tag2 === "glibc" || tag2 === "musl") {
|
|
3693
|
-
tags.libc = tag2;
|
|
3694
|
-
} else {
|
|
3695
|
-
continue;
|
|
3696
|
-
}
|
|
3697
|
-
tags.specificity++;
|
|
3698
|
-
}
|
|
3699
|
-
return tags;
|
|
3700
|
-
}
|
|
3701
|
-
function matchTags(runtime2, abi2) {
|
|
3702
|
-
return function(tags) {
|
|
3703
|
-
if (tags == null) return false;
|
|
3704
|
-
if (tags.runtime && tags.runtime !== runtime2 && !runtimeAgnostic(tags)) return false;
|
|
3705
|
-
if (tags.abi && tags.abi !== abi2 && !tags.napi) return false;
|
|
3706
|
-
if (tags.uv && tags.uv !== uv) return false;
|
|
3707
|
-
if (tags.armv && tags.armv !== armv) return false;
|
|
3708
|
-
if (tags.libc && tags.libc !== libc) return false;
|
|
3709
|
-
return true;
|
|
3710
|
-
};
|
|
3711
|
-
}
|
|
3712
|
-
function runtimeAgnostic(tags) {
|
|
3713
|
-
return tags.runtime === "node" && tags.napi;
|
|
3714
|
-
}
|
|
3715
|
-
function compareTags(runtime2) {
|
|
3716
|
-
return function(a, b) {
|
|
3717
|
-
if (a.runtime !== b.runtime) {
|
|
3718
|
-
return a.runtime === runtime2 ? -1 : 1;
|
|
3719
|
-
} else if (a.abi !== b.abi) {
|
|
3720
|
-
return a.abi ? -1 : 1;
|
|
3721
|
-
} else if (a.specificity !== b.specificity) {
|
|
3722
|
-
return a.specificity > b.specificity ? -1 : 1;
|
|
3723
|
-
} else {
|
|
3724
|
-
return 0;
|
|
3725
|
-
}
|
|
3726
|
-
};
|
|
3727
|
-
}
|
|
3728
|
-
function isNwjs() {
|
|
3729
|
-
return !!(process.versions && process.versions.nw);
|
|
3730
|
-
}
|
|
3731
|
-
function isElectron() {
|
|
3732
|
-
if (process.versions && process.versions.electron) return true;
|
|
3733
|
-
if (process.env.ELECTRON_RUN_AS_NODE) return true;
|
|
3734
|
-
return typeof window !== "undefined" && window.process && window.process.type === "renderer";
|
|
3735
|
-
}
|
|
3736
|
-
function isAlpine(platform9) {
|
|
3737
|
-
return platform9 === "linux" && fs.existsSync("/etc/alpine-release");
|
|
3738
|
-
}
|
|
3739
|
-
load.parseTags = parseTags;
|
|
3740
|
-
load.matchTags = matchTags;
|
|
3741
|
-
load.compareTags = compareTags;
|
|
3742
|
-
load.parseTuple = parseTuple;
|
|
3743
|
-
load.matchTuple = matchTuple;
|
|
3744
|
-
load.compareTuples = compareTuples;
|
|
3745
|
-
}
|
|
3746
|
-
});
|
|
3747
|
-
|
|
3748
|
-
// node_modules/node-gyp-build/index.js
|
|
3749
|
-
var require_node_gyp_build2 = __commonJS({
|
|
3750
|
-
"node_modules/node-gyp-build/index.js"(exports, module) {
|
|
3751
|
-
"use strict";
|
|
3752
|
-
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
3753
|
-
if (typeof runtimeRequire.addon === "function") {
|
|
3754
|
-
module.exports = runtimeRequire.addon.bind(runtimeRequire);
|
|
3755
|
-
} else {
|
|
3756
|
-
module.exports = require_node_gyp_build();
|
|
3757
|
-
}
|
|
3758
|
-
}
|
|
3759
|
-
});
|
|
3760
|
-
|
|
3761
|
-
// node_modules/isolated-vm/isolated-vm.js
|
|
3762
|
-
var require_isolated_vm = __commonJS({
|
|
3763
|
-
"node_modules/isolated-vm/isolated-vm.js"(exports, module) {
|
|
3764
|
-
"use strict";
|
|
3765
|
-
module.exports = require_node_gyp_build2()(__dirname).ivm;
|
|
3766
|
-
}
|
|
3767
|
-
});
|
|
3768
|
-
|
|
3769
3551
|
// src/code-mode/sandbox.ts
|
|
3770
3552
|
import { join as join12, dirname as dirname5 } from "path";
|
|
3771
3553
|
import { pathToFileURL } from "url";
|
|
@@ -3820,9 +3602,38 @@ async function transpileOrStrip(code, cwd) {
|
|
|
3820
3602
|
warnings: ["TypeScript not found in node_modules. Using fallback parser; install typescript for reliable transpilation."]
|
|
3821
3603
|
};
|
|
3822
3604
|
}
|
|
3605
|
+
async function loadIsolatedVm() {
|
|
3606
|
+
const mod = await import("isolated-vm");
|
|
3607
|
+
const ivm = mod.default?.Isolate ? mod.default : mod;
|
|
3608
|
+
if (typeof ivm.Isolate !== "function") throw new Error("isolated-vm loaded but exposes no Isolate constructor");
|
|
3609
|
+
return ivm;
|
|
3610
|
+
}
|
|
3611
|
+
function makeToolBridge(opts2, toolCalls) {
|
|
3612
|
+
let mutationTail = Promise.resolve();
|
|
3613
|
+
return (tool) => async (args) => {
|
|
3614
|
+
const invoke = async () => {
|
|
3615
|
+
const toolCallId = `code_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
3616
|
+
return opts2.executor.run(
|
|
3617
|
+
{ id: toolCallId, name: tool.name, arguments: JSON.stringify(args ?? {}) },
|
|
3618
|
+
opts2.askPermission,
|
|
3619
|
+
opts2.ctx
|
|
3620
|
+
);
|
|
3621
|
+
};
|
|
3622
|
+
let result2;
|
|
3623
|
+
if (tool.isReadOnly === true || tool.concurrent === true) {
|
|
3624
|
+
result2 = await invoke();
|
|
3625
|
+
} else {
|
|
3626
|
+
const run = mutationTail.then(invoke, invoke);
|
|
3627
|
+
mutationTail = run.catch(() => void 0);
|
|
3628
|
+
result2 = await run;
|
|
3629
|
+
}
|
|
3630
|
+
toolCalls.push({ name: tool.name, args, result: result2.content, ok: result2.ok });
|
|
3631
|
+
return result2.content;
|
|
3632
|
+
};
|
|
3633
|
+
}
|
|
3823
3634
|
async function runWithIsolatedVm(opts2) {
|
|
3824
|
-
const
|
|
3825
|
-
const isolate = new Isolate({ memoryLimit: opts2.memoryLimitMB ?? 128 });
|
|
3635
|
+
const ivm = await loadIsolatedVm();
|
|
3636
|
+
const isolate = new ivm.Isolate({ memoryLimit: opts2.memoryLimitMB ?? 128 });
|
|
3826
3637
|
const context = await isolate.createContext();
|
|
3827
3638
|
const jail = context.global;
|
|
3828
3639
|
await jail.set("global", jail.derefInto());
|
|
@@ -3836,30 +3647,15 @@ async function runWithIsolatedVm(opts2) {
|
|
|
3836
3647
|
{ arguments: { reference: true } }
|
|
3837
3648
|
);
|
|
3838
3649
|
await context.eval(`var console = { log: function(...args) { _log(args.map(String).join(" ")); } };`);
|
|
3839
|
-
const
|
|
3650
|
+
const bridge = makeToolBridge(opts2, toolCalls);
|
|
3840
3651
|
for (const tool of opts2.tools) {
|
|
3841
|
-
const
|
|
3842
|
-
|
|
3843
|
-
const args = JSON.parse(argsJson);
|
|
3844
|
-
const toolCallId = `code_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
3845
|
-
const result2 = await opts2.executor.run(
|
|
3846
|
-
{ id: toolCallId, name: tool.name, arguments: JSON.stringify(args) },
|
|
3847
|
-
opts2.askPermission,
|
|
3848
|
-
opts2.ctx
|
|
3849
|
-
);
|
|
3850
|
-
toolCalls.push({
|
|
3851
|
-
name: tool.name,
|
|
3852
|
-
args,
|
|
3853
|
-
result: result2.content
|
|
3854
|
-
});
|
|
3855
|
-
return result2.content;
|
|
3856
|
-
}
|
|
3857
|
-
);
|
|
3652
|
+
const call = bridge(tool);
|
|
3653
|
+
const host = async (argsJson) => call(JSON.parse(argsJson));
|
|
3858
3654
|
await context.evalClosure(
|
|
3859
3655
|
`globalThis["_api_${tool.name}"] = function(argsJson) {
|
|
3860
3656
|
return $0.applySyncPromise(undefined, [argsJson], { arguments: { copy: true } });
|
|
3861
3657
|
};`,
|
|
3862
|
-
[
|
|
3658
|
+
[host],
|
|
3863
3659
|
{ arguments: { reference: true } }
|
|
3864
3660
|
);
|
|
3865
3661
|
}
|
|
@@ -3933,22 +3729,10 @@ async function runWithNodeVm(opts2) {
|
|
|
3933
3729
|
NaN: NaN,
|
|
3934
3730
|
undefined: void 0
|
|
3935
3731
|
};
|
|
3732
|
+
const bridge = makeToolBridge(opts2, toolCalls);
|
|
3936
3733
|
for (const tool of opts2.tools) {
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
const toolCallId = `code_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
3940
|
-
const result2 = await opts2.executor.run(
|
|
3941
|
-
{ id: toolCallId, name: tool.name, arguments: JSON.stringify(args) },
|
|
3942
|
-
opts2.askPermission,
|
|
3943
|
-
opts2.ctx
|
|
3944
|
-
);
|
|
3945
|
-
toolCalls.push({
|
|
3946
|
-
name: tool.name,
|
|
3947
|
-
args,
|
|
3948
|
-
result: result2.content
|
|
3949
|
-
});
|
|
3950
|
-
return result2.content;
|
|
3951
|
-
};
|
|
3734
|
+
const call = bridge(tool);
|
|
3735
|
+
sandbox.api[tool.name] = (input) => call(input ?? {});
|
|
3952
3736
|
}
|
|
3953
3737
|
const { js: jsCode, warnings } = await transpileOrStrip(opts2.code, opts2.ctx.cwd);
|
|
3954
3738
|
const wrapped = `"use strict";
|
|
@@ -4663,7 +4447,8 @@ How to work:
|
|
|
4663
4447
|
- Prefer calling tools over guessing. Read files before editing them. Use \`glob\` and \`grep\` to explore code before assuming structure.
|
|
4664
4448
|
- Before any mutating tool call (write, edit, bash), state in one short sentence what you're about to do, then call the tool. The user will be asked to approve each mutating call.
|
|
4665
4449
|
- When the user asks for a change, make the change. Do not paste code in chat that you could apply with \`edit\` or \`write\`.
|
|
4666
|
-
-
|
|
4450
|
+
- For any request that needs two or more distinct steps, proactively create a visible checklist with \`tasks_set\` before doing work; do not wait for the user to ask. Keep it high-level (about 2\u20136 steps) and skip it only for a genuinely quick single-action request.
|
|
4451
|
+
- When working through a task list, call \`tasks_set\` **immediately before starting each new step** and **immediately after completing each step**. Pass the full list and show exactly one active step. Do not execute mutating tools (\`write\`, \`edit\`, \`bash\`) without updating task progress first.
|
|
4667
4452
|
- Keep responses concise, but make them useful: the user sees tool calls inline, so do not re-summarize routine progress.
|
|
4668
4453
|
- Treat blockers as problems to work through, not as a stopping point. After an error or failed attempt, diagnose the cause and try a safe, materially different recovery or verification path when possible; do not repeat the same failed attempt blindly.
|
|
4669
4454
|
- Prefer resolving a blocker yourself with available tools over shifting diagnosis to the user. If you still cannot finish after reasonable attempts, say what remains undone, why it is blocked, and the single most useful next action. Make that action concrete (for example, an exact command, setting to check, or specific input you need). Ask the user to act only when their access, choice, or interactive participation is genuinely required, and never imply unverified work succeeded.
|
|
@@ -5131,7 +4916,7 @@ function shouldCheckCompletion(input, tier) {
|
|
|
5131
4916
|
}
|
|
5132
4917
|
function createJevCompletionCheck(apiKey, ask = askJev) {
|
|
5133
4918
|
return async (input, signal) => {
|
|
5134
|
-
const
|
|
4919
|
+
const clip3 = (text, max) => redactPrompt(text.replace(/\s+/g, " ").trim()).slice(0, max);
|
|
5135
4920
|
const used = input.toolsUsed.length ? `${input.toolsUsed.length} tool calls (${[...new Set(input.toolsUsed)].join(", ")}); ${input.toolsUsed.some((t) => WRITE_TOOLS.has(t)) ? "it ran commands or edited files" : "it only read or searched"}` : "no tool calls";
|
|
5136
4921
|
const timeout = AbortSignal.timeout(COMPLETION_CHECK_TIMEOUT_MS);
|
|
5137
4922
|
try {
|
|
@@ -5139,9 +4924,9 @@ function createJevCompletionCheck(apiKey, ask = askJev) {
|
|
|
5139
4924
|
kind: "yes",
|
|
5140
4925
|
prompt: [
|
|
5141
4926
|
"Did the assistant end its turn legitimately \u2014 either by fully completing the user's request, or by clearly explaining a blocker or question that needs the user \u2014 as opposed to stopping early, only planning, or announcing next steps it has not done?",
|
|
5142
|
-
`User asked: ${
|
|
4927
|
+
`User asked: ${clip3(input.userRequest, 1200)}`,
|
|
5143
4928
|
`During the turn the assistant made ${used}.`,
|
|
5144
|
-
`Assistant's final message: ${
|
|
4929
|
+
`Assistant's final message: ${clip3(input.finalText, 1500)}`
|
|
5145
4930
|
].join("\n")
|
|
5146
4931
|
}, { signal: AbortSignal.any([timeout, signal]) });
|
|
5147
4932
|
return answer.type === "noul" && typeof answer.noul === "number" ? answer.noul : null;
|
|
@@ -5441,15 +5226,15 @@ async function gitNumstat(cwd, opts2 = {}) {
|
|
|
5441
5226
|
if (opts2.includeUntracked) {
|
|
5442
5227
|
try {
|
|
5443
5228
|
const { stdout } = await execFileAsync("git", ["ls-files", "--others", "--exclude-standard"], { cwd, timeout: 5e3 });
|
|
5444
|
-
const { readFile:
|
|
5445
|
-
const { join:
|
|
5229
|
+
const { readFile: readFile38, stat: stat15 } = await import("fs/promises");
|
|
5230
|
+
const { join: join59 } = await import("path");
|
|
5446
5231
|
for (const file of stdout.split("\n").filter(Boolean)) {
|
|
5447
5232
|
let lines = 0;
|
|
5448
5233
|
try {
|
|
5449
|
-
const path =
|
|
5450
|
-
const size = (await
|
|
5234
|
+
const path = join59(cwd, file);
|
|
5235
|
+
const size = (await stat15(path)).size;
|
|
5451
5236
|
if (size > 0 && size <= 1024 * 1024) {
|
|
5452
|
-
const text = await
|
|
5237
|
+
const text = await readFile38(path, "utf8");
|
|
5453
5238
|
lines = text.split("\n").length - (text.endsWith("\n") ? 1 : 0);
|
|
5454
5239
|
}
|
|
5455
5240
|
} catch {
|
|
@@ -5818,7 +5603,9 @@ ${codeModeApiString}
|
|
|
5818
5603
|
|
|
5819
5604
|
Use console.log() to return results. Only console.log output is sent back to you.
|
|
5820
5605
|
|
|
5821
|
-
IMPORTANT \u2014 explore through code, not direct tools: to read files, run shell commands, grep, or glob, call api.read(...), api.bash(...), api.grep(...), api.glob(...) INSIDE this code block and console.log only what you need. Do NOT call read/bash/grep/glob as separate tools \u2014 their full output floods your context, while here only what you log returns. Batch multiple reads/greps/commands into a single execute_code call
|
|
5606
|
+
IMPORTANT \u2014 explore through code, not direct tools: to read files, run shell commands, grep, or glob, call api.read(...), api.bash(...), api.grep(...), api.glob(...) INSIDE this code block and console.log only what you need. Do NOT call read/bash/grep/glob as separate tools \u2014 their full output floods your context, while here only what you log returns. Batch multiple reads/greps/commands into a single execute_code call.
|
|
5607
|
+
|
|
5608
|
+
Mutating calls (edit, write, bash, \u2026) run one at a time in call order even inside Promise.all; apply edits to the same file sequentially and re-read the file before editing it again.` + (directTools.length > 0 ? `
|
|
5822
5609
|
|
|
5823
5610
|
Not in this API \u2014 call these as separate tools instead: ${directTools.map((t) => t.name).join(", ")}.` : ""),
|
|
5824
5611
|
parameters: {
|
|
@@ -6538,6 +6325,7 @@ Not in this API \u2014 call these as separate tools instead: ${directTools.map((
|
|
|
6538
6325
|
turnId
|
|
6539
6326
|
);
|
|
6540
6327
|
}
|
|
6328
|
+
logger.debug("turn:code_mode_start", { sessionId: opts2.sessionId, toolCallId: tc.id, codeChars: code.length });
|
|
6541
6329
|
const sandboxResult = await runInSandbox({
|
|
6542
6330
|
code,
|
|
6543
6331
|
tools: sandboxTools,
|
|
@@ -6559,12 +6347,23 @@ Not in this API \u2014 call these as separate tools instead: ${directTools.map((
|
|
|
6559
6347
|
timeoutMs: 3e4,
|
|
6560
6348
|
memoryLimitMB: 128
|
|
6561
6349
|
});
|
|
6350
|
+
logger.debug("turn:code_mode_end", {
|
|
6351
|
+
sessionId: opts2.sessionId,
|
|
6352
|
+
toolCallId: tc.id,
|
|
6353
|
+
durationMs: Math.round(performance.now() - sandboxStartedAt),
|
|
6354
|
+
error: sandboxResult.error ?? null,
|
|
6355
|
+
calls: sandboxResult.toolCalls.map((c) => ({
|
|
6356
|
+
name: c.name,
|
|
6357
|
+
ok: c.ok,
|
|
6358
|
+
path: typeof c.args?.path === "string" ? c.args.path : void 0
|
|
6359
|
+
}))
|
|
6360
|
+
});
|
|
6562
6361
|
for (const stc of sandboxResult.toolCalls) {
|
|
6563
6362
|
const toolResult = {
|
|
6564
6363
|
tool_call_id: tc.id,
|
|
6565
6364
|
name: stc.name,
|
|
6566
6365
|
content: stc.result,
|
|
6567
|
-
ok:
|
|
6366
|
+
ok: stc.ok
|
|
6568
6367
|
};
|
|
6569
6368
|
toolResults.push(toolResult);
|
|
6570
6369
|
opts2.callbacks.onToolResult?.(toolResult);
|
|
@@ -7667,14 +7466,79 @@ var init_read = __esm({
|
|
|
7667
7466
|
}
|
|
7668
7467
|
});
|
|
7669
7468
|
|
|
7469
|
+
// src/util/file-lock.ts
|
|
7470
|
+
import { realpath } from "fs/promises";
|
|
7471
|
+
async function lockKeyFor(absPath) {
|
|
7472
|
+
try {
|
|
7473
|
+
return await realpath(absPath);
|
|
7474
|
+
} catch {
|
|
7475
|
+
return absPath;
|
|
7476
|
+
}
|
|
7477
|
+
}
|
|
7478
|
+
async function withFileLock2(absPath, fn) {
|
|
7479
|
+
const key = await lockKeyFor(absPath);
|
|
7480
|
+
const prev = tails.get(key) ?? Promise.resolve();
|
|
7481
|
+
const run = prev.then(fn, fn);
|
|
7482
|
+
const tail = run.then(
|
|
7483
|
+
() => void 0,
|
|
7484
|
+
() => void 0
|
|
7485
|
+
);
|
|
7486
|
+
tails.set(key, tail);
|
|
7487
|
+
try {
|
|
7488
|
+
return await run;
|
|
7489
|
+
} finally {
|
|
7490
|
+
if (tails.get(key) === tail) tails.delete(key);
|
|
7491
|
+
}
|
|
7492
|
+
}
|
|
7493
|
+
var tails;
|
|
7494
|
+
var init_file_lock = __esm({
|
|
7495
|
+
"src/util/file-lock.ts"() {
|
|
7496
|
+
"use strict";
|
|
7497
|
+
tails = /* @__PURE__ */ new Map();
|
|
7498
|
+
}
|
|
7499
|
+
});
|
|
7500
|
+
|
|
7501
|
+
// src/util/safe-write.ts
|
|
7502
|
+
import { chmod as chmod2, readFile as readFile7, rename as rename3, stat as stat5, unlink as unlink2, writeFile as writeFile6 } from "fs/promises";
|
|
7503
|
+
import { basename as basename2, dirname as dirname7, join as join16 } from "path";
|
|
7504
|
+
async function writeFileVerified(absPath, content) {
|
|
7505
|
+
const target = await lockKeyFor(absPath);
|
|
7506
|
+
let mode;
|
|
7507
|
+
try {
|
|
7508
|
+
mode = (await stat5(target)).mode & 511;
|
|
7509
|
+
} catch {
|
|
7510
|
+
}
|
|
7511
|
+
const tmp = join16(dirname7(target), `.${basename2(target)}.${process.pid}.${Math.random().toString(36).slice(2, 8)}.tmp`);
|
|
7512
|
+
try {
|
|
7513
|
+
await writeFile6(tmp, content, "utf8");
|
|
7514
|
+
if (mode !== void 0) await chmod2(tmp, mode);
|
|
7515
|
+
await rename3(tmp, target);
|
|
7516
|
+
} catch {
|
|
7517
|
+
await unlink2(tmp).catch(() => void 0);
|
|
7518
|
+
await writeFile6(target, content, "utf8");
|
|
7519
|
+
}
|
|
7520
|
+
const onDisk = await readFile7(target, "utf8");
|
|
7521
|
+
if (onDisk !== content) {
|
|
7522
|
+
throw new Error(`write verification failed for ${absPath}: file on disk does not match the intended content`);
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
7525
|
+
var init_safe_write = __esm({
|
|
7526
|
+
"src/util/safe-write.ts"() {
|
|
7527
|
+
"use strict";
|
|
7528
|
+
init_file_lock();
|
|
7529
|
+
}
|
|
7530
|
+
});
|
|
7531
|
+
|
|
7670
7532
|
// src/tools/write.ts
|
|
7671
|
-
import { mkdir as mkdir7, readFile as
|
|
7672
|
-
import { dirname as
|
|
7533
|
+
import { mkdir as mkdir7, readFile as readFile8 } from "fs/promises";
|
|
7534
|
+
import { dirname as dirname8 } from "path";
|
|
7673
7535
|
var writeTool;
|
|
7674
7536
|
var init_write = __esm({
|
|
7675
7537
|
"src/tools/write.ts"() {
|
|
7676
7538
|
"use strict";
|
|
7677
7539
|
init_paths2();
|
|
7540
|
+
init_file_lock();
|
|
7541
|
+
init_safe_write();
|
|
7678
7542
|
writeTool = {
|
|
7679
7543
|
name: "write",
|
|
7680
7544
|
description: "Create a file or overwrite an existing one with the given contents. Prompts the user for permission first and shows a diff preview.",
|
|
@@ -7694,22 +7558,30 @@ var init_write = __esm({
|
|
|
7694
7558
|
}),
|
|
7695
7559
|
async run(args, ctx) {
|
|
7696
7560
|
const abs = resolvePath(ctx.cwd, args.path);
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7561
|
+
return withFileLock2(abs, async () => {
|
|
7562
|
+
let before = "";
|
|
7563
|
+
try {
|
|
7564
|
+
before = await readFile8(abs, "utf8");
|
|
7565
|
+
} catch {
|
|
7566
|
+
}
|
|
7567
|
+
await mkdir7(dirname8(abs), { recursive: true });
|
|
7568
|
+
await writeFileVerified(abs, args.content);
|
|
7569
|
+
const verb = before ? "Overwrote" : "Created";
|
|
7570
|
+
return `${verb} ${args.path} (${args.content.length} chars).`;
|
|
7571
|
+
});
|
|
7706
7572
|
}
|
|
7707
7573
|
};
|
|
7708
7574
|
}
|
|
7709
7575
|
});
|
|
7710
7576
|
|
|
7711
7577
|
// src/tools/edit.ts
|
|
7712
|
-
import { readFile as
|
|
7578
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
7579
|
+
function replaceLiteral(haystack, needle, replacement, all) {
|
|
7580
|
+
if (all) return haystack.split(needle).join(replacement);
|
|
7581
|
+
const i = haystack.indexOf(needle);
|
|
7582
|
+
if (i === -1) return haystack;
|
|
7583
|
+
return haystack.slice(0, i) + replacement + haystack.slice(i + needle.length);
|
|
7584
|
+
}
|
|
7713
7585
|
function countOccurrences(haystack, needle) {
|
|
7714
7586
|
if (!needle) return 0;
|
|
7715
7587
|
let count = 0;
|
|
@@ -7726,6 +7598,8 @@ var init_edit = __esm({
|
|
|
7726
7598
|
"src/tools/edit.ts"() {
|
|
7727
7599
|
"use strict";
|
|
7728
7600
|
init_paths2();
|
|
7601
|
+
init_file_lock();
|
|
7602
|
+
init_safe_write();
|
|
7729
7603
|
editTool = {
|
|
7730
7604
|
name: "edit",
|
|
7731
7605
|
description: "Replace an exact string in a file. If replace_all is false (default), the old_string must appear exactly once or the call fails. Prompts the user for permission first and shows a diff preview.",
|
|
@@ -7747,17 +7621,19 @@ var init_edit = __esm({
|
|
|
7747
7621
|
}),
|
|
7748
7622
|
async run(args, ctx) {
|
|
7749
7623
|
const abs = resolvePath(ctx.cwd, args.path);
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7624
|
+
return withFileLock2(abs, async () => {
|
|
7625
|
+
const orig = await readFile9(abs, "utf8");
|
|
7626
|
+
const occurrences = countOccurrences(orig, args.old_string);
|
|
7627
|
+
if (occurrences === 0) throw new Error(`old_string not found in ${args.path}`);
|
|
7628
|
+
if (occurrences > 1 && !args.replace_all) {
|
|
7629
|
+
throw new Error(
|
|
7630
|
+
`old_string appears ${occurrences} times in ${args.path}; pass replace_all=true or include more surrounding context`
|
|
7631
|
+
);
|
|
7632
|
+
}
|
|
7633
|
+
const next = replaceLiteral(orig, args.old_string, args.new_string, args.replace_all === true);
|
|
7634
|
+
await writeFileVerified(abs, next);
|
|
7635
|
+
return `Replaced ${occurrences} occurrence(s) in ${args.path}.`;
|
|
7636
|
+
});
|
|
7761
7637
|
}
|
|
7762
7638
|
};
|
|
7763
7639
|
}
|
|
@@ -7766,7 +7642,7 @@ var init_edit = __esm({
|
|
|
7766
7642
|
// src/tools/bash.ts
|
|
7767
7643
|
import { spawn } from "child_process";
|
|
7768
7644
|
import { tmpdir, platform as platform2 } from "os";
|
|
7769
|
-
import { join as
|
|
7645
|
+
import { join as join17 } from "path";
|
|
7770
7646
|
function getShellCommand(override) {
|
|
7771
7647
|
const raw = override?.trim();
|
|
7772
7648
|
if (raw && raw !== "auto") {
|
|
@@ -7968,7 +7844,7 @@ function injectCoauthor(command, coauthor) {
|
|
|
7968
7844
|
if (movesHeadOnly) return unchanged;
|
|
7969
7845
|
const env2 = {
|
|
7970
7846
|
[COAUTHOR_TRAILER_ENV]: trailer,
|
|
7971
|
-
[COAUTHOR_MSG_ENV]:
|
|
7847
|
+
[COAUTHOR_MSG_ENV]: join17(tmpdir(), `kf-coauthor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`)
|
|
7972
7848
|
};
|
|
7973
7849
|
if (createsCommit || isRebaseContinue) {
|
|
7974
7850
|
return { command: `(${command}) && { ${AMEND_BLOCK}
|
|
@@ -8109,8 +7985,8 @@ var init_bash = __esm({
|
|
|
8109
7985
|
});
|
|
8110
7986
|
|
|
8111
7987
|
// src/util/glob.ts
|
|
8112
|
-
import { readdir as readdir3, lstat, realpath } from "fs/promises";
|
|
8113
|
-
import { join as
|
|
7988
|
+
import { readdir as readdir3, lstat, realpath as realpath2 } from "fs/promises";
|
|
7989
|
+
import { join as join18, relative as relative2, resolve as resolve2 } from "path";
|
|
8114
7990
|
function parsePattern(pattern) {
|
|
8115
7991
|
const parts = pattern.split(/\//g);
|
|
8116
7992
|
return parts.map((p) => {
|
|
@@ -8219,7 +8095,7 @@ async function* walk(root, pattern, options) {
|
|
|
8219
8095
|
if (!dot && name.startsWith(".")) continue;
|
|
8220
8096
|
const matched = seg.type === "literal" ? seg.value === name : matchSegment(name, seg.value);
|
|
8221
8097
|
if (!matched) continue;
|
|
8222
|
-
const childPath =
|
|
8098
|
+
const childPath = join18(dirPath, name);
|
|
8223
8099
|
const childRel = [...relativeParts, name];
|
|
8224
8100
|
const childRelStr = childRel.join("/");
|
|
8225
8101
|
if (shouldIgnore(childRelStr, ignorePatterns)) continue;
|
|
@@ -8244,14 +8120,14 @@ async function* walk(root, pattern, options) {
|
|
|
8244
8120
|
if (!dot && name.startsWith(".")) continue;
|
|
8245
8121
|
const matched = seg.type === "literal" ? seg.value === name : matchSegment(name, seg.value);
|
|
8246
8122
|
if (!matched) continue;
|
|
8247
|
-
const childPath =
|
|
8123
|
+
const childPath = join18(dirPath, name);
|
|
8248
8124
|
const childRel = [...relativeParts, name];
|
|
8249
8125
|
const childRelStr = childRel.join("/");
|
|
8250
8126
|
if (shouldIgnore(childRelStr, ignorePatterns)) continue;
|
|
8251
8127
|
let isDir = ent.isDirectory();
|
|
8252
8128
|
if (!isDir && followSymbolicLinks && ent.isSymbolicLink()) {
|
|
8253
8129
|
try {
|
|
8254
|
-
const rp = await
|
|
8130
|
+
const rp = await realpath2(childPath);
|
|
8255
8131
|
const s = await lstat(rp);
|
|
8256
8132
|
isDir = s.isDirectory();
|
|
8257
8133
|
} catch {
|
|
@@ -8286,7 +8162,7 @@ async function* walk(root, pattern, options) {
|
|
|
8286
8162
|
const name = String(ent.name);
|
|
8287
8163
|
if (name === "." || name === "..") continue;
|
|
8288
8164
|
if (!dot && name.startsWith(".")) continue;
|
|
8289
|
-
const childPath =
|
|
8165
|
+
const childPath = join18(dirPath, name);
|
|
8290
8166
|
const childRel = [...relativeParts, name];
|
|
8291
8167
|
const childRelStr = childRel.join("/");
|
|
8292
8168
|
if (shouldIgnore(childRelStr, ignorePatterns)) continue;
|
|
@@ -8294,7 +8170,7 @@ async function* walk(root, pattern, options) {
|
|
|
8294
8170
|
let isDir = ent.isDirectory();
|
|
8295
8171
|
if (!isDir && followSymbolicLinks && ent.isSymbolicLink()) {
|
|
8296
8172
|
try {
|
|
8297
|
-
const rp = await
|
|
8173
|
+
const rp = await realpath2(childPath);
|
|
8298
8174
|
const s = await lstat(rp);
|
|
8299
8175
|
isDir = s.isDirectory();
|
|
8300
8176
|
} catch {
|
|
@@ -8453,7 +8329,7 @@ var init_glob2 = __esm({
|
|
|
8453
8329
|
// src/tools/grep.ts
|
|
8454
8330
|
import { execFile as execFile2 } from "child_process";
|
|
8455
8331
|
import { promisify as promisify2 } from "util";
|
|
8456
|
-
import { readFile as
|
|
8332
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
8457
8333
|
async function hasRipgrep() {
|
|
8458
8334
|
if (cachedHasRg !== null) return cachedHasRg;
|
|
8459
8335
|
try {
|
|
@@ -8500,7 +8376,7 @@ async function runJsFallback(args, root, mode, signal) {
|
|
|
8500
8376
|
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
8501
8377
|
const file = files[fi];
|
|
8502
8378
|
try {
|
|
8503
|
-
const content = await
|
|
8379
|
+
const content = await readFile10(file, "utf8");
|
|
8504
8380
|
if (mode === "files") {
|
|
8505
8381
|
if (re.test(content)) out.push(file);
|
|
8506
8382
|
} else {
|
|
@@ -9103,9 +8979,9 @@ var changelog_image_exports = {};
|
|
|
9103
8979
|
__export(changelog_image_exports, {
|
|
9104
8980
|
changelogImageTool: () => changelogImageTool
|
|
9105
8981
|
});
|
|
9106
|
-
import { readFile as
|
|
9107
|
-
import { writeFile as
|
|
9108
|
-
import { join as
|
|
8982
|
+
import { readFile as readFile11 } from "fs/promises";
|
|
8983
|
+
import { writeFile as writeFile7 } from "fs/promises";
|
|
8984
|
+
import { join as join19 } from "path";
|
|
9109
8985
|
async function githubFetch2(path, token) {
|
|
9110
8986
|
const controller = new AbortController();
|
|
9111
8987
|
const timer3 = setTimeout(() => controller.abort(), TIMEOUT_MS4);
|
|
@@ -9136,7 +9012,7 @@ function escapeXml(str) {
|
|
|
9136
9012
|
}
|
|
9137
9013
|
async function loadLogoBase64() {
|
|
9138
9014
|
try {
|
|
9139
|
-
const buf = await
|
|
9015
|
+
const buf = await readFile11(join19(process.cwd(), "docs", "logo.png"));
|
|
9140
9016
|
return `data:image/png;base64,${buf.toString("base64")}`;
|
|
9141
9017
|
} catch {
|
|
9142
9018
|
return null;
|
|
@@ -9438,7 +9314,7 @@ Format your response as plain text bullet points, one per line, starting with "\
|
|
|
9438
9314
|
setTask("4", "completed");
|
|
9439
9315
|
setTask("5", "in_progress");
|
|
9440
9316
|
const outputPath = args.output ?? `./changelog-${args.repo}-${version.replace(/[^a-zA-Z0-9._-]/g, "_")}.png`;
|
|
9441
|
-
await
|
|
9317
|
+
await writeFile7(outputPath, pngBuffer);
|
|
9442
9318
|
setTask("5", "completed");
|
|
9443
9319
|
const periodLabel = days === 1 ? "past day" : `past ${days} days`;
|
|
9444
9320
|
const content = `\u2713 Changelog image saved to ${outputPath}
|
|
@@ -9453,7 +9329,7 @@ Format your response as plain text bullet points, one per line, starting with "\
|
|
|
9453
9329
|
// src/tools/browser.ts
|
|
9454
9330
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
9455
9331
|
import { tmpdir as tmpdir2 } from "os";
|
|
9456
|
-
import { join as
|
|
9332
|
+
import { join as join20, dirname as dirname9 } from "path";
|
|
9457
9333
|
async function autoScroll(page) {
|
|
9458
9334
|
await page.evaluate(async () => {
|
|
9459
9335
|
await new Promise((resolve20) => {
|
|
@@ -9529,8 +9405,8 @@ var init_browser = __esm({
|
|
|
9529
9405
|
}
|
|
9530
9406
|
let screenshotPath;
|
|
9531
9407
|
if (args.screenshot) {
|
|
9532
|
-
screenshotPath =
|
|
9533
|
-
await mkdir8(
|
|
9408
|
+
screenshotPath = join20(tmpdir2(), `kimiflare-browser-${Date.now()}.png`);
|
|
9409
|
+
await mkdir8(dirname9(screenshotPath), { recursive: true });
|
|
9534
9410
|
await page.screenshot({ path: screenshotPath, fullPage: true });
|
|
9535
9411
|
}
|
|
9536
9412
|
const text = await page.evaluate(() => {
|
|
@@ -9592,19 +9468,19 @@ var init_open_browser = __esm({
|
|
|
9592
9468
|
});
|
|
9593
9469
|
|
|
9594
9470
|
// src/tools/html-artifact.ts
|
|
9595
|
-
import { chmod as
|
|
9471
|
+
import { chmod as chmod3, lstat as lstat2, mkdir as mkdir9, mkdtemp, readFile as readFile12, readdir as readdir4, realpath as realpath3, rm as rm2, stat as stat6, writeFile as writeFile9 } from "fs/promises";
|
|
9596
9472
|
import { execFileSync } from "child_process";
|
|
9597
9473
|
import { tmpdir as tmpdir3 } from "os";
|
|
9598
|
-
import { isAbsolute as isAbsolute2, join as
|
|
9474
|
+
import { isAbsolute as isAbsolute2, join as join21, relative as relative3, resolve as resolve3, sep as sep2 } from "path";
|
|
9599
9475
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
9600
9476
|
async function createHtmlArtifactFromFile(args, cwd, options = {}) {
|
|
9601
9477
|
assertArtifactSourceArgs(args);
|
|
9602
9478
|
const workspaceRoot = await getWorkspaceRoot(cwd);
|
|
9603
|
-
const workspaceReal = await
|
|
9479
|
+
const workspaceReal = await realpath3(workspaceRoot);
|
|
9604
9480
|
const inputPath = resolvePath(cwd, args.sourcePath);
|
|
9605
9481
|
let inputReal;
|
|
9606
9482
|
try {
|
|
9607
|
-
inputReal = await
|
|
9483
|
+
inputReal = await realpath3(inputPath);
|
|
9608
9484
|
} catch (error) {
|
|
9609
9485
|
if (error.code === "ENOENT") {
|
|
9610
9486
|
throw new ToolError({
|
|
@@ -9622,34 +9498,34 @@ async function createHtmlArtifactFromFile(args, cwd, options = {}) {
|
|
|
9622
9498
|
suggestion: "Write the HTML file inside the workspace and retry with its workspace-relative path."
|
|
9623
9499
|
});
|
|
9624
9500
|
}
|
|
9625
|
-
const info = await
|
|
9501
|
+
const info = await stat6(inputReal);
|
|
9626
9502
|
if (!info.isFile()) {
|
|
9627
9503
|
throw new ToolError({ code: "invalid_args", message: "Artifact sourcePath must be a regular HTML file." });
|
|
9628
9504
|
}
|
|
9629
9505
|
if (info.size > MAX_ARTIFACT_HTML_LENGTH * 4) {
|
|
9630
9506
|
throw new ToolError({ code: "invalid_args", message: `Artifact HTML exceeds ${MAX_ARTIFACT_HTML_LENGTH} characters.` });
|
|
9631
9507
|
}
|
|
9632
|
-
const html = await
|
|
9508
|
+
const html = await readFile12(inputReal, "utf8");
|
|
9633
9509
|
return createHtmlArtifact({ title: args.title, html }, cwd, options);
|
|
9634
9510
|
}
|
|
9635
9511
|
async function createHtmlArtifact(args, cwd, options = {}) {
|
|
9636
9512
|
assertArtifactHtmlArgs(args);
|
|
9637
|
-
const rootDir = options.rootDir ??
|
|
9513
|
+
const rootDir = options.rootDir ?? join21(tmpdir3(), ARTIFACT_ROOT);
|
|
9638
9514
|
const workspaceRoot = await getWorkspaceRoot(cwd);
|
|
9639
|
-
const workspaceReal = await
|
|
9515
|
+
const workspaceReal = await realpath3(workspaceRoot);
|
|
9640
9516
|
if (isWithin(workspaceReal, resolve3(rootDir))) {
|
|
9641
9517
|
throw new Error("Refusing to store an artifact inside the workspace: " + rootDir);
|
|
9642
9518
|
}
|
|
9643
9519
|
await ensureSecureRoot(rootDir);
|
|
9644
|
-
const rootReal = await
|
|
9520
|
+
const rootReal = await realpath3(rootDir);
|
|
9645
9521
|
if (isWithin(workspaceReal, rootReal)) {
|
|
9646
9522
|
throw new Error("Refusing to store an artifact inside the workspace: " + rootReal);
|
|
9647
9523
|
}
|
|
9648
9524
|
await cleanupOldArtifacts(rootDir, (options.now ?? Date.now)());
|
|
9649
|
-
const artifactDir = await mkdtemp(
|
|
9650
|
-
await
|
|
9651
|
-
const filePath =
|
|
9652
|
-
await
|
|
9525
|
+
const artifactDir = await mkdtemp(join21(rootDir, ARTIFACT_PREFIX));
|
|
9526
|
+
await chmod3(artifactDir, 448);
|
|
9527
|
+
const filePath = join21(artifactDir, "index.html");
|
|
9528
|
+
await writeFile9(filePath, buildArtifactHtml(args.title, args.html), {
|
|
9653
9529
|
encoding: "utf8",
|
|
9654
9530
|
flag: "wx",
|
|
9655
9531
|
mode: 384
|
|
@@ -9667,7 +9543,7 @@ async function cleanupOldArtifacts(rootDir, now2 = Date.now()) {
|
|
|
9667
9543
|
}
|
|
9668
9544
|
for (const entry of entries) {
|
|
9669
9545
|
if (!entry.name.startsWith(ARTIFACT_PREFIX) || !entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
9670
|
-
const path =
|
|
9546
|
+
const path = join21(rootDir, entry.name);
|
|
9671
9547
|
try {
|
|
9672
9548
|
const info = await lstat2(path);
|
|
9673
9549
|
if (!info.isDirectory() || info.isSymbolicLink() || now2 - info.mtimeMs < ARTIFACT_MAX_AGE_MS) continue;
|
|
@@ -9785,7 +9661,7 @@ async function ensureSecureRoot(rootDir) {
|
|
|
9785
9661
|
if (typeof process.getuid === "function" && info.uid !== process.getuid()) {
|
|
9786
9662
|
throw new Error("Artifact storage directory is not owned by the current user: " + rootDir);
|
|
9787
9663
|
}
|
|
9788
|
-
if ((info.mode & 63) !== 0) await
|
|
9664
|
+
if ((info.mode & 63) !== 0) await chmod3(rootDir, 448);
|
|
9789
9665
|
}
|
|
9790
9666
|
async function getWorkspaceRoot(cwd) {
|
|
9791
9667
|
try {
|
|
@@ -9861,8 +9737,8 @@ var init_tasks = __esm({
|
|
|
9861
9737
|
name: "tasks_set",
|
|
9862
9738
|
description: [
|
|
9863
9739
|
"Set the visible task list shown to the user during this turn.",
|
|
9864
|
-
"Call this
|
|
9865
|
-
"at the start (all tasks pending
|
|
9740
|
+
"Call this proactively for any request that needs two or more distinct steps, before starting work, and whenever progress changes:",
|
|
9741
|
+
"at the start (all tasks pending except exactly one in_progress), and after each step completes",
|
|
9866
9742
|
"(flip that task to completed and the next to in_progress).",
|
|
9867
9743
|
"Pass the ENTIRE task list each call \u2014 this replaces the panel.",
|
|
9868
9744
|
"Keep tasks short (one imperative clause). Only one should be in_progress at a time.",
|
|
@@ -10068,7 +9944,7 @@ var init_memory = __esm({
|
|
|
10068
9944
|
import { execFile as execFile4 } from "child_process";
|
|
10069
9945
|
import { mkdtemp as mkdtemp2, rm as rm3 } from "fs/promises";
|
|
10070
9946
|
import { tmpdir as tmpdir4 } from "os";
|
|
10071
|
-
import { join as
|
|
9947
|
+
import { join as join22 } from "path";
|
|
10072
9948
|
import { promisify as promisify4 } from "util";
|
|
10073
9949
|
async function git(args, cwd, env2) {
|
|
10074
9950
|
const { stdout } = await execFileAsync2("git", args, {
|
|
@@ -10116,9 +9992,9 @@ async function getRepositorySnapshot(cwd) {
|
|
|
10116
9992
|
if (!ref) {
|
|
10117
9993
|
throw new Error("Could not find an origin branch containing the base commit. Run git fetch, then retry.");
|
|
10118
9994
|
}
|
|
10119
|
-
const scratch = await mkdtemp2(
|
|
9995
|
+
const scratch = await mkdtemp2(join22(tmpdir4(), "autopilot-snapshot-"));
|
|
10120
9996
|
try {
|
|
10121
|
-
const env2 = { GIT_INDEX_FILE:
|
|
9997
|
+
const env2 = { GIT_INDEX_FILE: join22(scratch, "index") };
|
|
10122
9998
|
await git(["read-tree", "HEAD"], root, env2);
|
|
10123
9999
|
await git(["add", "-A", "--", ".", ...SECRET_EXCLUDES], root, env2);
|
|
10124
10000
|
const tree = (await git(["write-tree"], root, env2)).trim();
|
|
@@ -10143,9 +10019,9 @@ async function getRepositorySnapshot(cwd) {
|
|
|
10143
10019
|
async function getWorkingTreeArchive(cwd, limitBytes = MAX_ARCHIVE_BYTES) {
|
|
10144
10020
|
const root = (await git(["rev-parse", "--show-toplevel"], cwd).catch(() => "")).trim();
|
|
10145
10021
|
if (!root) throw new Error("Subagents need to run inside a Git repository.");
|
|
10146
|
-
const scratch = await mkdtemp2(
|
|
10022
|
+
const scratch = await mkdtemp2(join22(tmpdir4(), "autopilot-archive-"));
|
|
10147
10023
|
try {
|
|
10148
|
-
const env2 = { GIT_INDEX_FILE:
|
|
10024
|
+
const env2 = { GIT_INDEX_FILE: join22(scratch, "index") };
|
|
10149
10025
|
const hasHead = await git(["rev-parse", "--verify", "-q", "HEAD"], root).then(() => true, () => false);
|
|
10150
10026
|
await git(hasHead ? ["read-tree", "HEAD"] : ["read-tree", "--empty"], root, env2);
|
|
10151
10027
|
await git(["add", "-A", "--", ".", ...SECRET_EXCLUDES], root, env2);
|
|
@@ -10193,23 +10069,23 @@ var init_hotcell_snapshot = __esm({
|
|
|
10193
10069
|
});
|
|
10194
10070
|
|
|
10195
10071
|
// src/tools/hotcell-worker-cache.ts
|
|
10196
|
-
import { mkdir as mkdir10, readFile as
|
|
10072
|
+
import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile10 } from "fs/promises";
|
|
10197
10073
|
import { homedir as homedir11 } from "os";
|
|
10198
|
-
import { dirname as
|
|
10074
|
+
import { dirname as dirname10, join as join23 } from "path";
|
|
10199
10075
|
function workerCachePath() {
|
|
10200
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
10201
|
-
return
|
|
10076
|
+
const xdg = process.env.XDG_CONFIG_HOME || join23(homedir11(), ".config");
|
|
10077
|
+
return join23(xdg, "kimiflare", "hotcell-worker-cache.json");
|
|
10202
10078
|
}
|
|
10203
10079
|
async function readCache2() {
|
|
10204
10080
|
try {
|
|
10205
|
-
return JSON.parse(await
|
|
10081
|
+
return JSON.parse(await readFile13(workerCachePath(), "utf8"));
|
|
10206
10082
|
} catch {
|
|
10207
10083
|
return {};
|
|
10208
10084
|
}
|
|
10209
10085
|
}
|
|
10210
10086
|
async function writeCache2(cache) {
|
|
10211
|
-
await mkdir10(
|
|
10212
|
-
await
|
|
10087
|
+
await mkdir10(dirname10(workerCachePath()), { recursive: true });
|
|
10088
|
+
await writeFile10(workerCachePath(), JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
|
|
10213
10089
|
}
|
|
10214
10090
|
function ensureWorkerBackup(opts2) {
|
|
10215
10091
|
const existing = inflight.get(opts2.packageSpec);
|
|
@@ -10815,17 +10691,17 @@ var init_worker_registry = __esm({
|
|
|
10815
10691
|
});
|
|
10816
10692
|
|
|
10817
10693
|
// src/tools/subagent-stats.ts
|
|
10818
|
-
import { appendFile as appendFile2, mkdir as mkdir11, readFile as
|
|
10694
|
+
import { appendFile as appendFile2, mkdir as mkdir11, readFile as readFile14 } from "fs/promises";
|
|
10819
10695
|
import { homedir as homedir12 } from "os";
|
|
10820
|
-
import { dirname as
|
|
10696
|
+
import { dirname as dirname11, join as join24 } from "path";
|
|
10821
10697
|
function subagentStatsPath() {
|
|
10822
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
10823
|
-
return
|
|
10698
|
+
const xdg = process.env.XDG_DATA_HOME || join24(homedir12(), ".local", "share");
|
|
10699
|
+
return join24(xdg, "kimiflare", "subagents.jsonl");
|
|
10824
10700
|
}
|
|
10825
10701
|
async function recordSubagentEvent(event) {
|
|
10826
10702
|
const path = subagentStatsPath();
|
|
10827
10703
|
try {
|
|
10828
|
-
await mkdir11(
|
|
10704
|
+
await mkdir11(dirname11(path), { recursive: true });
|
|
10829
10705
|
await appendFile2(path, JSON.stringify(event) + "\n");
|
|
10830
10706
|
} catch (error) {
|
|
10831
10707
|
logger.debug("subagents:stats_write_failed", { error: String(error) });
|
|
@@ -10845,7 +10721,7 @@ function failureReason(error) {
|
|
|
10845
10721
|
async function readSubagentStats(days = 7, now2 = Date.now()) {
|
|
10846
10722
|
let raw = "";
|
|
10847
10723
|
try {
|
|
10848
|
-
raw = await
|
|
10724
|
+
raw = await readFile14(subagentStatsPath(), "utf8");
|
|
10849
10725
|
} catch {
|
|
10850
10726
|
}
|
|
10851
10727
|
const since = now2 - days * 24 * 60 * 60 * 1e3;
|
|
@@ -11742,11 +11618,11 @@ import Database from "better-sqlite3";
|
|
|
11742
11618
|
import { spawn as spawn4, execFileSync as execFileSync2 } from "child_process";
|
|
11743
11619
|
import { mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync4, readSync, existsSync as existsSync4, statSync as statSync3, closeSync, rmSync } from "fs";
|
|
11744
11620
|
import { homedir as homedir13 } from "os";
|
|
11745
|
-
import { dirname as
|
|
11621
|
+
import { dirname as dirname12, join as join25 } from "path";
|
|
11746
11622
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
11747
11623
|
function defaultJobDbPath() {
|
|
11748
|
-
const root = process.env.XDG_STATE_HOME ||
|
|
11749
|
-
return process.env.AUTOPILOT_JOBS_DB ||
|
|
11624
|
+
const root = process.env.XDG_STATE_HOME || join25(homedir13(), ".local", "state");
|
|
11625
|
+
return process.env.AUTOPILOT_JOBS_DB || join25(root, "autopilot", "jobs.db");
|
|
11750
11626
|
}
|
|
11751
11627
|
function isProcessGroupAlive(pgid) {
|
|
11752
11628
|
try {
|
|
@@ -11776,8 +11652,8 @@ function waitForProcessStartTime(pid, jobId, exitPath) {
|
|
|
11776
11652
|
function readProcessStartTime(pid) {
|
|
11777
11653
|
if (process.platform === "linux") {
|
|
11778
11654
|
try {
|
|
11779
|
-
const
|
|
11780
|
-
const fieldsAfterCommand =
|
|
11655
|
+
const stat15 = readFileSync4(`/proc/${pid}/stat`, "utf8");
|
|
11656
|
+
const fieldsAfterCommand = stat15.slice(stat15.lastIndexOf(")") + 1).trim().split(/\s+/);
|
|
11781
11657
|
return fieldsAfterCommand[19] ? `linux:${fieldsAfterCommand[19]}` : null;
|
|
11782
11658
|
} catch {
|
|
11783
11659
|
return null;
|
|
@@ -11889,8 +11765,8 @@ child.on('close', (code, signal) => {
|
|
|
11889
11765
|
db;
|
|
11890
11766
|
jobsDir;
|
|
11891
11767
|
constructor(dbPath = defaultJobDbPath()) {
|
|
11892
|
-
mkdirSync5(
|
|
11893
|
-
this.jobsDir =
|
|
11768
|
+
mkdirSync5(dirname12(dbPath), { recursive: true, mode: 448 });
|
|
11769
|
+
this.jobsDir = join25(dirname12(dbPath), "jobs");
|
|
11894
11770
|
mkdirSync5(this.jobsDir, { recursive: true, mode: 448 });
|
|
11895
11771
|
this.db = new Database(dbPath);
|
|
11896
11772
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -11941,13 +11817,13 @@ child.on('close', (code, signal) => {
|
|
|
11941
11817
|
if (existing) return toJobRecord(existing);
|
|
11942
11818
|
}
|
|
11943
11819
|
const id = randomUUID4();
|
|
11944
|
-
const jobDir =
|
|
11820
|
+
const jobDir = join25(this.jobsDir, id);
|
|
11945
11821
|
mkdirSync5(jobDir, { recursive: true, mode: 448 });
|
|
11946
11822
|
const paths = {
|
|
11947
|
-
stdoutPath:
|
|
11948
|
-
stderrPath:
|
|
11949
|
-
exitPath:
|
|
11950
|
-
pidPath:
|
|
11823
|
+
stdoutPath: join25(jobDir, "stdout.log"),
|
|
11824
|
+
stderrPath: join25(jobDir, "stderr.log"),
|
|
11825
|
+
exitPath: join25(jobDir, "exit.json"),
|
|
11826
|
+
pidPath: join25(jobDir, "pid")
|
|
11951
11827
|
};
|
|
11952
11828
|
const now2 = Date.now();
|
|
11953
11829
|
try {
|
|
@@ -12228,10 +12104,10 @@ import Database2 from "better-sqlite3";
|
|
|
12228
12104
|
import { createHash as createHash2, randomUUID as randomUUID5 } from "crypto";
|
|
12229
12105
|
import { chmodSync, mkdirSync as mkdirSync6 } from "fs";
|
|
12230
12106
|
import { homedir as homedir14 } from "os";
|
|
12231
|
-
import { dirname as
|
|
12107
|
+
import { dirname as dirname13, join as join26 } from "path";
|
|
12232
12108
|
function defaultRunsDbPath() {
|
|
12233
|
-
const root = process.env.XDG_STATE_HOME ||
|
|
12234
|
-
return process.env.AUTOPILOT_RUNS_DB ||
|
|
12109
|
+
const root = process.env.XDG_STATE_HOME || join26(homedir14(), ".local", "state");
|
|
12110
|
+
return process.env.AUTOPILOT_RUNS_DB || join26(root, "autopilot", "runs.db");
|
|
12235
12111
|
}
|
|
12236
12112
|
function validateOptionalPositiveInteger(name, value, minimum = 1) {
|
|
12237
12113
|
if (value !== null && (!Number.isSafeInteger(value) || value < minimum)) {
|
|
@@ -12319,7 +12195,7 @@ var init_store = __esm({
|
|
|
12319
12195
|
RunStore = class {
|
|
12320
12196
|
db;
|
|
12321
12197
|
constructor(dbPath = defaultRunsDbPath()) {
|
|
12322
|
-
mkdirSync6(
|
|
12198
|
+
mkdirSync6(dirname13(dbPath), { recursive: true, mode: 448 });
|
|
12323
12199
|
this.db = new Database2(dbPath);
|
|
12324
12200
|
this.db.pragma("journal_mode = WAL");
|
|
12325
12201
|
this.db.pragma("foreign_keys = ON");
|
|
@@ -12841,7 +12717,7 @@ var init_wait_for = __esm({
|
|
|
12841
12717
|
});
|
|
12842
12718
|
|
|
12843
12719
|
// src/tools/executor.ts
|
|
12844
|
-
import { realpath as
|
|
12720
|
+
import { realpath as realpath4 } from "fs/promises";
|
|
12845
12721
|
import { isAbsolute as isAbsolute3, relative as relative4, resolve as resolve5, sep as sep3 } from "path";
|
|
12846
12722
|
function getWorkerTools(profile) {
|
|
12847
12723
|
return profile === "research" ? ALL_TOOLS.filter((tool) => RESEARCH_WORKER_TOOL_NAMES.has(tool.name) && tool.isReadOnly === true).map(restrictResearchTool) : ALL_TOOLS;
|
|
@@ -12863,11 +12739,11 @@ function restrictResearchTool(tool) {
|
|
|
12863
12739
|
}
|
|
12864
12740
|
async function assertResearchPath(pathValue, cwd) {
|
|
12865
12741
|
if (typeof pathValue !== "string" || !pathValue) throw new Error("Research worker paths must be non-empty strings.");
|
|
12866
|
-
const root = await
|
|
12742
|
+
const root = await realpath4(cwd);
|
|
12867
12743
|
const candidate = resolve5(root, pathValue);
|
|
12868
12744
|
assertInsideResearchRoot(candidate, root);
|
|
12869
12745
|
assertNoSensitivePath(candidate, root);
|
|
12870
|
-
const actual = await
|
|
12746
|
+
const actual = await realpath4(candidate);
|
|
12871
12747
|
assertInsideResearchRoot(actual, root);
|
|
12872
12748
|
assertNoSensitivePath(actual, root);
|
|
12873
12749
|
}
|
|
@@ -13415,12 +13291,12 @@ __export(sessions_exports, {
|
|
|
13415
13291
|
saveSession: () => saveSession,
|
|
13416
13292
|
sessionsDir: () => sessionsDir
|
|
13417
13293
|
});
|
|
13418
|
-
import { readFile as
|
|
13294
|
+
import { readFile as readFile15, writeFile as writeFile11, mkdir as mkdir12, readdir as readdir5, stat as stat7 } from "fs/promises";
|
|
13419
13295
|
import { homedir as homedir15 } from "os";
|
|
13420
|
-
import { join as
|
|
13296
|
+
import { join as join27 } from "path";
|
|
13421
13297
|
function sessionsDir() {
|
|
13422
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
13423
|
-
return
|
|
13298
|
+
const xdg = process.env.XDG_DATA_HOME || join27(homedir15(), ".local", "share");
|
|
13299
|
+
return join27(xdg, "kimiflare", "sessions");
|
|
13424
13300
|
}
|
|
13425
13301
|
function sanitize(text) {
|
|
13426
13302
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
@@ -13440,8 +13316,8 @@ function makeSessionId(firstPrompt) {
|
|
|
13440
13316
|
async function saveSession(file) {
|
|
13441
13317
|
const dir = sessionsDir();
|
|
13442
13318
|
await mkdir12(dir, { recursive: true });
|
|
13443
|
-
const path =
|
|
13444
|
-
await
|
|
13319
|
+
const path = join27(dir, `${file.id}.json`);
|
|
13320
|
+
await writeFile11(path, JSON.stringify(file, null, 2), "utf8");
|
|
13445
13321
|
return path;
|
|
13446
13322
|
}
|
|
13447
13323
|
async function pruneSessions() {
|
|
@@ -13460,9 +13336,9 @@ async function listSessions(limit = 30, cwd) {
|
|
|
13460
13336
|
const summaries = [];
|
|
13461
13337
|
for (const name of entries) {
|
|
13462
13338
|
if (!name.endsWith(".json")) continue;
|
|
13463
|
-
const path =
|
|
13339
|
+
const path = join27(dir, name);
|
|
13464
13340
|
try {
|
|
13465
|
-
const [s, raw] = await Promise.all([
|
|
13341
|
+
const [s, raw] = await Promise.all([stat7(path), readFile15(path, "utf8")]);
|
|
13466
13342
|
const parsed = JSON.parse(raw);
|
|
13467
13343
|
if (cwd && parsed.cwd !== cwd) continue;
|
|
13468
13344
|
const firstUser = parsed.messages.find((m) => m.role === "user");
|
|
@@ -13484,7 +13360,7 @@ async function listSessions(limit = 30, cwd) {
|
|
|
13484
13360
|
return summaries.slice(0, limit);
|
|
13485
13361
|
}
|
|
13486
13362
|
async function loadSession(filePath) {
|
|
13487
|
-
const raw = await
|
|
13363
|
+
const raw = await readFile15(filePath, "utf8");
|
|
13488
13364
|
const file = JSON.parse(raw);
|
|
13489
13365
|
if (Array.isArray(file.messages)) repairDanglingToolCalls(file.messages);
|
|
13490
13366
|
return file;
|
|
@@ -13534,10 +13410,10 @@ var init_sessions = __esm({
|
|
|
13534
13410
|
});
|
|
13535
13411
|
|
|
13536
13412
|
// src/util/image.ts
|
|
13537
|
-
import { readFile as
|
|
13538
|
-
import { basename as
|
|
13413
|
+
import { readFile as readFile16 } from "fs/promises";
|
|
13414
|
+
import { basename as basename3 } from "path";
|
|
13539
13415
|
async function encodeImageFile(filePath) {
|
|
13540
|
-
const buf = await
|
|
13416
|
+
const buf = await readFile16(filePath);
|
|
13541
13417
|
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
13542
13418
|
throw new Error(
|
|
13543
13419
|
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
@@ -13547,7 +13423,7 @@ async function encodeImageFile(filePath) {
|
|
|
13547
13423
|
const mime = EXT_TO_MIME[ext] ?? "image/jpeg";
|
|
13548
13424
|
const b64 = buf.toString("base64");
|
|
13549
13425
|
return {
|
|
13550
|
-
filename:
|
|
13426
|
+
filename: basename3(filePath),
|
|
13551
13427
|
mime,
|
|
13552
13428
|
dataUrl: `data:${mime};base64,${b64}`
|
|
13553
13429
|
};
|
|
@@ -13699,17 +13575,17 @@ __export(retention_exports, {
|
|
|
13699
13575
|
listTraceSessions: () => listTraceSessions,
|
|
13700
13576
|
pruneTraces: () => pruneTraces
|
|
13701
13577
|
});
|
|
13702
|
-
import { readdir as readdir6, rm as rm4, stat as
|
|
13703
|
-
import { join as
|
|
13578
|
+
import { readdir as readdir6, rm as rm4, stat as stat8 } from "fs/promises";
|
|
13579
|
+
import { join as join28 } from "path";
|
|
13704
13580
|
async function dirSize(path) {
|
|
13705
13581
|
let total = 0;
|
|
13706
13582
|
const entries = await readdir6(path, { withFileTypes: true });
|
|
13707
13583
|
for (const entry of entries) {
|
|
13708
|
-
const p =
|
|
13584
|
+
const p = join28(path, entry.name);
|
|
13709
13585
|
if (entry.isDirectory()) total += await dirSize(p);
|
|
13710
13586
|
else if (entry.isFile()) {
|
|
13711
13587
|
try {
|
|
13712
|
-
total += (await
|
|
13588
|
+
total += (await stat8(p)).size;
|
|
13713
13589
|
} catch {
|
|
13714
13590
|
}
|
|
13715
13591
|
}
|
|
@@ -13726,13 +13602,13 @@ async function listTraceSessions(root) {
|
|
|
13726
13602
|
}
|
|
13727
13603
|
const sessions = [];
|
|
13728
13604
|
for (const name of names) {
|
|
13729
|
-
const path =
|
|
13605
|
+
const path = join28(base, name);
|
|
13730
13606
|
try {
|
|
13731
|
-
const s = await
|
|
13607
|
+
const s = await stat8(path);
|
|
13732
13608
|
if (!s.isDirectory()) continue;
|
|
13733
13609
|
let mtime = s.mtime;
|
|
13734
13610
|
try {
|
|
13735
|
-
mtime = (await
|
|
13611
|
+
mtime = (await stat8(join28(path, TRACE_FILE_NAME))).mtime;
|
|
13736
13612
|
} catch {
|
|
13737
13613
|
}
|
|
13738
13614
|
sessions.push({ sessionId: name, path, mtime, bytes: await dirSize(path) });
|
|
@@ -13786,7 +13662,7 @@ var init_retention = __esm({
|
|
|
13786
13662
|
// src/trace/session-start.ts
|
|
13787
13663
|
import { execFile as execFile6 } from "child_process";
|
|
13788
13664
|
import { existsSync as existsSync5 } from "fs";
|
|
13789
|
-
import { dirname as
|
|
13665
|
+
import { dirname as dirname14, join as join29 } from "path";
|
|
13790
13666
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
13791
13667
|
import { promisify as promisify6 } from "util";
|
|
13792
13668
|
async function git2(args, cwd) {
|
|
@@ -13799,9 +13675,9 @@ async function git2(args, cwd) {
|
|
|
13799
13675
|
}
|
|
13800
13676
|
}
|
|
13801
13677
|
function harnessCheckoutDir() {
|
|
13802
|
-
const here =
|
|
13803
|
-
for (const candidate of [
|
|
13804
|
-
if (existsSync5(
|
|
13678
|
+
const here = dirname14(fileURLToPath4(import.meta.url));
|
|
13679
|
+
for (const candidate of [join29(here, "..", ".."), join29(here, "..")]) {
|
|
13680
|
+
if (existsSync5(join29(candidate, "package.json")) && existsSync5(join29(candidate, ".git"))) return candidate;
|
|
13805
13681
|
}
|
|
13806
13682
|
return null;
|
|
13807
13683
|
}
|
|
@@ -13939,14 +13815,14 @@ var init_types2 = __esm({
|
|
|
13939
13815
|
// src/hooks/settings.ts
|
|
13940
13816
|
import { existsSync as existsSync6, readFileSync as readFileSync5, mkdirSync as mkdirSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
13941
13817
|
import { homedir as homedir17 } from "os";
|
|
13942
|
-
import { join as
|
|
13818
|
+
import { join as join30, dirname as dirname15 } from "path";
|
|
13943
13819
|
import { createHash as createHash3 } from "crypto";
|
|
13944
13820
|
function globalSettingsPath() {
|
|
13945
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
13946
|
-
return
|
|
13821
|
+
const xdg = process.env.XDG_CONFIG_HOME || join30(homedir17(), ".config");
|
|
13822
|
+
return join30(xdg, "kimiflare", "settings.json");
|
|
13947
13823
|
}
|
|
13948
13824
|
function projectSettingsPath(cwd) {
|
|
13949
|
-
return
|
|
13825
|
+
return join30(cwd, ".kimiflare", "settings.json");
|
|
13950
13826
|
}
|
|
13951
13827
|
function readSettingsFile(path) {
|
|
13952
13828
|
if (!existsSync6(path)) return null;
|
|
@@ -14022,7 +13898,7 @@ function appendHook(scope, cwd, event, hook) {
|
|
|
14022
13898
|
return rest;
|
|
14023
13899
|
});
|
|
14024
13900
|
existing.hooks = hooks;
|
|
14025
|
-
mkdirSync7(
|
|
13901
|
+
mkdirSync7(dirname15(path), { recursive: true });
|
|
14026
13902
|
writeFileSync4(path, JSON.stringify(existing, null, 2) + "\n", "utf8");
|
|
14027
13903
|
return path;
|
|
14028
13904
|
}
|
|
@@ -14048,7 +13924,7 @@ function setHookEnabled(cwd, id, enabled2) {
|
|
|
14048
13924
|
}
|
|
14049
13925
|
}
|
|
14050
13926
|
if (changed) {
|
|
14051
|
-
mkdirSync7(
|
|
13927
|
+
mkdirSync7(dirname15(path), { recursive: true });
|
|
14052
13928
|
writeFileSync4(path, JSON.stringify(existing, null, 2) + "\n", "utf8");
|
|
14053
13929
|
return path;
|
|
14054
13930
|
}
|
|
@@ -14269,18 +14145,18 @@ var init_manager2 = __esm({
|
|
|
14269
14145
|
});
|
|
14270
14146
|
|
|
14271
14147
|
// src/eval/config.ts
|
|
14272
|
-
import { readFile as
|
|
14273
|
-
import { basename as
|
|
14148
|
+
import { readFile as readFile18 } from "fs/promises";
|
|
14149
|
+
import { basename as basename5, resolve as resolve8 } from "path";
|
|
14274
14150
|
async function loadEvalConfig(file) {
|
|
14275
14151
|
const path = resolve8(file);
|
|
14276
|
-
const raw = JSON.parse(await
|
|
14152
|
+
const raw = JSON.parse(await readFile18(path, "utf8"));
|
|
14277
14153
|
if (!raw || typeof raw !== "object") throw new Error(`${file}: config must be a JSON object`);
|
|
14278
14154
|
const config2 = raw.config ?? {};
|
|
14279
14155
|
if (typeof config2 !== "object" || Array.isArray(config2)) throw new Error(`${file}: "config" must be an object`);
|
|
14280
14156
|
if (raw.model !== void 0 && typeof raw.model !== "string") throw new Error(`${file}: "model" must be a string`);
|
|
14281
14157
|
if (raw.temperature !== void 0 && typeof raw.temperature !== "number") throw new Error(`${file}: "temperature" must be a number`);
|
|
14282
14158
|
return {
|
|
14283
|
-
name: typeof raw.name === "string" && raw.name ? raw.name :
|
|
14159
|
+
name: typeof raw.name === "string" && raw.name ? raw.name : basename5(path).replace(/\.json$/, ""),
|
|
14284
14160
|
...raw.model ? { model: raw.model } : {},
|
|
14285
14161
|
...raw.temperature !== void 0 ? { temperature: raw.temperature } : {},
|
|
14286
14162
|
config: config2
|
|
@@ -14293,8 +14169,8 @@ var init_config2 = __esm({
|
|
|
14293
14169
|
});
|
|
14294
14170
|
|
|
14295
14171
|
// src/eval/tasks.ts
|
|
14296
|
-
import { readdir as readdir7, readFile as
|
|
14297
|
-
import { basename as
|
|
14172
|
+
import { readdir as readdir7, readFile as readFile19, stat as stat9 } from "fs/promises";
|
|
14173
|
+
import { basename as basename6, join as join31, resolve as resolve9 } from "path";
|
|
14298
14174
|
function isNonEmptyString(v) {
|
|
14299
14175
|
return typeof v === "string" && v.trim().length > 0;
|
|
14300
14176
|
}
|
|
@@ -14327,9 +14203,9 @@ async function loadTasks(dir, filter) {
|
|
|
14327
14203
|
const tasks = [];
|
|
14328
14204
|
const seen = /* @__PURE__ */ new Set();
|
|
14329
14205
|
for (const name of names) {
|
|
14330
|
-
const file =
|
|
14331
|
-
const task = validateTask(JSON.parse(await
|
|
14332
|
-
if (task.id !==
|
|
14206
|
+
const file = join31(root, name);
|
|
14207
|
+
const task = validateTask(JSON.parse(await readFile19(file, "utf8")), name);
|
|
14208
|
+
if (task.id !== basename6(name, ".json")) throw new Error(`${name}: "id" (${task.id}) must match the file name`);
|
|
14333
14209
|
if (seen.has(task.id)) throw new Error(`duplicate task id ${task.id}`);
|
|
14334
14210
|
seen.add(task.id);
|
|
14335
14211
|
if (!matchesTaskFilter(task.id, filter)) continue;
|
|
@@ -14337,7 +14213,7 @@ async function loadTasks(dir, filter) {
|
|
|
14337
14213
|
for (const [dest, src] of Object.entries(task.files ?? {})) {
|
|
14338
14214
|
const abs = resolve9(root, src);
|
|
14339
14215
|
if (!abs.startsWith(root)) throw new Error(`${name}: files["${dest}"] escapes the task directory`);
|
|
14340
|
-
await
|
|
14216
|
+
await stat9(abs).catch(() => {
|
|
14341
14217
|
throw new Error(`${name}: files["${dest}"] -> ${src} does not exist`);
|
|
14342
14218
|
});
|
|
14343
14219
|
resolvedFiles[dest] = abs;
|
|
@@ -14358,8 +14234,8 @@ var init_tasks2 = __esm({
|
|
|
14358
14234
|
// src/eval/workspace.ts
|
|
14359
14235
|
import { execFile as execFile7 } from "child_process";
|
|
14360
14236
|
import { createHash as createHash4 } from "crypto";
|
|
14361
|
-
import { mkdir as mkdir13, rm as rm5, stat as
|
|
14362
|
-
import { isAbsolute as isAbsolute4, join as
|
|
14237
|
+
import { mkdir as mkdir13, rm as rm5, stat as stat10 } from "fs/promises";
|
|
14238
|
+
import { isAbsolute as isAbsolute4, join as join32, resolve as resolve10 } from "path";
|
|
14363
14239
|
import { promisify as promisify7 } from "util";
|
|
14364
14240
|
async function git3(args, cwd, timeoutMs = 6e5) {
|
|
14365
14241
|
const { stdout } = await execFileAsync5("git", args, { cwd, timeout: timeoutMs, maxBuffer: 64 * 1024 * 1024 });
|
|
@@ -14384,9 +14260,9 @@ async function prepareSourceRepoUncached(repo, cacheDir) {
|
|
|
14384
14260
|
return path;
|
|
14385
14261
|
}
|
|
14386
14262
|
const slug = `${repo.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(-60)}-${createHash4("sha1").update(repo).digest("hex").slice(0, 8)}`;
|
|
14387
|
-
const dir =
|
|
14263
|
+
const dir = join32(cacheDir, slug);
|
|
14388
14264
|
await mkdir13(cacheDir, { recursive: true });
|
|
14389
|
-
const exists = await
|
|
14265
|
+
const exists = await stat10(join32(dir, ".git")).then(() => true).catch(() => false);
|
|
14390
14266
|
if (!exists) {
|
|
14391
14267
|
await git3(["clone", "--quiet", "--no-checkout", repo, dir], cacheDir);
|
|
14392
14268
|
} else {
|
|
@@ -14405,7 +14281,7 @@ async function ensureCommit(sourceRepo, commit) {
|
|
|
14405
14281
|
async function createWorktree(sourceRepo, commit, path) {
|
|
14406
14282
|
await ensureCommit(sourceRepo, commit);
|
|
14407
14283
|
await removeWorktree({ sourceRepo, path }).catch(() => void 0);
|
|
14408
|
-
await mkdir13(
|
|
14284
|
+
await mkdir13(join32(path, ".."), { recursive: true });
|
|
14409
14285
|
await git3(["worktree", "add", "--quiet", "--detach", path, commit], sourceRepo);
|
|
14410
14286
|
return { sourceRepo, path };
|
|
14411
14287
|
}
|
|
@@ -14461,7 +14337,7 @@ __export(db_exports, {
|
|
|
14461
14337
|
updateMemoryEmbedding: () => updateMemoryEmbedding
|
|
14462
14338
|
});
|
|
14463
14339
|
import Database3 from "better-sqlite3";
|
|
14464
|
-
import { dirname as
|
|
14340
|
+
import { dirname as dirname16 } from "path";
|
|
14465
14341
|
import { mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
|
|
14466
14342
|
function initSchema(db) {
|
|
14467
14343
|
db.exec(`
|
|
@@ -14546,7 +14422,7 @@ function openMemoryDb(dbPath) {
|
|
|
14546
14422
|
if (dbInstance) {
|
|
14547
14423
|
dbInstance.close();
|
|
14548
14424
|
}
|
|
14549
|
-
mkdirSync8(
|
|
14425
|
+
mkdirSync8(dirname16(dbPath), { recursive: true });
|
|
14550
14426
|
dbInstance = new Database3(dbPath);
|
|
14551
14427
|
dbInstance.pragma("journal_mode = WAL");
|
|
14552
14428
|
dbInstance.pragma("foreign_keys = ON");
|
|
@@ -14882,8 +14758,8 @@ function computeExactScore(memory, queryText, cwd) {
|
|
|
14882
14758
|
let score = 0;
|
|
14883
14759
|
const lowerQuery = queryText.toLowerCase();
|
|
14884
14760
|
for (const file of memory.relatedFiles) {
|
|
14885
|
-
const
|
|
14886
|
-
if (lowerQuery.includes(
|
|
14761
|
+
const basename12 = file.split("/").pop() ?? file;
|
|
14762
|
+
if (lowerQuery.includes(basename12.toLowerCase()) || basename12.toLowerCase().includes(lowerQuery)) {
|
|
14887
14763
|
score += 0.3;
|
|
14888
14764
|
}
|
|
14889
14765
|
if (cwd && file.startsWith(cwd)) {
|
|
@@ -16510,12 +16386,12 @@ __export(openrouter_catalog_exports, {
|
|
|
16510
16386
|
loadOpenRouterCatalog: () => loadOpenRouterCatalog,
|
|
16511
16387
|
mapOpenRouterModel: () => mapOpenRouterModel
|
|
16512
16388
|
});
|
|
16513
|
-
import { readFile as
|
|
16389
|
+
import { readFile as readFile20, writeFile as writeFile12, mkdir as mkdir14 } from "fs/promises";
|
|
16514
16390
|
import { homedir as homedir18 } from "os";
|
|
16515
|
-
import { join as
|
|
16391
|
+
import { join as join34, dirname as dirname17 } from "path";
|
|
16516
16392
|
function catalogCachePath() {
|
|
16517
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
16518
|
-
return
|
|
16393
|
+
const xdg = process.env.XDG_CONFIG_HOME || join34(homedir18(), ".config");
|
|
16394
|
+
return join34(xdg, "kimiflare", "openrouter-models.json");
|
|
16519
16395
|
}
|
|
16520
16396
|
function perMtok(perToken) {
|
|
16521
16397
|
const n = Number(perToken);
|
|
@@ -16566,7 +16442,7 @@ async function fetchOpenRouterCatalog(fetchImpl2 = fetch) {
|
|
|
16566
16442
|
}
|
|
16567
16443
|
async function readCache3() {
|
|
16568
16444
|
try {
|
|
16569
|
-
const raw = await
|
|
16445
|
+
const raw = await readFile20(catalogCachePath(), "utf8");
|
|
16570
16446
|
const parsed = JSON.parse(raw);
|
|
16571
16447
|
return parsed.version === CACHE_VERSION ? parsed : null;
|
|
16572
16448
|
} catch {
|
|
@@ -16576,9 +16452,9 @@ async function readCache3() {
|
|
|
16576
16452
|
async function writeCache3(models) {
|
|
16577
16453
|
const path = catalogCachePath();
|
|
16578
16454
|
try {
|
|
16579
|
-
await mkdir14(
|
|
16455
|
+
await mkdir14(dirname17(path), { recursive: true });
|
|
16580
16456
|
const cache = { version: CACHE_VERSION, fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), models };
|
|
16581
|
-
await
|
|
16457
|
+
await writeFile12(path, JSON.stringify(cache, null, 2), "utf8");
|
|
16582
16458
|
} catch {
|
|
16583
16459
|
}
|
|
16584
16460
|
}
|
|
@@ -16625,12 +16501,12 @@ __export(requesty_catalog_exports, {
|
|
|
16625
16501
|
loadRequestyCatalog: () => loadRequestyCatalog,
|
|
16626
16502
|
mapRequestyModel: () => mapRequestyModel
|
|
16627
16503
|
});
|
|
16628
|
-
import { readFile as
|
|
16504
|
+
import { readFile as readFile21, writeFile as writeFile13, mkdir as mkdir15 } from "fs/promises";
|
|
16629
16505
|
import { homedir as homedir19 } from "os";
|
|
16630
|
-
import { join as
|
|
16506
|
+
import { join as join35, dirname as dirname18 } from "path";
|
|
16631
16507
|
function catalogCachePath2() {
|
|
16632
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
16633
|
-
return
|
|
16508
|
+
const xdg = process.env.XDG_CONFIG_HOME || join35(homedir19(), ".config");
|
|
16509
|
+
return join35(xdg, "kimiflare", "requesty-models.json");
|
|
16634
16510
|
}
|
|
16635
16511
|
function isSafeModelId(id) {
|
|
16636
16512
|
return typeof id === "string" && id.length > 0 && !CONTROL_CHARS.test(id);
|
|
@@ -16686,7 +16562,7 @@ async function fetchRequestyCatalog(fetchImpl2 = fetch) {
|
|
|
16686
16562
|
}
|
|
16687
16563
|
async function readCache4() {
|
|
16688
16564
|
try {
|
|
16689
|
-
const raw = await
|
|
16565
|
+
const raw = await readFile21(catalogCachePath2(), "utf8");
|
|
16690
16566
|
const parsed = JSON.parse(raw);
|
|
16691
16567
|
if (parsed.version !== CACHE_VERSION2) return null;
|
|
16692
16568
|
return {
|
|
@@ -16701,9 +16577,9 @@ async function readCache4() {
|
|
|
16701
16577
|
async function writeCache4(catalog) {
|
|
16702
16578
|
const path = catalogCachePath2();
|
|
16703
16579
|
try {
|
|
16704
|
-
await mkdir15(
|
|
16580
|
+
await mkdir15(dirname18(path), { recursive: true });
|
|
16705
16581
|
const cache = { version: CACHE_VERSION2, fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), ...catalog };
|
|
16706
|
-
await
|
|
16582
|
+
await writeFile13(path, JSON.stringify(cache, null, 2), "utf8");
|
|
16707
16583
|
} catch {
|
|
16708
16584
|
}
|
|
16709
16585
|
}
|
|
@@ -16798,7 +16674,7 @@ __export(session_exports, {
|
|
|
16798
16674
|
});
|
|
16799
16675
|
import { resolve as resolve11 } from "path";
|
|
16800
16676
|
import { homedir as homedir20 } from "os";
|
|
16801
|
-
import { join as
|
|
16677
|
+
import { join as join36 } from "path";
|
|
16802
16678
|
import { existsSync as existsSync7 } from "fs";
|
|
16803
16679
|
async function createAgentSession(opts2) {
|
|
16804
16680
|
const config2 = await resolveSdkConfig(opts2);
|
|
@@ -16815,7 +16691,7 @@ async function createAgentSession(opts2) {
|
|
|
16815
16691
|
let memoryManager = null;
|
|
16816
16692
|
const memoryEnabled = opts2.memoryEnabled ?? config2.memoryEnabled ?? false;
|
|
16817
16693
|
if (memoryEnabled) {
|
|
16818
|
-
const dbPath = config2.memoryDbPath ??
|
|
16694
|
+
const dbPath = config2.memoryDbPath ?? join36(homedir20(), ".local", "share", "kimiflare", "memory.db");
|
|
16819
16695
|
memoryManager = new MemoryManager({
|
|
16820
16696
|
dbPath,
|
|
16821
16697
|
...llmAuthFromConfig(config2),
|
|
@@ -16845,7 +16721,7 @@ async function createAgentSession(opts2) {
|
|
|
16845
16721
|
}
|
|
16846
16722
|
let sessionFile;
|
|
16847
16723
|
if (opts2.sessionId) {
|
|
16848
|
-
const filePath =
|
|
16724
|
+
const filePath = join36(sessionsDir(), `${opts2.sessionId}.json`);
|
|
16849
16725
|
try {
|
|
16850
16726
|
sessionFile = await loadSession(filePath);
|
|
16851
16727
|
} catch {
|
|
@@ -17044,8 +16920,8 @@ var init_session = __esm({
|
|
|
17044
16920
|
const parts = [{ type: "text", text }];
|
|
17045
16921
|
for (const img of options.images) {
|
|
17046
16922
|
if ("path" in img) {
|
|
17047
|
-
const { readFile:
|
|
17048
|
-
const data = await
|
|
16923
|
+
const { readFile: readFile38 } = await import("fs/promises");
|
|
16924
|
+
const data = await readFile38(img.path, "base64");
|
|
17049
16925
|
const mimeType = img.path.endsWith(".png") ? "image/png" : img.path.endsWith(".jpg") || img.path.endsWith(".jpeg") ? "image/jpeg" : "image/webp";
|
|
17050
16926
|
parts.push({ type: "image_url", image_url: { url: `data:${mimeType};base64,${data}` } });
|
|
17051
16927
|
} else {
|
|
@@ -17368,14 +17244,14 @@ var init_session = __esm({
|
|
|
17368
17244
|
this.lspManager?.notifyChange(path, content);
|
|
17369
17245
|
} else {
|
|
17370
17246
|
void import("fs/promises").then(
|
|
17371
|
-
({ readFile:
|
|
17247
|
+
({ readFile: readFile38 }) => readFile38(path, "utf8").then((c) => this.lspManager?.notifyChange(path, c)).catch(() => {
|
|
17372
17248
|
})
|
|
17373
17249
|
).catch(() => {
|
|
17374
17250
|
});
|
|
17375
17251
|
}
|
|
17376
17252
|
}
|
|
17377
17253
|
});
|
|
17378
|
-
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync7(
|
|
17254
|
+
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync7(join36(this.cwd, name)))) {
|
|
17379
17255
|
this.messages[0] = {
|
|
17380
17256
|
role: "system",
|
|
17381
17257
|
content: buildSystemPrompt({
|
|
@@ -17400,8 +17276,8 @@ __export(run_exports, {
|
|
|
17400
17276
|
summarizeTrace: () => summarizeTrace
|
|
17401
17277
|
});
|
|
17402
17278
|
import { spawn as spawn7 } from "child_process";
|
|
17403
|
-
import { appendFile as appendFile3, copyFile, mkdir as mkdir16, readFile as
|
|
17404
|
-
import { dirname as
|
|
17279
|
+
import { appendFile as appendFile3, copyFile, mkdir as mkdir16, readFile as readFile22, writeFile as writeFile14 } from "fs/promises";
|
|
17280
|
+
import { dirname as dirname19, join as join37, resolve as resolve12 } from "path";
|
|
17405
17281
|
import { performance as performance2 } from "perf_hooks";
|
|
17406
17282
|
function runShell(command, cwd, timeoutMs) {
|
|
17407
17283
|
return new Promise((resolveShell) => {
|
|
@@ -17434,8 +17310,8 @@ ${err.message}`, timedOut });
|
|
|
17434
17310
|
}
|
|
17435
17311
|
async function copyTaskFiles(task, worktree) {
|
|
17436
17312
|
for (const [dest, src] of Object.entries(task.resolvedFiles)) {
|
|
17437
|
-
const target =
|
|
17438
|
-
await mkdir16(
|
|
17313
|
+
const target = join37(worktree, dest);
|
|
17314
|
+
await mkdir16(dirname19(target), { recursive: true });
|
|
17439
17315
|
await copyFile(src, target);
|
|
17440
17316
|
}
|
|
17441
17317
|
}
|
|
@@ -17443,7 +17319,7 @@ async function summarizeTrace(traceFile) {
|
|
|
17443
17319
|
const out = { cost_usd: 0, prompt_tokens: 0, completion_tokens: 0, turns: 0, tool_calls: 0, overflow: false };
|
|
17444
17320
|
let raw;
|
|
17445
17321
|
try {
|
|
17446
|
-
raw = await
|
|
17322
|
+
raw = await readFile22(traceFile, "utf8");
|
|
17447
17323
|
} catch {
|
|
17448
17324
|
return out;
|
|
17449
17325
|
}
|
|
@@ -17475,7 +17351,7 @@ function sessionIdFor(runName, task, sample) {
|
|
|
17475
17351
|
async function runOne(task, sample, ctx) {
|
|
17476
17352
|
const startedAt2 = performance2.now();
|
|
17477
17353
|
const sessionId = sessionIdFor(ctx.runName, task, sample);
|
|
17478
|
-
const traceDir =
|
|
17354
|
+
const traceDir = join37(ctx.tracesRoot, sessionId);
|
|
17479
17355
|
const base = {
|
|
17480
17356
|
task_id: task.id,
|
|
17481
17357
|
sample,
|
|
@@ -17500,15 +17376,15 @@ async function runOne(task, sample, ctx) {
|
|
|
17500
17376
|
});
|
|
17501
17377
|
let worktree = null;
|
|
17502
17378
|
try {
|
|
17503
|
-
const sourceRepo = await prepareSourceRepo(task.repo,
|
|
17504
|
-
worktree = await createWorktree(sourceRepo, task.base_commit,
|
|
17379
|
+
const sourceRepo = await prepareSourceRepo(task.repo, join37(ctx.out, "cache"));
|
|
17380
|
+
worktree = await createWorktree(sourceRepo, task.base_commit, join37(ctx.out, "work", task.id, String(sample)));
|
|
17505
17381
|
await copyTaskFiles(task, worktree.path);
|
|
17506
17382
|
const timeoutMs = (task.timeout_s ?? DEFAULT_TASK_TIMEOUT_S) * 1e3;
|
|
17507
17383
|
if (task.setup) {
|
|
17508
17384
|
ctx.log(`[${task.id}#${sample}] setup`);
|
|
17509
17385
|
const setup = await runShell(task.setup, worktree.path, timeoutMs);
|
|
17510
17386
|
if (setup.exitCode !== 0) {
|
|
17511
|
-
await
|
|
17387
|
+
await writeFile14(join37(worktree.path, ".eval-setup.log"), setup.log, "utf8").catch(() => void 0);
|
|
17512
17388
|
return finish({ error: `setup failed (exit ${setup.exitCode}${setup.timedOut ? ", timed out" : ""}): ${setup.log.slice(-500)}` });
|
|
17513
17389
|
}
|
|
17514
17390
|
}
|
|
@@ -17543,7 +17419,7 @@ async function runOne(task, sample, ctx) {
|
|
|
17543
17419
|
const testMs = Math.round(performance2.now() - testStartedAt);
|
|
17544
17420
|
const passed = test.exitCode === 0 && !test.timedOut;
|
|
17545
17421
|
await mkdir16(traceDir, { recursive: true }).catch(() => void 0);
|
|
17546
|
-
await
|
|
17422
|
+
await writeFile14(join37(traceDir, "test.log"), test.log, "utf8").catch(() => void 0);
|
|
17547
17423
|
if (session.trace.enabled) {
|
|
17548
17424
|
session.trace.emit(
|
|
17549
17425
|
"outcome",
|
|
@@ -17561,7 +17437,7 @@ async function runOne(task, sample, ctx) {
|
|
|
17561
17437
|
}
|
|
17562
17438
|
session.dispose({ traceEndReason: "eval_done" });
|
|
17563
17439
|
await session.trace.flush();
|
|
17564
|
-
const stats = await summarizeTrace(
|
|
17440
|
+
const stats = await summarizeTrace(join37(traceDir, "trace.jsonl"));
|
|
17565
17441
|
ctx.log(`[${task.id}#${sample}] ${passed ? "PASS" : "FAIL"} in ${agentMs + testMs} ms${agentError ? ` (${agentError.slice(0, 120)})` : ""}`);
|
|
17566
17442
|
return finish({
|
|
17567
17443
|
passed,
|
|
@@ -17591,11 +17467,11 @@ async function runEval(opts2) {
|
|
|
17591
17467
|
const concurrency = Math.max(1, Math.floor(opts2.concurrency ?? 1));
|
|
17592
17468
|
const createSession = opts2.createSession ?? (await Promise.resolve().then(() => (init_session(), session_exports))).createAgentSession;
|
|
17593
17469
|
await mkdir16(out, { recursive: true });
|
|
17594
|
-
const tracesRoot =
|
|
17470
|
+
const tracesRoot = join37(out, "traces");
|
|
17595
17471
|
const runName = evalConfig.name;
|
|
17596
|
-
const resultsFile =
|
|
17597
|
-
await
|
|
17598
|
-
|
|
17472
|
+
const resultsFile = join37(out, "results.jsonl");
|
|
17473
|
+
await writeFile14(
|
|
17474
|
+
join37(out, "config.json"),
|
|
17599
17475
|
JSON.stringify({ name: evalConfig.name, model, temperature: evalConfig.temperature ?? null, config: redactConfig(evalConfig.config), tasks: opts2.tasksDir, samples, started_at: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
|
|
17600
17476
|
"utf8"
|
|
17601
17477
|
);
|
|
@@ -17639,9 +17515,9 @@ __export(compare_exports, {
|
|
|
17639
17515
|
perTask: () => perTask,
|
|
17640
17516
|
summarizeArm: () => summarizeArm
|
|
17641
17517
|
});
|
|
17642
|
-
import { readFile as
|
|
17518
|
+
import { readFile as readFile23 } from "fs/promises";
|
|
17643
17519
|
async function loadResults(file) {
|
|
17644
|
-
const raw = await
|
|
17520
|
+
const raw = await readFile23(file, "utf8");
|
|
17645
17521
|
return raw.split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
|
|
17646
17522
|
}
|
|
17647
17523
|
function median(values) {
|
|
@@ -17774,16 +17650,16 @@ __export(cost_verify_exports, {
|
|
|
17774
17650
|
verifySession: () => verifySession,
|
|
17775
17651
|
verifyTurn: () => verifyTurn
|
|
17776
17652
|
});
|
|
17777
|
-
import { readFile as
|
|
17653
|
+
import { readFile as readFile24 } from "fs/promises";
|
|
17778
17654
|
import { homedir as homedir21 } from "os";
|
|
17779
|
-
import { join as
|
|
17655
|
+
import { join as join38 } from "path";
|
|
17780
17656
|
function usagePath2() {
|
|
17781
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
17782
|
-
return
|
|
17657
|
+
const xdg = process.env.XDG_DATA_HOME || join38(homedir21(), ".local", "share");
|
|
17658
|
+
return join38(xdg, "kimiflare", "usage.json");
|
|
17783
17659
|
}
|
|
17784
17660
|
async function loadSessions() {
|
|
17785
17661
|
try {
|
|
17786
|
-
return JSON.parse(await
|
|
17662
|
+
return JSON.parse(await readFile24(usagePath2(), "utf8")).sessions ?? [];
|
|
17787
17663
|
} catch {
|
|
17788
17664
|
return [];
|
|
17789
17665
|
}
|
|
@@ -18102,12 +17978,12 @@ function extOf(path) {
|
|
|
18102
17978
|
const idx = path.lastIndexOf(".");
|
|
18103
17979
|
return idx >= 0 ? path.slice(idx).toLowerCase() : "";
|
|
18104
17980
|
}
|
|
18105
|
-
function
|
|
17981
|
+
function basename7(path) {
|
|
18106
17982
|
const idx = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
18107
17983
|
return idx >= 0 ? path.slice(idx + 1) : path;
|
|
18108
17984
|
}
|
|
18109
17985
|
function classifyFile(path) {
|
|
18110
|
-
const base =
|
|
17986
|
+
const base = basename7(path);
|
|
18111
17987
|
const ext = extOf(path);
|
|
18112
17988
|
if (TEST_PATTERNS.test(base)) return "writing-tests";
|
|
18113
17989
|
if (base.toLowerCase().startsWith("readme")) return "reading-documentation";
|
|
@@ -18118,7 +17994,7 @@ function classifyFile(path) {
|
|
|
18118
17994
|
return null;
|
|
18119
17995
|
}
|
|
18120
17996
|
function classifyWriteFile(path) {
|
|
18121
|
-
const base =
|
|
17997
|
+
const base = basename7(path);
|
|
18122
17998
|
const ext = extOf(path);
|
|
18123
17999
|
if (TEST_PATTERNS.test(base)) return "writing-tests";
|
|
18124
18000
|
if (base.toLowerCase().startsWith("readme") || DOC_EXTS.has(ext)) return "writing-documentation";
|
|
@@ -18127,7 +18003,7 @@ function classifyWriteFile(path) {
|
|
|
18127
18003
|
return null;
|
|
18128
18004
|
}
|
|
18129
18005
|
function classifyEditFile(path) {
|
|
18130
|
-
const base =
|
|
18006
|
+
const base = basename7(path);
|
|
18131
18007
|
const ext = extOf(path);
|
|
18132
18008
|
if (base.toLowerCase().startsWith("readme") || DOC_EXTS.has(ext)) return "editing-documentation";
|
|
18133
18009
|
if (CONFIG_EXTS.has(ext)) return "editing-configuration";
|
|
@@ -18314,12 +18190,12 @@ var init_heuristic = __esm({
|
|
|
18314
18190
|
});
|
|
18315
18191
|
|
|
18316
18192
|
// src/cost-attribution/classify-from-session.ts
|
|
18317
|
-
import { readFile as
|
|
18318
|
-
import { join as
|
|
18193
|
+
import { readFile as readFile25 } from "fs/promises";
|
|
18194
|
+
import { join as join39 } from "path";
|
|
18319
18195
|
import { homedir as homedir22 } from "os";
|
|
18320
18196
|
function sessionsDir2() {
|
|
18321
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
18322
|
-
return
|
|
18197
|
+
const xdg = process.env.XDG_DATA_HOME || join39(homedir22(), ".local", "share");
|
|
18198
|
+
return join39(xdg, "kimiflare", "sessions");
|
|
18323
18199
|
}
|
|
18324
18200
|
function parseToolCalls(calls) {
|
|
18325
18201
|
return calls.map((c) => {
|
|
@@ -18333,7 +18209,7 @@ function parseToolCalls(calls) {
|
|
|
18333
18209
|
}
|
|
18334
18210
|
async function classifyFromSessionFile(sessionId) {
|
|
18335
18211
|
try {
|
|
18336
|
-
const raw = await
|
|
18212
|
+
const raw = await readFile25(join39(sessionsDir2(), `${sessionId}.json`), "utf8");
|
|
18337
18213
|
const session = JSON.parse(raw);
|
|
18338
18214
|
const messages = session.messages ?? [];
|
|
18339
18215
|
const turns = [];
|
|
@@ -18366,15 +18242,15 @@ var cli_exports = {};
|
|
|
18366
18242
|
__export(cli_exports, {
|
|
18367
18243
|
runCostCommand: () => runCostCommand
|
|
18368
18244
|
});
|
|
18369
|
-
import { readFile as
|
|
18370
|
-
import { join as
|
|
18245
|
+
import { readFile as readFile26 } from "fs/promises";
|
|
18246
|
+
import { join as join40 } from "path";
|
|
18371
18247
|
import { homedir as homedir23 } from "os";
|
|
18372
18248
|
function usageDir2() {
|
|
18373
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
18374
|
-
return
|
|
18249
|
+
const xdg = process.env.XDG_DATA_HOME || join40(homedir23(), ".local", "share");
|
|
18250
|
+
return join40(xdg, "kimiflare");
|
|
18375
18251
|
}
|
|
18376
18252
|
function usagePath3() {
|
|
18377
|
-
return
|
|
18253
|
+
return join40(usageDir2(), "usage.json");
|
|
18378
18254
|
}
|
|
18379
18255
|
function today2() {
|
|
18380
18256
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -18386,7 +18262,7 @@ function daysAgo(n) {
|
|
|
18386
18262
|
}
|
|
18387
18263
|
async function loadLog2() {
|
|
18388
18264
|
try {
|
|
18389
|
-
const raw = await
|
|
18265
|
+
const raw = await readFile26(usagePath3(), "utf8");
|
|
18390
18266
|
return JSON.parse(raw);
|
|
18391
18267
|
} catch {
|
|
18392
18268
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -18476,12 +18352,12 @@ __export(aster_workspaces_exports, {
|
|
|
18476
18352
|
findAsterWorkspace: () => findAsterWorkspace,
|
|
18477
18353
|
loadAsterServerConfig: () => loadAsterServerConfig
|
|
18478
18354
|
});
|
|
18479
|
-
import { readFile as
|
|
18355
|
+
import { readFile as readFile27, realpath as realpath5, stat as stat11 } from "fs/promises";
|
|
18480
18356
|
import { isAbsolute as isAbsolute5, relative as relative8, sep as sep4 } from "path";
|
|
18481
18357
|
async function loadAsterServerConfig(configPath3 = process.env.AUTOPILOT_ASTER_CONFIG || "/etc/autopilot/aster.json") {
|
|
18482
18358
|
let raw;
|
|
18483
18359
|
try {
|
|
18484
|
-
raw = JSON.parse(await
|
|
18360
|
+
raw = JSON.parse(await readFile27(configPath3, "utf8"));
|
|
18485
18361
|
} catch {
|
|
18486
18362
|
throw new AsterConfigError();
|
|
18487
18363
|
}
|
|
@@ -18517,8 +18393,8 @@ async function loadAsterServerConfig(configPath3 = process.env.AUTOPILOT_ASTER_C
|
|
|
18517
18393
|
if (typeof workspace.rootPath !== "string" || !isAbsolute5(workspace.rootPath)) throw new AsterConfigError();
|
|
18518
18394
|
let rootPath;
|
|
18519
18395
|
try {
|
|
18520
|
-
rootPath = await
|
|
18521
|
-
if (!(await
|
|
18396
|
+
rootPath = await realpath5(workspace.rootPath);
|
|
18397
|
+
if (!(await stat11(rootPath)).isDirectory()) throw new Error("not a directory");
|
|
18522
18398
|
} catch {
|
|
18523
18399
|
throw new AsterConfigError();
|
|
18524
18400
|
}
|
|
@@ -18560,10 +18436,10 @@ import Database4 from "better-sqlite3";
|
|
|
18560
18436
|
import { createHash as createHash5, randomBytes as randomBytes2, randomUUID as randomUUID6 } from "crypto";
|
|
18561
18437
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync9 } from "fs";
|
|
18562
18438
|
import { homedir as homedir24 } from "os";
|
|
18563
|
-
import { dirname as
|
|
18439
|
+
import { dirname as dirname20, join as join41 } from "path";
|
|
18564
18440
|
function defaultAsterDbPath() {
|
|
18565
|
-
const root = process.env.XDG_STATE_HOME ||
|
|
18566
|
-
return process.env.AUTOPILOT_ASTER_DB ||
|
|
18441
|
+
const root = process.env.XDG_STATE_HOME || join41(homedir24(), ".local", "state");
|
|
18442
|
+
return process.env.AUTOPILOT_ASTER_DB || join41(root, "autopilot", "aster.db");
|
|
18567
18443
|
}
|
|
18568
18444
|
function hashToken(token) {
|
|
18569
18445
|
return createHash5("sha256").update(token).digest("hex");
|
|
@@ -18614,9 +18490,9 @@ var init_aster_store = __esm({
|
|
|
18614
18490
|
AsterStore = class {
|
|
18615
18491
|
db;
|
|
18616
18492
|
constructor(dbPath = defaultAsterDbPath()) {
|
|
18617
|
-
mkdirSync9(
|
|
18493
|
+
mkdirSync9(dirname20(dbPath), { recursive: true, mode: 448 });
|
|
18618
18494
|
try {
|
|
18619
|
-
chmodSync2(
|
|
18495
|
+
chmodSync2(dirname20(dbPath), 448);
|
|
18620
18496
|
} catch {
|
|
18621
18497
|
}
|
|
18622
18498
|
this.db = new Database4(dbPath);
|
|
@@ -19488,12 +19364,12 @@ var init_openapi = __esm({
|
|
|
19488
19364
|
|
|
19489
19365
|
// src/runs/worktrees.ts
|
|
19490
19366
|
import { execFile as execFile8 } from "child_process";
|
|
19491
|
-
import { access as access2, chmod as
|
|
19367
|
+
import { access as access2, chmod as chmod4, mkdir as mkdir17, realpath as realpath6 } from "fs/promises";
|
|
19492
19368
|
import { homedir as homedir25 } from "os";
|
|
19493
|
-
import { isAbsolute as isAbsolute6, join as
|
|
19369
|
+
import { isAbsolute as isAbsolute6, join as join42, parse, relative as relative9, resolve as resolve13, sep as sep5 } from "path";
|
|
19494
19370
|
function defaultWorktreesDir() {
|
|
19495
|
-
const dataHome = process.env.XDG_DATA_HOME ||
|
|
19496
|
-
return
|
|
19371
|
+
const dataHome = process.env.XDG_DATA_HOME || join42(homedir25(), ".local", "share");
|
|
19372
|
+
return join42(dataHome, "autopilot", "worktrees");
|
|
19497
19373
|
}
|
|
19498
19374
|
function isOutside(path) {
|
|
19499
19375
|
return path === ".." || path.startsWith(`..${sep5}`) || isAbsolute6(path);
|
|
@@ -19527,9 +19403,9 @@ var init_worktrees = __esm({
|
|
|
19527
19403
|
if (runId === "." || runId === ".." || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(runId)) {
|
|
19528
19404
|
throw new Error("runId must contain only letters, numbers, dots, underscores, or hyphens");
|
|
19529
19405
|
}
|
|
19530
|
-
const source = await
|
|
19406
|
+
const source = await realpath6(sourceCwd);
|
|
19531
19407
|
const repositoryRoot = (await runGit(["rev-parse", "--show-toplevel"], source)).trim();
|
|
19532
|
-
const repository = await
|
|
19408
|
+
const repository = await realpath6(repositoryRoot);
|
|
19533
19409
|
const sourceRelativePath = relative9(repository, source);
|
|
19534
19410
|
if (isOutside(sourceRelativePath)) {
|
|
19535
19411
|
throw new Error("sourceCwd must be inside the Git repository");
|
|
@@ -19539,12 +19415,12 @@ var init_worktrees = __esm({
|
|
|
19539
19415
|
throw new Error("worktree root must be outside the source repository and not the filesystem root");
|
|
19540
19416
|
}
|
|
19541
19417
|
await mkdir17(configuredRoot, { recursive: true, mode: 448 });
|
|
19542
|
-
const worktreesRoot = await
|
|
19418
|
+
const worktreesRoot = await realpath6(configuredRoot);
|
|
19543
19419
|
if (isWithin3(repository, worktreesRoot)) {
|
|
19544
19420
|
throw new Error("worktree root must be outside the source repository");
|
|
19545
19421
|
}
|
|
19546
|
-
await
|
|
19547
|
-
const worktreePath =
|
|
19422
|
+
await chmod4(worktreesRoot, 448);
|
|
19423
|
+
const worktreePath = join42(worktreesRoot, runId);
|
|
19548
19424
|
try {
|
|
19549
19425
|
await access2(worktreePath);
|
|
19550
19426
|
throw new Error(`worktree path already exists for run ${runId}`);
|
|
@@ -19564,9 +19440,9 @@ var init_worktrees = __esm({
|
|
|
19564
19440
|
}
|
|
19565
19441
|
/** Remove a newly-created, still-clean worktree when run initialization fails. */
|
|
19566
19442
|
async discard(worktree) {
|
|
19567
|
-
const root = await
|
|
19568
|
-
const target = await
|
|
19569
|
-
const repository = await
|
|
19443
|
+
const root = await realpath6(this.rootDir);
|
|
19444
|
+
const target = await realpath6(worktree.worktreePath);
|
|
19445
|
+
const repository = await realpath6(worktree.repositoryRoot);
|
|
19570
19446
|
if (target === root || !isWithin3(root, target)) {
|
|
19571
19447
|
throw new Error("worktree path is outside the configured worktree root");
|
|
19572
19448
|
}
|
|
@@ -19712,7 +19588,7 @@ var init_wake_scheduler = __esm({
|
|
|
19712
19588
|
});
|
|
19713
19589
|
|
|
19714
19590
|
// src/server/aster-tools.ts
|
|
19715
|
-
import { realpath as
|
|
19591
|
+
import { realpath as realpath7 } from "fs/promises";
|
|
19716
19592
|
import { isAbsolute as isAbsolute7, relative as relative10, sep as sep6 } from "path";
|
|
19717
19593
|
function createAsterTools(workspaceRoot) {
|
|
19718
19594
|
return ASTR_TOOLS.map((tool) => ({
|
|
@@ -19725,19 +19601,19 @@ function createAsterTools(workspaceRoot) {
|
|
|
19725
19601
|
}
|
|
19726
19602
|
async function assertAsterWorkspacePath(workspaceRoot, value, allowMissing = false) {
|
|
19727
19603
|
if (typeof value !== "string" || !value.trim()) throw new Error("workspace_path_invalid");
|
|
19728
|
-
const root = await
|
|
19604
|
+
const root = await realpath7(workspaceRoot);
|
|
19729
19605
|
const candidate = resolvePath(root, value);
|
|
19730
19606
|
assertInside(root, candidate);
|
|
19731
19607
|
assertNotSensitive(root, candidate);
|
|
19732
19608
|
let actual;
|
|
19733
19609
|
try {
|
|
19734
|
-
actual = await
|
|
19610
|
+
actual = await realpath7(candidate);
|
|
19735
19611
|
} catch (error) {
|
|
19736
19612
|
if (!allowMissing || error.code !== "ENOENT") throw new Error("workspace_path_unavailable");
|
|
19737
19613
|
let ancestor = candidate;
|
|
19738
19614
|
while (true) {
|
|
19739
19615
|
try {
|
|
19740
|
-
actual = await
|
|
19616
|
+
actual = await realpath7(ancestor);
|
|
19741
19617
|
break;
|
|
19742
19618
|
} catch (ancestorError) {
|
|
19743
19619
|
if (ancestorError.code !== "ENOENT") throw new Error("workspace_path_unavailable");
|
|
@@ -19803,7 +19679,7 @@ var init_aster_tools = __esm({
|
|
|
19803
19679
|
|
|
19804
19680
|
// src/server/aster-api.ts
|
|
19805
19681
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
19806
|
-
import { unlink as
|
|
19682
|
+
import { unlink as unlink3 } from "fs/promises";
|
|
19807
19683
|
import { resolve as resolve14 } from "path";
|
|
19808
19684
|
function parseCursor(header, query) {
|
|
19809
19685
|
const value = (Array.isArray(header) ? header[0] : header) ?? query ?? "0";
|
|
@@ -20117,7 +19993,7 @@ var init_aster_api = __esm({
|
|
|
20117
19993
|
store.appendEvent(id, null, "conversation.created", { conversationId: id, workspaceId: workspace.id, model });
|
|
20118
19994
|
json(res, 201, publicConversation(conversation));
|
|
20119
19995
|
} catch {
|
|
20120
|
-
await
|
|
19996
|
+
await unlink3(resolve14(sessionsDir(), `${sessionId}.json`)).catch(() => {
|
|
20121
19997
|
});
|
|
20122
19998
|
await worktreeManager.discard(worktree).catch(() => {
|
|
20123
19999
|
});
|
|
@@ -20460,7 +20336,7 @@ data: ${JSON.stringify(event.data)}
|
|
|
20460
20336
|
|
|
20461
20337
|
// src/server/aster-cell-runtime.ts
|
|
20462
20338
|
import { execFile as execFile9 } from "child_process";
|
|
20463
|
-
import { readFile as
|
|
20339
|
+
import { readFile as readFile28 } from "fs/promises";
|
|
20464
20340
|
import { promisify as promisify8 } from "util";
|
|
20465
20341
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
20466
20342
|
async function writeCellFileChunked(cell, path, content) {
|
|
@@ -20490,7 +20366,7 @@ async function writeCellFileChunked(cell, path, content) {
|
|
|
20490
20366
|
async function readBundledCellSdkBundle() {
|
|
20491
20367
|
for (const url of [new URL("./sdk/index.js", import.meta.url), new URL("../sdk/index.js", import.meta.url)]) {
|
|
20492
20368
|
try {
|
|
20493
|
-
return await
|
|
20369
|
+
return await readFile28(url, "utf8");
|
|
20494
20370
|
} catch {
|
|
20495
20371
|
}
|
|
20496
20372
|
}
|
|
@@ -20986,9 +20862,9 @@ ${turn.userText}` : turn.userText;
|
|
|
20986
20862
|
if (!isSafeArtifactPath(path)) throw new Error("invalid_artifact_path");
|
|
20987
20863
|
const cell = await this.provider.getCell(cellId);
|
|
20988
20864
|
const file = shellQuote2(`${ARTIFACTS_DIR}/${path}`);
|
|
20989
|
-
const
|
|
20990
|
-
if (
|
|
20991
|
-
if (Number(
|
|
20865
|
+
const stat15 = await cell.exec(`[ -f ${file} ] && [ ! -L ${file} ] && stat -c %s -- ${file}`);
|
|
20866
|
+
if (stat15.exitCode !== 0) throw new Error("artifact_not_found");
|
|
20867
|
+
if (Number(stat15.stdout.trim()) > MAX_ARTIFACT_BYTES) throw new Error("artifact_too_large");
|
|
20992
20868
|
const encoded = await cell.exec(`base64 -w0 -- ${file}`);
|
|
20993
20869
|
if (encoded.exitCode !== 0) throw new Error("artifact_not_found");
|
|
20994
20870
|
return { data: Buffer.from(encoded.stdout.trim(), "base64"), mimeType: artifactMimeType(path), name: path.split("/").pop() ?? path };
|
|
@@ -21285,8 +21161,8 @@ var init_hotcell_provider = __esm({
|
|
|
21285
21161
|
// src/server/routes.ts
|
|
21286
21162
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
21287
21163
|
import { URL as URL2 } from "url";
|
|
21288
|
-
import { readFile as
|
|
21289
|
-
import { resolve as resolve15, basename as
|
|
21164
|
+
import { readFile as readFile29, unlink as unlink4 } from "fs/promises";
|
|
21165
|
+
import { resolve as resolve15, basename as basename8 } from "path";
|
|
21290
21166
|
function createHotcellAsterRuntime() {
|
|
21291
21167
|
try {
|
|
21292
21168
|
const idlePauseMs = Number(process.env.AUTOPILOT_ASTER_IDLE_PAUSE_MS ?? 15 * 60 * 1e3);
|
|
@@ -21369,8 +21245,8 @@ async function resolveFiles2(filePatterns, cwd) {
|
|
|
21369
21245
|
const resolved = /* @__PURE__ */ new Set();
|
|
21370
21246
|
for (const pattern of filePatterns) {
|
|
21371
21247
|
try {
|
|
21372
|
-
const
|
|
21373
|
-
if (
|
|
21248
|
+
const stat15 = await import("fs/promises").then((m) => m.stat(resolve15(cwd, pattern)));
|
|
21249
|
+
if (stat15.isFile()) {
|
|
21374
21250
|
resolved.add(resolve15(cwd, pattern));
|
|
21375
21251
|
continue;
|
|
21376
21252
|
}
|
|
@@ -21394,12 +21270,12 @@ async function buildUserMessage2(prompt, files, cwd) {
|
|
|
21394
21270
|
imageParts.push({ type: "image_url", image_url: { url: img.dataUrl } });
|
|
21395
21271
|
} catch (e) {
|
|
21396
21272
|
fileContents.push(`
|
|
21397
|
-
<!-- failed to attach image ${
|
|
21273
|
+
<!-- failed to attach image ${basename8(filePath)}: ${e.message} -->
|
|
21398
21274
|
`);
|
|
21399
21275
|
}
|
|
21400
21276
|
} else {
|
|
21401
21277
|
try {
|
|
21402
|
-
const content = await
|
|
21278
|
+
const content = await readFile29(filePath, "utf8");
|
|
21403
21279
|
const relPath = filePath.startsWith(cwd) ? filePath.slice(cwd.length + 1) : filePath;
|
|
21404
21280
|
fileContents.push(`
|
|
21405
21281
|
--- ${relPath} ---
|
|
@@ -21408,7 +21284,7 @@ ${content}
|
|
|
21408
21284
|
`);
|
|
21409
21285
|
} catch (e) {
|
|
21410
21286
|
fileContents.push(`
|
|
21411
|
-
<!-- failed to read ${
|
|
21287
|
+
<!-- failed to read ${basename8(filePath)}: ${e.message} -->
|
|
21412
21288
|
`);
|
|
21413
21289
|
}
|
|
21414
21290
|
}
|
|
@@ -21676,7 +21552,7 @@ function setupRoutes(config2, options = {}) {
|
|
|
21676
21552
|
store.close();
|
|
21677
21553
|
}
|
|
21678
21554
|
} catch (error) {
|
|
21679
|
-
await
|
|
21555
|
+
await unlink4(resolve15(sessionsDir(), `${sessionId}.json`)).catch(() => {
|
|
21680
21556
|
});
|
|
21681
21557
|
if (worktree) {
|
|
21682
21558
|
await worktreeManager.discard(worktree).catch((cleanupError) => {
|
|
@@ -21830,8 +21706,8 @@ function setupRoutes(config2, options = {}) {
|
|
|
21830
21706
|
const sessionId = sessionMatch[1];
|
|
21831
21707
|
activeSessions.delete(sessionId);
|
|
21832
21708
|
try {
|
|
21833
|
-
const { unlink:
|
|
21834
|
-
await
|
|
21709
|
+
const { unlink: unlink7 } = await import("fs/promises");
|
|
21710
|
+
await unlink7(resolve15(sessionsDir(), `${sessionId}.json`));
|
|
21835
21711
|
} catch {
|
|
21836
21712
|
}
|
|
21837
21713
|
json2(res, 200, { deleted: sessionId });
|
|
@@ -23729,7 +23605,7 @@ __export(app_helpers_exports, {
|
|
|
23729
23605
|
});
|
|
23730
23606
|
import { execSync as execSync3 } from "child_process";
|
|
23731
23607
|
import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
|
|
23732
|
-
import { join as
|
|
23608
|
+
import { join as join43 } from "path";
|
|
23733
23609
|
function replaceQueuedPrompt(queue2, key, full, display) {
|
|
23734
23610
|
const index = queue2.findIndex((item) => item.key === key);
|
|
23735
23611
|
if (index >= 0) {
|
|
@@ -23836,7 +23712,7 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
23836
23712
|
];
|
|
23837
23713
|
const gitignorePatterns = [];
|
|
23838
23714
|
try {
|
|
23839
|
-
const gitignorePath =
|
|
23715
|
+
const gitignorePath = join43(cwd, ".gitignore");
|
|
23840
23716
|
const stats = statSync5(gitignorePath);
|
|
23841
23717
|
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
23842
23718
|
return hardcoded;
|
|
@@ -24002,9 +23878,9 @@ var init_app_helpers = __esm({
|
|
|
24002
23878
|
|
|
24003
23879
|
// src/ui/bang-command.ts
|
|
24004
23880
|
import { spawn as spawn8 } from "child_process";
|
|
24005
|
-
import { mkdtemp as mkdtemp3, readFile as
|
|
23881
|
+
import { mkdtemp as mkdtemp3, readFile as readFile30, rm as rm6 } from "fs/promises";
|
|
24006
23882
|
import { tmpdir as tmpdir5, platform as platform4 } from "os";
|
|
24007
|
-
import { join as
|
|
23883
|
+
import { join as join44 } from "path";
|
|
24008
23884
|
function registerInkInstance(instance) {
|
|
24009
23885
|
inkInstance = instance;
|
|
24010
23886
|
}
|
|
@@ -24107,8 +23983,8 @@ async function runBangCommand(command, cwd) {
|
|
|
24107
23983
|
const origErr = stderr.write;
|
|
24108
23984
|
const readable = stdin.listeners("readable");
|
|
24109
23985
|
const wasRaw = stdin.isTTY ? stdin.isRaw : false;
|
|
24110
|
-
const logDir2 = isWindows ? null : await mkdtemp3(
|
|
24111
|
-
const logPath = logDir2 ?
|
|
23986
|
+
const logDir2 = isWindows ? null : await mkdtemp3(join44(tmpdir5(), "autopilot-bang-"));
|
|
23987
|
+
const logPath = logDir2 ? join44(logDir2, "out.log") : null;
|
|
24112
23988
|
const viaScript = logPath ? scriptInvocation(command, shell, logPath) : null;
|
|
24113
23989
|
inkInstance?.clear();
|
|
24114
23990
|
origOut.call(stdout, `
|
|
@@ -24150,7 +24026,7 @@ $ ${command}
|
|
|
24150
24026
|
}
|
|
24151
24027
|
let output = spawnError ? `failed to start: ${spawnError}` : null;
|
|
24152
24028
|
if (captured && logPath) {
|
|
24153
|
-
output = cleanTerminalOutput(await
|
|
24029
|
+
output = cleanTerminalOutput(await readFile30(logPath, "utf8").catch(() => ""));
|
|
24154
24030
|
}
|
|
24155
24031
|
if (logDir2) await rm6(logDir2, { recursive: true, force: true }).catch(() => {
|
|
24156
24032
|
});
|
|
@@ -26331,6 +26207,7 @@ var init_activity = __esm({
|
|
|
26331
26207
|
var camouflage_view_exports = {};
|
|
26332
26208
|
__export(camouflage_view_exports, {
|
|
26333
26209
|
CamouflageUnavailable: () => CamouflageUnavailable,
|
|
26210
|
+
executeCodeSummary: () => executeCodeSummary,
|
|
26334
26211
|
helpOptions: () => helpOptions,
|
|
26335
26212
|
listMentionDir: () => listMentionDir,
|
|
26336
26213
|
modelOptions: () => modelOptions,
|
|
@@ -26345,7 +26222,7 @@ __export(camouflage_view_exports, {
|
|
|
26345
26222
|
import { execFileSync as execFileSync3, spawn as spawn10 } from "child_process";
|
|
26346
26223
|
import { readdir as readdir8 } from "fs/promises";
|
|
26347
26224
|
import { homedir as homedir26 } from "os";
|
|
26348
|
-
import { join as
|
|
26225
|
+
import { join as join45, resolve as resolve16 } from "path";
|
|
26349
26226
|
async function loadSdk() {
|
|
26350
26227
|
const sdk = await import("camouflage-tui").catch((err) => {
|
|
26351
26228
|
throw new CamouflageUnavailable(`camouflage-tui is not installed (${err.message})`);
|
|
@@ -26524,7 +26401,7 @@ function truncateText(s, max) {
|
|
|
26524
26401
|
async function listMentionDir(cwd, query) {
|
|
26525
26402
|
const exact = query === "~" || query === "." || query === ".." || query.endsWith("/..");
|
|
26526
26403
|
const dir = exact ? `${query}/` : query.slice(0, query.lastIndexOf("/") + 1);
|
|
26527
|
-
const expanded = dir.startsWith("~") ?
|
|
26404
|
+
const expanded = dir.startsWith("~") ? join45(homedir26(), dir.slice(1)) : dir;
|
|
26528
26405
|
const target = resolve16(cwd, expanded || ".");
|
|
26529
26406
|
try {
|
|
26530
26407
|
const items = await readdir8(target, { withFileTypes: true });
|
|
@@ -26562,8 +26439,26 @@ function toolRow(name, title, rawArgs) {
|
|
|
26562
26439
|
const rest = title.toLowerCase().startsWith(`${name.toLowerCase()} `) ? title.slice(name.length + 1) : title;
|
|
26563
26440
|
return { label, args: rest.trim() };
|
|
26564
26441
|
}
|
|
26442
|
+
if (name === "execute_code") {
|
|
26443
|
+
return { label: "Code", args: clip(executeCodeSummary(rawArgs)) };
|
|
26444
|
+
}
|
|
26565
26445
|
const args = (rawArgs ?? "").replace(/\s+/g, " ").trim();
|
|
26566
|
-
return { label, args: args
|
|
26446
|
+
return { label, args: clip(args) };
|
|
26447
|
+
}
|
|
26448
|
+
function clip(s) {
|
|
26449
|
+
return s.length > 120 ? `${s.slice(0, 119)}\u2026` : s;
|
|
26450
|
+
}
|
|
26451
|
+
function executeCodeSummary(rawArgs) {
|
|
26452
|
+
let parsed = {};
|
|
26453
|
+
try {
|
|
26454
|
+
parsed = rawArgs ? JSON.parse(rawArgs) : {};
|
|
26455
|
+
} catch {
|
|
26456
|
+
return "running a code batch";
|
|
26457
|
+
}
|
|
26458
|
+
if (typeof parsed.reasoning === "string" && parsed.reasoning.trim()) return parsed.reasoning.replace(/\s+/g, " ").trim();
|
|
26459
|
+
const code = typeof parsed.code === "string" ? parsed.code : "";
|
|
26460
|
+
const first = code.split("\n").map((l) => l.trim()).find((l) => l && !l.startsWith("//"));
|
|
26461
|
+
return first ? first.replace(/\s+/g, " ") : "running a code batch";
|
|
26567
26462
|
}
|
|
26568
26463
|
function toolSummary(name, ok, declined, content) {
|
|
26569
26464
|
if (declined) return "You declined this \xB7 tell autopilot what to do instead";
|
|
@@ -29874,8 +29769,8 @@ var init_queue_plan_picker = __esm({
|
|
|
29874
29769
|
|
|
29875
29770
|
// src/agent/jev-context.ts
|
|
29876
29771
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
29877
|
-
import { readFile as
|
|
29878
|
-
import { basename as
|
|
29772
|
+
import { readFile as readFile31 } from "fs/promises";
|
|
29773
|
+
import { basename as basename9, join as join46, resolve as resolve17 } from "path";
|
|
29879
29774
|
function messageText(message2) {
|
|
29880
29775
|
if (typeof message2.content === "string") return message2.content.trim();
|
|
29881
29776
|
if (!Array.isArray(message2.content)) return "";
|
|
@@ -29897,7 +29792,7 @@ function projectRoot(cwd) {
|
|
|
29897
29792
|
}
|
|
29898
29793
|
async function readPackageMetadata(root) {
|
|
29899
29794
|
try {
|
|
29900
|
-
const parsed = JSON.parse(await
|
|
29795
|
+
const parsed = JSON.parse(await readFile31(join46(root, "package.json"), "utf8"));
|
|
29901
29796
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
29902
29797
|
const pkg = parsed;
|
|
29903
29798
|
const metadata = {};
|
|
@@ -29914,7 +29809,7 @@ async function readPackageMetadata(root) {
|
|
|
29914
29809
|
async function readLicenseEvidence(root) {
|
|
29915
29810
|
for (const name of ["LICENSE", "LICENSE.md", "LICENSE.txt", "LICENCE", "COPYING"]) {
|
|
29916
29811
|
try {
|
|
29917
|
-
const content = (await
|
|
29812
|
+
const content = (await readFile31(join46(root, name), "utf8")).trim();
|
|
29918
29813
|
if (content) return { source: `project license (${name})`, content: content.slice(0, 700) };
|
|
29919
29814
|
} catch {
|
|
29920
29815
|
}
|
|
@@ -29947,13 +29842,13 @@ async function buildJevContext(question, messages, cwd = process.cwd()) {
|
|
|
29947
29842
|
conversationRemaining -= source.length + content.length + 2;
|
|
29948
29843
|
}
|
|
29949
29844
|
}
|
|
29950
|
-
const currentDirectory =
|
|
29845
|
+
const currentDirectory = basename9(resolve17(cwd));
|
|
29951
29846
|
const escapedDirectory = currentDirectory.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
29952
29847
|
const namesCurrentDirectory = currentDirectory.length >= 5 && !/^(?:agent|app|code|lib|project|repo|src|test|tests|workspace)$/i.test(currentDirectory) && new RegExp(`\\b${escapedDirectory}\\b`, "i").test(question);
|
|
29953
29848
|
if (CURRENT_PROJECT_REFERENCE.test(question) || namesCurrentDirectory) {
|
|
29954
29849
|
const root = projectRoot(cwd);
|
|
29955
29850
|
const metadata = await readPackageMetadata(root);
|
|
29956
|
-
if (!metadata.name) metadata.name =
|
|
29851
|
+
if (!metadata.name) metadata.name = basename9(root);
|
|
29957
29852
|
add("project metadata (package.json or directory)", JSON.stringify(metadata));
|
|
29958
29853
|
if (LICENSE_QUESTION.test(question)) {
|
|
29959
29854
|
const license = await readLicenseEvidence(root);
|
|
@@ -30996,8 +30891,8 @@ var init_frontmatter = __esm({
|
|
|
30996
30891
|
});
|
|
30997
30892
|
|
|
30998
30893
|
// src/skills/loader.ts
|
|
30999
|
-
import { readFile as
|
|
31000
|
-
import { join as
|
|
30894
|
+
import { readFile as readFile32, readdir as readdir9, stat as stat12 } from "fs/promises";
|
|
30895
|
+
import { join as join47, extname } from "path";
|
|
31001
30896
|
function normalizeManifest(raw, filePath) {
|
|
31002
30897
|
const name = typeof raw.name === "string" ? raw.name : "";
|
|
31003
30898
|
const description = typeof raw.description === "string" ? raw.description : "";
|
|
@@ -31011,7 +30906,7 @@ function normalizeManifest(raw, filePath) {
|
|
|
31011
30906
|
return { name, description, match, scope, priority, enabled: enabled2 };
|
|
31012
30907
|
}
|
|
31013
30908
|
async function loadSkillFile(filePath) {
|
|
31014
|
-
const raw = await
|
|
30909
|
+
const raw = await readFile32(filePath, "utf-8");
|
|
31015
30910
|
const parsed = parseFrontmatter(raw);
|
|
31016
30911
|
const manifest = normalizeManifest(parsed.data, filePath);
|
|
31017
30912
|
const body = parsed.content.trim();
|
|
@@ -31033,8 +30928,8 @@ async function loadSkillsFromDir(dirPath) {
|
|
|
31033
30928
|
const entries = await readdir9(dirPath);
|
|
31034
30929
|
const files = [];
|
|
31035
30930
|
for (const entry of entries) {
|
|
31036
|
-
const full =
|
|
31037
|
-
const s = await
|
|
30931
|
+
const full = join47(dirPath, entry);
|
|
30932
|
+
const s = await stat12(full);
|
|
31038
30933
|
if (s.isFile() && extname(entry) === ".md") {
|
|
31039
30934
|
files.push(full);
|
|
31040
30935
|
}
|
|
@@ -31061,12 +30956,12 @@ var init_loader = __esm({
|
|
|
31061
30956
|
});
|
|
31062
30957
|
|
|
31063
30958
|
// src/skills/manager.ts
|
|
31064
|
-
import { mkdir as mkdir18, writeFile as
|
|
31065
|
-
import { join as
|
|
30959
|
+
import { mkdir as mkdir18, writeFile as writeFile15, unlink as unlink5, readFile as readFile33 } from "fs/promises";
|
|
30960
|
+
import { join as join48 } from "path";
|
|
31066
30961
|
function getSkillDirs(cwd) {
|
|
31067
30962
|
return {
|
|
31068
|
-
projectDir:
|
|
31069
|
-
globalDir:
|
|
30963
|
+
projectDir: join48(cwd, ".kimiflare", "skills"),
|
|
30964
|
+
globalDir: join48(process.env.HOME ?? "", ".config", "kimiflare", "skills")
|
|
31070
30965
|
};
|
|
31071
30966
|
}
|
|
31072
30967
|
async function listAllSkills(cwd) {
|
|
@@ -31080,7 +30975,7 @@ async function listAllSkills(cwd) {
|
|
|
31080
30975
|
async function createSkill(opts2) {
|
|
31081
30976
|
const dirs = getSkillDirs(opts2.cwd);
|
|
31082
30977
|
const dir = opts2.scope === "project" ? dirs.projectDir : dirs.globalDir;
|
|
31083
|
-
const filepath =
|
|
30978
|
+
const filepath = join48(dir, `${opts2.name}.md`);
|
|
31084
30979
|
const frontmatter = {
|
|
31085
30980
|
name: opts2.name,
|
|
31086
30981
|
enabled: true,
|
|
@@ -31102,21 +30997,21 @@ ${yaml}
|
|
|
31102
30997
|
Add your instructions here.
|
|
31103
30998
|
`;
|
|
31104
30999
|
await mkdir18(dir, { recursive: true });
|
|
31105
|
-
await
|
|
31000
|
+
await writeFile15(filepath, content, "utf8");
|
|
31106
31001
|
return { filepath };
|
|
31107
31002
|
}
|
|
31108
31003
|
async function deleteSkill(name, cwd) {
|
|
31109
31004
|
const all = await listAllSkills(cwd);
|
|
31110
31005
|
const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
|
|
31111
31006
|
if (!skill) throw new Error(`skill "${name}" not found`);
|
|
31112
|
-
await
|
|
31007
|
+
await unlink5(skill.filePath);
|
|
31113
31008
|
return { filepath: skill.filePath };
|
|
31114
31009
|
}
|
|
31115
31010
|
async function setSkillEnabled(name, enabled2, cwd) {
|
|
31116
31011
|
const all = await listAllSkills(cwd);
|
|
31117
31012
|
const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
|
|
31118
31013
|
if (!skill) throw new Error(`skill "${name}" not found`);
|
|
31119
|
-
const raw = await
|
|
31014
|
+
const raw = await readFile33(skill.filePath, "utf-8");
|
|
31120
31015
|
const parsed = parseFrontmatter(raw);
|
|
31121
31016
|
parsed.data.enabled = enabled2;
|
|
31122
31017
|
const yaml = Object.entries(parsed.data).map(([k, v]) => {
|
|
@@ -31128,7 +31023,7 @@ ${v.map((item) => ` - ${item}`).join("\n")}`;
|
|
|
31128
31023
|
${yaml}
|
|
31129
31024
|
---
|
|
31130
31025
|
${parsed.content}`;
|
|
31131
|
-
await
|
|
31026
|
+
await writeFile15(skill.filePath, content, "utf8");
|
|
31132
31027
|
return { filepath: skill.filePath };
|
|
31133
31028
|
}
|
|
31134
31029
|
async function findSkillFile(name, cwd) {
|
|
@@ -31388,15 +31283,15 @@ var tui_report_exports = {};
|
|
|
31388
31283
|
__export(tui_report_exports, {
|
|
31389
31284
|
getCategoryReportText: () => getCategoryReportText
|
|
31390
31285
|
});
|
|
31391
|
-
import { readFile as
|
|
31392
|
-
import { join as
|
|
31286
|
+
import { readFile as readFile34 } from "fs/promises";
|
|
31287
|
+
import { join as join49 } from "path";
|
|
31393
31288
|
import { homedir as homedir27 } from "os";
|
|
31394
31289
|
function usageDir3() {
|
|
31395
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
31396
|
-
return
|
|
31290
|
+
const xdg = process.env.XDG_DATA_HOME || join49(homedir27(), ".local", "share");
|
|
31291
|
+
return join49(xdg, "kimiflare");
|
|
31397
31292
|
}
|
|
31398
31293
|
function usagePath4() {
|
|
31399
|
-
return
|
|
31294
|
+
return join49(usageDir3(), "usage.json");
|
|
31400
31295
|
}
|
|
31401
31296
|
function today3() {
|
|
31402
31297
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -31408,7 +31303,7 @@ function daysAgo2(n) {
|
|
|
31408
31303
|
}
|
|
31409
31304
|
async function loadLog3() {
|
|
31410
31305
|
try {
|
|
31411
|
-
const raw = await
|
|
31306
|
+
const raw = await readFile34(usagePath4(), "utf8");
|
|
31412
31307
|
return JSON.parse(raw);
|
|
31413
31308
|
} catch {
|
|
31414
31309
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -31465,7 +31360,7 @@ var init_tui_report = __esm({
|
|
|
31465
31360
|
});
|
|
31466
31361
|
|
|
31467
31362
|
// src/ui/slash-commands.ts
|
|
31468
|
-
import { join as
|
|
31363
|
+
import { join as join50 } from "path";
|
|
31469
31364
|
import QRCode from "qrcode";
|
|
31470
31365
|
function executeFreshStart(ctx, planText, overrideMode, opts2 = {}) {
|
|
31471
31366
|
const oldSessionId = ctx.sessionIdRef.current;
|
|
@@ -32397,7 +32292,7 @@ ${lines.join("\n")}` }]);
|
|
|
32397
32292
|
void (async () => {
|
|
32398
32293
|
try {
|
|
32399
32294
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
32400
|
-
const file = await loadSession(
|
|
32295
|
+
const file = await loadSession(join50(sessionsDir3(), `${currentId}.json`));
|
|
32401
32296
|
const cps = file.checkpoints ?? [];
|
|
32402
32297
|
if (cps.length === 0) {
|
|
32403
32298
|
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: "no checkpoints in this session" }]);
|
|
@@ -32442,7 +32337,7 @@ ${lines.join("\n")}` }]);
|
|
|
32442
32337
|
try {
|
|
32443
32338
|
ctx.ensureSessionId();
|
|
32444
32339
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
32445
|
-
const filePath =
|
|
32340
|
+
const filePath = join50(sessionsDir3(), `${ctx.sessionIdRef.current}.json`);
|
|
32446
32341
|
await addCheckpoint(filePath, cp);
|
|
32447
32342
|
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: `checkpoint saved: "${label}"` }]);
|
|
32448
32343
|
} catch (e) {
|
|
@@ -33167,9 +33062,9 @@ async function triageIncoming(text, context, opts2 = {}) {
|
|
|
33167
33062
|
"steer = it adjusts or adds to the current task and should be folded in at the next step;",
|
|
33168
33063
|
"queue = it is separate work that should run after the current task;",
|
|
33169
33064
|
"aside = it is a question about progress that can be answered without changing the work.",
|
|
33170
|
-
`Current task: ${
|
|
33171
|
-
context.activity ? `Doing now: ${
|
|
33172
|
-
`New message: ${
|
|
33065
|
+
`Current task: ${clip2(context.currentTask)}`,
|
|
33066
|
+
context.activity ? `Doing now: ${clip2(context.activity, 200)}` : "",
|
|
33067
|
+
`New message: ${clip2(text)}`
|
|
33173
33068
|
].filter(Boolean).join("\n"),
|
|
33174
33069
|
options: [...OPTIONS2]
|
|
33175
33070
|
};
|
|
@@ -33197,7 +33092,7 @@ async function triageIncoming(text, context, opts2 = {}) {
|
|
|
33197
33092
|
function unsure(reason, confidence) {
|
|
33198
33093
|
return { kind: "queue", source: "default", reason, ...confidence === void 0 ? {} : { confidence } };
|
|
33199
33094
|
}
|
|
33200
|
-
function
|
|
33095
|
+
function clip2(text, max = MAX_CHARS) {
|
|
33201
33096
|
const single = text.replace(/\s+/g, " ").trim();
|
|
33202
33097
|
return single.length > max ? `${single.slice(0, max - 1)}\u2026` : single;
|
|
33203
33098
|
}
|
|
@@ -33244,7 +33139,7 @@ var init_inbox_triage = __esm({
|
|
|
33244
33139
|
|
|
33245
33140
|
// src/agent/aside.ts
|
|
33246
33141
|
async function answerAside(question, context, opts2) {
|
|
33247
|
-
const
|
|
33142
|
+
const clip3 = (text2, max) => (text2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
|
|
33248
33143
|
const messages = [
|
|
33249
33144
|
{
|
|
33250
33145
|
role: "system",
|
|
@@ -33253,11 +33148,11 @@ async function answerAside(question, context, opts2) {
|
|
|
33253
33148
|
{
|
|
33254
33149
|
role: "user",
|
|
33255
33150
|
content: [
|
|
33256
|
-
`Task: ${
|
|
33257
|
-
context.progress ? `Progress: ${
|
|
33258
|
-
context.activity ? `Running now: ${
|
|
33259
|
-
context.recentAssistantText ? `Latest agent message: ${
|
|
33260
|
-
`Question: ${
|
|
33151
|
+
`Task: ${clip3(context.currentTask, 600)}`,
|
|
33152
|
+
context.progress ? `Progress: ${clip3(context.progress, 600)}` : "",
|
|
33153
|
+
context.activity ? `Running now: ${clip3(context.activity, 300)}` : "",
|
|
33154
|
+
context.recentAssistantText ? `Latest agent message: ${clip3(context.recentAssistantText, 800)}` : "",
|
|
33155
|
+
`Question: ${clip3(question, 400)}`
|
|
33261
33156
|
].filter(Boolean).join("\n")
|
|
33262
33157
|
}
|
|
33263
33158
|
];
|
|
@@ -33926,15 +33821,15 @@ var init_frontmatter2 = __esm({
|
|
|
33926
33821
|
});
|
|
33927
33822
|
|
|
33928
33823
|
// src/commands/loader.ts
|
|
33929
|
-
import { open, realpath as
|
|
33824
|
+
import { open, realpath as realpath8 } from "fs/promises";
|
|
33930
33825
|
import { homedir as homedir28 } from "os";
|
|
33931
|
-
import { join as
|
|
33826
|
+
import { join as join51, relative as relative11, sep as sep7 } from "path";
|
|
33932
33827
|
function projectCommandsDir(cwd = process.cwd()) {
|
|
33933
|
-
return
|
|
33828
|
+
return join51(cwd, ".kimiflare", "commands");
|
|
33934
33829
|
}
|
|
33935
33830
|
function globalCommandsDir() {
|
|
33936
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
33937
|
-
return
|
|
33831
|
+
const xdg = process.env.XDG_CONFIG_HOME || join51(homedir28(), ".config");
|
|
33832
|
+
return join51(xdg, "kimiflare", "commands");
|
|
33938
33833
|
}
|
|
33939
33834
|
async function loadCustomCommands(cwd = process.cwd()) {
|
|
33940
33835
|
const warnings = [];
|
|
@@ -33973,7 +33868,7 @@ async function loadCustomCommands(cwd = process.cwd()) {
|
|
|
33973
33868
|
async function resolveSafeDir(dir, source, cwd, warnings) {
|
|
33974
33869
|
let realDir;
|
|
33975
33870
|
try {
|
|
33976
|
-
realDir = await
|
|
33871
|
+
realDir = await realpath8(dir);
|
|
33977
33872
|
} catch (err) {
|
|
33978
33873
|
const code = err.code;
|
|
33979
33874
|
if (code !== "ENOENT" && code !== "ENOTDIR") {
|
|
@@ -33984,7 +33879,7 @@ async function resolveSafeDir(dir, source, cwd, warnings) {
|
|
|
33984
33879
|
if (source === "project") {
|
|
33985
33880
|
let realCwd;
|
|
33986
33881
|
try {
|
|
33987
|
-
realCwd = await
|
|
33882
|
+
realCwd = await realpath8(cwd);
|
|
33988
33883
|
} catch {
|
|
33989
33884
|
return null;
|
|
33990
33885
|
}
|
|
@@ -34086,7 +33981,7 @@ var init_loader2 = __esm({
|
|
|
34086
33981
|
|
|
34087
33982
|
// src/commands/renderer.ts
|
|
34088
33983
|
import { exec } from "child_process";
|
|
34089
|
-
import { open as open2, realpath as
|
|
33984
|
+
import { open as open2, realpath as realpath9 } from "fs/promises";
|
|
34090
33985
|
import { isAbsolute as isAbsolute8, relative as relative12, resolve as resolvePathJoin, basename as pathBasename } from "path";
|
|
34091
33986
|
import { promisify as promisify9 } from "util";
|
|
34092
33987
|
function tokenizeArgs(s) {
|
|
@@ -34178,7 +34073,7 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
|
|
|
34178
34073
|
return "" + trailing;
|
|
34179
34074
|
});
|
|
34180
34075
|
}
|
|
34181
|
-
const realCwd = await
|
|
34076
|
+
const realCwd = await realpath9(cwd).catch(() => cwd);
|
|
34182
34077
|
const replacements = await Promise.all(
|
|
34183
34078
|
matches.map(async (match) => {
|
|
34184
34079
|
const rawPath = match[1] ?? "";
|
|
@@ -34198,7 +34093,7 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
|
|
|
34198
34093
|
}
|
|
34199
34094
|
let real;
|
|
34200
34095
|
try {
|
|
34201
|
-
real = await
|
|
34096
|
+
real = await realpath9(resolved);
|
|
34202
34097
|
} catch (error) {
|
|
34203
34098
|
warnings.push(`file inclusion failed: @${rawPath} \u2014 ${message(error)}`);
|
|
34204
34099
|
return "";
|
|
@@ -34316,11 +34211,11 @@ var init_wcag = __esm({
|
|
|
34316
34211
|
});
|
|
34317
34212
|
|
|
34318
34213
|
// src/ui/theme-loader.ts
|
|
34319
|
-
import { readFile as
|
|
34320
|
-
import { join as
|
|
34214
|
+
import { readFile as readFile35, readdir as readdir10 } from "fs/promises";
|
|
34215
|
+
import { join as join52 } from "path";
|
|
34321
34216
|
import { homedir as homedir29 } from "os";
|
|
34322
34217
|
function projectThemesDir(cwd = process.cwd()) {
|
|
34323
|
-
return
|
|
34218
|
+
return join52(cwd, ".kimiflare", "themes");
|
|
34324
34219
|
}
|
|
34325
34220
|
function isHexColor(c) {
|
|
34326
34221
|
return /^#[0-9a-fA-F]{6}$/.test(c);
|
|
@@ -34409,10 +34304,10 @@ async function loadThemesFromDir(dir, source) {
|
|
|
34409
34304
|
return { themes, errors };
|
|
34410
34305
|
}
|
|
34411
34306
|
for (const file of files.filter((f) => f.endsWith(".json"))) {
|
|
34412
|
-
const path =
|
|
34307
|
+
const path = join52(dir, file);
|
|
34413
34308
|
let raw;
|
|
34414
34309
|
try {
|
|
34415
|
-
raw = await
|
|
34310
|
+
raw = await readFile35(path, "utf-8");
|
|
34416
34311
|
} catch (e) {
|
|
34417
34312
|
errors.push(`${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
34418
34313
|
continue;
|
|
@@ -34558,8 +34453,8 @@ var init_theme_loader = __esm({
|
|
|
34558
34453
|
"use strict";
|
|
34559
34454
|
init_wcag();
|
|
34560
34455
|
init_theme();
|
|
34561
|
-
USER_THEMES_DIR =
|
|
34562
|
-
process.env.XDG_CONFIG_HOME ||
|
|
34456
|
+
USER_THEMES_DIR = join52(
|
|
34457
|
+
process.env.XDG_CONFIG_HOME || join52(homedir29(), ".config"),
|
|
34563
34458
|
"kimiflare",
|
|
34564
34459
|
"themes"
|
|
34565
34460
|
);
|
|
@@ -37090,9 +36985,9 @@ var init_resume_progress = __esm({
|
|
|
37090
36985
|
});
|
|
37091
36986
|
|
|
37092
36987
|
// src/agent/supervisor.ts
|
|
37093
|
-
import { readdir as readdir11, readFile as
|
|
36988
|
+
import { readdir as readdir11, readFile as readFile36, stat as stat13 } from "fs/promises";
|
|
37094
36989
|
import { createHash as createHash7 } from "crypto";
|
|
37095
|
-
import { resolve as resolve18, join as
|
|
36990
|
+
import { resolve as resolve18, join as join53 } from "path";
|
|
37096
36991
|
var TurnSupervisor;
|
|
37097
36992
|
var init_supervisor = __esm({
|
|
37098
36993
|
"src/agent/supervisor.ts"() {
|
|
@@ -37482,12 +37377,12 @@ var init_input_handlers = __esm({
|
|
|
37482
37377
|
|
|
37483
37378
|
// src/init/context-generator.ts
|
|
37484
37379
|
import { existsSync as existsSync9, statSync as statSync6 } from "fs";
|
|
37485
|
-
import { join as
|
|
37380
|
+
import { join as join54 } from "path";
|
|
37486
37381
|
function detectFlavor(cwd) {
|
|
37487
37382
|
for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
|
|
37488
37383
|
if (flavor === "generic") continue;
|
|
37489
37384
|
for (const sig of signatures) {
|
|
37490
|
-
const path =
|
|
37385
|
+
const path = join54(cwd, sig);
|
|
37491
37386
|
if (sig.includes("*")) {
|
|
37492
37387
|
try {
|
|
37493
37388
|
const parts = sig.split("*");
|
|
@@ -37508,14 +37403,14 @@ function detectFlavor(cwd) {
|
|
|
37508
37403
|
}
|
|
37509
37404
|
function findFile(cwd, candidates) {
|
|
37510
37405
|
for (const c of candidates) {
|
|
37511
|
-
if (existsSync9(
|
|
37406
|
+
if (existsSync9(join54(cwd, c))) return c;
|
|
37512
37407
|
}
|
|
37513
37408
|
return null;
|
|
37514
37409
|
}
|
|
37515
37410
|
function findSourceRoots(cwd) {
|
|
37516
37411
|
const roots = [];
|
|
37517
37412
|
for (const r of SOURCE_ROOT_CANDIDATES) {
|
|
37518
|
-
const p =
|
|
37413
|
+
const p = join54(cwd, r);
|
|
37519
37414
|
try {
|
|
37520
37415
|
const s = statSync6(p);
|
|
37521
37416
|
if (s.isDirectory()) roots.push(r);
|
|
@@ -37526,9 +37421,9 @@ function findSourceRoots(cwd) {
|
|
|
37526
37421
|
}
|
|
37527
37422
|
function findCiConfig(cwd) {
|
|
37528
37423
|
for (const c of CI_PATHS) {
|
|
37529
|
-
if (existsSync9(
|
|
37424
|
+
if (existsSync9(join54(cwd, c))) {
|
|
37530
37425
|
try {
|
|
37531
|
-
const s = statSync6(
|
|
37426
|
+
const s = statSync6(join54(cwd, c));
|
|
37532
37427
|
return s.isDirectory() ? c : c;
|
|
37533
37428
|
} catch {
|
|
37534
37429
|
}
|
|
@@ -37665,7 +37560,7 @@ function analyzeProject(cwd) {
|
|
|
37665
37560
|
ciConfig: findCiConfig(cwd),
|
|
37666
37561
|
readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
|
|
37667
37562
|
sourceRoots: findSourceRoots(cwd),
|
|
37668
|
-
hasGit: existsSync9(
|
|
37563
|
+
hasGit: existsSync9(join54(cwd, ".git"))
|
|
37669
37564
|
};
|
|
37670
37565
|
}
|
|
37671
37566
|
function bashDiscoveryCommands(profile) {
|
|
@@ -37828,19 +37723,33 @@ Aim for 100\u2013200 lines total. Use markdown tables where they save space.
|
|
|
37828
37723
|
- State management approach
|
|
37829
37724
|
`.trim();
|
|
37830
37725
|
}
|
|
37726
|
+
function buildInitTasks(targetFilename) {
|
|
37727
|
+
return [
|
|
37728
|
+
{ id: "identity", title: "Inspect project identity and configuration", status: "in_progress" },
|
|
37729
|
+
{ id: "structure", title: "Discover source structure, tests, and conventions", status: "pending" },
|
|
37730
|
+
{ id: "workflow", title: "Identify build and development workflows", status: "pending" },
|
|
37731
|
+
{ id: "architecture", title: "Map architecture and project patterns", status: "pending" },
|
|
37732
|
+
{ id: "write", title: "Write or refresh " + targetFilename, status: "pending" },
|
|
37733
|
+
{ id: "verify", title: "Re-read and verify " + targetFilename, status: "pending" }
|
|
37734
|
+
];
|
|
37735
|
+
}
|
|
37831
37736
|
function buildInitPrompt(cwd) {
|
|
37832
37737
|
const existingName = ["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
|
|
37833
|
-
(n) => existsSync9(
|
|
37738
|
+
(n) => existsSync9(join54(cwd, n))
|
|
37834
37739
|
);
|
|
37835
37740
|
const isRefresh = existingName !== void 0;
|
|
37836
37741
|
const targetFilename = existingName ?? "AGENTS.md";
|
|
37837
37742
|
const profile = analyzeProject(cwd);
|
|
37838
37743
|
const checklist = discoveryChecklist(profile);
|
|
37839
37744
|
const sections = sectionTemplate();
|
|
37745
|
+
const tasks = buildInitTasks(targetFilename);
|
|
37840
37746
|
const promptParts = [
|
|
37841
37747
|
isRefresh ? `Regenerate \`${targetFilename}\` at the repository root to refresh project context. The file already exists \u2014 read it first and preserve anything still accurate, updating only what has changed or is missing.` : `Generate a \`${targetFilename}\` at the repository root so future agents have comprehensive project context.`,
|
|
37842
37748
|
"",
|
|
37843
37749
|
"This is a **structured investigation**. Follow the checklist below systematically. Use the `glob`, `read`, `grep`, and `bash` tools to gather information. Do not skip steps.",
|
|
37750
|
+
`Visible task list (already initialized in the UI; keep these IDs and titles):
|
|
37751
|
+
${tasks.map((task) => "- " + task.id + ": " + task.status + ": " + task.title).join("\n")}`,
|
|
37752
|
+
"Keep the visible task checklist synchronized with your progress using `tasks_set`: update the current phase and mark the next phase active before moving on. Map the detailed checklist below onto these high-level tasks.",
|
|
37844
37753
|
"",
|
|
37845
37754
|
`**Detected project profile:** ${profile.primaryLanguage} (${profile.flavor})`,
|
|
37846
37755
|
profile.packageFile ? `- Package file: ${profile.packageFile}` : null,
|
|
@@ -37862,10 +37771,10 @@ function buildInitPrompt(cwd) {
|
|
|
37862
37771
|
"",
|
|
37863
37772
|
isRefresh ? `After writing the file, re-read \`${targetFilename}\` and verify it is complete and accurate.` : "After writing the file, re-read it and verify all sections are present and accurate.",
|
|
37864
37773
|
"",
|
|
37865
|
-
"
|
|
37774
|
+
"The visible task checklist is already initialized. Mark investigation phases complete as you finish them, and complete the write and verification tasks only after re-reading the generated file."
|
|
37866
37775
|
];
|
|
37867
37776
|
const prompt = promptParts.filter((p) => p !== null).join("\n");
|
|
37868
|
-
return { prompt, targetFilename, isRefresh };
|
|
37777
|
+
return { prompt, targetFilename, isRefresh, tasks };
|
|
37869
37778
|
}
|
|
37870
37779
|
var FLAVOR_SIGNATURES, SOURCE_ROOT_CANDIDATES, CI_PATHS;
|
|
37871
37780
|
var init_context_generator = __esm({
|
|
@@ -37914,7 +37823,7 @@ var init_context_generator = __esm({
|
|
|
37914
37823
|
|
|
37915
37824
|
// src/init/run-init.ts
|
|
37916
37825
|
import { existsSync as existsSync10 } from "fs";
|
|
37917
|
-
import { join as
|
|
37826
|
+
import { join as join55 } from "path";
|
|
37918
37827
|
async function runInit(deps) {
|
|
37919
37828
|
const {
|
|
37920
37829
|
cfg,
|
|
@@ -37928,6 +37837,7 @@ async function runInit(deps) {
|
|
|
37928
37837
|
setUsage,
|
|
37929
37838
|
setSessionUsage,
|
|
37930
37839
|
setKimiMdStale,
|
|
37840
|
+
onTasks,
|
|
37931
37841
|
beginTurn,
|
|
37932
37842
|
endTurn,
|
|
37933
37843
|
ensureSessionId,
|
|
@@ -37962,7 +37872,8 @@ async function runInit(deps) {
|
|
|
37962
37872
|
return;
|
|
37963
37873
|
}
|
|
37964
37874
|
const cwd = process.cwd();
|
|
37965
|
-
const { prompt, targetFilename, isRefresh } = buildInitPrompt(cwd);
|
|
37875
|
+
const { prompt, targetFilename, isRefresh, tasks } = buildInitPrompt(cwd);
|
|
37876
|
+
onTasks(tasks);
|
|
37966
37877
|
setEvents((e) => [
|
|
37967
37878
|
...e,
|
|
37968
37879
|
{ kind: "user", key: mkKey2(), text: isRefresh ? `/init (refreshing ${targetFilename})` : "/init" }
|
|
@@ -38007,7 +37918,7 @@ async function runInit(deps) {
|
|
|
38007
37918
|
lspManagerRef.current.notifyChange(path, content);
|
|
38008
37919
|
} else {
|
|
38009
37920
|
void import("fs/promises").then(
|
|
38010
|
-
({ readFile:
|
|
37921
|
+
({ readFile: readFile38 }) => readFile38(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
38011
37922
|
})
|
|
38012
37923
|
);
|
|
38013
37924
|
}
|
|
@@ -38092,6 +38003,7 @@ async function runInit(deps) {
|
|
|
38092
38003
|
void getCostReport(sid).then((report) => setSessionUsage(report.session));
|
|
38093
38004
|
},
|
|
38094
38005
|
onResponseMeta: updateResponseMeta,
|
|
38006
|
+
onTasks,
|
|
38095
38007
|
askPermission: (req) => askForPermission(req, { promptOnBlockedBash: true }),
|
|
38096
38008
|
onGuardrail: (ev) => {
|
|
38097
38009
|
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: ev.message }]);
|
|
@@ -38112,7 +38024,7 @@ async function runInit(deps) {
|
|
|
38112
38024
|
}
|
|
38113
38025
|
}
|
|
38114
38026
|
});
|
|
38115
|
-
if (existsSync10(
|
|
38027
|
+
if (existsSync10(join55(cwd, targetFilename))) {
|
|
38116
38028
|
if (cacheStableRef.current) {
|
|
38117
38029
|
messagesRef.current[1] = {
|
|
38118
38030
|
role: "system",
|
|
@@ -38177,6 +38089,7 @@ async function runInit(deps) {
|
|
|
38177
38089
|
} finally {
|
|
38178
38090
|
logger.info("runInit:finally");
|
|
38179
38091
|
setCodeMode(false);
|
|
38092
|
+
onTasks([]);
|
|
38180
38093
|
const asstId = activeAsstIdRef.current;
|
|
38181
38094
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
38182
38095
|
endTurn();
|
|
@@ -38204,11 +38117,11 @@ var init_run_init = __esm({
|
|
|
38204
38117
|
});
|
|
38205
38118
|
|
|
38206
38119
|
// src/skills/discovery.ts
|
|
38207
|
-
import { readdir as readdir12, stat as
|
|
38208
|
-
import { join as
|
|
38120
|
+
import { readdir as readdir12, stat as stat14, readFile as readFile37 } from "fs/promises";
|
|
38121
|
+
import { join as join56, extname as extname2 } from "path";
|
|
38209
38122
|
async function dirExists(path) {
|
|
38210
38123
|
try {
|
|
38211
|
-
const s = await
|
|
38124
|
+
const s = await stat14(path);
|
|
38212
38125
|
return s.isDirectory();
|
|
38213
38126
|
} catch {
|
|
38214
38127
|
return false;
|
|
@@ -38216,7 +38129,7 @@ async function dirExists(path) {
|
|
|
38216
38129
|
}
|
|
38217
38130
|
async function fileExists(path) {
|
|
38218
38131
|
try {
|
|
38219
|
-
const s = await
|
|
38132
|
+
const s = await stat14(path);
|
|
38220
38133
|
return s.isFile();
|
|
38221
38134
|
} catch {
|
|
38222
38135
|
return false;
|
|
@@ -38229,20 +38142,20 @@ async function scanSkillDir(dirPath, source) {
|
|
|
38229
38142
|
for (const entry of entries) {
|
|
38230
38143
|
if (!entry.isFile()) continue;
|
|
38231
38144
|
if (!SKILL_EXTENSIONS.has(extname2(entry.name))) continue;
|
|
38232
|
-
files.push({ filePath:
|
|
38145
|
+
files.push({ filePath: join56(dirPath, entry.name), source });
|
|
38233
38146
|
}
|
|
38234
38147
|
return files;
|
|
38235
38148
|
}
|
|
38236
38149
|
async function discoverSkills(cwd) {
|
|
38237
|
-
const agentsSkills = await scanSkillDir(
|
|
38238
|
-
const agentsMd = await fileExists(
|
|
38239
|
-
const githubSkills = await scanSkillDir(
|
|
38240
|
-
const kimiflareSkills = await scanSkillDir(
|
|
38150
|
+
const agentsSkills = await scanSkillDir(join56(cwd, ".agents", "skills"), "agents");
|
|
38151
|
+
const agentsMd = await fileExists(join56(cwd, "AGENTS.md")) ? [{ filePath: join56(cwd, "AGENTS.md"), source: "agents-md" }] : [];
|
|
38152
|
+
const githubSkills = await scanSkillDir(join56(cwd, ".github", "skills"), "github");
|
|
38153
|
+
const kimiflareSkills = await scanSkillDir(join56(cwd, ".kimiflare", "skills"), "kimiflare");
|
|
38241
38154
|
const ordered = [...agentsSkills, ...agentsMd, ...githubSkills, ...kimiflareSkills];
|
|
38242
38155
|
return ordered;
|
|
38243
38156
|
}
|
|
38244
38157
|
async function readSkillFile(filePath) {
|
|
38245
|
-
const bytes = await
|
|
38158
|
+
const bytes = await readFile37(filePath);
|
|
38246
38159
|
return { bytes, text: bytes.toString("utf-8") };
|
|
38247
38160
|
}
|
|
38248
38161
|
var SKILL_EXTENSIONS;
|
|
@@ -38448,7 +38361,7 @@ var init_skills = __esm({
|
|
|
38448
38361
|
|
|
38449
38362
|
// src/ui/run-startup-tasks.ts
|
|
38450
38363
|
import { existsSync as existsSync11 } from "fs";
|
|
38451
|
-
import { join as
|
|
38364
|
+
import { join as join57 } from "path";
|
|
38452
38365
|
function runStartupTasks(deps) {
|
|
38453
38366
|
const {
|
|
38454
38367
|
cfg,
|
|
@@ -38471,7 +38384,7 @@ function runStartupTasks(deps) {
|
|
|
38471
38384
|
}
|
|
38472
38385
|
});
|
|
38473
38386
|
if (cfg.memoryEnabled) {
|
|
38474
|
-
const dbPath = cfg.memoryDbPath ??
|
|
38387
|
+
const dbPath = cfg.memoryDbPath ?? join57(process.cwd(), ".kimiflare", "memory.db");
|
|
38475
38388
|
const manager = new MemoryManager({
|
|
38476
38389
|
dbPath,
|
|
38477
38390
|
...auth,
|
|
@@ -38503,7 +38416,7 @@ function runStartupTasks(deps) {
|
|
|
38503
38416
|
});
|
|
38504
38417
|
const cwd = process.cwd();
|
|
38505
38418
|
sessionStartRecallRef.current = manager.recall({ text: cwd, repoPath: cwd, limit: 5 });
|
|
38506
|
-
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync11(
|
|
38419
|
+
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync11(join57(cwd, name)))) {
|
|
38507
38420
|
const lastRefresh = manager.getLastKimiMdRefreshTime(cwd);
|
|
38508
38421
|
const driftCount = manager.countHighSignalMemoriesSince(cwd, lastRefresh);
|
|
38509
38422
|
if (driftCount >= 5) {
|
|
@@ -38514,7 +38427,7 @@ function runStartupTasks(deps) {
|
|
|
38514
38427
|
memoryManagerRef.current?.close();
|
|
38515
38428
|
memoryManagerRef.current = null;
|
|
38516
38429
|
}
|
|
38517
|
-
const skillDbPath = cfg.memoryDbPath ??
|
|
38430
|
+
const skillDbPath = cfg.memoryDbPath ?? join57(process.cwd(), ".kimiflare", "memory.db");
|
|
38518
38431
|
const skillDb = getMemoryDb() ?? openMemoryDb(skillDbPath);
|
|
38519
38432
|
initSkillsSchema(skillDb);
|
|
38520
38433
|
void indexSkills({
|
|
@@ -38871,8 +38784,8 @@ var init_run_compact = __esm({
|
|
|
38871
38784
|
});
|
|
38872
38785
|
|
|
38873
38786
|
// src/commands/save.ts
|
|
38874
|
-
import { mkdir as mkdir19, writeFile as
|
|
38875
|
-
import { dirname as
|
|
38787
|
+
import { mkdir as mkdir19, writeFile as writeFile16, unlink as unlink6 } from "fs/promises";
|
|
38788
|
+
import { dirname as dirname22 } from "path";
|
|
38876
38789
|
async function saveCustomCommand(opts2) {
|
|
38877
38790
|
const dir = opts2.source === "project" ? projectCommandsDir(opts2.cwd) : globalCommandsDir();
|
|
38878
38791
|
const filepath = `${dir}/${opts2.name}.md`;
|
|
@@ -38883,12 +38796,12 @@ async function saveCustomCommand(opts2) {
|
|
|
38883
38796
|
if (opts2.effort) data.effort = opts2.effort;
|
|
38884
38797
|
const frontmatter = serializeFrontmatter(data);
|
|
38885
38798
|
const content = frontmatter + opts2.template;
|
|
38886
|
-
await mkdir19(
|
|
38887
|
-
await
|
|
38799
|
+
await mkdir19(dirname22(filepath), { recursive: true });
|
|
38800
|
+
await writeFile16(filepath, content, "utf8");
|
|
38888
38801
|
return { filepath };
|
|
38889
38802
|
}
|
|
38890
38803
|
async function deleteCustomCommand(cmd) {
|
|
38891
|
-
await
|
|
38804
|
+
await unlink6(cmd.filepath);
|
|
38892
38805
|
}
|
|
38893
38806
|
var init_save = __esm({
|
|
38894
38807
|
"src/commands/save.ts"() {
|
|
@@ -39007,7 +38920,7 @@ __export(app_exports, {
|
|
|
39007
38920
|
import React25, { useState as useState27, useRef as useRef9, useEffect as useEffect11, useCallback as useCallback8, useMemo as useMemo6 } from "react";
|
|
39008
38921
|
import { Box as Box40, Text as Text41, useApp, useInput as useInput19, useWindowSize as useWindowSize2, render } from "ink";
|
|
39009
38922
|
import { existsSync as existsSync12 } from "fs";
|
|
39010
|
-
import { join as
|
|
38923
|
+
import { join as join58, resolve as resolve19 } from "path";
|
|
39011
38924
|
import { homedir as homedir30 } from "os";
|
|
39012
38925
|
import { jsx as jsx42, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
39013
38926
|
function App({
|
|
@@ -39242,6 +39155,21 @@ ${wcagWarnings.join("\n")}` }
|
|
|
39242
39155
|
const effortRef = useRef9(effort);
|
|
39243
39156
|
const usageRef = useRef9(null);
|
|
39244
39157
|
const responseMetaRef = useRef9(null);
|
|
39158
|
+
const updateTaskTracking = useCallback8((nextTasks) => {
|
|
39159
|
+
const previousTasks = tasksRef.current;
|
|
39160
|
+
const prevEmpty = previousTasks.length === 0;
|
|
39161
|
+
const prevAllDone = previousTasks.length > 0 && previousTasks.every((task) => task.status === "completed");
|
|
39162
|
+
tasksRef.current = nextTasks;
|
|
39163
|
+
setTasks(nextTasks);
|
|
39164
|
+
if ((prevEmpty || prevAllDone) && nextTasks.length > 0) {
|
|
39165
|
+
setTasksStartedAt(Date.now());
|
|
39166
|
+
setTasksStartTokens(usageRef.current?.prompt_tokens ?? 0);
|
|
39167
|
+
}
|
|
39168
|
+
if (nextTasks.length === 0) {
|
|
39169
|
+
setTasksStartedAt(null);
|
|
39170
|
+
setTasksStartTokens(0);
|
|
39171
|
+
}
|
|
39172
|
+
}, [tasksRef, setTasks, setTasksStartedAt, setTasksStartTokens]);
|
|
39245
39173
|
const lastApiErrorRef = useRef9(null);
|
|
39246
39174
|
const updateCheckedRef = useRef9(false);
|
|
39247
39175
|
const sessionStateRef = useRef9(emptySessionState());
|
|
@@ -39335,7 +39263,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
39335
39263
|
const exactDirectory = query === "~" || query === "." || query === ".." || query.endsWith("/..");
|
|
39336
39264
|
const prefix = exactDirectory ? `${query.replace(/\/$/, "")}/` : slash >= 0 ? query.slice(0, slash + 1) : "";
|
|
39337
39265
|
const directory = exactDirectory ? query : slash >= 0 ? query.slice(0, slash + 1) : query;
|
|
39338
|
-
const expanded = directory.startsWith("~") ?
|
|
39266
|
+
const expanded = directory.startsWith("~") ? join58(homedir30(), directory.slice(1)) : directory;
|
|
39339
39267
|
const target = resolve19(cwd, expanded || ".");
|
|
39340
39268
|
const entries2 = await glob("*", {
|
|
39341
39269
|
cwd: target,
|
|
@@ -39835,6 +39763,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
39835
39763
|
setUsage,
|
|
39836
39764
|
setSessionUsage,
|
|
39837
39765
|
setKimiMdStale,
|
|
39766
|
+
onTasks: updateTaskTracking,
|
|
39838
39767
|
beginTurn,
|
|
39839
39768
|
endTurn,
|
|
39840
39769
|
ensureSessionId,
|
|
@@ -39864,7 +39793,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
39864
39793
|
lastApiErrorRef,
|
|
39865
39794
|
supervisorRef
|
|
39866
39795
|
});
|
|
39867
|
-
}, [cfg, busy, updateAssistant, updateTool, updateResponseMeta]);
|
|
39796
|
+
}, [cfg, busy, updateAssistant, updateTool, updateResponseMeta, updateTaskTracking]);
|
|
39868
39797
|
const handleThemePick = useCallback8(
|
|
39869
39798
|
(picked) => {
|
|
39870
39799
|
setShowThemePicker(false);
|
|
@@ -40318,7 +40247,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40318
40247
|
}
|
|
40319
40248
|
}
|
|
40320
40249
|
turnCounterRef.current += 1;
|
|
40321
|
-
if (turnCounterRef.current % 15 === 0 && ["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync12(
|
|
40250
|
+
if (turnCounterRef.current % 15 === 0 && ["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync12(join58(process.cwd(), name))) && !kimiMdStale) {
|
|
40322
40251
|
setEvents((e) => [
|
|
40323
40252
|
...e,
|
|
40324
40253
|
{ kind: "info", key: mkKey(), text: "Tip: Rerunning /init occasionally helps autopilot (formerly kimiflare) stay accurate as your project evolves." }
|
|
@@ -40342,7 +40271,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40342
40271
|
};
|
|
40343
40272
|
ensureSessionId();
|
|
40344
40273
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
40345
|
-
const filePath =
|
|
40274
|
+
const filePath = join58(sessionsDir3(), `${sessionIdRef.current}.json`);
|
|
40346
40275
|
await addCheckpoint(filePath, cp);
|
|
40347
40276
|
}
|
|
40348
40277
|
const summary = await generateContinuationSummary({
|
|
@@ -40493,24 +40422,16 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40493
40422
|
void getCostReport(sid).then((report) => setSessionUsage(report.session));
|
|
40494
40423
|
},
|
|
40495
40424
|
onResponseMeta: updateResponseMeta,
|
|
40496
|
-
onTasks:
|
|
40497
|
-
const prevEmpty = tasksRef.current.length === 0;
|
|
40498
|
-
const prevAllDone = tasksRef.current.length > 0 && tasksRef.current.every((t) => t.status === "completed");
|
|
40499
|
-
tasksRef.current = nextTasks;
|
|
40500
|
-
setTasks(nextTasks);
|
|
40501
|
-
if ((prevEmpty || prevAllDone) && nextTasks.length > 0) {
|
|
40502
|
-
setTasksStartedAt(Date.now());
|
|
40503
|
-
setTasksStartTokens(usageRef.current?.prompt_tokens ?? 0);
|
|
40504
|
-
}
|
|
40505
|
-
if (nextTasks.length === 0) {
|
|
40506
|
-
setTasksStartedAt(null);
|
|
40507
|
-
setTasksStartTokens(0);
|
|
40508
|
-
}
|
|
40509
|
-
},
|
|
40425
|
+
onTasks: updateTaskTracking,
|
|
40510
40426
|
onPlanOptions: (options) => {
|
|
40511
40427
|
planOptionsRef.current = options;
|
|
40512
40428
|
},
|
|
40513
40429
|
askPermission: askForPermission,
|
|
40430
|
+
// Sandbox/memory warnings (e.g. Code Mode falling back to the plain
|
|
40431
|
+
// node:vm sandbox) were previously dropped on the floor in the TUI.
|
|
40432
|
+
onWarning: (msg) => {
|
|
40433
|
+
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: msg }]);
|
|
40434
|
+
},
|
|
40514
40435
|
onGuardrail: (ev) => {
|
|
40515
40436
|
if (ev.kind === "loop_recovery" || ev.kind === "loop_stopped") return;
|
|
40516
40437
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: ev.message }]);
|
|
@@ -40673,7 +40594,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40673
40594
|
lspManagerRef.current.notifyChange(path, content2);
|
|
40674
40595
|
} else {
|
|
40675
40596
|
void import("fs/promises").then(
|
|
40676
|
-
({ readFile:
|
|
40597
|
+
({ readFile: readFile38 }) => readFile38(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
40677
40598
|
})
|
|
40678
40599
|
);
|
|
40679
40600
|
}
|
|
@@ -40866,7 +40787,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40866
40787
|
};
|
|
40867
40788
|
ensureSessionId();
|
|
40868
40789
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
40869
|
-
const filePath =
|
|
40790
|
+
const filePath = join58(sessionsDir3(), `${sessionIdRef.current}.json`);
|
|
40870
40791
|
await addCheckpoint(filePath, cp);
|
|
40871
40792
|
}
|
|
40872
40793
|
const summary = await generateContinuationSummary({
|
|
@@ -40942,7 +40863,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
40942
40863
|
}
|
|
40943
40864
|
);
|
|
40944
40865
|
},
|
|
40945
|
-
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateResponseMeta, setShowPlanCompletePicker, runUserShellCommand, ensureTraceStarted]
|
|
40866
|
+
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateResponseMeta, setShowPlanCompletePicker, runUserShellCommand, ensureTraceStarted, updateTaskTracking]
|
|
40946
40867
|
);
|
|
40947
40868
|
useEffect11(() => {
|
|
40948
40869
|
if (canDrainQueue({
|
|
@@ -41433,7 +41354,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
41433
41354
|
lsp: {
|
|
41434
41355
|
servers: cfg?.lspServers ?? {},
|
|
41435
41356
|
scope: lspScope,
|
|
41436
|
-
hasProjectDir: existsSync12(
|
|
41357
|
+
hasProjectDir: existsSync12(join58(process.cwd(), ".kimiflare"))
|
|
41437
41358
|
}
|
|
41438
41359
|
});
|
|
41439
41360
|
});
|
|
@@ -41490,7 +41411,7 @@ ${result2.output ?? "(output not captured)"}`,
|
|
|
41490
41411
|
onCommandDelete: handleCommandDelete2,
|
|
41491
41412
|
lspServers: cfg?.lspServers ?? {},
|
|
41492
41413
|
lspScope,
|
|
41493
|
-
hasProjectDir: existsSync12(
|
|
41414
|
+
hasProjectDir: existsSync12(join58(process.cwd(), ".kimiflare")),
|
|
41494
41415
|
onLspSave: handleLspSave2,
|
|
41495
41416
|
themes: themeList(),
|
|
41496
41417
|
onPickTheme: handleThemePick,
|
|
@@ -41977,8 +41898,8 @@ init_classify();
|
|
|
41977
41898
|
init_subagent_policy();
|
|
41978
41899
|
init_trace();
|
|
41979
41900
|
init_registry2();
|
|
41980
|
-
import { readFile as
|
|
41981
|
-
import { resolve as resolve7, basename as
|
|
41901
|
+
import { readFile as readFile17 } from "fs/promises";
|
|
41902
|
+
import { resolve as resolve7, basename as basename4 } from "path";
|
|
41982
41903
|
async function resolveSession(opts2) {
|
|
41983
41904
|
if (opts2.sessionId) {
|
|
41984
41905
|
const filePath = resolve7(sessionsDir(), `${opts2.sessionId}.json`);
|
|
@@ -42016,8 +41937,8 @@ async function resolveFiles(filePatterns, cwd) {
|
|
|
42016
41937
|
const resolved = /* @__PURE__ */ new Set();
|
|
42017
41938
|
for (const pattern of filePatterns) {
|
|
42018
41939
|
try {
|
|
42019
|
-
const
|
|
42020
|
-
if (
|
|
41940
|
+
const stat15 = await import("fs/promises").then((m) => m.stat(resolve7(cwd, pattern)));
|
|
41941
|
+
if (stat15.isFile()) {
|
|
42021
41942
|
resolved.add(resolve7(cwd, pattern));
|
|
42022
41943
|
continue;
|
|
42023
41944
|
}
|
|
@@ -42041,12 +41962,12 @@ async function buildUserMessage(prompt, files, cwd) {
|
|
|
42041
41962
|
imageParts.push({ type: "image_url", image_url: { url: img.dataUrl } });
|
|
42042
41963
|
} catch (e) {
|
|
42043
41964
|
fileContents.push(`
|
|
42044
|
-
<!-- failed to attach image ${
|
|
41965
|
+
<!-- failed to attach image ${basename4(filePath)}: ${e.message} -->
|
|
42045
41966
|
`);
|
|
42046
41967
|
}
|
|
42047
41968
|
} else {
|
|
42048
41969
|
try {
|
|
42049
|
-
const content = await
|
|
41970
|
+
const content = await readFile17(filePath, "utf8");
|
|
42050
41971
|
const relPath = filePath.startsWith(cwd) ? filePath.slice(cwd.length + 1) : filePath;
|
|
42051
41972
|
fileContents.push(`
|
|
42052
41973
|
--- ${relPath} ---
|
|
@@ -42055,7 +41976,7 @@ ${content}
|
|
|
42055
41976
|
`);
|
|
42056
41977
|
} catch (e) {
|
|
42057
41978
|
fileContents.push(`
|
|
42058
|
-
<!-- failed to read ${
|
|
41979
|
+
<!-- failed to read ${basename4(filePath)}: ${e.message} -->
|
|
42059
41980
|
`);
|
|
42060
41981
|
}
|
|
42061
41982
|
}
|