Fix lockstep versioning and improve documentation

- Sync all packages to version 0.7.7
- Rewrite sync-versions.js to handle ALL inter-package dependencies automatically
- Fix web-ui dependency on pi-ai (was 0.6.0, now 0.7.7)
- Move agent fix changelog entry to coding-agent CHANGELOG
- Remove redundant agent CHANGELOG.md
- Improve README.md with clearer lockstep versioning docs
- Add /changelog command to display full changelog in TUI (newest last)
- Fix changelog description (not a scrollable viewer, just displays in chat)
- Update CHANGELOG for 0.7.7 release
This commit is contained in:
Mario Zechner 2025-11-13 23:37:43 +01:00
parent 7b347291ff
commit bc670bc63c
17 changed files with 1721 additions and 186 deletions

View file

@ -1,82 +1,96 @@
#!/usr/bin/env node
/**
* Syncs inter-package dependency versions in the monorepo
* Updates internal @mariozechner/* package versions in dependent packages
* to match their current versions
* Syncs ALL @mariozechner/* package dependency versions to match their current versions.
* This ensures lockstep versioning across the monorepo.
*/
import { readFileSync, writeFileSync } from 'fs';
import { readFileSync, writeFileSync, readdirSync } from 'fs';
import { join } from 'path';
const packagesDir = join(process.cwd(), 'packages');
const packageDirs = readdirSync(packagesDir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
// Read current versions
const tui = JSON.parse(readFileSync(join(packagesDir, 'tui/package.json'), 'utf8'));
const ai = JSON.parse(readFileSync(join(packagesDir, 'ai/package.json'), 'utf8'));
const agent = JSON.parse(readFileSync(join(packagesDir, 'agent/package.json'), 'utf8'));
const codingAgent = JSON.parse(readFileSync(join(packagesDir, 'coding-agent/package.json'), 'utf8'));
const pods = JSON.parse(readFileSync(join(packagesDir, 'pods/package.json'), 'utf8'));
const webUi = JSON.parse(readFileSync(join(packagesDir, 'web-ui/package.json'), 'utf8'));
// Read all package.json files and build version map
const packages = {};
const versionMap = {};
for (const dir of packageDirs) {
const pkgPath = join(packagesDir, dir, 'package.json');
try {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
packages[dir] = { path: pkgPath, data: pkg };
versionMap[pkg.name] = pkg.version;
} catch (e) {
console.error(`Failed to read ${pkgPath}:`, e.message);
}
}
console.log('Current versions:');
console.log(` @mariozechner/pi-tui: ${tui.version}`);
console.log(` @mariozechner/pi-ai: ${ai.version}`);
console.log(` @mariozechner/pi-agent: ${agent.version}`);
console.log(` @mariozechner/coding-agent: ${codingAgent.version}`);
console.log(` @mariozechner/pi: ${pods.version}`);
console.log(` @mariozechner/pi-web-ui: ${webUi.version}`);
// Update agent's dependencies
let agentUpdated = false;
if (agent.dependencies['@mariozechner/pi-tui']) {
const oldVersion = agent.dependencies['@mariozechner/pi-tui'];
agent.dependencies['@mariozechner/pi-tui'] = `^${tui.version}`;
console.log(`\nUpdated agent's dependency on pi-tui: ${oldVersion} → ^${tui.version}`);
agentUpdated = true;
}
if (agent.dependencies['@mariozechner/pi-ai']) {
const oldVersion = agent.dependencies['@mariozechner/pi-ai'];
agent.dependencies['@mariozechner/pi-ai'] = `^${ai.version}`;
console.log(`Updated agent's dependency on pi-ai: ${oldVersion} → ^${ai.version}`);
agentUpdated = true;
}
if (agentUpdated) {
writeFileSync(join(packagesDir, 'agent/package.json'), JSON.stringify(agent, null, '\t') + '\n');
for (const [name, version] of Object.entries(versionMap).sort()) {
console.log(` ${name}: ${version}`);
}
// Update coding-agent's dependencies
let codingAgentUpdated = false;
if (codingAgent.dependencies['@mariozechner/pi-ai']) {
const oldVersion = codingAgent.dependencies['@mariozechner/pi-ai'];
codingAgent.dependencies['@mariozechner/pi-ai'] = `^${ai.version}`;
console.log(`Updated coding-agent's dependency on pi-ai: ${oldVersion} → ^${ai.version}`);
codingAgentUpdated = true;
}
if (codingAgent.dependencies['@mariozechner/pi-agent']) {
const oldVersion = codingAgent.dependencies['@mariozechner/pi-agent'];
codingAgent.dependencies['@mariozechner/pi-agent'] = `^${agent.version}`;
console.log(`Updated coding-agent's dependency on pi-agent: ${oldVersion} → ^${agent.version}`);
codingAgentUpdated = true;
}
if (codingAgentUpdated) {
writeFileSync(join(packagesDir, 'coding-agent/package.json'), JSON.stringify(codingAgent, null, '\t') + '\n');
// Verify all versions are the same (lockstep)
const versions = new Set(Object.values(versionMap));
if (versions.size > 1) {
console.error('\n❌ ERROR: Not all packages have the same version!');
console.error('Expected lockstep versioning. Run one of:');
console.error(' npm run version:patch');
console.error(' npm run version:minor');
console.error(' npm run version:major');
process.exit(1);
}
// Update pods' dependency on agent
if (pods.dependencies['@mariozechner/pi-agent']) {
const oldVersion = pods.dependencies['@mariozechner/pi-agent'];
pods.dependencies['@mariozechner/pi-agent'] = `^${agent.version}`;
writeFileSync(join(packagesDir, 'pods/package.json'), JSON.stringify(pods, null, '\t') + '\n');
console.log(`Updated pods' dependency on pi-agent: ${oldVersion} → ^${agent.version}`);
console.log('\n✅ All packages at same version (lockstep)');
// Update all inter-package dependencies
let totalUpdates = 0;
for (const [dir, pkg] of Object.entries(packages)) {
let updated = false;
// Check dependencies
if (pkg.data.dependencies) {
for (const [depName, currentVersion] of Object.entries(pkg.data.dependencies)) {
if (versionMap[depName]) {
const newVersion = `^${versionMap[depName]}`;
if (currentVersion !== newVersion) {
console.log(`\n${pkg.data.name}:`);
console.log(` ${depName}: ${currentVersion}${newVersion}`);
pkg.data.dependencies[depName] = newVersion;
updated = true;
totalUpdates++;
}
}
}
}
// Check devDependencies
if (pkg.data.devDependencies) {
for (const [depName, currentVersion] of Object.entries(pkg.data.devDependencies)) {
if (versionMap[depName]) {
const newVersion = `^${versionMap[depName]}`;
if (currentVersion !== newVersion) {
console.log(`\n${pkg.data.name}:`);
console.log(` ${depName}: ${currentVersion}${newVersion} (devDependencies)`);
pkg.data.devDependencies[depName] = newVersion;
updated = true;
totalUpdates++;
}
}
}
}
// Write if updated
if (updated) {
writeFileSync(pkg.path, JSON.stringify(pkg.data, null, '\t') + '\n');
}
}
// Update web-ui's dependency on tui
if (webUi.dependencies['@mariozechner/pi-tui']) {
const oldVersion = webUi.dependencies['@mariozechner/pi-tui'];
webUi.dependencies['@mariozechner/pi-tui'] = `^${tui.version}`;
writeFileSync(join(packagesDir, 'web-ui/package.json'), JSON.stringify(webUi, null, '\t') + '\n');
console.log(`Updated web-ui's dependency on pi-tui: ${oldVersion} → ^${tui.version}`);
if (totalUpdates === 0) {
console.log('\nAll inter-package dependencies already in sync.');
} else {
console.log(`\n✅ Updated ${totalUpdates} dependency version(s)`);
}
console.log('\n✅ Version sync complete!');