@zaisma/cli 0.14.0 → 0.15.0
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/package.json +1 -1
- package/zaisma.mjs +44 -0
package/package.json
CHANGED
package/zaisma.mjs
CHANGED
|
@@ -59,6 +59,7 @@ const COMMAND_ERROR_CODES = {
|
|
|
59
59
|
repeated_field: "A flag was given twice.",
|
|
60
60
|
missing_value: "A flag that takes a value was given none.",
|
|
61
61
|
takes_no_value: "A flag that takes no value was given one.",
|
|
62
|
+
conflicting_flags: "Two flags that don't go together were given, like logs --follow and --cursor.",
|
|
62
63
|
not_a_folder: "The folder to check or upload isn't a folder.",
|
|
63
64
|
not_a_file: "The file given (of statements, a dump to import, or a save) can't be read.",
|
|
64
65
|
file_exists: "database export won't write over a file that's already there.",
|
|
@@ -126,6 +127,19 @@ const COMMANDS = {
|
|
|
126
127
|
secrets: { about: "A game's secrets, which its game server reads as server.secrets and room.secrets: their names and when each was set, never the values", arguments: [{ name: "slug" }], flags: {} },
|
|
127
128
|
"secrets set": { about: "Set a secret for a game's server, replacing one of the same name: the value piped in, or typed without showing; it's never shown again", arguments: [{ name: "slug" }, { name: "secret_name" }], flags: {} },
|
|
128
129
|
"secrets delete": { about: "Delete one of a game's secrets", arguments: [{ name: "slug" }, { name: "secret_name" }], flags: {} },
|
|
130
|
+
logs: {
|
|
131
|
+
about: "What a game's server printed on Zaisma in the last 30 days, oldest first: the newest lines, older ones with --cursor, or new ones as they come with --follow",
|
|
132
|
+
arguments: [{ name: "slug" }],
|
|
133
|
+
flags: {
|
|
134
|
+
follow: { hasValue: false, about: "Keep printing new lines as the game server prints them, every 2 seconds, until Ctrl-C" },
|
|
135
|
+
"room-code": { hasValue: true, placeholder: "<code>", about: "Only lines printed in this room, like K7Q2MX" },
|
|
136
|
+
"minimum-level": { hasValue: true, choices: ["debug", "info", "warn", "error"], about: "debug (everything), info (all but debug), warn (warnings and errors) or error" },
|
|
137
|
+
"source-kind": { hasValue: true, choices: ["room", "request", "schedule", "webhook"], about: "Only lines printed in a room, onRequest, onSchedule or onWebhook" },
|
|
138
|
+
"search-text": { hasValue: true, placeholder: '"words"', about: "Only lines containing this, ignoring case" },
|
|
139
|
+
"maximum-line-count": { hasValue: true, placeholder: "<count>", about: "How many lines at most, up to 500; 100 by default" },
|
|
140
|
+
cursor: { hasValue: true, placeholder: "<next_cursor>", about: "The lines before an earlier answer's: the next_cursor it printed" },
|
|
141
|
+
},
|
|
142
|
+
},
|
|
129
143
|
forum: {
|
|
130
144
|
about: "Your forum topics and messages to Zaisma; one topic with every post you can see; or a search",
|
|
131
145
|
arguments: [{ name: "topic_id", isOptional: true }],
|
|
@@ -1240,6 +1254,35 @@ async function secrets(command, values) {
|
|
|
1240
1254
|
if (answer.next_steps.some((step) => step.tool === "update_game")) console.log(`It calls no other servers yet: list the hosts it uses this with, like zaisma allowed-hosts ${values.slug} discord.com`);
|
|
1241
1255
|
}
|
|
1242
1256
|
|
|
1257
|
+
/** A game server's logs (GET …/games/<slug>/logs), as the MCP's get_logs; --follow asks for new lines every 2 seconds. */
|
|
1258
|
+
async function logs(values, flags) {
|
|
1259
|
+
if (flags.follow && flags.cursor) refuse("conflicting_flags", { message: "--follow prints new lines, and --cursor older ones.", field: "cursor", fix: `Use one: zaisma logs ${values.slug} --follow, or zaisma logs ${values.slug} --cursor <next_cursor>.` });
|
|
1260
|
+
const filters = {};
|
|
1261
|
+
for (const [flag, input] of [["room-code", "room_code"], ["minimum-level", "minimum_level"], ["source-kind", "source_kind"], ["search-text", "search_text"], ["maximum-line-count", "maximum_line_count"], ["cursor", "cursor"]]) if (flags[flag] !== undefined) filters[input] = flags[flag];
|
|
1262
|
+
const ask = (more) => api("GET", `/games/${values.slug}/logs?${new URLSearchParams({ ...filters, ...more }).toString()}`);
|
|
1263
|
+
const print = (answer) => {
|
|
1264
|
+
if (isJson) {
|
|
1265
|
+
// Followed, each answer is one line of JSON.
|
|
1266
|
+
if (flags.follow) process.stdout.write(`${JSON.stringify(answer)}\n`);
|
|
1267
|
+
else printJson(answer);
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
for (const line of answer.log_lines) console.log(`${line.logged_at.slice(11, 23)} ${line.level.padEnd(5)} ${line.room_code ?? line.source_kind} ${line.text}`);
|
|
1271
|
+
};
|
|
1272
|
+
let answer = await ask({});
|
|
1273
|
+
print(answer);
|
|
1274
|
+
if (!flags.follow) {
|
|
1275
|
+
if (!isJson && !answer.log_lines.length) console.log(`No lines from ${values.slug}'s game server${Object.keys(filters).length ? " that match" : ""} in the last 30 days.`);
|
|
1276
|
+
if (!isJson && answer.next_cursor) console.log(`Older lines: zaisma logs ${values.slug} --cursor ${answer.next_cursor}`);
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
for (;;) {
|
|
1280
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
1281
|
+
answer = await ask({ new_lines_cursor: answer.new_lines_cursor });
|
|
1282
|
+
print(answer);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1243
1286
|
/** A secret's value: piped in (without the line break at its end), or typed in a terminal without showing it. */
|
|
1244
1287
|
async function readSecretValue(secretName) {
|
|
1245
1288
|
if (!process.stdin.isTTY) {
|
|
@@ -1426,6 +1469,7 @@ async function run({ command, values, flags, globalFlags, rest }) {
|
|
|
1426
1469
|
else if (command === "own-servers") await ownServers(values, flags);
|
|
1427
1470
|
else if (command === "links" || command.startsWith("links ")) await links(command, values, flags);
|
|
1428
1471
|
else if (command === "secrets" || command.startsWith("secrets ")) await secrets(command, values);
|
|
1472
|
+
else if (command === "logs") await logs(values, flags);
|
|
1429
1473
|
else if (command === "database" || command.startsWith("database ")) await database(command, values, flags);
|
|
1430
1474
|
else if (command === "saves" || command.startsWith("saves ")) await saves(command, values, flags);
|
|
1431
1475
|
else await forum(command, values, flags);
|