diff --git a/.githooks/sync-versions.ts b/.githooks/sync-versions.ts index b2d6bf68..bc46fa4c 100644 --- a/.githooks/sync-versions.ts +++ b/.githooks/sync-versions.ts @@ -1,221 +1,202 @@ #!/usr/bin/env tsx /** * Version Sync Script - * Auto-sync all sub-package versions before commit + * Auto-sync all publishable package versions before commit. */ -import { readFileSync, writeFileSync, readdirSync, existsSync, statSync } from 'node:fs' -import { execSync } from 'node:child_process' -import { resolve, join } from 'node:path' +import {readdirSync, readFileSync, writeFileSync} from 'node:fs' +import {join, relative, resolve} from 'node:path' import process from 'node:process' -interface PackageEntry { - readonly path: string - readonly name: string +interface VersionedJson { + version?: string + [key: string]: unknown } -interface PackageJson { - version?: string +const ROOT_DIR = resolve('.') +const ROOT_PACKAGE_PATH = resolve(ROOT_DIR, 'package.json') +const ROOT_CARGO_PATH = resolve(ROOT_DIR, 'Cargo.toml') +const IGNORED_DIRECTORIES = new Set([ + '.git', + '.next', + '.turbo', + 'coverage', + 'dist', + 'node_modules', + 'target', +]) + +function readJsonFile(filePath: string): VersionedJson { + return JSON.parse(readFileSync(filePath, 'utf-8').replace(/^\uFEFF/, '')) as VersionedJson } -function getCatalogVersion(pkgName: string): string | null { - try { - const yamlContent = readFileSync(resolve('pnpm-workspace.yaml'), 'utf-8') - const match = yamlContent.match(new RegExp(`${pkgName.replace('@', '\\@')}:\\s*\\^?([^\\s]+)`)) - return match ? match[1] : null - } catch { - return null - } +function writeJsonFile(filePath: string, value: VersionedJson): void { + writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n', 'utf-8') } -const eslintConfigVersion = getCatalogVersion('@truenine/eslint10-config') -const rootPackagePath = resolve('package.json') -const requestedVersion = process.argv[2]?.trim() -const rootPkg: PackageJson = JSON.parse(readFileSync(rootPackagePath, 'utf-8')) +function discoverFilesByName(baseDir: string, fileName: string): string[] { + const found: string[] = [] + const entries = readdirSync(baseDir, {withFileTypes: true}) -if (requestedVersion && rootPkg.version !== requestedVersion) { - rootPkg.version = requestedVersion - writeFileSync(rootPackagePath, JSON.stringify(rootPkg, null, 2) + '\n', 'utf-8') -} + for (const entry of entries) { + const entryPath = join(baseDir, entry.name) -const rootVersion = rootPkg.version + if (entry.isDirectory()) { + if (entry.name.startsWith('.')) { + continue + } -if (!rootVersion) { - console.error('❌ Root package.json missing version field') - process.exit(1) -} + if (IGNORED_DIRECTORIES.has(entry.name)) { + continue + } -console.log(`πŸ”„ Syncing version: ${rootVersion}`) -if (eslintConfigVersion) { - console.log(`πŸ”„ Catalog @truenine/eslint10-config: ^${eslintConfigVersion}`) -} + found.push(...discoverFilesByName(entryPath, fileName)) + continue + } -const topLevelWorkspacePackages: readonly PackageEntry[] = [ - { path: 'cli/package.json', name: 'cli' }, - { path: 'mcp/package.json', name: 'mcp' }, - { path: 'gui/package.json', name: 'gui' }, - { path: 'doc/package.json', name: 'doc' }, -] - -// Discover all libraries and their npm sub-packages -function discoverLibraryPackages(): PackageEntry[] { - const entries: PackageEntry[] = [] - const librariesDir = resolve('libraries') - if (!existsSync(librariesDir)) return entries - for (const lib of readdirSync(librariesDir)) { - const libDir = join(librariesDir, lib) - if (!statSync(libDir).isDirectory()) continue - const libPkg = join(libDir, 'package.json') - if (existsSync(libPkg)) { - entries.push({ path: `libraries/${lib}/package.json`, name: `lib:${lib}` }) + if (entry.isFile() && entry.name === fileName) { + found.push(entryPath) } } - return entries + + return found } -// Discover npm platform sub-packages under a given directory (e.g. cli/npm/) -function discoverNpmSubPackages(baseDir: string, prefix: string): PackageEntry[] { - const entries: PackageEntry[] = [] - const npmDir = resolve(baseDir, 'npm') - if (!existsSync(npmDir) || !statSync(npmDir).isDirectory()) return entries - for (const platform of readdirSync(npmDir)) { - const platformDir = join(npmDir, platform) - if (!statSync(platformDir).isDirectory()) continue - const platformPkg = join(platformDir, 'package.json') - if (existsSync(platformPkg)) { - entries.push({ path: `${baseDir}/npm/${platform}/package.json`, name: `${prefix}/${platform}` }) +function updateVersionLineInSection( + content: string, + sectionName: string, + targetVersion: string, +): string { + const lines = content.split(/\r?\n/) + let inTargetSection = false + + for (let index = 0; index < lines.length; index += 1) { + const line = lines[index] + const trimmed = line.trim() + + if (/^\[.*\]$/.test(trimmed)) { + inTargetSection = trimmed === `[${sectionName}]` + continue + } + + if (!inTargetSection) { + continue + } + + if (/^version\.workspace\s*=/.test(trimmed)) { + return content } - } - return entries -} -// Discover all packages under packages/ -function discoverPackagesDir(): PackageEntry[] { - const entries: PackageEntry[] = [] - const packagesDir = resolve('packages') - if (!existsSync(packagesDir)) return entries - for (const pkg of readdirSync(packagesDir)) { - const pkgDir = join(packagesDir, pkg) - if (!statSync(pkgDir).isDirectory()) continue - const pkgFile = join(pkgDir, 'package.json') - if (existsSync(pkgFile)) { - entries.push({ path: `packages/${pkg}/package.json`, name: `pkg:${pkg}` }) + const match = line.match(/^(\s*version\s*=\s*")([^"]+)(".*)$/) + if (match == null) { + continue } + + if (match[2] === targetVersion) { + return content + } + + lines[index] = `${match[1]}${targetVersion}${match[3]}` + return lines.join('\n') } - return entries + + return content } -const libraryPackages = discoverLibraryPackages() -const packagesPackages = discoverPackagesDir() -const cliNpmPackages = discoverNpmSubPackages('cli', 'cli-napi') +function syncJsonVersion( + filePath: string, + rootVersion: string, + changedPaths: Set, +): void { + try { + const json = readJsonFile(filePath) + if (json.version === rootVersion) { + return + } -let changed = false + console.log(` βœ“ ${relative(ROOT_DIR, filePath)}: version ${String(json.version ?? '(none)')} -> ${rootVersion}`) + json.version = rootVersion + writeJsonFile(filePath, json) + changedPaths.add(filePath) + } catch { + console.log(`⚠️ ${relative(ROOT_DIR, filePath)} not found or invalid, skipping`) + } +} -for (const pkg of [...topLevelWorkspacePackages, ...libraryPackages, ...packagesPackages, ...cliNpmPackages]) { - const fullPath = resolve(pkg.path) +function syncCargoVersion( + filePath: string, + sectionName: string, + rootVersion: string, + changedPaths: Set, +): void { try { - const content = readFileSync(fullPath, 'utf-8').replace(/^\uFEFF/, '') - const pkgJson: PackageJson = JSON.parse(content) - - if (pkgJson.version !== rootVersion) { - console.log(` βœ“ ${pkg.name}: version ${pkgJson.version} β†’ ${rootVersion}`) - pkgJson.version = rootVersion - writeFileSync(fullPath, JSON.stringify(pkgJson, null, 2) + '\n', 'utf-8') - changed = true + const originalContent = readFileSync(filePath, 'utf-8') + const updatedContent = updateVersionLineInSection(originalContent, sectionName, rootVersion) + + if (updatedContent === originalContent) { + return } + + writeFileSync(filePath, updatedContent, 'utf-8') + console.log(` βœ“ ${relative(ROOT_DIR, filePath)}: version -> ${rootVersion}`) + changedPaths.add(filePath) } catch { - console.log(`⚠️ ${pkg.path} not found or invalid, skipping`) + console.log(`⚠️ ${relative(ROOT_DIR, filePath)} not found or invalid, skipping`) } } -// Sync root workspace Cargo.toml version -const workspaceCargoTomlPath = resolve('Cargo.toml') -try { - const cargoContent = readFileSync(workspaceCargoTomlPath, 'utf-8') - const cargoUpdated = cargoContent.replace( - /(\[workspace\.package\][\s\S]*?^version = ")([^"]+)(")/m, - `$1${rootVersion}$3`, - ) - if (cargoContent !== cargoUpdated) { - writeFileSync(workspaceCargoTomlPath, cargoUpdated, 'utf-8') - console.log(` βœ“ workspace Cargo.toml: version β†’ ${rootVersion}`) - changed = true - } -} catch { - console.log('⚠️ Cargo.toml not found, skipping') +const requestedVersion = process.argv[2]?.trim() +const rootPkg = readJsonFile(ROOT_PACKAGE_PATH) +const changedPaths = new Set() + +if (requestedVersion && rootPkg.version !== requestedVersion) { + rootPkg.version = requestedVersion + writeJsonFile(ROOT_PACKAGE_PATH, rootPkg) + changedPaths.add(ROOT_PACKAGE_PATH) } -// Sync GUI Cargo.toml version -const cargoTomlPath = resolve('gui/src-tauri/Cargo.toml') -try { - const cargoContent = readFileSync(cargoTomlPath, 'utf-8') - const cargoUpdated = cargoContent.replace(/^version = ".*"/m, `version = "${rootVersion}"`) - if (cargoContent !== cargoUpdated) { - writeFileSync(cargoTomlPath, cargoUpdated, 'utf-8') - console.log(` βœ“ Cargo.toml: version β†’ ${rootVersion}`) - changed = true - } -} catch { - console.log('⚠️ gui/src-tauri/Cargo.toml not found, skipping') +const rootVersion = rootPkg.version + +if (rootVersion == null || rootVersion === '') { + console.error('Root package.json missing version field') + process.exit(1) } -// Sync tauri.conf.json version -const tauriConfPath = resolve('gui/src-tauri/tauri.conf.json') -try { - const tauriConfContent = readFileSync(tauriConfPath, 'utf-8') - const tauriConf = JSON.parse(tauriConfContent) - if (tauriConf.version !== rootVersion) { - console.log(` βœ“ tauri.conf.json: version ${tauriConf.version ?? '(none)'} β†’ ${rootVersion}`) - tauriConf.version = rootVersion - writeFileSync(tauriConfPath, JSON.stringify(tauriConf, null, 2) + '\n', 'utf-8') - changed = true - } -} catch { - console.log('⚠️ gui/src-tauri/tauri.conf.json not found, skipping') +console.log(`πŸ”„ Syncing version: ${rootVersion}`) + +const packageJsonPaths = discoverFilesByName(ROOT_DIR, 'package.json') + .filter(filePath => resolve(filePath) !== ROOT_PACKAGE_PATH) + .sort() + +for (const filePath of packageJsonPaths) { + syncJsonVersion(filePath, rootVersion, changedPaths) } -// Sync version field in tnmsc.example.json files -const exampleConfigPaths = [ - 'libraries/init-bundle/public/public/tnmsc.example.json', -] +syncCargoVersion(ROOT_CARGO_PATH, 'workspace.package', rootVersion, changedPaths) -for (const examplePath of exampleConfigPaths) { - const fullPath = resolve(examplePath) - try { - const content = readFileSync(fullPath, 'utf-8') - const exampleJson = JSON.parse(content) as Record - if (exampleJson['version'] !== rootVersion) { - console.log(` βœ“ ${examplePath}: version ${String(exampleJson['version'] ?? '(none)')} β†’ ${rootVersion}`) - exampleJson['version'] = rootVersion - writeFileSync(fullPath, JSON.stringify(exampleJson, null, 2) + '\n', 'utf-8') - changed = true - } - } catch { - console.log(`⚠️ ${examplePath} not found or invalid, skipping`) - } +const cargoTomlPaths = discoverFilesByName(ROOT_DIR, 'Cargo.toml') + .filter(filePath => resolve(filePath) !== ROOT_CARGO_PATH) + .sort() + +for (const filePath of cargoTomlPaths) { + syncCargoVersion(filePath, 'package', rootVersion, changedPaths) } -if (changed) { - console.log('\nπŸ“¦ Versions synced, auto-staging changes...') - try { - const filesToStage = [ - 'package.json', - 'Cargo.toml', - 'gui/src-tauri/Cargo.toml', - 'gui/src-tauri/tauri.conf.json', - 'libraries/init-bundle/public/public/tnmsc.example.json', - ...topLevelWorkspacePackages.map(p => p.path), - ...libraryPackages.map(p => p.path), - ...packagesPackages.map(p => p.path), - ...cliNpmPackages.map(p => p.path), - ].filter(path => existsSync(resolve(path))) - execSync( - `git add ${filesToStage.join(' ')}`, - { stdio: 'inherit' } - ) - console.log('βœ… Staged modified files') - } catch { - console.log('⚠️ git add failed, please execute manually') - } -} else { +for (const filePath of discoverFilesByName(ROOT_DIR, 'tauri.conf.json').sort()) { + syncJsonVersion(filePath, rootVersion, changedPaths) +} + +if (changedPaths.size === 0) { console.log('\nβœ… All versions consistent, no update needed') + process.exit(0) +} + +const changedRelativePaths = [...changedPaths] + .map(filePath => relative(ROOT_DIR, filePath)) + .sort() + +console.error('\n❌ Versions were out of sync. Updated files:') +for (const relativePath of changedRelativePaths) { + console.error(` - ${relativePath}`) } +console.error('\nReview these changes and rerun the commit.') +process.exit(1) diff --git a/.github/workflows/deploy-doc.yml b/.github/workflows/deploy-doc.yml new file mode 100644 index 00000000..66a25e56 --- /dev/null +++ b/.github/workflows/deploy-doc.yml @@ -0,0 +1,59 @@ +name: Deploy Docs + +on: + push: + branches: + - main + paths: + - doc/** + workflow_dispatch: + +permissions: + contents: read + +env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + +concurrency: + group: deploy-doc-${{ github.ref }} + cancel-in-progress: true + +jobs: + deploy-doc: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-node-pnpm + + - name: Preflight Vercel secrets + shell: bash + run: | + set -euo pipefail + + if [[ -z "${VERCEL_TOKEN:-}" ]]; then + echo "::error::VERCEL_TOKEN is missing." + exit 1 + fi + + if [[ -z "${VERCEL_ORG_ID:-}" ]]; then + echo "::error::VERCEL_ORG_ID is missing." + exit 1 + fi + + if [[ -z "${VERCEL_PROJECT_ID:-}" ]]; then + echo "::error::VERCEL_PROJECT_ID is missing." + exit 1 + fi + + - name: Pull Vercel production settings + run: pnpm dlx vercel@latest pull --yes --environment=production --cwd doc --token="$VERCEL_TOKEN" + + - name: Build docs on Vercel + run: pnpm dlx vercel@latest build --prod --cwd doc --token="$VERCEL_TOKEN" + + - name: Deploy docs to Vercel production + run: pnpm dlx vercel@latest deploy --prebuilt --prod --cwd doc --token="$VERCEL_TOKEN" diff --git a/.tmp-docs-dom.html b/.tmp-docs-dom.html deleted file mode 100644 index e69de29b..00000000 diff --git a/.tmp-docs-header-after-mobile.png b/.tmp-docs-header-after-mobile.png deleted file mode 100644 index 4a4acf59..00000000 Binary files a/.tmp-docs-header-after-mobile.png and /dev/null differ diff --git a/.tmp-docs-header-after-v2.png b/.tmp-docs-header-after-v2.png deleted file mode 100644 index bbd21e98..00000000 Binary files a/.tmp-docs-header-after-v2.png and /dev/null differ diff --git a/.tmp-docs-header-after-v3.png b/.tmp-docs-header-after-v3.png deleted file mode 100644 index 5245e113..00000000 Binary files a/.tmp-docs-header-after-v3.png and /dev/null differ diff --git a/.tmp-docs-header-after.png b/.tmp-docs-header-after.png deleted file mode 100644 index b0a0ac44..00000000 Binary files a/.tmp-docs-header-after.png and /dev/null differ diff --git a/.tmp-docs-header-before-mobile.png b/.tmp-docs-header-before-mobile.png deleted file mode 100644 index 09b3a17d..00000000 Binary files a/.tmp-docs-header-before-mobile.png and /dev/null differ diff --git a/.tmp-docs-header-before.png b/.tmp-docs-header-before.png deleted file mode 100644 index a71a47f6..00000000 Binary files a/.tmp-docs-header-before.png and /dev/null differ diff --git a/Cargo.lock b/Cargo.lock index 6ca279cf..fa76fbb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,7 +2071,7 @@ dependencies = [ [[package]] name = "memory-sync-gui" -version = "2026.10323.10738" +version = "2026.10324.10015" dependencies = [ "dirs", "proptest", @@ -4349,7 +4349,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tnmsc" -version = "2026.10323.10738" +version = "2026.10324.10015" dependencies = [ "clap", "dirs", @@ -4369,7 +4369,7 @@ dependencies = [ [[package]] name = "tnmsc-logger" -version = "2026.10323.10738" +version = "2026.10324.10015" dependencies = [ "chrono", "napi", @@ -4381,7 +4381,7 @@ dependencies = [ [[package]] name = "tnmsc-md-compiler" -version = "2026.10323.10738" +version = "2026.10324.10015" dependencies = [ "markdown", "napi", @@ -4396,7 +4396,7 @@ dependencies = [ [[package]] name = "tnmsc-script-runtime" -version = "2026.10323.10738" +version = "2026.10324.10015" dependencies = [ "napi", "napi-build", diff --git a/Cargo.toml b/Cargo.toml index cdcef094..6c66ecec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "2026.10323.10738" +version = "2026.10324.10015" edition = "2024" license = "AGPL-3.0-only" authors = ["TrueNine"] diff --git a/cli/npm/darwin-arm64/package.json b/cli/npm/darwin-arm64/package.json index 89971e2b..4541f255 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.10323.10738", + "version": "2026.10324.10015", "os": [ "darwin" ], diff --git a/cli/npm/darwin-x64/package.json b/cli/npm/darwin-x64/package.json index 8a52645f..f697687f 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.10323.10738", + "version": "2026.10324.10015", "os": [ "darwin" ], diff --git a/cli/npm/linux-arm64-gnu/package.json b/cli/npm/linux-arm64-gnu/package.json index d8339c98..146ef40a 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.10323.10738", + "version": "2026.10324.10015", "os": [ "linux" ], diff --git a/cli/npm/linux-x64-gnu/package.json b/cli/npm/linux-x64-gnu/package.json index 4331a516..dd97dba9 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.10323.10738", + "version": "2026.10324.10015", "os": [ "linux" ], diff --git a/cli/npm/win32-x64-msvc/package.json b/cli/npm/win32-x64-msvc/package.json index ce8538e8..8e0199cd 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.10323.10738", + "version": "2026.10324.10015", "os": [ "win32" ], diff --git a/cli/package.json b/cli/package.json index d0f40f1f..7a992591 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-cli", "type": "module", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "description": "TrueNine Memory Synchronization CLI", "author": "TrueNine", "license": "AGPL-3.0-only", diff --git a/cli/src/config/example.json b/cli/src/config/example.json deleted file mode 100644 index d83fdf94..00000000 --- a/cli/src/config/example.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": "2026.10218.12101", - "workspaceDir": "~/project", - "aindex": { - "name": "aindex", - "skills": { - "src": "skills", - "dist": "dist/skills" - }, - "commands": { - "src": "commands", - "dist": "dist/commands" - }, - "subAgents": { - "src": "agents", - "dist": "dist/agents" - }, - "rules": { - "src": "rules", - "dist": "dist/rules" - }, - "globalPrompt": { - "src": "app/global.src.mdx", - "dist": "dist/global.mdx" - }, - "workspacePrompt": { - "src": "app/workspace.src.mdx", - "dist": "dist/workspace.mdx" - }, - "app": { - "src": "app", - "dist": "dist/app" - }, - "ext": { - "src": "ext", - "dist": "dist/ext" - }, - "arch": { - "src": "arch", - "dist": "dist/arch" - } - }, - "logLevel": "info", - "windows": { - "wsl2": { - "instances": [ - "Ubuntu" - ] - } - }, - "profile": { - "name": "θ΅΅ζ—₯倩", - "username": "TrueNine", - "gender": "male", - "birthday": "1997-11-04" - } -} diff --git a/cli/src/plugins/CodexCLIOutputPlugin.test.ts b/cli/src/plugins/CodexCLIOutputPlugin.test.ts index 6a986654..91e4f2f7 100644 --- a/cli/src/plugins/CodexCLIOutputPlugin.test.ts +++ b/cli/src/plugins/CodexCLIOutputPlugin.test.ts @@ -244,12 +244,12 @@ describe('codexCLIOutputPlugin command output', () => { ].join('\n')) expect(String(rendered)).toContain('nickname_candidates = ["guard"]') expect(String(rendered)).toContain('sandbox_mode = "workspace-write"') - expect(String(rendered)).toContain('allowedTools = "shell"') expect(String(rendered)).toContain('[mcp_servers]') expect(String(rendered)).toContain('[mcp_servers.docs]') expect(String(rendered)).not.toContain('model = ') expect(String(rendered)).not.toContain('scope = ') expect(String(rendered)).not.toContain('allowTools') + expect(String(rendered)).not.toContain('allowedTools') expect(String(rendered)).not.toContain('color = ') }) }) diff --git a/cli/src/plugins/CodexCLIOutputPlugin.ts b/cli/src/plugins/CodexCLIOutputPlugin.ts index 986cdcfa..2b43cb8c 100644 --- a/cli/src/plugins/CodexCLIOutputPlugin.ts +++ b/cli/src/plugins/CodexCLIOutputPlugin.ts @@ -15,8 +15,8 @@ function transformCodexSubAgentFrontMatter( const frontMatter = {...sourceFrontMatter} frontMatter['name'] = subAgentCanonicalName - if (Array.isArray(frontMatter['allowTools']) && frontMatter['allowTools'].length > 0) frontMatter['allowedTools'] = frontMatter['allowTools'].join(', ') - + // Codex agent role deserialization currently rejects `allowedTools`. + // Keep accepting upstream `allowTools` metadata for other outputs, but drop it here for Codex TOML compatibility. delete frontMatter['allowTools'] return frontMatter } diff --git a/doc/app/layout.tsx b/doc/app/layout.tsx index bd3becae..0fb0d53d 100644 --- a/doc/app/layout.tsx +++ b/doc/app/layout.tsx @@ -1,9 +1,25 @@ import type {Metadata} from 'next' import {JetBrains_Mono} from 'next/font/google' +import Script from 'next/script' import {getSiteUrl, siteConfig} from '../lib/site' import 'nextra-theme-docs/style.css' import './globals.css' +const docsThemeStorageKey = 'memory-sync-docs-theme' +const docsThemeBootstrapScript = ` +try { + const storageKey = '${docsThemeStorageKey}'; + const storedTheme = window.localStorage.getItem(storageKey); + const normalizedTheme = storedTheme === 'light' ? 'light' : 'dark'; + + if (storedTheme !== normalizedTheme) { + window.localStorage.setItem(storageKey, normalizedTheme); + } + + document.documentElement.classList.toggle('dark', normalizedTheme === 'dark'); +} catch {} +` + const sans = JetBrains_Mono({ variable: '--font-sans', preload: true, @@ -48,6 +64,9 @@ export default function RootLayout({children}: {readonly children: React.ReactNo return ( + {children} diff --git a/doc/package.json b/doc/package.json index b8b4db2d..c63e242d 100644 --- a/doc/package.json +++ b/doc/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-docs", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "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 e530c892..1cf05d5e 100644 --- a/gui/package.json +++ b/gui/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-gui", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "private": true, "engines": { "node": ">=25.2.1", diff --git a/gui/src-tauri/Cargo.toml b/gui/src-tauri/Cargo.toml index 1cb5826c..78bb4718 100644 --- a/gui/src-tauri/Cargo.toml +++ b/gui/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "memory-sync-gui" -version = "2026.10323.10738" +version = "2026.10324.10015" 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 a57b7f68..07fb2ef2 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.10323.10738", + "version": "2026.10324.10015", "productName": "Memory Sync", "identifier": "org.truenine.memory-sync", "build": { @@ -24,7 +24,13 @@ "bundle": { "active": true, "createUpdaterArtifacts": true, - "targets": ["nsis", "deb", "rpm", "appimage", "dmg"], + "targets": [ + "nsis", + "deb", + "rpm", + "appimage", + "dmg" + ], "externalBin": [], "icon": [ "icons/32x32.png", diff --git a/libraries/logger/package.json b/libraries/logger/package.json index d2d593df..43cbdef1 100644 --- a/libraries/logger/package.json +++ b/libraries/logger/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/logger", "type": "module", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "private": true, "description": "Rust-powered structured 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 b8bef19c..e66768ed 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.10323.10738", + "version": "2026.10324.10015", "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 7a8ca748..4b2bc4cd 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.10323.10738", + "version": "2026.10324.10015", "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 9d3780dd..773241be 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-mcp", "type": "module", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "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 cec36846..9270ca3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync", - "version": "2026.10323.10738", + "version": "2026.10324.10015", "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": [ @@ -54,7 +54,7 @@ "rust": ">= 1.87.0" }, "simple-git-hooks": { - "pre-commit": "pnpm tsx .githooks/sync-versions.ts || true" + "pre-commit": "pnpm tsx .githooks/sync-versions.ts" }, "packageManager": "pnpm@10.32.1", "devDependencies": {