diff --git a/.github/actions/check-gui-release-state/action.yml b/.github/actions/check-gui-release-state/action.yml new file mode 100644 index 0000000..6f5c7ec --- /dev/null +++ b/.github/actions/check-gui-release-state/action.yml @@ -0,0 +1,36 @@ +name: Check GUI Release State +description: Check whether the current GUI version already has a GitHub release tag + +inputs: + github-token: + description: GitHub token used for release lookups + required: true + +outputs: + version: + description: GUI version from gui/package.json + value: ${{ steps.check.outputs.version }} + should_release: + description: Whether the GUI version still needs a GitHub release + value: ${{ steps.check.outputs.should_release }} + +runs: + using: composite + steps: + - name: Check GUI release state + id: check + shell: bash + env: + GH_TOKEN: ${{ inputs.github-token }} + run: | + version=$(jq -r '.version' gui/package.json) + echo "GUI version: $version" + + if gh release view "v${version}" >/dev/null 2>&1; then + echo "Release v${version} already exists on GitHub, skipping GUI" + echo "should_release=false" >> "$GITHUB_OUTPUT" + else + echo "Release v${version} does not exist, will build GUI" + echo "should_release=true" >> "$GITHUB_OUTPUT" + echo "version=$version" >> "$GITHUB_OUTPUT" + fi diff --git a/.github/actions/check-release-state/action.yml b/.github/actions/check-release-state/action.yml new file mode 100644 index 0000000..3e7e314 --- /dev/null +++ b/.github/actions/check-release-state/action.yml @@ -0,0 +1,73 @@ +name: Check Release State +description: Check whether CLI and MCP package versions are already published to npm + +inputs: + registry-url: + description: npm registry URL used for publish-state checks + required: false + default: "https://registry.npmjs.org/" + +outputs: + version: + description: Workspace version from the repository root package.json + value: ${{ steps.check.outputs.version }} + publish_cli: + description: Whether the CLI package should be published + value: ${{ steps.check.outputs.publish_cli }} + publish_mcp: + description: Whether the MCP package should be published + value: ${{ steps.check.outputs.publish_mcp }} + publish_npm: + description: Whether any npm package should be published + value: ${{ steps.check.outputs.publish_npm }} + +runs: + using: composite + steps: + - name: Check npm publish state + id: check + shell: bash + env: + NPM_REGISTRY_URL: ${{ inputs.registry-url }} + run: | + check_publish_state() { + local package_json_path="$1" + local output_key="$2" + local version + local name + local published_version + + version=$(jq -r '.version' "$package_json_path") + name=$(jq -r '.name' "$package_json_path") + published_version=$(npm view "${name}@${version}" version --registry "$NPM_REGISTRY_URL" 2>/dev/null || echo "") + + if [[ "$version" != "$published_version" ]]; then + echo "$name@$version is not published to npm, will publish" + echo "${output_key}=true" >> "$GITHUB_OUTPUT" + return 0 + fi + + echo "$name@$version already published to npm, skipping" + echo "${output_key}=false" >> "$GITHUB_OUTPUT" + return 1 + } + + version=$(jq -r '.version' package.json) + echo "version=$version" >> "$GITHUB_OUTPUT" + + cli_needs_publish=false + mcp_needs_publish=false + + if check_publish_state cli/package.json publish_cli; then + cli_needs_publish=true + fi + + if check_publish_state mcp/package.json publish_mcp; then + mcp_needs_publish=true + fi + + if [[ "$cli_needs_publish" == "true" || "$mcp_needs_publish" == "true" ]]; then + echo "publish_npm=true" >> "$GITHUB_OUTPUT" + else + echo "publish_npm=false" >> "$GITHUB_OUTPUT" + fi diff --git a/.github/actions/setup-node-pnpm/action.yml b/.github/actions/setup-node-pnpm/action.yml index 5275086..aa0df1c 100644 --- a/.github/actions/setup-node-pnpm/action.yml +++ b/.github/actions/setup-node-pnpm/action.yml @@ -14,6 +14,10 @@ inputs: description: Optional npm registry URL to configure for npm publish/auth steps required: false default: "" + cache: + description: Whether to enable actions/setup-node pnpm cache + required: false + default: "true" install: description: Whether to run pnpm install required: false @@ -31,7 +35,8 @@ runs: with: version: ${{ inputs.pnpm-version }} - - name: Setup Node + - name: Setup Node with pnpm cache + if: inputs.cache == 'true' uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version }} @@ -39,6 +44,14 @@ runs: cache-dependency-path: pnpm-lock.yaml registry-url: ${{ inputs.registry-url }} + - name: Setup Node without pnpm cache + if: inputs.cache != 'true' + uses: actions/setup-node@v6 + with: + node-version: ${{ inputs.node-version }} + package-manager-cache: false + registry-url: ${{ inputs.registry-url }} + - name: Install workspace dependencies if: inputs.install == 'true' && inputs['install-filter'] == '' shell: bash diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index cec915b..e92640e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -26,6 +26,35 @@ concurrency: cancel-in-progress: true jobs: + release-preflight: + if: github.event.pull_request.draft == false + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v6 + + - uses: ./.github/actions/setup-node-pnpm + with: + cache: "false" + install: "false" + + - name: Run npm release preflight + uses: ./.github/actions/check-release-state + with: + registry-url: https://registry.npmjs.org/ + + gui-release-preflight: + if: github.event.pull_request.draft == false + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v6 + + - name: Run GUI release preflight + uses: ./.github/actions/check-gui-release-state + with: + github-token: ${{ github.token }} + check: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 1b18efc..fc4716b 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -58,52 +58,13 @@ jobs: - uses: actions/checkout@v6 - uses: ./.github/actions/setup-node-pnpm with: + cache: "false" install: "false" - - name: Check if should publish id: check - run: | - check_publish_state() { - local package_json_path="$1" - local output_key="$2" - local version - local name - local published_version - - version=$(jq -r '.version' "$package_json_path") - name=$(jq -r '.name' "$package_json_path") - published_version=$(npm view "${name}@${version}" version --registry "$NPM_REGISTRY_URL" 2>/dev/null || echo "") - - if [[ "$version" != "$published_version" ]]; then - echo "$name@$version is not published to npm, will publish" - echo "${output_key}=true" >> "$GITHUB_OUTPUT" - return 0 - fi - - echo "$name@$version already published to npm, skipping" - echo "${output_key}=false" >> "$GITHUB_OUTPUT" - return 1 - } - - version=$(jq -r '.version' package.json) - echo "version=$version" >> "$GITHUB_OUTPUT" - - cli_needs_publish=false - mcp_needs_publish=false - - if check_publish_state cli/package.json publish_cli; then - cli_needs_publish=true - fi - - if check_publish_state mcp/package.json publish_mcp; then - mcp_needs_publish=true - fi - - if [[ "$cli_needs_publish" == "true" || "$mcp_needs_publish" == "true" ]]; then - echo "publish_npm=true" >> "$GITHUB_OUTPUT" - else - echo "publish_npm=false" >> "$GITHUB_OUTPUT" - fi + uses: ./.github/actions/check-release-state + with: + registry-url: ${{ env.NPM_REGISTRY_URL }} # 1.5. GUI 版本检查(独立于 npm,检查 GitHub Release) check-gui-version: @@ -114,24 +75,11 @@ jobs: version: ${{ steps.check.outputs.version }} steps: - uses: actions/checkout@v6 - - name: Check if GUI should be released id: check - env: - GH_TOKEN: ${{ github.token }} - run: | - version=$(jq -r '.version' gui/package.json) - echo "GUI version: $version" - - # Check if this version tag exists on GitHub - if gh release view "v${version}" >/dev/null 2>&1; then - echo "Release v${version} already exists on GitHub, skipping GUI" - echo "should_release=false" >> "$GITHUB_OUTPUT" - else - echo "Release v${version} does not exist, will build GUI" - echo "should_release=true" >> "$GITHUB_OUTPUT" - echo "version=$version" >> "$GITHUB_OUTPUT" - fi + uses: ./.github/actions/check-gui-release-state + with: + github-token: ${{ github.token }} # 2. 构建 NAPI 二进制(5 平台矩阵) build-napi: diff --git a/Cargo.toml b/Cargo.toml index 2973f14..92ea6e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ ] [workspace.package] -version = "2026.10402.103" +version = "2026.10402.109" edition = "2024" rust-version = "1.88" license = "AGPL-3.0-only" diff --git a/cli/npm/darwin-arm64/package.json b/cli/npm/darwin-arm64/package.json index c3eb9b4..b00c876 100644 --- a/cli/npm/darwin-arm64/package.json +++ b/cli/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-darwin-arm64", - "version": "2026.10402.103", + "version": "2026.10402.109", "os": [ "darwin" ], diff --git a/cli/npm/darwin-x64/package.json b/cli/npm/darwin-x64/package.json index 1947f7d..1fa2988 100644 --- a/cli/npm/darwin-x64/package.json +++ b/cli/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-darwin-x64", - "version": "2026.10402.103", + "version": "2026.10402.109", "os": [ "darwin" ], diff --git a/cli/npm/linux-arm64-gnu/package.json b/cli/npm/linux-arm64-gnu/package.json index fa0cf32..eab4b73 100644 --- a/cli/npm/linux-arm64-gnu/package.json +++ b/cli/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-linux-arm64-gnu", - "version": "2026.10402.103", + "version": "2026.10402.109", "os": [ "linux" ], diff --git a/cli/npm/linux-x64-gnu/package.json b/cli/npm/linux-x64-gnu/package.json index 54554dd..6b3d07e 100644 --- a/cli/npm/linux-x64-gnu/package.json +++ b/cli/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-linux-x64-gnu", - "version": "2026.10402.103", + "version": "2026.10402.109", "os": [ "linux" ], diff --git a/cli/npm/win32-x64-msvc/package.json b/cli/npm/win32-x64-msvc/package.json index 4e18a73..4607f49 100644 --- a/cli/npm/win32-x64-msvc/package.json +++ b/cli/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-win32-x64-msvc", - "version": "2026.10402.103", + "version": "2026.10402.109", "os": [ "win32" ], diff --git a/cli/package.json b/cli/package.json index 5e640a5..8874d3e 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-cli", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "description": "TrueNine Memory Synchronization CLI shell", "author": "TrueNine", "license": "AGPL-3.0-only", diff --git a/cli/scripts/sync-sdk-dist.ts b/cli/scripts/sync-sdk-dist.ts index be4980a..3bb729c 100644 --- a/cli/scripts/sync-sdk-dist.ts +++ b/cli/scripts/sync-sdk-dist.ts @@ -1,32 +1,152 @@ #!/usr/bin/env tsx -import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs"; -import { dirname, join, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; +import {spawnSync} from 'node:child_process' +import {copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync} from 'node:fs' +import {createRequire} from 'node:module' +import {tmpdir} from 'node:os' +import {dirname, join, resolve} from 'node:path' +import {fileURLToPath} from 'node:url' -const __dirname = dirname(fileURLToPath(import.meta.url)); -const cliDir = resolve(__dirname, ".."); -const sdkDistDir = resolve(cliDir, "../sdk/dist"); -const cliDistDir = resolve(cliDir, "dist"); +const __dirname = dirname(fileURLToPath(import.meta.url)) +const cliDir = resolve(__dirname, '..') +const sdkDistDir = resolve(cliDir, '../sdk/dist') +const cliDistDir = resolve(cliDir, 'dist') +const scriptRuntimeWorkerPath = resolve(cliDistDir, 'script-runtime-worker.mjs') -const EXACT_FILES = new Set(["tnmsc.schema.json"]); +const EXACT_FILES = new Set(['tnmsc.schema.json']) +const runtimeRequire = createRequire(import.meta.url) +const bundledJitiBabelRuntimeSourcePath = resolve( + dirname(runtimeRequire.resolve('jiti')), + '../dist/babel.cjs' +) +const bundledJitiBabelRuntimeTargetPath = resolve(cliDistDir, 'babel.cjs') -function shouldCopy(fileName: string): boolean { - return EXACT_FILES.has(fileName) || /^jiti-.*\.mjs$/u.test(fileName); +function shouldCopyFromSdk(fileName: string): boolean { + return EXACT_FILES.has(fileName) } -if (!existsSync(sdkDistDir)) { - throw new Error(`sdk dist directory is missing: ${sdkDistDir}`); +function getCombinedOutput(stdout?: string | null, stderr?: string | null): string { + return `${stdout ?? ''}${stderr ?? ''}`.trim() } -mkdirSync(cliDistDir, { recursive: true }); +function assertProcessSucceeded( + result: ReturnType, + lines: readonly string[] +): void { + if (result.error != null) { + throw result.error + } -for (const fileName of readdirSync(cliDistDir)) { - if (!shouldCopy(fileName)) continue; - rmSync(join(cliDistDir, fileName), { force: true, recursive: true }); + if (result.status === 0) { + return + } + + throw new Error([ + ...lines, + getCombinedOutput(result.stdout, result.stderr) || 'No output captured.' + ].join('\n')) +} + +function withTempDir(prefix: string, callback: (tempDir: string) => T): T { + const tempDir = mkdtempSync(join(tmpdir(), prefix)) + + try { + return callback(tempDir) + } + finally { + rmSync(tempDir, {recursive: true, force: true}) + } +} + +function findBundledJitiChunkPath(): string | undefined { + const bundledJitiChunkName = readdirSync(cliDistDir) + .find(fileName => /^jiti-.*\.mjs$/u.test(fileName)) + + return bundledJitiChunkName == null ? void 0 : resolve(cliDistDir, bundledJitiChunkName) +} + +function syncSdkAssets(): void { + if (!existsSync(sdkDistDir)) { + throw new Error(`sdk dist directory is missing: ${sdkDistDir}`) + } + + mkdirSync(cliDistDir, {recursive: true}) + + for (const fileName of readdirSync(cliDistDir)) { + if (!shouldCopyFromSdk(fileName)) continue + rmSync(join(cliDistDir, fileName), {force: true, recursive: true}) + } + + for (const fileName of readdirSync(sdkDistDir)) { + if (!shouldCopyFromSdk(fileName)) continue + cpSync(join(sdkDistDir, fileName), join(cliDistDir, fileName), {recursive: true}) + } } -for (const fileName of readdirSync(sdkDistDir)) { - if (!shouldCopy(fileName)) continue; - cpSync(join(sdkDistDir, fileName), join(cliDistDir, fileName), { recursive: true }); +function ensureBundledJitiRuntimeAssets(): void { + if (findBundledJitiChunkPath() == null) return + + if (!existsSync(bundledJitiBabelRuntimeSourcePath)) { + throw new Error( + `Bundled jiti runtime asset is missing: ${bundledJitiBabelRuntimeSourcePath}` + ) + } + + copyFileSync(bundledJitiBabelRuntimeSourcePath, bundledJitiBabelRuntimeTargetPath) } + +function smokeTestScriptRuntimeWorker(): void { + if (!existsSync(scriptRuntimeWorkerPath)) { + throw new Error(`Expected bundled script runtime worker at "${scriptRuntimeWorkerPath}".`) + } + + withTempDir('tnmsc-script-runtime-worker-', tempDir => { + const proxyModulePath = join(tempDir, 'proxy.ts') + const contextJsonPath = join(tempDir, 'ctx.json') + const expectedPath = '____git/config' + + writeFileSync( + proxyModulePath, + 'export default { resolvePublicPath(logicalPath) { return logicalPath.replace(/^\\.git\\//, "____git/") } }\n', + 'utf8' + ) + writeFileSync( + contextJsonPath, + JSON.stringify({ + cwd: tempDir, + workspaceDir: tempDir, + aindexDir: join(tempDir, '.aindex'), + command: 'execute', + platform: process.platform + }), + 'utf8' + ) + + const smokeTest = spawnSync( + process.execPath, + [scriptRuntimeWorkerPath, proxyModulePath, contextJsonPath, '.git/config'], + { + cwd: cliDir, + encoding: 'utf8' + } + ) + + assertProcessSucceeded(smokeTest, [ + `Bundled script runtime worker "${scriptRuntimeWorkerPath}" failed the runtime smoke test.` + ]) + + if (smokeTest.stdout.trim() !== expectedPath) { + throw new Error( + [ + `Bundled script runtime worker "${scriptRuntimeWorkerPath}" returned an unexpected path.`, + `Expected: ${expectedPath}`, + `Actual: ${smokeTest.stdout.trim() || '(empty)'}` + ].join('\n') + ) + } + }) +} + +syncSdkAssets() +ensureBundledJitiRuntimeAssets() +smokeTestScriptRuntimeWorker() diff --git a/cli/src/tsdown-config.test.ts b/cli/src/tsdown-config.test.ts new file mode 100644 index 0000000..cb469e6 --- /dev/null +++ b/cli/src/tsdown-config.test.ts @@ -0,0 +1,36 @@ +import {resolve} from 'node:path' +import {describe, expect, it} from 'vitest' +import tsconfig from '../tsconfig.json' +import tsdownConfig from '../tsdown.config' + +interface TsdownEntryConfig { + readonly entry?: string | readonly string[] + readonly alias?: Record + readonly deps?: { + readonly alwaysBundle?: readonly string[] + } +} + +function includesEntry(config: TsdownEntryConfig, targetEntry: string): boolean { + if (config.entry == null) return false + return (Array.isArray(config.entry) ? config.entry : [config.entry]).includes(targetEntry) +} + +describe('cli tsdown config', () => { + it('lets TypeScript resolve the script runtime package through workspace metadata', () => { + expect(tsconfig.compilerOptions.paths['@truenine/script-runtime']).toBeUndefined() + }) + + it('bundles the worker against the built script runtime module', () => { + const workerConfig = (tsdownConfig as readonly TsdownEntryConfig[]).find(config => + includesEntry(config, './src/script-runtime-worker.ts')) + + expect(workerConfig?.alias?.['@truenine/script-runtime']).toBe( + resolve('../libraries/script-runtime/dist/index.mjs') + ) + expect(workerConfig?.deps?.alwaysBundle).toEqual(expect.arrayContaining([ + '@truenine/script-runtime', + 'jiti' + ])) + }) +}) diff --git a/cli/tsconfig.json b/cli/tsconfig.json index 6dc3fc1..d0fc74f 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -14,8 +14,6 @@ "@sdk": ["../sdk/src/index.ts"], "@sdk/*": ["../sdk/src/*"], "@/*": ["./src/*"], - "@truenine/script-runtime": ["../libraries/script-runtime/dist/index.d.mts"], - "@truenine/script-runtime/*": ["../libraries/script-runtime/dist/*"], "@truenine/desk-paths": ["./src/core/desk-paths.ts"], "@truenine/desk-paths/*": ["./src/core/desk-paths/*"], "@truenine/plugin-output-shared": ["./src/plugins/plugin-output-shared/index.ts"], diff --git a/cli/tsdown.config.ts b/cli/tsdown.config.ts index 7d43e4b..2c7684a 100644 --- a/cli/tsdown.config.ts +++ b/cli/tsdown.config.ts @@ -1,6 +1,8 @@ +import {resolve} from 'node:path' import {defineConfig} from 'tsdown' const alwaysBundleDeps = ['@truenine/memory-sync-sdk'] +const scriptRuntimeWorkerBundleDeps = [...alwaysBundleDeps, '@truenine/script-runtime', 'jiti'] export default defineConfig([ { @@ -44,7 +46,10 @@ export default defineConfig([ platform: 'node', sourcemap: false, deps: { - alwaysBundle: alwaysBundleDeps + alwaysBundle: scriptRuntimeWorkerBundleDeps + }, + alias: { + '@truenine/script-runtime': resolve('../libraries/script-runtime/dist/index.mjs') }, format: ['esm'], minify: true, diff --git a/doc/package.json b/doc/package.json index 2de04ab..2c262cc 100644 --- a/doc/package.json +++ b/doc/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-docs", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "description": "Chinese-first manifesto-led documentation site for @truenine/memory-sync.", "engines": { diff --git a/gui/package.json b/gui/package.json index 8ed3129..2506ead 100644 --- a/gui/package.json +++ b/gui/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-gui", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "engines": { "node": ">=25.2.1", diff --git a/gui/src-tauri/Cargo.toml b/gui/src-tauri/Cargo.toml index 8ab527a..0abd2cd 100644 --- a/gui/src-tauri/Cargo.toml +++ b/gui/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "memory-sync-gui" -version = "2026.10402.103" +version = "2026.10402.109" description = "Memory Sync desktop GUI application" authors.workspace = true edition.workspace = true diff --git a/gui/src-tauri/tauri.conf.json b/gui/src-tauri/tauri.conf.json index 9ae149f..1a2c668 100644 --- a/gui/src-tauri/tauri.conf.json +++ b/gui/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "$schema": "https://schema.tauri.app/config/2", - "version": "2026.10402.103", + "version": "2026.10402.109", "productName": "Memory Sync", "identifier": "org.truenine.memory-sync", "build": { diff --git a/libraries/logger/package.json b/libraries/logger/package.json index bc01ee5..5ef000c 100644 --- a/libraries/logger/package.json +++ b/libraries/logger/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/logger", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "description": "Rust-powered AI-friendly Markdown logger for Node.js via N-API", "license": "AGPL-3.0-only", diff --git a/libraries/md-compiler/package.json b/libraries/md-compiler/package.json index a42e09a..895ae62 100644 --- a/libraries/md-compiler/package.json +++ b/libraries/md-compiler/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/md-compiler", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "description": "Rust-powered MDX→Markdown compiler for Node.js with pure-TS fallback", "license": "AGPL-3.0-only", diff --git a/libraries/script-runtime/package.json b/libraries/script-runtime/package.json index 70a4453..cb368ff 100644 --- a/libraries/script-runtime/package.json +++ b/libraries/script-runtime/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/script-runtime", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "description": "Rust-backed TypeScript proxy runtime for tnmsc", "license": "AGPL-3.0-only", diff --git a/mcp/package.json b/mcp/package.json index 78d5d1f..72d5e02 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-mcp", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "description": "MCP stdio server for managing memory-sync prompt sources and translation artifacts", "author": "TrueNine", "license": "AGPL-3.0-only", diff --git a/package.json b/package.json index 0e641bd..b2bd505 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync", - "version": "2026.10402.103", + "version": "2026.10402.109", "description": "Cross-AI-tool prompt synchronisation toolkit (CLI + Tauri desktop GUI) — one ruleset, multi-target adaptation. Monorepo powered by pnpm + Turbo.", "license": "AGPL-3.0-only", "keywords": [ diff --git a/sdk/package.json b/sdk/package.json index 7f33496..d995875 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-sdk", "type": "module", - "version": "2026.10402.103", + "version": "2026.10402.109", "private": true, "description": "TrueNine Memory Synchronization SDK", "author": "TrueNine",