min-agent 0.5.0 → 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.
- package/README.md +32 -18
- package/dist/cli.js +538 -12
- package/docs/API.md +25 -8
- package/package.json +6 -6
- package/skills/self-config/SKILL.md +7 -3
- package/skills/self-config/reference.md +8 -4
- package/dist/agent.js +0 -1342
- package/dist/assistant-stream.js +0 -131
- package/dist/cli/commands/chat.js +0 -13
- package/dist/cli/commands/exec.js +0 -35
- package/dist/cli/commands/history.js +0 -58
- package/dist/cli/commands/index.js +0 -241
- package/dist/cli/commands/init.js +0 -18
- package/dist/cli/commands/mcp.js +0 -173
- package/dist/cli/commands/memory.js +0 -87
- package/dist/cli/commands/models.js +0 -21
- package/dist/cli/commands/permission.js +0 -12
- package/dist/cli/commands/rules.js +0 -33
- package/dist/cli/commands/sandbox.js +0 -13
- package/dist/cli/commands/serve.js +0 -9
- package/dist/cli/commands/setup.js +0 -4
- package/dist/cli/commands/shared.js +0 -16
- package/dist/cli/commands/skills.js +0 -119
- package/dist/cli/commands/think.js +0 -12
- package/dist/cli/commands/update.js +0 -7
- package/dist/cli/commands/write-config.js +0 -52
- package/dist/cli/errors.js +0 -36
- package/dist/cli/exec-prompt.js +0 -26
- package/dist/cli/option-helpers.js +0 -65
- package/dist/cli/program.js +0 -217
- package/dist/clipboard.js +0 -142
- package/dist/code-mode.js +0 -184
- package/dist/compaction.js +0 -644
- package/dist/config.js +0 -470
- package/dist/confirm.js +0 -172
- package/dist/context-window.js +0 -246
- package/dist/doom-loop.js +0 -278
- package/dist/fetch-timeout.js +0 -152
- package/dist/http-approvals.js +0 -60
- package/dist/http.js +0 -119
- package/dist/instructions.js +0 -196
- package/dist/logger.js +0 -95
- package/dist/markdown.js +0 -259
- package/dist/mcp.js +0 -1036
- package/dist/memory-cli.js +0 -33
- package/dist/memory.js +0 -295
- package/dist/model-catalog.js +0 -285
- package/dist/output.js +0 -76
- package/dist/paste-handler.js +0 -41
- package/dist/permission-cli.js +0 -40
- package/dist/plugins.js +0 -131
- package/dist/pricing.js +0 -119
- package/dist/provider.js +0 -63
- package/dist/question-format.js +0 -60
- package/dist/reasoning-stream.js +0 -158
- package/dist/sandbox-cli.js +0 -79
- package/dist/sandbox.js +0 -403
- package/dist/save-throttle.js +0 -45
- package/dist/scope.js +0 -23
- package/dist/serve/common.js +0 -425
- package/dist/serve/routes-chat.js +0 -367
- package/dist/serve/routes-mcp.js +0 -212
- package/dist/serve/routes-memory.js +0 -95
- package/dist/serve/routes-meta.js +0 -233
- package/dist/serve/routes-sessions.js +0 -61
- package/dist/serve/routes-skills.js +0 -70
- package/dist/serve.js +0 -138
- package/dist/sessions.js +0 -265
- package/dist/skills.js +0 -599
- package/dist/structured-output.js +0 -29
- package/dist/synthetic.js +0 -7
- package/dist/think-cli.js +0 -36
- package/dist/thinking-wire.js +0 -228
- package/dist/thinking.js +0 -142
- package/dist/title-gen.js +0 -55
- package/dist/token-display.js +0 -39
- package/dist/tool-display.js +0 -178
- package/dist/tool-output.js +0 -126
- package/dist/tools/apply_patch.js +0 -265
- package/dist/tools/atomic-file.js +0 -35
- package/dist/tools/backend.js +0 -61
- package/dist/tools/bash.js +0 -231
- package/dist/tools/code_search.js +0 -98
- package/dist/tools/edit.js +0 -68
- package/dist/tools/explore.js +0 -232
- package/dist/tools/glob.js +0 -40
- package/dist/tools/grep.js +0 -174
- package/dist/tools/index.js +0 -34
- package/dist/tools/question.js +0 -54
- package/dist/tools/read.js +0 -109
- package/dist/tools/search-searxng.js +0 -223
- package/dist/tools/search-serper.js +0 -189
- package/dist/tools/task.js +0 -165
- package/dist/tools/todo.js +0 -213
- package/dist/tools/web_fetch.js +0 -195
- package/dist/tools/web_search.js +0 -228
- package/dist/tools/write.js +0 -55
- package/dist/tui/App.js +0 -126
- package/dist/tui/ConfirmBar.js +0 -66
- package/dist/tui/InputBar.js +0 -616
- package/dist/tui/MessageList.js +0 -718
- package/dist/tui/ModelPicker.js +0 -113
- package/dist/tui/QuestionBar.js +0 -136
- package/dist/tui/SessionPicker.js +0 -79
- package/dist/tui/Spinner.js +0 -6
- package/dist/tui/StatusBar.js +0 -22
- package/dist/tui/ThinkPicker.js +0 -77
- package/dist/tui/agent-runner.js +0 -223
- package/dist/tui/bracketed-paste.js +0 -37
- package/dist/tui/caret-pos.js +0 -179
- package/dist/tui/caret.js +0 -69
- package/dist/tui/click-count.js +0 -13
- package/dist/tui/diff-view.js +0 -61
- package/dist/tui/drag-state.js +0 -49
- package/dist/tui/hydrate.js +0 -129
- package/dist/tui/index.js +0 -258
- package/dist/tui/input-history.js +0 -125
- package/dist/tui/layout.js +0 -105
- package/dist/tui/mouse.js +0 -46
- package/dist/tui/overlay-input.js +0 -12
- package/dist/tui/paste-draft.js +0 -173
- package/dist/tui/prompt-queue.js +0 -24
- package/dist/tui/selection.js +0 -232
- package/dist/tui/session-switch.js +0 -28
- package/dist/tui/slash-commands.js +0 -123
- package/dist/tui/slash-handler.js +0 -589
- package/dist/tui/text-width.js +0 -113
- package/dist/tui/theme.js +0 -12
- package/dist/tui/token-info.js +0 -7
- package/dist/tui/tool-children.js +0 -19
- package/dist/tui/types.js +0 -1
- package/dist/tui/undo-stack.js +0 -14
- package/dist/tui/use-sgr-mouse.js +0 -29
- package/dist/tui-chat.js +0 -456
- package/dist/updater.js +0 -116
- package/dist/xml-search.js +0 -194
- package/docs/superpowers/plans/2026-08-16-batch1-tui-improvements.md +0 -1510
- package/docs/superpowers/plans/2026-08-16-batch2-cli-tools-api.md +0 -2105
- package/docs/superpowers/plans/2026-08-16-batch3-config-engineering.md +0 -1595
- package/docs/superpowers/plans/2026-08-16-input-caret.md +0 -782
- package/docs/superpowers/plans/2026-08-20-tui-completeness.md +0 -873
- package/docs/superpowers/plans/2026-08-20-unified-tui-default.md +0 -631
- package/docs/superpowers/plans/2026-08-23-input-paste-attachments.md +0 -475
- package/docs/superpowers/plans/2026-08-23-thinking-wire-profile.md +0 -450
- package/docs/superpowers/specs/2026-08-16-batch1-tui-improvements-design.md +0 -183
- package/docs/superpowers/specs/2026-08-16-batch2-cli-tools-api-design.md +0 -220
- package/docs/superpowers/specs/2026-08-16-batch3-config-engineering-design.md +0 -196
- package/docs/superpowers/specs/2026-08-16-input-caret-design.md +0 -63
- package/docs/superpowers/specs/2026-08-17-mouse-selection-design.md +0 -116
- package/docs/superpowers/specs/2026-08-20-config-http-alignment-design.md +0 -47
- package/docs/superpowers/specs/2026-08-20-mcp-plugins-alignment-design.md +0 -37
- package/docs/superpowers/specs/2026-08-20-sandbox-permissions-design.md +0 -68
- package/docs/superpowers/specs/2026-08-20-tui-completeness-design.md +0 -273
- package/docs/superpowers/specs/2026-08-20-unified-tui-default-design.md +0 -165
- package/docs/superpowers/specs/2026-08-23-input-paste-attachments-design.md +0 -174
- package/docs/superpowers/specs/2026-08-23-thinking-wire-profile-design.md +0 -140
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { loadMemories, addMemory, deleteMemory, searchMemories, defaultMemoryScope, formatMemoryLine, parseMemoryMode, resolveMemoryMode, memoryModeLabel, memorySourceLabel, isMemoryEnabled, } from "../../memory.js";
|
|
2
|
-
import { runMemoryCli } from "../../memory-cli.js";
|
|
3
|
-
import { CliError } from "../errors.js";
|
|
4
|
-
function printList(which) {
|
|
5
|
-
const memories = loadMemories(which);
|
|
6
|
-
const label = which === "project" ? "Project memories" : "Global memories";
|
|
7
|
-
if (memories.length === 0) {
|
|
8
|
-
console.log(`${label}: none`);
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
console.log(`${label} (${memories.length}):`);
|
|
12
|
-
for (const line of memories.map((m, i) => formatMemoryLine(m, i, { date: true }))) {
|
|
13
|
-
console.log(line);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export async function runMemoryMode(state, scope, flagMode) {
|
|
17
|
-
if (!state && flagMode === undefined)
|
|
18
|
-
return false;
|
|
19
|
-
if (state && state !== "list" && !parseMemoryMode(state))
|
|
20
|
-
return false;
|
|
21
|
-
if (state === "list")
|
|
22
|
-
return false;
|
|
23
|
-
const result = runMemoryCli({
|
|
24
|
-
positionals: state ? [state] : [],
|
|
25
|
-
flagMode,
|
|
26
|
-
scope,
|
|
27
|
-
});
|
|
28
|
-
console.log(result.lines.join("\n"));
|
|
29
|
-
if (!result.ok)
|
|
30
|
-
process.exitCode = 1;
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
export async function runMemoryList(scope) {
|
|
34
|
-
const { memory, source } = resolveMemoryMode();
|
|
35
|
-
console.log(`Current memory: ${memoryModeLabel(memory)} (${memorySourceLabel(source)})`);
|
|
36
|
-
if (!scope && loadMemories("project").length === 0 && loadMemories("global").length === 0) {
|
|
37
|
-
console.log("No memories stored.");
|
|
38
|
-
if (!isMemoryEnabled())
|
|
39
|
-
console.log("Turn on with: min-agent memory on");
|
|
40
|
-
console.log('Or add manually: min-agent memory add "prefer TypeScript over JavaScript"');
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const scopes = scope ? [scope] : ["project", "global"];
|
|
44
|
-
for (const s of scopes)
|
|
45
|
-
printList(s);
|
|
46
|
-
if (!isMemoryEnabled())
|
|
47
|
-
console.log("Memories are stored but not used in chat until you run: min-agent memory on");
|
|
48
|
-
}
|
|
49
|
-
export async function runMemoryAdd(textTokens, scope) {
|
|
50
|
-
const text = textTokens.join(" ");
|
|
51
|
-
if (!text)
|
|
52
|
-
throw new CliError("Usage: min-agent memory add <text> [--project|--global]");
|
|
53
|
-
const resolved = scope ?? defaultMemoryScope();
|
|
54
|
-
addMemory(text, [], resolved);
|
|
55
|
-
const hint = isMemoryEnabled() ? "" : " (memory is off — turn on with: min-agent memory on)";
|
|
56
|
-
console.log(`✓ ${resolved === "project" ? "Project" : "Global"} memory saved: "${text}"${hint}`);
|
|
57
|
-
}
|
|
58
|
-
export async function runMemorySearch(queryTokens, scope) {
|
|
59
|
-
const query = queryTokens.join(" ");
|
|
60
|
-
if (!query)
|
|
61
|
-
throw new CliError("Usage: min-agent memory search <query> [--project|--global]");
|
|
62
|
-
const scopes = scope ? [scope] : ["project", "global"];
|
|
63
|
-
const lines = scopes.flatMap((s) => searchMemories(query, s).map((m) => {
|
|
64
|
-
const tags = m.tags.length > 0 ? ` [${m.tags.join(", ")}]` : "";
|
|
65
|
-
return ` [${s}] #${m.index + 1}: ${m.content}${tags}`;
|
|
66
|
-
}));
|
|
67
|
-
if (lines.length === 0) {
|
|
68
|
-
console.log(`No memories matching "${query}"`);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
console.log(`Found ${lines.length} memory(s):`);
|
|
72
|
-
for (const line of lines)
|
|
73
|
-
console.log(line);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export async function runMemoryDelete(indexArg, scope) {
|
|
77
|
-
const idx = Number.parseInt(indexArg, 10);
|
|
78
|
-
if (Number.isNaN(idx))
|
|
79
|
-
throw new CliError("Usage: min-agent memory delete <number> [--project|--global]");
|
|
80
|
-
const resolved = scope ?? defaultMemoryScope();
|
|
81
|
-
if (deleteMemory(idx - 1, resolved)) {
|
|
82
|
-
console.log(`✓ ${resolved === "project" ? "Project" : "Global"} memory #${idx} deleted`);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
throw new CliError(`${resolved === "project" ? "Project" : "Global"} memory #${idx} not found`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { loadConfig, fetchModels, getActiveProvider } from "../../config.js";
|
|
2
|
-
import { CliError } from "../errors.js";
|
|
3
|
-
export async function runModelsCommand(opts) {
|
|
4
|
-
const config = loadConfig();
|
|
5
|
-
const provider = opts.provider ? config.providers?.find((p) => p.name === opts.provider) : getActiveProvider(config);
|
|
6
|
-
if (!provider?.baseURL || !provider?.apiKey) {
|
|
7
|
-
throw new CliError("Not configured.", { hint: "Run: min-agent setup" });
|
|
8
|
-
}
|
|
9
|
-
console.log(`Fetching models (${provider.name ?? "default"})...`);
|
|
10
|
-
const models = await fetchModels(provider.baseURL, provider.apiKey);
|
|
11
|
-
if (models.length === 0) {
|
|
12
|
-
console.log("No models found or unable to fetch model list.");
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
console.log(`\nAvailable models (${models.length}):`);
|
|
16
|
-
for (const m of models) {
|
|
17
|
-
const marker = m === provider.defaultModel ? " ← default" : "";
|
|
18
|
-
console.log(` ${m}${marker}`);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { runPermissionCli } from "../../permission-cli.js";
|
|
2
|
-
export async function runPermissionCommand(args, opts, parentOpts) {
|
|
3
|
-
const scope = opts.project ? "project" : opts.global ? "global" : undefined;
|
|
4
|
-
const result = runPermissionCli({
|
|
5
|
-
positionals: args,
|
|
6
|
-
flagMode: parentOpts.permission,
|
|
7
|
-
scope,
|
|
8
|
-
});
|
|
9
|
-
console.log(result.lines.join("\n"));
|
|
10
|
-
if (!result.ok)
|
|
11
|
-
process.exitCode = 1;
|
|
12
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { existsSync, writeFileSync, mkdirSync } from "fs";
|
|
2
|
-
import { getConfigDir, getRulesFile } from "../../config.js";
|
|
3
|
-
export async function runRulesShow() {
|
|
4
|
-
const { loadInstructions } = await import("../../instructions.js");
|
|
5
|
-
const instructions = await loadInstructions();
|
|
6
|
-
if (instructions.length === 0) {
|
|
7
|
-
console.log("No instruction rules loaded.");
|
|
8
|
-
console.log("");
|
|
9
|
-
console.log("Add rules by creating:");
|
|
10
|
-
console.log(` Global: ${getRulesFile()}`);
|
|
11
|
-
console.log(" Project: ./AGENTS.md or ./RULES.md");
|
|
12
|
-
console.log("");
|
|
13
|
-
console.log("Or add paths/URLs in ~/.min-agent/config.json:");
|
|
14
|
-
console.log(' { "instructions": ["./docs/rules.md", "https://..."] }');
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
console.log(`Loaded ${instructions.length} instruction source(s):\n`);
|
|
18
|
-
for (const inst of instructions) {
|
|
19
|
-
const firstLine = inst.split("\n")[0];
|
|
20
|
-
console.log(` ${firstLine}`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export async function runRulesEdit() {
|
|
25
|
-
const rulesFile = getRulesFile();
|
|
26
|
-
if (!existsSync(rulesFile)) {
|
|
27
|
-
mkdirSync(getConfigDir(), { recursive: true });
|
|
28
|
-
writeFileSync(rulesFile, `# Global Agent Rules\n\n<!-- Add your custom instructions here. They will be included in every conversation. -->\n`, "utf-8");
|
|
29
|
-
}
|
|
30
|
-
const editor = process.env.EDITOR || "vi";
|
|
31
|
-
const { execSync } = await import("child_process");
|
|
32
|
-
execSync(`${editor} "${rulesFile}"`, { stdio: "inherit" });
|
|
33
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { runSandboxCli } from "../../sandbox-cli.js";
|
|
2
|
-
export async function runSandboxCommand(args, opts, parentOpts) {
|
|
3
|
-
const scope = opts.project ? "project" : opts.global ? "global" : undefined;
|
|
4
|
-
const result = runSandboxCli({
|
|
5
|
-
positionals: args,
|
|
6
|
-
flagMode: parentOpts.sandbox,
|
|
7
|
-
flagNetwork: parentOpts.network ?? opts.network,
|
|
8
|
-
scope,
|
|
9
|
-
});
|
|
10
|
-
console.log(result.lines.join("\n"));
|
|
11
|
-
if (!result.ok)
|
|
12
|
-
process.exitCode = 1;
|
|
13
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { isConfigured } from "../../config.js";
|
|
2
|
-
import { CliError } from "../errors.js";
|
|
3
|
-
export async function runServeCommand(opts) {
|
|
4
|
-
if (!isConfigured()) {
|
|
5
|
-
throw new CliError("Not configured.", { hint: "Run: min-agent setup" });
|
|
6
|
-
}
|
|
7
|
-
const { runServe } = await import("../../serve.js");
|
|
8
|
-
await runServe({ port: opts.port, host: opts.host });
|
|
9
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { isConfigured } from "../../config.js";
|
|
2
|
-
import { CliError } from "../errors.js";
|
|
3
|
-
export async function startTuiSession(input) {
|
|
4
|
-
if (!isConfigured()) {
|
|
5
|
-
throw new CliError("Not configured.", { hint: "Run: min-agent setup" });
|
|
6
|
-
}
|
|
7
|
-
const { runTui } = await import("../../tui-chat.js");
|
|
8
|
-
const prompt = input.positionals.join(" ").trim();
|
|
9
|
-
await runTui({
|
|
10
|
-
modelId: input.model,
|
|
11
|
-
providerName: input.provider,
|
|
12
|
-
resumeSessionId: input.resume,
|
|
13
|
-
images: input.images,
|
|
14
|
-
initialPrompt: prompt || undefined,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { discoverSkills } from "../../skills.js";
|
|
2
|
-
import { existsSync, writeFileSync, mkdirSync } from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import os from "os";
|
|
5
|
-
import { CliError } from "../errors.js";
|
|
6
|
-
/** One-line, length-capped text for list output. */
|
|
7
|
-
function truncate(text, max) {
|
|
8
|
-
const flat = text.replace(/\s+/g, " ").trim();
|
|
9
|
-
return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;
|
|
10
|
-
}
|
|
11
|
-
export async function runSkillsList(json) {
|
|
12
|
-
discoverSkills({ silent: true });
|
|
13
|
-
const { getAllSkills, getStaleDisabledSkills } = await import("../../skills.js");
|
|
14
|
-
const all = getAllSkills().sort((a, b) => a.name.localeCompare(b.name));
|
|
15
|
-
const stale = getStaleDisabledSkills();
|
|
16
|
-
if (json) {
|
|
17
|
-
console.log(JSON.stringify({
|
|
18
|
-
count: all.length,
|
|
19
|
-
enabled_count: all.filter((s) => s.enabled).length,
|
|
20
|
-
stale_disabled: stale,
|
|
21
|
-
skills: all.map((s) => ({
|
|
22
|
-
name: s.name,
|
|
23
|
-
description: s.description,
|
|
24
|
-
location: s.location,
|
|
25
|
-
enabled: s.enabled,
|
|
26
|
-
...(s.disabledScope ? { disabled_scope: s.disabledScope } : {}),
|
|
27
|
-
...(s.version ? { version: s.version } : {}),
|
|
28
|
-
...(s.allowedTools.length ? { allowed_tools: s.allowedTools } : {}),
|
|
29
|
-
...(s.requiredBins.length ? { requires_bins: s.requiredBins } : {}),
|
|
30
|
-
...(s.builtin ? { builtin: true } : {}),
|
|
31
|
-
...(s.alwaysLoad ? { always_load: true } : {}),
|
|
32
|
-
})),
|
|
33
|
-
}, null, 2));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (all.length === 0 && stale.length === 0) {
|
|
37
|
-
console.log("No skills found. Add SKILL.md files in .min-agent/skills/<name>/");
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
console.log(`Skills (${all.filter((s) => s.enabled).length} enabled, ${all.filter((s) => !s.enabled).length} disabled):`);
|
|
41
|
-
for (const skill of all) {
|
|
42
|
-
const status = skill.enabled
|
|
43
|
-
? "\x1b[32menabled \x1b[0m"
|
|
44
|
-
: `\x1b[90mdisabled(${skill.disabledScope === "project" ? "proj" : "glob"})\x1b[0m`;
|
|
45
|
-
const origin = skill.builtin ? " \x1b[90mbuiltin\x1b[0m" : "";
|
|
46
|
-
console.log(` ${skill.name} ${status}${origin} \x1b[90m${truncate(skill.description, 60)}\x1b[0m`);
|
|
47
|
-
console.log(` \x1b[90m${skill.location}\x1b[0m`);
|
|
48
|
-
}
|
|
49
|
-
if (stale.length > 0) {
|
|
50
|
-
console.log(`\n\x1b[33m⚠ disabledSkills/enabledSkills entries matching no skill: ${stale.join(", ")}\x1b[0m`);
|
|
51
|
-
console.log(`\x1b[33m Remove them with: min-agent skills enable ${stale.join(" ")} (add --project if the entry is project-scoped)\x1b[0m`);
|
|
52
|
-
}
|
|
53
|
-
console.log("\nUse: min-agent skills info <name> for details");
|
|
54
|
-
}
|
|
55
|
-
export async function runSkillsInfo(name, json) {
|
|
56
|
-
discoverSkills({ silent: true });
|
|
57
|
-
const { getSkill, getAllSkills } = await import("../../skills.js");
|
|
58
|
-
const skill = getSkill(name);
|
|
59
|
-
if (!skill) {
|
|
60
|
-
const names = getAllSkills().map((s) => s.name);
|
|
61
|
-
throw new CliError(`Skill "${name}" not found.${names.length ? ` Available: ${names.join(", ")}` : " No skills discovered."}`);
|
|
62
|
-
}
|
|
63
|
-
if (json) {
|
|
64
|
-
console.log(JSON.stringify(skill, null, 2));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
console.log(`Name: ${skill.name}`);
|
|
68
|
-
console.log(`Status: ${skill.enabled ? "enabled" : `disabled (${skill.disabledScope} scope)`}`);
|
|
69
|
-
if (skill.builtin)
|
|
70
|
-
console.log("Source: builtin");
|
|
71
|
-
if (skill.version)
|
|
72
|
-
console.log(`Version: ${skill.version}`);
|
|
73
|
-
console.log(`Description: ${skill.description}`);
|
|
74
|
-
console.log(`Location: ${skill.location}`);
|
|
75
|
-
if (skill.allowedTools.length > 0)
|
|
76
|
-
console.log(`Tools: ${skill.allowedTools.join(", ")}`);
|
|
77
|
-
if (skill.requiredBins.length > 0)
|
|
78
|
-
console.log(`Requires: ${skill.requiredBins.join(", ")}`);
|
|
79
|
-
if (skill.content.trim()) {
|
|
80
|
-
console.log("\n--- Content ---\n");
|
|
81
|
-
console.log(skill.content.trim());
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
export async function runSkillsToggle(names, enabled, scope) {
|
|
85
|
-
const verb = enabled ? "enable" : "disable";
|
|
86
|
-
if (names.length === 0)
|
|
87
|
-
throw new CliError(`Usage: min-agent skills ${verb} <name...> [--project]`);
|
|
88
|
-
discoverSkills({ silent: true });
|
|
89
|
-
const { getAllSkills, setSkillEnabled, getStaleDisabledSkills } = await import("../../skills.js");
|
|
90
|
-
const known = new Set(getAllSkills().map((s) => s.name));
|
|
91
|
-
const stale = new Set(getStaleDisabledSkills());
|
|
92
|
-
// `enable` must accept stale names so they can be cleaned up from config;
|
|
93
|
-
// `disable` on an unknown name is always an error.
|
|
94
|
-
const unknown = names.filter((n) => !known.has(n) && !(enabled && stale.has(n)));
|
|
95
|
-
if (unknown.length > 0) {
|
|
96
|
-
throw new CliError(`Skill${unknown.length > 1 ? "s" : ""} not found: ${unknown.join(", ")}`, {
|
|
97
|
-
hint: known.size ? `Available: ${[...known].join(", ")}` : "No skills discovered.",
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
for (const result of setSkillEnabled(names, enabled, scope)) {
|
|
101
|
-
console.log(`✓ Skill "${result.name}" ${verb}d (${scope} scope)`);
|
|
102
|
-
if (result.blockedBy) {
|
|
103
|
-
console.log(`\x1b[33m ⚠ still ${result.enabled ? "enabled" : "disabled"} — overridden by ${result.blockedBy} scope\x1b[0m`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
export async function runSkillsNew(name, global) {
|
|
108
|
-
if (!/^[\w-]+$/.test(name)) {
|
|
109
|
-
throw new CliError("Invalid skill name", { hint: "use letters, digits, _ or -" });
|
|
110
|
-
}
|
|
111
|
-
const root = global ? path.join(os.homedir(), ".agents", "skills") : path.join(process.cwd(), ".min-agent", "skills");
|
|
112
|
-
const dir = path.join(root, name);
|
|
113
|
-
if (existsSync(path.join(dir, "SKILL.md"))) {
|
|
114
|
-
throw new CliError(`Skill "${name}" already exists at ${dir}`);
|
|
115
|
-
}
|
|
116
|
-
mkdirSync(dir, { recursive: true });
|
|
117
|
-
writeFileSync(path.join(dir, "SKILL.md"), `---\nname: ${name}\ndescription: What this skill does\n# version: 1.0.0\n# allowed-tools: [read, grep]\n# metadata:\n# requires:\n# bins: ["some-cli"]\n---\n\n# ${name}\n\nWrite the skill instructions here.\n`, "utf-8");
|
|
118
|
-
console.log(`✓ Created skill "${name}" at ${path.join(dir, "SKILL.md")}`);
|
|
119
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { runThinkCli } from "../../think-cli.js";
|
|
2
|
-
export async function runThinkCommand(args, opts, parentOpts) {
|
|
3
|
-
const scope = opts.project ? "project" : opts.global ? "global" : undefined;
|
|
4
|
-
const result = runThinkCli({
|
|
5
|
-
positionals: args,
|
|
6
|
-
flagEffort: parentOpts.think,
|
|
7
|
-
scope,
|
|
8
|
-
});
|
|
9
|
-
console.log(result.lines.join("\n"));
|
|
10
|
-
if (!result.ok)
|
|
11
|
-
process.exitCode = 1;
|
|
12
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { runSandboxCli } from "../../sandbox-cli.js";
|
|
2
|
-
import { runPermissionCli } from "../../permission-cli.js";
|
|
3
|
-
import { runThinkCli } from "../../think-cli.js";
|
|
4
|
-
import { runMemoryCli } from "../../memory-cli.js";
|
|
5
|
-
export async function runWriteConfig(input) {
|
|
6
|
-
const lines = [];
|
|
7
|
-
let ok = true;
|
|
8
|
-
if (input.sandbox !== undefined || input.network !== undefined) {
|
|
9
|
-
const result = runSandboxCli({
|
|
10
|
-
positionals: [],
|
|
11
|
-
flagMode: input.sandbox,
|
|
12
|
-
flagNetwork: input.network,
|
|
13
|
-
scope: input.scope,
|
|
14
|
-
});
|
|
15
|
-
lines.push(...result.lines);
|
|
16
|
-
if (!result.ok)
|
|
17
|
-
ok = false;
|
|
18
|
-
}
|
|
19
|
-
if (input.permission !== undefined) {
|
|
20
|
-
const result = runPermissionCli({
|
|
21
|
-
positionals: [],
|
|
22
|
-
flagMode: input.permission,
|
|
23
|
-
scope: input.scope,
|
|
24
|
-
});
|
|
25
|
-
lines.push(...result.lines);
|
|
26
|
-
if (!result.ok)
|
|
27
|
-
ok = false;
|
|
28
|
-
}
|
|
29
|
-
if (input.think !== undefined) {
|
|
30
|
-
const result = runThinkCli({
|
|
31
|
-
positionals: [],
|
|
32
|
-
flagEffort: input.think,
|
|
33
|
-
scope: input.scope,
|
|
34
|
-
});
|
|
35
|
-
lines.push(...result.lines);
|
|
36
|
-
if (!result.ok)
|
|
37
|
-
ok = false;
|
|
38
|
-
}
|
|
39
|
-
if (input.memory !== undefined) {
|
|
40
|
-
const result = runMemoryCli({
|
|
41
|
-
positionals: [],
|
|
42
|
-
flagMode: input.memory,
|
|
43
|
-
scope: input.scope,
|
|
44
|
-
});
|
|
45
|
-
lines.push(...result.lines);
|
|
46
|
-
if (!result.ok)
|
|
47
|
-
ok = false;
|
|
48
|
-
}
|
|
49
|
-
console.log(lines.join("\n"));
|
|
50
|
-
if (!ok)
|
|
51
|
-
process.exitCode = 1;
|
|
52
|
-
}
|
package/dist/cli/errors.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified CLI error contract.
|
|
3
|
-
*
|
|
4
|
-
* Exit code convention:
|
|
5
|
-
* 1 - user error (bad arguments, missing input, not found, validation failure)
|
|
6
|
-
* 2 - runtime error (network failure, subprocess failure, unexpected exception)
|
|
7
|
-
*/
|
|
8
|
-
export class CliError extends Error {
|
|
9
|
-
exitCode;
|
|
10
|
-
hint;
|
|
11
|
-
constructor(message, options) {
|
|
12
|
-
super(message);
|
|
13
|
-
this.name = "CliError";
|
|
14
|
-
this.exitCode = options?.exitCode ?? 1;
|
|
15
|
-
this.hint = options?.hint;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export function userError(message, hint) {
|
|
19
|
-
return new CliError(message, { exitCode: 1, hint });
|
|
20
|
-
}
|
|
21
|
-
export function runtimeError(message, hint) {
|
|
22
|
-
return new CliError(message, { exitCode: 2, hint });
|
|
23
|
-
}
|
|
24
|
-
/** Render a CliError (or any error) as the standard `✖ message` block on stderr. */
|
|
25
|
-
export function formatCliError(err) {
|
|
26
|
-
if (err instanceof CliError) {
|
|
27
|
-
return err.hint ? `✖ ${err.message}\n → ${err.hint}` : `✖ ${err.message}`;
|
|
28
|
-
}
|
|
29
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
30
|
-
return `✖ ${message}`;
|
|
31
|
-
}
|
|
32
|
-
export function exitCodeFor(err) {
|
|
33
|
-
if (err instanceof CliError)
|
|
34
|
-
return err.exitCode;
|
|
35
|
-
return 2;
|
|
36
|
-
}
|
package/dist/cli/exec-prompt.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolve the final prompt text for `min-agent exec`, combining positional
|
|
3
|
-
* arguments with piped stdin according to these rules:
|
|
4
|
-
* - `exec -` reads the entire prompt from stdin.
|
|
5
|
-
* - `exec` (no args) requires piped stdin (non-TTY); errors otherwise.
|
|
6
|
-
* - `exec <msg>` + pipe appends piped stdin after the message.
|
|
7
|
-
* - `exec <msg>` uses the message as-is.
|
|
8
|
-
*/
|
|
9
|
-
export function resolveExecPrompt(positionals, stdinText, stdinIsTty) {
|
|
10
|
-
const joined = positionals.join(" ");
|
|
11
|
-
const piped = stdinText.length > 0;
|
|
12
|
-
if (joined === "-") {
|
|
13
|
-
const prompt = stdinText;
|
|
14
|
-
if (!prompt.trim())
|
|
15
|
-
return { ok: false, error: "Usage: min-agent exec <message>" };
|
|
16
|
-
return { ok: true, prompt };
|
|
17
|
-
}
|
|
18
|
-
if (!joined) {
|
|
19
|
-
if (stdinIsTty || !piped)
|
|
20
|
-
return { ok: false, error: "Usage: min-agent exec <message>" };
|
|
21
|
-
return { ok: true, prompt: stdinText };
|
|
22
|
-
}
|
|
23
|
-
if (piped && !stdinIsTty)
|
|
24
|
-
return { ok: true, prompt: `${joined}\n\n${stdinText}` };
|
|
25
|
-
return { ok: true, prompt: joined };
|
|
26
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Option } from "commander";
|
|
2
|
-
import { parseNetworkPolicy, parseSandboxMode } from "../sandbox.js";
|
|
3
|
-
import { parsePermissionMode, parseThinkingEffort, parseMemoryMode, } from "../config.js";
|
|
4
|
-
import { userError } from "./errors.js";
|
|
5
|
-
/** Reusable --project / --global mutually exclusive scope selector. */
|
|
6
|
-
export function scopeOptions() {
|
|
7
|
-
return [
|
|
8
|
-
new Option("--project", "Apply to this project only (.min-agent/config.json)").conflicts("global"),
|
|
9
|
-
new Option("--global", "Apply to every project (~/.min-agent/config.json)").conflicts("project"),
|
|
10
|
-
];
|
|
11
|
-
}
|
|
12
|
-
/** Resolve --project/--global into a Scope, given an optional fallback. */
|
|
13
|
-
export function resolveScope(opts, fallback = "global") {
|
|
14
|
-
if (opts.project)
|
|
15
|
-
return "project";
|
|
16
|
-
if (opts.global)
|
|
17
|
-
return "global";
|
|
18
|
-
return fallback;
|
|
19
|
-
}
|
|
20
|
-
export function parseSandboxModeArg(value) {
|
|
21
|
-
const parsed = parseSandboxMode(value);
|
|
22
|
-
if (!parsed)
|
|
23
|
-
throw userError(`Invalid --sandbox value: "${value}"`, "use one of: off, workspace, strict");
|
|
24
|
-
return parsed;
|
|
25
|
-
}
|
|
26
|
-
export function parseNetworkPolicyArg(value) {
|
|
27
|
-
const parsed = parseNetworkPolicy(value);
|
|
28
|
-
if (!parsed)
|
|
29
|
-
throw userError(`Invalid --network value: "${value}"`, "use one of: allow, deny");
|
|
30
|
-
return parsed;
|
|
31
|
-
}
|
|
32
|
-
export function parsePermissionModeArg(value) {
|
|
33
|
-
const parsed = parsePermissionMode(value);
|
|
34
|
-
if (!parsed)
|
|
35
|
-
throw userError(`Invalid --permission value: "${value}"`, "use one of: ask, accept-edits, allow-all");
|
|
36
|
-
return parsed;
|
|
37
|
-
}
|
|
38
|
-
export function parseThinkingEffortArg(value) {
|
|
39
|
-
const parsed = parseThinkingEffort(value);
|
|
40
|
-
if (!parsed)
|
|
41
|
-
throw userError(`Invalid --think value: "${value}"`, "use one of: off, low, medium, high, max");
|
|
42
|
-
return parsed;
|
|
43
|
-
}
|
|
44
|
-
export function parseMemoryModeArg(value) {
|
|
45
|
-
const parsed = parseMemoryMode(value);
|
|
46
|
-
if (!parsed)
|
|
47
|
-
throw userError(`Invalid --memory value: "${value}"`, "use one of: on, off");
|
|
48
|
-
return parsed;
|
|
49
|
-
}
|
|
50
|
-
export function parsePortArg(value) {
|
|
51
|
-
const n = Number.parseInt(value, 10);
|
|
52
|
-
if (!Number.isFinite(n) || n <= 0 || n > 65535) {
|
|
53
|
-
throw userError(`Invalid --port value: "${value}"`, "use an integer between 1 and 65535");
|
|
54
|
-
}
|
|
55
|
-
return n;
|
|
56
|
-
}
|
|
57
|
-
export function parsePositiveIntArg(flagName) {
|
|
58
|
-
return (value) => {
|
|
59
|
-
const n = Number.parseInt(value, 10);
|
|
60
|
-
if (!Number.isFinite(n) || n <= 0) {
|
|
61
|
-
throw userError(`Invalid ${flagName} value: "${value}"`, "use a positive integer");
|
|
62
|
-
}
|
|
63
|
-
return n;
|
|
64
|
-
};
|
|
65
|
-
}
|