@runeya/runeya 2.0.140 → 2.0.141

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 (120) hide show
  1. package/agent/index.js.map +1 -1
  2. package/agent-manager-M4NA5YFD.js +11 -0
  3. package/{chat-L7RRHXX5.js → chat-UQIVCG33.js} +9 -7
  4. package/{chunk-G4TOLDZB.js → chunk-36CC5CZK.js} +123 -57
  5. package/chunk-36CC5CZK.js.map +1 -0
  6. package/{chunk-GOMF7NWS.js → chunk-7L6AQUBR.js} +2 -2
  7. package/{chunk-O2KOX4LU.js → chunk-C2BGNVBT.js} +35 -9
  8. package/chunk-C2BGNVBT.js.map +1 -0
  9. package/{chunk-SYCUQDA4.js → chunk-GXE5TLLJ.js} +10 -4
  10. package/chunk-GXE5TLLJ.js.map +1 -0
  11. package/{chunk-QWX6R6AW.js → chunk-H2MAALKN.js} +46 -8
  12. package/chunk-H2MAALKN.js.map +1 -0
  13. package/{chunk-EV3TBM7E.js → chunk-IXO5KIO5.js} +9 -2
  14. package/{chunk-EV3TBM7E.js.map → chunk-IXO5KIO5.js.map} +1 -1
  15. package/{chunk-6HSZPK2W.js → chunk-UR3HL373.js} +3 -3
  16. package/{companion-LQVLEHU7.js → companion-EVCS2HNC.js} +5 -5
  17. package/{desktop-installer-page-OKE4WY5Q.js → desktop-installer-page-6JDSXK2E.js} +226 -33
  18. package/desktop-installer-page-6JDSXK2E.js.map +1 -0
  19. package/{free-port-565NMFIZ.js → free-port-5UNHDWGE.js} +2 -2
  20. package/index.js +70 -22
  21. package/index.js.map +1 -1
  22. package/install-gate-SFHNMBWT.js +60 -0
  23. package/install-gate-SFHNMBWT.js.map +1 -0
  24. package/mcp-server/index.js +84 -10
  25. package/mcp-server/index.js.map +1 -1
  26. package/mcp-server/launch.d.ts +5 -4
  27. package/mcp-server/launch.js.map +1 -1
  28. package/package.json +1 -1
  29. package/settings-manager-32SVMAFN.js +10 -0
  30. package/{src-NVQHFMTQ.js → src-ZSQISY6W.js} +936 -807
  31. package/src-ZSQISY6W.js.map +1 -0
  32. package/{vault-resolver-B5P2OUI5.js → vault-resolver-VK6W5J6W.js} +2 -2
  33. package/web/assets/{AgentScalarChatInterface.vue-Dgobg9wk.js → AgentScalarChatInterface.vue-Df0_SDmK.js} +1 -1
  34. package/web/assets/{AgentTerminalPage-B43nSPSz.js → AgentTerminalPage-BGA_7YUb.js} +1 -1
  35. package/web/assets/{AiChatModals-CVZ5ilmt.js → AiChatModals-CaGj0i1I.js} +1 -1
  36. package/web/assets/{AppLayout-B5yKLUj9.js → AppLayout-CDOSGDLm.js} +1 -1
  37. package/web/assets/{AuditPage-KR5ydSRG.js → AuditPage-BMYSSho1.js} +1 -1
  38. package/web/assets/{CloudAccountPage-RNosmi99.js → CloudAccountPage-DJNbXhOH.js} +1 -1
  39. package/web/assets/{CloudMessagingPage-Dp-FDdoH.js → CloudMessagingPage-JXnnH4aT.js} +1 -1
  40. package/web/assets/{DashboardPage-Bjj11oP_.js → DashboardPage-BjeN6ZQ3.js} +1 -1
  41. package/web/assets/{DirectoryPickerDialog-C28UH35_.js → DirectoryPickerDialog-CNIrtkmh.js} +1 -1
  42. package/web/assets/{EnvironmentForm-Dj2T2DuS.js → EnvironmentForm-DTJsmGg_.js} +1 -1
  43. package/web/assets/{EnvironmentFormPage-B4Bt1bXS.js → EnvironmentFormPage-HNIgKqaJ.js} +1 -1
  44. package/web/assets/{EnvironmentListPage-B_V9mEhR.js → EnvironmentListPage-DRI3aFZw.js} +1 -1
  45. package/web/assets/{KanbanBoardPage-CQLiin5v.js → KanbanBoardPage-DocxhfeF.js} +3 -3
  46. package/web/assets/{KanbanListPage-ChD0Zj0Y.js → KanbanListPage-DR_DYt46.js} +1 -1
  47. package/web/assets/{LaunchProjectPage-ByIfq7ka.js → LaunchProjectPage-Dgtz9dX8.js} +1 -1
  48. package/web/assets/{LaunchServicesPage-BweD0CWu.js → LaunchServicesPage-iM8a_UHk.js} +1 -1
  49. package/web/assets/{LaunchShell-C9jV0DDh.js → LaunchShell-DccCGeLx.js} +1 -1
  50. package/web/assets/{LogViewer-Cv024Meq.js → LogViewer-DOcy8D-m.js} +2 -2
  51. package/web/assets/{OrgKeyPrompt-D95Zm3Tl.js → OrgKeyPrompt-Dx95YhKV.js} +1 -1
  52. package/web/assets/{ProcessControls-84xtt8ud.js → ProcessControls-BUMbz3Cc.js} +1 -1
  53. package/web/assets/{ProcessDetailPage-CqMk8XQv.js → ProcessDetailPage-DKVRY4sj.js} +1 -1
  54. package/web/assets/{ProjectCreateDialog-C4rLTHw0.js → ProjectCreateDialog-CdYIXATf.js} +1 -1
  55. package/web/assets/{ProjectLocationGate-BtI0T-GU.js → ProjectLocationGate-BpKnR1WI.js} +1 -1
  56. package/web/assets/{ProjectPublishDialog-v5xz8t4N.js → ProjectPublishDialog-BTZXEmZh.js} +1 -1
  57. package/web/assets/{RandomJobTestPage-CzT3LSMu.js → RandomJobTestPage-BLR9jVah.js} +1 -1
  58. package/web/assets/ScenarioEditorPage-ebK_glPw.js +14 -0
  59. package/web/assets/{SendToChatDialog-BtsCq9hv.js → SendToChatDialog-VwH8FOP7.js} +1 -1
  60. package/web/assets/{ServiceControlsBar-BFemdioZ.js → ServiceControlsBar-3dlgA6Sg.js} +1 -1
  61. package/web/assets/{ServiceDetailPage-DsGHPdUc.js → ServiceDetailPage-C9MWIf-1.js} +1 -1
  62. package/web/assets/{ServiceFormPage-x3jtyV1A.js → ServiceFormPage-DIJMr_Ij.js} +1 -1
  63. package/web/assets/{SettingsPage-3tVWDaUN.js → SettingsPage-4bd7gsHf.js} +6 -6
  64. package/web/assets/{UnlockPage-CPcll-ov.js → UnlockPage-F37odjgM.js} +1 -1
  65. package/web/assets/{VaultMigrationPage-BMS4BcsA.js → VaultMigrationPage-CT6EFAXK.js} +1 -1
  66. package/web/assets/VersionBadge-4MjBn5ih.js +1 -0
  67. package/web/assets/VersionBadge-CtFji3sv.css +1 -0
  68. package/web/assets/{WikiPage-CM1-hJvF.js → WikiPage-Dhil7fWU.js} +1 -1
  69. package/web/assets/{WikiView-MQLuO7ey.js → WikiView-Ca2kGbvZ.js} +1 -1
  70. package/web/assets/{add-scalar-classes-BDJ0Zhvc.js → add-scalar-classes-ny-bwITc.js} +2 -2
  71. package/web/assets/{agent.store-CEmOZ8XE.js → agent.store-BBUsxY3E.js} +1 -1
  72. package/web/assets/auth-DgcowXmP.js +2 -0
  73. package/web/assets/{cloud-chat.store-DhCEhagv.js → cloud-chat.store-BT0ikifC.js} +1 -1
  74. package/web/assets/{cloud-client-CmrptmtM.js → cloud-client-7eaj_DyS.js} +2 -2
  75. package/web/assets/cloud-session-BI06sY79.js +2 -0
  76. package/web/assets/{editor.store-Be5P5Eur.js → editor.store-uLBvEAgM.js} +1 -1
  77. package/web/assets/index-CZJJuyAp.css +1 -0
  78. package/web/assets/{index-CXnyET_X.js → index-c8l1Vzb5.js} +101 -101
  79. package/web/assets/{modal-9BC14oRF.js → modal-CNk5Pd2V.js} +1 -1
  80. package/web/assets/{project-launch.store-cO8Wr508.js → project-launch.store-C0TgNDYm.js} +1 -1
  81. package/web/assets/{project.store-CpUEwUgF.js → project.store-Dx530iqh.js} +1 -1
  82. package/web/assets/{scenario.store-B5uv1DSO.js → scenario.store-DWezewHe.js} +1 -1
  83. package/web/assets/{service.store-ve_P4_2O.js → service.store-CgzQ1QCL.js} +1 -1
  84. package/web/assets/{settings-scope-CcYu-GYo.js → settings-scope-54SF-1Hf.js} +1 -1
  85. package/web/assets/{settings.store-CdCOUAsL.js → settings.store-Cz6g0qH2.js} +1 -1
  86. package/web/assets/{src-RO7PD0gR.js → src-BbRuct-7.js} +1 -1
  87. package/web/assets/{src-T5uKA02c.js → src-gyxHZ5yB.js} +1 -1
  88. package/web/assets/{theme-CPaZfI9r.js → theme-BZCAxfJD.js} +1 -1
  89. package/web/assets/trpc-PGQoddea.js +3 -0
  90. package/web/assets/{useCloudOrg-DaFUgt9j.js → useCloudOrg-DePshxqA.js} +1 -1
  91. package/web/assets/{useEnvVarAutocomplete-CXlyG01r.js → useEnvVarAutocomplete-lyIwYncA.js} +1 -1
  92. package/web/assets/{useProjectCatalog-1vLcCQlh.js → useProjectCatalog-BFmo-l75.js} +1 -1
  93. package/web/assets/{useProjectCloudOrg-MAfohLuM.js → useProjectCloudOrg-DN7UK1So.js} +1 -1
  94. package/web/assets/{useServiceUrlHost-D9k9s21s.js → useServiceUrlHost-D31YSsBc.js} +1 -1
  95. package/web/assets/{vue-draggable-plus-SmOauPHy.js → vue-draggable-plus-DE0HToYu.js} +1 -1
  96. package/web/favicon.svg +1 -5
  97. package/web/index.html +17 -17
  98. package/agent-manager-RZI65MSV.js +0 -11
  99. package/chunk-G4TOLDZB.js.map +0 -1
  100. package/chunk-O2KOX4LU.js.map +0 -1
  101. package/chunk-QWX6R6AW.js.map +0 -1
  102. package/chunk-SYCUQDA4.js.map +0 -1
  103. package/desktop-installer-page-OKE4WY5Q.js.map +0 -1
  104. package/settings-manager-5JHSSKQ2.js +0 -10
  105. package/src-NVQHFMTQ.js.map +0 -1
  106. package/web/assets/ScenarioEditorPage-DrWcVOHg.js +0 -14
  107. package/web/assets/VersionBadge-54viPqlY.css +0 -1
  108. package/web/assets/VersionBadge-prnLNUGg.js +0 -1
  109. package/web/assets/auth-BpxI0N26.js +0 -2
  110. package/web/assets/cloud-session-ByODsQrA.js +0 -2
  111. package/web/assets/index-Dsh11_J0.css +0 -1
  112. package/web/assets/trpc-BFA-mSM8.js +0 -3
  113. /package/{agent-manager-RZI65MSV.js.map → agent-manager-M4NA5YFD.js.map} +0 -0
  114. /package/{chat-L7RRHXX5.js.map → chat-UQIVCG33.js.map} +0 -0
  115. /package/{chunk-GOMF7NWS.js.map → chunk-7L6AQUBR.js.map} +0 -0
  116. /package/{chunk-6HSZPK2W.js.map → chunk-UR3HL373.js.map} +0 -0
  117. /package/{companion-LQVLEHU7.js.map → companion-EVCS2HNC.js.map} +0 -0
  118. /package/{free-port-565NMFIZ.js.map → free-port-5UNHDWGE.js.map} +0 -0
  119. /package/{settings-manager-5JHSSKQ2.js.map → settings-manager-32SVMAFN.js.map} +0 -0
  120. /package/{vault-resolver-B5P2OUI5.js.map → vault-resolver-VK6W5J6W.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  machineRoot
3
- } from "./chunk-EV3TBM7E.js";
3
+ } from "./chunk-IXO5KIO5.js";
4
4
 
