@clawsaga/cli 0.1.27 → 0.1.28
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/CHANGELOG.md +4 -0
- package/bin/clawsaga.mjs +30 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Changes to this CLI and skill, newest first. Game, rule and API changes shared with MCP are in `clawsaga changelog`.
|
|
4
4
|
|
|
5
|
+
## 0.1.28
|
|
6
|
+
|
|
7
|
+
- Internal code cleanup. Commands, output and skill instructions are unchanged.
|
|
8
|
+
|
|
5
9
|
## 0.1.27
|
|
6
10
|
|
|
7
11
|
- Updated the response format to v3.18. Older CLIs reject responses from the current server. World quests replace `reward_tiers`, `your_tier` and `next_tier_points` with `reward_per_stage` and `reward_point_cap`.
|
package/bin/clawsaga.mjs
CHANGED
|
@@ -24565,7 +24565,7 @@ var CredentialStore = class {
|
|
|
24565
24565
|
// package.json
|
|
24566
24566
|
var package_default = {
|
|
24567
24567
|
name: "@clawsaga/cli",
|
|
24568
|
-
version: "0.1.
|
|
24568
|
+
version: "0.1.28",
|
|
24569
24569
|
homepage: "https://clawsaga.net",
|
|
24570
24570
|
repository: {
|
|
24571
24571
|
type: "git",
|
|
@@ -24640,7 +24640,7 @@ var retryAfterSchema = external_exports.object({
|
|
|
24640
24640
|
var schemaVersionSchema = external_exports.object({ schema_version: external_exports.string() });
|
|
24641
24641
|
var [supportedSchemaMajor = 0, supportedSchemaMinor = 0] = agentSchemaVersion.split(".").map(Number);
|
|
24642
24642
|
var checkOutcome = "The action may still have been applied; check its outcome before another change.";
|
|
24643
|
-
async function
|
|
24643
|
+
async function readJsonOrUndefined(response) {
|
|
24644
24644
|
return response.json().catch(() => void 0);
|
|
24645
24645
|
}
|
|
24646
24646
|
function serverMessage(body) {
|
|
@@ -24668,9 +24668,9 @@ function needsUpdate(body) {
|
|
|
24668
24668
|
var announcedCli;
|
|
24669
24669
|
function noteAnnouncedCli(response) {
|
|
24670
24670
|
const version2 = response.headers.get("ClawSaga-CLI-Version");
|
|
24671
|
-
if (version2
|
|
24672
|
-
|
|
24673
|
-
|
|
24671
|
+
if (!version2 || !/^\d+\.\d+\.\d+$/.test(version2)) return;
|
|
24672
|
+
const announcedIsNewer = version2.localeCompare(package_default.version, "en", { numeric: true }) > 0;
|
|
24673
|
+
if (announcedIsNewer) announcedCli = version2;
|
|
24674
24674
|
}
|
|
24675
24675
|
function announcedCliUpdate() {
|
|
24676
24676
|
return announcedCli;
|
|
@@ -24713,13 +24713,13 @@ var GameClient = class {
|
|
|
24713
24713
|
});
|
|
24714
24714
|
if (response.status >= 500) throw new CliError("SERVICE_UNAVAILABLE");
|
|
24715
24715
|
if (response.status === 429) {
|
|
24716
|
-
throw rateLimited(response, await
|
|
24716
|
+
throw rateLimited(response, await readJsonOrUndefined(response));
|
|
24717
24717
|
}
|
|
24718
24718
|
return response;
|
|
24719
24719
|
}
|
|
24720
24720
|
async decodeTokens(response) {
|
|
24721
24721
|
if (!response.ok) throw new CliError("AUTH_REQUIRED");
|
|
24722
|
-
const parsed = tokensSchema.safeParse(await
|
|
24722
|
+
const parsed = tokensSchema.safeParse(await readJsonOrUndefined(response));
|
|
24723
24723
|
if (!parsed.success) throw new CliError("INVALID_RESPONSE");
|
|
24724
24724
|
return {
|
|
24725
24725
|
...parsed.data,
|
|
@@ -24733,7 +24733,7 @@ var GameClient = class {
|
|
|
24733
24733
|
resource: `${this.origin}/`
|
|
24734
24734
|
});
|
|
24735
24735
|
if (!response.ok) throw new CliError("AUTH_START_FAILED");
|
|
24736
|
-
const parsed = deviceSchema.safeParse(await
|
|
24736
|
+
const parsed = deviceSchema.safeParse(await readJsonOrUndefined(response));
|
|
24737
24737
|
if (!parsed.success) throw new CliError("INVALID_RESPONSE");
|
|
24738
24738
|
const device = parsed.data;
|
|
24739
24739
|
if (new URL(device.verification_uri_complete).origin !== this.origin) {
|
|
@@ -24778,7 +24778,9 @@ var GameClient = class {
|
|
|
24778
24778
|
entries[this.origin] = credential;
|
|
24779
24779
|
return credential.access_token;
|
|
24780
24780
|
}
|
|
24781
|
-
const failure = errorSchema.safeParse(
|
|
24781
|
+
const failure = errorSchema.safeParse(
|
|
24782
|
+
await readJsonOrUndefined(polled)
|
|
24783
|
+
);
|
|
24782
24784
|
if (!failure.success) {
|
|
24783
24785
|
throw new CliError("AUTH_NOT_COMPLETED", {
|
|
24784
24786
|
reason: "invalid_response"
|
|
@@ -24822,7 +24824,7 @@ var GameClient = class {
|
|
|
24822
24824
|
body: JSON.stringify(input2)
|
|
24823
24825
|
});
|
|
24824
24826
|
noteAnnouncedCli(response);
|
|
24825
|
-
const body = await
|
|
24827
|
+
const body = await readJsonOrUndefined(response);
|
|
24826
24828
|
const message = serverMessage(body);
|
|
24827
24829
|
if (response.status === 401) {
|
|
24828
24830
|
throw new CliError("AUTH_REQUIRED", {
|
|
@@ -24862,10 +24864,13 @@ var GameClient = class {
|
|
|
24862
24864
|
}
|
|
24863
24865
|
return parsed.data;
|
|
24864
24866
|
}
|
|
24865
|
-
|
|
24867
|
+
/**
|
|
24868
|
+
* Reads a public document. It works before authorization, and the body is
|
|
24869
|
+
* not an agent game response.
|
|
24870
|
+
*/
|
|
24866
24871
|
async readDocument(path2, schema) {
|
|
24867
24872
|
const response = await this.send(`/api/v1/${path2}`, { method: "GET" });
|
|
24868
|
-
const body = await
|
|
24873
|
+
const body = await readJsonOrUndefined(response);
|
|
24869
24874
|
if (response.status === 429) throw rateLimited(response, body);
|
|
24870
24875
|
if (response.status >= 500) throw new CliError("SERVICE_UNAVAILABLE");
|
|
24871
24876
|
const parsed = schema.safeParse(body);
|
|
@@ -24931,7 +24936,8 @@ function ambushNotes(response, character) {
|
|
|
24931
24936
|
const activity = response.data.activity ?? void 0;
|
|
24932
24937
|
const ambush = lastResult?.ambush;
|
|
24933
24938
|
if (!lastResult || !ambush) return { notes };
|
|
24934
|
-
|
|
24939
|
+
const ambushIsCurrentActivity = activity?.kind === "combat" && activity.activity_id === ambush.activity_id;
|
|
24940
|
+
if (ambushIsCurrentActivity) {
|
|
24935
24941
|
notes.push(
|
|
24936
24942
|
`The ${lastResult.kind} activity is complete. Continue the ambush battle or retreat.`
|
|
24937
24943
|
);
|
|
@@ -25139,8 +25145,11 @@ async function updateCli(server) {
|
|
|
25139
25145
|
}
|
|
25140
25146
|
throw new CliError("UPDATE_FAILED");
|
|
25141
25147
|
}
|
|
25148
|
+
function isVerificationRead() {
|
|
25149
|
+
return process.env.CLAWSAGA_AUTO_UPDATE === "0";
|
|
25150
|
+
}
|
|
25142
25151
|
async function updateAnnouncedCli(version2, notify) {
|
|
25143
|
-
if (
|
|
25152
|
+
if (isVerificationRead()) return;
|
|
25144
25153
|
notify(
|
|
25145
25154
|
`Updating the CLI to ${version2}. The result above is final; wait for this command to finish.`
|
|
25146
25155
|
);
|
|
@@ -25154,8 +25163,7 @@ async function updateAnnouncedCli(version2, notify) {
|
|
|
25154
25163
|
}
|
|
25155
25164
|
}
|
|
25156
25165
|
async function recoverUpdate(error61, notify) {
|
|
25157
|
-
if (!(error61 instanceof CliError) || error61.code !== "UPDATE_REQUIRED" ||
|
|
25158
|
-
process.env.CLAWSAGA_AUTO_UPDATE === "0") {
|
|
25166
|
+
if (!(error61 instanceof CliError) || error61.code !== "UPDATE_REQUIRED" || isVerificationRead()) {
|
|
25159
25167
|
return error61;
|
|
25160
25168
|
}
|
|
25161
25169
|
const { server } = error61.detail;
|
|
@@ -25192,7 +25200,6 @@ function acceptedActivityNote(activity, nextPollAfterSeconds, requestId) {
|
|
|
25192
25200
|
activity_id: activity.activity_id,
|
|
25193
25201
|
kind: activity.kind,
|
|
25194
25202
|
started_at: activity.started_at,
|
|
25195
|
-
// 出力のJSONでは値のない項目が落ちる。
|
|
25196
25203
|
completes_at: activity.completes_at,
|
|
25197
25204
|
arrives_at: activity.arrives_at,
|
|
25198
25205
|
time_limit_at: activity.time_limit_at,
|
|
@@ -25219,7 +25226,7 @@ async function repeatActivity(client, path2, input2, values, count, options) {
|
|
|
25219
25226
|
},
|
|
25220
25227
|
repetition: summary(stoppedReason)
|
|
25221
25228
|
});
|
|
25222
|
-
const
|
|
25229
|
+
const finalResponseOfLot = async (lotInput, requestId) => {
|
|
25223
25230
|
const started = await client.invoke(path2, lotInput);
|
|
25224
25231
|
if (!started.ok) {
|
|
25225
25232
|
return { ...started, repetition: summary("start_rejected") };
|
|
@@ -25260,7 +25267,7 @@ async function repeatActivity(client, path2, input2, values, count, options) {
|
|
|
25260
25267
|
lastRequestId = requestId;
|
|
25261
25268
|
const lotInput = requestId === void 0 ? input2 : { ...input2, request_id: requestId };
|
|
25262
25269
|
try {
|
|
25263
|
-
const final = await
|
|
25270
|
+
const final = await finalResponseOfLot(lotInput, requestId);
|
|
25264
25271
|
if (final) return final;
|
|
25265
25272
|
} catch (error61) {
|
|
25266
25273
|
if (error61 instanceof CliError) {
|
|
@@ -25289,7 +25296,7 @@ async function walkRoute(client, path2, input2, values, route, notify) {
|
|
|
25289
25296
|
error: { message: "The travel stopped before reaching every location." },
|
|
25290
25297
|
repetition: summary(stoppedReason)
|
|
25291
25298
|
});
|
|
25292
|
-
const
|
|
25299
|
+
const finalResponseOfStep = async (to) => {
|
|
25293
25300
|
const started = await client.invoke(path2, { ...input2, to });
|
|
25294
25301
|
if (!started.ok) {
|
|
25295
25302
|
return { ...started, repetition: summary("start_rejected") };
|
|
@@ -25313,7 +25320,7 @@ async function walkRoute(client, path2, input2, values, route, notify) {
|
|
|
25313
25320
|
};
|
|
25314
25321
|
for (const to of route) {
|
|
25315
25322
|
try {
|
|
25316
|
-
const final = await
|
|
25323
|
+
const final = await finalResponseOfStep(to);
|
|
25317
25324
|
if (final) return final;
|
|
25318
25325
|
} catch (error61) {
|
|
25319
25326
|
if (error61 instanceof CliError) {
|
|
@@ -25505,12 +25512,13 @@ var optionsSchema = external_exports.object({
|
|
|
25505
25512
|
function isJsonObject(value) {
|
|
25506
25513
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25507
25514
|
}
|
|
25515
|
+
var maxStdinLength = 128 * 1024;
|
|
25508
25516
|
async function readStdin() {
|
|
25509
25517
|
process.stdin.setEncoding("utf8");
|
|
25510
25518
|
let text2 = "";
|
|
25511
25519
|
for await (const chunk of process.stdin) {
|
|
25512
25520
|
text2 += String(chunk);
|
|
25513
|
-
if (text2.length >
|
|
25521
|
+
if (text2.length > maxStdinLength) throw new CliError("INVALID_INPUT_FILE");
|
|
25514
25522
|
}
|
|
25515
25523
|
return text2;
|
|
25516
25524
|
}
|