opencode-qoder-bridge 0.1.7 → 0.1.9

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +67 -1
  2. package/README.md +111 -38
  3. package/SECURITY.md +3 -2
  4. package/bin/statusline.mjs +30 -6
  5. package/bin/usage.mjs +7 -6
  6. package/dist/async-utils.d.ts +8 -0
  7. package/dist/async-utils.d.ts.map +1 -0
  8. package/dist/async-utils.js +27 -0
  9. package/dist/async-utils.js.map +1 -0
  10. package/dist/auth.d.ts +4 -2
  11. package/dist/auth.d.ts.map +1 -1
  12. package/dist/auth.js +28 -8
  13. package/dist/auth.js.map +1 -1
  14. package/dist/cost.d.ts +2 -1
  15. package/dist/cost.d.ts.map +1 -1
  16. package/dist/cost.js +163 -63
  17. package/dist/cost.js.map +1 -1
  18. package/dist/errors.d.ts.map +1 -1
  19. package/dist/errors.js +6 -3
  20. package/dist/errors.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +156 -46
  24. package/dist/index.js.map +1 -1
  25. package/dist/language-model.d.ts +22 -0
  26. package/dist/language-model.d.ts.map +1 -1
  27. package/dist/language-model.js +934 -186
  28. package/dist/language-model.js.map +1 -1
  29. package/dist/logger.d.ts +1 -0
  30. package/dist/logger.d.ts.map +1 -1
  31. package/dist/logger.js +35 -5
  32. package/dist/logger.js.map +1 -1
  33. package/dist/mcp-bridge.d.ts.map +1 -1
  34. package/dist/mcp-bridge.js +71 -7
  35. package/dist/mcp-bridge.js.map +1 -1
  36. package/dist/models.d.ts +8 -1
  37. package/dist/models.d.ts.map +1 -1
  38. package/dist/models.js +157 -46
  39. package/dist/models.js.map +1 -1
  40. package/dist/prompt-builder.d.ts.map +1 -1
  41. package/dist/prompt-builder.js +241 -43
  42. package/dist/prompt-builder.js.map +1 -1
  43. package/dist/sdk-auth.d.ts +3 -3
  44. package/dist/sdk-auth.d.ts.map +1 -1
  45. package/dist/sdk-auth.js +13 -9
  46. package/dist/sdk-auth.js.map +1 -1
  47. package/dist/sdk-session.d.ts.map +1 -1
  48. package/dist/sdk-session.js +26 -2
  49. package/dist/sdk-session.js.map +1 -1
  50. package/dist/session-store.d.ts +14 -3
  51. package/dist/session-store.d.ts.map +1 -1
  52. package/dist/session-store.js +451 -46
  53. package/dist/session-store.js.map +1 -1
  54. package/dist/state-dir.d.ts.map +1 -1
  55. package/dist/state-dir.js +2 -1
  56. package/dist/state-dir.js.map +1 -1
  57. package/dist/tool-normalizer.d.ts.map +1 -1
  58. package/dist/tool-normalizer.js +11 -2
  59. package/dist/tool-normalizer.js.map +1 -1
  60. package/dist/tui-register.d.ts.map +1 -1
  61. package/dist/tui-register.js +88 -37
  62. package/dist/tui-register.js.map +1 -1
  63. package/dist/tui.d.ts.map +1 -1
  64. package/dist/tui.js +42 -17
  65. package/dist/tui.js.map +1 -1
  66. package/dist/types.d.ts +14 -4
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/usage.d.ts.map +1 -1
  69. package/dist/usage.js +55 -30
  70. package/dist/usage.js.map +1 -1
  71. package/package.json +12 -4
@@ -4,7 +4,18 @@ export interface QoderSessionRecord {
4
4
  createdAt: string;
5
5
  lastUsedAt: string;
6
6
  }
