astrocode-workflow 0.3.3 → 0.3.4

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": "astrocode-workflow",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -83,6 +83,7 @@ function safeUnlink(p: string) {
83
83
 
84
84
  /**
85
85
  * Reads & validates lock file defensively.
86
+ * Supports both v2 JSON format and legacy PID-only format for compatibility.
86
87
  * Returns null on any parse/validation failure.
87
88
  */
88
89
  function readLock(lockPath: string): LockFile | null {
@@ -91,23 +92,46 @@ function readLock(lockPath: string): LockFile | null {
91
92
  if (!st.isFile()) return null;
92
93
  if (st.size <= 0 || st.size > MAX_LOCK_BYTES) return null;
93
94
 
94
- const raw = fs.readFileSync(lockPath, "utf8");
95
- const parsed = JSON.parse(raw) as LockFile;
95
+ const raw = fs.readFileSync(lockPath, "utf8").trim();
96
96
 
97
- if (!parsed) return null;
98
- if (parsed.v !== LOCK_VERSION) return null;
99
-
100
- if (typeof parsed.pid !== "number") return null;
101
- if (typeof parsed.created_at !== "string") return null;
102
- if (typeof parsed.updated_at !== "string") return null;
103
- if (typeof parsed.repo_root !== "string") return null;
104
- if (typeof parsed.instance_id !== "string") return null;
105
- if (typeof parsed.lease_id !== "string") return null;
97
+ // Try v2 JSON first
98
+ try {
99
+ const parsed = JSON.parse(raw) as LockFile;
100
+ if (parsed && typeof parsed === "object" && parsed.v === LOCK_VERSION) {
101
+ if (typeof parsed.pid !== "number") return null;
102
+ if (typeof parsed.created_at !== "string") return null;
103
+ if (typeof parsed.updated_at !== "string") return null;
104
+ if (typeof parsed.repo_root !== "string") return null;
105
+ if (typeof parsed.instance_id !== "string") return null;
106
+ if (typeof parsed.lease_id !== "string") return null;
107
+
108
+ if (parsed.session_id !== undefined && typeof parsed.session_id !== "string") return null;
109
+ if (parsed.owner !== undefined && typeof parsed.owner !== "string") return null;
110
+
111
+ return parsed;
112
+ }
113
+ } catch {
114
+ // Not JSON, try legacy format
115
+ }
106
116
 
107
- if (parsed.session_id !== undefined && typeof parsed.session_id !== "string") return null;
108
- if (parsed.owner !== undefined && typeof parsed.owner !== "string") return null;
117
+ // Legacy format: just PID as number string
118
+ const legacyPid = parseInt(raw, 10);
119
+ if (Number.isNaN(legacyPid) || legacyPid <= 0) return null;
109
120
 
110
- return parsed;
121
+ // Convert legacy to v2 format
122
+ const now = nowISO();
123
+ const leaseId = crypto.randomUUID();
124
+ return {
125
+ v: LOCK_VERSION,
126
+ pid: legacyPid,
127
+ created_at: now, // Approximate
128
+ updated_at: now,
129
+ repo_root: "", // Unknown, will be filled by caller
130
+ instance_id: PROCESS_INSTANCE_ID, // Assume same instance
131
+ session_id: undefined,
132
+ lease_id: leaseId,
133
+ owner: "legacy-lock",
134
+ };
111
135
  } catch {
112
136
  return null;
113
137
  }
@@ -453,8 +477,8 @@ export async function acquireRepoLock(opts: {
453
477
  continue;
454
478
  }
455
479
 
456
- // Re-entrant by SAME PROCESS IDENTITY (pid+instance).
457
- if (existing.pid === myPid && existing.instance_id === PROCESS_INSTANCE_ID) {
480
+ // Re-entrant by SAME PROCESS IDENTITY (pid+instance), or legacy lock with same PID.
481
+ if (existing.pid === myPid && (existing.instance_id === PROCESS_INSTANCE_ID || existing.owner === "legacy-lock")) {
458
482
  const leaseId = crypto.randomUUID();
459
483
 
460
484
  writeLockAtomicish(lockPath, {
@@ -462,6 +486,7 @@ export async function acquireRepoLock(opts: {
462
486
  v: LOCK_VERSION,
463
487
  updated_at: nowISO(),
464
488
  repo_root: repoRoot,
489
+ instance_id: PROCESS_INSTANCE_ID, // Upgrade legacy
465
490
  session_id: sessionId ?? existing.session_id,
466
491
  owner: owner ?? existing.owner,
467
492
  lease_id: leaseId,