soturail 0.2.2 → 0.2.3

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 CHANGED
@@ -57,6 +57,17 @@ npm run release:full -- --version X.Y.Z
57
57
 
58
58
  The release script never runs `npm audit fix --force`, never publishes when build/tests/runtime audit fail and never creates a GitHub release before npm publish succeeds. See [docs/release-workflow.md](docs/release-workflow.md).
59
59
 
60
+ ## Release Reliability
61
+
62
+ SotuRail includes a release preflight check to prevent stale package metadata, broken npm CLI binaries, missing release notes, and changelog/version mismatches.
63
+
64
+ ```bash
65
+ npm run build
66
+ npm test
67
+ npm run release:check
68
+ npm pack --dry-run
69
+ ```
70
+
60
71
  ## 2. Why SotuRail Exists
61
72
 
62
73
  AI coding agents often receive too much unstable context: full files, noisy test logs, repeated terminal output and long conversational summaries. SotuRail is designed to unify those workflows into one independent local-first tool without sending telemetry or inventing provider metrics.
@@ -88,7 +99,7 @@ Use directly with npx:
88
99
 
89
100
  ```bash
90
101
  npx soturail --help
91
- npx soturail@0.2.2 --help
102
+ npx soturail@0.2.3 --help
92
103
  ```
93
104
 
94
105
  Install globally:
@@ -96,6 +107,7 @@ Install globally:
96
107
  ```bash
97
108
  npm install -g soturail
98
109
  soturail --help
110
+ soturail --version
99
111
  ```
100
112
 
101
113
  For local development from source:
@@ -255,7 +267,7 @@ Windows users should see [docs/windows.md](docs/windows.md) for CMD vs PowerShel
255
267
 
256
268
  ## Road To Skill Rail
257
269
 
258
- Skill Rail and Workflow Rail are planned, not implemented in v0.2.2. See [docs/skill-rail.md](docs/skill-rail.md) and [docs/workflow-rail.md](docs/workflow-rail.md) for the security-first roadmap.
270
+ Skill Rail and Workflow Rail are planned, not implemented in v0.2.x. See [docs/skill-rail.md](docs/skill-rail.md) and [docs/workflow-rail.md](docs/workflow-rail.md) for the security-first roadmap.
259
271
 
260
272
  ## Comparison Philosophy
261
273
 
package/dist/cli.js CHANGED
@@ -19,12 +19,14 @@ import { registerRulesCommand } from "./commands/rules.js";
19
19
  import { registerSelfCommand } from "./commands/self.js";
20
20
  import { registerSpecCommand } from "./commands/spec.js";
21
21
  import { registerStatsCommand } from "./commands/stats.js";
