min-agent 0.2.1 → 0.4.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 (137) hide show
  1. package/README.md +242 -31
  2. package/dist/agent.js +1233 -485
  3. package/dist/assistant-stream.js +11 -7
  4. package/dist/cli/commands/chat.js +10 -0
  5. package/dist/cli/commands/exec.js +32 -0
  6. package/dist/cli/commands/history.js +58 -0
  7. package/dist/cli/commands/index.js +224 -0
  8. package/dist/cli/commands/init.js +18 -0
  9. package/dist/cli/commands/mcp.js +173 -0
  10. package/dist/cli/commands/memory.js +69 -0
  11. package/dist/cli/commands/models.js +21 -0
  12. package/dist/cli/commands/permission.js +12 -0
  13. package/dist/cli/commands/rules.js +33 -0
  14. package/dist/cli/commands/sandbox.js +13 -0
  15. package/dist/cli/commands/serve.js +9 -0
  16. package/dist/cli/commands/setup.js +4 -0
  17. package/dist/cli/commands/shared.js +16 -0
  18. package/dist/cli/commands/skills.js +119 -0
  19. package/dist/cli/commands/update.js +7 -0
  20. package/dist/cli/commands/write-config.js +30 -0
  21. package/dist/cli/errors.js +36 -0
  22. package/dist/cli/exec-prompt.js +26 -0
  23. package/dist/cli/option-helpers.js +53 -0
  24. package/dist/cli/program.js +180 -0
  25. package/dist/cli.js +7 -632
  26. package/dist/clipboard.js +59 -23
  27. package/dist/code-mode.js +35 -17
  28. package/dist/compaction.js +457 -169
  29. package/dist/config.js +298 -38
  30. package/dist/confirm.js +105 -9
  31. package/dist/context-window.js +156 -75
  32. package/dist/doom-loop.js +268 -26
  33. package/dist/fetch-timeout.js +152 -0
  34. package/dist/http-approvals.js +60 -0
  35. package/dist/http.js +119 -0
  36. package/dist/instructions.js +72 -33
  37. package/dist/logger.js +95 -0
  38. package/dist/markdown.js +35 -50
  39. package/dist/mcp.js +847 -102
  40. package/dist/memory.js +128 -45
  41. package/dist/output.js +42 -31
  42. package/dist/paste-handler.js +3 -3
  43. package/dist/permission-cli.js +43 -0
  44. package/dist/plugins.js +76 -11
  45. package/dist/pricing.js +119 -0
  46. package/dist/provider.js +34 -15
  47. package/dist/question-format.js +60 -0
  48. package/dist/sandbox-cli.js +82 -0
  49. package/dist/sandbox.js +403 -0
  50. package/dist/save-throttle.js +45 -0
  51. package/dist/serve/common.js +404 -0
  52. package/dist/serve/routes-chat.js +347 -0
  53. package/dist/serve/routes-mcp.js +212 -0
  54. package/dist/serve/routes-memory.js +66 -0
  55. package/dist/serve/routes-meta.js +205 -0
  56. package/dist/serve/routes-sessions.js +61 -0
  57. package/dist/serve/routes-skills.js +70 -0
  58. package/dist/serve.js +74 -635
  59. package/dist/sessions.js +197 -15
  60. package/dist/skills.js +531 -77
  61. package/dist/synthetic.js +7 -0
  62. package/dist/title-gen.js +9 -2
  63. package/dist/token-display.js +36 -0
  64. package/dist/tool-display.js +178 -0
  65. package/dist/tool-output.js +53 -46
  66. package/dist/tools/apply_patch.js +265 -0
  67. package/dist/tools/atomic-file.js +35 -0
  68. package/dist/tools/backend.js +61 -0
  69. package/dist/tools/bash.js +186 -71
  70. package/dist/tools/code_search.js +13 -6
  71. package/dist/tools/edit.js +26 -9
  72. package/dist/tools/explore.js +144 -16
  73. package/dist/tools/glob.js +7 -3
  74. package/dist/tools/grep.js +153 -14
  75. package/dist/tools/index.js +9 -24
  76. package/dist/tools/question.js +31 -30
  77. package/dist/tools/read.js +77 -15
  78. package/dist/tools/search-searxng.js +223 -0
  79. package/dist/tools/search-serper.js +189 -0
  80. package/dist/tools/task.js +100 -33
  81. package/dist/tools/todo.js +178 -67
  82. package/dist/tools/web_fetch.js +158 -46
  83. package/dist/tools/web_search.js +217 -29
  84. package/dist/tools/write.js +34 -11
  85. package/dist/tui/App.js +89 -6
  86. package/dist/tui/ConfirmBar.js +57 -4
  87. package/dist/tui/InputBar.js +504 -44
  88. package/dist/tui/MessageList.js +674 -20
  89. package/dist/tui/ModelPicker.js +113 -0
  90. package/dist/tui/QuestionBar.js +136 -0
  91. package/dist/tui/SessionPicker.js +79 -0
  92. package/dist/tui/StatusBar.js +14 -12
  93. package/dist/tui/agent-runner.js +223 -0
  94. package/dist/tui/caret-pos.js +177 -0
  95. package/dist/tui/caret.js +69 -0
  96. package/dist/tui/click-count.js +13 -0
  97. package/dist/tui/diff-view.js +61 -0
  98. package/dist/tui/drag-state.js +49 -0
  99. package/dist/tui/hydrate.js +129 -0
  100. package/dist/tui/index.js +189 -31
  101. package/dist/tui/input-history.js +125 -0
  102. package/dist/tui/layout.js +88 -0
  103. package/dist/tui/mouse.js +46 -0
  104. package/dist/tui/prompt-queue.js +24 -0
  105. package/dist/tui/selection.js +226 -0
  106. package/dist/tui/session-switch.js +28 -0
  107. package/dist/tui/slash-commands.js +106 -0
  108. package/dist/tui/slash-handler.js +545 -0
  109. package/dist/tui/text-width.js +113 -0
  110. package/dist/tui/theme.js +12 -0
  111. package/dist/tui/token-info.js +7 -0
  112. package/dist/tui/tool-children.js +19 -0
  113. package/dist/tui/undo-stack.js +14 -0
  114. package/dist/tui/use-sgr-mouse.js +29 -0
  115. package/dist/tui-chat.js +346 -330
  116. package/dist/updater.js +116 -0
  117. package/dist/xml-search.js +194 -0
  118. package/docs/API.md +410 -32
  119. package/docs/superpowers/plans/2026-08-16-batch1-tui-improvements.md +1510 -0
  120. package/docs/superpowers/plans/2026-08-16-batch2-cli-tools-api.md +2105 -0
  121. package/docs/superpowers/plans/2026-08-16-batch3-config-engineering.md +1595 -0
  122. package/docs/superpowers/plans/2026-08-16-input-caret.md +782 -0
  123. package/docs/superpowers/plans/2026-08-20-tui-completeness.md +873 -0
  124. package/docs/superpowers/plans/2026-08-20-unified-tui-default.md +631 -0
  125. package/docs/superpowers/specs/2026-08-16-batch1-tui-improvements-design.md +183 -0
  126. package/docs/superpowers/specs/2026-08-16-batch2-cli-tools-api-design.md +220 -0
  127. package/docs/superpowers/specs/2026-08-16-batch3-config-engineering-design.md +196 -0
  128. package/docs/superpowers/specs/2026-08-16-input-caret-design.md +63 -0
  129. package/docs/superpowers/specs/2026-08-17-mouse-selection-design.md +116 -0
  130. package/docs/superpowers/specs/2026-08-20-config-http-alignment-design.md +47 -0
  131. package/docs/superpowers/specs/2026-08-20-mcp-plugins-alignment-design.md +37 -0
  132. package/docs/superpowers/specs/2026-08-20-sandbox-permissions-design.md +68 -0
  133. package/docs/superpowers/specs/2026-08-20-tui-completeness-design.md +273 -0
  134. package/docs/superpowers/specs/2026-08-20-unified-tui-default-design.md +165 -0
  135. package/package.json +12 -8
  136. package/skills/self-config/SKILL.md +90 -0
  137. package/skills/self-config/reference.md +149 -0
