negotium 0.2.1 → 0.2.2

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/dist/main.js CHANGED
@@ -4594,7 +4594,7 @@ var exports_version = {};
4594
4594
  __export(exports_version, {
4595
4595
  NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
4596
4596
  });
4597
- var NEGOTIUM_VERSION = "0.2.1";
4597
+ var NEGOTIUM_VERSION = "0.2.2";
4598
4598
 
4599
4599
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
4600
4600
  import { spawn as spawn3 } from "child_process";
@@ -43726,18 +43726,49 @@ function addDirectoryContents(operations, sourceDir, destinationDir, stagingDir)
43726
43726
  });
43727
43727
  }
43728
43728
  }
43729
- function assertNoCollisions(operations) {
43729
+ function pathWithin(path, root) {
43730
+ return path === root || path.startsWith(`${root}/`);
43731
+ }
43732
+ function collisionPolicy(operation, stateDir2) {
43733
+ const destination = operation.destination;
43734
+ if (!destination || !existsSync36(destination))
43735
+ return;
43736
+ if (pathWithin(destination, join42(stateDir2, "runtime")))
43737
+ return "keep-destination";
43738
+ if (pathWithin(destination, join42(stateDir2, "binaries")))
43739
+ return "keep-destination";
43740
+ if (pathWithin(destination, join42(stateDir2, "secrets")))
43741
+ return "replace-destination";
43742
+ if (destination === join42(stateDir2, "data", "vault", "vault.db")) {
43743
+ return "replace-destination";
43744
+ }
43745
+ if (pathWithin(destination, join42(stateDir2, "browser", "profiles"))) {
43746
+ return "replace-destination";
43747
+ }
43748
+ if (pathWithin(destination, join42(stateDir2, "data", "conversations")) && destination.endsWith(".jsonl")) {
43749
+ return "merge-jsonl";
43750
+ }
43751
+ if (pathWithin(destination, join42(stateDir2, "data", "tasks")) && destination.endsWith(".json")) {
43752
+ return "merge-tasks";
43753
+ }
43754
+ if (statSync19(operation.source).isFile() && statSync19(destination).isFile() && readFileSync27(operation.source).equals(readFileSync27(destination))) {
43755
+ return "keep-destination";
43756
+ }
43757
+ throw new Error(`Migration collision at ${destination}.`);
43758
+ }
43759
+ function configureCollisions(operations, stateDir2, stagingRoot) {
43730
43760
  const destinations = new Set;
43731
43761
  for (const operation of operations) {
43732
43762
  if (!operation.destination)
43733
43763
  continue;
43734
- if (existsSync36(operation.destination)) {
43735
- throw new Error(`Migration collision at ${operation.destination}.`);
43736
- }
43737
43764
  if (destinations.has(operation.destination)) {
43738
43765
  throw new Error(`Multiple legacy paths target ${operation.destination}.`);
43739
43766
  }
43740
43767
  destinations.add(operation.destination);
43768
+ operation.collision = collisionPolicy(operation, stateDir2);
43769
+ if (operation.collision && operation.collision !== "keep-destination") {
43770
+ operation.destinationStaged = join42(stagingRoot, randomUUID34());
43771
+ }
43741
43772
  }
43742
43773
  }
43743
43774
  function writeJournal(path, journal) {
@@ -43746,16 +43777,96 @@ function writeJournal(path, journal) {
43746
43777
  }
43747
43778
  function rollbackFilesystem(journal, journalPath) {
43748
43779
  for (const operation of [...journal.operations].reverse()) {
43749
- const current3 = operation.state === "placed" ? operation.destination : operation.staged;
43750
- if (!current3 || !existsSync36(current3) || existsSync36(operation.source))
43751
- continue;
43752
- mkdirSync35(dirname23(operation.source), { recursive: true });
43753
- renameSync16(current3, operation.source);
43780
+ if (operation.state === "placed") {
43781
+ if (operation.collision === "keep-destination" || !operation.destination) {
43782
+ if (existsSync36(operation.staged) && !existsSync36(operation.source)) {
43783
+ mkdirSync35(dirname23(operation.source), { recursive: true });
43784
+ renameSync16(operation.staged, operation.source);
43785
+ }
43786
+ } else if (operation.destination && existsSync36(operation.destination)) {
43787
+ if (operation.collision === "merge-jsonl" || operation.collision === "merge-tasks") {
43788
+ rmSync11(operation.destination, { recursive: true, force: true });
43789
+ if (existsSync36(operation.staged) && !existsSync36(operation.source)) {
43790
+ mkdirSync35(dirname23(operation.source), { recursive: true });
43791
+ renameSync16(operation.staged, operation.source);
43792
+ }
43793
+ } else if (!existsSync36(operation.source)) {
43794
+ mkdirSync35(dirname23(operation.source), { recursive: true });
43795
+ renameSync16(operation.destination, operation.source);
43796
+ }
43797
+ }
43798
+ } else if (existsSync36(operation.staged) && !existsSync36(operation.source)) {
43799
+ mkdirSync35(dirname23(operation.source), { recursive: true });
43800
+ renameSync16(operation.staged, operation.source);
43801
+ }
43802
+ if (operation.destination && operation.destinationStaged && existsSync36(operation.destinationStaged) && !existsSync36(operation.destination)) {
43803
+ mkdirSync35(dirname23(operation.destination), { recursive: true });
43804
+ renameSync16(operation.destinationStaged, operation.destination);
43805
+ }
43754
43806
  operation.state = "pending";
43755
43807
  }
43756
43808
  journal.phase = "filesystem";
43757
43809
  writeJournal(journalPath, journal);
43758
43810
  }
43811
+ function mergedJsonl(source, destination) {
43812
+ const lines = new Set;
43813
+ for (const path of [source, destination]) {
43814
+ for (const line2 of readFileSync27(path, "utf8").split(/\r?\n/)) {
43815
+ if (line2)
43816
+ lines.add(line2);
43817
+ }
43818
+ }
43819
+ return lines.size > 0 ? `${[...lines].join(`
43820
+ `)}
43821
+ ` : "";
43822
+ }
43823
+ function readTaskFile(path) {
43824
+ const parsed = JSON.parse(readFileSync27(path, "utf8"));
43825
+ if (parsed.version !== 1 || !Array.isArray(parsed.tasks)) {
43826
+ throw new Error(`Invalid task file during migration: ${path}`);
43827
+ }
43828
+ return parsed;
43829
+ }
43830
+ function mergedTasks(source, destination) {
43831
+ const legacy = readTaskFile(source).tasks;
43832
+ const current3 = readTaskFile(destination).tasks;
43833
+ const merged = legacy.map((task) => ({ ...task }));
43834
+ const usedIds = new Set(merged.map((task) => String(task.id)));
43835
+ let nextId = Math.max(0, ...[...usedIds].map(Number).filter(Number.isInteger)) + 1;
43836
+ const remapped = new Map;
43837
+ for (const task of current3) {
43838
+ const originalId = String(task.id);
43839
+ const exact = merged.find((candidate) => candidate.id === originalId && JSON.stringify(candidate) === JSON.stringify(task));
43840
+ if (exact) {
43841
+ remapped.set(originalId, originalId);
43842
+ continue;
43843
+ }
43844
+ const id = usedIds.has(originalId) ? String(nextId++) : originalId;
43845
+ usedIds.add(id);
43846
+ remapped.set(originalId, id);
43847
+ merged.push({ ...task, id });
43848
+ }
43849
+ for (const task of merged.slice(legacy.length)) {
43850
+ if (task.blockedBy)
43851
+ task.blockedBy = task.blockedBy.map((id) => remapped.get(id) ?? id);
43852
+ }
43853
+ return `${JSON.stringify({ version: 1, tasks: merged }, null, 2)}
43854
+ `;
43855
+ }
43856
+ function placeOperation(operation) {
43857
+ if (!operation.destination || operation.collision === "keep-destination")
43858
+ return;
43859
+ mkdirSync35(dirname23(operation.destination), { recursive: true });
43860
+ if (operation.collision === "merge-jsonl") {
43861
+ writeFileSync25(operation.destination, mergedJsonl(operation.staged, operation.destinationStaged));
43862
+ return;
43863
+ }
43864
+ if (operation.collision === "merge-tasks") {
43865
+ writeFileSync25(operation.destination, mergedTasks(operation.staged, operation.destinationStaged));
43866
+ return;
43867
+ }
43868
+ renameSync16(operation.staged, operation.destination);
43869
+ }
43759
43870
  function tablesWithColumn(database, columnName) {
43760
43871
  const tables = database.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all();
43761
43872
  return tables.map((row) => row.name).filter((table) => database.query(`PRAGMA table_info("${table.replaceAll('"', '""')}")`).all().some((column) => column.name === columnName));
@@ -43993,7 +44104,7 @@ function migrateSingleUserState(options) {
43993
44104
  state: "pending"
43994
44105
  });
43995
44106
  }
43996
- assertNoCollisions(operations);
44107
+ configureCollisions(operations, stateDir2, stagingRoot);
43997
44108
  journal = {
43998
44109
  id: SINGLE_USER_MIGRATION_ID,
43999
44110
  sourcePrincipal: source,
@@ -44009,21 +44120,43 @@ function migrateSingleUserState(options) {
44009
44120
  const vaultDbBackup = join42(stagingRoot, "vault.db.rollback");
44010
44121
  try {
44011
44122
  for (const operation of journal.operations) {
44012
- if (operation.state === "pending" && !existsSync36(operation.source) && existsSync36(operation.staged)) {
44013
- operation.state = "staged";
44014
- }
44015
- if (operation.state === "staged" && operation.destination && !existsSync36(operation.staged) && existsSync36(operation.destination)) {
44016
- operation.state = "placed";
44123
+ if (operation.state === "staged")
44124
+ operation.state = "source-staged";
44125
+ if (operation.state === "pending" && !existsSync36(operation.source)) {
44126
+ if (existsSync36(operation.staged))
44127
+ operation.state = "source-staged";
44128
+ else if (operation.destination && existsSync36(operation.destination)) {
44129
+ operation.state = "placed";
44130
+ }
44017
44131
  }
44018
44132
  if (operation.state === "pending") {
44019
44133
  mkdirSync35(dirname23(operation.staged), { recursive: true });
44020
44134
  renameSync16(operation.source, operation.staged);
44021
- operation.state = "staged";
44135
+ operation.state = "source-staged";
44136
+ writeJournal(journalPath, journal);
44137
+ }
44138
+ if (operation.state === "source-staged" && operation.collision === "replace-destination" && operation.destination && operation.destinationStaged && !existsSync36(operation.staged) && existsSync36(operation.destination) && existsSync36(operation.destinationStaged)) {
44139
+ operation.state = "placed";
44140
+ writeJournal(journalPath, journal);
44141
+ }
44142
+ if (operation.state === "destination-staged" && operation.collision !== "merge-jsonl" && operation.collision !== "merge-tasks" && operation.collision !== "keep-destination" && operation.destination && !existsSync36(operation.staged) && existsSync36(operation.destination)) {
44143
+ operation.state = "placed";
44144
+ writeJournal(journalPath, journal);
44145
+ }
44146
+ if (operation.state === "source-staged") {
44147
+ if (operation.destination && operation.destinationStaged) {
44148
+ if (existsSync36(operation.destination) && !existsSync36(operation.destinationStaged)) {
44149
+ renameSync16(operation.destination, operation.destinationStaged);
44150
+ }
44151
+ if (!existsSync36(operation.destinationStaged)) {
44152
+ throw new Error(`Missing collision backup for ${operation.destination}.`);
44153
+ }
44154
+ }
44155
+ operation.state = "destination-staged";
44022
44156
  writeJournal(journalPath, journal);
44023
44157
  }
44024
- if (operation.state === "staged" && operation.destination) {
44025
- mkdirSync35(dirname23(operation.destination), { recursive: true });
44026
- renameSync16(operation.staged, operation.destination);
44158
+ if (operation.state === "destination-staged") {
44159
+ placeOperation(operation);
44027
44160
  operation.state = "placed";
44028
44161
  writeJournal(journalPath, journal);
44029
44162
  }
@@ -44066,11 +44199,22 @@ function migrateSingleUserState(options) {
44066
44199
  migratedTables
44067
44200
  };
44068
44201
  for (const store of ["conversations", "tasks", "users"]) {
44069
- rmSync11(join42(stateDir2, "data", store, source), { recursive: true, force: true });
44202
+ rmSync11(join42(stateDir2, "data", store, source), {
44203
+ recursive: true,
44204
+ force: true
44205
+ });
44070
44206
  }
44071
- rmSync11(join42(stateDir2, "workspace", "browser-profiles"), { recursive: true, force: true });
44207
+ rmSync11(join42(stateDir2, "run"), { recursive: true, force: true });
44208
+ rmSync11(join42(stateDir2, "bin"), { recursive: true, force: true });
44209
+ rmSync11(join42(stateDir2, "workspace", "browser-profiles"), {
44210
+ recursive: true,
44211
+ force: true
44212
+ });
44072
44213
  writeFileSync25(markerPath, `${JSON.stringify(marker, null, 2)}
44073
- `, { mode: 384, flag: "wx" });
44214
+ `, {
44215
+ mode: 384,
44216
+ flag: "wx"
44217
+ });
44074
44218
  journal.phase = "complete";
44075
44219
  rmSync11(stagingRoot, { recursive: true, force: true });
44076
44220
  return {
@@ -44798,4 +44942,4 @@ switch (command) {
44798
44942
  }
44799
44943
  }
44800
44944
 
44801
- //# debugId=9371DDB5367979FC64756E2164756E21
44945
+ //# debugId=29CE1495263F2C6864756E2164756E21