@vatio-ai/cli 0.47.1 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/bin/vatio.mjs +3 -3
- package/lib/commands/chat.mjs +72 -4
- package/lib/commands/deploy.mjs +5 -2
- package/lib/commands/mcp.mjs +5 -3
- package/lib/config.mjs +1 -1
- package/lib/help.mjs +4 -1
- package/lib/version.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ login | logout Authorize this machine in a browser, or forget it
|
|
|
56
56
|
doctor Node, config, workspace and token status
|
|
57
57
|
|
|
58
58
|
push [--env NAME] Validate the workspace, then update a preview
|
|
59
|
-
publish [--env NAME] Promote
|
|
59
|
+
publish [--env NAME] Promote the latest push to live, or the named preview
|
|
60
60
|
diff [--env NAME] What this directory would change
|
|
61
61
|
status Preview and live deployment state
|
|
62
62
|
rollback Restore the previous live deployment
|
|
@@ -64,6 +64,7 @@ tools check Validate the workspace against Vatio's contracts
|
|
|
64
64
|
|
|
65
65
|
chat "message" [--env NAME] Talk to your own agent; the token is the identity
|
|
66
66
|
chat transcript|debug|reset|destroy
|
|
67
|
+
chat show CHAT_ID [--json] Any chat in the workspace, with its deployment and tool calls
|
|
67
68
|
|
|
68
69
|
kb list|show|create|rm Knowledge bases
|
|
69
70
|
kb write|cat|rm-entry Entries, from a file or stdin
|
package/bin/vatio.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// The Vatio CLI, as an npm package: `npx vatio push`.
|
|
2
|
+
// The Vatio CLI, as an npm package: `npx @vatio-ai/cli push`.
|
|
3
3
|
//
|
|
4
4
|
// Same platform, same API, same ~/.vatio/config.json as the Ruby CLI that
|
|
5
5
|
// `curl … /install.sh | bash` puts on a machine. Either can drive a workspace,
|
|
@@ -31,8 +31,8 @@ const RETIRED = {
|
|
|
31
31
|
pull: "was removed: a deployed manifest only ever comes from a push, so it could never\n" +
|
|
32
32
|
"hand back anything your repository did not already have. Use `vatio diff --env live`,\n" +
|
|
33
33
|
"or read the manifest at GET /api/v1/:slug/deploy/manifest.",
|
|
34
|
-
update: "is npm's job now: `npx vatio@latest` always runs the current release, and\n" +
|
|
35
|
-
"`npm install -g vatio@latest` updates a global install."
|
|
34
|
+
update: "is npm's job now: `npx @vatio-ai/cli@latest` always runs the current release, and\n" +
|
|
35
|
+
"`npm install -g @vatio-ai/cli@latest` updates a global install."
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
async function main(argv) {
|
package/lib/commands/chat.mjs
CHANGED
|
@@ -10,11 +10,11 @@ import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
|
|
12
12
|
import { ApiClient } from "../api-client.mjs";
|
|
13
|
-
import { fail, sleep, takeEnv, takeValue } from "../support.mjs";
|
|
13
|
+
import { fail, sleep, takeEnv, takeFlag, takeValue } from "../support.mjs";
|
|
14
14
|
|
|
15
15
|
export const STATE_FILE = ".vatio-chat.json";
|
|
16
16
|
|
|
17
|
-
const SUBCOMMANDS = new Set(["transcript", "debug", "reset", "destroy", "delete", "help"]);
|
|
17
|
+
const SUBCOMMANDS = new Set(["show", "transcript", "debug", "reset", "destroy", "delete", "help"]);
|
|
18
18
|
const REMOVED_FLAGS = ["--channel", "--from", "--as", "--sandbox-url"];
|
|
19
19
|
|
|
20
20
|
export async function chat(config, args) {
|
|
@@ -30,14 +30,17 @@ export async function chat(config, args) {
|
|
|
30
30
|
|
|
31
31
|
const environment = takeEnv(args, { fallback: "preview" });
|
|
32
32
|
const timeout = Number(takeValue(args, "--timeout") ?? 120);
|
|
33
|
-
const
|
|
33
|
+
const lastValue = takeValue(args, "--last");
|
|
34
|
+
const last = Number(lastValue ?? 10);
|
|
35
|
+
const json = takeFlag(args, "--json");
|
|
34
36
|
const apiUrl = takeValue(args, "--api-url");
|
|
35
37
|
const token = takeValue(args, "--token");
|
|
36
38
|
|
|
37
|
-
const options = { environment, timeout, last, apiUrl, token };
|
|
39
|
+
const options = { environment, timeout, last, lastGiven: lastValue != null, json, apiUrl, token };
|
|
38
40
|
const sub = SUBCOMMANDS.has(args[0]) ? args.shift() : null;
|
|
39
41
|
|
|
40
42
|
if (sub === "help") return console.log(chatHelp());
|
|
43
|
+
if (sub === "show") return await showChat(config, options, args);
|
|
41
44
|
if (sub === "transcript") return await transcript(config, options);
|
|
42
45
|
if (sub === "debug") return await debugChat(config, options);
|
|
43
46
|
if (sub === "reset") return await resetChat(config, options);
|
|
@@ -54,6 +57,7 @@ function chatHelp() {
|
|
|
54
57
|
vatio chat "message" [--env NAME] [--timeout N]
|
|
55
58
|
vatio chat transcript [--last N]
|
|
56
59
|
vatio chat debug [--last N]
|
|
60
|
+
vatio chat show CHAT_ID [--last N] [--json]
|
|
57
61
|
vatio chat reset
|
|
58
62
|
vatio chat destroy CHAT_ID
|
|
59
63
|
|
|
@@ -61,6 +65,10 @@ function chatHelp() {
|
|
|
61
65
|
name like pr-42. A chat against live is a real conversation and shows up in
|
|
62
66
|
your inbox.
|
|
63
67
|
|
|
68
|
+
\`show\` reads any chat in the workspace by id -- one a visitor had on the web,
|
|
69
|
+
WhatsApp or Instagram, not only yours -- with the environment and deployment
|
|
70
|
+
that answered it, and every tool call.
|
|
71
|
+
|
|
64
72
|
The open chat per deployment is remembered in ${STATE_FILE}, so a second
|
|
65
73
|
\`vatio chat\` continues the first. \`reset\` starts over as a visitor the
|
|
66
74
|
workspace has never met.`;
|
|
@@ -200,6 +208,66 @@ async function debugChat(config, options) {
|
|
|
200
208
|
}
|
|
201
209
|
}
|
|
202
210
|
|
|
211
|
+
// Every message, not the first page: a chat worth reading by id is usually one
|
|
212
|
+
// that went wrong somewhere in the middle.
|
|
213
|
+
async function allMessages(api, chatId) {
|
|
214
|
+
const messages = [];
|
|
215
|
+
let after = null;
|
|
216
|
+
for (;;) {
|
|
217
|
+
const payload = await api.chatMessages({ chatId, after, limit: 200 });
|
|
218
|
+
const page = Array.isArray(payload.data) ? payload.data : [];
|
|
219
|
+
messages.push(...page);
|
|
220
|
+
if (page.length < 200) return messages;
|
|
221
|
+
after = page[page.length - 1].id;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function showChat(config, options, args) {
|
|
226
|
+
const chatId = args.shift();
|
|
227
|
+
if (!chatId || !/^\d+$/.test(chatId)) fail("Usage: vatio chat show CHAT_ID [--last N] [--json]");
|
|
228
|
+
|
|
229
|
+
const api = client(config, options);
|
|
230
|
+
const chat = await api.showChat({ chatId });
|
|
231
|
+
let messages = await allMessages(api, chatId);
|
|
232
|
+
if (options.lastGiven) messages = messages.slice(-options.last);
|
|
233
|
+
|
|
234
|
+
if (options.json) return console.log(JSON.stringify({ chat, messages }, null, 2));
|
|
235
|
+
|
|
236
|
+
const header = [
|
|
237
|
+
`Chat ${chat.chat_id}`,
|
|
238
|
+
chat.channel,
|
|
239
|
+
chat.environment,
|
|
240
|
+
chat.deployment_id && `deployment #${chat.deployment_id}`,
|
|
241
|
+
`agent ${chat.agent_slug}`
|
|
242
|
+
];
|
|
243
|
+
console.log(header.filter(Boolean).join(" · "));
|
|
244
|
+
console.log(`Started ${chat.created_at}, last activity ${chat.updated_at}`);
|
|
245
|
+
if (chat.identity) console.log(`Identity: ${JSON.stringify(chat.identity)}`);
|
|
246
|
+
console.log("");
|
|
247
|
+
|
|
248
|
+
for (const message of messages) {
|
|
249
|
+
const content = String(message.content ?? "").trim();
|
|
250
|
+
if (message.role === "system") {
|
|
251
|
+
console.log(`[system] ${content.length} characters of prompt (--json prints it)`);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (message.role === "tool") {
|
|
255
|
+
console.log(` [tool result] ${truncate(content, 400)}`);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const flags = message.discarded ? " (discarded)" : "";
|
|
259
|
+
if (content !== "" || flags) console.log(`[${message.role}]${flags} ${content}`);
|
|
260
|
+
for (const call of Array.isArray(message.tool_calls) ? message.tool_calls : []) {
|
|
261
|
+
console.log(` -> ${call.name}(${truncate(JSON.stringify(call.arguments ?? {}), 400)})`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (messages.length === 0) console.log("(no messages)");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function truncate(text, max) {
|
|
268
|
+
return text.length > max ? `${text.slice(0, max)}…` : text;
|
|
269
|
+
}
|
|
270
|
+
|
|
203
271
|
async function resetChat(config, options) {
|
|
204
272
|
const apiUrl = config.resolveApiUrl({ explicit: options.apiUrl });
|
|
205
273
|
const payload = await openChat(config, options, {
|
package/lib/commands/deploy.mjs
CHANGED
|
@@ -145,14 +145,17 @@ export async function push(config, args) {
|
|
|
145
145
|
|
|
146
146
|
export async function publish(config, args) {
|
|
147
147
|
// Here `--env` names the preview being promoted, not a destination: the
|
|
148
|
-
// destination of a publish is always live.
|
|
148
|
+
// destination of a publish is always live. Without it the platform promotes
|
|
149
|
+
// the most recent push, whichever preview it landed on.
|
|
149
150
|
const environment = takeEnv(args, { fallback: null });
|
|
150
151
|
const workspace = config.resolveWorkspaceRequired();
|
|
151
152
|
const payload = await deployClient(config, workspace).publish({
|
|
152
153
|
createdBy: process.env.USER ?? null,
|
|
153
154
|
environment
|
|
154
155
|
});
|
|
155
|
-
|
|
156
|
+
const from = asArray(payload.published_from);
|
|
157
|
+
const source = from.length > 0 ? ` from ${from.join(", ")}` : "";
|
|
158
|
+
console.log(`Published live deployment #${payload.deployment_id}${source} (git_sha=${JSON.stringify(payload.git_sha ?? null)})`);
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
export async function rollback(config) {
|
package/lib/commands/mcp.mjs
CHANGED
|
@@ -67,7 +67,8 @@ const COMMANDS = {
|
|
|
67
67
|
publish: {
|
|
68
68
|
usage: "[--env NAME]",
|
|
69
69
|
summary:
|
|
70
|
-
"Promote
|
|
70
|
+
"Promote the latest push to live (or the preview `--env` names), which is what customers " +
|
|
71
|
+
"see. Ask the developer first: this is " +
|
|
71
72
|
"the one step that changes what real visitors get.",
|
|
72
73
|
annotations: { readOnlyHint: false, destructiveHint: true }
|
|
73
74
|
},
|
|
@@ -77,11 +78,12 @@ const COMMANDS = {
|
|
|
77
78
|
annotations: { readOnlyHint: false, destructiveHint: true }
|
|
78
79
|
},
|
|
79
80
|
chat: {
|
|
80
|
-
usage: '"message" | transcript | debug | reset [--env NAME]',
|
|
81
|
+
usage: '"message" | transcript | debug | reset [--env NAME] | show CHAT_ID [--json]',
|
|
81
82
|
summary:
|
|
82
83
|
"Talk to the deployed agent as the developer holding the token, and read the transcript. " +
|
|
83
84
|
"`debug` shows the developer view, including tool calls. `--env live` is a real conversation " +
|
|
84
|
-
"that appears in the inbox."
|
|
85
|
+
"that appears in the inbox. `show CHAT_ID` reads any chat in the workspace — a visitor's on " +
|
|
86
|
+
"the web or WhatsApp too — with the environment and deployment that answered it.",
|
|
85
87
|
annotations: { readOnlyHint: false }
|
|
86
88
|
},
|
|
87
89
|
secrets: {
|
package/lib/config.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// ~/.vatio/config.json, or $VATIO_HOME/config.json.
|
|
3
3
|
//
|
|
4
4
|
// Deliberately the same file and the same keys. Someone who already ran
|
|
5
|
-
// `vatio login` through the curl installer can run `npx vatio push` without
|
|
5
|
+
// `vatio login` through the curl installer can run `npx @vatio-ai/cli push` without
|
|
6
6
|
// logging in again, and can go back, because neither client owns the
|
|
7
7
|
// credential -- the developer's home does.
|
|
8
8
|
//
|
package/lib/help.mjs
CHANGED
|
@@ -24,7 +24,8 @@ flag, the directory decides.
|
|
|
24
24
|
|
|
25
25
|
Deploy:
|
|
26
26
|
push [--env NAME] Validate the workspace, then update a preview
|
|
27
|
-
publish [--env NAME] Promote
|
|
27
|
+
publish [--env NAME] Promote the latest push to live. --env promotes
|
|
28
|
+
a specific preview instead
|
|
28
29
|
rollback Restore the previous live deployment
|
|
29
30
|
status Preview and live deployment state
|
|
30
31
|
diff [--env NAME] What this directory would change (default: preview)
|
|
@@ -35,6 +36,8 @@ flag, the directory decides.
|
|
|
35
36
|
Talk to your agent (as yourself — the token is the identity):
|
|
36
37
|
chat "message" [--env NAME] preview by default; --env live is real
|
|
37
38
|
chat transcript|debug|reset [--last N]
|
|
39
|
+
chat show CHAT_ID [--json] Any chat in the workspace (web, WhatsApp, ...) with
|
|
40
|
+
its channel, environment, deployment and tool calls
|
|
38
41
|
chat destroy CHAT_ID
|
|
39
42
|
|
|
40
43
|
Knowledge:
|
package/lib/version.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Read from package.json rather than written twice: `npx vatio` resolves a
|
|
1
|
+
// Read from package.json rather than written twice: `npx @vatio-ai/cli` resolves a
|
|
2
2
|
// version from the registry, and a constant in here could disagree with the
|
|
3
3
|
// one the developer actually downloaded.
|
|
4
4
|
|