@sean.holung/minicode 0.3.2 → 0.3.3
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 +48 -43
- package/dist/scripts/run-benchmarks.js +147 -0
- package/dist/src/agent/config.js +149 -40
- package/dist/src/agent/editable-config.js +314 -0
- package/dist/src/analysis/structural-analysis.js +379 -0
- package/dist/src/benchmark/evaluator.js +79 -0
- package/dist/src/benchmark/index.js +4 -0
- package/dist/src/benchmark/reporter.js +177 -0
- package/dist/src/benchmark/runner.js +100 -0
- package/dist/src/benchmark/task-loader.js +78 -0
- package/dist/src/benchmark/types.js +5 -0
- package/dist/src/cli/args.js +10 -0
- package/dist/src/cli/config-slash-command.js +135 -0
- package/dist/src/cli/plugin-install.js +69 -0
- package/dist/src/index.js +76 -6
- package/dist/src/indexer/cache.js +6 -4
- package/dist/src/indexer/code-map.js +41 -13
- package/dist/src/indexer/plugins/typescript.js +70 -23
- package/dist/src/indexer/project-index.js +175 -36
- package/dist/src/indexer/symbol-names.js +92 -0
- package/dist/src/model-utils.js +18 -0
- package/dist/src/serve/agent-bridge.js +203 -24
- package/dist/src/serve/mcp-server.js +405 -0
- package/dist/src/serve/server.js +165 -10
- package/dist/src/serve/websocket.js +8 -0
- package/dist/src/shared/graph-styles.js +119 -0
- package/dist/src/tools/find-path.js +75 -0
- package/dist/src/tools/find-references.js +7 -2
- package/dist/src/tools/get-dependencies.js +3 -2
- package/dist/src/tools/read-symbol.js +12 -5
- package/dist/src/tools/registry.js +3 -1
- package/dist/src/tools/search-code-map.js +4 -2
- package/dist/src/ui/app.js +1 -1
- package/dist/src/ui/cli-ink.js +79 -4
- package/dist/src/ui/components/header-bar.js +6 -2
- package/dist/src/ui/state/ui-store.js +5 -0
- package/dist/src/web/app.js +1124 -176
- package/dist/src/web/index.html +113 -3
- package/dist/src/web/style.css +973 -55
- package/dist/tests/agent.test.js +31 -0
- package/dist/tests/analysis-helpers.test.js +89 -0
- package/dist/tests/analysis-ui.test.js +29 -0
- package/dist/tests/benchmark-harness.test.js +527 -0
- package/dist/tests/config-api.test.js +143 -0
- package/dist/tests/config-integration.test.js +751 -0
- package/dist/tests/config-slash-command.test.js +106 -0
- package/dist/tests/config.test.js +42 -1
- package/dist/tests/context-indicator.test.js +220 -0
- package/dist/tests/editable-config.test.js +109 -0
- package/dist/tests/find-path.test.js +183 -0
- package/dist/tests/focus-tracker.test.js +62 -0
- package/dist/tests/graph-onboarding.test.js +55 -0
- package/dist/tests/graph-styles.test.js +65 -0
- package/dist/tests/indexer.test.js +137 -0
- package/dist/tests/mcp-and-plugin.test.js +186 -0
- package/dist/tests/model-client-openai.test.js +29 -0
- package/dist/tests/model-selection.test.js +136 -0
- package/dist/tests/model-utils.test.js +22 -0
- package/dist/tests/reasoning-effort.test.js +264 -0
- package/dist/tests/run-benchmarks.test.js +161 -0
- package/dist/tests/search-code-map.test.js +18 -0
- package/dist/tests/serve.integration.test.js +218 -2
- package/dist/tests/session-ui.test.js +21 -0
- package/dist/tests/session.test.js +50 -0
- package/dist/tests/settings-ui.test.js +30 -0
- package/dist/tests/structural-analysis.test.js +218 -0
- package/node_modules/@minicode/agent-sdk/README.md +80 -51
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts +16 -5
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js +51 -33
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts +14 -0
- package/node_modules/@minicode/agent-sdk/dist/src/agent/types.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts +3 -2
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.js +2 -0
- package/node_modules/@minicode/agent-sdk/dist/src/index.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.d.ts +35 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.d.ts.map +1 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.js +64 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/focus-tracker.js.map +1 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts +7 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.d.ts +5 -1
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.js +83 -11
- package/node_modules/@minicode/agent-sdk/dist/src/model/client.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.d.ts +1 -0
- package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.js +8 -1
- package/node_modules/@minicode/agent-sdk/dist/src/safety/guardrails.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.js +4 -1
- package/node_modules/@minicode/agent-sdk/dist/src/session/session.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tests/agent.test.js +3 -1
- package/node_modules/@minicode/agent-sdk/dist/tests/agent.test.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tests/guardrails.test.js +8 -2
- package/node_modules/@minicode/agent-sdk/dist/tests/guardrails.test.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -5
- package/plugin/.claude-plugin/plugin.json +12 -0
- package/plugin/.mcp.json +8 -0
- package/plugin/CLAUDE.md +26 -0
- package/plugin/skills/analyze/SKILL.md +12 -0
- package/plugin/skills/focus/SKILL.md +20 -0
- package/plugin/skills/graph/SKILL.md +13 -0
- package/plugin/skills/symbols/SKILL.md +13 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { afterEach, test } from "node:test";
|
|
7
|
+
import { createRequestHandler } from "../src/serve/server.js";
|
|
8
|
+
import { AgentBridge } from "../src/serve/agent-bridge.js";
|
|
9
|
+
import { createTestAgentConfig } from "./test-utils.js";
|
|
10
|
+
class ConfigApiBridge extends AgentBridge {
|
|
11
|
+
workspaceRoot;
|
|
12
|
+
constructor(workspaceRoot) {
|
|
13
|
+
super(() => { }, false);
|
|
14
|
+
this.workspaceRoot = workspaceRoot;
|
|
15
|
+
}
|
|
16
|
+
isBusy() {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
getConfig() {
|
|
20
|
+
return createTestAgentConfig(this.workspaceRoot);
|
|
21
|
+
}
|
|
22
|
+
async listModels() {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
async runTurn(message) {
|
|
26
|
+
return { text: `Echo: ${message}`, usage: { inputTokens: 1, outputTokens: 1 } };
|
|
27
|
+
}
|
|
28
|
+
async listSess() { return []; }
|
|
29
|
+
hasIndex() { return false; }
|
|
30
|
+
}
|
|
31
|
+
const activeServers = new Set();
|
|
32
|
+
const tempDirs = [];
|
|
33
|
+
afterEach(async () => {
|
|
34
|
+
await Promise.all([...activeServers].map((server) => new Promise((resolve) => server.close(() => resolve()))));
|
|
35
|
+
activeServers.clear();
|
|
36
|
+
await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })));
|
|
37
|
+
});
|
|
38
|
+
async function startServer(bridge, options = {}) {
|
|
39
|
+
const server = createServer(createRequestHandler(bridge, undefined, options));
|
|
40
|
+
activeServers.add(server);
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
server.listen(0, "127.0.0.1", () => {
|
|
43
|
+
const address = server.address();
|
|
44
|
+
if (typeof address === "object" && address) {
|
|
45
|
+
resolve(`http://127.0.0.1:${address.port}`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function withUnsetEnvVars(names, callback) {
|
|
51
|
+
const previous = new Map();
|
|
52
|
+
for (const name of names) {
|
|
53
|
+
previous.set(name, process.env[name]);
|
|
54
|
+
delete process.env[name];
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
await callback();
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
for (const [name, value] of previous) {
|
|
61
|
+
if (value === undefined) {
|
|
62
|
+
delete process.env[name];
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
process.env[name] = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
test("GET /api/config returns structured editable settings payload", async () => {
|
|
71
|
+
await withUnsetEnvVars(["MAX_STEPS"], async () => {
|
|
72
|
+
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), "minicode-config-api-"));
|
|
73
|
+
const minicodeHome = await mkdtemp(path.join(os.tmpdir(), "minicode-config-home-"));
|
|
74
|
+
tempDirs.push(workspaceRoot);
|
|
75
|
+
tempDirs.push(minicodeHome);
|
|
76
|
+
const base = await startServer(new ConfigApiBridge(workspaceRoot), { minicodeHome });
|
|
77
|
+
const res = await fetch(`${base}/api/config`);
|
|
78
|
+
assert.equal(res.status, 200);
|
|
79
|
+
const body = await res.json();
|
|
80
|
+
assert.match(body.config, /workspaceRoot/);
|
|
81
|
+
assert.equal(body.restartRequired, true);
|
|
82
|
+
assert.equal(body.secretsUiSupported, false);
|
|
83
|
+
assert.equal(body.settings.configPath, path.join(minicodeHome, "agent.config.json"));
|
|
84
|
+
const maxSteps = body.settings.entries.find((entry) => entry.key === "maxSteps");
|
|
85
|
+
assert.equal(maxSteps?.type, "number");
|
|
86
|
+
assert.equal(maxSteps?.envVar, "MAX_STEPS");
|
|
87
|
+
assert.equal(maxSteps?.effectiveValue, 10);
|
|
88
|
+
assert.equal(maxSteps?.persistedValue, null);
|
|
89
|
+
assert.equal(maxSteps?.envValue, null);
|
|
90
|
+
assert.equal(maxSteps?.overriddenByEnv, false);
|
|
91
|
+
assert.match(maxSteps?.description ?? "", /Turn call limit/);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
test("POST /api/config persists global settings and returns updated metadata", async () => {
|
|
95
|
+
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), "minicode-config-api-"));
|
|
96
|
+
const minicodeHome = await mkdtemp(path.join(os.tmpdir(), "minicode-config-home-"));
|
|
97
|
+
tempDirs.push(workspaceRoot);
|
|
98
|
+
tempDirs.push(minicodeHome);
|
|
99
|
+
const base = await startServer(new ConfigApiBridge(workspaceRoot), { minicodeHome });
|
|
100
|
+
const res = await fetch(`${base}/api/config`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "Content-Type": "application/json" },
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
updates: {
|
|
105
|
+
maxSteps: 42,
|
|
106
|
+
enableDynamicPrompt: false,
|
|
107
|
+
},
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
110
|
+
assert.equal(res.status, 200);
|
|
111
|
+
const body = await res.json();
|
|
112
|
+
assert.equal(body.ok, true);
|
|
113
|
+
assert.equal(body.scope, "global");
|
|
114
|
+
assert.equal(body.path, path.join(minicodeHome, "agent.config.json"));
|
|
115
|
+
assert.equal(body.restartRequired, true);
|
|
116
|
+
assert.match(body.message, /Persisted config updated/);
|
|
117
|
+
assert.deepEqual(body.saved, [
|
|
118
|
+
{ key: "maxSteps", value: 42 },
|
|
119
|
+
{ key: "enableDynamicPrompt", value: false },
|
|
120
|
+
]);
|
|
121
|
+
const persisted = JSON.parse(await readFile(path.join(minicodeHome, "agent.config.json"), "utf8"));
|
|
122
|
+
assert.equal(persisted.maxSteps, 42);
|
|
123
|
+
assert.equal(persisted.enableDynamicPrompt, false);
|
|
124
|
+
const maxSteps = body.settings.entries.find((entry) => entry.key === "maxSteps");
|
|
125
|
+
assert.equal(maxSteps?.persistedValue, 42);
|
|
126
|
+
});
|
|
127
|
+
test("POST /api/config rejects invalid keys", async () => {
|
|
128
|
+
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), "minicode-config-api-"));
|
|
129
|
+
tempDirs.push(workspaceRoot);
|
|
130
|
+
const base = await startServer(new ConfigApiBridge(workspaceRoot));
|
|
131
|
+
const res = await fetch(`${base}/api/config`, {
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers: { "Content-Type": "application/json" },
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
updates: {
|
|
136
|
+
openAiApiKey: "secret",
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
assert.equal(res.status, 400);
|
|
141
|
+
const body = await res.json();
|
|
142
|
+
assert.match(body.error, /Unknown editable config key/);
|
|
143
|
+
});
|