autopilot-ai 1.10.0 → 1.10.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 +255 -230
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20920,11 +20920,179 @@ var init_app_helpers = __esm({
|
|
|
20920
20920
|
}
|
|
20921
20921
|
});
|
|
20922
20922
|
|
|
20923
|
-
// src/
|
|
20923
|
+
// src/ui/bang-command.ts
|
|
20924
20924
|
import { spawn as spawn7 } from "child_process";
|
|
20925
|
-
import { mkdtemp, readFile as readFile22,
|
|
20926
|
-
import { tmpdir as tmpdir3 } from "os";
|
|
20925
|
+
import { mkdtemp, readFile as readFile22, rm as rm2 } from "fs/promises";
|
|
20926
|
+
import { tmpdir as tmpdir3, platform as platform4 } from "os";
|
|
20927
20927
|
import { join as join33 } from "path";
|
|
20928
|
+
function registerInkInstance(instance) {
|
|
20929
|
+
inkInstance = instance;
|
|
20930
|
+
}
|
|
20931
|
+
function registerTerminalHandoff(h) {
|
|
20932
|
+
terminalHandoff = h;
|
|
20933
|
+
}
|
|
20934
|
+
function runCaptured(inv, cwd) {
|
|
20935
|
+
return new Promise((resolve15) => {
|
|
20936
|
+
const child = spawn7(inv.file, inv.args, { cwd, stdio: ["ignore", "pipe", "pipe"], env: inv.env ?? process.env });
|
|
20937
|
+
let output = "";
|
|
20938
|
+
child.stdout?.on("data", (c) => output += c.toString("utf8"));
|
|
20939
|
+
child.stderr?.on("data", (c) => output += c.toString("utf8"));
|
|
20940
|
+
child.once("error", (e) => resolve15({ code: 127, signal: null, output: `failed to start: ${e.message}` }));
|
|
20941
|
+
child.once("exit", (code, signal) => resolve15({ code, signal, output }));
|
|
20942
|
+
});
|
|
20943
|
+
}
|
|
20944
|
+
function isTerminalHandedOff() {
|
|
20945
|
+
return handedOff;
|
|
20946
|
+
}
|
|
20947
|
+
function parseBangCommand(input) {
|
|
20948
|
+
const t = input.trimStart();
|
|
20949
|
+
if (!t.startsWith("!")) return null;
|
|
20950
|
+
return t.slice(1).trim();
|
|
20951
|
+
}
|
|
20952
|
+
function scriptInvocation(command, shell, logPath, plat = platform4()) {
|
|
20953
|
+
if (plat === "darwin" || plat === "freebsd" || plat === "openbsd" || plat === "netbsd") {
|
|
20954
|
+
return { file: "script", args: ["-q", logPath, shell, "-c", command] };
|
|
20955
|
+
}
|
|
20956
|
+
if (plat === "linux") {
|
|
20957
|
+
return { file: "script", args: ["-q", "-e", "-c", command, logPath], env: { ...process.env, SHELL: shell } };
|
|
20958
|
+
}
|
|
20959
|
+
return null;
|
|
20960
|
+
}
|
|
20961
|
+
function cleanTerminalOutput(raw) {
|
|
20962
|
+
const text = raw.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "").replace(/\x1b[@-Z\\-_]/g, "").replace(/^Script (?:started|done) on .*$/gm, "");
|
|
20963
|
+
const lines = text.split(/\r?\n/).map((line) => {
|
|
20964
|
+
const segs = line.split("\r");
|
|
20965
|
+
let out = segs[segs.length - 1] ?? "";
|
|
20966
|
+
if (!out && segs.length > 1) out = segs.filter(Boolean).pop() ?? "";
|
|
20967
|
+
while (/[^\x08]\x08/.test(out)) out = out.replace(/[^\x08]\x08/, "");
|
|
20968
|
+
return out.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
|
|
20969
|
+
});
|
|
20970
|
+
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
20971
|
+
}
|
|
20972
|
+
function truncateMiddle2(text, max = MAX_CONTEXT_CHARS) {
|
|
20973
|
+
if (text.length <= max) return text;
|
|
20974
|
+
const half = Math.floor(max / 2);
|
|
20975
|
+
return `${text.slice(0, half)}
|
|
20976
|
+
|
|
20977
|
+
[\u2026 ${text.length - max} chars omitted \u2026]
|
|
20978
|
+
|
|
20979
|
+
${text.slice(-half)}`;
|
|
20980
|
+
}
|
|
20981
|
+
function formatBangContext(r) {
|
|
20982
|
+
const status = r.signal ? `killed by ${r.signal}` : `exit code ${r.exitCode ?? "?"}`;
|
|
20983
|
+
const body = r.output === null ? "(output was shown in the user's terminal but could not be captured)" : r.output ? truncateMiddle2(r.output) : "(no output)";
|
|
20984
|
+
return `[The user ran this shell command themselves with \`!\` in the autopilot prompt. This is context for you, not a new request.]
|
|
20985
|
+
$ ${r.command}
|
|
20986
|
+
(${status})
|
|
20987
|
+
${body}`;
|
|
20988
|
+
}
|
|
20989
|
+
function stopReading(stdin) {
|
|
20990
|
+
stdin.pause();
|
|
20991
|
+
const stream = stdin;
|
|
20992
|
+
try {
|
|
20993
|
+
if (stream._handle?.reading && stream._handle.readStop) {
|
|
20994
|
+
stream._handle.readStop();
|
|
20995
|
+
stream._handle.reading = false;
|
|
20996
|
+
if (stream._readableState) stream._readableState.reading = false;
|
|
20997
|
+
}
|
|
20998
|
+
} catch {
|
|
20999
|
+
}
|
|
21000
|
+
}
|
|
21001
|
+
function swallow() {
|
|
21002
|
+
return ((_chunk, encOrCb, cb) => {
|
|
21003
|
+
const done = typeof encOrCb === "function" ? encOrCb : cb;
|
|
21004
|
+
if (typeof done === "function") done();
|
|
21005
|
+
return true;
|
|
21006
|
+
});
|
|
21007
|
+
}
|
|
21008
|
+
function spawnInherit(inv, cwd) {
|
|
21009
|
+
return new Promise((resolve15, reject) => {
|
|
21010
|
+
const child = spawn7(inv.file, inv.args, { cwd, stdio: "inherit", env: inv.env ?? process.env });
|
|
21011
|
+
child.once("error", reject);
|
|
21012
|
+
child.once("exit", (code, signal) => resolve15({ code, signal }));
|
|
21013
|
+
});
|
|
21014
|
+
}
|
|
21015
|
+
async function runBangCommand(command, cwd) {
|
|
21016
|
+
const isWindows = platform4() === "win32";
|
|
21017
|
+
const shell = isWindows ? process.env.COMSPEC || "cmd.exe" : process.env.SHELL || "/bin/sh";
|
|
21018
|
+
const direct = isWindows ? { file: shell, args: ["/c", command] } : { file: shell, args: ["-c", command] };
|
|
21019
|
+
if (terminalHandoff && !await terminalHandoff.suspend()) {
|
|
21020
|
+
const r = await runCaptured(direct, cwd);
|
|
21021
|
+
return { command, exitCode: r.code, signal: r.signal, output: cleanTerminalOutput(r.output) };
|
|
21022
|
+
}
|
|
21023
|
+
const stdin = process.stdin;
|
|
21024
|
+
const stdout = process.stdout;
|
|
21025
|
+
const stderr = process.stderr;
|
|
21026
|
+
const origOut = stdout.write;
|
|
21027
|
+
const origErr = stderr.write;
|
|
21028
|
+
const readable = stdin.listeners("readable");
|
|
21029
|
+
const wasRaw = stdin.isTTY ? stdin.isRaw : false;
|
|
21030
|
+
const logDir2 = isWindows ? null : await mkdtemp(join33(tmpdir3(), "autopilot-bang-"));
|
|
21031
|
+
const logPath = logDir2 ? join33(logDir2, "out.log") : null;
|
|
21032
|
+
const viaScript = logPath ? scriptInvocation(command, shell, logPath) : null;
|
|
21033
|
+
inkInstance?.clear();
|
|
21034
|
+
origOut.call(stdout, `
|
|
21035
|
+
$ ${command}
|
|
21036
|
+
`);
|
|
21037
|
+
stdout.write = swallow();
|
|
21038
|
+
stderr.write = swallow();
|
|
21039
|
+
for (const l of readable) stdin.removeListener("readable", l);
|
|
21040
|
+
if (stdin.isTTY) stdin.setRawMode(false);
|
|
21041
|
+
stopReading(stdin);
|
|
21042
|
+
handedOff = true;
|
|
21043
|
+
let result2;
|
|
21044
|
+
let captured = false;
|
|
21045
|
+
let spawnError = null;
|
|
21046
|
+
try {
|
|
21047
|
+
if (viaScript) {
|
|
21048
|
+
try {
|
|
21049
|
+
result2 = await spawnInherit(viaScript, cwd);
|
|
21050
|
+
captured = true;
|
|
21051
|
+
} catch (e) {
|
|
21052
|
+
logger.warn("bang:script_unavailable", { error: e.message });
|
|
21053
|
+
result2 = await spawnInherit(direct, cwd);
|
|
21054
|
+
}
|
|
21055
|
+
} else {
|
|
21056
|
+
result2 = await spawnInherit(direct, cwd);
|
|
21057
|
+
}
|
|
21058
|
+
} catch (e) {
|
|
21059
|
+
result2 = { code: 127, signal: null };
|
|
21060
|
+
spawnError = e.message;
|
|
21061
|
+
logger.warn("bang:spawn_failed", { error: spawnError });
|
|
21062
|
+
} finally {
|
|
21063
|
+
handedOff = false;
|
|
21064
|
+
stdout.write = origOut;
|
|
21065
|
+
stderr.write = origErr;
|
|
21066
|
+
if (stdin.isTTY) stdin.setRawMode(wasRaw);
|
|
21067
|
+
for (const l of readable) stdin.addListener("readable", l);
|
|
21068
|
+
origOut.call(stdout, "\n");
|
|
21069
|
+
terminalHandoff?.resume();
|
|
21070
|
+
}
|
|
21071
|
+
let output = spawnError ? `failed to start: ${spawnError}` : null;
|
|
21072
|
+
if (captured && logPath) {
|
|
21073
|
+
output = cleanTerminalOutput(await readFile22(logPath, "utf8").catch(() => ""));
|
|
21074
|
+
}
|
|
21075
|
+
if (logDir2) await rm2(logDir2, { recursive: true, force: true }).catch(() => {
|
|
21076
|
+
});
|
|
21077
|
+
return { command, exitCode: result2.code, signal: result2.signal, output };
|
|
21078
|
+
}
|
|
21079
|
+
var inkInstance, handedOff, terminalHandoff, MAX_CONTEXT_CHARS;
|
|
21080
|
+
var init_bang_command = __esm({
|
|
21081
|
+
"src/ui/bang-command.ts"() {
|
|
21082
|
+
"use strict";
|
|
21083
|
+
init_logger();
|
|
21084
|
+
inkInstance = null;
|
|
21085
|
+
handedOff = false;
|
|
21086
|
+
terminalHandoff = null;
|
|
21087
|
+
MAX_CONTEXT_CHARS = 16e3;
|
|
21088
|
+
}
|
|
21089
|
+
});
|
|
21090
|
+
|
|
21091
|
+
// src/remote/deploy-commute.ts
|
|
21092
|
+
import { spawn as spawn8 } from "child_process";
|
|
21093
|
+
import { mkdtemp as mkdtemp2, readFile as readFile23, writeFile as writeFile13, rm as rm3 } from "fs/promises";
|
|
21094
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
21095
|
+
import { join as join34 } from "path";
|
|
20928
21096
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
20929
21097
|
async function cfApiFetch(accountId, apiToken, path, init) {
|
|
20930
21098
|
const url = `${CF_API}/accounts/${encodeURIComponent(accountId)}${path}`;
|
|
@@ -20995,7 +21163,7 @@ function generateSecret2() {
|
|
|
20995
21163
|
}
|
|
20996
21164
|
function runCmd(cmd, args, opts2 = {}) {
|
|
20997
21165
|
return new Promise((resolve15) => {
|
|
20998
|
-
const child =
|
|
21166
|
+
const child = spawn8(cmd, args, {
|
|
20999
21167
|
cwd: opts2.cwd,
|
|
21000
21168
|
env: { ...process.env, ...opts2.env ?? {} },
|
|
21001
21169
|
stdio: [opts2.input ? "pipe" : "ignore", "pipe", "pipe"]
|
|
@@ -21155,8 +21323,8 @@ ${wranglerInstall.stderr.slice(-600)}`,
|
|
|
21155
21323
|
ok: true
|
|
21156
21324
|
};
|
|
21157
21325
|
yield { message: "Prerequisites ready", ok: true };
|
|
21158
|
-
const tmpRoot = await
|
|
21159
|
-
const repoDir =
|
|
21326
|
+
const tmpRoot = await mkdtemp2(join34(tmpdir4(), "kimiflare-commute-"));
|
|
21327
|
+
const repoDir = join34(tmpRoot, "kimiflare-commute");
|
|
21160
21328
|
yield { message: `Fetching worker source from GitHub (${COMMUTE_REPO})\u2026` };
|
|
21161
21329
|
const clone = await runCmd("git", ["clone", "--depth", "1", "--branch", COMMUTE_BRANCH, COMMUTE_REPO, repoDir], { timeoutMs: 6e4 });
|
|
21162
21330
|
if (clone.code !== 0) {
|
|
@@ -21165,8 +21333,8 @@ ${(clone.stderr || clone.stdout).slice(0, 400)}`, error: true };
|
|
|
21165
21333
|
throw new Error("clone failed");
|
|
21166
21334
|
}
|
|
21167
21335
|
yield { message: "Source fetched from GitHub", ok: true };
|
|
21168
|
-
const workerDir =
|
|
21169
|
-
const wranglerToml =
|
|
21336
|
+
const workerDir = join34(repoDir, "remote", "worker");
|
|
21337
|
+
const wranglerToml = join34(workerDir, "wrangler.toml");
|
|
21170
21338
|
yield { message: "Installing Worker dependencies (npm install)\u2026" };
|
|
21171
21339
|
const install = await runCmd("npm", ["install", "--no-audit", "--no-fund", "--loglevel=error"], {
|
|
21172
21340
|
cwd: workerDir,
|
|
@@ -21255,7 +21423,7 @@ ${(install.stderr || install.stdout).slice(-1200).trim()}`,
|
|
|
21255
21423
|
ok: true
|
|
21256
21424
|
};
|
|
21257
21425
|
yield { message: "Patching wrangler.toml\u2026" };
|
|
21258
|
-
let toml = await
|
|
21426
|
+
let toml = await readFile23(wranglerToml, "utf8");
|
|
21259
21427
|
toml = toml.replace(/^name\s*=\s*"[^"]+"/m, `name = "${workerName}"`);
|
|
21260
21428
|
toml = toml.replace(
|
|
21261
21429
|
/(\[\[kv_namespaces\]\][\s\S]*?binding\s*=\s*"OAUTH_KV"[\s\S]*?id\s*=\s*")[^"]+(")/,
|
|
@@ -21339,7 +21507,7 @@ invocation_logs = true
|
|
|
21339
21507
|
};
|
|
21340
21508
|
await saveConfig(next);
|
|
21341
21509
|
yield { message: "Saved to ~/.config/kimiflare/config.json", ok: true };
|
|
21342
|
-
await
|
|
21510
|
+
await rm3(tmpRoot, { recursive: true, force: true }).catch(() => {
|
|
21343
21511
|
});
|
|
21344
21512
|
yield { message: "Setup complete \u2014 multi-agent is ready to use.", done: true };
|
|
21345
21513
|
return { workerEndpoint: workerUrl, workerApiKey };
|
|
@@ -22593,7 +22761,7 @@ var init_text_input = __esm({
|
|
|
22593
22761
|
import { useState as useState5 } from "react";
|
|
22594
22762
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
22595
22763
|
import SelectInput3 from "ink-select-input";
|
|
22596
|
-
import { spawn as
|
|
22764
|
+
import { spawn as spawn9 } from "child_process";
|
|
22597
22765
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
22598
22766
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
22599
22767
|
const theme = useTheme();
|
|
@@ -22607,7 +22775,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
22607
22775
|
const runInstall = (command) => {
|
|
22608
22776
|
setInstallState({ status: "running", output: "Installing..." });
|
|
22609
22777
|
const { shell, args } = getShellCommand();
|
|
22610
|
-
const child =
|
|
22778
|
+
const child = spawn9(shell, [...args, command], {
|
|
22611
22779
|
env: process.env
|
|
22612
22780
|
});
|
|
22613
22781
|
let stdout = "";
|
|
@@ -23115,7 +23283,7 @@ var init_lsp_wizard = __esm({
|
|
|
23115
23283
|
});
|
|
23116
23284
|
|
|
23117
23285
|
// src/hooks/recommended.ts
|
|
23118
|
-
import { platform as
|
|
23286
|
+
import { platform as platform5 } from "os";
|
|
23119
23287
|
function getRecommendedHook(id) {
|
|
23120
23288
|
return RECOMMENDED_HOOKS.find((r) => r.id === id);
|
|
23121
23289
|
}
|
|
@@ -23123,7 +23291,7 @@ var isMac, RECOMMENDED_HOOKS;
|
|
|
23123
23291
|
var init_recommended = __esm({
|
|
23124
23292
|
"src/hooks/recommended.ts"() {
|
|
23125
23293
|
"use strict";
|
|
23126
|
-
isMac =
|
|
23294
|
+
isMac = platform5() === "darwin";
|
|
23127
23295
|
RECOMMENDED_HOOKS = [
|
|
23128
23296
|
// ── Stop notifications ───────────────────────────────────────────────
|
|
23129
23297
|
{
|
|
@@ -23599,10 +23767,10 @@ __export(camouflage_view_exports, {
|
|
|
23599
23767
|
toolSummary: () => toolSummary,
|
|
23600
23768
|
validateCommandName: () => validateCommandName
|
|
23601
23769
|
});
|
|
23602
|
-
import { execFileSync as execFileSync3, spawn as
|
|
23770
|
+
import { execFileSync as execFileSync3, spawn as spawn10 } from "child_process";
|
|
23603
23771
|
import { readdir as readdir6 } from "fs/promises";
|
|
23604
23772
|
import { homedir as homedir23 } from "os";
|
|
23605
|
-
import { join as
|
|
23773
|
+
import { join as join35, resolve as resolve12 } from "path";
|
|
23606
23774
|
async function loadSdk() {
|
|
23607
23775
|
const sdk = await import("camouflage-tui").catch((err) => {
|
|
23608
23776
|
throw new CamouflageUnavailable(`camouflage-tui is not installed (${err.message})`);
|
|
@@ -23643,6 +23811,10 @@ async function runCamouflageView(opts2) {
|
|
|
23643
23811
|
cam.send("MentionCandidatesRegistered", { candidates: files.map((token) => ({ token, kind: "file" })) });
|
|
23644
23812
|
}
|
|
23645
23813
|
const view = new View(cam, sdk);
|
|
23814
|
+
registerTerminalHandoff({
|
|
23815
|
+
suspend: async () => sdk.suspendTerminal ? (await sdk.suspendTerminal(cam)).supported : false,
|
|
23816
|
+
resume: () => sdk.resumeTerminal?.(cam)
|
|
23817
|
+
});
|
|
23646
23818
|
cam.on("userInput", (text) => {
|
|
23647
23819
|
view.echoed.push(text.trim());
|
|
23648
23820
|
view.actions?.submit(text);
|
|
@@ -23663,6 +23835,7 @@ async function runCamouflageView(opts2) {
|
|
|
23663
23835
|
const finish = async () => {
|
|
23664
23836
|
if (closing) return;
|
|
23665
23837
|
closing = true;
|
|
23838
|
+
registerTerminalHandoff(null);
|
|
23666
23839
|
await cam.close().catch(() => void 0);
|
|
23667
23840
|
restoreConsole();
|
|
23668
23841
|
};
|
|
@@ -23682,7 +23855,7 @@ async function runCamouflageView(opts2) {
|
|
|
23682
23855
|
function runShell(command) {
|
|
23683
23856
|
return new Promise((resolve15) => {
|
|
23684
23857
|
const { shell, args } = getShellCommand();
|
|
23685
|
-
const child =
|
|
23858
|
+
const child = spawn10(shell, [...args, command], { env: process.env });
|
|
23686
23859
|
let out = "";
|
|
23687
23860
|
child.stdout?.on("data", (c) => out += c.toString("utf8"));
|
|
23688
23861
|
child.stderr?.on("data", (c) => out += c.toString("utf8"));
|
|
@@ -23738,7 +23911,7 @@ function truncateText(s, max) {
|
|
|
23738
23911
|
async function listMentionDir(cwd, query) {
|
|
23739
23912
|
const exact = query === "~" || query === "." || query === ".." || query.endsWith("/..");
|
|
23740
23913
|
const dir = exact ? `${query}/` : query.slice(0, query.lastIndexOf("/") + 1);
|
|
23741
|
-
const expanded = dir.startsWith("~") ?
|
|
23914
|
+
const expanded = dir.startsWith("~") ? join35(homedir23(), dir.slice(1)) : dir;
|
|
23742
23915
|
const target = resolve12(cwd, expanded || ".");
|
|
23743
23916
|
try {
|
|
23744
23917
|
const items = await readdir6(target, { withFileTypes: true });
|
|
@@ -23870,6 +24043,7 @@ var init_camouflage_view = __esm({
|
|
|
23870
24043
|
init_model_picker();
|
|
23871
24044
|
init_help_menu();
|
|
23872
24045
|
init_app_helpers();
|
|
24046
|
+
init_bang_command();
|
|
23873
24047
|
init_deploy_commute();
|
|
23874
24048
|
init_remote_dashboard();
|
|
23875
24049
|
init_worker_client();
|
|
@@ -26449,7 +26623,7 @@ var init_status = __esm({
|
|
|
26449
26623
|
// src/ui/permission.tsx
|
|
26450
26624
|
import { useState as useState9, useCallback } from "react";
|
|
26451
26625
|
import { Box as Box13, Text as Text14, useInput as useInput6 } from "ink";
|
|
26452
|
-
import { platform as
|
|
26626
|
+
import { platform as platform6 } from "os";
|
|
26453
26627
|
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
26454
26628
|
function formatSelection(label, shortcut) {
|
|
26455
26629
|
return `${label} [${MOD_KEY}+${shortcut}]`;
|
|
@@ -26613,7 +26787,7 @@ var init_permission = __esm({
|
|
|
26613
26787
|
{ value: { decision: "deny", scope: "once" }, label: "Something else", key: 3 }
|
|
26614
26788
|
];
|
|
26615
26789
|
DENY = { decision: "deny", scope: "once" };
|
|
26616
|
-
MOD_KEY =
|
|
26790
|
+
MOD_KEY = platform6() === "darwin" ? "\u2325" : "Alt";
|
|
26617
26791
|
}
|
|
26618
26792
|
});
|
|
26619
26793
|
|
|
@@ -27812,13 +27986,13 @@ var init_frontmatter = __esm({
|
|
|
27812
27986
|
// src/commands/loader.ts
|
|
27813
27987
|
import { open, realpath as realpath6 } from "fs/promises";
|
|
27814
27988
|
import { homedir as homedir24 } from "os";
|
|
27815
|
-
import { join as
|
|
27989
|
+
import { join as join36, relative as relative10, sep as sep6 } from "path";
|
|
27816
27990
|
function projectCommandsDir(cwd = process.cwd()) {
|
|
27817
|
-
return
|
|
27991
|
+
return join36(cwd, ".kimiflare", "commands");
|
|
27818
27992
|
}
|
|
27819
27993
|
function globalCommandsDir() {
|
|
27820
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
27821
|
-
return
|
|
27994
|
+
const xdg = process.env.XDG_CONFIG_HOME || join36(homedir24(), ".config");
|
|
27995
|
+
return join36(xdg, "kimiflare", "commands");
|
|
27822
27996
|
}
|
|
27823
27997
|
async function loadCustomCommands(cwd = process.cwd()) {
|
|
27824
27998
|
const warnings = [];
|
|
@@ -29026,11 +29200,11 @@ var init_wcag = __esm({
|
|
|
29026
29200
|
});
|
|
29027
29201
|
|
|
29028
29202
|
// src/ui/theme-loader.ts
|
|
29029
|
-
import { readFile as
|
|
29030
|
-
import { join as
|
|
29203
|
+
import { readFile as readFile24, readdir as readdir7 } from "fs/promises";
|
|
29204
|
+
import { join as join37 } from "path";
|
|
29031
29205
|
import { homedir as homedir25 } from "os";
|
|
29032
29206
|
function projectThemesDir(cwd = process.cwd()) {
|
|
29033
|
-
return
|
|
29207
|
+
return join37(cwd, ".kimiflare", "themes");
|
|
29034
29208
|
}
|
|
29035
29209
|
function isHexColor(c) {
|
|
29036
29210
|
return /^#[0-9a-fA-F]{6}$/.test(c);
|
|
@@ -29119,10 +29293,10 @@ async function loadThemesFromDir(dir, source) {
|
|
|
29119
29293
|
return { themes, errors };
|
|
29120
29294
|
}
|
|
29121
29295
|
for (const file of files.filter((f) => f.endsWith(".json"))) {
|
|
29122
|
-
const path =
|
|
29296
|
+
const path = join37(dir, file);
|
|
29123
29297
|
let raw;
|
|
29124
29298
|
try {
|
|
29125
|
-
raw = await
|
|
29299
|
+
raw = await readFile24(path, "utf-8");
|
|
29126
29300
|
} catch (e) {
|
|
29127
29301
|
errors.push(`${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
29128
29302
|
continue;
|
|
@@ -29268,8 +29442,8 @@ var init_theme_loader = __esm({
|
|
|
29268
29442
|
"use strict";
|
|
29269
29443
|
init_wcag();
|
|
29270
29444
|
init_theme();
|
|
29271
|
-
USER_THEMES_DIR =
|
|
29272
|
-
process.env.XDG_CONFIG_HOME ||
|
|
29445
|
+
USER_THEMES_DIR = join37(
|
|
29446
|
+
process.env.XDG_CONFIG_HOME || join37(homedir25(), ".config"),
|
|
29273
29447
|
"kimiflare",
|
|
29274
29448
|
"themes"
|
|
29275
29449
|
);
|
|
@@ -32388,8 +32562,8 @@ var init_input_handlers = __esm({
|
|
|
32388
32562
|
|
|
32389
32563
|
// src/agent/jev-context.ts
|
|
32390
32564
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
32391
|
-
import { readFile as
|
|
32392
|
-
import { basename as basename6, join as
|
|
32565
|
+
import { readFile as readFile25 } from "fs/promises";
|
|
32566
|
+
import { basename as basename6, join as join38, resolve as resolve13 } from "path";
|
|
32393
32567
|
function messageText(message2) {
|
|
32394
32568
|
if (typeof message2.content === "string") return message2.content.trim();
|
|
32395
32569
|
if (!Array.isArray(message2.content)) return "";
|
|
@@ -32411,7 +32585,7 @@ function projectRoot(cwd) {
|
|
|
32411
32585
|
}
|
|
32412
32586
|
async function readPackageMetadata(root) {
|
|
32413
32587
|
try {
|
|
32414
|
-
const parsed = JSON.parse(await
|
|
32588
|
+
const parsed = JSON.parse(await readFile25(join38(root, "package.json"), "utf8"));
|
|
32415
32589
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
32416
32590
|
const pkg = parsed;
|
|
32417
32591
|
const metadata = {};
|
|
@@ -32428,7 +32602,7 @@ async function readPackageMetadata(root) {
|
|
|
32428
32602
|
async function readLicenseEvidence(root) {
|
|
32429
32603
|
for (const name of ["LICENSE", "LICENSE.md", "LICENSE.txt", "LICENCE", "COPYING"]) {
|
|
32430
32604
|
try {
|
|
32431
|
-
const content = (await
|
|
32605
|
+
const content = (await readFile25(join38(root, name), "utf8")).trim();
|
|
32432
32606
|
if (content) return { source: `project license (${name})`, content: content.slice(0, 700) };
|
|
32433
32607
|
} catch {
|
|
32434
32608
|
}
|
|
@@ -32437,7 +32611,7 @@ async function readLicenseEvidence(root) {
|
|
|
32437
32611
|
}
|
|
32438
32612
|
async function buildJevContext(question, messages, cwd = process.cwd()) {
|
|
32439
32613
|
const entries = [];
|
|
32440
|
-
let remaining =
|
|
32614
|
+
let remaining = MAX_CONTEXT_CHARS2;
|
|
32441
32615
|
const add = (source, content, limit = remaining) => {
|
|
32442
32616
|
if (remaining <= 0 || !content.trim()) return;
|
|
32443
32617
|
const sourceText = source.slice(0, 160);
|
|
@@ -32504,11 +32678,11 @@ function formatJevContextReceipt(entries, includeContent = false) {
|
|
|
32504
32678
|
"Chat/project context is reference data, not verified fact."
|
|
32505
32679
|
].join("\n");
|
|
32506
32680
|
}
|
|
32507
|
-
var
|
|
32681
|
+
var MAX_CONTEXT_CHARS2, MAX_CONVERSATION_CHARS, CURRENT_PROJECT_REFERENCE, LICENSE_QUESTION, CONVERSATION_REFERENCE, SECRET_PATTERNS3;
|
|
32508
32682
|
var init_jev_context = __esm({
|
|
32509
32683
|
"src/agent/jev-context.ts"() {
|
|
32510
32684
|
"use strict";
|
|
32511
|
-
|
|
32685
|
+
MAX_CONTEXT_CHARS2 = 6e3;
|
|
32512
32686
|
MAX_CONVERSATION_CHARS = 4e3;
|
|
32513
32687
|
CURRENT_PROJECT_REFERENCE = /\b(?:this|that|our|current|local|working)\s+(?:repo(?:sitory)?|project|workspace|codebase|harness)\b/i;
|
|
32514
32688
|
LICENSE_QUESTION = /\bopen[\s-]?source\b|\blicen[cs](?:e|ed|ing)?\b|\bspdx\b|\bcopyleft\b/i;
|
|
@@ -32684,8 +32858,8 @@ var init_frontmatter2 = __esm({
|
|
|
32684
32858
|
});
|
|
32685
32859
|
|
|
32686
32860
|
// src/skills/loader.ts
|
|
32687
|
-
import { readFile as
|
|
32688
|
-
import { join as
|
|
32861
|
+
import { readFile as readFile26, readdir as readdir8, stat as stat8 } from "fs/promises";
|
|
32862
|
+
import { join as join39, extname } from "path";
|
|
32689
32863
|
function normalizeManifest(raw, filePath) {
|
|
32690
32864
|
const name = typeof raw.name === "string" ? raw.name : "";
|
|
32691
32865
|
const description = typeof raw.description === "string" ? raw.description : "";
|
|
@@ -32699,7 +32873,7 @@ function normalizeManifest(raw, filePath) {
|
|
|
32699
32873
|
return { name, description, match, scope, priority, enabled: enabled2 };
|
|
32700
32874
|
}
|
|
32701
32875
|
async function loadSkillFile(filePath) {
|
|
32702
|
-
const raw = await
|
|
32876
|
+
const raw = await readFile26(filePath, "utf-8");
|
|
32703
32877
|
const parsed = parseFrontmatter2(raw);
|
|
32704
32878
|
const manifest = normalizeManifest(parsed.data, filePath);
|
|
32705
32879
|
const body = parsed.content.trim();
|
|
@@ -32721,7 +32895,7 @@ async function loadSkillsFromDir(dirPath) {
|
|
|
32721
32895
|
const entries = await readdir8(dirPath);
|
|
32722
32896
|
const files = [];
|
|
32723
32897
|
for (const entry of entries) {
|
|
32724
|
-
const full =
|
|
32898
|
+
const full = join39(dirPath, entry);
|
|
32725
32899
|
const s = await stat8(full);
|
|
32726
32900
|
if (s.isFile() && extname(entry) === ".md") {
|
|
32727
32901
|
files.push(full);
|
|
@@ -32749,12 +32923,12 @@ var init_loader2 = __esm({
|
|
|
32749
32923
|
});
|
|
32750
32924
|
|
|
32751
32925
|
// src/skills/manager.ts
|
|
32752
|
-
import { mkdir as mkdir13, writeFile as writeFile14, unlink as unlink4, readFile as
|
|
32753
|
-
import { join as
|
|
32926
|
+
import { mkdir as mkdir13, writeFile as writeFile14, unlink as unlink4, readFile as readFile27 } from "fs/promises";
|
|
32927
|
+
import { join as join40 } from "path";
|
|
32754
32928
|
function getSkillDirs(cwd) {
|
|
32755
32929
|
return {
|
|
32756
|
-
projectDir:
|
|
32757
|
-
globalDir:
|
|
32930
|
+
projectDir: join40(cwd, ".kimiflare", "skills"),
|
|
32931
|
+
globalDir: join40(process.env.HOME ?? "", ".config", "kimiflare", "skills")
|
|
32758
32932
|
};
|
|
32759
32933
|
}
|
|
32760
32934
|
async function listAllSkills(cwd) {
|
|
@@ -32768,7 +32942,7 @@ async function listAllSkills(cwd) {
|
|
|
32768
32942
|
async function createSkill(opts2) {
|
|
32769
32943
|
const dirs = getSkillDirs(opts2.cwd);
|
|
32770
32944
|
const dir = opts2.scope === "project" ? dirs.projectDir : dirs.globalDir;
|
|
32771
|
-
const filepath =
|
|
32945
|
+
const filepath = join40(dir, `${opts2.name}.md`);
|
|
32772
32946
|
const frontmatter = {
|
|
32773
32947
|
name: opts2.name,
|
|
32774
32948
|
enabled: true,
|
|
@@ -32804,7 +32978,7 @@ async function setSkillEnabled(name, enabled2, cwd) {
|
|
|
32804
32978
|
const all = await listAllSkills(cwd);
|
|
32805
32979
|
const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
|
|
32806
32980
|
if (!skill) throw new Error(`skill "${name}" not found`);
|
|
32807
|
-
const raw = await
|
|
32981
|
+
const raw = await readFile27(skill.filePath, "utf-8");
|
|
32808
32982
|
const parsed = parseFrontmatter2(raw);
|
|
32809
32983
|
parsed.data.enabled = enabled2;
|
|
32810
32984
|
const yaml = Object.entries(parsed.data).map(([k, v]) => {
|
|
@@ -32860,9 +33034,9 @@ var init_plan_resolver = __esm({
|
|
|
32860
33034
|
|
|
32861
33035
|
// src/util/clipboard.ts
|
|
32862
33036
|
import { execSync as execSync5 } from "child_process";
|
|
32863
|
-
import { platform as
|
|
33037
|
+
import { platform as platform7 } from "os";
|
|
32864
33038
|
function writeToClipboard(text) {
|
|
32865
|
-
const os2 =
|
|
33039
|
+
const os2 = platform7();
|
|
32866
33040
|
try {
|
|
32867
33041
|
if (os2 === "darwin") {
|
|
32868
33042
|
execSync5("pbcopy", { input: text, timeout: 5e3 });
|
|
@@ -32897,15 +33071,15 @@ var tui_report_exports = {};
|
|
|
32897
33071
|
__export(tui_report_exports, {
|
|
32898
33072
|
getCategoryReportText: () => getCategoryReportText
|
|
32899
33073
|
});
|
|
32900
|
-
import { readFile as
|
|
32901
|
-
import { join as
|
|
33074
|
+
import { readFile as readFile28 } from "fs/promises";
|
|
33075
|
+
import { join as join41 } from "path";
|
|
32902
33076
|
import { homedir as homedir26 } from "os";
|
|
32903
33077
|
function usageDir3() {
|
|
32904
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
32905
|
-
return
|
|
33078
|
+
const xdg = process.env.XDG_DATA_HOME || join41(homedir26(), ".local", "share");
|
|
33079
|
+
return join41(xdg, "kimiflare");
|
|
32906
33080
|
}
|
|
32907
33081
|
function usagePath4() {
|
|
32908
|
-
return
|
|
33082
|
+
return join41(usageDir3(), "usage.json");
|
|
32909
33083
|
}
|
|
32910
33084
|
function today3() {
|
|
32911
33085
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -32917,7 +33091,7 @@ function daysAgo2(n) {
|
|
|
32917
33091
|
}
|
|
32918
33092
|
async function loadLog3() {
|
|
32919
33093
|
try {
|
|
32920
|
-
const raw = await
|
|
33094
|
+
const raw = await readFile28(usagePath4(), "utf8");
|
|
32921
33095
|
return JSON.parse(raw);
|
|
32922
33096
|
} catch {
|
|
32923
33097
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -32974,7 +33148,7 @@ var init_tui_report = __esm({
|
|
|
32974
33148
|
});
|
|
32975
33149
|
|
|
32976
33150
|
// src/ui/slash-commands.ts
|
|
32977
|
-
import { join as
|
|
33151
|
+
import { join as join42 } from "path";
|
|
32978
33152
|
import QRCode from "qrcode";
|
|
32979
33153
|
function executeFreshStart(ctx, planText, overrideMode, opts2 = {}) {
|
|
32980
33154
|
const oldSessionId = ctx.sessionIdRef.current;
|
|
@@ -33898,7 +34072,7 @@ ${lines.join("\n")}` }]);
|
|
|
33898
34072
|
void (async () => {
|
|
33899
34073
|
try {
|
|
33900
34074
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
33901
|
-
const file = await loadSession(
|
|
34075
|
+
const file = await loadSession(join42(sessionsDir3(), `${currentId}.json`));
|
|
33902
34076
|
const cps = file.checkpoints ?? [];
|
|
33903
34077
|
if (cps.length === 0) {
|
|
33904
34078
|
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: "no checkpoints in this session" }]);
|
|
@@ -33943,7 +34117,7 @@ ${lines.join("\n")}` }]);
|
|
|
33943
34117
|
try {
|
|
33944
34118
|
ctx.ensureSessionId();
|
|
33945
34119
|
const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
|
|
33946
|
-
const filePath =
|
|
34120
|
+
const filePath = join42(sessionsDir3(), `${ctx.sessionIdRef.current}.json`);
|
|
33947
34121
|
await addCheckpoint(filePath, cp);
|
|
33948
34122
|
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: `checkpoint saved: "${label}"` }]);
|
|
33949
34123
|
} catch (e) {
|
|
@@ -34575,12 +34749,12 @@ project: ${projectSettingsPath(cwd)}`
|
|
|
34575
34749
|
|
|
34576
34750
|
// src/init/context-generator.ts
|
|
34577
34751
|
import { existsSync as existsSync6, statSync as statSync6 } from "fs";
|
|
34578
|
-
import { join as
|
|
34752
|
+
import { join as join43 } from "path";
|
|
34579
34753
|
function detectFlavor(cwd) {
|
|
34580
34754
|
for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
|
|
34581
34755
|
if (flavor === "generic") continue;
|
|
34582
34756
|
for (const sig of signatures) {
|
|
34583
|
-
const path =
|
|
34757
|
+
const path = join43(cwd, sig);
|
|
34584
34758
|
if (sig.includes("*")) {
|
|
34585
34759
|
try {
|
|
34586
34760
|
const parts = sig.split("*");
|
|
@@ -34601,14 +34775,14 @@ function detectFlavor(cwd) {
|
|
|
34601
34775
|
}
|
|
34602
34776
|
function findFile(cwd, candidates) {
|
|
34603
34777
|
for (const c of candidates) {
|
|
34604
|
-
if (existsSync6(
|
|
34778
|
+
if (existsSync6(join43(cwd, c))) return c;
|
|
34605
34779
|
}
|
|
34606
34780
|
return null;
|
|
34607
34781
|
}
|
|
34608
34782
|
function findSourceRoots(cwd) {
|
|
34609
34783
|
const roots = [];
|
|
34610
34784
|
for (const r of SOURCE_ROOT_CANDIDATES) {
|
|
34611
|
-
const p =
|
|
34785
|
+
const p = join43(cwd, r);
|
|
34612
34786
|
try {
|
|
34613
34787
|
const s = statSync6(p);
|
|
34614
34788
|
if (s.isDirectory()) roots.push(r);
|
|
@@ -34619,9 +34793,9 @@ function findSourceRoots(cwd) {
|
|
|
34619
34793
|
}
|
|
34620
34794
|
function findCiConfig(cwd) {
|
|
34621
34795
|
for (const c of CI_PATHS) {
|
|
34622
|
-
if (existsSync6(
|
|
34796
|
+
if (existsSync6(join43(cwd, c))) {
|
|
34623
34797
|
try {
|
|
34624
|
-
const s = statSync6(
|
|
34798
|
+
const s = statSync6(join43(cwd, c));
|
|
34625
34799
|
return s.isDirectory() ? c : c;
|
|
34626
34800
|
} catch {
|
|
34627
34801
|
}
|
|
@@ -34758,7 +34932,7 @@ function analyzeProject(cwd) {
|
|
|
34758
34932
|
ciConfig: findCiConfig(cwd),
|
|
34759
34933
|
readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
|
|
34760
34934
|
sourceRoots: findSourceRoots(cwd),
|
|
34761
|
-
hasGit: existsSync6(
|
|
34935
|
+
hasGit: existsSync6(join43(cwd, ".git"))
|
|
34762
34936
|
};
|
|
34763
34937
|
}
|
|
34764
34938
|
function bashDiscoveryCommands(profile) {
|
|
@@ -34923,7 +35097,7 @@ Aim for 100\u2013200 lines total. Use markdown tables where they save space.
|
|
|
34923
35097
|
}
|
|
34924
35098
|
function buildInitPrompt(cwd) {
|
|
34925
35099
|
const existingName = ["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
|
|
34926
|
-
(n) => existsSync6(
|
|
35100
|
+
(n) => existsSync6(join43(cwd, n))
|
|
34927
35101
|
);
|
|
34928
35102
|
const isRefresh = existingName !== void 0;
|
|
34929
35103
|
const targetFilename = existingName ?? "AGENTS.md";
|
|
@@ -35007,7 +35181,7 @@ var init_context_generator = __esm({
|
|
|
35007
35181
|
|
|
35008
35182
|
// src/init/run-init.ts
|
|
35009
35183
|
import { existsSync as existsSync7 } from "fs";
|
|
35010
|
-
import { join as
|
|
35184
|
+
import { join as join44 } from "path";
|
|
35011
35185
|
async function runInit(deps) {
|
|
35012
35186
|
const {
|
|
35013
35187
|
cfg,
|
|
@@ -35205,7 +35379,7 @@ async function runInit(deps) {
|
|
|
35205
35379
|
}
|
|
35206
35380
|
}
|
|
35207
35381
|
});
|
|
35208
|
-
if (existsSync7(
|
|
35382
|
+
if (existsSync7(join44(cwd, targetFilename))) {
|
|
35209
35383
|
if (cacheStableRef.current) {
|
|
35210
35384
|
messagesRef.current[1] = {
|
|
35211
35385
|
role: "system",
|
|
@@ -35297,8 +35471,8 @@ var init_run_init = __esm({
|
|
|
35297
35471
|
});
|
|
35298
35472
|
|
|
35299
35473
|
// src/skills/discovery.ts
|
|
35300
|
-
import { readdir as readdir9, stat as stat9, readFile as
|
|
35301
|
-
import { join as
|
|
35474
|
+
import { readdir as readdir9, stat as stat9, readFile as readFile29 } from "fs/promises";
|
|
35475
|
+
import { join as join45, extname as extname2 } from "path";
|
|
35302
35476
|
async function dirExists(path) {
|
|
35303
35477
|
try {
|
|
35304
35478
|
const s = await stat9(path);
|
|
@@ -35322,20 +35496,20 @@ async function scanSkillDir(dirPath, source) {
|
|
|
35322
35496
|
for (const entry of entries) {
|
|
35323
35497
|
if (!entry.isFile()) continue;
|
|
35324
35498
|
if (!SKILL_EXTENSIONS.has(extname2(entry.name))) continue;
|
|
35325
|
-
files.push({ filePath:
|
|
35499
|
+
files.push({ filePath: join45(dirPath, entry.name), source });
|
|
35326
35500
|
}
|
|
35327
35501
|
return files;
|
|
35328
35502
|
}
|
|
35329
35503
|
async function discoverSkills(cwd) {
|
|
35330
|
-
const agentsSkills = await scanSkillDir(
|
|
35331
|
-
const agentsMd = await fileExists(
|
|
35332
|
-
const githubSkills = await scanSkillDir(
|
|
35333
|
-
const kimiflareSkills = await scanSkillDir(
|
|
35504
|
+
const agentsSkills = await scanSkillDir(join45(cwd, ".agents", "skills"), "agents");
|
|
35505
|
+
const agentsMd = await fileExists(join45(cwd, "AGENTS.md")) ? [{ filePath: join45(cwd, "AGENTS.md"), source: "agents-md" }] : [];
|
|
35506
|
+
const githubSkills = await scanSkillDir(join45(cwd, ".github", "skills"), "github");
|
|
35507
|
+
const kimiflareSkills = await scanSkillDir(join45(cwd, ".kimiflare", "skills"), "kimiflare");
|
|
35334
35508
|
const ordered = [...agentsSkills, ...agentsMd, ...githubSkills, ...kimiflareSkills];
|
|
35335
35509
|
return ordered;
|
|
35336
35510
|
}
|
|
35337
35511
|
async function readSkillFile(filePath) {
|
|
35338
|
-
const bytes = await
|
|
35512
|
+
const bytes = await readFile29(filePath);
|
|
35339
35513
|
return { bytes, text: bytes.toString("utf-8") };
|
|
35340
35514
|
}
|
|
35341
35515
|
var SKILL_EXTENSIONS;
|
|
@@ -35541,7 +35715,7 @@ var init_skills = __esm({
|
|
|
35541
35715
|
|
|
35542
35716
|
// src/ui/run-startup-tasks.ts
|
|
35543
35717
|
import { existsSync as existsSync8 } from "fs";
|
|
35544
|
-
import { join as
|
|
35718
|
+
import { join as join46 } from "path";
|
|
35545
35719
|
function runStartupTasks(deps) {
|
|
35546
35720
|
const {
|
|
35547
35721
|
cfg,
|
|
@@ -35563,7 +35737,7 @@ function runStartupTasks(deps) {
|
|
|
35563
35737
|
}
|
|
35564
35738
|
});
|
|
35565
35739
|
if (cfg.memoryEnabled) {
|
|
35566
|
-
const dbPath = cfg.memoryDbPath ??
|
|
35740
|
+
const dbPath = cfg.memoryDbPath ?? join46(process.cwd(), ".kimiflare", "memory.db");
|
|
35567
35741
|
const manager = new MemoryManager({
|
|
35568
35742
|
dbPath,
|
|
35569
35743
|
...auth,
|
|
@@ -35595,7 +35769,7 @@ function runStartupTasks(deps) {
|
|
|
35595
35769
|
});
|
|
35596
35770
|
const cwd = process.cwd();
|
|
35597
35771
|
sessionStartRecallRef.current = manager.recall({ text: cwd, repoPath: cwd, limit: 5 });
|
|
35598
|
-
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync8(
|
|
35772
|
+
if (["AGENTS.md", "KIMI.md", "KIMIFLARE.md", "AGENT.md"].some((name) => existsSync8(join46(cwd, name)))) {
|
|
35599
35773
|
const lastRefresh = manager.getLastKimiMdRefreshTime(cwd);
|
|
35600
35774
|
const driftCount = manager.countHighSignalMemoriesSince(cwd, lastRefresh);
|
|
35601
35775
|
if (driftCount >= 5) {
|
|
@@ -35606,7 +35780,7 @@ function runStartupTasks(deps) {
|
|
|
35606
35780
|
memoryManagerRef.current?.close();
|
|
35607
35781
|
memoryManagerRef.current = null;
|
|
35608
35782
|
}
|
|
35609
|
-
const skillDbPath = cfg.memoryDbPath ??
|
|
35783
|
+
const skillDbPath = cfg.memoryDbPath ?? join46(process.cwd(), ".kimiflare", "memory.db");
|
|
35610
35784
|
const skillDb = getMemoryDb() ?? openMemoryDb(skillDbPath);
|
|
35611
35785
|
initSkillsSchema(skillDb);
|
|
35612
35786
|
void indexSkills({
|
|
@@ -35957,155 +36131,6 @@ var init_run_compact = __esm({
|
|
|
35957
36131
|
}
|
|
35958
36132
|
});
|
|
35959
36133
|
|
|
35960
|
-
// src/ui/bang-command.ts
|
|
35961
|
-
import { spawn as spawn10 } from "child_process";
|
|
35962
|
-
import { mkdtemp as mkdtemp2, readFile as readFile29, rm as rm3 } from "fs/promises";
|
|
35963
|
-
import { tmpdir as tmpdir4, platform as platform7 } from "os";
|
|
35964
|
-
import { join as join46 } from "path";
|
|
35965
|
-
function registerInkInstance(instance) {
|
|
35966
|
-
inkInstance = instance;
|
|
35967
|
-
}
|
|
35968
|
-
function isTerminalHandedOff() {
|
|
35969
|
-
return handedOff;
|
|
35970
|
-
}
|
|
35971
|
-
function parseBangCommand(input) {
|
|
35972
|
-
const t = input.trimStart();
|
|
35973
|
-
if (!t.startsWith("!")) return null;
|
|
35974
|
-
return t.slice(1).trim();
|
|
35975
|
-
}
|
|
35976
|
-
function scriptInvocation(command, shell, logPath, plat = platform7()) {
|
|
35977
|
-
if (plat === "darwin" || plat === "freebsd" || plat === "openbsd" || plat === "netbsd") {
|
|
35978
|
-
return { file: "script", args: ["-q", logPath, shell, "-c", command] };
|
|
35979
|
-
}
|
|
35980
|
-
if (plat === "linux") {
|
|
35981
|
-
return { file: "script", args: ["-q", "-e", "-c", command, logPath], env: { ...process.env, SHELL: shell } };
|
|
35982
|
-
}
|
|
35983
|
-
return null;
|
|
35984
|
-
}
|
|
35985
|
-
function cleanTerminalOutput(raw) {
|
|
35986
|
-
const text = raw.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "").replace(/\x1b[@-Z\\-_]/g, "").replace(/^Script (?:started|done) on .*$/gm, "");
|
|
35987
|
-
const lines = text.split(/\r?\n/).map((line) => {
|
|
35988
|
-
const segs = line.split("\r");
|
|
35989
|
-
let out = segs[segs.length - 1] ?? "";
|
|
35990
|
-
if (!out && segs.length > 1) out = segs.filter(Boolean).pop() ?? "";
|
|
35991
|
-
while (/[^\x08]\x08/.test(out)) out = out.replace(/[^\x08]\x08/, "");
|
|
35992
|
-
return out.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
|
|
35993
|
-
});
|
|
35994
|
-
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
35995
|
-
}
|
|
35996
|
-
function truncateMiddle2(text, max = MAX_CONTEXT_CHARS2) {
|
|
35997
|
-
if (text.length <= max) return text;
|
|
35998
|
-
const half = Math.floor(max / 2);
|
|
35999
|
-
return `${text.slice(0, half)}
|
|
36000
|
-
|
|
36001
|
-
[\u2026 ${text.length - max} chars omitted \u2026]
|
|
36002
|
-
|
|
36003
|
-
${text.slice(-half)}`;
|
|
36004
|
-
}
|
|
36005
|
-
function formatBangContext(r) {
|
|
36006
|
-
const status = r.signal ? `killed by ${r.signal}` : `exit code ${r.exitCode ?? "?"}`;
|
|
36007
|
-
const body = r.output === null ? "(output was shown in the user's terminal but could not be captured)" : r.output ? truncateMiddle2(r.output) : "(no output)";
|
|
36008
|
-
return `[The user ran this shell command themselves with \`!\` in the autopilot prompt. This is context for you, not a new request.]
|
|
36009
|
-
$ ${r.command}
|
|
36010
|
-
(${status})
|
|
36011
|
-
${body}`;
|
|
36012
|
-
}
|
|
36013
|
-
function stopReading(stdin) {
|
|
36014
|
-
stdin.pause();
|
|
36015
|
-
const stream = stdin;
|
|
36016
|
-
try {
|
|
36017
|
-
if (stream._handle?.reading && stream._handle.readStop) {
|
|
36018
|
-
stream._handle.readStop();
|
|
36019
|
-
stream._handle.reading = false;
|
|
36020
|
-
if (stream._readableState) stream._readableState.reading = false;
|
|
36021
|
-
}
|
|
36022
|
-
} catch {
|
|
36023
|
-
}
|
|
36024
|
-
}
|
|
36025
|
-
function swallow() {
|
|
36026
|
-
return ((_chunk, encOrCb, cb) => {
|
|
36027
|
-
const done = typeof encOrCb === "function" ? encOrCb : cb;
|
|
36028
|
-
if (typeof done === "function") done();
|
|
36029
|
-
return true;
|
|
36030
|
-
});
|
|
36031
|
-
}
|
|
36032
|
-
function spawnInherit(inv, cwd) {
|
|
36033
|
-
return new Promise((resolve15, reject) => {
|
|
36034
|
-
const child = spawn10(inv.file, inv.args, { cwd, stdio: "inherit", env: inv.env ?? process.env });
|
|
36035
|
-
child.once("error", reject);
|
|
36036
|
-
child.once("exit", (code, signal) => resolve15({ code, signal }));
|
|
36037
|
-
});
|
|
36038
|
-
}
|
|
36039
|
-
async function runBangCommand(command, cwd) {
|
|
36040
|
-
const isWindows = platform7() === "win32";
|
|
36041
|
-
const shell = isWindows ? process.env.COMSPEC || "cmd.exe" : process.env.SHELL || "/bin/sh";
|
|
36042
|
-
const direct = isWindows ? { file: shell, args: ["/c", command] } : { file: shell, args: ["-c", command] };
|
|
36043
|
-
const stdin = process.stdin;
|
|
36044
|
-
const stdout = process.stdout;
|
|
36045
|
-
const stderr = process.stderr;
|
|
36046
|
-
const origOut = stdout.write;
|
|
36047
|
-
const origErr = stderr.write;
|
|
36048
|
-
const readable = stdin.listeners("readable");
|
|
36049
|
-
const wasRaw = stdin.isTTY ? stdin.isRaw : false;
|
|
36050
|
-
const logDir2 = isWindows ? null : await mkdtemp2(join46(tmpdir4(), "autopilot-bang-"));
|
|
36051
|
-
const logPath = logDir2 ? join46(logDir2, "out.log") : null;
|
|
36052
|
-
const viaScript = logPath ? scriptInvocation(command, shell, logPath) : null;
|
|
36053
|
-
inkInstance?.clear();
|
|
36054
|
-
origOut.call(stdout, `
|
|
36055
|
-
$ ${command}
|
|
36056
|
-
`);
|
|
36057
|
-
stdout.write = swallow();
|
|
36058
|
-
stderr.write = swallow();
|
|
36059
|
-
for (const l of readable) stdin.removeListener("readable", l);
|
|
36060
|
-
if (stdin.isTTY) stdin.setRawMode(false);
|
|
36061
|
-
stopReading(stdin);
|
|
36062
|
-
handedOff = true;
|
|
36063
|
-
let result2;
|
|
36064
|
-
let captured = false;
|
|
36065
|
-
let spawnError = null;
|
|
36066
|
-
try {
|
|
36067
|
-
if (viaScript) {
|
|
36068
|
-
try {
|
|
36069
|
-
result2 = await spawnInherit(viaScript, cwd);
|
|
36070
|
-
captured = true;
|
|
36071
|
-
} catch (e) {
|
|
36072
|
-
logger.warn("bang:script_unavailable", { error: e.message });
|
|
36073
|
-
result2 = await spawnInherit(direct, cwd);
|
|
36074
|
-
}
|
|
36075
|
-
} else {
|
|
36076
|
-
result2 = await spawnInherit(direct, cwd);
|
|
36077
|
-
}
|
|
36078
|
-
} catch (e) {
|
|
36079
|
-
result2 = { code: 127, signal: null };
|
|
36080
|
-
spawnError = e.message;
|
|
36081
|
-
logger.warn("bang:spawn_failed", { error: spawnError });
|
|
36082
|
-
} finally {
|
|
36083
|
-
handedOff = false;
|
|
36084
|
-
stdout.write = origOut;
|
|
36085
|
-
stderr.write = origErr;
|
|
36086
|
-
if (stdin.isTTY) stdin.setRawMode(wasRaw);
|
|
36087
|
-
for (const l of readable) stdin.addListener("readable", l);
|
|
36088
|
-
origOut.call(stdout, "\n");
|
|
36089
|
-
}
|
|
36090
|
-
let output = spawnError ? `failed to start: ${spawnError}` : null;
|
|
36091
|
-
if (captured && logPath) {
|
|
36092
|
-
output = cleanTerminalOutput(await readFile29(logPath, "utf8").catch(() => ""));
|
|
36093
|
-
}
|
|
36094
|
-
if (logDir2) await rm3(logDir2, { recursive: true, force: true }).catch(() => {
|
|
36095
|
-
});
|
|
36096
|
-
return { command, exitCode: result2.code, signal: result2.signal, output };
|
|
36097
|
-
}
|
|
36098
|
-
var inkInstance, handedOff, MAX_CONTEXT_CHARS2;
|
|
36099
|
-
var init_bang_command = __esm({
|
|
36100
|
-
"src/ui/bang-command.ts"() {
|
|
36101
|
-
"use strict";
|
|
36102
|
-
init_logger();
|
|
36103
|
-
inkInstance = null;
|
|
36104
|
-
handedOff = false;
|
|
36105
|
-
MAX_CONTEXT_CHARS2 = 16e3;
|
|
36106
|
-
}
|
|
36107
|
-
});
|
|
36108
|
-
|
|
36109
36134
|
// src/commands/save.ts
|
|
36110
36135
|
import { mkdir as mkdir14, writeFile as writeFile15, unlink as unlink5 } from "fs/promises";
|
|
36111
36136
|
import { dirname as dirname17 } from "path";
|