Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
3 changes: 2 additions & 1 deletion src/archive/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions src/archive/ttsmod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
Expand Down
4 changes: 3 additions & 1 deletion src/assets/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import { ProxyAgent, request } from "undici";
import { z } from "zod";

import pkg from "../../package.json" with { type: "json" };

// ---------------------------------------------------------------------------
// 常量
// ---------------------------------------------------------------------------
Expand All @@ -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 的宽限(毫秒)。
Expand Down
3 changes: 2 additions & 1 deletion src/assets/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 <lang>", t("cli.option.lang"))
.option("--dev", t("cli.option.dev"))
Expand Down
3 changes: 2 additions & 1 deletion src/host/s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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<Record<string, string>> = Object.freeze({
Expand Down
5 changes: 3 additions & 2 deletions src/mcp/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/phase4.acceptance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 英文,
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/archive-ttsmod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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' },
});
Expand Down
Loading