mini-coder 0.5.1 → 0.5.2
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 +39 -40
- package/package.json +10 -11
- package/src/errors.ts +15 -0
- package/src/git.ts +43 -17
- package/src/index.ts +125 -6
- package/src/prompt.ts +7 -4
- package/src/settings.ts +66 -4
- package/src/submit.ts +4 -6
- package/src/tools.ts +3 -2
- package/src/ui/agent.ts +1 -4
- package/src/ui/commands.test.ts +3 -0
- package/src/ui/commands.ts +1 -4
- package/src/ui/conversation.test.ts +165 -1
- package/src/ui/conversation.ts +268 -36
- package/src/ui/input.test.ts +5 -1
- package/src/ui/input.ts +7 -1
- package/src/ui/status.test.ts +3 -0
- package/src/ui.ts +6 -0
- package/src/version.ts +48 -0
package/bun.lock
CHANGED
|
@@ -5,18 +5,17 @@
|
|
|
5
5
|
"": {
|
|
6
6
|
"name": "mini-coder",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@cel-tui/components": "^0.
|
|
9
|
-
"@cel-tui/core": "^0.
|
|
10
|
-
"@cel-tui/types": "^0.
|
|
11
|
-
"@mariozechner/pi-ai": "^0.
|
|
12
|
-
"diff": "^8.0.4",
|
|
8
|
+
"@cel-tui/components": "^0.6.2",
|
|
9
|
+
"@cel-tui/core": "^0.6.2",
|
|
10
|
+
"@cel-tui/types": "^0.6.2",
|
|
11
|
+
"@mariozechner/pi-ai": "^0.66.1",
|
|
13
12
|
},
|
|
14
13
|
"devDependencies": {
|
|
15
|
-
"@biomejs/biome": "^2.4.
|
|
16
|
-
"@types/bun": "
|
|
17
|
-
"lefthook": "^2.1.
|
|
18
|
-
"prettier": "^3.8.
|
|
19
|
-
"typescript": "^
|
|
14
|
+
"@biomejs/biome": "^2.4.11",
|
|
15
|
+
"@types/bun": "^1.3.12",
|
|
16
|
+
"lefthook": "^2.1.5",
|
|
17
|
+
"prettier": "^3.8.2",
|
|
18
|
+
"typescript": "^6.0.2",
|
|
20
19
|
},
|
|
21
20
|
},
|
|
22
21
|
},
|
|
@@ -91,33 +90,33 @@
|
|
|
91
90
|
|
|
92
91
|
"@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
|
|
93
92
|
|
|
94
|
-
"@biomejs/biome": ["@biomejs/biome@2.4.
|
|
93
|
+
"@biomejs/biome": ["@biomejs/biome@2.4.11", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.11", "@biomejs/cli-darwin-x64": "2.4.11", "@biomejs/cli-linux-arm64": "2.4.11", "@biomejs/cli-linux-arm64-musl": "2.4.11", "@biomejs/cli-linux-x64": "2.4.11", "@biomejs/cli-linux-x64-musl": "2.4.11", "@biomejs/cli-win32-arm64": "2.4.11", "@biomejs/cli-win32-x64": "2.4.11" }, "bin": { "biome": "bin/biome" } }, "sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA=="],
|
|
95
94
|
|
|
96
|
-
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.
|
|
95
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg=="],
|
|
97
96
|
|
|
98
|
-
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.
|
|
97
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw=="],
|
|
99
98
|
|
|
100
|
-
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.
|
|
99
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA=="],
|
|
101
100
|
|
|
102
|
-
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.
|
|
101
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q=="],
|
|
103
102
|
|
|
104
|
-
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.
|
|
103
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.11", "", { "os": "linux", "cpu": "x64" }, "sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ=="],
|
|
105
104
|
|
|
106
|
-
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.
|
|
105
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.11", "", { "os": "linux", "cpu": "x64" }, "sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA=="],
|
|
107
106
|
|
|
108
|
-
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.
|
|
107
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg=="],
|
|
109
108
|
|
|
110
|
-
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.
|
|
109
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.11", "", { "os": "win32", "cpu": "x64" }, "sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A=="],
|
|
111
110
|
|
|
112
|
-
"@cel-tui/components": ["@cel-tui/components@0.
|
|
111
|
+
"@cel-tui/components": ["@cel-tui/components@0.6.2", "", { "dependencies": { "@cel-tui/core": "0.6.2", "@cel-tui/types": "0.6.2", "lextide": "^0.1.0", "yoctomarkdown": "^0.1.0" }, "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-FYR7lX3/gPAyEkfMuyVapdxfO0e9OIw4lmdIUF2Tw7QszkpV4MAkEoB3G2oUY6UZyxJCSCKLBPvLzwu5uxaDgw=="],
|
|
113
112
|
|
|
114
|
-
"@cel-tui/core": ["@cel-tui/core@0.
|
|
113
|
+
"@cel-tui/core": ["@cel-tui/core@0.6.2", "", { "dependencies": { "@cel-tui/types": "0.6.2", "get-east-asian-width": "^1.5.0" }, "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-KJQdDMPbwLE211Hvn75jUKEvHiKTtQ7iVGJiiOpG+s4DjhnpySBXWO0hReMxe5NR2NPls7wmze1dBZ8/MXqVXA=="],
|
|
115
114
|
|
|
116
|
-
"@cel-tui/types": ["@cel-tui/types@0.
|
|
115
|
+
"@cel-tui/types": ["@cel-tui/types@0.6.2", "", { "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-JsJdo20KmgtC67QlG/ZrZyGi0xNJBKd3G6kM/yN/6/hk8a86P+1k1jqtSUjcZ4E9x1v9IXqPk6QelU7kLyOV1A=="],
|
|
117
116
|
|
|
118
117
|
"@google/genai": ["@google/genai@1.48.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-plonYK4ML2PrxsRD9SeqmFt76eREWkQdPCglOA6aYDzL1AAbE+7PUnT54SvpWGfws13L0AZEqGSpL7+1IPnTxQ=="],
|
|
119
118
|
|
|
120
|
-
"@mariozechner/pi-ai": ["@mariozechner/pi-ai@0.
|
|
119
|
+
"@mariozechner/pi-ai": ["@mariozechner/pi-ai@0.66.1", "", { "dependencies": { "@anthropic-ai/sdk": "^0.73.0", "@aws-sdk/client-bedrock-runtime": "^3.983.0", "@google/genai": "^1.40.0", "@mistralai/mistralai": "1.14.1", "@sinclair/typebox": "^0.34.41", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "chalk": "^5.6.2", "openai": "6.26.0", "partial-json": "^0.1.7", "proxy-agent": "^6.5.0", "undici": "^7.19.1", "zod-to-json-schema": "^3.24.6" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-7IZHvpsFdKEBkTmjNrdVL7JLUJVIpha6bwTr12cZ5XyDrxij06wP6Ncpnf4HT5BXAzD5w2JnoqTOSbMEIZj3dg=="],
|
|
121
120
|
|
|
122
121
|
"@mistralai/mistralai": ["@mistralai/mistralai@1.14.1", "", { "dependencies": { "ws": "^8.18.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.1" } }, "sha512-IiLmmZFCCTReQgPAT33r7KQ1nYo5JPdvGkrkZqA8qQ2qB1GHgs5LoP5K2ICyrjnpw2n8oSxMM/VP+liiKcGNlQ=="],
|
|
123
122
|
|
|
@@ -233,7 +232,7 @@
|
|
|
233
232
|
|
|
234
233
|
"@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
|
|
235
234
|
|
|
236
|
-
"@types/bun": ["@types/bun@1.3.
|
|
235
|
+
"@types/bun": ["@types/bun@1.3.12", "", { "dependencies": { "bun-types": "1.3.12" } }, "sha512-DBv81elK+/VSwXHDlnH3Qduw+KxkTIWi7TXkAeh24zpi5l0B2kUg9Ga3tb4nJaPcOFswflgi/yAvMVBPrxMB+A=="],
|
|
237
236
|
|
|
238
237
|
"@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="],
|
|
239
238
|
|
|
@@ -259,7 +258,7 @@
|
|
|
259
258
|
|
|
260
259
|
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
|
261
260
|
|
|
262
|
-
"bun-types": ["bun-types@1.3.
|
|
261
|
+
"bun-types": ["bun-types@1.3.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-HqOLj5PoFajAQciOMRiIZGNoKxDJSr6qigAttOX40vJuSp6DN/CxWp9s3C1Xwm4oH7ybueITwiaOcWXoYVoRkA=="],
|
|
263
262
|
|
|
264
263
|
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
|
265
264
|
|
|
@@ -269,8 +268,6 @@
|
|
|
269
268
|
|
|
270
269
|
"degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="],
|
|
271
270
|
|
|
272
|
-
"diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="],
|
|
273
|
-
|
|
274
271
|
"ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
|
|
275
272
|
|
|
276
273
|
"escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
|
|
@@ -323,27 +320,29 @@
|
|
|
323
320
|
|
|
324
321
|
"jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
|
|
325
322
|
|
|
326
|
-
"lefthook": ["lefthook@2.1.
|
|
323
|
+
"lefthook": ["lefthook@2.1.5", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.5", "lefthook-darwin-x64": "2.1.5", "lefthook-freebsd-arm64": "2.1.5", "lefthook-freebsd-x64": "2.1.5", "lefthook-linux-arm64": "2.1.5", "lefthook-linux-x64": "2.1.5", "lefthook-openbsd-arm64": "2.1.5", "lefthook-openbsd-x64": "2.1.5", "lefthook-windows-arm64": "2.1.5", "lefthook-windows-x64": "2.1.5" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-yB9IFWurFllusbPZqvG0EavTmpNXPya2MuO7Li7YT78xAj3uCQ3AgmW9TVUbTTsSMhsegbiAMRpwfEk2TP1P0A=="],
|
|
324
|
+
|
|
325
|
+
"lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VITTaw8PxxyE26gkZ8UcwIa5ZrWnKNRGLeeSrqri40cQdXvLTEoMq2tjjw7eiL9UcB0waRReDdzydevy9GOPUQ=="],
|
|
327
326
|
|
|
328
|
-
"lefthook-darwin-
|
|
327
|
+
"lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-AvtjYiW0BSGHBGrdvL313seUymrW9FxI+6JJwJ+ZSaa2sH81etrTB0wAwlH1L9VfFwK9+gWvatZBvLfF3L4fPw=="],
|
|
329
328
|
|
|
330
|
-
"lefthook-
|
|
329
|
+
"lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-mXjJwe8jKGWGiBYUxfQY1ab3Nn5NhafqT9q3KJz8m5joGGQj4JD0cbWxF1nVBLBWsDGbWZRZunTCMGcIScT2bQ=="],
|
|
331
330
|
|
|
332
|
-
"lefthook-freebsd-
|
|
331
|
+
"lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-exD69dCjc1K45BxatDPGoH4NmEvgLKPm4kJLOWn1fTeHRKZwWiFPwnjknEoG2OemlCDHmCU++5X40kMEG0WBlA=="],
|
|
333
332
|
|
|
334
|
-
"lefthook-
|
|
333
|
+
"lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-57TDKC5ewWpsCLZQKIJMHumFEObYKVundmPpiWhX491hINRZYYOL/26yrnVnNcidThRzTiTC+HLcuplLcaXtbA=="],
|
|
335
334
|
|
|
336
|
-
"lefthook-linux-
|
|
335
|
+
"lefthook-linux-x64": ["lefthook-linux-x64@2.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-bqK3LrAB5l5YaCaoHk6qRWlITrGWzP4FbwRxA31elbxjd0wgNWZ2Sn3zEfSEcxz442g7/PPkEwqqsTx0kSFzpg=="],
|
|
337
336
|
|
|
338
|
-
"lefthook-
|
|
337
|
+
"lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-5aSwK7vV3A6t0w9PnxCMiVjQlcvopBP50BtmnnLnNJyAYHnFbZ0Baq5M0WkE9IsUkWSux0fe6fd0jDkuG711MA=="],
|
|
339
338
|
|
|
340
|
-
"lefthook-openbsd-
|
|
339
|
+
"lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-Y+pPdDuENJ8qWnUgL02xxhpjblc0WnwXvWGfqnl3WZrAgHzQpwx3G6469RID/wlNVdHYAlw3a8UkFSMYsTzXvA=="],
|
|
341
340
|
|
|
342
|
-
"lefthook-
|
|
341
|
+
"lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-2PlcFBjTzJaMufw0c28kfhB/0zmaRCU0TRPPsil/HU2YNOExod4upPGLk9qjgsOmb2YVWFz6zq6u7+D1yqmzTQ=="],
|
|
343
342
|
|
|
344
|
-
"lefthook-windows-
|
|
343
|
+
"lefthook-windows-x64": ["lefthook-windows-x64@2.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-yiAh8qxml6uqy10jDxOdN9fOQpyLxBFY1fgCEAhn7sVJYmJKRhjqSBwZX6LG5MQjzr29KStrIdw7TR3lf3rT7Q=="],
|
|
345
344
|
|
|
346
|
-
"
|
|
345
|
+
"lextide": ["lextide@0.1.0", "", {}, "sha512-i1fx9SzultDOIgVtFt/vBOeyFaGYCNLT6OcdqOLRfWL9p6aTQsq8JQ+8LpJ4T7znWNjfjLqUU6dK5g2kXhSq3A=="],
|
|
347
346
|
|
|
348
347
|
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
|
349
348
|
|
|
@@ -369,7 +368,7 @@
|
|
|
369
368
|
|
|
370
369
|
"path-expression-matcher": ["path-expression-matcher@1.2.1", "", {}, "sha512-d7gQQmLvAKXKXE2GeP9apIGbMYKz88zWdsn/BN2HRWVQsDFdUY36WSLTY0Jvd4HWi7Fb30gQ62oAOzdgJA6fZw=="],
|
|
371
370
|
|
|
372
|
-
"prettier": ["prettier@3.8.
|
|
371
|
+
"prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="],
|
|
373
372
|
|
|
374
373
|
"protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
|
|
375
374
|
|
|
@@ -401,7 +400,7 @@
|
|
|
401
400
|
|
|
402
401
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
403
402
|
|
|
404
|
-
"typescript": ["typescript@
|
|
403
|
+
"typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
|
|
405
404
|
|
|
406
405
|
"undici": ["undici@7.24.7", "", {}, "sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ=="],
|
|
407
406
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-coder",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "A small, fast CLI coding agent",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -18,18 +18,17 @@
|
|
|
18
18
|
"test": "bun test"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@cel-tui/components": "^0.
|
|
22
|
-
"@cel-tui/core": "^0.
|
|
23
|
-
"@cel-tui/types": "^0.
|
|
24
|
-
"@mariozechner/pi-ai": "^0.
|
|
25
|
-
"diff": "^8.0.4"
|
|
21
|
+
"@cel-tui/components": "^0.6.2",
|
|
22
|
+
"@cel-tui/core": "^0.6.2",
|
|
23
|
+
"@cel-tui/types": "^0.6.2",
|
|
24
|
+
"@mariozechner/pi-ai": "^0.66.1"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
28
|
-
"@biomejs/biome": "^2.4.
|
|
29
|
-
"@types/bun": "
|
|
30
|
-
"lefthook": "^2.1.
|
|
31
|
-
"prettier": "^3.8.
|
|
32
|
-
"typescript": "^
|
|
27
|
+
"@biomejs/biome": "^2.4.11",
|
|
28
|
+
"@types/bun": "^1.3.12",
|
|
29
|
+
"lefthook": "^2.1.5",
|
|
30
|
+
"prettier": "^3.8.2",
|
|
31
|
+
"typescript": "^6.0.2"
|
|
33
32
|
},
|
|
34
33
|
"license": "MIT"
|
|
35
34
|
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared error-formatting helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Convert an unknown thrown value into a readable message string.
|
|
9
|
+
*
|
|
10
|
+
* @param error - The thrown value to format.
|
|
11
|
+
* @returns The error message when available, otherwise the stringified value.
|
|
12
|
+
*/
|
|
13
|
+
export function getErrorMessage(error: unknown): string {
|
|
14
|
+
return error instanceof Error ? error.message : String(error);
|
|
15
|
+
}
|
package/src/git.ts
CHANGED
|
@@ -83,7 +83,7 @@ function hasTrackedChange(status: string): boolean {
|
|
|
83
83
|
* @param output - Raw `git status --porcelain` output.
|
|
84
84
|
* @returns Counts of staged, modified, and untracked files.
|
|
85
85
|
*/
|
|
86
|
-
function
|
|
86
|
+
export function parseGitStatus(output: string): {
|
|
87
87
|
staged: number;
|
|
88
88
|
modified: number;
|
|
89
89
|
untracked: number;
|
|
@@ -117,6 +117,26 @@ function parseStatus(output: string): {
|
|
|
117
117
|
return { staged, modified, untracked };
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Parse `git rev-list --left-right --count HEAD...@{upstream}` output.
|
|
122
|
+
*
|
|
123
|
+
* The command returns two whitespace-separated integers: ahead then behind.
|
|
124
|
+
* Invalid or missing values are treated as `0`.
|
|
125
|
+
*
|
|
126
|
+
* @param output - Raw `git rev-list --left-right --count` output.
|
|
127
|
+
* @returns Parsed ahead and behind counts.
|
|
128
|
+
*/
|
|
129
|
+
export function parseGitAheadBehind(output: string): {
|
|
130
|
+
ahead: number;
|
|
131
|
+
behind: number;
|
|
132
|
+
} {
|
|
133
|
+
const parts = output.trim().split(/\s+/);
|
|
134
|
+
return {
|
|
135
|
+
ahead: parseInt(parts[0] ?? "0", 10) || 0,
|
|
136
|
+
behind: parseInt(parts[1] ?? "0", 10) || 0,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
120
140
|
// ---------------------------------------------------------------------------
|
|
121
141
|
// Public API
|
|
122
142
|
// ---------------------------------------------------------------------------
|
|
@@ -129,34 +149,40 @@ function parseStatus(output: string): {
|
|
|
129
149
|
* is not inside a git repository.
|
|
130
150
|
*
|
|
131
151
|
* @param cwd - The directory to query (can be a subdirectory of the repo).
|
|
152
|
+
* @param opts - Optional runtime overrides used by tests.
|
|
132
153
|
* @returns A {@link GitState} snapshot, or `null` if not in a git repo.
|
|
133
154
|
*/
|
|
134
|
-
export async function getGitState(
|
|
155
|
+
export async function getGitState(
|
|
156
|
+
cwd: string,
|
|
157
|
+
opts?: {
|
|
158
|
+
run?: (
|
|
159
|
+
args: string[],
|
|
160
|
+
cwd: string,
|
|
161
|
+
trim?: boolean,
|
|
162
|
+
) => Promise<string | null>;
|
|
163
|
+
},
|
|
164
|
+
): Promise<GitState | null> {
|
|
165
|
+
const exec = opts?.run ?? run;
|
|
166
|
+
|
|
135
167
|
// Check if we're in a repo and get the root
|
|
136
|
-
const root = await
|
|
168
|
+
const root = await exec(["rev-parse", "--show-toplevel"], cwd);
|
|
137
169
|
if (root === null) return null;
|
|
138
170
|
|
|
139
171
|
// Run remaining commands in parallel
|
|
140
172
|
const [branch, upstream, status, revList] = await Promise.all([
|
|
141
|
-
|
|
142
|
-
|
|
173
|
+
exec(["branch", "--show-current"], cwd),
|
|
174
|
+
exec(
|
|
143
175
|
["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"],
|
|
144
176
|
cwd,
|
|
145
177
|
),
|
|
146
|
-
|
|
147
|
-
|
|
178
|
+
exec(["status", "--porcelain"], cwd, false),
|
|
179
|
+
exec(["rev-list", "--left-right", "--count", "HEAD...@{upstream}"], cwd),
|
|
148
180
|
]);
|
|
149
181
|
|
|
150
|
-
const { staged, modified, untracked } =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
let behind = 0;
|
|
155
|
-
if (revList) {
|
|
156
|
-
const parts = revList.split(/\s+/);
|
|
157
|
-
ahead = parseInt(parts[0] ?? "0", 10) || 0;
|
|
158
|
-
behind = parseInt(parts[1] ?? "0", 10) || 0;
|
|
159
|
-
}
|
|
182
|
+
const { staged, modified, untracked } = parseGitStatus(status ?? "");
|
|
183
|
+
const { ahead, behind } = revList
|
|
184
|
+
? parseGitAheadBehind(revList)
|
|
185
|
+
: { ahead: 0, behind: 0 };
|
|
160
186
|
|
|
161
187
|
return {
|
|
162
188
|
root,
|
package/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
resolveHeadlessPrompt,
|
|
29
29
|
shouldUseHeadlessMode,
|
|
30
30
|
} from "./cli.ts";
|
|
31
|
+
import { getErrorMessage } from "./errors.ts";
|
|
31
32
|
import { type GitState, getGitState } from "./git.ts";
|
|
32
33
|
import { canonicalizePath } from "./paths.ts";
|
|
33
34
|
import {
|
|
@@ -56,6 +57,7 @@ import {
|
|
|
56
57
|
truncateSessions,
|
|
57
58
|
} from "./session.ts";
|
|
58
59
|
import {
|
|
60
|
+
type CustomProvider,
|
|
59
61
|
loadSettings,
|
|
60
62
|
resolveStartupSettings,
|
|
61
63
|
type UserSettings,
|
|
@@ -70,6 +72,7 @@ import {
|
|
|
70
72
|
readImageTool,
|
|
71
73
|
shellTool,
|
|
72
74
|
} from "./tools.ts";
|
|
75
|
+
import { resolveAppVersionLabel } from "./version.ts";
|
|
73
76
|
|
|
74
77
|
// ---------------------------------------------------------------------------
|
|
75
78
|
// Constants
|
|
@@ -98,10 +101,6 @@ export const MAX_SESSIONS_PER_CWD = 20;
|
|
|
98
101
|
/** Maximum raw prompt-history entries to retain globally. */
|
|
99
102
|
export const MAX_PROMPT_HISTORY = 1_000;
|
|
100
103
|
|
|
101
|
-
function getErrorMessage(error: unknown): string {
|
|
102
|
-
return error instanceof Error ? error.message : String(error);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
104
|
// ---------------------------------------------------------------------------
|
|
106
105
|
// OAuth credential persistence
|
|
107
106
|
// ---------------------------------------------------------------------------
|
|
@@ -211,6 +210,101 @@ async function discoverProviders(): Promise<DiscoveryResult> {
|
|
|
211
210
|
return { providers, oauthCredentials };
|
|
212
211
|
}
|
|
213
212
|
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// Custom provider discovery
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
/** Timeout for custom provider model discovery requests. */
|
|
218
|
+
const CUSTOM_PROVIDER_TIMEOUT_MS = 3_000;
|
|
219
|
+
|
|
220
|
+
/** Default API key for custom providers that don't require authentication. */
|
|
221
|
+
const CUSTOM_PROVIDER_DEFAULT_KEY = "no-key";
|
|
222
|
+
|
|
223
|
+
/** Result of custom provider discovery. */
|
|
224
|
+
interface CustomDiscoveryResult {
|
|
225
|
+
/** Discovered models from all reachable custom providers. */
|
|
226
|
+
models: Model<"openai-completions">[];
|
|
227
|
+
/** Provider name → API key for discovered providers. */
|
|
228
|
+
providers: Map<string, string>;
|
|
229
|
+
/** Warning messages for unreachable or invalid providers. */
|
|
230
|
+
warnings: string[];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Discover models from user-configured OpenAI-compatible endpoints.
|
|
235
|
+
*
|
|
236
|
+
* Queries each provider's `/models` endpoint and constructs pi-ai Model
|
|
237
|
+
* objects from the response. Unreachable endpoints produce a warning
|
|
238
|
+
* instead of failing startup.
|
|
239
|
+
*
|
|
240
|
+
* @param customProviders - Configured custom provider entries.
|
|
241
|
+
* @param builtInProviderNames - Names of built-in providers (to detect collisions).
|
|
242
|
+
* @returns Discovered models, provider credentials, and warnings.
|
|
243
|
+
*/
|
|
244
|
+
export async function discoverCustomProviders(
|
|
245
|
+
customProviders: readonly CustomProvider[],
|
|
246
|
+
builtInProviderNames: ReadonlySet<string>,
|
|
247
|
+
): Promise<CustomDiscoveryResult> {
|
|
248
|
+
const models: Model<"openai-completions">[] = [];
|
|
249
|
+
const providers = new Map<string, string>();
|
|
250
|
+
const warnings: string[] = [];
|
|
251
|
+
|
|
252
|
+
for (const entry of customProviders) {
|
|
253
|
+
if (builtInProviderNames.has(entry.name)) {
|
|
254
|
+
warnings.push(
|
|
255
|
+
`Custom provider "${entry.name}" skipped: name conflicts with a built-in provider.`,
|
|
256
|
+
);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const apiKey = entry.apiKey ?? CUSTOM_PROVIDER_DEFAULT_KEY;
|
|
261
|
+
const modelsUrl = `${entry.baseUrl}/models`;
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
const response = await fetch(modelsUrl, {
|
|
265
|
+
signal: AbortSignal.timeout(CUSTOM_PROVIDER_TIMEOUT_MS),
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (!response.ok) {
|
|
269
|
+
warnings.push(
|
|
270
|
+
`Custom provider "${entry.name}": ${response.status} ${response.statusText} (${modelsUrl})`,
|
|
271
|
+
);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const body = (await response.json()) as {
|
|
276
|
+
data?: { id: string }[];
|
|
277
|
+
};
|
|
278
|
+
const modelList = body.data ?? [];
|
|
279
|
+
|
|
280
|
+
for (const item of modelList) {
|
|
281
|
+
if (typeof item.id !== "string" || !item.id) continue;
|
|
282
|
+
|
|
283
|
+
models.push({
|
|
284
|
+
id: item.id,
|
|
285
|
+
name: item.id,
|
|
286
|
+
api: "openai-completions",
|
|
287
|
+
provider: entry.name,
|
|
288
|
+
baseUrl: entry.baseUrl,
|
|
289
|
+
reasoning: false,
|
|
290
|
+
input: ["text"],
|
|
291
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
292
|
+
contextWindow: 131072,
|
|
293
|
+
maxTokens: 8192,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
providers.set(entry.name, apiKey);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
warnings.push(
|
|
300
|
+
`Custom provider "${entry.name}": ${getErrorMessage(error)} (${modelsUrl})`,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return { models, providers, warnings };
|
|
306
|
+
}
|
|
307
|
+
|
|
214
308
|
// ---------------------------------------------------------------------------
|
|
215
309
|
// Model selection
|
|
216
310
|
// ---------------------------------------------------------------------------
|
|
@@ -440,8 +534,12 @@ export interface AppState {
|
|
|
440
534
|
plugins: LoadedPlugin[];
|
|
441
535
|
/** Active theme (default + plugin overrides). */
|
|
442
536
|
theme: Theme;
|
|
537
|
+
/** Version label shown in the empty conversation banner. */
|
|
538
|
+
versionLabel: string;
|
|
443
539
|
/** Current git state (null if not in a repo). */
|
|
444
540
|
git: GitState | null;
|
|
541
|
+
/** Optional git state loader override used by tests. */
|
|
542
|
+
loadGitState?: (cwd: string) => Promise<GitState | null>;
|
|
445
543
|
/** Available provider credentials (provider → API key). */
|
|
446
544
|
providers: Map<string, string>;
|
|
447
545
|
/** OAuth credentials on disk. */
|
|
@@ -464,6 +562,10 @@ export interface AppState {
|
|
|
464
562
|
showReasoning: boolean;
|
|
465
563
|
/** Whether to show full (un-truncated) tool output. */
|
|
466
564
|
verbose: boolean;
|
|
565
|
+
/** Models discovered from custom OpenAI-compatible providers. */
|
|
566
|
+
customModels: Model<string>[];
|
|
567
|
+
/** Warnings from startup (e.g. unreachable custom providers). */
|
|
568
|
+
startupWarnings: string[];
|
|
467
569
|
}
|
|
468
570
|
|
|
469
571
|
// ---------------------------------------------------------------------------
|
|
@@ -482,7 +584,21 @@ export async function init(): Promise<AppState> {
|
|
|
482
584
|
|
|
483
585
|
// Load user settings and resolve startup defaults
|
|
484
586
|
const settings = loadSettings(SETTINGS_PATH);
|
|
485
|
-
|
|
587
|
+
|
|
588
|
+
// Discover custom providers from settings
|
|
589
|
+
const builtInProviderNames = new Set(providers.keys());
|
|
590
|
+
const customResult = await discoverCustomProviders(
|
|
591
|
+
settings.customProviders ?? [],
|
|
592
|
+
builtInProviderNames,
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
// Merge custom provider credentials
|
|
596
|
+
for (const [name, key] of customResult.providers) {
|
|
597
|
+
providers.set(name, key);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const builtInModels = listAvailableModels(providers);
|
|
601
|
+
const availableModels = [...builtInModels, ...customResult.models];
|
|
486
602
|
const startup = resolveStartupSettings(
|
|
487
603
|
settings,
|
|
488
604
|
availableModels.map((model) => `${model.provider}/${model.id}`),
|
|
@@ -509,6 +625,7 @@ export async function init(): Promise<AppState> {
|
|
|
509
625
|
skills: promptContext.skills,
|
|
510
626
|
plugins: promptContext.plugins,
|
|
511
627
|
theme: promptContext.theme,
|
|
628
|
+
versionLabel: resolveAppVersionLabel(),
|
|
512
629
|
git: promptContext.git,
|
|
513
630
|
providers,
|
|
514
631
|
oauthCredentials,
|
|
@@ -521,6 +638,8 @@ export async function init(): Promise<AppState> {
|
|
|
521
638
|
activeTurnPromise: null,
|
|
522
639
|
showReasoning: startup.showReasoning,
|
|
523
640
|
verbose: startup.verbose,
|
|
641
|
+
customModels: customResult.models,
|
|
642
|
+
startupWarnings: customResult.warnings,
|
|
524
643
|
};
|
|
525
644
|
}
|
|
526
645
|
|
|
@@ -593,7 +712,7 @@ export function ensureSession(
|
|
|
593
712
|
* for, suitable for the `/model` selector.
|
|
594
713
|
*/
|
|
595
714
|
export function getAvailableModels(state: AppState): Model<string>[] {
|
|
596
|
-
return listAvailableModels(state.providers);
|
|
715
|
+
return [...listAvailableModels(state.providers), ...state.customModels];
|
|
597
716
|
}
|
|
598
717
|
|
|
599
718
|
/** Clean up resources on shutdown. */
|
package/src/prompt.ts
CHANGED
|
@@ -192,14 +192,14 @@ const BASE_INSTRUCTIONS = `You are mini-coder, a coding agent running in the use
|
|
|
192
192
|
|
|
193
193
|
# Role
|
|
194
194
|
|
|
195
|
-
You are an autonomous, senior-level coding assistant. When the user gives a direction, proactively gather context, plan with the user, implement, and verify. Bias toward action:
|
|
195
|
+
You are an autonomous, senior-level coding assistant. When the user gives a direction, proactively gather context, plan with the user, implement, and verify. Bias toward action: plan briefly when needed to clear important assumptions, then continue into implementation. First identify the task contract: required files, names, interfaces, output format, and checks for success. Treat those details as part of correctness, not as polish. Deliver working code, unless you are genuinely blocked.
|
|
196
196
|
|
|
197
197
|
# Tools
|
|
198
198
|
|
|
199
199
|
You have these core tools:
|
|
200
200
|
|
|
201
|
-
- \`shell\` — run commands in the user's shell. Use this to explore the codebase
|
|
202
|
-
- \`edit\` — make exact-text replacements in files. Provide the file path, the exact text to find, and the replacement text. The old text must match exactly one location in the file. To create a new file, use an empty old text and the full file content as new text.
|
|
201
|
+
- \`shell\` — run commands in the user's shell. Use this to explore the codebase, read tests/verifiers/examples, inspect required outputs, and run targeted checks, builds, or git commands. Prefer \`rg\` over \`grep\` for speed.
|
|
202
|
+
- \`edit\` — make exact-text replacements in files. Provide the file path, the exact text to find, and the replacement text. The old text must match exactly one location in the file. To create a new file, use an empty old text and the full file content as new text. Use this to write the exact final file content the task requires.
|
|
203
203
|
|
|
204
204
|
You may also have additional tools provided by plugins. Use them when they match the task.
|
|
205
205
|
|
|
@@ -208,7 +208,7 @@ Workflow: **inspect with shell → mutate with edit → verify with shell**.
|
|
|
208
208
|
# Code quality
|
|
209
209
|
|
|
210
210
|
- Conform to the codebase's existing conventions: patterns, naming, formatting, language idioms.
|
|
211
|
-
- Write correct, clear, minimal code. Don't over-engineer, don't add abstractions for hypothetical futures.
|
|
211
|
+
- Write correct, clear, minimal code. Prefer the simplest solution that satisfies the task's checks exactly. Don't over-engineer, don't add abstractions for hypothetical futures.
|
|
212
212
|
- Reuse before creating. Search for existing helpers before writing new ones.
|
|
213
213
|
- Tight error handling: no broad try/catch, no silent failures, no swallowed errors.
|
|
214
214
|
- Keep type safety. Avoid \`any\` casts. Use proper types and guards.
|
|
@@ -224,6 +224,7 @@ Workflow: **inspect with shell → mutate with edit → verify with shell**.
|
|
|
224
224
|
# Exploring the codebase
|
|
225
225
|
|
|
226
226
|
- Think first: before any tool call, decide all files and information you need.
|
|
227
|
+
- Early in the task, look for acceptance criteria in tests, verifier scripts, eval scripts, examples, and expected-output files. Do not rely on the task text alone when machine-checkable criteria are available.
|
|
227
228
|
- Batch reads: if you need multiple files, read them together in parallel rather than one at a time.
|
|
228
229
|
- Only make sequential calls when a later call genuinely depends on an earlier result.
|
|
229
230
|
|
|
@@ -238,7 +239,9 @@ Workflow: **inspect with shell → mutate with edit → verify with shell**.
|
|
|
238
239
|
# Persistence
|
|
239
240
|
|
|
240
241
|
- Carry work through to completion within the current turn. Don't stop at analysis or partial fixes.
|
|
242
|
+
- Once the contract is clear, create the required artifact early, then iterate and improve it. Do not spend most of the turn exploring.
|
|
241
243
|
- If you encounter an error, diagnose and fix it rather than reporting it and stopping.
|
|
244
|
+
- Before concluding, run the smallest targeted verification that checks the exact contract: required files exist, names and signatures match, outputs are in the required format, and no forbidden extra artifacts were left behind.
|
|
242
245
|
- Avoid excessive looping: if you're re-reading or re-editing the same files without progress, stop and ask the user.`;
|
|
243
246
|
|
|
244
247
|
// ---------------------------------------------------------------------------
|