22
+ import { registerReleaseCommand } from "./commands/release.js";
23
+ import { SOTURAIL_VERSION } from "./core/version.js";
22
24
  export function buildProgram() {
23
25
  const program = new Command();
24
26
  program
25
27
  .name("soturail")
26
28
  .description("Local-first Context OS rails for AI coding agents.")
27
- .version("0.2.2")
29
+ .version(SOTURAIL_VERSION)
28
30
  .showHelpAfterError();
29
31
  registerInitCommand(program);
30
32
  registerIndexCommand(program);
@@ -40,6 +42,7 @@ export function buildProgram() {
40
42
  registerMemoryCommand(program);
41
43
  registerNativeCommand(program);
42
44
  registerRulesCommand(program);
45
+ registerReleaseCommand(program);
43
46
  registerSelfCommand(program);
44
47
  registerDoctorCommand(program);
45
48
  registerStatsCommand(program);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerReleaseCommand(program: Command): void;
3
+ export declare function writeReleaseNotesSkeleton(version: string, root?: string): Promise<string>;
@@ -0,0 +1,59 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { formatReleasePreflight, runReleasePreflight } from "../core/release-preflight.js";
4
+ export function registerReleaseCommand(program) {
5
+ const release = program
6
+ .command("release")
7
+ .description("Run local release reliability checks and release-note helpers.");
8
+ release
9
+ .command("check")
10
+ .description("Validate package, CLI, changelog, release notes, pack metadata and runtime audit.")
11
+ .action(async () => {
12
+ const result = await runReleasePreflight(process.cwd());
13
+ process.stdout.write(`${formatReleasePreflight(result)}\n`);
14
+ if (!result.ok)
15
+ process.exitCode = 1;
16
+ });
17
+ release
18
+ .command("notes")
19
+ .description("Create a release notes skeleton for a version.")
20
+ .requiredOption("--version <version>", "Release version, for example X.Y.Z")
21
+ .action(async (options) => {
22
+ const filePath = await writeReleaseNotesSkeleton(options.version, process.cwd());
23
+ process.stdout.write(`Release notes written: ${path.relative(process.cwd(), filePath)}\n`);
24
+ });
25
+ }
26
+ export async function writeReleaseNotesSkeleton(version, root = process.cwd()) {
27
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) {
28
+ throw new Error(`Invalid version: ${version}`);
29
+ }
30
+ const filePath = path.join(path.resolve(root), `RELEASE_NOTES_v${version}.md`);
31
+ const contents = `# SotuRail v${version} - Release Notes
32
+
33
+ ## Install
34
+
35
+ npx soturail@${version} --help
36
+ npm install -g soturail
37
+ soturail --help
38
+
39
+ ## Highlights
40
+
41
+ - Update this section before publishing.
42
+
43
+ ## Validation
44
+
45
+ - \`npm run build\`
46
+ - \`npm test\`
47
+ - \`npm audit --omit=dev\`
48
+ - \`npm pack --dry-run\`
49
+ - \`node dist/cli.js --version\`
50
+
51
+ ## Links
52
+
53
+ - npm: https://www.npmjs.com/package/soturail
54
+ - GitHub: https://github.com/Soturine/soturail
55
+ `;
56
+ await fs.writeFile(filePath, contents, "utf8");
57
+ return filePath;
58
+ }
59
+ //# sourceMappingURL=release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../../src/commands/release.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAE3F,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,gEAAgE,CAAC,CAAC;IAEjF,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,mFAAmF,CAAC;SAChG,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,cAAc,CAAC,qBAAqB,EAAE,oCAAoC,CAAC;SAC3E,MAAM,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC7C,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAe,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE;IACnF,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,kBAAkB,OAAO,KAAK,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,eAAe,OAAO;;;;mBAItB,OAAO;;;;;;;;;;;;;;;;;;;;CAoBzB,CAAC;IACA,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface ReleaseGateResult {
2
+ id: string;
3
+ label: string;
4
+ ok: boolean;
5
+ required: boolean;
6
+ details: string;
7
+ }
8
+ export interface ReleasePreflightResult {
9
+ ok: boolean;
10
+ version: string | null;
11
+ packageName: string | null;
12
+ fullAuditDevOnly: boolean;
13
+ fullAuditFindings: string[];
14
+ gates: ReleaseGateResult[];
15
+ }
16
+ export interface ReleasePreflightOptions {
17
+ runAudit?: boolean;
18
+ runPack?: boolean;
19
+ cliCommand?: string[];
20
+ }
21
+ export declare function runReleasePreflight(root?: string, options?: ReleasePreflightOptions): Promise<ReleasePreflightResult>;
22
+ export declare function formatReleasePreflight(result: ReleasePreflightResult): string;
@@ -0,0 +1,199 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { promises as fs } from "node:fs";
4
+ import path from "node:path";
5
+ const SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
6
+ export async function runReleasePreflight(root = process.cwd(), options = {}) {
7
+ const resolvedRoot = path.resolve(root);
8
+ const runAudit = options.runAudit ?? true;
9
+ const runPack = options.runPack ?? true;
10
+ const gates = [];
11
+ const packageJson = await readOptionalJson(path.join(resolvedRoot, "package.json"));
12
+ const packageName = typeof packageJson?.name === "string" ? packageJson.name : null;
13
+ const version = typeof packageJson?.version === "string" ? packageJson.version : null;
14
+ addGate(gates, "package_version", "package.json version", Boolean(version && SEMVER_PATTERN.test(version)), version ?? "missing");
15
+ const packageLock = await readOptionalJson(path.join(resolvedRoot, "package-lock.json"));
16
+ const lockVersion = typeof packageLock?.version === "string" ? packageLock.version : null;
17
+ const lockRootVersion = packageLock && typeof packageLock === "object"
18
+ && "packages" in packageLock
19
+ && packageLock.packages
20
+ && typeof packageLock.packages === "object"
21
+ && "" in packageLock.packages
22
+ && packageLock.packages[""]
23
+ && typeof packageLock.packages[""] === "object"
24
+ && "version" in packageLock.packages[""]
25
+ && typeof packageLock.packages[""].version === "string"
26
+ ? packageLock.packages[""].version
27
+ : null;
28
+ addGate(gates, "package_lock_version", "package-lock version sync", Boolean(version && lockVersion === version && lockRootVersion === version), `package-lock.version=${lockVersion ?? "missing"}, packages[\"\"].version=${lockRootVersion ?? "missing"}`);
29
+ const cliVersion = await readCliVersion(resolvedRoot, options.cliCommand);
30
+ addGate(gates, "cli_version", "CLI runtime version sync", Boolean(version && cliVersion.code === 0 && cliVersion.stdout.trim() === version), cliVersion.code === 0 ? `cli=${cliVersion.stdout.trim() || "empty"}, package=${version ?? "missing"}` : cliVersion.stderr.trim());
31
+ if (runPack) {
32
+ const pack = await runProcess("npm", ["pack", "--dry-run"], resolvedRoot, true);
33
+ const combined = `${pack.stdout}\n${pack.stderr}`;
34
+ const expectedTarball = packageName && version ? `${packageName}-${version}.tgz` : null;
35
+ addGate(gates, "npm_pack_metadata", "npm pack metadata", Boolean(pack.code === 0 && expectedTarball && combined.includes(expectedTarball)), expectedTarball ? `expected ${expectedTarball}` : "missing package name or version");
36
+ }
37
+ else {
38
+ addGate(gates, "npm_pack_metadata", "npm pack metadata", true, "skipped by test options", false);
39
+ }
40
+ const readme = await readOptionalText(path.join(resolvedRoot, "README.md"));
41
+ addGate(gates, "readme_install", "README install instructions", Boolean(readme && /npx\s+soturail/.test(readme) && readme.includes("npm install -g soturail") && readme.includes("soturail --version")), readme ? "README.md contains npm/npx/global install guidance" : "README.md missing");
42
+ const changelog = await readOptionalText(path.join(resolvedRoot, "CHANGELOG.md"));
43
+ addGate(gates, "changelog_entry", "CHANGELOG version entry", Boolean(version && changelog?.includes(`## [${version}]`)), version ? `expected ## [${version}]` : "missing version");
44
+ const releaseNotesPath = version ? path.join(resolvedRoot, `RELEASE_NOTES_v${version}.md`) : "";
45
+ addGate(gates, "release_notes", "release notes file", Boolean(version && existsSync(releaseNotesPath)), version ? path.relative(resolvedRoot, releaseNotesPath) : "missing version");
46
+ addGate(gates, "license", "LICENSE file", existsSync(path.join(resolvedRoot, "LICENSE")), "LICENSE");
47
+ let fullAudit = { total: 0, names: [] };
48
+ let runtimeAudit = { total: 0, names: [] };
49
+ if (runAudit) {
50
+ const runtime = await runProcess("npm", ["audit", "--omit=dev", "--json"], resolvedRoot, true);
51
+ runtimeAudit = parseAudit(runtime.stdout);
52
+ addGate(gates, "runtime_audit", "runtime npm audit", runtime.code === 0 && runtimeAudit.total === 0, runtimeAudit.total === 0 ? "0 runtime vulnerabilities" : `${runtimeAudit.total} runtime findings: ${runtimeAudit.names.join(", ")}`);
53
+ const full = await runProcess("npm", ["audit", "--json"], resolvedRoot, true);
54
+ fullAudit = parseAudit(full.stdout);
55
+ }
56
+ else {
57
+ addGate(gates, "runtime_audit", "runtime npm audit", true, "skipped by test options", false);
58
+ }
59
+ const fullAuditDevOnly = fullAudit.total === 0 || (runtimeAudit.total === 0 && fullAudit.total >= runtimeAudit.total);
60
+ addGate(gates, "full_audit_explained", "full npm audit explanation", fullAuditDevOnly, fullAudit.total === 0
61
+ ? "0 full audit findings"
62
+ : `${fullAudit.total} full audit findings treated as dev-only: ${fullAudit.names.join(", ")}`);
63
+ return {
64
+ ok: gates.every((gate) => !gate.required || gate.ok),
65
+ version,
66
+ packageName,
67
+ fullAuditDevOnly,
68
+ fullAuditFindings: fullAudit.names,
69
+ gates
70
+ };
71
+ }
72
+ export function formatReleasePreflight(result) {
73
+ const lines = [
74
+ `Release preflight: ${result.ok ? "passed" : "failed"}`,
75
+ `package: ${result.packageName ?? "unknown"}`,
76
+ `version: ${result.version ?? "unknown"}`,
77
+ `full_audit_dev_only: ${result.fullAuditDevOnly}`,
78
+ "gates:"
79
+ ];
80
+ for (const gate of result.gates) {
81
+ lines.push(`- ${gate.ok ? "PASS" : "FAIL"} ${gate.id}: ${gate.details}`);
82
+ }
83
+ return lines.join("\n");
84
+ }
85
+ async function readCliVersion(root, cliCommand) {
86
+ if (cliCommand && cliCommand.length > 0) {
87
+ const command = cliCommand[0];
88
+ const args = cliCommand.slice(1);
89
+ if (!command)
90
+ return { code: 1, stdout: "", stderr: "empty CLI command" };
91
+ return runProcess(command, args, root, true);
92
+ }
93
+ const cliPath = path.join(root, "dist", "cli.js");
94
+ if (!existsSync(cliPath)) {
95
+ return { code: 1, stdout: "", stderr: "dist/cli.js is missing; run npm run build first" };
96
+ }
97
+ return runProcess(process.execPath, [cliPath, "--version"], root, true);
98
+ }
99
+ async function readOptionalText(filePath) {
100
+ try {
101
+ return await fs.readFile(filePath, "utf8");
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ async function readOptionalJson(filePath) {
108
+ const text = await readOptionalText(filePath);
109
+ if (!text)
110
+ return null;
111
+ try {
112
+ return JSON.parse(text);
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ }
118
+ function addGate(gates, id, label, ok, details, required = true) {
119
+ gates.push({ id, label, ok, details, required });
120
+ }
121
+ function parseAudit(text) {
122
+ try {
123
+ const parsed = JSON.parse(text);
124
+ return {
125
+ total: parsed.metadata?.vulnerabilities?.total ?? 0,
126
+ names: Object.keys(parsed.vulnerabilities ?? {})
127
+ };
128
+ }
129
+ catch {
130
+ return { total: -1, names: [] };
131
+ }
132
+ }
133
+ async function runProcess(command, args, cwd, allowFailure = false) {
134
+ return new Promise((resolve, reject) => {
135
+ const spawnSpec = resolveSpawn(command, args);
136
+ const child = spawn(spawnSpec.command, spawnSpec.args, {
137
+ cwd,
138
+ shell: false,
139
+ windowsHide: true,
140
+ env: process.env
141
+ });
142
+ let stdout = "";
143
+ let stderr = "";
144
+ child.stdout?.on("data", (chunk) => {
145
+ stdout += chunk.toString();
146
+ });
147
+ child.stderr?.on("data", (chunk) => {
148
+ stderr += chunk.toString();
149
+ });
150
+ child.on("error", reject);
151
+ child.on("close", (code) => {
152
+ const result = { code: code ?? 1, stdout, stderr };
153
+ if ((code ?? 1) !== 0 && !allowFailure) {
154
+ reject(new Error(`${command} ${args.join(" ")} failed with exit code ${code ?? 1}`));
155
+ }
156
+ else {
157
+ resolve(result);
158
+ }
159
+ });
160
+ });
161
+ }
162
+ function resolveSpawn(command, args) {
163
+ if (process.platform !== "win32")
164
+ return { command, args };
165
+ if (command === "npm" || command === "npx") {
166
+ const cli = npmCliPath(command);
167
+ if (cli)
168
+ return { command: process.execPath, args: [cli, ...args] };
169
+ }
170
+ if (command === "node")
171
+ return { command: process.execPath, args };
172
+ return { command: resolveWindowsCommand(command), args };
173
+ }
174
+ function npmCliPath(command) {
175
+ const npmExecPath = process.env.npm_execpath;
176
+ const candidates = [];
177
+ if (npmExecPath) {
178
+ const dir = path.dirname(npmExecPath);
179
+ candidates.push(path.resolve(dir, command === "npm" ? "npm-cli.js" : "npx-cli.js"));
180
+ }
181
+ const nodeDir = path.dirname(process.execPath);
182
+ candidates.push(path.resolve(nodeDir, "node_modules", "npm", "bin", command === "npm" ? "npm-cli.js" : "npx-cli.js"));
183
+ return candidates.find((candidate) => existsSync(candidate));
184
+ }
185
+ function resolveWindowsCommand(command) {
186
+ if (path.isAbsolute(command) && existsSync(command))
187
+ return command;
188
+ const extensions = path.extname(command) ? [""] : [".exe", ".cmd", ".bat", ""];
189
+ const entries = (process.env.PATH ?? "").split(path.delimiter).filter(Boolean);
190
+ for (const entry of entries) {
191
+ for (const extension of extensions) {
192
+ const candidate = path.resolve(entry, `${command}${extension}`);
193
+ if (existsSync(candidate))
194
+ return candidate;
195
+ }
196
+ }
197
+ return command;
198
+ }
199
+ //# sourceMappingURL=release-preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-preflight.js","sourceRoot":"","sources":["../../src/core/release-preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const SOTURAIL_VERSION = "0.2.3";
@@ -0,0 +1,3 @@
1
+ // Generated by scripts/sync-version.mjs from package.json. Do not edit manually.
2
+ export const SOTURAIL_VERSION = "0.2.3";
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/core/version.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC"}
@@ -11,10 +11,22 @@ Before publishing:
11
11
  - [ ] `node dist/cli.js self all`
12
12
  - [ ] `npm pack --dry-run`
13
13
  - [ ] `npm run release:check`
14
+ - [ ] `node dist/cli.js --version` matches `package.json`.
14
15
  - [ ] Confirm docs mention limitations honestly.
15
16
  - [ ] Confirm no telemetry exists.
16
17
  - [ ] Confirm no `git push` is routed through `soturail run`.
17
18
 
19
+ ## Version Sync
20
+
21
+ Check four separate release identifiers before publishing:
22
+
23
+ - npm package version: `package.json` and `package-lock.json`.
24
+ - CLI runtime version: `node dist/cli.js --version`.
25
+ - Git tag: created only when the release process calls for it.
26
+ - GitHub release: created only after npm publish succeeds.
27
+
28
+ The package version and CLI runtime version must match. `npm run build` regenerates the CLI version source from `package.json`, and `npm run release:check` verifies the built CLI before publication.
29
+
18
30
  ## Audit Distinction
19
31
 
20
32
  `npm audit` checks all dependencies, including dev dependencies used for local tests and builds.
@@ -23,7 +35,35 @@ Before publishing:
23
35
 
24
36
  Runtime audit is clean with `npm audit --omit=dev`. Remaining audit findings, if any, are development dependency findings and should be upgraded safely without `--force`.
25
37
 
26
- For v0.2.2, the full audit findings are in the Vitest/Vite development test stack. npm's suggested fix is a semver-major Vitest upgrade, so do not run `npm audit fix --force` blindly.
38
+ For v0.2.x, the full audit findings are in the Vitest/Vite development test stack when present. npm's suggested fix may be a semver-major Vitest upgrade, so do not run `npm audit fix --force` blindly.
39
+
40
+ ## npm Login And 2FA
41
+
42
+ Use browser-based npm login before publishing:
43
+
44
+ ```bash
45
+ npm login --auth-type=web
46
+ npm whoami
47
+ ```
48
+
49
+ If npm requires a one-time password during publish, provide a fresh authenticator code through `NPM_CONFIG_OTP` or `--otp`. Do not commit tokens, OTPs or npm credentials.
50
+
51
+ PowerShell example:
52
+
53
+ ```powershell
54
+ $env:NPM_CONFIG_OTP="<code>"
55
+ npm run release:publish -- --version X.Y.Z
56
+ Remove-Item Env:NPM_CONFIG_OTP
57
+ ```
58
+
59
+ After npm publish succeeds, verify:
60
+
61
+ ```bash
62
+ npm view soturail version
63
+ npx --yes soturail@X.Y.Z --version
64
+ ```
65
+
66
+ Create or update the GitHub release only after those npm checks pass.
27
67
 
28
68
  ## Windows Paste Safety
29
69
 
@@ -10,6 +10,14 @@ npm run release:check
10
10
 
11
11
  Runs install, build, tests, runtime audit, self-dogfooding, pack dry-run and npm version checks. It also reports whether full audit findings are development-only.
12
12
 
13
+ The check also verifies:
14
+
15
+ - `package.json` and `package-lock.json` version sync;
16
+ - `node dist/cli.js --version` matches the package version;
17
+ - npm pack dry-run emits the matching tarball name;
18
+ - `CHANGELOG.md` and `RELEASE_NOTES_vX.Y.Z.md` exist for the local version;
19
+ - README install instructions and `LICENSE` exist.
20
+
13
21
  ## Prepare
14
22
 
15
23
  ```bash
@@ -33,7 +41,22 @@ Prepare mode:
33
41
  npm run release:publish -- --version X.Y.Z
34
42
  ```
35
43
 
36
- Publish mode refuses to publish if build, tests or runtime audit fail, if the git tree is dirty, or if the version already exists on npm. If npm asks for 2FA or authentication, rerun the same command after completing the auth step.
44
+ Publish mode refuses to publish if build, tests, release preflight or runtime audit fail, if the git tree is dirty, or if the version already exists on npm.
45
+
46
+ For browser-based npm login:
47
+
48
+ ```bash
49
+ npm login --auth-type=web
50
+ npm whoami
51
+ ```
52
+
53
+ If npm asks for 2FA during publish, use a fresh authenticator code:
54
+
55
+ ```powershell
56
+ $env:NPM_CONFIG_OTP="<code>"
57
+ npm run release:publish -- --version X.Y.Z
58
+ Remove-Item Env:NPM_CONFIG_OTP
59
+ ```
37
60
 
38
61
  ## Full
39
62
 
@@ -43,6 +66,13 @@ npm run release:full -- --version X.Y.Z
43
66
 
44
67
  Full mode runs prepare, publish and then creates or updates the GitHub release using `gh` when available. If the npm version already exists, full mode skips npm publish and only creates or updates the GitHub release.
45
68
 
69
+ Only create or update the GitHub release after npm publish succeeds and these checks pass:
70
+
71
+ ```bash
72
+ npm view soturail version
73
+ npx --yes soturail@X.Y.Z --version
74
+ ```
75
+
46
76
  Safety rules:
47
77
 
48
78
  - Never run `npm audit fix --force`.
@@ -1,6 +1,6 @@
1
1
  # Skill Rail
2
2
 
3
- Skill Rail is planned for v0.3.0. It is not implemented in v0.2.2.
3
+ Skill Rail is planned for v0.3.0. It is not implemented in v0.2.x.
4
4
 
5
5
  The goal is to turn approved SotuRail specs, rules and workflows into portable, reviewable agent skills without installing untrusted marketplace content automatically.
6
6
 
package/docs/windows.md CHANGED
@@ -26,7 +26,7 @@ From a source checkout:
26
26
  npm run build
27
27
  npm pack --dry-run
28
28
  npm pack
29
- npm install -g .\soturail-0.2.1.tgz
29
+ npm install -g .\soturail-0.2.3.tgz
30
30
  soturail --version
31
31
  ```
32
32
 
@@ -74,3 +74,24 @@ npx soturail --help
74
74
  ## Safety
75
75
 
76
76
  SotuRail blocks destructive command shapes through `soturail run`, including `rm -rf`, `sudo`, `del /s`, downloaded script piping and automatic `git push`.
77
+
78
+ ## Release Checks On Windows
79
+
80
+ Before publishing from Windows, run:
81
+
82
+ ```powershell
83
+ npm run build
84
+ node .\dist\cli.js --version
85
+ npm run release:check
86
+ ```
87
+
88
+ `package.json`, `package-lock.json`, `node dist/cli.js --version`, the npm tarball name, the changelog and the release notes must all agree on the same version.
89
+
90
+ Use browser-based npm login when needed:
91
+
92
+ ```powershell
93
+ npm login --auth-type=web
94
+ npm whoami
95
+ ```
96
+
97
+ Only create the GitHub release after npm publish succeeds and `npx --yes soturail@X.Y.Z --version` prints the published version.
@@ -1,6 +1,6 @@
1
1
  # Workflow Rail
2
2
 
3
- Workflow Rail is planned for v0.4.0. It is not implemented in v0.2.2.
3
+ Workflow Rail is planned for v0.4.0. It is not implemented in v0.2.x.
4
4
 
5
5
  The goal is to describe repeatable engineering workflows as local, auditable artifacts that can later export into Skill Rail or an MCP server.
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soturail",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Local-first context rails for AI coding agents: reversible terminal compression, progressive repo reading, SDD workflows, hooks, benchmarks, memory and cache-friendly payloads.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,8 @@
16
16
  "docs"
17
17
  ],
18
18
  "scripts": {
19
- "build": "tsc -p tsconfig.json",
19
+ "sync:version": "node scripts/sync-version.mjs",
20
+ "build": "npm run sync:version && tsc -p tsconfig.json",
20
21
  "prepack": "npm run build",
21
22
  "test": "vitest run",
22
23
  "typecheck": "tsc -p tsconfig.json --noEmit",