ship-or-theater 1.0.0 → 1.0.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/CHANGELOG.md +12 -0
- package/README.md +10 -0
- package/dist/cli.d.ts +10 -3
- package/dist/cli.js +102 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/{llm-gKw2aSfQ.d.ts → llm-BDKu9GhU.d.ts} +1 -8
- package/dist/mcp.js +14 -2
- package/dist/mcp.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.1] - 2026-11-07
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Updated `package.json`, CLI `--help`, and MCP `evaluate_claim` descriptions to begin with the plain-English summary: *"Paste in an AI claim you saw online and get a straight answer, with evidence: real (SHIPS), half-true (MIXED) or hype (THEATER)."*
|
|
12
|
+
- Landing page, README and social card now say who it's for and why; phone menu links to Principles.
|
|
13
|
+
- Upgraded `@anthropic-ai/sdk` from `^0.39.0` to `^1.6.0`, removing the transitive `formdata-node` / `node-domexception@1.0.0` install deprecation warning.
|
|
14
|
+
- `VERSION` is now read from `package.json` at runtime so CLI and MCP version metadata cannot drift from the package manifest.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- `npx ship-or-theater "<claim>" > file` from Git Bash on Windows could exit 0 with an empty file. The CLI now waits for `stdout` to finish writing (and drain) before it exits; verified with a real run through `npx` in Git Bash. `--out <file>` remains the most robust way to save a scorecard.
|
|
18
|
+
- Output write errors (for example a closed pipe) are reported on `stderr` with exit code `1` instead of crashing.
|
|
19
|
+
|
|
8
20
|
## [1.0.0] - 2026-11-07
|
|
9
21
|
|
|
10
22
|
### Added
|
package/README.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
<!-- sot:readme-pitch:start -->
|
|
2
|
+
# Saw an AI claim that sounds too good to be true?
|
|
3
|
+
|
|
4
|
+
Paste in an AI claim you saw online and get a straight answer, with evidence: real (SHIPS), half-true (MIXED) or hype (THEATER).
|
|
5
|
+
|
|
6
|
+
- Reading a launch post? Find out what actually shipped.
|
|
7
|
+
- Vetting a vendor demo? See what the evidence supports.
|
|
8
|
+
- Checking a headline before you share it? Get the reasons first.
|
|
9
|
+
<!-- sot:readme-pitch:end -->
|
|
10
|
+
|
|
1
11
|
<div align="center">
|
|
2
12
|
|
|
3
13
|
<img src="assets/logo.svg" alt="ship or theater" width="360">
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { L as LLM } from './llm-
|
|
1
|
+
import { L as LLM } from './llm-BDKu9GhU.js';
|
|
2
2
|
import '@anthropic-ai/sdk';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
interface CliStream {
|
|
6
6
|
isTTY?: boolean;
|
|
7
7
|
columns?: number;
|
|
8
|
-
write: (chunk: string) => boolean;
|
|
8
|
+
write: (chunk: string, callback?: (error?: Error | null) => void) => boolean;
|
|
9
|
+
once?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
10
|
+
off?: (event: string, listener: (...args: unknown[]) => void) => unknown;
|
|
9
11
|
}
|
|
10
12
|
interface CliIO {
|
|
11
13
|
stdout?: CliStream;
|
|
@@ -13,6 +15,11 @@ interface CliIO {
|
|
|
13
15
|
env?: NodeJS.ProcessEnv;
|
|
14
16
|
llmOverride?: LLM;
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Write a chunk to stdout and wait for both the write callback and stream
|
|
20
|
+
* drain when backpressure occurs on a pipe or redirected file descriptor.
|
|
21
|
+
*/
|
|
22
|
+
declare function writeStdout(stream: CliStream, chunk: string): Promise<void>;
|
|
16
23
|
declare function runCli(argv: string[], io?: CliIO): Promise<number>;
|
|
17
24
|
|
|
18
|
-
export { type CliIO, type CliStream, runCli };
|
|
25
|
+
export { type CliIO, type CliStream, runCli, writeStdout };
|
package/dist/cli.js
CHANGED
|
@@ -5,9 +5,21 @@ import { writeFile } from "fs/promises";
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/llm.ts
|
|
8
|
+
import { readFileSync } from "fs";
|
|
8
9
|
import Anthropic from "@anthropic-ai/sdk";
|
|
9
10
|
import "zod";
|
|
10
|
-
|
|
11
|
+
function readPackageVersion(pkgUrl = new URL("../package.json", import.meta.url)) {
|
|
12
|
+
try {
|
|
13
|
+
const raw = readFileSync(pkgUrl, "utf8");
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
if (typeof parsed.version === "string" && parsed.version.trim().length > 0) {
|
|
16
|
+
return parsed.version.trim();
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
return "1.0.1";
|
|
21
|
+
}
|
|
22
|
+
var VERSION = readPackageVersion();
|
|
11
23
|
var DEFAULT_MODEL = "claude-sonnet-5-5";
|
|
12
24
|
function resolveModel() {
|
|
13
25
|
const fromEnv = process.env.SOT_MODEL?.trim();
|
|
@@ -1226,6 +1238,68 @@ function createProgressReporter(stream = process.stderr, options = {}) {
|
|
|
1226
1238
|
}
|
|
1227
1239
|
|
|
1228
1240
|
// src/cli.ts
|
|
1241
|
+
async function writeStdout(stream, chunk) {
|
|
1242
|
+
await new Promise((resolve, reject) => {
|
|
1243
|
+
let settled = false;
|
|
1244
|
+
let writeReturned = false;
|
|
1245
|
+
let writeDone = false;
|
|
1246
|
+
let drainDone = true;
|
|
1247
|
+
const cleanup = (keepErrorListener = false) => {
|
|
1248
|
+
if (typeof stream.off === "function") {
|
|
1249
|
+
stream.off("drain", onDrain);
|
|
1250
|
+
if (!keepErrorListener) stream.off("error", onError);
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
const finish = (err) => {
|
|
1254
|
+
if (settled) return;
|
|
1255
|
+
if (err) {
|
|
1256
|
+
settled = true;
|
|
1257
|
+
cleanup(true);
|
|
1258
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
if (writeReturned && writeDone && drainDone) {
|
|
1262
|
+
settled = true;
|
|
1263
|
+
cleanup();
|
|
1264
|
+
resolve();
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
const onDrain = () => {
|
|
1268
|
+
drainDone = true;
|
|
1269
|
+
finish();
|
|
1270
|
+
};
|
|
1271
|
+
const onError = (err) => {
|
|
1272
|
+
finish(err ?? new Error("stdout stream error"));
|
|
1273
|
+
};
|
|
1274
|
+
if (typeof stream.once === "function") {
|
|
1275
|
+
stream.once("error", onError);
|
|
1276
|
+
}
|
|
1277
|
+
try {
|
|
1278
|
+
const expectsCallback = stream.write.length >= 2;
|
|
1279
|
+
const flushed = expectsCallback ? stream.write(chunk, (err) => {
|
|
1280
|
+
if (err) {
|
|
1281
|
+
finish(err);
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
writeDone = true;
|
|
1285
|
+
finish();
|
|
1286
|
+
}) : stream.write(chunk);
|
|
1287
|
+
if (!expectsCallback) {
|
|
1288
|
+
writeDone = true;
|
|
1289
|
+
}
|
|
1290
|
+
if (!flushed && typeof stream.once === "function") {
|
|
1291
|
+
drainDone = false;
|
|
1292
|
+
}
|
|
1293
|
+
writeReturned = true;
|
|
1294
|
+
if (!drainDone && typeof stream.once === "function") {
|
|
1295
|
+
stream.once("drain", onDrain);
|
|
1296
|
+
}
|
|
1297
|
+
finish();
|
|
1298
|
+
} catch (err) {
|
|
1299
|
+
finish(err);
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1229
1303
|
async function runCli(argv, io = {}) {
|
|
1230
1304
|
const stdout = io.stdout ?? process.stdout;
|
|
1231
1305
|
const stderr = io.stderr ?? process.stderr;
|
|
@@ -1233,7 +1307,7 @@ async function runCli(argv, io = {}) {
|
|
|
1233
1307
|
let exitCode = 0;
|
|
1234
1308
|
const program = new Command();
|
|
1235
1309
|
program.name("ship-or-theater").version(VERSION, "-V, --version", "print the package version").description(
|
|
1236
|
-
"
|
|
1310
|
+
"Paste in an AI claim you saw online and get a straight answer, with evidence: real (SHIPS), half-true (MIXED) or hype (THEATER)."
|
|
1237
1311
|
).argument(
|
|
1238
1312
|
"[claim]",
|
|
1239
1313
|
"the AI claim, announcement, or demo description to evaluate (or 'rubric' to print the fixed rubric)"
|
|
@@ -1280,12 +1354,19 @@ async function runCli(argv, io = {}) {
|
|
|
1280
1354
|
color: useColor,
|
|
1281
1355
|
width
|
|
1282
1356
|
});
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1357
|
+
try {
|
|
1358
|
+
if (options.out) {
|
|
1359
|
+
await writeFile(options.out, rubricText, "utf8");
|
|
1360
|
+
stderr.write(`Rubric written to ${options.out}
|
|
1286
1361
|
`);
|
|
1287
|
-
|
|
1288
|
-
|
|
1362
|
+
} else {
|
|
1363
|
+
await writeStdout(stdout, rubricText + "\n");
|
|
1364
|
+
}
|
|
1365
|
+
} catch (err) {
|
|
1366
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1367
|
+
stderr.write(`Failed to write output: ${message}
|
|
1368
|
+
`);
|
|
1369
|
+
exitCode = 1;
|
|
1289
1370
|
}
|
|
1290
1371
|
return;
|
|
1291
1372
|
}
|
|
@@ -1334,12 +1415,19 @@ async function runCli(argv, io = {}) {
|
|
|
1334
1415
|
progress.clear();
|
|
1335
1416
|
}
|
|
1336
1417
|
const output = format === "json" ? toJSON(scorecard) : format === "pretty" ? renderTerminal(scorecard, { color: useColor, width }) : renderMarkdown(scorecard);
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1418
|
+
try {
|
|
1419
|
+
if (options.out) {
|
|
1420
|
+
await writeFile(options.out, output, "utf8");
|
|
1421
|
+
stderr.write(`Scorecard written to ${options.out}
|
|
1340
1422
|
`);
|
|
1341
|
-
|
|
1342
|
-
|
|
1423
|
+
} else {
|
|
1424
|
+
await writeStdout(stdout, output + "\n");
|
|
1425
|
+
}
|
|
1426
|
+
} catch (err) {
|
|
1427
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1428
|
+
stderr.write(`Failed to write output: ${message}
|
|
1429
|
+
`);
|
|
1430
|
+
exitCode = 1;
|
|
1343
1431
|
}
|
|
1344
1432
|
});
|
|
1345
1433
|
try {
|
|
@@ -1367,6 +1455,7 @@ if (!process.env.VITEST) {
|
|
|
1367
1455
|
});
|
|
1368
1456
|
}
|
|
1369
1457
|
export {
|
|
1370
|
-
runCli
|
|
1458
|
+
runCli,
|
|
1459
|
+
writeStdout
|
|
1371
1460
|
};
|
|
1372
1461
|
//# sourceMappingURL=cli.js.map
|