7
- export declare function getQoderSession(key: string): Promise<QoderSessionRecord | null>;
8
- export declare function ensureQoderSession(key: string, qoderSessionId: string, cwd: string): Promise<QoderSessionRecord>;
9
- export declare function deleteQoderSession(key: string): Promise<void>;
7
+ /**
8
+ * Serialize a persisted/explicit Qoder session across both threads and OS
9
+ * processes. The lease covers the SDK turn, not just the JSON mapping write.
10
+ */
11
+ export declare function withQoderSessionLease<T>(key: string, cwd: string, signal: AbortSignal | undefined, fn: () => Promise<T>): Promise<T | undefined>;
12
+ /** Read the generation used to fence reset-all against in-flight writes. */
13
+ export declare function getQoderSessionResetEpoch(): Promise<string>;
14
+ export declare function getQoderSession(key: string, cwd?: string): Promise<QoderSessionRecord | null>;
15
+ export declare function getQoderSessionForCwd(key: string, cwd: string): Promise<QoderSessionRecord | null>;
16
+ export declare function ensureQoderSession(key: string, qoderSessionId: string, cwd: string, expectedResetEpoch?: string): Promise<QoderSessionRecord>;
17
+ export declare function deleteQoderSession(key: string, cwd?: string): Promise<void>;
18
+ /** Delete a mapping after waiting for any active turn in the same workspace. */
19
+ export declare function deleteQoderSessionForCwd(key: string, cwd: string, leaseKey?: string): Promise<void>;
20
+ export declare function clearAllSessions(): Promise<void>;
10
21
  //# sourceMappingURL=session-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AA4CD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAGrF;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CAe7B;AAED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnE"}
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AA6FD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAyBxB;AAsLD,4EAA4E;AAC5E,wBAAgB,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC,CAE3D;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAanG;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAExG;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAgC7B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3E;AAED,gFAAgF;AAChF,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatG;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQhD"}
@@ -1,84 +1,489 @@
1
- import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
- import { randomUUID } from "node:crypto";
3
- import { join } from "node:path";
1
+ import { chmod, lstat, mkdir, open, readFile, rename, unlink, writeFile } from "node:fs/promises";
2
+ import { createHash, randomUUID } from "node:crypto";
3
+ import { realpathSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
4
5
  import { resolveStateDir } from "./state-dir.js";
5
6
  import { QoderSessionError } from "./errors.js";
6
7
  import { debug, describeError } from "./logger.js";
7
8
  const STATE_DIR = resolveStateDir();
8
9
  const STATE_FILE = join(STATE_DIR, "sessions.json");
10
+ const LOCK_FILE = join(STATE_DIR, "sessions.lock");
11
+ const RESET_FILE = join(STATE_DIR, "sessions.reset");
12
+ const MAX_STATE_BYTES = 1_000_000;
13
+ const MAX_RESET_BYTES = 128;
14
+ const LOCK_STALE_MS = 120_000;
15
+ const LOCK_ATTEMPTS = 80;
16
+ const SESSION_LEASE_STALE_MS = 2 * 60 * 1000;
17
+ const SESSION_LEASE_HEARTBEAT_MS = 30_000;
18
+ const SESSION_LEASE_ATTEMPTS = 4_320_000;
9
19
  const UNSAFE_KEYS = new Set(["__proto__", "prototype", "constructor"]);
20
+ const SCOPED_SEPARATOR = "\u0000";
21
+ const SCOPED_HASH = /^[a-f0-9]{64}$/;
22
+ function emptyState() {
23
+ return Object.create(null);
24
+ }
25
+ let queue = Promise.resolve();
26
+ const sessionLeaseQueues = new Map();
27
+ function withLock(fn) {
28
+ const result = queue.then(fn, fn);
29
+ queue = result.then(() => { }, () => { });
30
+ return result;
31
+ }
32
+ function waitForPrevious(previous, signal) {
33
+ if (!signal)
34
+ return previous.then(() => true, () => true);
35
+ if (signal.aborted)
36
+ return Promise.resolve(false);
37
+ return new Promise((resolveResult) => {
38
+ let settled = false;
39
+ const finish = (ready) => {
40
+ if (settled)
41
+ return;
42
+ settled = true;
43
+ signal.removeEventListener("abort", onAbort);
44
+ resolveResult(ready);
45
+ };
46
+ const onAbort = () => finish(false);
47
+ signal.addEventListener("abort", onAbort, { once: true });
48
+ previous.then(() => finish(true), () => finish(true));
49
+ if (signal.aborted)
50
+ finish(false);
51
+ });
52
+ }
53
+ async function withLeaseFile(lockPath, signal, fn) {
54
+ await mkdir(STATE_DIR, { recursive: true, mode: 0o700 });
55
+ try {
56
+ await chmod(STATE_DIR, 0o700);
57
+ }
58
+ catch { /* best-effort */ }
59
+ let handle;
60
+ for (let attempt = 0; attempt < SESSION_LEASE_ATTEMPTS; attempt++) {
61
+ if (signal?.aborted)
62
+ return undefined;
63
+ try {
64
+ handle = await open(lockPath, "wx", 0o600);
65
+ break;
66
+ }
67
+ catch (error) {
68
+ if (error?.code !== "EEXIST")
69
+ throw error;
70
+ try {
71
+ const info = await lstat(lockPath);
72
+ if (info.isSymbolicLink())
73
+ throw new QoderSessionError("Invalid Qoder session lease");
74
+ if (Date.now() - info.mtimeMs > SESSION_LEASE_STALE_MS)
75
+ await unlink(lockPath);
76
+ }
77
+ catch (lockError) {
78
+ if (lockError instanceof QoderSessionError)
79
+ throw lockError;
80
+ }
81
+ await new Promise((resolveDelay) => setTimeout(resolveDelay, 25));
82
+ }
83
+ }
84
+ if (!handle)
85
+ throw new QoderSessionError("Could not acquire the Qoder session lease");
86
+ // Keep an active lease fresh so a long-running turn does not look like a
87
+ // crashed process. The inode check in finally prevents an old owner from
88
+ // unlinking a replacement lock if stale recovery had to take over.
89
+ try {
90
+ await handle.writeFile(randomUUID(), "utf8");
91
+ }
92
+ catch { /* lock ownership is still represented by the open file */ }
93
+ const heartbeat = setInterval(() => {
94
+ void handle?.utimes(new Date(), new Date()).catch(() => undefined);
95
+ }, SESSION_LEASE_HEARTBEAT_MS);
96
+ if (typeof heartbeat.unref === "function")
97
+ heartbeat.unref();
98
+ try {
99
+ return await fn();
100
+ }
101
+ finally {
102
+ clearInterval(heartbeat);
103
+ let ownsLock = false;
104
+ try {
105
+ const [pathInfo, handleInfo] = await Promise.all([lstat(lockPath), handle.stat()]);
106
+ ownsLock = pathInfo.dev === handleInfo.dev && pathInfo.ino === handleInfo.ino;
107
+ }
108
+ catch { /* lock was already replaced or removed */ }
109
+ try {
110
+ await handle.close();
111
+ }
112
+ catch { /* best-effort */ }
113
+ if (ownsLock) {
114
+ try {
115
+ await unlink(lockPath);
116
+ }
117
+ catch { /* best-effort */ }
118
+ }
119
+ }
120
+ }
121
+ function leasePath(key, cwd) {
122
+ const digest = createHash("sha256").update(`${normalizedCwd(cwd)}\u0000${key}`).digest("hex");
123
+ return join(STATE_DIR, `.session-${digest}.lock`);
124
+ }
125
+ /**
126
+ * Serialize a persisted/explicit Qoder session across both threads and OS
127
+ * processes. The lease covers the SDK turn, not just the JSON mapping write.
128
+ */
129
+ export function withQoderSessionLease(key, cwd, signal, fn) {
130
+ if (!validKey(key))
131
+ return Promise.reject(new QoderSessionError("Invalid Qoder session lease key"));
132
+ const localKey = `${normalizedCwd(cwd)}\u0000${key}`;
133
+ const previous = sessionLeaseQueues.get(localKey) ?? Promise.resolve();
134
+ let release;
135
+ const current = new Promise((resolveRelease) => { release = resolveRelease; });
136
+ sessionLeaseQueues.set(localKey, current);
137
+ const releaseAndClean = () => {
138
+ release();
139
+ if (sessionLeaseQueues.get(localKey) === current)
140
+ sessionLeaseQueues.delete(localKey);
141
+ };
142
+ return waitForPrevious(previous, signal).then(async (acquired) => {
143
+ if (!acquired) {
144
+ void previous.then(releaseAndClean, releaseAndClean);
145
+ return undefined;
146
+ }
147
+ try {
148
+ if (signal?.aborted)
149
+ return undefined;
150
+ return await withLeaseFile(leasePath(key, cwd), signal, fn);
151
+ }
152
+ finally {
153
+ releaseAndClean();
154
+ }
155
+ });
156
+ }
157
+ async function withFileLock(fn) {
158
+ await mkdir(STATE_DIR, { recursive: true, mode: 0o700 });
159
+ try {
160
+ await chmod(STATE_DIR, 0o700);
161
+ }
162
+ catch { /* best-effort */ }
163
+ let handle;
164
+ for (let attempt = 0; attempt < LOCK_ATTEMPTS; attempt++) {
165
+ try {
166
+ handle = await open(LOCK_FILE, "wx", 0o600);
167
+ break;
168
+ }
169
+ catch (error) {
170
+ if (error?.code !== "EEXIST")
171
+ throw error;
172
+ try {
173
+ const info = await lstat(LOCK_FILE);
174
+ if (info.isSymbolicLink())
175
+ throw new QoderSessionError("Invalid Qoder session lock");
176
+ if (Date.now() - info.mtimeMs > LOCK_STALE_MS)
177
+ await unlink(LOCK_FILE);
178
+ }
179
+ catch (lockError) {
180
+ if (lockError instanceof QoderSessionError)
181
+ throw lockError;
182
+ }
183
+ await new Promise((resolveDelay) => setTimeout(resolveDelay, 25));
184
+ }
185
+ }
186
+ if (!handle)
187
+ throw new QoderSessionError("Could not acquire the Qoder session store lock");
188
+ try {
189
+ return await fn();
190
+ }
191
+ finally {
192
+ try {
193
+ await handle.close();
194
+ }
195
+ catch { /* best-effort */ }
196
+ try {
197
+ await unlink(LOCK_FILE);
198
+ }
199
+ catch { /* best-effort */ }
200
+ }
201
+ }
10
202
  function validRecord(value) {
11
203
  if (!value || typeof value !== "object" || Array.isArray(value))
12
204
  return false;
13
205
  const record = value;
14
206
  return typeof record.qoderSessionId === "string"
207
+ && record.qoderSessionId.length > 0
208
+ && record.qoderSessionId.length <= 512
15
209
  && typeof record.cwd === "string"
210
+ && record.cwd.length > 0
211
+ && record.cwd.length <= 4096
16
212
  && typeof record.createdAt === "string"
17
213
  && typeof record.lastUsedAt === "string";
18
214
  }
215
+ function validKey(key) {
216
+ return typeof key === "string"
217
+ && key.trim().length > 0
218
+ && key.length <= 512
219
+ && !/[\u0000-\u001f\u007f-\u009f]/.test(key)
220
+ && !UNSAFE_KEYS.has(key);
221
+ }
222
+ function scopedStateKey(key, cwd) {
223
+ return `${key}${SCOPED_SEPARATOR}${createHash("sha256").update(normalizedCwd(cwd)).digest("hex")}`;
224
+ }
225
+ function validStateKey(key) {
226
+ if (validKey(key))
227
+ return true;
228
+ if (typeof key !== "string")
229
+ return false;
230
+ const separator = key.indexOf(SCOPED_SEPARATOR);
231
+ return separator > 0
232
+ && validKey(key.slice(0, separator))
233
+ && SCOPED_HASH.test(key.slice(separator + SCOPED_SEPARATOR.length));
234
+ }
235
+ function scopedKeys(state, key) {
236
+ const prefix = `${key}${SCOPED_SEPARATOR}`;
237
+ return Object.keys(state).filter((stateKey) => stateKey.startsWith(prefix) && validStateKey(stateKey));
238
+ }
239
+ function recordForCwd(state, key, cwd) {
240
+ const targetCwd = normalizedCwd(cwd);
241
+ const scopedKey = scopedStateKey(key, targetCwd);
242
+ const scoped = Object.hasOwn(state, scopedKey) ? state[scopedKey] : undefined;
243
+ if (scoped && normalizedCwd(scoped.cwd) === targetCwd)
244
+ return { stateKey: scopedKey, record: scoped };
245
+ // Read the pre-workspace-scoping format for migration/compatibility. It is
246
+ // only eligible when its stored cwd matches the requested workspace.
247
+ const legacy = Object.hasOwn(state, key) ? state[key] : undefined;
248
+ if (legacy && normalizedCwd(legacy.cwd) === targetCwd)
249
+ return { stateKey: key, record: legacy };
250
+ return null;
251
+ }
252
+ function normalizedCwd(cwd) {
253
+ try {
254
+ const resolved = resolve(cwd);
255
+ try {
256
+ return realpathSync(resolved);
257
+ }
258
+ catch {
259
+ return resolved;
260
+ }
261
+ }
262
+ catch {
263
+ return cwd;
264
+ }
265
+ }
19
266
  async function load() {
267
+ try {
268
+ const info = await lstat(STATE_FILE);
269
+ if (!info.isFile() || info.isSymbolicLink() || info.size > MAX_STATE_BYTES) {
270
+ return { state: emptyState(), writable: false };
271
+ }
272
+ }
273
+ catch (error) {
274
+ const code = error?.code;
275
+ if (code === "ENOENT")
276
+ return { state: emptyState(), writable: true };
277
+ debug("Session store stat failed:", describeError(error));
278
+ return { state: emptyState(), writable: false };
279
+ }
20
280
  let raw;
21
281
  try {
22
282
  raw = await readFile(STATE_FILE, "utf8");
23
283
  }
24
284
  catch (error) {
25
285
  const code = error?.code;
26
- if (code !== "ENOENT")
27
- debug("Session store unreadable:", describeError(error));
28
- return {};
286
+ if (code === "ENOENT")
287
+ return { state: emptyState(), writable: true };
288
+ debug("Session store unreadable:", describeError(error));
289
+ return { state: emptyState(), writable: false };
29
290
  }
30
291
  try {
292
+ if (Buffer.byteLength(raw, "utf8") > MAX_STATE_BYTES)
293
+ return { state: emptyState(), writable: false };
31
294
  const parsed = JSON.parse(raw);
32
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
33
- return {};
34
- const state = {};
295
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
296
+ return { state: emptyState(), writable: false };
297
+ }
298
+ const state = emptyState();
299
+ let valid = true;
35
300
  for (const [key, value] of Object.entries(parsed)) {
36
- if (!UNSAFE_KEYS.has(key) && validRecord(value))
301
+ if (validStateKey(key) && validRecord(value))
37
302
  state[key] = value;
303
+ else
304
+ valid = false;
38
305
  }
39
- return state;
306
+ // Keep usable entries available for reads, but never rewrite a file that
307
+ // contains an entry we could not validate; doing so would silently delete
308
+ // data added by a newer bridge version or a partially corrupted write.
309
+ return { state, writable: valid };
40
310
  }
41
311
  catch (error) {
42
312
  debug("Session store held invalid JSON; starting empty:", describeError(error));
43
- return {};
313
+ return { state: emptyState(), writable: false };
44
314
  }
45
315
  }
