@runeya/runeya 2.0.126 → 2.0.127

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,10 +1,10 @@
1
1
  import {
2
2
  agentManager
3
- } from "./chunk-WLZQDWJT.js";
4
- import "./chunk-HK5QNU6P.js";
3
+ } from "./chunk-WQWRTPPJ.js";
4
+ import "./chunk-BDQOBEZ3.js";
5
5
  import "./chunk-TTPL2M74.js";
6
6
  import "./chunk-ZFELQG4B.js";
7
7
  export {
8
8
  agentManager
9
9
  };
10
- //# sourceMappingURL=agent-manager-QLXVQ7OD.js.map
10
+ //# sourceMappingURL=agent-manager-FN6M6CLD.js.map
@@ -3,13 +3,13 @@ import {
3
3
  startClaudeCodeSession,
4
4
  startCliSession,
5
5
  startCodexSession
6
- } from "./chunk-2EDVDRKV.js";
6
+ } from "./chunk-LHVTBWM7.js";
7
7
  import "./chunk-B7MABGQN.js";
8
- import "./chunk-SG2ACPOE.js";
8
+ import "./chunk-UKLNK5YA.js";
9
9
  import "./chunk-MD3VW4HQ.js";
10
- import "./chunk-WLZQDWJT.js";
11
- import "./chunk-K7A3Q62R.js";
12
- import "./chunk-HK5QNU6P.js";
10
+ import "./chunk-WQWRTPPJ.js";
11
+ import "./chunk-QPII36FL.js";
12
+ import "./chunk-BDQOBEZ3.js";
13
13
  import "./chunk-TTPL2M74.js";
14
14
  import "./chunk-ZFELQG4B.js";
15
15
  export {
@@ -18,4 +18,4 @@ export {
18
18
  startCliSession,
19
19
  startCodexSession
20
20
  };
21
- //# sourceMappingURL=chat-ODBVFMKX.js.map
21
+ //# sourceMappingURL=chat-VCHK77CW.js.map
@@ -54,12 +54,27 @@ function resolveConversationRunDir(rootDirName, conversationId) {
54
54
  }
55
55
  return dir;
56
56
  }
