smithers-orchestrator 0.26.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smithers-orchestrator",
3
- "version": "0.26.0",
3
+ "version": "0.26.1",
4
4
  "description": "Public Smithers facade for durable coding-agent workflows and Gateway operation",
5
5
  "license": "MIT",
6
6
  "homepage": "https://smithers.sh",
@@ -92,28 +92,28 @@
92
92
  "incur": "^0.4.1",
93
93
  "react": "^19.2.5",
94
94
  "zod": "^4.3.6",
95
- "@smithers-orchestrator/agents": "0.26.0",
96
- "@smithers-orchestrator/components": "0.26.0",
97
- "@smithers-orchestrator/control-plane": "0.26.0",
98
- "@smithers-orchestrator/db": "0.26.0",
99
- "@smithers-orchestrator/cli": "0.26.0",
100
- "@smithers-orchestrator/driver": "0.26.0",
101
- "@smithers-orchestrator/errors": "0.26.0",
102
- "@smithers-orchestrator/engine": "0.26.0",
103
- "@smithers-orchestrator/gateway-client": "0.26.0",
104
- "@smithers-orchestrator/gateway-react": "0.26.0",
105
- "@smithers-orchestrator/graph": "0.26.0",
106
- "@smithers-orchestrator/openapi": "0.26.0",
107
- "@smithers-orchestrator/memory": "0.26.0",
108
- "@smithers-orchestrator/observability": "0.26.0",
109
- "@smithers-orchestrator/react-reconciler": "0.26.0",
110
- "@smithers-orchestrator/sandbox": "0.26.0",
111
- "@smithers-orchestrator/scheduler": "0.26.0",
112
- "@smithers-orchestrator/scorers": "0.26.0",
113
- "@smithers-orchestrator/server": "0.26.0",
114
- "@smithers-orchestrator/time-travel": "0.26.0",
115
- "@smithers-orchestrator/vcs": "0.26.0",
116
- "@smithers-orchestrator/tool-context": "0.26.0"
95
+ "@smithers-orchestrator/agents": "0.26.1",
96
+ "@smithers-orchestrator/components": "0.26.1",
97
+ "@smithers-orchestrator/cli": "0.26.1",
98
+ "@smithers-orchestrator/control-plane": "0.26.1",
99
+ "@smithers-orchestrator/db": "0.26.1",
100
+ "@smithers-orchestrator/driver": "0.26.1",
101
+ "@smithers-orchestrator/engine": "0.26.1",
102
+ "@smithers-orchestrator/errors": "0.26.1",
103
+ "@smithers-orchestrator/gateway-client": "0.26.1",
104
+ "@smithers-orchestrator/gateway-react": "0.26.1",
105
+ "@smithers-orchestrator/graph": "0.26.1",
106
+ "@smithers-orchestrator/memory": "0.26.1",
107
+ "@smithers-orchestrator/observability": "0.26.1",
108
+ "@smithers-orchestrator/react-reconciler": "0.26.1",
109
+ "@smithers-orchestrator/openapi": "0.26.1",
110
+ "@smithers-orchestrator/sandbox": "0.26.1",
111
+ "@smithers-orchestrator/scheduler": "0.26.1",
112
+ "@smithers-orchestrator/scorers": "0.26.1",
113
+ "@smithers-orchestrator/server": "0.26.1",
114
+ "@smithers-orchestrator/time-travel": "0.26.1",
115
+ "@smithers-orchestrator/tool-context": "0.26.1",
116
+ "@smithers-orchestrator/vcs": "0.26.1"
117
117
  },
118
118
  "optionalDependencies": {
119
119
  "@electric-sql/pglite": "0.5.1",
@@ -1,7 +1,7 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import { Effect } from "effect";
3
3
  import { drizzle } from "drizzle-orm/bun-sqlite";
4
- import { existsSync, mkdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
4
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { dirname, join, resolve } from "node:path";
6
6
  import { ensureSmithersTables } from "@smithers-orchestrator/db/ensure";
7
7
  import { POSTGRES, quoteIdentifier, translateDdl } from "@smithers-orchestrator/db/dialect";
@@ -875,8 +875,44 @@ async function pgliteRunCountAt(cwd, workspaceRoot, opts) {
875
875
  }
876
876
  }
877
877
 
878
+ /**
879
+ * Read the migration receipt (migrated.json) at the workspace root and return
880
+ * the CURRENT backend it records. After a prior migration this receipt is the
881
+ * AUTHORITY on which backend now holds the run store: earlier-backend stores
882
+ * (e.g. a leftover smithers.db after sqlite->pglite) can still sit on disk, so
883
+ * a run-count heuristic alone would misread the source. Returns undefined when
884
+ * there is no usable receipt so callers can fall back to the heuristic.
885
+ * @param {string} workspaceRoot
886
+ * @returns {MigrateSmithersBackend | undefined}
887
+ */
888
+ function readReceiptCurrentBackend(workspaceRoot) {
889
+ const receiptPath = join(workspaceRoot, ".smithers", MIGRATION_MARKER_NAME);
890
+ if (!existsSync(receiptPath)) return undefined;
891
+ try {
892
+ const receipt = JSON.parse(readFileSync(receiptPath, "utf8"));
893
+ // migrated.json records the destination of the last migration under
894
+ // `target.backend`; a top-level `backend` (backend.json shape) is also
895
+ // honored defensively. Either is the current authoritative backend.
896
+ const current = receipt?.target?.backend ?? receipt?.backend;
897
+ if (current === undefined || current === null || current === "") {
898
+ return undefined;
899
+ }
900
+ return normalizeBackend(current);
901
+ }
902
+ catch {
903
+ return undefined;
904
+ }
905
+ }
906
+
878
907
  async function inferSourceBackend(opts, cwd, workspaceRoot, dbPath, target) {
879
908
  if (opts.from) return normalizeBackend(opts.from);
909
+ // The migration receipt is authoritative after a prior migration: trust the
910
+ // backend it records over any leftover stores on disk. When the receipt's
911
+ // current backend equals the requested target, the caller's clear
912
+ // "source and target are both X" guard fires; only fall back to the
913
+ // run-count heuristic (and SMITHERS_BACKEND_CONFLICT) when no receipt exists.
914
+ const receiptBackend = readReceiptCurrentBackend(workspaceRoot);
915
+ if (receiptBackend) return receiptBackend;
880
916
  const counts = [
881
917
  { backend: "sqlite", runCount: sqliteRunCountAt(inferSqliteSourceDbPath(dbPath, workspaceRoot, Boolean(opts.dbPath))) },
882
918
  { backend: "pglite", runCount: await pgliteRunCountAt(cwd, workspaceRoot, opts) },