@wrongstack/core 0.8.6 → 0.9.0

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.
@@ -1,5 +1,5 @@
1
1
  export { D as DefaultLogger, a as DefaultLoggerOptions } from '../logger-bOzkF5LL.js';
2
- export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from '../plan-templates-Cqdy6rtM.js';
2
+ export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from '../plan-templates-Cc-04Z8o.js';
3
3
  export { D as DefaultSessionReader } from '../session-reader-DsadjyF9.js';
4
4
  export { D as DirectorStateCheckpoint, a as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from '../director-state-BmYi3DGA.js';
5
5
  export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-C0n1EqrC.js';
@@ -1649,9 +1649,14 @@ var RecoveryLock = class {
1649
1649
  };
1650
1650
  }
1651
1651
  /**
1652
- * Claim the lock for the given session. Overwrites any existing lock
1653
- * the caller should have already handled abandonment (via
1654
- * `checkAbandoned`) before calling this.
1652
+ * Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)
1653
+ * to detect whether another process acquired the lock between our
1654
+ * `checkAbandoned()` call and now. If the file already exists, it means
1655
+ * another process won the race and we throw instead of silently
1656
+ * overwriting their recovery record.
1657
+ *
1658
+ * The caller MUST have already called `checkAbandoned()` and handled its
1659
+ * null return before calling this.
1655
1660
  */
1656
1661
  async write(sessionId) {
1657
1662
  await ensureDir(path3.dirname(this.file));
@@ -1662,7 +1667,15 @@ var RecoveryLock = class {
1662
1667
  hostname: this.hostname,
1663
1668
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
1664
1669
  };
1665
- await atomicWrite(this.file, JSON.stringify(lock), { mode: 384 });
1670
+ try {
1671
+ await fsp.writeFile(this.file, JSON.stringify(lock), { flag: "wx", mode: 384 });
1672
+ } catch (err) {
1673
+ const code = err.code;
1674
+ if (code === "EEXIST") {
1675
+ throw new Error(`Recovery lock already held by another process`);
1676
+ }
1677
+ throw err;
1678
+ }
1666
1679
  }
1667
1680
  /**
1668
1681
  * Release the lock. Idempotent — silently succeeds if the file is