feat(agent): prepare SQLite storage package for publishing
This commit is contained in:
Generated
+2
-2
@@ -786,7 +786,7 @@
|
|||||||
"resolved": "packages/agent",
|
"resolved": "packages/agent",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@earendil-works/pi-agent-sqlite-node": {
|
"node_modules/@earendil-works/pi-storage-sqlite-node": {
|
||||||
"resolved": "packages/storage/sqlite-node",
|
"resolved": "packages/storage/sqlite-node",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
@@ -6093,7 +6093,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/storage/sqlite-node": {
|
"packages/storage/sqlite-node": {
|
||||||
"name": "@earendil-works/pi-agent-sqlite-node",
|
"name": "@earendil-works/pi-storage-sqlite-node",
|
||||||
"version": "0.80.10",
|
"version": "0.80.10",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ npm install @earendil-works/pi-agent-core
|
|||||||
|
|
||||||
### SQLite session backends
|
### SQLite session backends
|
||||||
|
|
||||||
The SQLite session backend and the `node:sqlite` adapter live in a separate package, `@earendil-works/pi-agent-sqlite-node`, so the core package does not pull in runtime builtins or native SQLite dependencies by default. The backend accepts a runtime-specific SQLite factory, allowing other storage backends to ship as their own packages in the future.
|
The SQLite session backend and the `node:sqlite` adapter live in a separate package, `@earendil-works/pi-storage-sqlite-node`, so the core package does not pull in runtime builtins or native SQLite dependencies by default. The backend accepts a runtime-specific SQLite factory, allowing other storage backends to ship as their own packages in the future.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added a Node.js SQLite storage backend for agent harness sessions, including migrations and materialized session views ([#6594](https://github.com/earendil-works/pi/pull/6594) by [@cristinaponcela](https://github.com/cristinaponcela)).
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# @earendil-works/pi-agent-sqlite-node
|
# @earendil-works/pi-storage-sqlite-node
|
||||||
|
|
||||||
Node sqlite storage backend for `@earendil-works/pi-agent-core` sessions. Provides the
|
Node sqlite storage backend for `@earendil-works/pi-agent-core` sessions. Provides the
|
||||||
`node:sqlite` adapter (`SqliteDatabase` implementation) and the SQLite session
|
`node:sqlite` adapter (`SqliteDatabase` implementation) and the SQLite session
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@earendil-works/pi-agent-sqlite-node",
|
"name": "@earendil-works/pi-storage-sqlite-node",
|
||||||
"version": "0.80.10",
|
"version": "0.80.10",
|
||||||
"description": "Node sqlite storage backend for @earendil-works/pi-agent-core sessions",
|
"description": "Node sqlite storage backend for @earendil-works/pi-agent-core sessions",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -13,7 +13,8 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"CHANGELOG.md"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "node -e \"import('node:fs/promises').then(fs=>fs.rm('dist',{recursive:true,force:true}))\"",
|
"clean": "node -e \"import('node:fs/promises').then(fs=>fs.rm('dist',{recursive:true,force:true}))\"",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const packages = [
|
|||||||
{ directory: "packages/ai", name: "@earendil-works/pi-ai" },
|
{ directory: "packages/ai", name: "@earendil-works/pi-ai" },
|
||||||
{ directory: "packages/tui", name: "@earendil-works/pi-tui" },
|
{ directory: "packages/tui", name: "@earendil-works/pi-tui" },
|
||||||
{ directory: "packages/agent", name: "@earendil-works/pi-agent-core" },
|
{ directory: "packages/agent", name: "@earendil-works/pi-agent-core" },
|
||||||
|
{ directory: "packages/storage/sqlite-node", name: "@earendil-works/pi-storage-sqlite-node" },
|
||||||
{ directory: "packages/coding-agent", name: "@earendil-works/pi-coding-agent" },
|
{ directory: "packages/coding-agent", name: "@earendil-works/pi-coding-agent" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { existsSync, readdirSync } from "node:fs";
|
||||||
|
import { join } from "node:path";
|
||||||
|
|
||||||
|
const SKIPPED_DIRECTORIES = new Set(["dist", "node_modules"]);
|
||||||
|
|
||||||
|
export function findPackageDirectories(root = "packages") {
|
||||||
|
const packageDirectories = [];
|
||||||
|
|
||||||
|
function visit(directory) {
|
||||||
|
if (existsSync(join(directory, "package.json"))) {
|
||||||
|
packageDirectories.push(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
||||||
|
if (!entry.isDirectory() || SKIPPED_DIRECTORIES.has(entry.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visit(join(directory, entry.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(root);
|
||||||
|
return packageDirectories.sort();
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { join } from "node:path";
|
|||||||
const packages = [
|
const packages = [
|
||||||
{ directory: "packages/ai", name: "@earendil-works/pi-ai" },
|
{ directory: "packages/ai", name: "@earendil-works/pi-ai" },
|
||||||
{ directory: "packages/agent", name: "@earendil-works/pi-agent-core" },
|
{ directory: "packages/agent", name: "@earendil-works/pi-agent-core" },
|
||||||
|
{ directory: "packages/storage/sqlite-node", name: "@earendil-works/pi-storage-sqlite-node" },
|
||||||
{ directory: "packages/tui", name: "@earendil-works/pi-tui" },
|
{ directory: "packages/tui", name: "@earendil-works/pi-tui" },
|
||||||
{ directory: "packages/coding-agent", name: "@earendil-works/pi-coding-agent" },
|
{ directory: "packages/coding-agent", name: "@earendil-works/pi-coding-agent" },
|
||||||
];
|
];
|
||||||
|
|||||||
+6
-7
@@ -18,9 +18,10 @@
|
|||||||
* 9. Push main and the tag to trigger CI publishing
|
* 9. Push main and the tag to trigger CI publishing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { execSync } from "child_process";
|
import { execSync } from "node:child_process";
|
||||||
import { readFileSync, writeFileSync, readdirSync, existsSync } from "fs";
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||||
import { join } from "path";
|
import { join } from "node:path";
|
||||||
|
import { findPackageDirectories } from "./package-workspaces.mjs";
|
||||||
|
|
||||||
const RELEASE_TARGET = process.argv[2];
|
const RELEASE_TARGET = process.argv[2];
|
||||||
const BUMP_TYPES = new Set(["major", "minor", "patch"]);
|
const BUMP_TYPES = new Set(["major", "minor", "patch"]);
|
||||||
@@ -97,10 +98,8 @@ function bumpOrSetVersion(target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getChangelogs() {
|
function getChangelogs() {
|
||||||
const packagesDir = "packages";
|
return findPackageDirectories()
|
||||||
const packages = readdirSync(packagesDir);
|
.map((directory) => join(directory, "CHANGELOG.md"))
|
||||||
return packages
|
|
||||||
.map((pkg) => join(packagesDir, pkg, "CHANGELOG.md"))
|
|
||||||
.filter((path) => existsSync(path));
|
.filter((path) => existsSync(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+48
-68
@@ -1,96 +1,76 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs all workspace package dependency versions to match their current versions.
|
* Syncs all non-private workspace package dependency versions to match their current versions.
|
||||||
* This ensures lockstep versioning across the monorepo.
|
* This ensures release packages, including unpublished packages, use lockstep versioning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { readFileSync, writeFileSync, readdirSync } from 'fs';
|
import { readFileSync, writeFileSync } from "node:fs";
|
||||||
import { join } from 'path';
|
import { join } from "node:path";
|
||||||
|
import { findPackageDirectories } from "./package-workspaces.mjs";
|
||||||
|
|
||||||
const packagesDir = join(process.cwd(), 'packages');
|
const packages = findPackageDirectories()
|
||||||
const packageDirs = readdirSync(packagesDir, { withFileTypes: true })
|
.map((directory) => {
|
||||||
.filter(dirent => dirent.isDirectory())
|
const path = join(directory, "package.json");
|
||||||
.map(dirent => dirent.name);
|
return { data: JSON.parse(readFileSync(path, "utf8")), path };
|
||||||
|
})
|
||||||
|
.filter((pkg) => pkg.data.private !== true);
|
||||||
|
|
||||||
// Read all package.json files and build version map
|
const versionMap = new Map(packages.map((pkg) => [pkg.data.name, pkg.data.version]));
|
||||||
const packages = {};
|
|
||||||
const versionMap = {};
|
|
||||||
|
|
||||||
for (const dir of packageDirs) {
|
console.log("Current versions:");
|
||||||
const pkgPath = join(packagesDir, dir, 'package.json');
|
for (const [name, version] of [...versionMap].sort(([a], [b]) => a.localeCompare(b))) {
|
||||||
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:');
|
|
||||||
for (const [name, version] of Object.entries(versionMap).sort()) {
|
|
||||||
console.log(` ${name}: ${version}`);
|
console.log(` ${name}: ${version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify all versions are the same (lockstep)
|
const versions = new Set(versionMap.values());
|
||||||
const versions = new Set(Object.values(versionMap));
|
|
||||||
if (versions.size > 1) {
|
if (versions.size > 1) {
|
||||||
console.error('\n❌ ERROR: Not all packages have the same version!');
|
console.error("\nERROR: Not all non-private packages have the same version.");
|
||||||
console.error('Expected lockstep versioning. Run one of:');
|
console.error("Expected lockstep versioning. Run one of:");
|
||||||
console.error(' npm run version:patch');
|
console.error(" npm run version:patch");
|
||||||
console.error(' npm run version:minor');
|
console.error(" npm run version:minor");
|
||||||
console.error(' npm run version:major');
|
console.error(" npm run version:major");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('\n✅ All packages at same version (lockstep)');
|
console.log("\nAll non-private packages are at the same version (lockstep).");
|
||||||
|
|
||||||
// Update all inter-package dependencies
|
|
||||||
let totalUpdates = 0;
|
let totalUpdates = 0;
|
||||||
for (const [dir, pkg] of Object.entries(packages)) {
|
for (const pkg of packages) {
|
||||||
let updated = false;
|
let updated = false;
|
||||||
|
|
||||||
// Check dependencies
|
for (const dependencyType of ["dependencies", "devDependencies"]) {
|
||||||
if (pkg.data.dependencies) {
|
const dependencies = pkg.data[dependencyType];
|
||||||
for (const [depName, currentVersion] of Object.entries(pkg.data.dependencies)) {
|
if (!dependencies) {
|
||||||
if (versionMap[depName]) {
|
continue;
|
||||||
const newVersion = `^${versionMap[depName]}`;
|
}
|
||||||
if (currentVersion !== newVersion) {
|
|
||||||
console.log(`\n${pkg.data.name}:`);
|
for (const [dependencyName, currentVersion] of Object.entries(dependencies)) {
|
||||||
console.log(` ${depName}: ${currentVersion} → ${newVersion}`);
|
const dependencyVersion = versionMap.get(dependencyName);
|
||||||
pkg.data.dependencies[depName] = newVersion;
|
if (!dependencyVersion) {
|
||||||
updated = true;
|
continue;
|
||||||
totalUpdates++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const newVersion = `^${dependencyVersion}`;
|
||||||
|
if (currentVersion === newVersion) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n${pkg.data.name}:`);
|
||||||
|
console.log(` ${dependencyName}: ${currentVersion} → ${newVersion}${dependencyType === "devDependencies" ? " (devDependencies)" : ""}`);
|
||||||
|
dependencies[dependencyName] = 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) {
|
if (updated) {
|
||||||
writeFileSync(pkg.path, JSON.stringify(pkg.data, null, '\t') + '\n');
|
writeFileSync(pkg.path, `${JSON.stringify(pkg.data, null, "\t")}\n`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalUpdates === 0) {
|
if (totalUpdates === 0) {
|
||||||
console.log('\nAll inter-package dependencies already in sync.');
|
console.log("\nAll inter-package dependencies are already in sync.");
|
||||||
} else {
|
} else {
|
||||||
console.log(`\n✅ Updated ${totalUpdates} dependency version(s)`);
|
console.log(`\nUpdated ${totalUpdates} dependency version(s).`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user