57
+ var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
58
+ var RENAME_RETRY_BUDGET_MS = 2e3;
59
+ async function renameWithRetry(from, to) {
60
+ const deadline = Date.now() + RENAME_RETRY_BUDGET_MS;
61
+ for (let delay = 10; ; delay = Math.min(delay * 2, 200)) {
62
+ try {
63
+ await rename(from, to);
64
+ return;
65
+ } catch (err) {
66
+ const code = err.code;
67
+ if (!code || !TRANSIENT_RENAME_CODES.has(code) || Date.now() + delay > deadline) throw err;
68
+ await new Promise((r) => setTimeout(r, delay));
69
+ }
70
+ }
71
+ }
57
72
  async function atomicWriteSecure(filePath, content) {
58
73
  await mkdir(dirname(filePath), { recursive: true });
59
74
  const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
60
75
  try {
61
76
  await writeFile(tmpPath, content, typeof content === "string" ? "utf-8" : void 0);
62
- await rename(tmpPath, filePath);
77
+ await renameWithRetry(tmpPath, filePath);
63
78
  } catch (err) {
64
79
  await rm(tmpPath, { force: true }).catch(() => {
65
80
  });
@@ -109,9 +124,10 @@ export {
109
124
  wasRead,
110
125
  fingerprintFiles,
111
126
  resolveConversationRunDir,
127
+ renameWithRetry,
112
128
  atomicWriteSecure,
113
129
  sweepStaleTempFiles,
114
130
  atomicWriteJsonSecure,
115
131
  readJsonFileSafe
116
132
  };
117
- //# sourceMappingURL=chunk-HK5QNU6P.js.map
133
+ //# sourceMappingURL=chunk-BDQOBEZ3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../server/src/services/disk-freshness.ts","../../server/src/services/run-store-utils.ts"],"sourcesContent":["import { stat } from 'node:fs/promises';\n\n/**\n * Le fichier a-t-il changé depuis qu'on l'a lu ?\n *\n * Les stores gardent de côté ce qu'ils n'ont pas su déchiffrer, pour le\n * réécrire tel quel plutôt que de l'effacer. Cette copie est la bonne réponse\n * tant que personne d'autre ne touche au fichier — et la mauvaise dès que\n * quelqu'un le répare par-dessous : la copie, elle, ne se périme jamais, et la\n * sauvegarde suivante réinstalle l'état d'avant la réparation.\n *\n * C'est arrivé deux fois de suite sur le même coffre : une conversion de clé\n * menée sur le disque, défaite quelques minutes plus tard par un store qui\n * tenait encore l'ancien chiffré en mémoire.\n *\n * D'où ce repère : l'empreinte du fichier au moment de la lecture. Si elle a\n * bougé, la copie mémoire ne fait plus foi et doit être abandonnée.\n */\n\ninterface Fingerprint {\n mtimeMs: number;\n size: number;\n /**\n * L'inode du chemin, qui change à chaque `rename` par-dessus.\n *\n * La date et la taille laissent passer le motif d'écriture de tout le dépôt :\n * les stores réécrivent le fichier entier, donc une modification rend souvent\n * le même nombre d'octets, et deux instances qui réagissent au même événement\n * écrivent dans la même milliseconde. Le fichier temporaire renommé\n * par-dessus, lui, installe toujours un autre inode.\n *\n * Là où le système n'en expose pas (il rend alors 0), le repère retombe sur\n * la date et la taille — ce qu'il valait avant.\n */\n ino: number;\n}\n\nconst seen = new Map<string, Fingerprint>();\n\n/** Retenir l'état d'un fichier au moment où on vient de le lire. */\nexport async function rememberFile(path: string): Promise<void> {\n try {\n const s = await stat(path);\n seen.set(path, { mtimeMs: s.mtimeMs, size: s.size, ino: s.ino });\n } catch {\n // Pas encore de fichier : rien à retenir, et rien à réémettre non plus.\n seen.delete(path);\n }\n}\n\n/**\n * Vrai si le fichier a changé — ou si l'on ne sait pas.\n *\n * L'ignorance compte comme un changement : réécrire une copie dont on ne peut\n * plus prouver qu'elle correspond au disque est précisément le geste à éviter.\n */\nexport async function hasChangedSinceRead(path: string): Promise<boolean> {\n const known = seen.get(path);\n if (!known) return true;\n try {\n const s = await stat(path);\n return s.mtimeMs !== known.mtimeMs || s.size !== known.size || s.ino !== known.ino;\n } catch {\n return true;\n }\n}\n\n/**\n * A-t-on lu ce fichier ?\n *\n * `hasChangedSinceRead` tient l'ignorance pour un changement : c'est juste\n * quand il s'agit de décider si une copie mémoire fait encore foi. Ça ne l'est\n * pas pour décider d'écrire — un fichier jamais lu est le cas d'un coffre neuf,\n * et le traiter comme « modifié sous nos pieds » revenait à ne jamais écrire la\n * première fois. Les appelants qui protègent une écriture demandent donc les\n * deux : connu, et inchangé.\n */\nexport function wasRead(path: string): boolean {\n return seen.has(path);\n}\n\n/** Oublier un fichier — après un rechargement complet, par exemple. */\nexport function forgetFile(path: string): void {\n seen.delete(path);\n}\n\n/**\n * L'empreinte d'un ensemble de fichiers : lesquels, et dans quel état.\n *\n * Le repère ci-dessus répond pour un fichier qu'on a lu soi-même ; celui-ci\n * répond pour un store dont le contenu vient de plusieurs fichiers à la fois —\n * un par coffre — et dont la question est « le disque a-t-il bougé depuis mon\n * dernier chargement ? ». Comparer deux empreintes coûte quelques `stat` ;\n * recharger coûte autant de lectures, d'analyses et de déchiffrements.\n *\n * L'absence d'un fichier en fait partie : un coffre disparu change l'empreinte\n * autant qu'un coffre modifié.\n */\nexport async function fingerprintFiles(paths: string[]): Promise<string> {\n const stamps = await Promise.all(paths.map(async (path) => {\n try {\n const s = await stat(path);\n // L'inode en fait partie pour la raison décrite sur `Fingerprint` : un\n // fichier renommé par-dessus la cible peut n'avoir bougé ni en taille ni\n // en date, et reste pourtant un autre contenu.\n return `${path}:${s.mtimeMs}:${s.size}:${s.ino}`;\n } catch {\n return `${path}:-`;\n }\n }));\n return stamps.sort().join('|');\n}\n","import { randomUUID } from 'node:crypto';\nimport { chmod, mkdir, readdir, rename, rm, stat, writeFile, readFile } from 'node:fs/promises';\nimport { dirname, join, resolve, sep } from 'node:path';\nimport { machineRoot } from './vault-resolver.js';\n\nconst SAFE_PATH_SEGMENT_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;\n\nexport function resolveConversationRunDir(rootDirName: string, conversationId: string): string {\n if (!SAFE_PATH_SEGMENT_RE.test(conversationId)) {\n throw new Error('Invalid conversationId');\n }\n // Machine-wide, like the conversations these runs belong to: using the launch\n // directory would put a `.runeya` in a repository just for asking the AI a\n // question about a cloud project.\n const base = resolve(machineRoot(), rootDirName);\n const dir = resolve(base, conversationId);\n if (!dir.startsWith(base + sep)) {\n throw new Error('Invalid conversationId');\n }\n return dir;\n}\n\n/** Codes que Windows renvoie tant qu'un autre descripteur tient la cible ouverte. */\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EACCES', 'EBUSY']);\nconst RENAME_RETRY_BUDGET_MS = 2000;\n\n/**\n * Sous Windows, remplacer un fichier qu'un lecteur concurrent, un antivirus ou\n * l'indexeur tient ouvert échoue quelques millisecondes. Réessayer avec un recul\n * croissant, borné : au-delà, le refus est réel et remonte.\n */\nexport async function renameWithRetry(from: string, to: string): Promise<void> {\n const deadline = Date.now() + RENAME_RETRY_BUDGET_MS;\n for (let delay = 10; ; delay = Math.min(delay * 2, 200)) {\n try {\n await rename(from, to);\n return;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || Date.now() + delay > deadline) throw err;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n}\n\nexport async function atomicWriteSecure(filePath: string, content: string | Uint8Array): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n // Un nom par écriture : deux Runeya d'un même poste écrivent les mêmes\n // fichiers, et un `.tmp` commun se fait renommer sous le nez de l'autre.\n const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await writeFile(tmpPath, content, typeof content === 'string' ? 'utf-8' : undefined);\n await renameWithRetry(tmpPath, filePath);\n } catch (err) {\n // Un nom unique ne se réécrit jamais : laissé là, chaque échec en ajouterait un.\n await rm(tmpPath, { force: true }).catch(() => {});\n throw err;\n }\n await chmod(filePath, 0o600);\n}\n\n/** Le nom qu'`atomicWriteSecure` donne à ses fichiers temporaires : `<fichier>.<pid>.<uuid>.tmp`. */\nconst OWN_TEMP_RE = /\\.\\d+\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\.tmp$/;\nconst STALE_TEMP_MS = 3600_000;\n\n/**\n * Retirer les fichiers temporaires qu'un arrêt brutal a laissés.\n *\n * Un nom par écriture ne se réécrit jamais : chaque arrêt en pleine écriture en\n * laissait un pour toujours. Seuls les nôtres sont concernés, et seulement\n * passé une heure — un plus récent peut appartenir à une écriture en cours,\n * celle d'une autre Runeya du même poste.\n */\nexport async function sweepStaleTempFiles(dirs: string[]): Promise<number> {\n let removed = 0;\n const limit = Date.now() - STALE_TEMP_MS;\n for (const dir of dirs) {\n let names: string[];\n try {\n names = await readdir(dir);\n } catch {\n continue;\n }\n for (const name of names.filter((n) => OWN_TEMP_RE.test(n))) {\n const path = join(dir, name);\n try {\n if ((await stat(path)).mtimeMs > limit) continue;\n await rm(path, { force: true });\n removed += 1;\n } catch {\n // Disparu entre-temps : rien à retirer.\n }\n }\n }\n return removed;\n}\n\nexport async function atomicWriteJsonSecure(filePath: string, data: unknown, pretty = false): Promise<void> {\n await atomicWriteSecure(filePath, JSON.stringify(data, null, pretty ? 2 : 0));\n}\n\nexport async function readJsonFileSafe<T>(filePath: string): Promise<T | null> {\n try {\n const raw = await readFile(filePath, 'utf-8');\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":["stat","stat"]}
@@ -31,7 +31,7 @@ import {
31
31
  runCompanionNow,
32
32
  syncConversationFromClaudeTranscript,
33
33
  verifyJwt
34
- } from "./chunk-SG2ACPOE.js";
34
+ } from "./chunk-UKLNK5YA.js";
35
35
  import {
36
36
  StoreDiskCoordinator,
37
37
  agentManager,
@@ -50,10 +50,10 @@ import {
50
50
  recordLocalRemoval,
51
51
  refsOfProjectId,
52
52
  serviceStore
53
- } from "./chunk-WLZQDWJT.js";
53
+ } from "./chunk-WQWRTPPJ.js";
54
54
  import {
55
55
  settingsManager
56
- } from "./chunk-K7A3Q62R.js";
56
+ } from "./chunk-QPII36FL.js";
57
57
  import {
58
58
  atomicWriteJsonSecure,
59
59
  atomicWriteSecure,
@@ -61,9 +61,10 @@ import {
61
61
  hasChangedSinceRead,
62
62
  readJsonFileSafe,
63
63
  rememberFile,
64
+ renameWithRetry,
64
65
  resolveConversationRunDir,
65
66
  wasRead
66
- } from "./chunk-HK5QNU6P.js";
67
+ } from "./chunk-BDQOBEZ3.js";
67
68
  import {
68
69
  AGENT_STOP_FETCH_TIMEOUT,
69
70
  ApiKeysFileSchema,
@@ -642,7 +643,7 @@ async function resolveConversationCwd(conversationId) {
642
643
  }
643
644
 
644
645
  // ../server/src/services/environment-overrides-store.ts
645
- import { readFile as readFile2, writeFile, rename, mkdir, chmod } from "fs/promises";
646
+ import { readFile as readFile2, writeFile, mkdir, chmod } from "fs/promises";
646
647
  import { dirname as dirname2, join as join4 } from "path";
647
648
  var FILENAME = "environment-overrides.json";
648
649
  var EnvironmentOverridesStore = class {
@@ -757,7 +758,7 @@ var EnvironmentOverridesStore = class {
757
758
  const path = join4(root, FILENAME);
758
759
  const tmpPath = path + ".tmp";
759
760
  await writeFile(tmpPath, JSON.stringify(encrypted, null, 2), "utf-8");
760
- await rename(tmpPath, path);
761
+ await renameWithRetry(tmpPath, path);
761
762
  await chmod(path, 384);
762
763
  }
763
764
  }
@@ -2517,7 +2518,7 @@ import { z as z6 } from "zod";
2517
2518
  import { TRPCError as TRPCError2 } from "@trpc/server";
2518
2519
 
2519
2520
  // ../server/src/services/audit-service.ts
2520
- import { appendFile, readFile as readFile3, stat, rename as rename2, unlink, readdir as readdir2, mkdir as mkdir2 } from "fs/promises";
2521
+ import { appendFile, readFile as readFile3, stat, rename, unlink, readdir as readdir2, mkdir as mkdir2 } from "fs/promises";
2521
2522
  var AUDIT_FILENAME = "audit.log";
2522
2523
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
2523
2524
  var MAX_AGE_DAYS = 30;
@@ -2583,7 +2584,7 @@ var AuditService = class {
2583
2584
  try {
2584
2585
  const stats = await stat(filepath);
2585
2586
  if (stats.size > MAX_FILE_SIZE) {
2586
- await rename2(filepath, this.getRotatedPath());
2587
+ await rename(filepath, this.getRotatedPath());
2587
2588
  }
2588
2589
  } catch {
2589
2590
  }
@@ -4163,7 +4164,7 @@ import { basename } from "path";
4163
4164
  import { TRPCError as TRPCError3 } from "@trpc/server";
4164
4165
 
4165
4166
  // ../server/src/services/cloud-session-store.ts
4166
- import { readFile as readFile6, writeFile as writeFile3, rename as rename3, mkdir as mkdir5, chmod as chmod2, unlink as unlink3 } from "fs/promises";
4167
+ import { readFile as readFile6, writeFile as writeFile3, mkdir as mkdir5, chmod as chmod2, unlink as unlink3 } from "fs/promises";
4167
4168
  import { dirname as dirname3 } from "path";
4168
4169
  import { randomBytes as randomBytes2, createHash, timingSafeEqual as timingSafeEqual2 } from "crypto";
4169
4170
  var FILENAME2 = "cloud-session.json";
@@ -4275,7 +4276,7 @@ var CloudSessionStore = class {
4275
4276
  const payload = { version: 2, accounts: this.accounts };
4276
4277
  const tmpPath = filePath + ".tmp";
4277
4278
  await writeFile3(tmpPath, JSON.stringify(payload, null, 2), "utf-8");
4278
- await rename3(tmpPath, filePath);
4279
+ await renameWithRetry(tmpPath, filePath);
4279
4280
  await chmod2(filePath, 384);
4280
4281
  }
4281
4282
  /**
@@ -4412,7 +4413,7 @@ var cloudSessionStore = new CloudSessionStore();
4412
4413
 
4413
4414
  // ../server/src/services/lan-mode.ts
4414
4415
  import { networkInterfaces } from "os";
4415
- import { readFile as readFile7, writeFile as writeFile4, rename as rename4, mkdir as mkdir6 } from "fs/promises";
4416
+ import { readFile as readFile7, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
4416
4417
  import { join as join7 } from "path";
4417
4418
  import { z as z7 } from "zod";
4418
4419
  var LOOPBACK2 = "127.0.0.1";
@@ -4447,7 +4448,7 @@ async function writePersisted(lanEnabled) {
4447
4448
  const filePath = networkFilePath();
4448
4449
  const tmpPath = filePath + ".tmp";
4449
4450
  await writeFile4(tmpPath, JSON.stringify(state, null, 2), "utf-8");
4450
- await rename4(tmpPath, filePath);
4451
+ await renameWithRetry(tmpPath, filePath);
4451
4452
  }
4452
4453
  function registerHttpServer(server) {
4453
4454
  httpServer = server;
@@ -5604,7 +5605,7 @@ function tailTranscript(opts) {
5604
5605
 
5605
5606
  // ../server/src/services/ai-runners/claude-pty-runner.ts
5606
5607
  async function getAgentManager() {
5607
- const { agentManager: agentManager2 } = await import("./agent-manager-QLXVQ7OD.js");
5608
+ const { agentManager: agentManager2 } = await import("./agent-manager-FN6M6CLD.js");
5608
5609
  return agentManager2;
5609
5610
  }
5610
5611
  function buildPtyArgs(params, sessionId, opts) {
@@ -6296,7 +6297,7 @@ async function shutdownCodexAppServer() {
6296
6297
  }
6297
6298
  }
6298
6299
  async function getAgentManager2() {
6299
- const { agentManager: agentManager2 } = await import("./agent-manager-QLXVQ7OD.js");
6300
+ const { agentManager: agentManager2 } = await import("./agent-manager-FN6M6CLD.js");
6300
6301
  return agentManager2;
6301
6302
  }
6302
6303
  function parseRuneyaCurlCommand(command) {
@@ -8342,4 +8343,4 @@ export {
8342
8343
  startCliSession,
8343
8344
  chatRouter
8344
8345
  };
8345
- //# sourceMappingURL=chunk-2EDVDRKV.js.map
8346
+ //# sourceMappingURL=chunk-LHVTBWM7.js.map