min-agent 0.5.1 → 0.6.0

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.
Files changed (169) hide show
  1. package/README.md +18 -18
  2. package/dist/cli.js +538 -12
  3. package/docs/API.md +6 -6
  4. package/package.json +6 -6
  5. package/skills/self-config/SKILL.md +4 -2
  6. package/skills/self-config/reference.md +4 -1
  7. package/dist/agent.js +0 -1388
  8. package/dist/assistant-stream.js +0 -131
  9. package/dist/cli/commands/chat.js +0 -13
  10. package/dist/cli/commands/ctx.js +0 -7
  11. package/dist/cli/commands/exec.js +0 -35
  12. package/dist/cli/commands/history.js +0 -58
  13. package/dist/cli/commands/index.js +0 -249
  14. package/dist/cli/commands/init.js +0 -18
  15. package/dist/cli/commands/mcp.js +0 -173
  16. package/dist/cli/commands/memory.js +0 -87
  17. package/dist/cli/commands/models.js +0 -21
  18. package/dist/cli/commands/permission.js +0 -12
  19. package/dist/cli/commands/rules.js +0 -33
  20. package/dist/cli/commands/sandbox.js +0 -13
  21. package/dist/cli/commands/serve.js +0 -9
  22. package/dist/cli/commands/setup.js +0 -56
  23. package/dist/cli/commands/shared.js +0 -25
  24. package/dist/cli/commands/skills.js +0 -119
  25. package/dist/cli/commands/think.js +0 -12
  26. package/dist/cli/commands/update.js +0 -7
  27. package/dist/cli/commands/write-config.js +0 -52
  28. package/dist/cli/errors.js +0 -36
  29. package/dist/cli/exec-prompt.js +0 -26
  30. package/dist/cli/option-helpers.js +0 -65
  31. package/dist/cli/program.js +0 -223
  32. package/dist/cli/setup/detect.js +0 -17
  33. package/dist/cli/setup/flags.js +0 -12
  34. package/dist/cli/setup/flow.js +0 -108
  35. package/dist/cli/setup/provider-form.js +0 -102
  36. package/dist/cli/setup/ui.js +0 -534
  37. package/dist/clipboard.js +0 -142
  38. package/dist/code-mode.js +0 -184
  39. package/dist/compaction.js +0 -644
  40. package/dist/config.js +0 -363
  41. package/dist/confirm.js +0 -172
  42. package/dist/context-window.js +0 -256
  43. package/dist/ctx-cli.js +0 -30
  44. package/dist/ctx.js +0 -80
  45. package/dist/doom-loop.js +0 -278
  46. package/dist/fetch-timeout.js +0 -152
  47. package/dist/http-approvals.js +0 -60
  48. package/dist/http.js +0 -119
  49. package/dist/instructions.js +0 -196
  50. package/dist/logger.js +0 -95
  51. package/dist/markdown.js +0 -259
  52. package/dist/mcp.js +0 -1036
  53. package/dist/memory-cli.js +0 -33
  54. package/dist/memory.js +0 -295
  55. package/dist/model-catalog.js +0 -285
  56. package/dist/ollama-model.js +0 -234
  57. package/dist/ollama-openai-bridge.js +0 -383
  58. package/dist/output.js +0 -76
  59. package/dist/paste-handler.js +0 -41
  60. package/dist/permission-cli.js +0 -40
  61. package/dist/plugins.js +0 -131
  62. package/dist/pricing.js +0 -119
  63. package/dist/provider.js +0 -63
  64. package/dist/question-format.js +0 -60
  65. package/dist/reasoning-stream.js +0 -158
  66. package/dist/sandbox-cli.js +0 -79
  67. package/dist/sandbox.js +0 -403
  68. package/dist/save-throttle.js +0 -45
  69. package/dist/scope.js +0 -23
  70. package/dist/serve/common.js +0 -425
  71. package/dist/serve/routes-chat.js +0 -367
  72. package/dist/serve/routes-mcp.js +0 -212
  73. package/dist/serve/routes-memory.js +0 -95
  74. package/dist/serve/routes-meta.js +0 -268
  75. package/dist/serve/routes-sessions.js +0 -61
  76. package/dist/serve/routes-skills.js +0 -70
  77. package/dist/serve.js +0 -138
  78. package/dist/sessions.js +0 -265
  79. package/dist/skills.js +0 -599
  80. package/dist/structured-output.js +0 -29
  81. package/dist/synthetic.js +0 -7
  82. package/dist/think-cli.js +0 -36
  83. package/dist/thinking-wire.js +0 -239
  84. package/dist/thinking.js +0 -166
  85. package/dist/title-gen.js +0 -55
  86. package/dist/token-display.js +0 -39
  87. package/dist/tool-display.js +0 -178
  88. package/dist/tool-output.js +0 -126
  89. package/dist/tools/apply_patch.js +0 -265
  90. package/dist/tools/atomic-file.js +0 -35
  91. package/dist/tools/backend.js +0 -61
  92. package/dist/tools/bash.js +0 -231
  93. package/dist/tools/code_search.js +0 -98
  94. package/dist/tools/edit.js +0 -68
  95. package/dist/tools/explore.js +0 -232
  96. package/dist/tools/glob.js +0 -40
  97. package/dist/tools/grep.js +0 -174
  98. package/dist/tools/index.js +0 -34
  99. package/dist/tools/question.js +0 -54
  100. package/dist/tools/read.js +0 -109
  101. package/dist/tools/search-searxng.js +0 -223
  102. package/dist/tools/search-serper.js +0 -189
  103. package/dist/tools/task.js +0 -165
  104. package/dist/tools/todo.js +0 -213
  105. package/dist/tools/web_fetch.js +0 -195
  106. package/dist/tools/web_search.js +0 -228
  107. package/dist/tools/write.js +0 -55
  108. package/dist/tui/App.js +0 -138
  109. package/dist/tui/ConfirmBar.js +0 -66
  110. package/dist/tui/CtxPicker.js +0 -68
  111. package/dist/tui/InputBar.js +0 -618
  112. package/dist/tui/MessageList.js +0 -718
  113. package/dist/tui/ModelPicker.js +0 -113
  114. package/dist/tui/QuestionBar.js +0 -136
  115. package/dist/tui/SessionPicker.js +0 -79
  116. package/dist/tui/Spinner.js +0 -6
  117. package/dist/tui/StatusBar.js +0 -22
  118. package/dist/tui/ThinkPicker.js +0 -75
  119. package/dist/tui/agent-runner.js +0 -223
  120. package/dist/tui/bracketed-paste.js +0 -37
  121. package/dist/tui/caret-pos.js +0 -179
  122. package/dist/tui/caret.js +0 -69
  123. package/dist/tui/click-count.js +0 -13
  124. package/dist/tui/diff-view.js +0 -61
  125. package/dist/tui/drag-state.js +0 -49
  126. package/dist/tui/hydrate.js +0 -129
  127. package/dist/tui/index.js +0 -264
  128. package/dist/tui/input-history.js +0 -125
  129. package/dist/tui/layout.js +0 -105
  130. package/dist/tui/mouse.js +0 -46
  131. package/dist/tui/overlay-input.js +0 -12
  132. package/dist/tui/paste-draft.js +0 -173
  133. package/dist/tui/prompt-queue.js +0 -24
  134. package/dist/tui/selection.js +0 -232
  135. package/dist/tui/session-switch.js +0 -28
  136. package/dist/tui/slash-commands.js +0 -129
  137. package/dist/tui/slash-handler.js +0 -615
  138. package/dist/tui/text-width.js +0 -113
  139. package/dist/tui/theme.js +0 -12
  140. package/dist/tui/token-info.js +0 -7
  141. package/dist/tui/tool-children.js +0 -19
  142. package/dist/tui/types.js +0 -1
  143. package/dist/tui/undo-stack.js +0 -14
  144. package/dist/tui/use-sgr-mouse.js +0 -29
  145. package/dist/tui-chat.js +0 -478
  146. package/dist/updater.js +0 -116
  147. package/dist/xml-search.js +0 -194
  148. package/docs/superpowers/plans/2026-08-16-batch1-tui-improvements.md +0 -1510
  149. package/docs/superpowers/plans/2026-08-16-batch2-cli-tools-api.md +0 -2105
  150. package/docs/superpowers/plans/2026-08-16-batch3-config-engineering.md +0 -1595
  151. package/docs/superpowers/plans/2026-08-16-input-caret.md +0 -782
  152. package/docs/superpowers/plans/2026-08-20-tui-completeness.md +0 -873
  153. package/docs/superpowers/plans/2026-08-20-unified-tui-default.md +0 -631
  154. package/docs/superpowers/plans/2026-08-23-cli-setup.md +0 -501
  155. package/docs/superpowers/plans/2026-08-23-input-paste-attachments.md +0 -475
  156. package/docs/superpowers/plans/2026-08-23-thinking-wire-profile.md +0 -450
  157. package/docs/superpowers/specs/2026-08-16-batch1-tui-improvements-design.md +0 -183
  158. package/docs/superpowers/specs/2026-08-16-batch2-cli-tools-api-design.md +0 -220
  159. package/docs/superpowers/specs/2026-08-16-batch3-config-engineering-design.md +0 -196
  160. package/docs/superpowers/specs/2026-08-16-input-caret-design.md +0 -63
  161. package/docs/superpowers/specs/2026-08-17-mouse-selection-design.md +0 -116
  162. package/docs/superpowers/specs/2026-08-20-config-http-alignment-design.md +0 -47
  163. package/docs/superpowers/specs/2026-08-20-mcp-plugins-alignment-design.md +0 -37
  164. package/docs/superpowers/specs/2026-08-20-sandbox-permissions-design.md +0 -68
  165. package/docs/superpowers/specs/2026-08-20-tui-completeness-design.md +0 -273
  166. package/docs/superpowers/specs/2026-08-20-unified-tui-default-design.md +0 -165
  167. package/docs/superpowers/specs/2026-08-23-cli-setup-design.md +0 -282
  168. package/docs/superpowers/specs/2026-08-23-input-paste-attachments-design.md +0 -174
  169. package/docs/superpowers/specs/2026-08-23-thinking-wire-profile-design.md +0 -140
