From 49c64afe218febbbc5940cb9642ea48c2633885e Mon Sep 17 00:00:00 2001 From: Smirk1921 Date: Thu, 8 Oct 2026 01:45:03 +0800 Subject: [PATCH] fix(version): unify hardcoded version strings to pkg.version (v0.8.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cli/index.ts: .version("0.1.0") → .version(pkg.version) - mcp/server.ts: SERVER_VERSION = pkg.version - archive/ttsmod.ts: TOOL_VERSION = pkg.version - archive/detect.ts / assets/check.ts / assets/fetch.ts / host/s3.ts: user-agent string now built from pkg.version All 7 sites now follow the pattern established in hub/control.ts:111 (import pkg from "../../package.json" with { type: "json" }). Future version bumps only need to update package.json. Also: - Bump package.json version to 0.8.0 (MINOR — hub contract extension) - Add CHANGELOG [0.8.0] section + backfill [0.7.1] section - Update archive-ttsmod.test.ts to assert version === pkg.version - Update phase4.acceptance.test.ts TODO comment to reference pkg.version --- CHANGELOG.md | 45 +++++++++++++++++++++ package-lock.json | 4 +- package.json | 2 +- src/archive/detect.ts | 3 +- src/archive/ttsmod.ts | 5 ++- src/assets/check.ts | 4 +- src/assets/fetch.ts | 3 +- src/cli/index.ts | 3 +- src/host/s3.ts | 3 +- src/mcp/server.ts | 5 ++- tests/integration/phase4.acceptance.test.ts | 4 +- tests/unit/archive-ttsmod.test.ts | 3 +- 12 files changed, 69 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f2ffd..811e505 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > Phase tags (`v0.x.0-phaseN`) are annotated on the corresponding commits for > historical reference; the npm-published version drops the `-phaseN` suffix. +## [0.8.0] - 2026-10-08 — Desktop UI + hub contract extension + +### Added + +- **hub**: 2 new routes (`POST /v1/files/read`, `PUT /v1/files/write`) for + desktop UI file operations, with path-traversal protection and optimistic + locking via sha256. +- **hub**: `--app-mode` CLI flag — error responses now include + `details.userAction` for UI rendering. +- **hub**: `/v1/status` response gains `hub.version` and `hub.appMode` fields. +- **hub**: loopback CORS headers for Vite dev-server → hub communication. +- **tts-desktop** (separate repo): Tauri 2 + React 18 desktop workbench, + implementing the Round-03 blueprint design (5 layers, 9 components, SSE event + flow, ConfirmGate for all destructive ops). + +### Fixed + +- **version**: unified 7 hardcoded version strings to read from `pkg.version` + (cli/index.ts, mcp/server.ts, archive/ttsmod.ts, archive/detect.ts, + assets/check.ts, assets/fetch.ts, host/s3.ts). Previously `tts --version` + printed `0.1.0` regardless of `package.json`. All sites now follow the + pattern established in `hub/control.ts` (`import pkg from "../../package.json" + with { type: "json" }`); future version bumps only need to update + `package.json`. + +### Test baseline + +- 2057 unit tests passing locally (with `TTS_EXTRACTED_DIR`), 2024 in CI + (fixture-dependent tests skip), 0 failed. + +## [0.7.1] - 2026-10-07 — Republish via CI with corrected dependencies + +### Fixed + +- **packaging**: moved `execa` from `devDependencies` to `dependencies` — + `npm install -g tts-toolkit@0.7.0` previously failed with + `ERR_MODULE_NOT_FOUND` when any CLI command tried to spawn kpsteam or other + subprocesses. v0.7.0 was deprecated on npm in favor of this release. + +### Changed + +- **release**: switched from manual `npm publish` to GitHub Actions + `release.yml` (tag-triggered, `npm publish --provenance --access public`). + v0.7.1 is the first version published via CI. + ## [0.7.0] - 2026-10-06 — Phase 7: Lua test runner + Workshop publish ### Added diff --git a/package-lock.json b/package-lock.json index c95514c..d2392d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@smirk1921/tts-toolkit", - "version": "0.7.1", + "version": "0.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@smirk1921/tts-toolkit", - "version": "0.7.1", + "version": "0.8.0", "license": "MIT", "dependencies": { "@modelcontextprotocol/server": "^2.3.0", diff --git a/package.json b/package.json index eed215a..a61d2e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@smirk1921/tts-toolkit", - "version": "0.7.1", + "version": "0.8.0", "description": "Toolchain for Tabletop Simulator mod creators: pack workspace, atlas slicing, git-based version control, hub daemon, MCP integration, Lua test runner, and Steam Workshop publishing.", "author": "Smirk1921", "license": "MIT", diff --git a/src/archive/detect.ts b/src/archive/detect.ts index 5cd5837..eb5810a 100644 --- a/src/archive/detect.ts +++ b/src/archive/detect.ts @@ -42,6 +42,7 @@ import path from "node:path"; import { ProxyAgent, request } from "undici"; +import pkg from "../../package.json" with { type: "json" }; import { t } from "../i18n/index.js"; import { sanitizeUrl } from "./cachekey.js"; @@ -289,7 +290,7 @@ export async function httpProbeContentType( dispatcher, headersTimeout: timeoutMs, bodyTimeout: timeoutMs, - headers: { "user-agent": "tts-toolkit/0.1.0" }, + headers: { "user-agent": `tts-toolkit/${pkg.version}` }, }); if ([301, 302, 303, 307, 308].includes(res.statusCode)) { const location = res.headers.location; diff --git a/src/archive/ttsmod.ts b/src/archive/ttsmod.ts index 8266efc..5f68a2a 100644 --- a/src/archive/ttsmod.ts +++ b/src/archive/ttsmod.ts @@ -87,6 +87,7 @@ import { mkdir, readFile, stat, writeFile } from "node:fs/promises"; import path from "node:path"; import { crc32, deflateRawSync, inflateRawSync } from "node:zlib"; +import pkg from "../../package.json" with { type: "json" }; import { getLang, initI18n, t, type Lang } from "../i18n/index.js"; import { PackError } from "../pack/packyaml.js"; import { cacheFileName, sanitizeUrl } from "./cachekey.js"; @@ -106,8 +107,8 @@ import { /** 工具名(manifest 用;与 package.json 的 name 一致) */ const TOOL_NAME = "tts-toolkit"; -/** 工具版本(manifest 用;与 package.json / CLI 的 version 保持同步) */ -const TOOL_VERSION = "0.1.0"; +/** 工具版本(manifest 用;与 package.json / CLI 的 version 保持同步,import 时直接读) */ +const TOOL_VERSION = pkg.version; /** manifest 条目名(ZIP 根;旧读取器不认识根条目会当普通文件忽略,无害) */ export const MANIFEST_ENTRY = "manifest.json"; diff --git a/src/assets/check.ts b/src/assets/check.ts index fe0f282..0cb8ee9 100644 --- a/src/assets/check.ts +++ b/src/assets/check.ts @@ -25,6 +25,8 @@ import { ProxyAgent, request } from "undici"; import { z } from "zod"; +import pkg from "../../package.json" with { type: "json" }; + // --------------------------------------------------------------------------- // 常量 // --------------------------------------------------------------------------- @@ -39,7 +41,7 @@ const DEFAULT_TIMEOUT_MS = 10_000; const HEAD_UNSUPPORTED_STATUSES: readonly number[] = [405, 501]; /** 请求 UA(部分 CDN 对空 UA 更苛刻;保持 ASCII,避免 header 编码问题) */ -const USER_AGENT = "tts-toolkit/0.1.0"; +const USER_AGENT = `tts-toolkit/${pkg.version}`; /** * 硬性超时相对 timeoutMs 的宽限(毫秒)。 diff --git a/src/assets/fetch.ts b/src/assets/fetch.ts index 00b40ec..c2eebbf 100644 --- a/src/assets/fetch.ts +++ b/src/assets/fetch.ts @@ -48,6 +48,7 @@ import { ProxyAgent, request } from "undici"; import { z } from "zod"; +import pkg from "../../package.json" with { type: "json" }; import { isLangVariant, isLocalFileUrl, isMissingProtocol } from "../deck/patch.js"; import { t } from "../i18n/index.js"; import { PackError } from "../pack/packyaml.js"; @@ -75,7 +76,7 @@ const HEAD_UNSUPPORTED_STATUSES: readonly number[] = [405, 501]; const REDIRECT_STATUSES: readonly number[] = [301, 302, 303, 307, 308]; /** 请求 UA(与 check.ts 保持一致) */ -const USER_AGENT = "tts-toolkit/0.1.0"; +const USER_AGENT = `tts-toolkit/${pkg.version}`; /** 批次结束时关闭 ProxyAgent 的上限(毫秒),超时改强制 destroy(与 check.ts 一致) */ const AGENT_CLOSE_TIMEOUT_MS = 2_000; diff --git a/src/cli/index.ts b/src/cli/index.ts index c0adc2e..9a8c63e 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -18,6 +18,7 @@ import { Command, CommanderError } from "commander"; +import pkg from "../../package.json" with { type: "json" }; import { initI18n, t, type Lang } from "../i18n/index.js"; import { assetsCommand } from "./commands/assets.js"; import { buildCommand } from "./commands/build.js"; @@ -86,7 +87,7 @@ const program = new Command(); program .name("tts") .description(t("cli.program.description")) - .version("0.1.0", "-V, --version", t("cli.option.version")) + .version(pkg.version, "-V, --version", t("cli.option.version")) .helpOption("-h, --help", t("cli.option.help")) .option("--lang ", t("cli.option.lang")) .option("--dev", t("cli.option.dev")) diff --git a/src/host/s3.ts b/src/host/s3.ts index eb27c71..c731f6d 100644 --- a/src/host/s3.ts +++ b/src/host/s3.ts @@ -40,6 +40,7 @@ import { createHash, createHmac } from "node:crypto"; import { request } from "undici"; +import pkg from "../../package.json" with { type: "json" }; import { t } from "../i18n/index.js"; import { PackError } from "../pack/packyaml.js"; import { DEFAULT_UPLOAD_TIMEOUT_MS, parseUploadOptions, probeHttpLiveness, safeObjectName, validateUploadFiles } from "./types.js"; @@ -59,7 +60,7 @@ const ALGORITHM = "AWS4-HMAC-SHA256"; export const S3_MAX_PUT_BYTES = 5 * 1024 ** 3; /** 非实体请求 UA(与 src/assets/check.ts 保持一致) */ -const USER_AGENT = "tts-toolkit/0.1.0"; +const USER_AGENT = `tts-toolkit/${pkg.version}`; /** 常见扩展名 → MIME(缺省 application/octet-stream) */ const MIME_BY_EXTENSION: Readonly> = Object.freeze({ diff --git a/src/mcp/server.ts b/src/mcp/server.ts index a4d8364..eb80af9 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -43,6 +43,7 @@ import { McpServer } from "@modelcontextprotocol/server"; import { StdioServerTransport } from "@modelcontextprotocol/server/stdio"; +import pkg from "../../package.json" with { type: "json" }; import { initI18n, type Lang } from "../i18n/index.js"; import { HubClient } from "./client.js"; import { register as registerAssets } from "./tools/assets.js"; @@ -61,8 +62,8 @@ import { register as registerTestRun } from "./tools/test-run.js"; /** MCP 服务器名(MCP 客户端 initialize 时可见)。 */ const SERVER_NAME = "tts-toolkit"; -/** MCP 服务器版本(与 package.json 的 version 保持一致)。 */ -const SERVER_VERSION = "0.1.0"; +/** MCP 服务器版本(与 package.json 的 version 保持一致,import 时直接读)。 */ +const SERVER_VERSION = pkg.version; /** `--lang` 参数的合法字面值(i18n 模块对显式 lang 不做猜测,只认全称)。 */ function isSupportedLang(value: string | undefined): value is Lang { diff --git a/tests/integration/phase4.acceptance.test.ts b/tests/integration/phase4.acceptance.test.ts index 1c1d321..b7dc56b 100644 --- a/tests/integration/phase4.acceptance.test.ts +++ b/tests/integration/phase4.acceptance.test.ts @@ -411,8 +411,8 @@ describe("阶段 4 集成验收:hub 守护进程 + S2 控制通道 + CLI 委 // 1) spawn `node dist/mcp/main.js`(可加 `--lang zh-CN`;server.ts 只认 // "zh-CN"/"en-US",非法值 stderr 告警后回退,见 server.ts:82-98 / :155-160); // 2) 按 MCP stdio 协议写 initialize(protocolVersion / capabilities / clientInfo) - // → 读响应,断言 `serverInfo.name === "tts-toolkit"`、`version === "0.1.0"` - // (server.ts:57-61 / :163);随后发 notifications/initialized; + // → 读响应,断言 `serverInfo.name === "tts-toolkit"`、`version === pkg.version` + // (与 package.json 同步;server.ts 从 pkg.version 读,不写死字符串); // 可用 @modelcontextprotocol/server 的客户端 SDK(stdio 传输;InMemoryTransport // 亦可)或手写 JSON-RPC 行协议; // 3) 断言 stdout **只有协议 JSON**(无日志行),诊断只在 stderr(JSON Lines 英文, diff --git a/tests/unit/archive-ttsmod.test.ts b/tests/unit/archive-ttsmod.test.ts index 49d5e8f..165a4da 100644 --- a/tests/unit/archive-ttsmod.test.ts +++ b/tests/unit/archive-ttsmod.test.ts @@ -42,6 +42,7 @@ import { promisify } from 'node:util'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import pkg from '../../package.json' with { type: 'json' }; import { cacheFileName, sanitizeUrl } from '../../src/archive/cachekey.js'; import { exportTtsmod, importTtsmod, readZip, ttsmodFileName, writeZip } from '../../src/archive/ttsmod.js'; import { PackError } from '../../src/pack/packyaml.js'; @@ -544,7 +545,7 @@ describe('exportTtsmod manifest(3B.4)与 README(3B.9)', () => { expect(result.manifestIncluded).toBe(true); expect(result.manifest).toMatchObject({ manifest_version: 1, - tool: { name: 'tts-toolkit', version: '0.1.0' }, + tool: { name: 'tts-toolkit', version: pkg.version }, created_at: FIXED_TIME.toISOString(), pack: { name: 'M Pack', version: '1.2.0', workshop_id: 777, source_mod_id: 555, save_json_target: 'workshop' }, });