@lingjingai/scriptctl 0.25.10 → 0.26.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.
@@ -0,0 +1,147 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { CliError, EXIT_INPUT, EXIT_OK, EXIT_USAGE } from "../common.js";
5
+ const VERSION_RE = /^\d+\.\d+\.\d+$/;
6
+ const UNRELEASED = "unreleased";
7
+ function repoRoot() {
8
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
9
+ }
10
+ function changesDir() {
11
+ return path.join(repoRoot(), "changes");
12
+ }
13
+ function readPackageVersion() {
14
+ const pkgPath = path.join(repoRoot(), "package.json");
15
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
16
+ return pkg.version ?? "0.0.0";
17
+ }
18
+ function versionParts(version) {
19
+ if (!VERSION_RE.test(version)) {
20
+ throw new CliError("CHANGELOG BLOCKED: version invalid", "Version must use x.y.z.", {
21
+ exitCode: EXIT_USAGE,
22
+ required: ["x.y.z"],
23
+ received: [version || "<empty>"],
24
+ nextSteps: ["Pass a released version such as `scriptctl changelog 0.25.10`."],
25
+ errorCode: "CHANGELOG_VERSION_INVALID",
26
+ });
27
+ }
28
+ const [major, minor, patch] = version.split(".").map((part) => Number(part));
29
+ return [major, minor, patch];
30
+ }
31
+ function compareVersions(a, b) {
32
+ const av = versionParts(a);
33
+ const bv = versionParts(b);
34
+ for (let i = 0; i < 3; i++) {
35
+ if (av[i] !== bv[i])
36
+ return av[i] - bv[i];
37
+ }
38
+ return 0;
39
+ }
40
+ function listReleasedVersions() {
41
+ const dir = changesDir();
42
+ return fs.readdirSync(dir)
43
+ .filter((name) => name.endsWith(".md"))
44
+ .map((name) => name.slice(0, -".md".length))
45
+ .filter((version) => VERSION_RE.test(version))
46
+ .sort(compareVersions);
47
+ }
48
+ function readChangeFile(version) {
49
+ return fs.readFileSync(path.join(changesDir(), `${version}.md`), "utf-8").trimEnd();
50
+ }
51
+ function missingVersion(version, available) {
52
+ return new CliError("CHANGELOG BLOCKED: version not found", `No changelog entry exists for ${version}.`, {
53
+ exitCode: EXIT_INPUT,
54
+ required: ["existing changelog version"],
55
+ received: [version],
56
+ nextSteps: [
57
+ available.length > 0
58
+ ? `Available versions: ${available.join(", ")}`
59
+ : "Add changes/<version>.md first.",
60
+ ],
61
+ errorCode: "CHANGELOG_VERSION_NOT_FOUND",
62
+ });
63
+ }
64
+ function emptyRange(from, to) {
65
+ return new CliError("CHANGELOG BLOCKED: range empty", `No released changelog entries found after ${from} through ${to}.`, {
66
+ exitCode: EXIT_INPUT,
67
+ required: ["a version range containing released changelog entries"],
68
+ received: [`--from ${from}`, `--to ${to}`],
69
+ nextSteps: ["Choose a wider range or run `scriptctl changelog <version>` for a known release."],
70
+ errorCode: "CHANGELOG_RANGE_EMPTY",
71
+ });
72
+ }
73
+ function bodyForVersions(versions) {
74
+ return versions.map(readChangeFile).join("\n\n");
75
+ }
76
+ export function commandChangelog(opts) {
77
+ const args = opts._args ?? [];
78
+ const versionArg = args[0]?.trim() ?? "";
79
+ const from = String(opts.from ?? "").trim();
80
+ const to = String(opts.to ?? "").trim();
81
+ const unreleased = Boolean(opts.unreleased);
82
+ if (args.length > 1) {
83
+ throw new CliError("CHANGELOG BLOCKED: too many arguments", "changelog accepts at most one version argument.", {
84
+ exitCode: EXIT_USAGE,
85
+ required: ["scriptctl changelog [version] [--from X] [--to Y] [--unreleased]"],
86
+ received: [args.join(" ")],
87
+ nextSteps: ["Pass a single version, or use --from/--to for a range."],
88
+ errorCode: "CHANGELOG_TOO_MANY_ARGS",
89
+ });
90
+ }
91
+ if (unreleased && (versionArg || from || to)) {
92
+ throw new CliError("CHANGELOG BLOCKED: option conflict", "--unreleased cannot combine with version, --from, or --to.", {
93
+ exitCode: EXIT_USAGE,
94
+ required: ["either --unreleased, a version, or a --from/--to range"],
95
+ received: ["--unreleased with another selector"],
96
+ nextSteps: ["Run `scriptctl changelog --unreleased` by itself."],
97
+ errorCode: "CHANGELOG_SELECTOR_CONFLICT",
98
+ });
99
+ }
100
+ if (versionArg && (from || to)) {
101
+ throw new CliError("CHANGELOG BLOCKED: option conflict", "A version argument cannot combine with --from or --to.", {
102
+ exitCode: EXIT_USAGE,
103
+ required: ["either a version argument, or --from/--to"],
104
+ received: [versionArg, from ? `--from ${from}` : "", to ? `--to ${to}` : ""].filter(Boolean),
105
+ nextSteps: ["Run `scriptctl changelog 0.25.10` or `scriptctl changelog --from 0.25.8 --to 0.25.10`."],
106
+ errorCode: "CHANGELOG_SELECTOR_CONFLICT",
107
+ });
108
+ }
109
+ if (unreleased) {
110
+ const body = readChangeFile(UNRELEASED);
111
+ return [{ title: "CHANGELOG", body, versions: [], unreleased: true }, EXIT_OK];
112
+ }
113
+ const available = listReleasedVersions();
114
+ const current = readPackageVersion();
115
+ if (versionArg) {
116
+ versionParts(versionArg);
117
+ if (!available.includes(versionArg))
118
+ throw missingVersion(versionArg, available);
119
+ const body = readChangeFile(versionArg);
120
+ return [{ title: "CHANGELOG", body, versions: [versionArg], unreleased: false }, EXIT_OK];
121
+ }
122
+ if (from || to) {
123
+ if (!from) {
124
+ throw new CliError("CHANGELOG BLOCKED: --from missing", "--from is required for range queries.", {
125
+ exitCode: EXIT_USAGE,
126
+ required: ["--from <x.y.z>"],
127
+ received: [to ? `--to ${to}` : "<missing>"],
128
+ nextSteps: ["Run `scriptctl changelog --from 0.25.8 --to 0.25.10`."],
129
+ errorCode: "CHANGELOG_FROM_MISSING",
130
+ });
131
+ }
132
+ versionParts(from);
133
+ const upper = to || current;
134
+ versionParts(upper);
135
+ if (!available.includes(upper))
136
+ throw missingVersion(upper, available);
137
+ const versions = available.filter((version) => compareVersions(version, from) > 0 && compareVersions(version, upper) <= 0);
138
+ if (versions.length === 0)
139
+ throw emptyRange(from, upper);
140
+ return [{ title: "CHANGELOG", body: bodyForVersions(versions), versions, from, to: upper, unreleased: false }, EXIT_OK];
141
+ }
142
+ if (!available.includes(current))
143
+ throw missingVersion(current, available);
144
+ const body = readChangeFile(current);
145
+ return [{ title: "CHANGELOG", body, versions: [current], unreleased: false }, EXIT_OK];
146
+ }
147
+ //# sourceMappingURL=changelog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/usecases/changelog.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingjingai/scriptctl",
3
- "version": "0.25.10",
3
+ "version": "0.26.0",
4
4
  "description": "剧本阶段统一 CLI:直转外部素材到 script.json,以及当前最终剧本的读取、校验、原子编辑与批量 patch 精修。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,6 +10,7 @@
10
10
  "types": "./dist/cli.d.ts",
11
11
  "files": [
12
12
  "dist",
13
+ "changes",
13
14
  "README.md"
14
15
  ],
15
16
  "engines": {