minimal-agent 0.1.3 → 0.1.4
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/main.js +133 -59
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
import { createRequire } from "module";
|
|
6
6
|
|
|
7
|
+
// src/bootstrap/workingDir.ts
|
|
8
|
+
import { resolve } from "path";
|
|
9
|
+
var _workingDir = null;
|
|
10
|
+
function initWorkingDir() {
|
|
11
|
+
if (_workingDir !== null) return _workingDir;
|
|
12
|
+
const override = process.env.MINIMAL_AGENT_CWD;
|
|
13
|
+
_workingDir = resolve(override ?? process.cwd());
|
|
14
|
+
return _workingDir;
|
|
15
|
+
}
|
|
16
|
+
function getWorkingDir() {
|
|
17
|
+
return _workingDir ?? initWorkingDir();
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
// src/config/configFile.ts
|
|
8
21
|
import { chmod, mkdir, readFile, writeFile } from "fs/promises";
|
|
9
22
|
import { homedir } from "os";
|
|
@@ -111,16 +124,51 @@ async function loadProviderLayered() {
|
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
// src/context/persistContext.ts
|
|
114
|
-
import { mkdir as
|
|
127
|
+
import { mkdir as mkdir3, readFile as readFile2, unlink, writeFile as writeFile2 } from "fs/promises";
|
|
128
|
+
import { dirname as dirname3 } from "path";
|
|
129
|
+
|
|
130
|
+
// src/context/sessionPath.ts
|
|
131
|
+
import { createHash } from "crypto";
|
|
132
|
+
import { mkdir as mkdir2, rename, stat } from "fs/promises";
|
|
115
133
|
import { homedir as homedir2 } from "os";
|
|
116
|
-
import { dirname as dirname2, join as join2 } from "path";
|
|
134
|
+
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
135
|
+
function sessionFileFor(cwd) {
|
|
136
|
+
const normalized = resolve2(cwd).replace(/\\/g, "/").toLowerCase();
|
|
137
|
+
const sanitized = normalized.replace(/:/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
138
|
+
const hash = createHash("sha1").update(normalized).digest("hex").slice(0, 6);
|
|
139
|
+
return join2(
|
|
140
|
+
homedir2(),
|
|
141
|
+
".minimal-agent",
|
|
142
|
+
"sessions",
|
|
143
|
+
`${sanitized}-${hash}.json`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
async function migrateLegacyContext(cwd) {
|
|
147
|
+
const legacy = join2(homedir2(), ".minimal-agent", "last-context.json");
|
|
148
|
+
try {
|
|
149
|
+
await stat(legacy);
|
|
150
|
+
} catch {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const target = sessionFileFor(cwd);
|
|
154
|
+
try {
|
|
155
|
+
await mkdir2(dirname2(target), { recursive: true });
|
|
156
|
+
await rename(legacy, target);
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/context/persistContext.ts
|
|
117
162
|
function getContextPath() {
|
|
118
|
-
|
|
163
|
+
if (process.env.MINIMAL_AGENT_CONTEXT_FILE) {
|
|
164
|
+
return process.env.MINIMAL_AGENT_CONTEXT_FILE;
|
|
165
|
+
}
|
|
166
|
+
return sessionFileFor(getWorkingDir());
|
|
119
167
|
}
|
|
120
|
-
async function loadContext() {
|
|
121
|
-
const
|
|
168
|
+
async function loadContext(file) {
|
|
169
|
+
const target = file ?? getContextPath();
|
|
122
170
|
try {
|
|
123
|
-
const raw = await readFile2(
|
|
171
|
+
const raw = await readFile2(target, "utf8");
|
|
124
172
|
const data = JSON.parse(raw);
|
|
125
173
|
if (!Array.isArray(data.messages)) return null;
|
|
126
174
|
return data.messages;
|
|
@@ -128,19 +176,19 @@ async function loadContext() {
|
|
|
128
176
|
return null;
|
|
129
177
|
}
|
|
130
178
|
}
|
|
131
|
-
async function saveContext(messages) {
|
|
132
|
-
const
|
|
179
|
+
async function saveContext(messages, file) {
|
|
180
|
+
const target = file ?? getContextPath();
|
|
133
181
|
try {
|
|
134
|
-
await
|
|
182
|
+
await mkdir3(dirname3(target), { recursive: true });
|
|
135
183
|
const data = { updatedAt: Date.now(), messages };
|
|
136
|
-
await writeFile2(
|
|
184
|
+
await writeFile2(target, JSON.stringify(data), "utf8");
|
|
137
185
|
} catch {
|
|
138
186
|
}
|
|
139
187
|
}
|
|
140
|
-
async function clearContext() {
|
|
141
|
-
const
|
|
188
|
+
async function clearContext(file) {
|
|
189
|
+
const target = file ?? getContextPath();
|
|
142
190
|
try {
|
|
143
|
-
await unlink(
|
|
191
|
+
await unlink(target);
|
|
144
192
|
} catch {
|
|
145
193
|
}
|
|
146
194
|
}
|
|
@@ -177,20 +225,20 @@ import { join as join4 } from "path";
|
|
|
177
225
|
|
|
178
226
|
// src/utils/packageRoot.ts
|
|
179
227
|
import { existsSync } from "fs";
|
|
180
|
-
import { dirname as
|
|
228
|
+
import { dirname as dirname4, resolve as resolve3 } from "path";
|
|
181
229
|
import { fileURLToPath } from "url";
|
|
182
230
|
var cache = /* @__PURE__ */ new Map();
|
|
183
231
|
var MAX_DEPTH = 8;
|
|
184
232
|
function findPackageRoot(metaUrl) {
|
|
185
233
|
const cached2 = cache.get(metaUrl);
|
|
186
234
|
if (cached2 !== void 0) return cached2;
|
|
187
|
-
let dir =
|
|
235
|
+
let dir = dirname4(fileURLToPath(metaUrl));
|
|
188
236
|
for (let i = 0; i < MAX_DEPTH; i++) {
|
|
189
|
-
if (existsSync(
|
|
237
|
+
if (existsSync(resolve3(dir, "package.json"))) {
|
|
190
238
|
cache.set(metaUrl, dir);
|
|
191
239
|
return dir;
|
|
192
240
|
}
|
|
193
|
-
const parent =
|
|
241
|
+
const parent = dirname4(dir);
|
|
194
242
|
if (parent === dir) break;
|
|
195
243
|
dir = parent;
|
|
196
244
|
}
|
|
@@ -249,10 +297,14 @@ function formatSkillHint(skills) {
|
|
|
249
297
|
const lines = [];
|
|
250
298
|
lines.push("# \u53EF\u7528\u6280\u80FD\uFF08/\u547D\u4EE4\uFF09");
|
|
251
299
|
lines.push("");
|
|
300
|
+
lines.push(`> Skills \u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF1A\`${SKILLS_DIR}\``);
|
|
301
|
+
lines.push("");
|
|
252
302
|
lines.push(
|
|
253
303
|
"\u4EE5\u4E0B\u662F\u5F53\u524D\u53EF\u7528\u7684\u6280\u80FD\u3002**\u5F53\u7528\u6237\u610F\u56FE\u5339\u914D\u67D0\u4E2A\u6280\u80FD\u7684\u89E6\u53D1\u65F6\u673A\u65F6\uFF0C\u4F60\u5E94\u8BE5\u4E3B\u52A8\u4F7F\u7528\u5B83**\u3002"
|
|
254
304
|
);
|
|
255
|
-
lines.push(
|
|
305
|
+
lines.push(
|
|
306
|
+
`\u5728\u4F7F\u7528\u524D\uFF0C\u5148\u7528 Read \u5DE5\u5177\u8BFB\u53D6 \`${SKILLS_DIR}/{name}/SKILL.md\` \u4E86\u89E3\u5B8C\u6574\u6D41\u7A0B\u3002`
|
|
307
|
+
);
|
|
256
308
|
lines.push("");
|
|
257
309
|
for (const skill of skills) {
|
|
258
310
|
const type = skill.type ?? "prompt\uFF08\u5C55\u5F00\u4E3A\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF0C\u6307\u5BFC\u6A21\u578B\u6267\u884C\u590D\u6742\u4EFB\u52A1\uFF09";
|
|
@@ -268,7 +320,7 @@ function formatSkillHint(skills) {
|
|
|
268
320
|
lines.push("");
|
|
269
321
|
lines.push("```");
|
|
270
322
|
lines.push("1. \u5728 T \u9636\u6BB5\u5224\u65AD\u7528\u6237\u610F\u56FE\u662F\u5426\u5339\u914D\u67D0\u4E2A\u6280\u80FD\u7684\u89E6\u53D1\u65F6\u673A");
|
|
271
|
-
lines.push(`2. \u5339\u914D \u2192 \u5728 A \u9636\u6BB5\u7528 Read \u5DE5\u5177\u8BFB\u53D6
|
|
323
|
+
lines.push(`2. \u5339\u914D \u2192 \u5728 A \u9636\u6BB5\u7528 Read \u5DE5\u5177\u8BFB\u53D6 ${SKILLS_DIR}/{name}/SKILL.md`);
|
|
272
324
|
lines.push("3. \u6309\u7167 SKILL.md \u7684 Quick Reference \u548C\u6D41\u7A0B\u6267\u884C");
|
|
273
325
|
lines.push("4. \u6280\u80FD\u811A\u672C\uFF08scripts/\uFF09\u4E0E SKILL.md \u4F4D\u4E8E\u540C\u4E00\u76EE\u5F55\u4E0B\uFF0C\u7528\u7EDD\u5BF9\u8DEF\u5F84\u6267\u884C");
|
|
274
326
|
lines.push("5. \u5982\u679C\u6280\u80FD\u7C7B\u578B\u662F prompt\uFF0C\u5C06\u5176\u5185\u5BB9\u4F5C\u4E3A\u989D\u5916\u4E0A\u4E0B\u6587\u6307\u5BFC\u540E\u7EED\u64CD\u4F5C");
|
|
@@ -563,7 +615,7 @@ async function call(input, signal) {
|
|
|
563
615
|
await new Promise((resolveP, rejectP) => {
|
|
564
616
|
const child = spawn(command, {
|
|
565
617
|
shell: true,
|
|
566
|
-
cwd:
|
|
618
|
+
cwd: getWorkingDir(),
|
|
567
619
|
signal: ac.signal,
|
|
568
620
|
env: process.env,
|
|
569
621
|
windowsHide: true
|
|
@@ -641,9 +693,9 @@ var bashTool = {
|
|
|
641
693
|
};
|
|
642
694
|
|
|
643
695
|
// src/tools/edit/edit.ts
|
|
644
|
-
import { readFile as readFile5, writeFile as writeFile3, mkdir as
|
|
696
|
+
import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir4 } from "fs/promises";
|
|
645
697
|
import { existsSync as existsSync2 } from "fs";
|
|
646
|
-
import { dirname as
|
|
698
|
+
import { dirname as dirname5, resolve as resolve4 } from "path";
|
|
647
699
|
import { z as z2 } from "zod";
|
|
648
700
|
var MAX_EDIT_FILE_SIZE_BYTES = 1024 * 1024 * 1024;
|
|
649
701
|
var inputSchema2 = z2.object({
|
|
@@ -676,7 +728,7 @@ function validatePath(filePath) {
|
|
|
676
728
|
return { ok: true };
|
|
677
729
|
}
|
|
678
730
|
async function call2(input) {
|
|
679
|
-
const filePath =
|
|
731
|
+
const filePath = resolve4(input.file_path);
|
|
680
732
|
const { old_string, new_string } = input;
|
|
681
733
|
const replaceAll = input.replace_all ?? false;
|
|
682
734
|
const pathCheck = validatePath(filePath);
|
|
@@ -686,7 +738,7 @@ async function call2(input) {
|
|
|
686
738
|
}
|
|
687
739
|
if (old_string === "" && !existsSync2(filePath)) {
|
|
688
740
|
try {
|
|
689
|
-
await
|
|
741
|
+
await mkdir4(dirname5(filePath), { recursive: true });
|
|
690
742
|
await writeFile3(filePath, new_string, "utf8");
|
|
691
743
|
return {
|
|
692
744
|
ok: true,
|
|
@@ -841,8 +893,8 @@ var editTool = {
|
|
|
841
893
|
};
|
|
842
894
|
|
|
843
895
|
// src/tools/glob/glob.ts
|
|
844
|
-
import { stat } from "fs/promises";
|
|
845
|
-
import { isAbsolute, resolve as
|
|
896
|
+
import { stat as stat2 } from "fs/promises";
|
|
897
|
+
import { isAbsolute, resolve as resolve5 } from "path";
|
|
846
898
|
import fg from "fast-glob";
|
|
847
899
|
import { z as z3 } from "zod";
|
|
848
900
|
var inputSchema3 = z3.object({
|
|
@@ -856,7 +908,7 @@ var description3 = `- Fast file pattern matching tool that works with any codeba
|
|
|
856
908
|
- Use this tool when you need to find files by name patterns
|
|
857
909
|
- When you need to do an open ended search that may require multiple rounds, prefer the Grep tool for content search`;
|
|
858
910
|
async function call3(input) {
|
|
859
|
-
const cwd = input.path ?
|
|
911
|
+
const cwd = input.path ? resolve5(input.path) : getWorkingDir();
|
|
860
912
|
const pattern = input.pattern.replace(/\\/g, "/");
|
|
861
913
|
let matches;
|
|
862
914
|
try {
|
|
@@ -877,9 +929,9 @@ async function call3(input) {
|
|
|
877
929
|
}
|
|
878
930
|
const withMtime = await Promise.all(
|
|
879
931
|
matches.map(async (rel) => {
|
|
880
|
-
const abs = isAbsolute(rel) ? rel :
|
|
932
|
+
const abs = isAbsolute(rel) ? rel : resolve5(cwd, rel);
|
|
881
933
|
try {
|
|
882
|
-
const st = await
|
|
934
|
+
const st = await stat2(abs);
|
|
883
935
|
return { path: rel, mtime: st.mtimeMs };
|
|
884
936
|
} catch {
|
|
885
937
|
return { path: rel, mtime: 0 };
|
|
@@ -913,13 +965,13 @@ var globTool = {
|
|
|
913
965
|
|
|
914
966
|
// src/tools/grep/grep.ts
|
|
915
967
|
import { spawn as spawn3 } from "child_process";
|
|
916
|
-
import { resolve as
|
|
968
|
+
import { resolve as resolve7 } from "path";
|
|
917
969
|
import { z as z4 } from "zod";
|
|
918
970
|
|
|
919
971
|
// src/tools/grep/rgPath.ts
|
|
920
972
|
import { spawn as spawn2 } from "child_process";
|
|
921
973
|
import { chmodSync, existsSync as existsSync3 } from "fs";
|
|
922
|
-
import { resolve as
|
|
974
|
+
import { resolve as resolve6 } from "path";
|
|
923
975
|
var cached;
|
|
924
976
|
async function resolveRgPath() {
|
|
925
977
|
if (cached !== void 0) return cached;
|
|
@@ -946,7 +998,7 @@ async function detect() {
|
|
|
946
998
|
function vendoredRgPath() {
|
|
947
999
|
try {
|
|
948
1000
|
const projectRoot = findPackageRoot(import.meta.url);
|
|
949
|
-
return
|
|
1001
|
+
return resolve6(projectRoot, "vendor", "ripgrep", subdir(), exeName());
|
|
950
1002
|
} catch {
|
|
951
1003
|
return null;
|
|
952
1004
|
}
|
|
@@ -1005,26 +1057,26 @@ function claudeCodeCandidates() {
|
|
|
1005
1057
|
const npmRoots = [];
|
|
1006
1058
|
if (platform === "win32") {
|
|
1007
1059
|
if (process.env.APPDATA) {
|
|
1008
|
-
npmRoots.push(
|
|
1060
|
+
npmRoots.push(resolve6(process.env.APPDATA, "npm", "node_modules"));
|
|
1009
1061
|
}
|
|
1010
1062
|
if (process.env.USERPROFILE) {
|
|
1011
1063
|
npmRoots.push(
|
|
1012
|
-
|
|
1064
|
+
resolve6(process.env.USERPROFILE, "AppData", "Roaming", "npm", "node_modules")
|
|
1013
1065
|
);
|
|
1014
1066
|
}
|
|
1015
1067
|
} else {
|
|
1016
1068
|
const home = process.env.HOME ?? "";
|
|
1017
1069
|
if (home) {
|
|
1018
|
-
npmRoots.push(
|
|
1019
|
-
npmRoots.push(
|
|
1020
|
-
npmRoots.push(
|
|
1070
|
+
npmRoots.push(resolve6(home, ".npm-global", "lib", "node_modules"));
|
|
1071
|
+
npmRoots.push(resolve6(home, ".npm", "lib", "node_modules"));
|
|
1072
|
+
npmRoots.push(resolve6(home, "node_modules"));
|
|
1021
1073
|
}
|
|
1022
1074
|
npmRoots.push("/usr/local/lib/node_modules");
|
|
1023
1075
|
npmRoots.push("/usr/lib/node_modules");
|
|
1024
1076
|
npmRoots.push("/opt/homebrew/lib/node_modules");
|
|
1025
1077
|
}
|
|
1026
1078
|
return npmRoots.map(
|
|
1027
|
-
(root) =>
|
|
1079
|
+
(root) => resolve6(root, "@anthropic-ai", "claude-code", "vendor", "ripgrep", subdir2, exe)
|
|
1028
1080
|
);
|
|
1029
1081
|
}
|
|
1030
1082
|
|
|
@@ -1070,7 +1122,7 @@ async function call4(input, signal) {
|
|
|
1070
1122
|
args.push("--max-columns-preview");
|
|
1071
1123
|
args.push("--sort", "modified");
|
|
1072
1124
|
args.push("-e", input.pattern);
|
|
1073
|
-
args.push(input.path ?
|
|
1125
|
+
args.push(input.path ? resolve7(input.path) : ".");
|
|
1074
1126
|
const rgPath = await resolveRgPath();
|
|
1075
1127
|
if (!rgPath) {
|
|
1076
1128
|
return {
|
|
@@ -1084,7 +1136,7 @@ async function call4(input, signal) {
|
|
|
1084
1136
|
try {
|
|
1085
1137
|
await new Promise((resolveP, rejectP) => {
|
|
1086
1138
|
const child = spawn3(rgPath, args, {
|
|
1087
|
-
cwd:
|
|
1139
|
+
cwd: getWorkingDir(),
|
|
1088
1140
|
signal,
|
|
1089
1141
|
windowsHide: true
|
|
1090
1142
|
});
|
|
@@ -1138,8 +1190,8 @@ var grepTool = {
|
|
|
1138
1190
|
};
|
|
1139
1191
|
|
|
1140
1192
|
// src/tools/read/read.ts
|
|
1141
|
-
import { readFile as readFile6, stat as
|
|
1142
|
-
import { resolve as
|
|
1193
|
+
import { readFile as readFile6, stat as stat3 } from "fs/promises";
|
|
1194
|
+
import { resolve as resolve8 } from "path";
|
|
1143
1195
|
import { z as z5 } from "zod";
|
|
1144
1196
|
var inputSchema5 = z5.object({
|
|
1145
1197
|
file_path: z5.string().min(1, "\u5FC5\u987B\u63D0\u4F9B file_path").describe("\u8981\u8BFB\u53D6\u7684\u6587\u4EF6\u8DEF\u5F84\uFF0C\u7EDD\u5BF9\u8DEF\u5F84\u4F18\u5148"),
|
|
@@ -1158,12 +1210,12 @@ Usage:
|
|
|
1158
1210
|
- This tool can only read text files, not directories. To read a directory, use the Glob tool.
|
|
1159
1211
|
- If you read a file that exists but has empty contents you will receive a warning in place of file contents.`;
|
|
1160
1212
|
async function call5(input) {
|
|
1161
|
-
const filePath =
|
|
1213
|
+
const filePath = resolve8(input.file_path);
|
|
1162
1214
|
const offset = input.offset ?? 1;
|
|
1163
1215
|
const limit = input.limit ?? MAX_LINES_TO_READ;
|
|
1164
1216
|
let st;
|
|
1165
1217
|
try {
|
|
1166
|
-
st = await
|
|
1218
|
+
st = await stat3(filePath);
|
|
1167
1219
|
} catch (e) {
|
|
1168
1220
|
return {
|
|
1169
1221
|
ok: false,
|
|
@@ -2028,8 +2080,8 @@ var webSearchTool = {
|
|
|
2028
2080
|
|
|
2029
2081
|
// src/tools/write/write.ts
|
|
2030
2082
|
import { existsSync as existsSync4 } from "fs";
|
|
2031
|
-
import { mkdir as
|
|
2032
|
-
import { dirname as
|
|
2083
|
+
import { mkdir as mkdir5, stat as stat4, writeFile as writeFile4 } from "fs/promises";
|
|
2084
|
+
import { dirname as dirname6, resolve as resolve9 } from "path";
|
|
2033
2085
|
import { z as z9 } from "zod";
|
|
2034
2086
|
var MAX_WRITE_SIZE_BYTES = 1024 * 1024 * 1024;
|
|
2035
2087
|
var inputSchema9 = z9.object({
|
|
@@ -2054,7 +2106,7 @@ function validatePath2(filePath) {
|
|
|
2054
2106
|
return { ok: true };
|
|
2055
2107
|
}
|
|
2056
2108
|
async function call9(input) {
|
|
2057
|
-
const filePath =
|
|
2109
|
+
const filePath = resolve9(input.file_path);
|
|
2058
2110
|
const pathCheck = validatePath2(filePath);
|
|
2059
2111
|
if (!pathCheck.ok) return pathCheck;
|
|
2060
2112
|
const contentSize = Buffer.byteLength(input.content, "utf8");
|
|
@@ -2065,12 +2117,12 @@ async function call9(input) {
|
|
|
2065
2117
|
};
|
|
2066
2118
|
}
|
|
2067
2119
|
try {
|
|
2068
|
-
await
|
|
2120
|
+
await mkdir5(dirname6(filePath), { recursive: true });
|
|
2069
2121
|
let originalSize = 0;
|
|
2070
2122
|
const fileExisted = existsSync4(filePath);
|
|
2071
2123
|
if (fileExisted) {
|
|
2072
2124
|
try {
|
|
2073
|
-
const st = await
|
|
2125
|
+
const st = await stat4(filePath);
|
|
2074
2126
|
originalSize = st.size;
|
|
2075
2127
|
} catch {
|
|
2076
2128
|
}
|
|
@@ -2910,6 +2962,8 @@ function MessageRow({ message }) {
|
|
|
2910
2962
|
|
|
2911
2963
|
// src/ui/StatusLine.tsx
|
|
2912
2964
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
2965
|
+
import { homedir as homedir4 } from "os";
|
|
2966
|
+
import { sep } from "path";
|
|
2913
2967
|
|
|
2914
2968
|
// src/llm/client.ts
|
|
2915
2969
|
async function* chat(args) {
|
|
@@ -3301,7 +3355,11 @@ function StatusLine({ provider, history }) {
|
|
|
3301
3355
|
const usage = useTokenUsage(history, provider);
|
|
3302
3356
|
const ratio = usage.tokens / usage.threshold;
|
|
3303
3357
|
const color = ratio >= 1 ? "red" : ratio >= 0.7 ? "yellow" : "green";
|
|
3358
|
+
const cwdDisplay = shortenPath(getWorkingDir());
|
|
3304
3359
|
return /* @__PURE__ */ jsxs4(Box4, { children: [
|
|
3360
|
+
/* @__PURE__ */ jsx4(Text4, { color: "cyan", children: "cwd " }),
|
|
3361
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: cwdDisplay }),
|
|
3362
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: " \xB7 " }),
|
|
3305
3363
|
/* @__PURE__ */ jsxs4(Text4, { color: "gray", children: [
|
|
3306
3364
|
provider.name,
|
|
3307
3365
|
"/",
|
|
@@ -3323,6 +3381,19 @@ function fmt(n) {
|
|
|
3323
3381
|
if (n < 1e6) return `${(n / 1e3).toFixed(1)}K`;
|
|
3324
3382
|
return `${(n / 1e6).toFixed(2)}M`;
|
|
3325
3383
|
}
|
|
3384
|
+
function shortenPath(abs) {
|
|
3385
|
+
const home = homedir4();
|
|
3386
|
+
let p = abs;
|
|
3387
|
+
if (home && (p === home || p.startsWith(home + sep))) {
|
|
3388
|
+
p = "~" + p.slice(home.length);
|
|
3389
|
+
}
|
|
3390
|
+
if (p.length <= 40) return p;
|
|
3391
|
+
const parts = p.split(/[\\/]/).filter(Boolean);
|
|
3392
|
+
if (parts.length <= 3) return p;
|
|
3393
|
+
const head = p.startsWith("~") ? "~" : parts[0];
|
|
3394
|
+
const tail = parts.slice(-2).join(sep);
|
|
3395
|
+
return `${head}${sep}\u2026${sep}${tail}`;
|
|
3396
|
+
}
|
|
3326
3397
|
|
|
3327
3398
|
// src/ui/ToolStatus.tsx
|
|
3328
3399
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
@@ -3474,7 +3545,7 @@ async function reactiveCompactIfApplicable(messages, provider, error) {
|
|
|
3474
3545
|
}
|
|
3475
3546
|
|
|
3476
3547
|
// src/context/microCompactLite.ts
|
|
3477
|
-
import { createHash } from "crypto";
|
|
3548
|
+
import { createHash as createHash2 } from "crypto";
|
|
3478
3549
|
var MAX_REPEAT_COUNT = 3;
|
|
3479
3550
|
var MAX_RESULT_SIZE = 4e3;
|
|
3480
3551
|
var HEAD_KEEP_CHARS = 2e3;
|
|
@@ -3526,7 +3597,7 @@ function expireOldEntries() {
|
|
|
3526
3597
|
return expired;
|
|
3527
3598
|
}
|
|
3528
3599
|
function sha1(str) {
|
|
3529
|
-
return
|
|
3600
|
+
return createHash2("sha1").update(str).digest("hex");
|
|
3530
3601
|
}
|
|
3531
3602
|
function truncateContent(content) {
|
|
3532
3603
|
const omitted = content.length - HEAD_KEEP_CHARS - TAIL_KEEP_CHARS;
|
|
@@ -3758,7 +3829,7 @@ function useChat(args) {
|
|
|
3758
3829
|
}, []);
|
|
3759
3830
|
const clearHistory = useCallback5(async () => {
|
|
3760
3831
|
if (isLoading) return;
|
|
3761
|
-
const newSystemPrompt = await buildFullSystemPrompt(
|
|
3832
|
+
const newSystemPrompt = await buildFullSystemPrompt(getWorkingDir(), ALL_TOOLS);
|
|
3762
3833
|
historyRef.current.length = 0;
|
|
3763
3834
|
historyRef.current.push({ role: "system", content: newSystemPrompt });
|
|
3764
3835
|
resetReactiveCompactState();
|
|
@@ -3935,7 +4006,7 @@ function Root({ initialProvider }) {
|
|
|
3935
4006
|
return /* @__PURE__ */ jsx7(App, { provider: phase.provider, initialHistory: phase.initialHistory });
|
|
3936
4007
|
}
|
|
3937
4008
|
async function buildInitialHistory() {
|
|
3938
|
-
const content = await buildFullSystemPrompt(
|
|
4009
|
+
const content = await buildFullSystemPrompt(getWorkingDir(), ALL_TOOLS);
|
|
3939
4010
|
const fresh = { role: "system", content };
|
|
3940
4011
|
const persisted = await loadContext();
|
|
3941
4012
|
if (!persisted || persisted.length === 0) return [fresh];
|
|
@@ -4057,13 +4128,13 @@ function handleEvent2(event, output, verbose) {
|
|
|
4057
4128
|
}
|
|
4058
4129
|
}
|
|
4059
4130
|
function readFromStdin() {
|
|
4060
|
-
return new Promise((
|
|
4131
|
+
return new Promise((resolve10) => {
|
|
4061
4132
|
let data = "";
|
|
4062
4133
|
let settled = false;
|
|
4063
4134
|
const timer = setTimeout(() => {
|
|
4064
4135
|
if (!settled) {
|
|
4065
4136
|
settled = true;
|
|
4066
|
-
|
|
4137
|
+
resolve10("");
|
|
4067
4138
|
}
|
|
4068
4139
|
}, STDIN_TIMEOUT_MS);
|
|
4069
4140
|
process.stdin.setEncoding("utf8");
|
|
@@ -4074,7 +4145,7 @@ function readFromStdin() {
|
|
|
4074
4145
|
if (!settled) {
|
|
4075
4146
|
clearTimeout(timer);
|
|
4076
4147
|
settled = true;
|
|
4077
|
-
|
|
4148
|
+
resolve10(data.trim());
|
|
4078
4149
|
}
|
|
4079
4150
|
}
|
|
4080
4151
|
process.stdin.on("data", onData);
|
|
@@ -4087,6 +4158,8 @@ import { jsx as jsx8 } from "react/jsx-runtime";
|
|
|
4087
4158
|
var require2 = createRequire(import.meta.url);
|
|
4088
4159
|
var pkg = require2("../package.json");
|
|
4089
4160
|
async function main() {
|
|
4161
|
+
initWorkingDir();
|
|
4162
|
+
await migrateLegacyContext(getWorkingDir());
|
|
4090
4163
|
const args = process.argv.slice(2);
|
|
4091
4164
|
if (args.includes("-h") || args.includes("--help")) {
|
|
4092
4165
|
printHelp();
|
|
@@ -4122,7 +4195,7 @@ ${e.message}
|
|
|
4122
4195
|
await waitUntilExit();
|
|
4123
4196
|
}
|
|
4124
4197
|
async function buildInitialHistory2() {
|
|
4125
|
-
const content = await buildFullSystemPrompt(
|
|
4198
|
+
const content = await buildFullSystemPrompt(getWorkingDir(), ALL_TOOLS);
|
|
4126
4199
|
const fresh = { role: "system", content };
|
|
4127
4200
|
const persisted = await loadContext();
|
|
4128
4201
|
if (!persisted || persisted.length === 0) return [fresh];
|
|
@@ -4143,8 +4216,9 @@ minimal-agent - \u8F7B\u91CF\u7EA7 AI \u7F16\u7A0B\u52A9\u624B
|
|
|
4143
4216
|
-h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F
|
|
4144
4217
|
|
|
4145
4218
|
\u4F1A\u8BDD\u8BB0\u5FC6:
|
|
4146
|
-
\u81EA\u52A8\u52A0\u8F7D / \u4FDD\u5B58
|
|
4147
|
-
|
|
4219
|
+
\u6309\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u9694\u79BB\uFF0C\u81EA\u52A8\u52A0\u8F7D / \u4FDD\u5B58\u5230
|
|
4220
|
+
~/.minimal-agent/sessions/<\u76EE\u5F55\u54C8\u5E0C>.json
|
|
4221
|
+
TUI \u4E0E -p \u5171\u4EAB\u540C\u4E00\u76EE\u5F55\u7684\u4E0A\u4E0B\u6587\uFF1BTUI \u4E2D\u8F93\u5165 /new \u4EC5\u6E05\u5F53\u524D\u76EE\u5F55\u7684\u4F1A\u8BDD
|
|
4148
4222
|
|
|
4149
4223
|
\u793A\u4F8B:
|
|
4150
4224
|
minimal-agent -p "\u5E2E\u6211\u5199\u4E00\u4E2A hello world"
|
package/package.json
CHANGED