5
5
  // ../server/src/services/disk-freshness.ts
6
6
  import { stat } from "fs/promises";
@@ -130,4 +130,4 @@ export {
130
130
  atomicWriteJsonSecure,
131
131
  readJsonFileSafe
132
132
  };
133
- //# sourceMappingURL=chunk-GOMF7NWS.js.map
133
+ //# sourceMappingURL=chunk-7L6AQUBR.js.map
@@ -1,23 +1,48 @@
1
1
  // src/free-port.ts
2
- import { createServer } from "net";
2
+ import { connect, createServer } from "net";
3
3
  import { randomInt } from "crypto";
4
4
  var MIN_PORT = 1e4;
5
5
  var MAX_PORT = 3e4;
6
- function tryBind(port, host) {
6
+ function bind(port, host) {
7
7
  return new Promise((resolve) => {
8
8
  const server = createServer();
9
- server.once("error", () => resolve(null));
9
+ server.once("error", (err) => resolve(err.code ?? "EUNKNOWN"));
10
10
  server.listen(port, host, () => resolve(server));
11
11
  });
12
12
  }
13
+ async function tryBind(port, host) {
14
+ const result = await bind(port, host);
15
+ return typeof result === "string" ? null : result;
16
+ }
17
+ var ALL_HOSTS = ["127.0.0.1", "0.0.0.0", "::"];
18
+ var NO_SUCH_ADDRESS = /* @__PURE__ */ new Set(["EAFNOSUPPORT", "EADDRNOTAVAIL"]);
13
19
  function close(server) {
14
20
  return new Promise((resolve) => server.close(() => resolve()));
15
21
  }
16
- async function isPortFree(port, host = "127.0.0.1") {
17
- const server = await tryBind(port, host);
18
- if (!server) return false;
19
- await close(server);
20
- return true;
22
+ function answers(port, host) {
23
+ return new Promise((resolve) => {
24
+ const socket = connect({ port, host });
25
+ const done = (value) => {
26
+ socket.destroy();
27
+ resolve(value);
28
+ };
29
+ socket.setTimeout(500, () => done(false));
30
+ socket.once("connect", () => done(true));
31
+ socket.once("error", () => done(false));
32
+ });
33
+ }
34
+ async function isPortFree(port, host) {
35
+ for (const h of host ? [host] : ALL_HOSTS) {
36
+ const result = await bind(port, h);
37
+ if (typeof result === "string") {
38
+ if (!host && h === "::" && NO_SUCH_ADDRESS.has(result)) continue;
39
+ return false;
40
+ }
41
+ await close(result);
42
+ }
43
+ if (host) return true;
44
+ const [v4, v6] = await Promise.all([answers(port, "127.0.0.1"), answers(port, "::1")]);
45
+ return !v4 && !v6;
21
46
  }
22
47
  async function findFreePortPair({ host = "127.0.0.1", attempts = 200 } = {}) {
23
48
  for (let i = 0; i < attempts; i++) {
@@ -30,6 +55,7 @@ async function findFreePortPair({ host = "127.0.0.1", attempts = 200 } = {}) {
30
55
  continue;
31
56
  }
32
57
  await Promise.all([close(first), close(second)]);
58
+ if (!await isPortFree(base) || !await isPortFree(base + 1)) continue;
33
59
  return base;
34
60
  }
35
61
  return null;
@@ -63,4 +89,4 @@ export {
63
89
  parsePort,
64
90
  probeRuneya
65
91
  };
66
- //# sourceMappingURL=chunk-O2KOX4LU.js.map
92
+ //# sourceMappingURL=chunk-C2BGNVBT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/free-port.ts"],"sourcesContent":["/**\n * Free-port discovery for desktop launchers.\n *\n * A launcher needs a port it can keep: the whole point of baking one into the\n * shortcut is that clicking it tomorrow lands on the same address. Runeya\n * derives the agent port from the server port (`server + 1`), so a usable\n * suggestion is a *pair* of consecutive free ports, not just one free port.\n */\nimport { connect, createServer, type Server } from 'node:net';\nimport { randomInt } from 'node:crypto';\n\n/**\n * Range the suggestion is drawn from. Deliberately below every platform's\n * ephemeral range (Linux 32768+, macOS and Windows 49152+): a port handed out\n * there could be taken by a transient outbound socket between our check and\n * the next launch.\n */\nconst MIN_PORT = 10_000;\nconst MAX_PORT = 30_000;\n\n/** Le serveur lié, ou le code d'erreur du `listen`. */\nfunction bind(port: number, host: string): Promise<Server | string> {\n return new Promise((resolve) => {\n const server = createServer();\n server.once('error', (err: NodeJS.ErrnoException) => resolve(err.code ?? 'EUNKNOWN'));\n server.listen(port, host, () => resolve(server));\n });\n}\n\nasync function tryBind(port: number, host: string): Promise<Server | null> {\n const result = await bind(port, host);\n return typeof result === 'string' ? null : result;\n}\n\n/**\n * Les adresses où un port peut être pris. En tester une ne suffit pas : sous\n * macOS et Windows, un service lié à `0.0.0.0` n'empêche pas de se lier à\n * `127.0.0.1` sur le même port, et Runeya en mode réseau local écoute sur\n * `0.0.0.0`. Beaucoup de serveurs Node écoutent aussi sur `::` par défaut.\n */\nconst ALL_HOSTS = ['127.0.0.1', '0.0.0.0', '::'];\n\n/** Erreurs qui disent que l'adresse n'existe pas sur cette machine (IPv6 désactivé), pas que le port est pris. */\nconst NO_SUCH_ADDRESS = new Set(['EAFNOSUPPORT', 'EADDRNOTAVAIL']);\n\nfunction close(server: Server): Promise<void> {\n return new Promise((resolve) => server.close(() => resolve()));\n}\n\n/** Un service répond-il sur `host:port` ? Refus, adresse absente ou délai : non. */\nfunction answers(port: number, host: string): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = connect({ port, host });\n const done = (value: boolean) => { socket.destroy(); resolve(value); };\n socket.setTimeout(500, () => done(false));\n socket.once('connect', () => done(true));\n socket.once('error', () => done(false));\n });\n}\n\n/**\n * True when nothing is listening on `port`: on `host` when given, otherwise on\n * any of the loopback, IPv4 wildcard and IPv6 wildcard addresses.\n *\n * Sans `host`, deux contrôles. Se lier au port d'abord ; puis s'y connecter en\n * local, en IPv4 et en IPv6. Le second rattrape ce que le premier laisse passer\n * sous Windows, où un service IPv6 seul n'empêche pas de se lier au même port.\n * Qu'un service réponde suffit : le port est pris, quelle que soit la façon\n * dont le système partage ses adresses.\n */\nexport async function isPortFree(port: number, host?: string): Promise<boolean> {\n for (const h of host ? [host] : ALL_HOSTS) {\n const result = await bind(port, h);\n if (typeof result === 'string') {\n if (!host && h === '::' && NO_SUCH_ADDRESS.has(result)) continue;\n return false;\n }\n await close(result);\n }\n if (host) return true;\n const [v4, v6] = await Promise.all([answers(port, '127.0.0.1'), answers(port, '::1')]);\n return !v4 && !v6;\n}\n\n/**\n * Find a port `p` such that `p` and `p + 1` are both free, and return `p`.\n *\n * Both are held at the same time before either is released: binding one,\n * closing it, then binding the next would leave a window where the first is\n * reclaimed and the pair is not actually a pair.\n *\n * The result is a suggestion, not a reservation — nothing stops another\n * process from taking the port a moment later. That is why the failure path\n * matters more than the check: a launcher that cannot bind now shows the\n * startup report instead of dying silently.\n */\nexport async function findFreePortPair(\n { host = '127.0.0.1', attempts = 200 }: { host?: string; attempts?: number } = {},\n): Promise<number | null> {\n for (let i = 0; i < attempts; i++) {\n // MAX_PORT - 1 so that base + 1 stays inside the range\n const base = randomInt(MIN_PORT, MAX_PORT - 1);\n\n const first = await tryBind(base, host);\n if (!first) continue;\n\n const second = await tryBind(base + 1, host);\n if (!second) {\n await close(first);\n continue;\n }\n\n await Promise.all([close(first), close(second)]);\n // Libres sur `host`, mais peut-être pris sur une autre adresse.\n if (!(await isPortFree(base)) || !(await isPortFree(base + 1))) continue;\n return base;\n }\n return null;\n}\n\n/**\n * Parse a port from user input or a flag. Returns null when unusable.\n *\n * Only plain decimal digits are accepted. `Number()` alone would take \"4e3\"\n * for 4000 and \"0x10\" for 16 — for a port someone typed, those are typos, and\n * silently resolving them to a valid number is worse than refusing them.\n */\nexport function parsePort(raw: string | undefined): number | null {\n if (raw === undefined) return null;\n const trimmed = raw.trim();\n if (!/^\\d+$/.test(trimmed)) return null;\n const port = Number(trimmed);\n if (port < 1 || port > 65_535) return null;\n return port;\n}\n\n/**\n * Ask a port whether a Runeya answers there.\n *\n * `health.check` is public and returns the version, so a positive answer\n * identifies Runeya rather than merely proving the port is taken. That\n * distinction is the whole point: a Runeya already serving the port should be\n * opened, while anything else is a genuine conflict the user must see.\n */\nexport async function probeRuneya(port: number): Promise<{ version: string } | null> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/trpc/health.check`, {\n signal: AbortSignal.timeout(1500),\n });\n if (!res.ok) return null;\n const body = await res.json() as { result?: { data?: { status?: string; version?: string } } };\n const data = body.result?.data;\n if (data?.status !== 'ok') return null;\n return { version: data.version ?? 'unknown' };\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  rememberFile,
6
6
  renameWithRetry,
7
7
  wasRead
8
- } from "./chunk-GOMF7NWS.js";
8
+ } from "./chunk-7L6AQUBR.js";
9
9
  import {
10
10
  AGENT_FETCH_TIMEOUT,
11
11
  AGENT_HEALTH_POLL_INTERVAL,
@@ -29,7 +29,7 @@ import {
29
29
  projectVaultRoot,
30
30
  vaultFor,
31
31
  vaultIdOfRoot
32
- } from "./chunk-EV3TBM7E.js";
32
+ } from "./chunk-IXO5KIO5.js";
33
33
  import {
34
34
  decryptValueWith,
35
35
  encryptValueWith
@@ -972,7 +972,13 @@ var EnvironmentStore = class {
972
972
  });
973
973
  continue;
974
974
  }
975
- await atomicWriteSecure(filePath, JSON.stringify(environments, null, 2));
975
+ try {
976
+ await atomicWriteSecure(filePath, JSON.stringify(environments, null, 2));
977
+ } catch (err) {
978
+ if (err.code !== "ENOENT") throw err;
979
+ console.warn(`[environment-store] ${filePath} a disparu pendant l'\xE9criture (projet supprim\xE9 ?) \u2014 coffre ignor\xE9.`);
980
+ continue;
981
+ }
976
982
  await rememberFile(filePath);
977
983
  }
978
984
  this.fingerprint = await this.diskFingerprint();
@@ -3112,4 +3118,4 @@ export {
3112
3118
  traefikManager,
3113
3119
  agentManager
3114
3120
  };
3115
- //# sourceMappingURL=chunk-SYCUQDA4.js.map
3121
+ //# sourceMappingURL=chunk-GXE5TLLJ.js.map