package/dist/updater.js DELETED
@@ -1,116 +0,0 @@
1
- import { readFileSync } from "fs";
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- import { spawnSync } from "child_process";
5
- export const UPDATE_PACKAGE = "min-agent";
6
- export const NPM_LATEST_URL = `https://registry.npmjs.org/${UPDATE_PACKAGE}/latest`;
7
- export const UPDATE_NPM_BIN = "npm";
8
- export const UPDATE_NPM_ARGS = ["install", "-g", UPDATE_PACKAGE];
9
- const VERSION_RE = /^\d+\.\d+\.\d+/;
10
- const FETCH_TIMEOUT_MS = 10_000;
11
- export function updateInstallCommand() {
12
- return [UPDATE_NPM_BIN, ...UPDATE_NPM_ARGS].join(" ");
13
- }
14
- export function localVersion() {
15
- try {
16
- const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../package.json");
17
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
18
- return typeof pkg.version === "string" && pkg.version.length > 0 ? pkg.version : "0.0.0";
19
- }
20
- catch {
21
- return "0.0.0";
22
- }
23
- }
24
- export function compareVersions(a, b) {
25
- const pa = a.split("-")[0].split(".").map(Number);
26
- const pb = b.split("-")[0].split(".").map(Number);
27
- for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
28
- const va = pa[i] ?? 0;
29
- const vb = pb[i] ?? 0;
30
- const na = Number.isFinite(va) ? va : 0;
31
- const nb = Number.isFinite(vb) ? vb : 0;
32
- if (na !== nb)
33
- return na - nb;
34
- }
35
- return 0;
36
- }
37
- function parseVersion(value) {
38
- if (typeof value !== "string" || !VERSION_RE.test(value))
39
- return null;
40
- return value;
41
- }
42
- export async function fetchLatestVersion(fetchFn = fetch) {
43
- let response;
44
- try {
45
- response = await fetchFn(NPM_LATEST_URL, {
46
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
47
- headers: { Accept: "application/json" },
48
- });
49
- }
50
- catch {
51
- return null;
52
- }
53
- if (!response.ok)
54
- return null;
55
- let data;
56
- try {
57
- data = await response.json();
58
- }
59
- catch {
60
- return null;
61
- }
62
- if (!data || typeof data !== "object" || !("version" in data))
63
- return null;
64
- return parseVersion(data.version);
65
- }
66
- export async function checkForUpdate(opts) {
67
- const current = opts?.currentVersion ?? localVersion();
68
- const latest = await fetchLatestVersion(opts?.fetchFn);
69
- return {
70
- current,
71
- latest,
72
- updateAvailable: latest !== null && compareVersions(current, latest) < 0,
73
- };
74
- }
75
- export function installLatest() {
76
- const result = spawnSync(UPDATE_NPM_BIN, [...UPDATE_NPM_ARGS], {
77
- stdio: "inherit",
78
- shell: process.platform === "win32",
79
- env: process.env,
80
- });
81
- if (result.error) {
82
- const code = result.error.code;
83
- return { ok: false, missing: code === "ENOENT" };
84
- }
85
- return { ok: result.status === 0 };
86
- }
87
- export async function runUpdate(io = {}) {
88
- const log = io.log ?? ((msg) => console.log(msg));
89
- const error = io.error ?? ((msg) => console.error(msg));
90
- const current = io.currentVersion?.() ?? localVersion();
91
- const cmd = updateInstallCommand();
92
- log(`当前版本: ${current}`);
93
- const latest = io.fetchLatest ? await io.fetchLatest() : await fetchLatestVersion();
94
- if (!latest) {
95
- error(`无法检查新版本(网络不可用)。请稍后重试,或手动执行: ${cmd}`);
96
- return { status: "check-failed", current, latest: null };
97
- }
98
- if (compareVersions(current, latest) >= 0) {
99
- log(`已是最新版本 (${latest})`);
100
- return { status: "up-to-date", current, latest };
101
- }
102
- log(`发现新版本: ${latest}`);
103
- log(`正在执行 ${cmd} ...`);
104
- const installed = (io.install ?? installLatest)();
105
- if (!installed.ok) {
106
- if (installed.missing) {
107
- error(`未找到 npm。请先安装 Node.js,然后执行: ${cmd}`);
108
- }
109
- else {
110
- error(`自动升级失败。请手动执行: ${cmd}`);
111
- }
112
- return { status: "install-failed", current, latest };
113
- }
114
- log(`✓ 已升级到 ${latest}`);
115
- return { status: "updated", current, latest };
116
- }
@@ -1,194 +0,0 @@
1
- /**
2
- * Some OpenAI-compatible gateways (and a few models) dump built-in web search
3
- * into the assistant text as <web_search>…</web_search> instead of a tool call,
4
- * then stop. This module splits those blocks out of the stream so the agent can
5
- * turn them into search_web tool results and keep going.
6
- */
7
- const OPEN_NAME = "<web_search";
8
- const CLOSE_NAME = "</web_search";
9
- const PARTIAL_TAG_HOLD = 80;
10
- const UNCLOSED_MAX = 64 * 1024;
11
- function collapse(s) {
12
- return s.replace(/\s+/g, " ").trim();
13
- }
14
- function isNameBoundary(ch) {
15
- return ch === undefined || ch === ">" || ch === "/" || ch === " " || ch === "\t" || ch === "\n" || ch === "\r";
16
- }
17
- function findOpen(buf) {
18
- const l = buf.toLowerCase();
19
- let from = 0;
20
- while (from < l.length) {
21
- const index = l.indexOf(OPEN_NAME, from);
22
- if (index < 0)
23
- return null;
24
- if (!isNameBoundary(l[index + OPEN_NAME.length])) {
25
- from = index + 1;
26
- continue;
27
- }
28
- const gt = buf.indexOf(">", index);
29
- if (gt < 0)
30
- return null;
31
- return { index, openLen: gt - index + 1, raw: buf.slice(index, gt + 1) };
32
- }
33
- return null;
34
- }
35
- function findClose(buf, from) {
36
- const l = buf.toLowerCase();
37
- let start = from;
38
- while (start < l.length) {
39
- const index = l.indexOf(CLOSE_NAME, start);
40
- if (index < 0)
41
- return null;
42
- if (!isNameBoundary(l[index + CLOSE_NAME.length])) {
43
- start = index + 1;
44
- continue;
45
- }
46
- const gt = buf.indexOf(">", index);
47
- if (gt < 0)
48
- return null;
49
- return { innerEnd: index, tagEnd: gt + 1 };
50
- }
51
- return null;
52
- }
53
- function queryFromOpenTag(raw) {
54
- const m = /\bquery\s*=\s*"([^"]*)"/i.exec(raw) ?? /\bquery\s*=\s*'([^']*)'/i.exec(raw);
55
- return m?.[1]?.trim() ?? "";
56
- }
57
- const RESULTS_HEADER = /^Search results for\s+"([^"]*)"\s*:/im;
58
- export function classifyXmlSearchBody(inner, attrQuery = "") {
59
- const trimmed = inner.trim();
60
- if (!trimmed) {
61
- const query = attrQuery.trim();
62
- return query ? { kind: "invoke", query } : { kind: "results", query: "", body: "" };
63
- }
64
- const header = RESULTS_HEADER.exec(trimmed);
65
- if (header) {
66
- return { kind: "results", query: header[1].trim() || attrQuery, body: trimmed };
67
- }
68
- if (/^\d+\.\s+Title\s*:/m.test(trimmed) && /\bURL\s*:/m.test(trimmed)) {
69
- return { kind: "results", query: attrQuery, body: trimmed };
70
- }
71
- const query = collapse(trimmed) || attrQuery;
72
- if (query && query.length <= 500 && !/\bURL\s*:\s*https?:\/\//i.test(trimmed)) {
73
- return { kind: "invoke", query };
74
- }
75
- return { kind: "results", query: attrQuery || query, body: trimmed };
76
- }
77
- function lastPotentialPartialOpen(buf) {
78
- const start = Math.max(0, buf.length - PARTIAL_TAG_HOLD);
79
- const tail = buf.slice(start);
80
- const lt = tail.lastIndexOf("<");
81
- if (lt < 0)
82
- return -1;
83
- const globalLt = start + lt;
84
- const cand = buf.slice(globalLt).toLowerCase();
85
- if (cand.length > 72)
86
- return -1;
87
- if (OPEN_NAME.startsWith(cand) || CLOSE_NAME.startsWith(cand))
88
- return globalLt;
89
- if (cand.startsWith(OPEN_NAME) && !cand.includes(">"))
90
- return globalLt;
91
- if (cand.startsWith(CLOSE_NAME) && !cand.includes(">"))
92
- return globalLt;
93
- return -1;
94
- }
95
- export class XmlSearchSplitter {
96
- buf = "";
97
- feed(chunk) {
98
- this.buf += chunk;
99
- return this.drain(false);
100
- }
101
- flush() {
102
- return this.drain(true);
103
- }
104
- drain(isFinal) {
105
- const out = [];
106
- let hadBlock = false;
107
- const pushDisplay = (text) => {
108
- if (!text)
109
- return;
110
- const last = out[out.length - 1];
111
- if (last?.type === "display")
112
- last.text += text;
113
- else
114
- out.push({ type: "display", text });
115
- };
116
- while (this.buf.length > 0) {
117
- const open = findOpen(this.buf);
118
- if (!open) {
119
- if (isFinal) {
120
- pushDisplay(this.buf);
121
- this.buf = "";
122
- }
123
- else {
124
- const holdFrom = lastPotentialPartialOpen(this.buf);
125
- if (holdFrom >= 0) {
126
- pushDisplay(this.buf.slice(0, holdFrom));
127
- this.buf = this.buf.slice(holdFrom);
128
- }
129
- else {
130
- pushDisplay(this.buf);
131
- this.buf = "";
132
- }
133
- }
134
- break;
135
- }
136
- if (open.index > 0) {
137
- let pre = this.buf.slice(0, open.index);
138
- pre = pre.replace(/\n+$/, "");
139
- if (pre)
140
- pushDisplay(pre);
141
- this.buf = this.buf.slice(open.index);
142
- }
143
- const close = findClose(this.buf, open.openLen);
144
- if (!close) {
145
- const innerLen = this.buf.length - open.openLen;
146
- if (isFinal || innerLen > UNCLOSED_MAX) {
147
- const inner = this.buf.slice(open.openLen);
148
- out.push({ type: "search", block: classifyXmlSearchBody(inner, queryFromOpenTag(open.raw)) });
149
- hadBlock = true;
150
- this.buf = "";
151
- }
152
- break;
153
- }
154
- const inner = this.buf.slice(open.openLen, close.innerEnd);
155
- out.push({ type: "search", block: classifyXmlSearchBody(inner, queryFromOpenTag(open.raw)) });
156
- hadBlock = true;
157
- this.buf = this.buf.slice(close.tagEnd).replace(/^\n+/, "");
158
- }
159
- if (hadBlock) {
160
- const first = out[0];
161
- if (first?.type === "display")
162
- first.text = first.text.replace(/^\n+/, "");
163
- }
164
- return out.filter((sl) => sl.type === "search" || sl.text.length > 0);
165
- }
166
- }
167
- export function extractXmlSearch(text) {
168
- const splitter = new XmlSearchSplitter();
169
- const slices = [...splitter.feed(text), ...splitter.flush()];
170
- let display = "";
171
- const blocks = [];
172
- for (const sl of slices) {
173
- if (sl.type === "display")
174
- display += sl.text;
175
- else
176
- blocks.push(sl.block);
177
- }
178
- return { display, blocks, slices };
179
- }
180
- /** Drop the XML wrappers but keep the inner query/results, for sub-agent returns. */
181
- export function unwrapXmlSearchTags(text) {
182
- const { slices } = extractXmlSearch(text);
183
- if (slices.every((sl) => sl.type === "display"))
184
- return text;
185
- return slices
186
- .map((sl) => {
187
- if (sl.type === "display")
188
- return sl.text;
189
- return sl.block.kind === "results" ? sl.block.body : sl.block.query;
190
- })
191
- .join("")
192
- .replace(/^\n+/, "")
193
- .replace(/\n+$/, "");
194
- }