@heyamiko/amiko-cli 0.4.10 → 0.4.11

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
@@ -19,6 +19,7 @@
19
19
  "@types/react-dom": "^18.2.0",
20
20
  "tsx": "^4.7.0",
21
21
  "typescript": "^5.4.0",
22
+ "vitest": "^4.1.3",
22
23
  },
23
24
  },
24
25
  },
@@ -97,6 +98,12 @@
97
98
 
98
99
  "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="],
99
100
 
101
+ "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="],
102
+
103
+ "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="],
104
+
105
+ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
106
+
100
107
  "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="],
101
108
 
102
109
  "@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="],
@@ -153,6 +160,8 @@
153
160
 
154
161
  "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "5.1.2", "string-width-cjs": "npm:string-width@4.2.3", "strip-ansi": "7.1.2", "strip-ansi-cjs": "npm:strip-ansi@6.0.1", "wrap-ansi": "8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
155
162
 
163
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
164
+
156
165
  "@mariozechner/pi-agent-core": ["@mariozechner/pi-agent-core@0.50.1", "", { "dependencies": { "@mariozechner/pi-ai": "0.50.1", "@mariozechner/pi-tui": "0.50.1" } }, "sha512-rW/CwANMGjqXcDvOT09ljHeNxfPHp/1hWamJrk9JamzkqVS+UHrFTJdc5qPv+O0naNDRUGBr6woer22C6F8BOA=="],
157
166
 
158
167
  "@mariozechner/pi-ai": ["@mariozechner/pi-ai@0.50.1", "", { "dependencies": { "@anthropic-ai/sdk": "0.71.2", "@aws-sdk/client-bedrock-runtime": "3.975.0", "@google/genai": "1.34.0", "@mistralai/mistralai": "1.10.0", "@sinclair/typebox": "0.34.48", "ajv": "8.17.1", "ajv-formats": "3.0.1", "chalk": "5.6.2", "openai": "6.10.0", "partial-json": "0.1.7", "proxy-agent": "6.5.0", "undici": "7.19.2", "zod-to-json-schema": "3.25.1" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-t8qUHHqz3tgK4r3f/msRKK2QbhvlDjBCjOJlTn7iJDwVAWABO8EYwf0BzkB0RGrGkiIOKhDwEVbB4jD3VxaKnA=="],
@@ -161,8 +170,44 @@
161
170
 
162
171
  "@mistralai/mistralai": ["@mistralai/mistralai@1.10.0", "", { "dependencies": { "zod": "3.25.76", "zod-to-json-schema": "3.25.1" } }, "sha512-tdIgWs4Le8vpvPiUEWne6tK0qbVc+jMenujnvTqOjogrJUsCSQhus0tHTU1avDDh5//Rq2dFgP9mWRAdIEoBqg=="],
163
172
 
173
+ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="],
174
+
175
+ "@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="],
176
+
164
177
  "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
165
178
 
179
+ "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.13", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g=="],
180
+
181
+ "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA=="],
182
+
183
+ "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug=="],
184
+
185
+ "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.13", "", { "os": "freebsd", "cpu": "x64" }, "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA=="],
186
+
187
+ "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm" }, "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw=="],
188
+
189
+ "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg=="],
190
+
191
+ "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA=="],
192
+
193
+ "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ=="],
194
+
195
+ "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "s390x" }, "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg=="],
196
+
197
+ "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA=="],
198
+
199
+ "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w=="],
200
+
201
+ "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.13", "", { "os": "none", "cpu": "arm64" }, "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w=="],
202
+
203
+ "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.13", "", { "dependencies": { "@emnapi/core": "1.9.1", "@emnapi/runtime": "1.9.1", "@napi-rs/wasm-runtime": "^1.1.2" }, "cpu": "none" }, "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g=="],
204
+
205
+ "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ=="],
206
+
207
+ "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "x64" }, "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ=="],
208
+
209
+ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.13", "", {}, "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA=="],
210
+
166
211
  "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
167
212
 
168
213
  "@smithy/abort-controller": ["@smithy/abort-controller@4.2.8", "", { "dependencies": { "@smithy/types": "4.12.0", "tslib": "2.8.1" } }, "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw=="],
@@ -255,8 +300,18 @@
255
300
 
256
301
  "@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
257
302
 
303
+ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
304
+
258
305
  "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
259
306
 
307
+ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
308
+
309
+ "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="],
310
+
311
+ "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="],
312
+
313
+ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
314
+
260
315
  "@types/mime-types": ["@types/mime-types@2.1.4", "", {}, "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w=="],
261
316
 
262
317
  "@types/node": ["@types/node@20.19.30", "", { "dependencies": { "undici-types": "6.21.0" } }, "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g=="],
@@ -267,6 +322,20 @@
267
322
 
268
323
  "@types/react-dom": ["@types/react-dom@18.3.7", "", { "peerDependencies": { "@types/react": "18.3.27" } }, "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ=="],
269
324
 
