@runeya/runeya 2.0.121 → 2.0.122
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/{agent-manager-4HBMLHXU.js → agent-manager-BSPEFZKZ.js} +3 -3
- package/{chat-VL6BIVO5.js → chat-SE5GIT4B.js} +6 -6
- package/{chunk-HJUFIZ7H.js → chunk-BVBK2WII.js} +128 -158
- package/chunk-BVBK2WII.js.map +1 -0
- package/chunk-GL7WA5K3.js +92 -0
- package/chunk-GL7WA5K3.js.map +1 -0
- package/{chunk-3N55WR7F.js → chunk-NIU3CN5A.js} +7 -16
- package/chunk-NIU3CN5A.js.map +1 -0
- package/{chunk-OVV52N5F.js → chunk-VNLIA5PV.js} +78 -74
- package/chunk-VNLIA5PV.js.map +1 -0
- package/{chunk-CNTL6NVU.js → chunk-XTLQOYLT.js} +118 -58
- package/chunk-XTLQOYLT.js.map +1 -0
- package/{companion-AUMA6RGX.js → companion-HEJHC3UR.js} +4 -4
- package/index.js +3 -3
- package/package.json +1 -1
- package/{settings-manager-ROWQ5GC2.js → settings-manager-4GAINSJO.js} +3 -3
- package/{src-JIS3X4OU.js → src-YUVA6WCM.js} +253 -110
- package/src-YUVA6WCM.js.map +1 -0
- package/chunk-3N55WR7F.js.map +0 -1
- package/chunk-CNTL6NVU.js.map +0 -1
- package/chunk-HJUFIZ7H.js.map +0 -1
- package/chunk-OVV52N5F.js.map +0 -1
- package/chunk-YZU5FNXR.js +0 -43
- package/chunk-YZU5FNXR.js.map +0 -1
- package/src-JIS3X4OU.js.map +0 -1
- /package/{agent-manager-4HBMLHXU.js.map → agent-manager-BSPEFZKZ.js.map} +0 -0
- /package/{chat-VL6BIVO5.js.map → chat-SE5GIT4B.js.map} +0 -0
- /package/{companion-AUMA6RGX.js.map → companion-HEJHC3UR.js.map} +0 -0
- /package/{settings-manager-ROWQ5GC2.js.map → settings-manager-4GAINSJO.js.map} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
atomicWriteSecure,
|
|
2
3
|
fingerprintFiles,
|
|
3
4
|
hasChangedSinceRead,
|
|
4
5
|
rememberFile,
|
|
5
6
|
wasRead
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GL7WA5K3.js";
|
|
7
8
|
import {
|
|
8
9
|
AGENT_FETCH_TIMEOUT,
|
|
9
10
|
AGENT_HEALTH_POLL_INTERVAL,
|
|
@@ -390,7 +391,7 @@ var agentStore = new AgentStore();
|
|
|
390
391
|
|
|
391
392
|
// ../server/src/services/service-store.ts
|
|
392
393
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
393
|
-
import { readFile as readFile3,
|
|
394
|
+
import { readFile as readFile3, rm as rm2 } from "fs/promises";
|
|
394
395
|
import { join as join3 } from "path";
|
|
395
396
|
|
|
396
397
|
// ../server/src/services/project-key.ts
|
|
@@ -501,9 +502,49 @@ function isVaultConflicted(root) {
|
|
|
501
502
|
return conflicted.has(root);
|
|
502
503
|
}
|
|
503
504
|
|
|
505
|
+
// ../server/src/services/store-disk-coordinator.ts
|
|
506
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
507
|
+
var insideReload = new AsyncLocalStorage();
|
|
508
|
+
var StoreDiskCoordinator = class {
|
|
509
|
+
reloading = null;
|
|
510
|
+
saves = 0;
|
|
511
|
+
queue = Promise.resolve();
|
|
512
|
+
/**
|
|
513
|
+
* `read` rend de quoi substituer le nouvel état, ou `null` s'il n'y a rien à
|
|
514
|
+
* relire. La substitution doit être synchrone : c'est ce qui la rend atomique.
|
|
515
|
+
*/
|
|
516
|
+
load(read) {
|
|
517
|
+
const inside = insideReload.getStore();
|
|
518
|
+
if (inside && (inside.has(this) || this.reloading)) return Promise.resolve();
|
|
519
|
+
this.reloading ??= this.reload(read).finally(() => {
|
|
520
|
+
this.reloading = null;
|
|
521
|
+
});
|
|
522
|
+
return this.reloading;
|
|
523
|
+
}
|
|
524
|
+
async reload(read) {
|
|
525
|
+
for (; ; ) {
|
|
526
|
+
await this.queue;
|
|
527
|
+
const savesBefore = this.saves;
|
|
528
|
+
const outer = insideReload.getStore() ?? /* @__PURE__ */ new Set();
|
|
529
|
+
const commit = await insideReload.run(/* @__PURE__ */ new Set([...outer, this]), read);
|
|
530
|
+
if (!commit) return;
|
|
531
|
+
if (this.saves !== savesBefore) continue;
|
|
532
|
+
commit();
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
save(write) {
|
|
537
|
+
this.saves += 1;
|
|
538
|
+
const run = this.queue.then(write);
|
|
539
|
+
this.queue = run.catch(() => {
|
|
540
|
+
});
|
|
541
|
+
return run;
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
504
545
|
// ../server/src/services/environment-store.ts
|
|
505
546
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
506
|
-
import { readFile as readFile2,
|
|
547
|
+
import { readFile as readFile2, rm } from "fs/promises";
|
|
507
548
|
import { join as join2 } from "path";
|
|
508
549
|
|
|
509
550
|
// ../server/src/services/crypto-helpers.ts
|
|
@@ -647,6 +688,7 @@ var EnvironmentStore = class {
|
|
|
647
688
|
* refusée l'est pour toujours et la modification de l'utilisateur se perd.
|
|
648
689
|
*/
|
|
649
690
|
fingerprint = "";
|
|
691
|
+
disk = new StoreDiskCoordinator();
|
|
650
692
|
listeners = /* @__PURE__ */ new Set();
|
|
651
693
|
/** Notified after every persisted mutation, for the cloud sync bridge. */
|
|
652
694
|
onChange(fn) {
|
|
@@ -810,7 +852,7 @@ var EnvironmentStore = class {
|
|
|
810
852
|
}
|
|
811
853
|
return result;
|
|
812
854
|
}
|
|
813
|
-
decryptEnvironment(environment, vault) {
|
|
855
|
+
decryptEnvironment(environment, vault, unreadable = this.unreadableSecrets) {
|
|
814
856
|
let decryptedVars = environment.variables;
|
|
815
857
|
if (environment.variables && Object.keys(environment.variables).length > 0) {
|
|
816
858
|
const failed = /* @__PURE__ */ new Set();
|
|
@@ -820,8 +862,8 @@ var EnvironmentStore = class {
|
|
|
820
862
|
(variableId) => failed.add(variableId),
|
|
821
863
|
vault ?? this.vaultOf(environment)
|
|
822
864
|
);
|
|
823
|
-
if (failed.size > 0)
|
|
824
|
-
else
|
|
865
|
+
if (failed.size > 0) unreadable.set(environment.id, failed);
|
|
866
|
+
else unreadable.delete(environment.id);
|
|
825
867
|
}
|
|
826
868
|
return { ...environment, variables: decryptedVars };
|
|
827
869
|
}
|
|
@@ -837,39 +879,47 @@ var EnvironmentStore = class {
|
|
|
837
879
|
* store reads environments while absorbing a project, which would deadlock).
|
|
838
880
|
*/
|
|
839
881
|
async load() {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
882
|
+
await this.disk.load(async () => {
|
|
883
|
+
const fingerprint = await this.diskFingerprint();
|
|
884
|
+
if (this.loaded && fingerprint === this.fingerprint) return null;
|
|
885
|
+
await ensureProjectsLoaded();
|
|
886
|
+
if (!getEncryptionKey()) return null;
|
|
887
|
+
const next = await this.readVaults();
|
|
888
|
+
return () => {
|
|
889
|
+
this.environments = next.environments;
|
|
890
|
+
this.diskEncryptedSlots = next.diskEncryptedSlots;
|
|
891
|
+
this.roots = next.roots;
|
|
892
|
+
this.unreadableSecrets = next.unreadableSecrets;
|
|
893
|
+
this.fingerprint = fingerprint;
|
|
894
|
+
this.loaded = true;
|
|
895
|
+
};
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
/** Lire tous les coffres dans des tables neuves, que `load` substitue d'un coup. */
|
|
899
|
+
async readVaults() {
|
|
900
|
+
const environments = /* @__PURE__ */ new Map();
|
|
901
|
+
const diskEncryptedSlots = /* @__PURE__ */ new Map();
|
|
902
|
+
const roots = /* @__PURE__ */ new Map();
|
|
903
|
+
const unreadableSecrets = /* @__PURE__ */ new Map();
|
|
904
|
+
for (const root of await allVaultRoots()) {
|
|
855
905
|
try {
|
|
856
906
|
const raw = await readFile2(this.getFilePath(root), "utf-8");
|
|
857
907
|
await rememberFile(this.getFilePath(root));
|
|
858
908
|
const data = JSON.parse(raw);
|
|
859
|
-
const clash = data.find((e) =>
|
|
909
|
+
const clash = data.find((e) => environments.has(e.id) && roots.get(e.id) !== root);
|
|
860
910
|
if (clash) {
|
|
861
911
|
markVaultConflict(root, `environnement ${clash.id}`);
|
|
862
912
|
continue;
|
|
863
913
|
}
|
|
864
914
|
for (const e of data) {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
this.environments.set(e.id, decrypted);
|
|
915
|
+
diskEncryptedSlots.set(e.id, this.extractEncryptedCache(e));
|
|
916
|
+
roots.set(e.id, root);
|
|
917
|
+
environments.set(e.id, this.decryptEnvironment(e, vaultIdOfRoot(root), unreadableSecrets));
|
|
869
918
|
}
|
|
870
919
|
} catch {
|
|
871
920
|
}
|
|
872
921
|
}
|
|
922
|
+
return { environments, diskEncryptedSlots, roots, unreadableSecrets };
|
|
873
923
|
}
|
|
874
924
|
/**
|
|
875
925
|
* Write each vault that holds — or held — an environment.
|
|
@@ -891,7 +941,10 @@ var EnvironmentStore = class {
|
|
|
891
941
|
if (wasRead(path) && await hasChangedSinceRead(path)) this.staleRoots.add(root);
|
|
892
942
|
}
|
|
893
943
|
}
|
|
894
|
-
|
|
944
|
+
save() {
|
|
945
|
+
return this.disk.save(() => this.writeVaults());
|
|
946
|
+
}
|
|
947
|
+
async writeVaults() {
|
|
895
948
|
await this.markStaleRoots();
|
|
896
949
|
const byRoot = /* @__PURE__ */ new Map();
|
|
897
950
|
for (const root of this.roots.values()) {
|
|
@@ -921,11 +974,7 @@ var EnvironmentStore = class {
|
|
|
921
974
|
});
|
|
922
975
|
continue;
|
|
923
976
|
}
|
|
924
|
-
await
|
|
925
|
-
const tmpPath = filePath + ".tmp";
|
|
926
|
-
await writeFile2(tmpPath, JSON.stringify(environments, null, 2), "utf-8");
|
|
927
|
-
await rename2(tmpPath, filePath);
|
|
928
|
-
await chmod2(filePath, 384);
|
|
977
|
+
await atomicWriteSecure(filePath, JSON.stringify(environments, null, 2));
|
|
929
978
|
await rememberFile(filePath);
|
|
930
979
|
}
|
|
931
980
|
this.fingerprint = await this.diskFingerprint();
|
|
@@ -1273,6 +1322,7 @@ var ServiceStore = class {
|
|
|
1273
1322
|
* pour toutes ne verrait jamais les services créés par l'autre.
|
|
1274
1323
|
*/
|
|
1275
1324
|
fingerprint = "";
|
|
1325
|
+
disk = new StoreDiskCoordinator();
|
|
1276
1326
|
listeners = /* @__PURE__ */ new Set();
|
|
1277
1327
|
/**
|
|
1278
1328
|
* Last on-disk (encrypted) form per service id, so `prepareForDisk` can reuse
|
|
@@ -1344,20 +1394,30 @@ var ServiceStore = class {
|
|
|
1344
1394
|
*/
|
|
1345
1395
|
async load() {
|
|
1346
1396
|
if (!getEncryptionKey()) return;
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1397
|
+
await this.disk.load(async () => {
|
|
1398
|
+
const fingerprint = await this.diskFingerprint();
|
|
1399
|
+
if (this.loaded && fingerprint === this.fingerprint) return null;
|
|
1400
|
+
await ensureProjectsLoaded();
|
|
1401
|
+
const next = await this.readVaults();
|
|
1402
|
+
return () => {
|
|
1403
|
+
this.services = next.services;
|
|
1404
|
+
this.diskForm = next.diskForm;
|
|
1405
|
+
this.roots = next.roots;
|
|
1406
|
+
this.fingerprint = fingerprint;
|
|
1407
|
+
this.loaded = true;
|
|
1408
|
+
if (this.services.size > 0) this.notify();
|
|
1409
|
+
};
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
async readVaults() {
|
|
1413
|
+
const services = /* @__PURE__ */ new Map();
|
|
1414
|
+
const diskForm = /* @__PURE__ */ new Map();
|
|
1415
|
+
const roots = /* @__PURE__ */ new Map();
|
|
1416
|
+
for (const root of await allVaultRoots()) {
|
|
1357
1417
|
try {
|
|
1358
1418
|
const raw = await readFile3(this.getFilePath(root), "utf-8");
|
|
1359
1419
|
const data = JSON.parse(raw);
|
|
1360
|
-
const clash = data.find((s) =>
|
|
1420
|
+
const clash = data.find((s) => services.has(s.id) && roots.get(s.id) !== root);
|
|
1361
1421
|
if (clash) {
|
|
1362
1422
|
markVaultConflict(root, `service ${clash.id}`);
|
|
1363
1423
|
continue;
|
|
@@ -1368,17 +1428,17 @@ var ServiceStore = class {
|
|
|
1368
1428
|
if (cmd.shell === void 0) cmd.shell = true;
|
|
1369
1429
|
}
|
|
1370
1430
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1431
|
+
diskForm.set(s.id, s);
|
|
1432
|
+
services.set(s.id, {
|
|
1373
1433
|
...s,
|
|
1374
1434
|
logSources: decryptLogSources(s.logSources ?? [], vaultIdOfRoot(root))
|
|
1375
1435
|
});
|
|
1376
|
-
|
|
1436
|
+
roots.set(s.id, root);
|
|
1377
1437
|
}
|
|
1378
1438
|
} catch {
|
|
1379
1439
|
}
|
|
1380
1440
|
}
|
|
1381
|
-
|
|
1441
|
+
return { services, diskForm, roots };
|
|
1382
1442
|
}
|
|
1383
1443
|
/**
|
|
1384
1444
|
* Write each vault that holds — or held — a service.
|
|
@@ -1387,7 +1447,10 @@ var ServiceStore = class {
|
|
|
1387
1447
|
* another vault must not survive in the one it left, and a `[]` left behind
|
|
1388
1448
|
* would keep (or recreate) a `.runeya` in a directory that holds nothing.
|
|
1389
1449
|
*/
|
|
1390
|
-
|
|
1450
|
+
save() {
|
|
1451
|
+
return this.disk.save(() => this.writeVaults());
|
|
1452
|
+
}
|
|
1453
|
+
async writeVaults() {
|
|
1391
1454
|
const byRoot = /* @__PURE__ */ new Map();
|
|
1392
1455
|
for (const root of this.roots.values()) {
|
|
1393
1456
|
if (!isVaultConflicted(root)) byRoot.set(root, []);
|
|
@@ -1410,11 +1473,7 @@ var ServiceStore = class {
|
|
|
1410
1473
|
});
|
|
1411
1474
|
continue;
|
|
1412
1475
|
}
|
|
1413
|
-
await
|
|
1414
|
-
const tmpPath = filePath + ".tmp";
|
|
1415
|
-
await writeFile3(tmpPath, JSON.stringify(services, null, 2), "utf-8");
|
|
1416
|
-
await rename3(tmpPath, filePath);
|
|
1417
|
-
await chmod3(filePath, 384);
|
|
1476
|
+
await atomicWriteSecure(filePath, JSON.stringify(services, null, 2));
|
|
1418
1477
|
}
|
|
1419
1478
|
this.fingerprint = await this.diskFingerprint();
|
|
1420
1479
|
}
|
|
@@ -1627,7 +1686,7 @@ import { dirname as dirname2, join as join5 } from "path";
|
|
|
1627
1686
|
import { fileURLToPath } from "url";
|
|
1628
1687
|
|
|
1629
1688
|
// ../server/src/services/instance-registry.ts
|
|
1630
|
-
import { mkdir as
|
|
1689
|
+
import { mkdir as mkdir2, readdir, readFile as readFile4, writeFile as writeFile2, rm as rm3 } from "fs/promises";
|
|
1631
1690
|
import { readFileSync } from "fs";
|
|
1632
1691
|
import dotenv from "dotenv";
|
|
1633
1692
|
import { spawn } from "child_process";
|
|
@@ -1724,9 +1783,9 @@ function selfRecord() {
|
|
|
1724
1783
|
}
|
|
1725
1784
|
async function registerInstance() {
|
|
1726
1785
|
try {
|
|
1727
|
-
await
|
|
1786
|
+
await mkdir2(registryDir(), { recursive: true });
|
|
1728
1787
|
published = selfRecord();
|
|
1729
|
-
await
|
|
1788
|
+
await writeFile2(fileFor(process.pid), JSON.stringify(published, null, 2));
|
|
1730
1789
|
} catch (err) {
|
|
1731
1790
|
console.log("[instances] Could not register this instance:", err.message);
|
|
1732
1791
|
}
|
|
@@ -1739,7 +1798,7 @@ async function setInstanceAgentPid(agentPid) {
|
|
|
1739
1798
|
if (!published) return;
|
|
1740
1799
|
published = { ...published, agentPid: agentPid ?? void 0 };
|
|
1741
1800
|
try {
|
|
1742
|
-
await
|
|
1801
|
+
await writeFile2(fileFor(process.pid), JSON.stringify(published, null, 2));
|
|
1743
1802
|
} catch {
|
|
1744
1803
|
}
|
|
1745
1804
|
}
|
|
@@ -3011,6 +3070,7 @@ export {
|
|
|
3011
3070
|
decryptVariableSlots,
|
|
3012
3071
|
extractEncryptedVariableSlots,
|
|
3013
3072
|
isEncryptedValue,
|
|
3073
|
+
StoreDiskCoordinator,
|
|
3014
3074
|
projectKey,
|
|
3015
3075
|
AmbiguousProjectError,
|
|
3016
3076
|
registerProjectLoader,
|
|
@@ -3035,4 +3095,4 @@ export {
|
|
|
3035
3095
|
traefikManager,
|
|
3036
3096
|
agentManager
|
|
3037
3097
|
};
|
|
3038
|
-
//# sourceMappingURL=chunk-
|
|
3098
|
+
//# sourceMappingURL=chunk-XTLQOYLT.js.map
|