46
316
  async function save(state) {
47
- await mkdir(STATE_DIR, { recursive: true, mode: 0o700 });
48
- const temporary = join(STATE_DIR, `.sessions.${process.pid}.${randomUUID()}.tmp`);
49
- await writeFile(temporary, JSON.stringify(state, null, 2) + "\n", { mode: 0o600 });
50
- await chmod(temporary, 0o600);
51
- await rename(temporary, STATE_FILE);
317
+ let temporary;
318
+ try {
319
+ await mkdir(STATE_DIR, { recursive: true, mode: 0o700 });
320
+ try {
321
+ await chmod(STATE_DIR, 0o700);
322
+ }
323
+ catch { /* best-effort */ }
324
+ temporary = join(STATE_DIR, `.sessions.${process.pid}.${randomUUID()}.tmp`);
325
+ await writeFile(temporary, JSON.stringify(state, null, 2) + "\n", { mode: 0o600 });
326
+ try {
327
+ await chmod(temporary, 0o600);
328
+ }
329
+ catch { /* best-effort */ }
330
+ await rename(temporary, STATE_FILE);
331
+ temporary = undefined;
332
+ }
333
+ finally {
334
+ if (temporary) {
335
+ try {
336
+ await unlink(temporary);
337
+ }
338
+ catch { /* best-effort */ }
339
+ }
340
+ }
341
+ }
342
+ async function readResetEpoch() {
343
+ try {
344
+ const info = await lstat(RESET_FILE);
345
+ if (!info.isFile() || info.isSymbolicLink() || info.size > MAX_RESET_BYTES)
346
+ return "invalid";
347
+ return (await readFile(RESET_FILE, "utf8")).trim().slice(0, MAX_RESET_BYTES);
348
+ }
349
+ catch (error) {
350
+ if (error?.code === "ENOENT")
351
+ return "";
352
+ debug("Session reset marker unreadable:", describeError(error));
353
+ return "invalid";
354
+ }
52
355
  }