325
+ "@vitest/expect": ["@vitest/expect@4.1.3", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.3", "@vitest/utils": "4.1.3", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-CW8Q9KMtXDGHj0vCsqui0M5KqRsu0zm0GNDW7Gd3U7nZ2RFpPKSCpeCXoT+/+5zr1TNlsoQRDEz+LzZUyq6gnQ=="],
326
+
327
+ "@vitest/mocker": ["@vitest/mocker@4.1.3", "", { "dependencies": { "@vitest/spy": "4.1.3", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-XN3TrycitDQSzGRnec/YWgoofkYRhouyVQj4YNsJ5r/STCUFqMrP4+oxEv3e7ZbLi4og5kIHrZwekDJgw6hcjw=="],
328
+
329
+ "@vitest/pretty-format": ["@vitest/pretty-format@4.1.3", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-hYqqwuMbpkkBodpRh4k4cQSOELxXky1NfMmQvOfKvV8zQHz8x8Dla+2wzElkMkBvSAJX5TRGHJAQvK0TcOafwg=="],
330
+
331
+ "@vitest/runner": ["@vitest/runner@4.1.3", "", { "dependencies": { "@vitest/utils": "4.1.3", "pathe": "^2.0.3" } }, "sha512-VwgOz5MmT0KhlUj40h02LWDpUBVpflZ/b7xZFA25F29AJzIrE+SMuwzFf0b7t4EXdwRNX61C3B6auIXQTR3ttA=="],
332
+
333
+ "@vitest/snapshot": ["@vitest/snapshot@4.1.3", "", { "dependencies": { "@vitest/pretty-format": "4.1.3", "@vitest/utils": "4.1.3", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-9l+k/J9KG5wPJDX9BcFFzhhwNjwkRb8RsnYhaT1vPY7OufxmQFc9sZzScRCPTiETzl37mrIWVY9zxzmdVeJwDQ=="],
334
+
335
+ "@vitest/spy": ["@vitest/spy@4.1.3", "", {}, "sha512-ujj5Uwxagg4XUIfAUyRQxAg631BP6e9joRiN99mr48Bg9fRs+5mdUElhOoZ6rP5mBr8Bs3lmrREnkrQWkrsTCw=="],
336
+
337
+ "@vitest/utils": ["@vitest/utils@4.1.3", "", { "dependencies": { "@vitest/pretty-format": "4.1.3", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-Pc/Oexse/khOWsGB+w3q4yzA4te7W4gpZZAvk+fr8qXfTURZUMj5i7kuxsNK5mP/dEB6ao3jfr0rs17fHhbHdw=="],
338
+
270
339
  "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
271
340
 
272
341
  "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "3.1.3", "fast-uri": "3.1.0", "json-schema-traverse": "1.0.0", "require-from-string": "2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
@@ -281,6 +350,8 @@
281
350
 
282
351
  "arr-rotate": ["arr-rotate@1.0.0", "", {}, "sha512-yOzOZcR9Tn7enTF66bqKorGGH0F36vcPaSWg8fO0c0UYb3LX3VMXj5ZxEqQLNOecAhlRJ7wYZja5i4jTlnbIfQ=="],
283
352
 
353
+ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
354
+
284
355
  "ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="],
285
356
 
286
357
  "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="],
@@ -299,6 +370,8 @@
299
370
 
300
371
  "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
301
372
 
373
+ "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="],
374
+
302
375
  "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
303
376
 
304
377
  "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
@@ -315,6 +388,8 @@
315
388
 
316
389
  "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
317
390
 
391
+ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
392
+
318
393
  "convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
319
394
 
320
395
  "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "3.1.1", "shebang-command": "2.0.0", "which": "2.0.2" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
@@ -327,12 +402,16 @@
327
402
 
328
403
  "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=="],
329
404
 
405
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
406
+
330
407
  "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
331
408
 
332
409
  "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
333
410
 
334
411
  "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
335
412
 
413
+ "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="],
414
+
336
415
  "esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
337
416
 
338
417
  "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
@@ -343,8 +422,12 @@
343
422
 
344
423
  "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
345
424
 
425
+ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
426
+
346
427
  "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
347
428
 
429
+ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
430
+
348
431
  "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
349
432
 
350
433
  "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
@@ -353,6 +436,8 @@
353
436
 
354
437
  "fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
355
438
 
439
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
440
+
356
441
  "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "3.3.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
357
442
 
358
443
  "figures": ["figures@5.0.0", "", { "dependencies": { "escape-string-regexp": "5.0.0", "is-unicode-supported": "1.3.0" } }, "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg=="],
@@ -419,6 +504,30 @@
419
504
 
420
505
  "jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "2.0.1", "safe-buffer": "5.2.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
421
506
 
507
+ "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
508
+
509
+ "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
510
+
511
+ "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
512
+
513
+ "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
514
+
515
+ "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
516
+
517
+ "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
518
+
519
+ "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
520
+
521
+ "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
522
+
523
+ "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
524
+
525
+ "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
526
+
527
+ "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
528
+
529
+ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
530
+
422
531
  "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="],
423
532
 
424
533
  "lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="],
@@ -427,6 +536,8 @@
427
536
 
428
537
  "lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
429
538
 
539
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
540
+
430
541
  "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
431
542
 
432
543
  "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
@@ -441,12 +552,16 @@
441
552
 
442
553
  "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
443
554
 
555
+ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
556
+
444
557
  "netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
445
558
 
446
559
  "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
447
560
 
448
561
  "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "4.0.1", "fetch-blob": "3.2.0", "formdata-polyfill": "4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
449
562
 
563
+ "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
564
+
450
565
  "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
451
566
 
452
567
  "openai": ["openai@6.10.0", "", { "optionalDependencies": { "ws": "8.19.0", "zod": "3.25.76" }, "bin": { "openai": "bin/cli" } }, "sha512-ITxOGo7rO3XRMiKA5l7tQ43iNNu+iXGFAcf2t+aWVzzqRaS0i7m1K2BhxNdaveB+5eENhO0VY1FkiZzhBk4v3A=="],
@@ -465,6 +580,14 @@
465
580
 
466
581
  "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "10.4.3", "minipass": "7.1.2" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
467
582
 
583
+ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
584
+
585
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
586
+
587
+ "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
588
+
589
+ "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="],
590
+
468
591
  "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "7.1.4", "debug": "4.4.3", "http-proxy-agent": "7.0.2", "https-proxy-agent": "7.0.6", "lru-cache": "7.18.3", "pac-proxy-agent": "7.2.0", "proxy-from-env": "1.1.0", "socks-proxy-agent": "8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="],
469
592
 
470
593
  "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
@@ -483,6 +606,8 @@
483
606
 
484
607
  "rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "10.5.0" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
485
608
 
609
+ "rolldown": ["rolldown@1.0.0-rc.13", "", { "dependencies": { "@oxc-project/types": "=0.123.0", "@rolldown/pluginutils": "1.0.0-rc.13" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-x64": "1.0.0-rc.13", "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw=="],
610
+
486
611
  "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
487
612
 
488
613
  "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "1.4.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
@@ -491,6 +616,8 @@
491
616
 
492
617
  "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
493
618
 
619
+ "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
620
+
494
621
  "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
495
622
 
496
623
  "slice-ansi": ["slice-ansi@6.0.0", "", { "dependencies": { "ansi-styles": "6.2.3", "is-fullwidth-code-point": "4.0.0" } }, "sha512-6bn4hRfkTvDfUoEQYkERg0BVF1D0vrX9HEkMl08uDiNWvVvjylLHvZFZWkDo6wjT8tUctbYl1nCOuE66ZTaUtA=="],
@@ -503,8 +630,14 @@
503
630
 
504
631
  "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
505
632
 
633
+ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
634
+
506
635
  "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="],
507
636
 
637
+ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
638
+
639
+ "std-env": ["std-env@4.0.0", "", {}, "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ=="],
640
+
508
641
  "string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "0.2.0", "emoji-regex": "9.2.2", "strip-ansi": "7.1.2" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
509
642
 
510
643
  "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -515,6 +648,14 @@
515
648
 
516
649
  "strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
517
650
 
651
+ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
652
+
653
+ "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="],
654
+
655
+ "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
656
+
657
+ "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="],
658
+
518
659
  "ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="],
519
660
 
520
661
  "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
@@ -529,10 +670,16 @@
529
670
 
530
671
  "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
531
672
 
673
+ "vite": ["vite@8.0.7", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.13", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw=="],
674
+
675
+ "vitest": ["vitest@4.1.3", "", { "dependencies": { "@vitest/expect": "4.1.3", "@vitest/mocker": "4.1.3", "@vitest/pretty-format": "4.1.3", "@vitest/runner": "4.1.3", "@vitest/snapshot": "4.1.3", "@vitest/spy": "4.1.3", "@vitest/utils": "4.1.3", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.3", "@vitest/browser-preview": "4.1.3", "@vitest/browser-webdriverio": "4.1.3", "@vitest/coverage-istanbul": "4.1.3", "@vitest/coverage-v8": "4.1.3", "@vitest/ui": "4.1.3", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-DBc4Tx0MPNsqb9isoyOq00lHftVx/KIU44QOm2q59npZyLUkENn8TMFsuzuO+4U2FUa9rgbbPt3udrP25GcjXw=="],
676
+
532
677
  "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
533
678
 
534
679
  "which": ["which@2.0.2", "", { "dependencies": { "isexe": "2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
535
680
 
681
+ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
682
+
536
683
  "widest-line": ["widest-line@4.0.1", "", { "dependencies": { "string-width": "5.1.2" } }, "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig=="],
537
684
 
538
685
  "wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "6.2.3", "string-width": "5.1.2", "strip-ansi": "7.1.2" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { execFile } from "node:child_process";
3
+ import { join, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const CLI_PATH = join(__dirname, "..", "..", "dist", "cli.js");
7
+ function runCli(args = [], stdin) {
8
+ return new Promise((resolve) => {
9
+ const child = execFile("node", [CLI_PATH, ...args], {
10
+ timeout: 10000,
11
+ env: { ...process.env, HOME: "/tmp/amiko-cli-test" },
12
+ }, (error, stdout, stderr) => {
13
+ resolve({
14
+ stdout: stdout || "",
15
+ stderr: stderr || "",
16
+ code: error?.code === "ETIMEDOUT" ? 0 : error?.status ?? 0,
17
+ });
18
+ });
19
+ if (stdin !== undefined) {
20
+ child.stdin?.write(stdin);
21
+ }
22
+ child.stdin?.end();
23
+ });
24
+ }
25
+ describe("amiko-cli non-TTY behavior", () => {
26
+ it("does not crash with RangeError in piped mode", async () => {
27
+ const result = await runCli();
28
+ const combined = result.stdout + result.stderr;
29
+ expect(combined).not.toContain("RangeError");
30
+ expect(combined).not.toContain("Invalid count value");
31
+ });
32
+ it("enters headless mode when stdin is not a TTY", async () => {
33
+ const result = await runCli([], "/help\n");
34
+ const combined = result.stdout + result.stderr;
35
+ expect(combined).toContain("headless");
36
+ expect(combined).toContain("Commands:");
37
+ });
38
+ it("--headless flag is recognized", async () => {
39
+ const result = await runCli(["--headless"], "/help\n");
40
+ const combined = result.stdout + result.stderr;
41
+ expect(combined).toContain("headless");
42
+ expect(combined).toContain("Commands:");
43
+ });
44
+ it("headless /help lists available commands", async () => {
45
+ const result = await runCli([], "/help\n");
46
+ expect(result.stdout).toContain("/exit");
47
+ expect(result.stdout).toContain("/memory");
48
+ expect(result.stdout).toContain("/model");
49
+ expect(result.stdout).toContain("/search");
50
+ });
51
+ });
52
+ describe("String.repeat patch", () => {
53
+ it("clamps negative values to empty string", () => {
54
+ const origRepeat = String.prototype.repeat;
55
+ String.prototype.repeat = function (count) {
56
+ return origRepeat.call(this, Math.max(0, Math.floor(count)));
57
+ };
58
+ try {
59
+ expect("─".repeat(-2)).toBe("");
60
+ expect("─".repeat(-1)).toBe("");
61
+ expect("─".repeat(0)).toBe("");
62
+ expect("─".repeat(1)).toBe("─");
63
+ expect("─".repeat(3)).toBe("───");
64
+ expect("x".repeat(2.9)).toBe("xx");
65
+ }
66
+ finally {
67
+ String.prototype.repeat = origRepeat;
68
+ }
69
+ });
70
+ it("original String.repeat throws on negative values", () => {
71
+ expect(() => "x".repeat(-2)).toThrow(RangeError);
72
+ expect(() => "x".repeat(-1)).toThrow(RangeError);
73
+ });
74
+ });
package/dist/cli.js CHANGED
@@ -6,11 +6,15 @@ import { initWorkspace } from "./workspace.js";
6
6
  import { createSessionFile } from "./session.js";
7
7
  import { App } from "./app.js";
8
8
  import { loadConfigFile } from "./configFile.js";
9
+ import { runHeadless } from "./headless.js";
9
10
  function parseArgs(argv) {
10
11
  const overrides = {};
11
12
  for (let i = 0; i < argv.length; i += 1) {
12
13
  const arg = argv[i];
13
14
  switch (arg) {
15
+ case "--headless":
16
+ overrides.headless = true;
17
+ break;
14
18
  case "--workspace":
15
19
  case "-w":
16
20
  overrides.workspacePath = argv[i + 1];
@@ -76,6 +80,11 @@ async function main() {
76
80
  const persisted = await loadConfigFile(workspace.root);
77
81
  const mergedConfig = { ...finalConfig, ...persisted, ...overrides };
78
82
  const sessionFile = await createSessionFile(workspace.sessionsDir, finalConfig.sessionId);
83
+ // Auto-detect non-TTY or explicit --headless flag
84
+ if (overrides.headless || !process.stdout.isTTY) {
85
+ await runHeadless(mergedConfig, workspace, sessionFile.path);
86
+ return;
87
+ }
79
88
  render(_jsx(App, { config: mergedConfig, workspace: workspace, sessionPath: sessionFile.path }));
80
89
  }
81
90
  main().catch((error) => {
@@ -0,0 +1,218 @@
1
+ import { createInterface } from "node:readline";
2
+ import { parseCommand } from "./commands.js";
3
+ import { buildPrompt } from "./prompt.js";
4
+ import { appendSession } from "./session.js";
5
+ import { readWorkspaceFiles } from "./workspace.js";
6
+ import { createPiAgent } from "./agent/piAgent.js";
7
+ import { qmdSearch, qmdGet, qmdCollectionAdd, qmdEmbed } from "./memory/qmd.js";
8
+ import { saveConfigFile } from "./configFile.js";
9
+ import { getModels, getProviders } from "@mariozechner/pi-ai";
10
+ export async function runHeadless(config, workspace, sessionPath) {
11
+ const agent = await createPiAgent(config);
12
+ let currentModel = config.model
13
+ ?? (config.modelProvider && config.modelId ? `${config.modelProvider}/${config.modelId}` : "auto");
14
+ if (currentModel === "auto") {
15
+ const value = agent.getCurrentModel?.();
16
+ if (value)
17
+ currentModel = value;
18
+ }
19
+ if (agent.onEvent) {
20
+ agent.onEvent((event) => {
21
+ if (event?.type === "tool_execution_start") {
22
+ const lines = [`[tool] ${event.toolName} start`];
23
+ if (event.args?.command)
24
+ lines.push(` command: ${event.args.command}`);
25
+ console.log(lines.join("\n"));
26
+ }
27
+ if (event?.type === "tool_execution_end") {
28
+ const resultText = event.result?.content
29
+ ? event.result.content.map((c) => (c.text ? c.text : "")).join("\n")
30
+ : "";
31
+ const summary = resultText.trim() || "(no output)";
32
+ console.log(`[tool] ${event.toolName} done\n${summary}`);
33
+ }
34
+ });
35
+ }
36
+ console.log(`amiko-cli (headless) | model: ${currentModel} | workspace: ${workspace.root}`);
37
+ console.log("Type a message or /command. Press Ctrl+D to exit.");
38
+ const rl = createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ prompt: "> ",
42
+ terminal: false,
43
+ });
44
+ rl.prompt();
45
+ for await (const line of rl) {
46
+ const trimmed = line.trim();
47
+ if (!trimmed) {
48
+ rl.prompt();
49
+ continue;
50
+ }
51
+ const command = parseCommand(trimmed);
52
+ if (command) {
53
+ await handleCommand(command.name, command.args, {
54
+ config, workspace, sessionPath, agent, currentModel,
55
+ setModel: (m) => { currentModel = m; },
56
+ });
57
+ rl.prompt();
58
+ continue;
59
+ }
60
+ console.log(`[user] ${trimmed}`);
61
+ await appendSession(sessionPath, "user", trimmed);
62
+ const workspaceData = await readWorkspaceFiles(workspace);
63
+ let hits = [];
64
+ if (config.qmdEnabled) {
65
+ hits = await qmdSearch({
66
+ qmdBin: config.qmdBin,
67
+ query: trimmed,
68
+ limit: config.qmdLimit,
69
+ collection: config.qmdCollection,
70
+ });
71
+ }
72
+ if (config.qmdFull && hits.length > 0) {
73
+ const expanded = [];
74
+ for (const hit of hits) {
75
+ const docId = hit.path || hit.id;
76
+ if (!docId) {
77
+ expanded.push(hit);
78
+ continue;
79
+ }
80
+ const text = await qmdGet({ qmdBin: config.qmdBin, docId, full: true });
81
+ expanded.push({ ...hit, snippet: text || hit.snippet });
82
+ }
83
+ hits = expanded;
84
+ }
85
+ const prompt = buildPrompt({
86
+ identity: workspaceData.identity,
87
+ personality: workspaceData.personality,
88
+ memory: workspaceData.memory,
89
+ hits,
90
+ });
91
+ let assistantText = "";
92
+ try {
93
+ for await (const chunk of agent.streamReply({ prompt, userMessage: trimmed })) {
94
+ process.stdout.write(chunk);
95
+ assistantText += chunk;
96
+ }
97
+ }
98
+ catch (error) {
99
+ const message = error.message || "unknown error";
100
+ assistantText += `\n[error] ${message}\n`;
101
+ console.error(`[error] ${message}`);
102
+ }
103
+ if (!assistantText.endsWith("\n"))
104
+ process.stdout.write("\n");
105
+ if (assistantText) {
106
+ await appendSession(sessionPath, "assistant", assistantText);
107
+ }
108
+ rl.prompt();
109
+ }
110
+ process.exit(0);
111
+ }
112
+ async function handleCommand(name, args, ctx) {
113
+ switch (name) {
114
+ case "exit":
115
+ process.exit(0);
116
+ case "help":
117
+ console.log("Commands: /help /exit /search <query> /memory /session /plan /identity /personality /index [collection] /model [provider[/id]]");
118
+ return;
119
+ case "memory": {
120
+ const data = await readWorkspaceFiles(ctx.workspace);
121
+ console.log(`MEMORY.md:\n\n${data.memory.trim() || "(empty)"}`);
122
+ return;
123
+ }
124
+ case "session":
125
+ console.log(`Session file: ${ctx.sessionPath}`);
126
+ return;
127
+ case "plan":
128
+ console.log("Plan file: PLAN.md");
129
+ return;
130
+ case "identity": {
131
+ const data = await readWorkspaceFiles(ctx.workspace);
132
+ console.log(`IDENTITY.md:\n\n${data.identity.trim() || "(empty)"}`);
133
+ return;
134
+ }
135
+ case "personality": {
136
+ const data = await readWorkspaceFiles(ctx.workspace);
137
+ console.log(`PERSONALITY.md:\n\n${data.personality.trim() || "(empty)"}`);
138
+ return;
139
+ }
140
+ case "index": {
141
+ if (!ctx.config.qmdEnabled) {
142
+ console.log("QMD is disabled.");
143
+ return;
144
+ }
145
+ const collName = args || ctx.config.qmdCollection || "amiko";
146
+ const added = await qmdCollectionAdd({ qmdBin: ctx.config.qmdBin, name: collName, path: ctx.workspace.root });
147
+ if (!added) {
148
+ console.log("Failed to add QMD collection.");
149
+ return;
150
+ }
151
+ const embedded = await qmdEmbed({ qmdBin: ctx.config.qmdBin, collection: collName });
152
+ console.log(embedded ? `Indexed QMD collection "${collName}".` : `Collection "${collName}" added, but embedding failed.`);
153
+ return;
154
+ }
155
+ case "search": {
156
+ if (!args) {
157
+ console.log("Usage: /search <query>");
158
+ return;
159
+ }
160
+ if (!ctx.config.qmdEnabled) {
161
+ console.log("QMD is disabled.");
162
+ return;
163
+ }
164
+ const hits = await qmdSearch({ qmdBin: ctx.config.qmdBin, query: args, limit: ctx.config.qmdLimit, collection: ctx.config.qmdCollection });
165
+ if (hits.length === 0) {
166
+ console.log("No memory hits.");
167
+ return;
168
+ }
169
+ const formatted = hits.map((hit, i) => {
170
+ const label = hit.title || hit.path || hit.id;
171
+ const score = hit.score ? ` (${hit.score.toFixed(2)})` : "";
172
+ return `${i + 1}. ${label}${score}`;
173
+ }).join("\n");
174
+ console.log(formatted);
175
+ return;
176
+ }
177
+ case "model": {
178
+ if (!args) {
179
+ const providers = getProviders().sort();
180
+ console.log(`Current model: ${ctx.currentModel}\nProviders:\n${providers.map((p, i) => ` ${i + 1}. ${p}`).join("\n")}`);
181
+ return;
182
+ }
183
+ const slashParts = args.includes("/") ? args.split("/") : [];
184
+ let provider = args.split(" ")[0];
185
+ let modelId = args.split(" ")[1];
186
+ if (slashParts.length >= 2) {
187
+ provider = slashParts[0]?.trim();
188
+ modelId = slashParts.slice(1).join("/").trim();
189
+ }
190
+ if (provider && !modelId) {
191
+ const models = getModels(provider);
192
+ if (models.length === 0) {
193
+ console.log(`Unknown provider: ${provider}`);
194
+ return;
195
+ }
196
+ console.log(`Models for ${provider}:\n${models.map((m) => m.id).sort().join("\n")}`);
197
+ return;
198
+ }
199
+ if (!provider || !modelId) {
200
+ console.log("Usage: /model <provider>/<modelId>");
201
+ return;
202
+ }
203
+ if (!ctx.agent.setModel) {
204
+ console.log("Agent does not support model switching.");
205
+ return;
206
+ }
207
+ const result = ctx.agent.setModel(provider, modelId);
208
+ console.log(result.message);
209
+ if (result.ok) {
210
+ ctx.setModel(`${provider}/${modelId}`);
211
+ await saveConfigFile(ctx.workspace.root, { model: `${provider}/${modelId}`, modelProvider: provider, modelId });
212
+ }
213
+ return;
214
+ }
215
+ default:
216
+ console.log(`Unknown command: ${name}`);
217
+ }
218
+ }
package/package.json CHANGED
@@ -1,20 +1,22 @@
1
1
  {
2
2
  "name": "@heyamiko/amiko-cli",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "amiko": "dist/cli.js"
7
7
  },
8
8
  "scripts": {
9
9
  "dev": "tsx src/cli.tsx",
10
- "build": "tsc -p tsconfig.json"
10
+ "build": "tsc -p tsconfig.json",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest"
11
13
  },
12
14
  "dependencies": {
13
15
  "@mariozechner/pi-agent-core": "*",
14
16
  "@mariozechner/pi-ai": "*",
17
+ "@sinclair/typebox": "^0.34.41",
15
18
  "ink": "^4.4.1",
16
19
  "ink-select-input": "^5.0.0",
17
- "@sinclair/typebox": "^0.34.41",
18
20
  "react": "^18.2.0",
19
21
  "react-dom": "^18.2.0"
20
22
  },
@@ -23,6 +25,7 @@
23
25
  "@types/react": "^18.2.0",
24
26
  "@types/react-dom": "^18.2.0",
25
27
  "tsx": "^4.7.0",
26
- "typescript": "^5.4.0"
28
+ "typescript": "^5.4.0",
29
+ "vitest": "^4.1.3"
27
30
  }
28
31
  }
@@ -0,0 +1,86 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { execFile } from "node:child_process";
3
+ import { join, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const CLI_PATH = join(__dirname, "..", "..", "dist", "cli.js");
8
+
9
+ function runCli(args: string[] = [], stdin?: string): Promise<{ stdout: string; stderr: string; code: number | null }> {
10
+ return new Promise((resolve) => {
11
+ const child = execFile("node", [CLI_PATH, ...args], {
12
+ timeout: 10000,
13
+ env: { ...process.env, HOME: "/tmp/amiko-cli-test" },
14
+ }, (error, stdout, stderr) => {
15
+ resolve({
16
+ stdout: stdout || "",
17
+ stderr: stderr || "",
18
+ code: error?.code === "ETIMEDOUT" ? 0 : (error as any)?.status ?? 0,
19
+ });
20
+ });
21
+ if (stdin !== undefined) {
22
+ child.stdin?.write(stdin);
23
+ }
24
+ child.stdin?.end();
25
+ });
26
+ }
27
+
28
+ describe("amiko-cli non-TTY behavior", () => {
29
+ it("does not crash with RangeError in piped mode", async () => {
30
+ const result = await runCli();
31
+ const combined = result.stdout + result.stderr;
32
+
33
+ expect(combined).not.toContain("RangeError");
34
+ expect(combined).not.toContain("Invalid count value");
35
+ });
36
+
37
+ it("enters headless mode when stdin is not a TTY", async () => {
38
+ const result = await runCli([], "/help\n");
39
+ const combined = result.stdout + result.stderr;
40
+
41
+ expect(combined).toContain("headless");
42
+ expect(combined).toContain("Commands:");
43
+ });
44
+
45
+ it("--headless flag is recognized", async () => {
46
+ const result = await runCli(["--headless"], "/help\n");
47
+ const combined = result.stdout + result.stderr;
48
+
49
+ expect(combined).toContain("headless");
50
+ expect(combined).toContain("Commands:");
51
+ });
52
+
53
+ it("headless /help lists available commands", async () => {
54
+ const result = await runCli([], "/help\n");
55
+
56
+ expect(result.stdout).toContain("/exit");
57
+ expect(result.stdout).toContain("/memory");
58
+ expect(result.stdout).toContain("/model");
59
+ expect(result.stdout).toContain("/search");
60
+ });
61
+ });
62
+
63
+ describe("String.repeat patch", () => {
64
+ it("clamps negative values to empty string", () => {
65
+ const origRepeat = String.prototype.repeat;
66
+ String.prototype.repeat = function (count: number) {
67
+ return origRepeat.call(this, Math.max(0, Math.floor(count)));
68
+ };
69
+
70
+ try {
71
+ expect("─".repeat(-2)).toBe("");
72
+ expect("─".repeat(-1)).toBe("");
73
+ expect("─".repeat(0)).toBe("");
74
+ expect("─".repeat(1)).toBe("─");
75
+ expect("─".repeat(3)).toBe("───");
76
+ expect("x".repeat(2.9)).toBe("xx");
77
+ } finally {
78
+ String.prototype.repeat = origRepeat;
79
+ }
80
+ });
81
+
82
+ it("original String.repeat throws on negative values", () => {
83
+ expect(() => "x".repeat(-2)).toThrow(RangeError);
84
+ expect(() => "x".repeat(-1)).toThrow(RangeError);
85
+ });
86
+ });
package/src/cli.tsx CHANGED
@@ -6,6 +6,7 @@ import { initWorkspace } from "./workspace.js";
6
6
  import { createSessionFile } from "./session.js";
7
7
  import { App } from "./app.js";
8
8
  import { loadConfigFile } from "./configFile.js";
9
+ import { runHeadless } from "./headless.js";
9
10
 
10
11
  type ArgOverrides = Partial<{
11
12
  workspacePath: string;
@@ -19,6 +20,7 @@ type ArgOverrides = Partial<{
19
20
  modelProvider?: string;
20
21
  modelId?: string;
21
22
  thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
23
+ headless?: boolean;
22
24
  }>;
23
25
 
24
26
  function parseArgs(argv: string[]): ArgOverrides {
@@ -26,6 +28,9 @@ function parseArgs(argv: string[]): ArgOverrides {
26
28
  for (let i = 0; i < argv.length; i += 1) {
27
29
  const arg = argv[i];
28
30
  switch (arg) {
31
+ case "--headless":
32
+ overrides.headless = true;
33
+ break;
29
34
  case "--workspace":
30
35
  case "-w":
31
36
  overrides.workspacePath = argv[i + 1];
@@ -94,6 +99,12 @@ async function main() {
94
99
  const mergedConfig = { ...finalConfig, ...persisted, ...overrides };
95
100
  const sessionFile = await createSessionFile(workspace.sessionsDir, finalConfig.sessionId);
96
101
 
102
+ // Auto-detect non-TTY or explicit --headless flag
103
+ if (overrides.headless || !process.stdout.isTTY) {
104
+ await runHeadless(mergedConfig, workspace, sessionFile.path);
105
+ return;
106
+ }
107
+
97
108
  render(<App config={mergedConfig} workspace={workspace} sessionPath={sessionFile.path} />);
98
109
  }
99
110
 
@@ -0,0 +1,222 @@
1
+ import { createInterface } from "node:readline";
2
+ import { AppConfig, Message, MemoryHit } from "./types.js";
3
+ import { parseCommand } from "./commands.js";
4
+ import { buildPrompt } from "./prompt.js";
5
+ import { appendSession } from "./session.js";
6
+ import { readWorkspaceFiles, WorkspaceFiles } from "./workspace.js";
7
+ import { createPiAgent } from "./agent/piAgent.js";
8
+ import { qmdSearch, qmdGet, qmdCollectionAdd, qmdEmbed } from "./memory/qmd.js";
9
+ import { saveConfigFile } from "./configFile.js";
10
+ import { getModels, getProviders, type KnownProvider } from "@mariozechner/pi-ai";
11
+
12
+ export async function runHeadless(
13
+ config: AppConfig,
14
+ workspace: WorkspaceFiles,
15
+ sessionPath: string,
16
+ ) {
17
+ const agent = await createPiAgent(config);
18
+ let currentModel = config.model
19
+ ?? (config.modelProvider && config.modelId ? `${config.modelProvider}/${config.modelId}` : "auto");
20
+
21
+ if (currentModel === "auto") {
22
+ const value = agent.getCurrentModel?.();
23
+ if (value) currentModel = value;
24
+ }
25
+
26
+ if (agent.onEvent) {
27
+ agent.onEvent((event) => {
28
+ if (event?.type === "tool_execution_start") {
29
+ const lines = [`[tool] ${event.toolName} start`];
30
+ if (event.args?.command) lines.push(` command: ${event.args.command}`);
31
+ console.log(lines.join("\n"));
32
+ }
33
+ if (event?.type === "tool_execution_end") {
34
+ const resultText = event.result?.content
35
+ ? event.result.content.map((c: any) => (c.text ? c.text : "")).join("\n")
36
+ : "";
37
+ const summary = resultText.trim() || "(no output)";
38
+ console.log(`[tool] ${event.toolName} done\n${summary}`);
39
+ }
40
+ });
41
+ }
42
+
43
+ console.log(`amiko-cli (headless) | model: ${currentModel} | workspace: ${workspace.root}`);
44
+ console.log("Type a message or /command. Press Ctrl+D to exit.");
45
+
46
+ const rl = createInterface({
47
+ input: process.stdin,
48
+ output: process.stdout,
49
+ prompt: "> ",
50
+ terminal: false,
51
+ });
52
+
53
+ rl.prompt();
54
+
55
+ for await (const line of rl) {
56
+ const trimmed = line.trim();
57
+ if (!trimmed) {
58
+ rl.prompt();
59
+ continue;
60
+ }
61
+
62
+ const command = parseCommand(trimmed);
63
+ if (command) {
64
+ await handleCommand(command.name, command.args, {
65
+ config, workspace, sessionPath, agent, currentModel,
66
+ setModel: (m: string) => { currentModel = m; },
67
+ });
68
+ rl.prompt();
69
+ continue;
70
+ }
71
+
72
+ console.log(`[user] ${trimmed}`);
73
+ await appendSession(sessionPath, "user", trimmed);
74
+
75
+ const workspaceData = await readWorkspaceFiles(workspace);
76
+
77
+ let hits: MemoryHit[] = [];
78
+ if (config.qmdEnabled) {
79
+ hits = await qmdSearch({
80
+ qmdBin: config.qmdBin,
81
+ query: trimmed,
82
+ limit: config.qmdLimit,
83
+ collection: config.qmdCollection,
84
+ });
85
+ }
86
+
87
+ if (config.qmdFull && hits.length > 0) {
88
+ const expanded: MemoryHit[] = [];
89
+ for (const hit of hits) {
90
+ const docId = hit.path || hit.id;
91
+ if (!docId) { expanded.push(hit); continue; }
92
+ const text = await qmdGet({ qmdBin: config.qmdBin, docId, full: true });
93
+ expanded.push({ ...hit, snippet: text || hit.snippet });
94
+ }
95
+ hits = expanded;
96
+ }
97
+
98
+ const prompt = buildPrompt({
99
+ identity: workspaceData.identity,
100
+ personality: workspaceData.personality,
101
+ memory: workspaceData.memory,
102
+ hits,
103
+ });
104
+
105
+ let assistantText = "";
106
+ try {
107
+ for await (const chunk of agent.streamReply({ prompt, userMessage: trimmed })) {
108
+ process.stdout.write(chunk);
109
+ assistantText += chunk;
110
+ }
111
+ } catch (error) {
112
+ const message = (error as Error).message || "unknown error";
113
+ assistantText += `\n[error] ${message}\n`;
114
+ console.error(`[error] ${message}`);
115
+ }
116
+
117
+ if (!assistantText.endsWith("\n")) process.stdout.write("\n");
118
+
119
+ if (assistantText) {
120
+ await appendSession(sessionPath, "assistant", assistantText);
121
+ }
122
+
123
+ rl.prompt();
124
+ }
125
+
126
+ process.exit(0);
127
+ }
128
+
129
+ async function handleCommand(
130
+ name: string,
131
+ args: string,
132
+ ctx: {
133
+ config: AppConfig;
134
+ workspace: WorkspaceFiles;
135
+ sessionPath: string;
136
+ agent: any;
137
+ currentModel: string;
138
+ setModel: (m: string) => void;
139
+ },
140
+ ) {
141
+ switch (name) {
142
+ case "exit":
143
+ process.exit(0);
144
+ case "help":
145
+ console.log("Commands: /help /exit /search <query> /memory /session /plan /identity /personality /index [collection] /model [provider[/id]]");
146
+ return;
147
+ case "memory": {
148
+ const data = await readWorkspaceFiles(ctx.workspace);
149
+ console.log(`MEMORY.md:\n\n${data.memory.trim() || "(empty)"}`);
150
+ return;
151
+ }
152
+ case "session":
153
+ console.log(`Session file: ${ctx.sessionPath}`);
154
+ return;
155
+ case "plan":
156
+ console.log("Plan file: PLAN.md");
157
+ return;
158
+ case "identity": {
159
+ const data = await readWorkspaceFiles(ctx.workspace);
160
+ console.log(`IDENTITY.md:\n\n${data.identity.trim() || "(empty)"}`);
161
+ return;
162
+ }
163
+ case "personality": {
164
+ const data = await readWorkspaceFiles(ctx.workspace);
165
+ console.log(`PERSONALITY.md:\n\n${data.personality.trim() || "(empty)"}`);
166
+ return;
167
+ }
168
+ case "index": {
169
+ if (!ctx.config.qmdEnabled) { console.log("QMD is disabled."); return; }
170
+ const collName = args || ctx.config.qmdCollection || "amiko";
171
+ const added = await qmdCollectionAdd({ qmdBin: ctx.config.qmdBin, name: collName, path: ctx.workspace.root });
172
+ if (!added) { console.log("Failed to add QMD collection."); return; }
173
+ const embedded = await qmdEmbed({ qmdBin: ctx.config.qmdBin, collection: collName });
174
+ console.log(embedded ? `Indexed QMD collection "${collName}".` : `Collection "${collName}" added, but embedding failed.`);
175
+ return;
176
+ }
177
+ case "search": {
178
+ if (!args) { console.log("Usage: /search <query>"); return; }
179
+ if (!ctx.config.qmdEnabled) { console.log("QMD is disabled."); return; }
180
+ const hits = await qmdSearch({ qmdBin: ctx.config.qmdBin, query: args, limit: ctx.config.qmdLimit, collection: ctx.config.qmdCollection });
181
+ if (hits.length === 0) { console.log("No memory hits."); return; }
182
+ const formatted = hits.map((hit, i) => {
183
+ const label = hit.title || hit.path || hit.id;
184
+ const score = hit.score ? ` (${hit.score.toFixed(2)})` : "";
185
+ return `${i + 1}. ${label}${score}`;
186
+ }).join("\n");
187
+ console.log(formatted);
188
+ return;
189
+ }
190
+ case "model": {
191
+ if (!args) {
192
+ const providers = getProviders().sort();
193
+ console.log(`Current model: ${ctx.currentModel}\nProviders:\n${providers.map((p, i) => ` ${i + 1}. ${p}`).join("\n")}`);
194
+ return;
195
+ }
196
+ const slashParts = args.includes("/") ? args.split("/") : [];
197
+ let provider = args.split(" ")[0];
198
+ let modelId = args.split(" ")[1];
199
+ if (slashParts.length >= 2) {
200
+ provider = slashParts[0]?.trim();
201
+ modelId = slashParts.slice(1).join("/").trim();
202
+ }
203
+ if (provider && !modelId) {
204
+ const models = getModels(provider as KnownProvider);
205
+ if (models.length === 0) { console.log(`Unknown provider: ${provider}`); return; }
206
+ console.log(`Models for ${provider}:\n${models.map((m) => m.id).sort().join("\n")}`);
207
+ return;
208
+ }
209
+ if (!provider || !modelId) { console.log("Usage: /model <provider>/<modelId>"); return; }
210
+ if (!ctx.agent.setModel) { console.log("Agent does not support model switching."); return; }
211
+ const result = ctx.agent.setModel(provider, modelId);
212
+ console.log(result.message);
213
+ if (result.ok) {
214
+ ctx.setModel(`${provider}/${modelId}`);
215
+ await saveConfigFile(ctx.workspace.root, { model: `${provider}/${modelId}`, modelProvider: provider, modelId });
216
+ }
217
+ return;
218
+ }
219
+ default:
220
+ console.log(`Unknown command: ${name}`);
221
+ }
222
+ }