@agentskit/cli 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -4
- package/dist/bin.cjs +129 -41
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-IMW4N7X2.js → chunk-CCPJYGHP.js} +132 -44
- package/dist/chunk-CCPJYGHP.js.map +1 -0
- package/dist/index.cjs +129 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +8 -8
- package/dist/chunk-IMW4N7X2.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Chat with any LLM, scaffold projects, and run agents — all from your terminal.
|
|
|
7
7
|
[](https://bundlephobia.com/package/@agentskit/cli)
|
|
8
8
|
[](../../LICENSE)
|
|
9
9
|
[](../../docs/STABILITY.md)
|
|
10
|
-
[](https://github.com/AgentsKit-io/agentskit)
|
|
11
11
|
|
|
12
12
|
**Tags:** `ai` · `agents` · `llm` · `agentskit` · `openai` · `anthropic` · `claude` · `gemini` · `chatgpt` · `cli` · `command-line` · `scaffolding` · `ai-agents` · `autonomous-agents`
|
|
13
13
|
|
|
@@ -43,14 +43,25 @@ agentskit init --template ink --dir my-cli
|
|
|
43
43
|
agentskit run --help
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
### agentskit init
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
46
50
|
## Features
|
|
47
51
|
|
|
48
52
|
- `agentskit chat` — interactive streaming chat in the terminal powered by `@agentskit/ink`
|
|
49
53
|
- `agentskit init` — interactive project generator (React or Ink templates, production-ready structure)
|
|
50
54
|
- `agentskit run` — execute headless runtime agents from the terminal
|
|
55
|
+
- `agentskit doctor` — diagnose your environment, packages, and provider config
|
|
56
|
+
- `agentskit dev` — hot-reload agent development
|
|
57
|
+
- `agentskit tunnel` — expose local agent via public URL
|
|
51
58
|
- Provider flags: `--provider`, `--model`, `--system`, `--skill`, `--memory`
|
|
52
59
|
- Env-var based key injection — works seamlessly in CI and scripts
|
|
53
60
|
|
|
61
|
+
### agentskit doctor
|
|
62
|
+
|
|
63
|
+

|
|
64
|
+
|
|
54
65
|
## Ecosystem
|
|
55
66
|
|
|
56
67
|
| Package | Role |
|
|
@@ -62,8 +73,8 @@ agentskit run --help
|
|
|
62
73
|
|
|
63
74
|
## Contributors
|
|
64
75
|
|
|
65
|
-
<a href="https://github.com/
|
|
66
|
-
<img src="https://contrib.rocks/image?repo=
|
|
76
|
+
<a href="https://github.com/AgentsKit-io/agentskit/graphs/contributors">
|
|
77
|
+
<img src="https://contrib.rocks/image?repo=AgentsKit-io/agentskit" alt="AgentsKit contributors" />
|
|
67
78
|
</a>
|
|
68
79
|
|
|
69
80
|
## License
|
|
@@ -72,4 +83,4 @@ MIT — see [LICENSE](../../LICENSE).
|
|
|
72
83
|
|
|
73
84
|
## Docs
|
|
74
85
|
|
|
75
|
-
[Full documentation](https://www.agentskit.io) · [GitHub](https://github.com/
|
|
86
|
+
[Full documentation](https://www.agentskit.io) · [GitHub](https://github.com/AgentsKit-io/agentskit)
|
package/dist/bin.cjs
CHANGED
|
@@ -233,11 +233,31 @@ function resolveMemory(backend, memoryPath) {
|
|
|
233
233
|
return memory.fileChatMemory(memoryPath);
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
+
function groupIntoTurns(messages) {
|
|
237
|
+
const turns = [];
|
|
238
|
+
let current = [];
|
|
239
|
+
for (const message of messages) {
|
|
240
|
+
if (message.role === "user") {
|
|
241
|
+
if (current.length > 0) turns.push(current);
|
|
242
|
+
current = [message];
|
|
243
|
+
} else if (message.role === "system") {
|
|
244
|
+
if (current.length > 0) turns.push(current);
|
|
245
|
+
turns.push([message]);
|
|
246
|
+
current = [];
|
|
247
|
+
} else {
|
|
248
|
+
current.push(message);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (current.length > 0) turns.push(current);
|
|
252
|
+
return turns;
|
|
253
|
+
}
|
|
236
254
|
function ChatApp(options) {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
255
|
+
const runtime = React3.useMemo(() => resolveChatProvider(options), [
|
|
256
|
+
options.apiKey,
|
|
257
|
+
options.baseUrl,
|
|
258
|
+
options.model,
|
|
259
|
+
options.provider
|
|
260
|
+
]);
|
|
241
261
|
const memory = React3.useMemo(
|
|
242
262
|
() => resolveMemory(options.memoryBackend, options.memoryPath ?? ".agentskit-history.json"),
|
|
243
263
|
[options.memoryPath, options.memoryBackend]
|
|
@@ -251,21 +271,51 @@ function ChatApp(options) {
|
|
|
251
271
|
return resolved;
|
|
252
272
|
}, [options.skill]);
|
|
253
273
|
const chat = ink$1.useChat({
|
|
254
|
-
adapter,
|
|
274
|
+
adapter: runtime.adapter,
|
|
255
275
|
memory,
|
|
256
276
|
systemPrompt: options.system,
|
|
257
277
|
tools: tools.length > 0 ? tools : void 0,
|
|
258
278
|
skills
|
|
259
279
|
});
|
|
280
|
+
const turns = React3.useMemo(() => groupIntoTurns(chat.messages), [chat.messages]);
|
|
281
|
+
const toolNames = options.tools ? options.tools.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
260
282
|
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", gap: 1, children: [
|
|
261
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
283
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
284
|
+
ink$1.StatusHeader,
|
|
285
|
+
{
|
|
286
|
+
provider: runtime.provider,
|
|
287
|
+
model: runtime.model,
|
|
288
|
+
mode: runtime.mode,
|
|
289
|
+
tools: toolNames,
|
|
290
|
+
messageCount: chat.messages.length
|
|
291
|
+
}
|
|
292
|
+
),
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink$1.ChatContainer, { children: turns.map((turn, turnIdx) => {
|
|
294
|
+
const assistantSteps = turn.filter((m) => m.role === "assistant").length;
|
|
295
|
+
let stepIndex = 0;
|
|
296
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { flexDirection: "column", gap: 1, children: turn.map((message) => {
|
|
297
|
+
const showStep = message.role === "assistant" && assistantSteps > 1;
|
|
298
|
+
if (showStep) stepIndex++;
|
|
299
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [
|
|
300
|
+
showStep ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { dimColor: true, children: [
|
|
301
|
+
"\u21BB step ",
|
|
302
|
+
stepIndex,
|
|
303
|
+
"/",
|
|
304
|
+
assistantSteps
|
|
305
|
+
] }) : null,
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink$1.Message, { message }),
|
|
307
|
+
message.toolCalls?.map((toolCall) => /* @__PURE__ */ jsxRuntime.jsx(ink$1.ToolCallView, { toolCall, expanded: true }, toolCall.id))
|
|
308
|
+
] }, message.id);
|
|
309
|
+
}) }, `turn-${turnIdx}`);
|
|
310
|
+
}) }),
|
|
311
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
312
|
+
ink$1.ThinkingIndicator,
|
|
313
|
+
{
|
|
314
|
+
visible: chat.status === "streaming",
|
|
315
|
+
label: toolNames.length > 0 ? "agent working" : "thinking"
|
|
316
|
+
}
|
|
317
|
+
),
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsx(ink$1.InputBar, { chat, placeholder: "Type a message and press Enter\u2026" })
|
|
269
319
|
] });
|
|
270
320
|
}
|
|
271
321
|
function renderChatHeader(options) {
|
|
@@ -1042,8 +1092,8 @@ var PROVIDER_ENV_KEYS = {
|
|
|
1042
1092
|
};
|
|
1043
1093
|
var PROVIDER_REACH_URLS = {
|
|
1044
1094
|
openai: "https://api.openai.com/v1/models",
|
|
1045
|
-
anthropic: "https://api.anthropic.com",
|
|
1046
|
-
gemini: "https://generativelanguage.googleapis.com",
|
|
1095
|
+
anthropic: "https://api.anthropic.com/v1/messages",
|
|
1096
|
+
gemini: "https://generativelanguage.googleapis.com/v1beta/models",
|
|
1047
1097
|
ollama: "http://localhost:11434/api/tags"
|
|
1048
1098
|
};
|
|
1049
1099
|
async function checkNodeVersion() {
|
|
@@ -1131,10 +1181,10 @@ async function checkProviderEnv(provider) {
|
|
|
1131
1181
|
const value = process.env[envKey];
|
|
1132
1182
|
if (!value) {
|
|
1133
1183
|
return {
|
|
1134
|
-
status: "
|
|
1184
|
+
status: "skip",
|
|
1135
1185
|
name: `${provider} API key`,
|
|
1136
|
-
detail: `${envKey}
|
|
1137
|
-
fix: `export ${envKey}
|
|
1186
|
+
detail: `${envKey} not set`,
|
|
1187
|
+
fix: `export ${envKey}=... (only needed if you use ${provider})`
|
|
1138
1188
|
};
|
|
1139
1189
|
}
|
|
1140
1190
|
if (value.length < 16) {
|
|
@@ -1150,7 +1200,11 @@ async function checkProviderEnv(provider) {
|
|
|
1150
1200
|
async function checkProviderReachable(provider, fetchImpl = fetch, timeoutMs = 4e3) {
|
|
1151
1201
|
const url = PROVIDER_REACH_URLS[provider];
|
|
1152
1202
|
if (!url) {
|
|
1153
|
-
return { status: "skip", name: `${provider} reachable`, detail: "No reachability check
|
|
1203
|
+
return { status: "skip", name: `${provider} reachable`, detail: "No reachability check configured" };
|
|
1204
|
+
}
|
|
1205
|
+
const envKey = PROVIDER_ENV_KEYS[provider];
|
|
1206
|
+
if (envKey && !process.env[envKey]) {
|
|
1207
|
+
return { status: "skip", name: `${provider} reachable`, detail: "Skipped \u2014 no API key configured" };
|
|
1154
1208
|
}
|
|
1155
1209
|
const controller = new AbortController();
|
|
1156
1210
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -1158,12 +1212,18 @@ async function checkProviderReachable(provider, fetchImpl = fetch, timeoutMs = 4
|
|
|
1158
1212
|
const res = await fetchImpl(url, {
|
|
1159
1213
|
method: "GET",
|
|
1160
1214
|
signal: controller.signal
|
|
1161
|
-
// No auth — we just want to confirm DNS + network reach.
|
|
1162
1215
|
});
|
|
1216
|
+
if (res.status >= 200 && res.status < 400) {
|
|
1217
|
+
return { status: "pass", name: `${provider} reachable`, detail: `${url} \u2192 ${res.status} OK` };
|
|
1218
|
+
}
|
|
1219
|
+
if (res.status === 401 || res.status === 403 || res.status === 405) {
|
|
1220
|
+
return { status: "pass", name: `${provider} reachable`, detail: `${url} \u2192 ${res.status} (host reachable)` };
|
|
1221
|
+
}
|
|
1163
1222
|
return {
|
|
1164
|
-
status: "
|
|
1223
|
+
status: "warn",
|
|
1165
1224
|
name: `${provider} reachable`,
|
|
1166
|
-
detail: `${url} \u2192 HTTP ${res.status}
|
|
1225
|
+
detail: `${url} \u2192 HTTP ${res.status}`,
|
|
1226
|
+
fix: "Host reachable but returned unexpected status \u2014 check provider docs"
|
|
1167
1227
|
};
|
|
1168
1228
|
} catch (err) {
|
|
1169
1229
|
const reason = err.name === "AbortError" ? `timeout after ${timeoutMs}ms` : err.message;
|
|
@@ -1221,41 +1281,69 @@ async function runDoctor(options = {}) {
|
|
|
1221
1281
|
};
|
|
1222
1282
|
}
|
|
1223
1283
|
var ICON = {
|
|
1224
|
-
pass: "\
|
|
1225
|
-
warn: "
|
|
1226
|
-
fail: "\
|
|
1227
|
-
skip: "\
|
|
1284
|
+
pass: "\u2714",
|
|
1285
|
+
warn: "\u26A0",
|
|
1286
|
+
fail: "\u2718",
|
|
1287
|
+
skip: "\u25CB"
|
|
1228
1288
|
};
|
|
1229
1289
|
function renderReport(report, opts = {}) {
|
|
1230
1290
|
const color = opts.color ?? true;
|
|
1231
1291
|
const c = (code, text) => color ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
1232
1292
|
const colorFor = {
|
|
1233
1293
|
pass: (t) => c("32", t),
|
|
1294
|
+
// green
|
|
1234
1295
|
warn: (t) => c("33", t),
|
|
1296
|
+
// yellow
|
|
1235
1297
|
fail: (t) => c("31", t),
|
|
1298
|
+
// red
|
|
1236
1299
|
skip: (t) => c("90", t)
|
|
1300
|
+
// dim
|
|
1237
1301
|
};
|
|
1238
1302
|
const lines = [];
|
|
1239
1303
|
lines.push("");
|
|
1240
|
-
lines.push(c("1", "
|
|
1304
|
+
lines.push(` ${c("1;36", "\u26A1 AgentsKit Doctor")}`);
|
|
1305
|
+
lines.push(` ${c("90", "\u2500".repeat(50))}`);
|
|
1241
1306
|
lines.push("");
|
|
1307
|
+
const groups = {
|
|
1308
|
+
"Environment": [],
|
|
1309
|
+
"Providers": [],
|
|
1310
|
+
"Network": []
|
|
1311
|
+
};
|
|
1242
1312
|
for (const r of report.results) {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1313
|
+
if (r.name.includes("reachable")) {
|
|
1314
|
+
groups["Network"].push(r);
|
|
1315
|
+
} else if (r.name.includes("API key")) {
|
|
1316
|
+
groups["Providers"].push(r);
|
|
1317
|
+
} else {
|
|
1318
|
+
groups["Environment"].push(r);
|
|
1249
1319
|
}
|
|
1250
1320
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1321
|
+
for (const [group, results] of Object.entries(groups)) {
|
|
1322
|
+
if (results.length === 0) continue;
|
|
1323
|
+
lines.push(` ${c("1", group)}`);
|
|
1324
|
+
for (const r of results) {
|
|
1325
|
+
const icon = colorFor[r.status](ICON[r.status]);
|
|
1326
|
+
const name = r.name.padEnd(28);
|
|
1327
|
+
const detail = r.detail ? c("90", r.detail) : "";
|
|
1328
|
+
lines.push(` ${icon} ${name} ${detail}`);
|
|
1329
|
+
if (r.fix && r.status !== "pass") {
|
|
1330
|
+
lines.push(` ${c("90", "\u21B3 " + r.fix)}`);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
lines.push("");
|
|
1334
|
+
}
|
|
1335
|
+
lines.push(` ${c("90", "\u2500".repeat(50))}`);
|
|
1336
|
+
const parts = [];
|
|
1337
|
+
if (report.pass > 0) parts.push(colorFor.pass(`${report.pass} passed`));
|
|
1338
|
+
if (report.warn > 0) parts.push(colorFor.warn(`${report.warn} warnings`));
|
|
1339
|
+
if (report.fail > 0) parts.push(colorFor.fail(`${report.fail} failed`));
|
|
1340
|
+
if (report.skip > 0) parts.push(colorFor.skip(`${report.skip} skipped`));
|
|
1341
|
+
lines.push(` ${parts.join(" \xB7 ")}`);
|
|
1342
|
+
if (report.fail === 0) {
|
|
1343
|
+
lines.push(` ${c("32", "\u2714 Ready to build agents.")}`);
|
|
1344
|
+
} else {
|
|
1345
|
+
lines.push(` ${c("31", "\u2718 Fix the issues above before continuing.")}`);
|
|
1346
|
+
}
|
|
1259
1347
|
lines.push("");
|
|
1260
1348
|
return lines.join("\n");
|
|
1261
1349
|
}
|