53
- export async function getQoderSession(key) {
54
- if (!key || UNSAFE_KEYS.has(key))
356
+ async function writeResetEpoch(epoch) {
357
+ let temporary;
358
+ try {
359
+ await mkdir(STATE_DIR, { recursive: true, mode: 0o700 });
360
+ try {
361
+ await chmod(STATE_DIR, 0o700);
362
+ }
363
+ catch { /* best-effort */ }
364
+ temporary = join(STATE_DIR, `.sessions-reset.${process.pid}.${randomUUID()}.tmp`);
365
+ await writeFile(temporary, `${epoch}\n`, { mode: 0o600 });
366
+ try {
367
+ await chmod(temporary, 0o600);
368
+ }
369
+ catch { /* best-effort */ }
370
+ await rename(temporary, RESET_FILE);
371
+ temporary = undefined;
372
+ }
373
+ finally {
374
+ if (temporary) {
375
+ try {
376
+ await unlink(temporary);
377
+ }
378
+ catch { /* best-effort */ }
379
+ }
380
+ }
381
+ }
382
+ /** Read the generation used to fence reset-all against in-flight writes. */
383
+ export function getQoderSessionResetEpoch() {
384
+ return readResetEpoch();
385
+ }
386
+ export async function getQoderSession(key, cwd) {
387
+ if (!validKey(key))
55
388
  return null;
56
- return (await load())[key] ?? null;
57
- }
58
- export async function ensureQoderSession(key, qoderSessionId, cwd) {
59
- if (!key || UNSAFE_KEYS.has(key))
60
- throw new QoderSessionError("Invalid Qoder session key");
61
- const state = await load();
62
- const now = new Date().toISOString();
63
- const existing = state[key];
64
- const record = existing ?? {
65
- qoderSessionId,
66
- cwd,
67
- createdAt: now,
68
- lastUsedAt: now,
69
- };
70
- record.lastUsedAt = now;
71
- state[key] = record;
72
- await save(state);
73
- return record;
74
- }
75
- export async function deleteQoderSession(key) {
76
- if (!key || UNSAFE_KEYS.has(key))
77
- return;
78
- const state = await load();
79
- if (!(key in state))
80
- return;
81
- delete state[key];
82
- await save(state);
389
+ return withLock(() => withFileLock(async () => {
390
+ const { state } = await load();
391
+ if (cwd)
392
+ return recordForCwd(state, key, cwd)?.record ?? null;
393
+ const legacy = Object.hasOwn(state, key) ? state[key] : undefined;
394
+ if (legacy)
395
+ return legacy;
396
+ const matches = scopedKeys(state, key).map((stateKey) => state[stateKey]);
397
+ // The legacy API has no workspace argument. Returning an unambiguous
398
+ // scoped record keeps old callers working without selecting another
399
+ // workspace's session when a key is reused.
400
+ return matches.length === 1 ? matches[0] : null;
401
+ }));
402
+ }
403
+ export async function getQoderSessionForCwd(key, cwd) {
404
+ return getQoderSession(key, cwd);
405
+ }
406
+ export function ensureQoderSession(key, qoderSessionId, cwd, expectedResetEpoch) {
407
+ if (!validKey(key) || typeof qoderSessionId !== "string" || !qoderSessionId || qoderSessionId.length > 512
408
+ || typeof cwd !== "string" || !cwd || cwd.length > 4096) {
409
+ return Promise.reject(new QoderSessionError("Invalid Qoder session key or session record"));
410
+ }
411
+ return withLock(() => withFileLock(async () => {
412
+ const loaded = await load();
413
+ if (!loaded.writable) {
414
+ throw new QoderSessionError("Qoder session state is invalid or unreadable; refusing to overwrite it");
415
+ }
416
+ if (expectedResetEpoch === "invalid" || (expectedResetEpoch !== undefined && await readResetEpoch() !== expectedResetEpoch)) {
417
+ throw new QoderSessionError("Qoder session reset superseded this request; refusing to recreate the mapping");
418
+ }
419
+ const state = loaded.state;
420
+ const now = new Date().toISOString();
421
+ const targetCwd = normalizedCwd(cwd);
422
+ const targetKey = scopedStateKey(key, targetCwd);
423
+ const existingMapping = recordForCwd(state, key, targetCwd);
424
+ const existing = existingMapping?.record;
425
+ const record = existing ?? {
426
+ qoderSessionId,
427
+ cwd: targetCwd,
428
+ createdAt: now,
429
+ lastUsedAt: now,
430
+ };
431
+ record.cwd = targetCwd;
432
+ record.lastUsedAt = now;
433
+ if (existingMapping?.stateKey === key)
434
+ delete state[key];
435
+ state[targetKey] = record;
436
+ await save(state);
437
+ return record;
438
+ }));
439
+ }
440
+ export function deleteQoderSession(key, cwd) {
441
+ if (!validKey(key))
442
+ return Promise.resolve();
443
+ return withLock(() => withFileLock(async () => {
444
+ const loaded = await load();
445
+ if (!loaded.writable) {
446
+ throw new QoderSessionError("Qoder session state is invalid or unreadable; refusing to overwrite it");
447
+ }
448
+ const state = loaded.state;
449
+ if (cwd) {
450
+ const mapping = recordForCwd(state, key, cwd);
451
+ if (mapping)
452
+ delete state[mapping.stateKey];
453
+ await save(state);
454
+ return;
455
+ }
456
+ delete state[key];
457
+ for (const stateKey of scopedKeys(state, key))
458
+ delete state[stateKey];
459
+ await save(state);
460
+ }));
461
+ }
462
+ /** Delete a mapping after waiting for any active turn in the same workspace. */
463
+ export async function deleteQoderSessionForCwd(key, cwd, leaseKey = key) {
464
+ const abortController = new AbortController();
465
+ const waitTimer = setTimeout(() => abortController.abort(), 10_000);
466
+ if (typeof waitTimer.unref === "function")
467
+ waitTimer.unref();
468
+ try {
469
+ const completed = await withQoderSessionLease(leaseKey, cwd, abortController.signal, async () => {
470
+ await deleteQoderSession(key, cwd);
471
+ return true;
472
+ });
473
+ if (completed !== true)
474
+ throw new QoderSessionError("Could not reset the Qoder session while it was active");
475
+ }
476
+ finally {
477
+ clearTimeout(waitTimer);
478
+ }
479
+ }
480
+ export function clearAllSessions() {
481
+ return withLock(() => withFileLock(async () => {
482
+ // Advance the fence before replacing the mapping. Requests that started
483
+ // under the previous epoch will be refused by ensureQoderSession even if
484
+ // they finish after this reset.
485
+ await writeResetEpoch(randomUUID());
486
+ await save(emptyState());
487
+ }));
83
488
  }
84
489
  //# sourceMappingURL=session-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"state-dir.d.ts","sourceRoot":"","sources":["../src/state-dir.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAK5E"}
1
+ {"version":3,"file":"state-dir.d.ts","sourceRoot":"","sources":["../src/state-dir.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAM5E"}
package/dist/state-dir.js CHANGED
@@ -8,7 +8,8 @@ export function resolveStateDir(env = process.env) {
8
8
  const override = env.QODER_BRIDGE_STATE_DIR?.trim();
9
9
  if (override)
10
10
  return join(override);
11
- const configHome = env.XDG_CONFIG_HOME?.trim();
11
+ const configHome = env.XDG_CONFIG_HOME?.trim()
12
+ || (process.platform === "win32" ? env.APPDATA?.trim() : undefined);
12
13
  return join(configHome || join(homedir(), ".config"), "opencode-qoder-bridge");
13
14
  }
14
15
  //# sourceMappingURL=state-dir.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state-dir.js","sourceRoot":"","sources":["../src/state-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAyB,OAAO,CAAC,GAAG;IAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAC/C,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,uBAAuB,CAAC,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"state-dir.js","sourceRoot":"","sources":["../src/state-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAyB,OAAO,CAAC,GAAG;IAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE;WACzC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,uBAAuB,CAAC,CAAC;AACjF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-normalizer.d.ts","sourceRoot":"","sources":["../src/tool-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuCH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA6B5E;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhF"}
1
+ {"version":3,"file":"tool-normalizer.d.ts","sourceRoot":"","sources":["../src/tool-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgDH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA6B5E;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhF"}