package/dist/clipboard.js CHANGED
@@ -1,6 +1,18 @@
1
1
  import { execSync } from "child_process";
2
+ import { readFileSync, unlinkSync } from "fs";
2
3
  import path from "path";
3
4
  import os from "os";
5
+ function readTmpImage(tmpFile) {
6
+ const data = readFileSync(tmpFile);
7
+ try {
8
+ unlinkSync(tmpFile);
9
+ }
10
+ catch { }
11
+ return data.length > 0 ? data : null;
12
+ }
13
+ function tmpImagePath() {
14
+ return path.join(os.tmpdir(), `min-agent-paste-${Date.now()}.png`);
15
+ }
4
16
  export function getClipboardImage() {
5
17
  switch (process.platform) {
6
18
  case "darwin":
@@ -13,18 +25,52 @@ export function getClipboardImage() {
13
25
  return null;
14
26
  }
15
27
  }
28
+ /** Write plain text to the system clipboard. False on failure (silent). */
29
+ export function writeClipboard(text) {
30
+ switch (process.platform) {
31
+ case "darwin":
32
+ try {
33
+ execSync("pbcopy", { input: text, stdio: "pipe" });
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ case "linux": {
40
+ try {
41
+ execSync("xclip -selection clipboard", { input: text, stdio: "pipe" });
42
+ return true;
43
+ }
44
+ catch { }
45
+ try {
46
+ execSync("xsel --clipboard --input", { input: text, stdio: "pipe" });
47
+ return true;
48
+ }
49
+ catch { }
50
+ return false;
51
+ }
52
+ case "win32":
53
+ try {
54
+ execSync('powershell -NoProfile -Command "Set-Clipboard -Value ([Console]::In.ReadToEnd())"', {
55
+ input: text,
56
+ stdio: "pipe",
57
+ });
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ default:
64
+ return false;
65
+ }
66
+ }
16
67
  function getClipboardImageMac() {
17
- const tmpFile = path.join(os.tmpdir(), `min-agent-paste-${Date.now()}.png`);
68
+ const tmpFile = tmpImagePath();
18
69
  try {
19
70
  // Try pngpaste first (brew install pngpaste)
20
71
  execSync(`pngpaste "${tmpFile}" 2>/dev/null`, { stdio: "pipe" });
21
- const { readFileSync } = require("fs");
22
- const data = readFileSync(tmpFile);
23
- try {
24
- require("fs").unlinkSync(tmpFile);
25
- }
26
- catch { }
27
- if (data.length > 0)
72
+ const data = readTmpImage(tmpFile);
73
+ if (data)
28
74
  return { data, mimeType: "image/png" };
29
75
  }
30
76
  catch { }
@@ -44,13 +90,8 @@ function getClipboardImageMac() {
44
90
  `;
45
91
  const result = execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, { encoding: "utf-8" }).trim();
46
92
  if (result === "ok") {
47
- const { readFileSync, unlinkSync } = require("fs");
48
- const data = readFileSync(tmpFile);
49
- try {
50
- unlinkSync(tmpFile);
51
- }
52
- catch { }
53
- if (data.length > 0)
93
+ const data = readTmpImage(tmpFile);
94
+ if (data)
54
95
  return { data, mimeType: "image/png" };
55
96
  }
56
97
  }
@@ -81,7 +122,7 @@ function getClipboardImageLinux() {
81
122
  return null;
82
123
  }
83
124
  function getClipboardImageWindows() {
84
- const tmpFile = path.join(os.tmpdir(), `min-agent-paste-${Date.now()}.png`);
125
+ const tmpFile = tmpImagePath();
85
126
  try {
86
127
  const ps = `
87
128
  Add-Type -AssemblyName System.Windows.Forms
@@ -91,13 +132,8 @@ function getClipboardImageWindows() {
91
132
  `;
92
133
  const result = execSync(`powershell -NoProfile -Command "${ps}"`, { encoding: "utf-8" }).trim();
93
134
  if (result === "ok") {
94
- const { readFileSync, unlinkSync } = require("fs");
95
- const data = readFileSync(tmpFile);
96
- try {
97
- unlinkSync(tmpFile);
98
- }
99
- catch { }
100
- if (data.length > 0)
135
+ const data = readTmpImage(tmpFile);
136
+ if (data)
101
137
  return { data, mimeType: "image/png" };
102
138
  }
103
139
  }
package/dist/code-mode.js CHANGED
@@ -7,19 +7,19 @@ export function scanProject() {
7
7
  let branch;
8
8
  if (isGitRepo) {
9
9
  try {
10
- branch = execSync("git branch --show-current", { encoding: "utf-8", cwd }).trim();
10
+ branch = execSync("git branch --show-current", { encoding: "utf-8", cwd, timeout: 5000 }).trim();
11
11
  }
12
12
  catch { }
13
13
  }
14
14
  const languages = [];
15
15
  const configFiles = [];
16
16
  const entryFiles = [];
17
- // Detect by config files
17
+ // Detect by config files (lockfiles first so they win over package.json)
18
18
  const checks = [
19
- { file: "package.json", lang: "TypeScript/JavaScript", pm: "npm" },
20
19
  { file: "bun.lock", lang: "TypeScript/JavaScript", pm: "bun" },
21
20
  { file: "yarn.lock", lang: "TypeScript/JavaScript", pm: "yarn" },
22
21
  { file: "pnpm-lock.yaml", lang: "TypeScript/JavaScript", pm: "pnpm" },
22
+ { file: "package.json", lang: "TypeScript/JavaScript", pm: "npm" },
23
23
  { file: "tsconfig.json", lang: "TypeScript" },
24
24
  { file: "Cargo.toml", lang: "Rust", pm: "cargo" },
25
25
  { file: "go.mod", lang: "Go" },
@@ -48,35 +48,47 @@ export function scanProject() {
48
48
  try {
49
49
  const pkg = JSON.parse(readFileSync(path.join(cwd, "package.json"), "utf-8"));
50
50
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
51
- if (allDeps["next"])
51
+ if (allDeps.next)
52
52
  framework = "Next.js";
53
- else if (allDeps["nuxt"])
53
+ else if (allDeps.nuxt)
54
54
  framework = "Nuxt";
55
55
  else if (allDeps["@angular/core"])
56
56
  framework = "Angular";
57
- else if (allDeps["vue"])
57
+ else if (allDeps.vue)
58
58
  framework = "Vue";
59
- else if (allDeps["react"])
59
+ else if (allDeps.react)
60
60
  framework = "React";
61
- else if (allDeps["svelte"])
61
+ else if (allDeps.svelte)
62
62
  framework = "Svelte";
63
- else if (allDeps["express"])
63
+ else if (allDeps.express)
64
64
  framework = "Express";
65
- else if (allDeps["fastify"])
65
+ else if (allDeps.fastify)
66
66
  framework = "Fastify";
67
- else if (allDeps["hono"])
67
+ else if (allDeps.hono)
68
68
  framework = "Hono";
69
- else if (allDeps["effect"])
69
+ else if (allDeps.effect)
70
70
  framework = "Effect";
71
71
  }
72
72
  catch { }
73
73
  }
74
74
  // Find entry files
75
75
  const entryPatterns = [
76
- "src/index.ts", "src/index.js", "src/main.ts", "src/main.js",
77
- "src/app.ts", "src/app.js", "index.ts", "index.js",
78
- "main.ts", "main.js", "app.ts", "app.js",
79
- "src/lib.rs", "main.go", "main.py", "app.py",
76
+ "src/index.ts",
77
+ "src/index.js",
78
+ "src/main.ts",
79
+ "src/main.js",
80
+ "src/app.ts",
81
+ "src/app.js",
82
+ "index.ts",
83
+ "index.js",
84
+ "main.ts",
85
+ "main.js",
86
+ "app.ts",
87
+ "app.js",
88
+ "src/lib.rs",
89
+ "main.go",
90
+ "main.py",
91
+ "app.py",
80
92
  ];
81
93
  for (const p of entryPatterns) {
82
94
  if (existsSync(path.join(cwd, p)))
@@ -134,9 +146,15 @@ export function buildCodeSystemPrompt(project, instructions) {
134
146
  "- Prefer editing existing files over creating new ones.",
135
147
  "- After making changes, run lint/typecheck/build if available.",
136
148
  "- NEVER commit unless explicitly asked.",
149
+ "- When the user asks to configure, install, or manage MCP servers, skills, rules, memory, permission, sandbox, providers, plugins, or other min-agent settings, follow the built-in `self-config` skill (already loaded). If its instructions are missing, load it with the skill tool before making changes.",
137
150
  "",
138
151
  "# Workflow",
139
- "- Use search tools (grep, glob) to understand the codebase before making changes.",
152
+ "- For greetings, thanks, or general chat with no concrete task, reply directly do not call any tools. The Project Structure below already covers the basics; do not re-explore the codebase just to answer a greeting.",
153
+ "- Use search tools (grep, glob) to understand the codebase before making changes, only once the user gives a concrete task.",
154
+ "- Use the search_web tool for live web search. Never emit XML tags such as <web_search>.",
155
+ "- After a few targeted web searches and fetching the best sources, stop researching and produce the requested output.",
156
+ "- Do not keep searching for completeness, extra models, or slightly better numbers. Mark uncertain dates or scores as estimates and move on.",
157
+ "- If the user asked for a file or other artifact, write it as soon as the required fields can be filled. Then stop.",
140
158
  "- Use the edit tool for precise changes instead of rewriting entire files.",
141
159
  "- When fixing bugs: read the relevant code, understand the issue, fix it, verify.",
142
160
  "- When adding features: explore existing patterns first, then implement consistently.",