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 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.75.5",
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.4.15",
16
+ "@biomejs/biome": "^2.5.0",
17
17
  "@types/bun": "^1.3.14",
18
- "prettier": "^3.8.3",
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.4.15", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.15", "@biomejs/cli-darwin-x64": "2.4.15", "@biomejs/cli-linux-arm64": "2.4.15", "@biomejs/cli-linux-arm64-musl": "2.4.15", "@biomejs/cli-linux-x64": "2.4.15", "@biomejs/cli-linux-x64-musl": "2.4.15", "@biomejs/cli-win32-arm64": "2.4.15", "@biomejs/cli-win32-x64": "2.4.15" }, "bin": { "biome": "bin/biome" } }, "sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw=="],
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.4.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg=="],
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.4.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ=="],
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.4.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug=="],
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.4.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ=="],
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.4.15", "", { "os": "linux", "cpu": "x64" }, "sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g=="],
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.4.15", "", { "os": "linux", "cpu": "x64" }, "sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w=="],
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.4.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w=="],
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.4.15", "", { "os": "win32", "cpu": "x64" }, "sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ=="],
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.75.5", "", { "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-zf1F5kXk1pqZeFShXOqq9ibUk8QdtRoLCDPAjO+hj44e3EUs9/GFO2qnhTC5+JA2uwVCx+WCNe1PiCjlBYWm5w=="],
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.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="],
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.0",
3
+ "version": "0.7.1",
4
4
  "type": "module",
5
- "packageManager": "bun@1.3.12",
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.4.15",
17
+ "@biomejs/biome": "^2.5.0",
18
18
  "@types/bun": "^1.3.14",
19
- "prettier": "^3.8.3",
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.75.5",
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
- const submit = async () => {
106
- await streamAgentTUI(state);
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}`;
package/src/types.ts CHANGED
@@ -94,6 +94,7 @@ export type TUIMessage = {
94
94
  export type TUIState = {
95
95
  options: CliOptions;
96
96
  prompt: string;
97
+ promptSkill?: string;
97
98
  messages: Message[]; // Context messages
98
99
  tuiMessages: TUIMessage[];
99
100
  contextSize?: number;