mini-coder 0.7.0 → 0.7.1
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/bun.lock +14 -14
- package/package.json +5 -5
- package/src/tui.ts +74 -3
- package/src/types.ts +1 -0
package/bun.lock
CHANGED
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@cel-tui/components": "^0.8.3",
|
|
9
9
|
"@cel-tui/core": "^0.8.3",
|
|
10
|
-
"@earendil-works/pi-ai": "^0.
|
|
10
|
+
"@earendil-works/pi-ai": "^0.79.3",
|
|
11
11
|
"diff": "^9.0.0",
|
|
12
12
|
"simple-git": "^3.36.0",
|
|
13
13
|
"yaml": "^2.9.0",
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@biomejs/biome": "^2.
|
|
16
|
+
"@biomejs/biome": "^2.5.0",
|
|
17
17
|
"@types/bun": "^1.3.14",
|
|
18
|
-
"prettier": "^3.8.
|
|
18
|
+
"prettier": "^3.8.4",
|
|
19
19
|
"typescript": "^6.0.3",
|
|
20
20
|
},
|
|
21
21
|
},
|
|
@@ -75,23 +75,23 @@
|
|
|
75
75
|
|
|
76
76
|
"@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
|
|
77
77
|
|
|
78
|
-
"@biomejs/biome": ["@biomejs/biome@2.
|
|
78
|
+
"@biomejs/biome": ["@biomejs/biome@2.5.0", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.0", "@biomejs/cli-darwin-x64": "2.5.0", "@biomejs/cli-linux-arm64": "2.5.0", "@biomejs/cli-linux-arm64-musl": "2.5.0", "@biomejs/cli-linux-x64": "2.5.0", "@biomejs/cli-linux-x64-musl": "2.5.0", "@biomejs/cli-win32-arm64": "2.5.0", "@biomejs/cli-win32-x64": "2.5.0" }, "bin": { "biome": "bin/biome" } }, "sha512-4kURkd9hAPrdDM3C9n82ycYgx8hvQcW6MjKTEejruj8rK0N8P3OPpdy8BvI8kt3KWY4ycF5XtDOrktetEfhfuw=="],
|
|
79
79
|
|
|
80
|
-
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.
|
|
80
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Mn3Fwi3SA5fgmfCPqmzpWF2DLZnms3BVAhM088nTnGrTZmHS3wwIjcoZPqpXeNgd3DrrLH6xp8vTLIBuJoZiXw=="],
|
|
81
81
|
|
|
82
|
-
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.
|
|
82
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-rg3VPL5P8mYro6pqlXYXuJWph21slVp3SZtAqWSrkZs40d2gTzYmHF8E/X1iTID25btmNKltNDJ926sqVBp7DQ=="],
|
|
83
83
|
|
|
84
|
-
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.
|
|
84
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-tl+LW8fdD96/xdeWtWwc82LIOc5CoY7N2AsogLTp5R4ECErYt+8Jl/N68ezN9vzSiqPTxw6vjcihoLPYKZHrlw=="],
|
|
85
85
|
|
|
86
|
-
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.
|
|
86
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vQdM4oSGaf7ZNeGO9w5+Y8SBtyser9M6znxYbm7Ec8wInxJu1WiKxFYZW5Auj2d80bcVvefuGGRxoFOE0eee8g=="],
|
|
87
87
|
|
|
88
|
-
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.
|
|
88
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zpEGf4RQbFEh8Vt7OmavLyyOzRbtcE9osCqrS1kfvt8jDvxwhKXLSf7n0ebr/ov0RJ9ssP+lhs6C8a9WwFvrQA=="],
|
|
89
89
|
|
|
90
|
-
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.
|
|
90
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+9hIcMngJ+yGUahXqZuZ8CoWKJE9SAZsFsM3QDvXpNsLbXZ9lqVzgBhOk/jTSYkOA0GLP9eu3teukqpLUojHMg=="],
|
|
91
91
|
|
|
92
|
-
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.
|
|
92
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-jB0wAvTLI4itx5VidqVUejPQFhRUxiZ9l9FvZ26D5fl6t3qme+ZB4PD3bTSeL1vZ8NI2Rx/zj6H9zcESuGHKGw=="],
|
|
93
93
|
|
|
94
|
-
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.
|
|
94
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.0", "", { "os": "win32", "cpu": "x64" }, "sha512-VT/lF+GId+67j8aDfLkxdxNoVApsPSTbyAtB3jJq0IWTrY77WXfbPfpngxq0bA6JCEv/7k8C9qWjDRKRznDlyw=="],
|
|
95
95
|
|
|
96
96
|
"@cel-tui/clew": ["@cel-tui/clew@0.8.3", "", { "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-7OFUe8ECleXjq9+vv2EvDcTXsiWNSQqVALD1LC/Gi9DzVp1aw0S6SloJuAv1KUVkwjZxil+mvYlk2LoC28mETQ=="],
|
|
97
97
|
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
|
|
102
102
|
"@cel-tui/types": ["@cel-tui/types@0.8.3", "", { "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-yEKXCY16U/W4A4JaVysv2/x/IBEHQAfb93CzL6HugN+N15ETB3Vn8tZrQwdyrOT/9WdlCQkeBH8Vj7BJHs4Hkw=="],
|
|
103
103
|
|
|
104
|
-
"@earendil-works/pi-ai": ["@earendil-works/pi-ai@0.
|
|
104
|
+
"@earendil-works/pi-ai": ["@earendil-works/pi-ai@0.79.3", "", { "dependencies": { "@anthropic-ai/sdk": "0.91.1", "@aws-sdk/client-bedrock-runtime": "3.1048.0", "@google/genai": "1.52.0", "@mistralai/mistralai": "2.2.1", "@smithy/node-http-handler": "4.7.3", "http-proxy-agent": "7.0.2", "https-proxy-agent": "7.0.6", "openai": "6.26.0", "partial-json": "0.1.7", "typebox": "1.1.38" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-lMSput/haP5uZAGbXhS5rAYd3GB7GYdJkoAUxg3VFummBeqGqGqllaTWrbHFN12kVGyVfWHhdySNXkiqVh65Iw=="],
|
|
105
105
|
|
|
106
106
|
"@google/genai": ["@google/genai@1.52.0", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q=="],
|
|
107
107
|
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
|
|
232
232
|
"path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="],
|
|
233
233
|
|
|
234
|
-
"prettier": ["prettier@3.8.
|
|
234
|
+
"prettier": ["prettier@3.8.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q=="],
|
|
235
235
|
|
|
236
236
|
"protobufjs": ["protobufjs@7.5.6", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.1", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg=="],
|
|
237
237
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-coder",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"packageManager": "bun@1.3.
|
|
5
|
+
"packageManager": "bun@1.3.13",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mc": "bin/mc.ts"
|
|
8
8
|
},
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
"format": "bun run prettier --write *.md && bun run biome format --write . && bun run biome check --write ."
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@biomejs/biome": "^2.
|
|
17
|
+
"@biomejs/biome": "^2.5.0",
|
|
18
18
|
"@types/bun": "^1.3.14",
|
|
19
|
-
"prettier": "^3.8.
|
|
19
|
+
"prettier": "^3.8.4",
|
|
20
20
|
"typescript": "^6.0.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@cel-tui/components": "^0.8.3",
|
|
24
24
|
"@cel-tui/core": "^0.8.3",
|
|
25
|
-
"@earendil-works/pi-ai": "^0.
|
|
25
|
+
"@earendil-works/pi-ai": "^0.79.3",
|
|
26
26
|
"diff": "^9.0.0",
|
|
27
27
|
"simple-git": "^3.36.0",
|
|
28
28
|
"yaml": "^2.9.0"
|
package/src/tui.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
1
4
|
import { cel, HStack, ProcessTerminal, VStack } from "@cel-tui/core";
|
|
2
5
|
import type {
|
|
3
6
|
AssistantMessage,
|
|
@@ -42,6 +45,52 @@ function clearOrAbort(state: TUIState) {
|
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
|
|
48
|
+
async function directoryExists(path: string): Promise<boolean> {
|
|
49
|
+
try {
|
|
50
|
+
return (await stat(path)).isDirectory();
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function handleSkillSlashCommand(prompt: string) {
|
|
57
|
+
const match = prompt.trim().match(/^\/([a-zA-Z0-9_-]+)(?:\s|$)/);
|
|
58
|
+
|
|
59
|
+
if (!match) return;
|
|
60
|
+
|
|
61
|
+
const skillName = match[1];
|
|
62
|
+
const skillRoots = [
|
|
63
|
+
join(homedir(), ".agents", "skills"),
|
|
64
|
+
join(process.cwd(), ".agents", "skills"),
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
for (const root of skillRoots) {
|
|
68
|
+
if (!(await directoryExists(root))) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const glob = new Bun.Glob("*/SKILL.md");
|
|
73
|
+
|
|
74
|
+
for await (const path of glob.scan({ cwd: root, absolute: true })) {
|
|
75
|
+
const file = Bun.file(path);
|
|
76
|
+
|
|
77
|
+
if (!(await file.exists())) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const body = await file.text();
|
|
82
|
+
const frontmatter = body.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
83
|
+
const name = frontmatter?.[1]
|
|
84
|
+
.match(/^name:\s*["']?([^"'\n]+)["']?\s*$/m)?.[1]
|
|
85
|
+
?.trim();
|
|
86
|
+
|
|
87
|
+
if (name === skillName) {
|
|
88
|
+
return body;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
45
94
|
export function initTUI(state: TUIState, leave: (s: string) => void) {
|
|
46
95
|
// TODO: Cleanup accumulated sessions for this cwd.
|
|
47
96
|
const { spinnerEvery, currentSpinner } = Spinner();
|
|
@@ -84,6 +133,19 @@ export function initTUI(state: TUIState, leave: (s: string) => void) {
|
|
|
84
133
|
};
|
|
85
134
|
|
|
86
135
|
const onEditorKeyPress = (key: string) => {
|
|
136
|
+
const submit = async () => {
|
|
137
|
+
await streamAgentTUI(state);
|
|
138
|
+
};
|
|
139
|
+
const skillSubmit = async () => {
|
|
140
|
+
const skill = await handleSkillSlashCommand(state.prompt);
|
|
141
|
+
if (skill) {
|
|
142
|
+
state.streaming = true;
|
|
143
|
+
// This cause the prompt to flash the body before vanishing on submit.
|
|
144
|
+
// To avoid this I added a new state property
|
|
145
|
+
state.promptSkill = skill;
|
|
146
|
+
await streamAgentTUI(state);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
87
149
|
// onKeyPress
|
|
88
150
|
if (key === "enter") {
|
|
89
151
|
if (state.prompt === ":q") {
|
|
@@ -102,9 +164,10 @@ export function initTUI(state: TUIState, leave: (s: string) => void) {
|
|
|
102
164
|
state.stickToBottom = true;
|
|
103
165
|
return false;
|
|
104
166
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
167
|
+
if (state.prompt && state.prompt[0] === "/" && !state.streaming) {
|
|
168
|
+
skillSubmit();
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
108
171
|
if (state.prompt && !state.streaming) submit();
|
|
109
172
|
return false;
|
|
110
173
|
}
|
|
@@ -144,6 +207,8 @@ export function initTUI(state: TUIState, leave: (s: string) => void) {
|
|
|
144
207
|
}
|
|
145
208
|
|
|
146
209
|
async function streamAgentTUI(state: TUIState) {
|
|
210
|
+
// Just as a defensive thought, callers should set this ahead of time if doing other
|
|
211
|
+
// ops before starting the stream.
|
|
147
212
|
state.streaming = true;
|
|
148
213
|
|
|
149
214
|
const abortController = new AbortController();
|
|
@@ -156,6 +221,12 @@ async function streamAgentTUI(state: TUIState) {
|
|
|
156
221
|
];
|
|
157
222
|
|
|
158
223
|
let userContent = state.prompt;
|
|
224
|
+
if (state.promptSkill) {
|
|
225
|
+
// TODO: Skill arguments? replace template marks in skill body for arguments?
|
|
226
|
+
// Right now we just appead the user prompt to the skill body
|
|
227
|
+
userContent = `${state.promptSkill}\n${state.prompt}`;
|
|
228
|
+
state.promptSkill = undefined;
|
|
229
|
+
}
|
|
159
230
|
if (state.messages.length === 0) {
|
|
160
231
|
const envReminder = await injectEnvReminder();
|
|
161
232
|
userContent = `${envReminder}\n\n${userContent}`;
|