rovloom 0.5.0 → 0.6.1

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 (64) hide show
  1. package/README.md +9 -1
  2. package/dist/src/admin/index.js +1 -1
  3. package/dist/src/{chunk-emcefrc1.js → chunk-0e9gg4sg.js} +3 -4
  4. package/dist/src/chunk-1xer1ent.js +102 -0
  5. package/dist/src/{chunk-863tk45b.js → chunk-41fny9qm.js} +5 -5
  6. package/dist/src/{chunk-zjzrcc59.js → chunk-59h200cr.js} +139 -7
  7. package/dist/src/chunk-5w5srj3b.js +93 -0
  8. package/dist/src/{chunk-d4ejrtjq.js → chunk-6n6b1xpy.js} +1 -1
  9. package/dist/src/{chunk-ympzv86c.js → chunk-6w4g9fw8.js} +16 -4
  10. package/dist/src/{chunk-smpevv7n.js → chunk-73aq2qkz.js} +9 -16
  11. package/dist/src/{chunk-0ake7e4r.js → chunk-8c9yc0ge.js} +9 -17
  12. package/dist/src/{chunk-57ayxqnb.js → chunk-8fy8w7ds.js} +2 -23
  13. package/dist/src/{chunk-64ftwe9b.js → chunk-8ykrqhxh.js} +8 -2
  14. package/dist/src/{chunk-2tn0r64b.js → chunk-9h9x79bx.js} +5 -5
  15. package/dist/src/{chunk-nyn75b8v.js → chunk-av31bx1e.js} +31 -2
  16. package/dist/src/{chunk-0xgpxdgc.js → chunk-bbdtsg4b.js} +7 -5
  17. package/dist/src/{chunk-q5pgbwb3.js → chunk-e7jgpxkf.js} +2 -2
  18. package/dist/src/{chunk-zj48jvfe.js → chunk-efty77sb.js} +3 -40
  19. package/dist/src/{chunk-abd4envz.js → chunk-enj7s8cv.js} +71 -78
  20. package/dist/src/{chunk-4etdq0cp.js → chunk-ftpy8xx3.js} +313 -28
  21. package/dist/src/{chunk-zdxww7ms.js → chunk-h3xyq7zk.js} +1 -1
  22. package/dist/src/{chunk-ttsrctxg.js → chunk-hxmq28pg.js} +9 -7
  23. package/dist/src/{chunk-r0nfthsf.js → chunk-j59ac0xs.js} +2 -2
  24. package/dist/src/{chunk-5s2emvww.js → chunk-j6svdqr8.js} +10 -302
  25. package/dist/src/{chunk-9y36gntb.js → chunk-jkzfck98.js} +10 -5
  26. package/dist/src/{chunk-sj24fpz3.js → chunk-m76cmkfy.js} +28 -30
  27. package/dist/src/{chunk-5n8csngz.js → chunk-m96mbzcw.js} +816 -305
  28. package/dist/src/{chunk-xhq21g24.js → chunk-m9c1pnv9.js} +3 -3
  29. package/dist/src/{chunk-fnakrk0a.js → chunk-n3z3jaxy.js} +39 -36
  30. package/dist/src/{chunk-e7x51y0t.js → chunk-ndj0ay2p.js} +19 -18
  31. package/dist/src/chunk-pgs9jp6t.js +320 -0
  32. package/dist/src/chunk-pksaqt9a.js +25 -0
  33. package/dist/src/{chunk-ebm3kvnq.js → chunk-pnep7yhj.js} +31 -100
  34. package/dist/src/chunk-qn5xae7g.js +66 -0
  35. package/dist/src/{chunk-0pewfj89.js → chunk-qp8tgms2.js} +1 -1
  36. package/dist/src/{chunk-7k9g0x5e.js → chunk-rmgw8h27.js} +10 -8
  37. package/dist/src/{chunk-gbsbwssz.js → chunk-sf4ztxba.js} +3 -3
  38. package/dist/src/{chunk-7q96e161.js → chunk-shez7hkc.js} +6 -12
  39. package/dist/src/chunk-sqz614bh.js +30 -0
  40. package/dist/src/{chunk-09f9q26d.js → chunk-vdwzb63d.js} +2 -2
  41. package/dist/src/chunk-xtvgm6kf.js +48 -0
  42. package/dist/src/chunk-y8zm75jt.js +157 -0
  43. package/dist/src/chunk-yasqw2vj.js +756 -0
  44. package/dist/src/{chunk-ybte82d3.js → chunk-z0qmfqvd.js} +4 -3
  45. package/dist/src/chunk-zm705snh.js +53 -0
  46. package/dist/src/cli/index.js +39 -30
  47. package/dist/src/cli/main.js +14 -9
  48. package/dist/src/connector/herdr/installation.js +4 -4
  49. package/dist/src/connector/herdr/provider.js +9 -9
  50. package/dist/src/connector/herdr/runtime.js +7 -7
  51. package/dist/src/connector/luvus/index.js +7 -6
  52. package/dist/src/mcp/index.js +16 -14
  53. package/dist/src/runtime/index.js +16 -15
  54. package/dist/src/service/index.js +3 -4
  55. package/dist/src/store.js +4 -4
  56. package/dist/src/transport/index.js +9 -9
  57. package/dist/src/webui/index.js +975 -834
  58. package/package.json +1 -1
  59. package/dist/src/chunk-5j0gj6w2.js +0 -7
  60. package/dist/src/chunk-9yg6x3gt.js +0 -24
  61. package/dist/src/chunk-erdq0rn8.js +0 -1300
  62. package/dist/src/chunk-n073xnr1.js +0 -1117
  63. package/dist/src/chunk-rwpynx2j.js +0 -51
  64. package/dist/src/chunk-vwcntax3.js +0 -228
@@ -3,109 +3,14 @@ import {
3
3
  object2,
4
4
  fields2,
5
5
  id2,
6
- boundedJson2,
7
6
  validatePolicies2
8
7
  } from "./chunk-qt9m2kg2.js";
9
- import {
10
- DEFAULT_PAIRING_POLICY_REF
11
- } from "./chunk-5j0gj6w2.js";
12
- import {
13
- readRuntimeJson
14
- } from "./chunk-z7kkfrgz.js";
15
8
  import {
16
9
  CliError2
17
10
  } from "./chunk-hpzr94hm.js";
18
- import {
19
- privatePath,
20
- readPrivateBytes
21
- } from "./chunk-0y5542k8.js";
22
-
23
- // src/cli/setup-files.ts
24
- import {
25
- closeSync,
26
- fsyncSync,
27
- fchmodSync,
28
- linkSync,
29
- statSync,
30
- openSync,
31
- renameSync,
32
- unlinkSync,
33
- writeFileSync
34
- } from "fs";
35
- import { createHash, randomUUID } from "crypto";
36
- import { dirname, join } from "path";
37
- function setupFileStamp(path) {
38
- const bytes = readPrivateBytes(path, 16777216);
39
- try {
40
- return createHash("sha256").update(bytes).digest("hex");
41
- } finally {
42
- bytes.fill(0);
43
- }
44
- }
45
- function writeSetupFile(path, bytes, replace = false, expectedStamp) {
46
- privatePath(path);
47
- const previous = replace ? expectedStamp ?? setupFileStamp(path) : undefined;
48
- if (replace && setupFileStamp(path) !== previous) {
49
- throw new CliError2("config_changed");
50
- }
51
- const temporary = join(dirname(path), ".rovloom-setup-" + randomUUID() + ".tmp");
52
- let fd;
53
- let created = false;
54
- try {
55
- const mode = replace ? statSync(path).mode & 511 : 384;
56
- fd = openSync(temporary, "wx", mode);
57
- created = true;
58
- if (replace && process.platform !== "win32") {
59
- fchmodSync(fd, mode);
60
- }
61
- writeFileSync(fd, bytes);
62
- fsyncSync(fd);
63
- const complete = fd;
64
- fd = undefined;
65
- closeSync(complete);
66
- if (replace) {
67
- if (setupFileStamp(path) !== previous) {
68
- throw new CliError2("config_changed");
69
- }
70
- renameSync(temporary, path);
71
- } else {
72
- linkSync(temporary, path);
73
- unlinkSync(temporary);
74
- }
75
- created = false;
76
- } catch (error) {
77
- if (error instanceof CliError2) {
78
- throw error;
79
- }
80
- throw new CliError2("config_unreadable");
81
- } finally {
82
- try {
83
- if (fd !== undefined) {
84
- closeSync(fd);
85
- }
86
- } finally {
87
- if (created) {
88
- unlinkSync(temporary);
89
- }
90
- }
91
- }
92
- }
93
- function readSetupJson(path, maximum = 16384) {
94
- try {
95
- return readRuntimeJson(path, maximum);
96
- } catch (error) {
97
- if (error instanceof CliError2 && error.code === "backend_unavailable") {
98
- return;
99
- }
100
- throw error;
101
- }
102
- }
103
- function writeSetupJson(path, value, replace = false, maximum = 16384) {
104
- writeSetupFile(path, boundedJson2(value, maximum), replace);
105
- }
106
11
 
107
12
  // src/cli/token-registry.ts
108
- import { createHash as createHash2, randomBytes } from "crypto";
13
+ import { createHash, randomBytes } from "crypto";
109
14
  var REGISTRY_MAX_BYTES = 262144;
110
15
  var MAX_CALLERS = 64;
111
16
  var DEFAULT_TTL_DAYS = 30;
@@ -113,7 +18,7 @@ var DAY = 86400000;
113
18
  var HEX = /^[a-f0-9]{64}$/;
114
19
  var PRINCIPAL = /^[a-zA-Z0-9_-]{1,128}$/;
115
20
  function digestToken(token) {
116
- return createHash2("sha256").update(token).digest("hex");
21
+ return createHash("sha256").update(token).digest("hex");
117
22
  }
118
23
  function newToken() {
119
24
  return randomBytes(32).toString("base64url");
@@ -133,7 +38,10 @@ function parseRegistry(value, resource) {
133
38
  const digests = new Set;
134
39
  for (const input of source.callers) {
135
40
  const caller = object2(input);
136
- fields2(caller, ["principal", "token_sha256", "issued_at", "expires_at"], ["previous"]);
41
+ fields2(caller, ["principal", "token_sha256", "issued_at", "expires_at"], ["previous", "token", "scope"]);
42
+ if (caller.scope !== undefined && caller.scope !== "gateway" || caller.token !== undefined && (typeof caller.token !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(caller.token) || digestToken(caller.token) !== caller.token_sha256)) {
43
+ invalid();
44
+ }
137
45
  const principal = object2(caller.principal);
138
46
  fields2(principal, ["id", "policy"], ["permissions"]);
139
47
  if (principal.permissions !== undefined) {
@@ -190,7 +98,9 @@ function createCaller(registry, principal, like, now, days) {
190
98
  const expires_at = now + ttl(days);
191
99
  const entry = {
192
100
  principal: { ...structuredClone(template.principal), id: principal },
101
+ ...template.scope ? { scope: template.scope } : {},
193
102
  token_sha256: digestToken(token),
103
+ token,
194
104
  issued_at: now,
195
105
  expires_at
196
106
  };
@@ -223,7 +133,9 @@ function rotateCaller(registry, principal, now, options = {}) {
223
133
  const expires_at = now + ttl(options.days);
224
134
  const entry = {
225
135
  principal: old.principal,
136
+ ...old.scope ? { scope: old.scope } : {},
226
137
  token_sha256: digestToken(token),
138
+ token,
227
139
  issued_at: now,
228
140
  expires_at,
229
141
  ...grace > 0 ? { previous: { token_sha256: old.token_sha256, expires_at: Math.min(now + grace * 60000, old.expires_at) } } : {}
@@ -250,6 +162,25 @@ function summarize(registry, now) {
250
162
  rotating: entry.previous !== undefined && now < entry.previous.expires_at
251
163
  }));
252
164
  }
165
+ function createGatewayCaller(registry, principal, now, days = 365) {
166
+ if (!PRINCIPAL.test(principal) || registry.callers.some((entry) => entry.principal.id === principal) || registry.callers.length >= MAX_CALLERS) {
167
+ throw new CliError2("invalid_arguments");
168
+ }
169
+ const token = newToken();
170
+ const expires_at = now + ttl(days);
171
+ const entry = {
172
+ principal: { id: principal, policy: structuredClone(registry.local_policy) },
173
+ scope: "gateway",
174
+ token,
175
+ token_sha256: digestToken(token),
176
+ issued_at: now,
177
+ expires_at
178
+ };
179
+ return { registry: { ...registry, callers: [...registry.callers, entry] }, token, expires_at };
180
+ }
181
+
182
+ // src/pairing-policy.ts
183
+ var DEFAULT_PAIRING_POLICY_REF = "rovloom_setup_v1";
253
184
 
254
185
  // src/cli/admin-registry.ts
255
186
  var ADMIN_POLICY_REVISION = "rovloom_admin_v1";
@@ -351,6 +282,6 @@ function summarizeAdmins(management, now) {
351
282
  }));
352
283
  }
353
284
 
354
- export { setupFileStamp, writeSetupFile, readSetupJson, writeSetupJson, REGISTRY_MAX_BYTES, parseRegistry, createCaller, setDiscardPermission, renewCaller, rotateCaller, revokeCaller, summarize, DEFAULT_ADMIN_TTL_DAYS, emptyManagement, isAdminPlaceholder, issueAdmin, revokeAdmin, summarizeAdmins };
285
+ export { REGISTRY_MAX_BYTES, digestToken, parseRegistry, createCaller, setDiscardPermission, renewCaller, rotateCaller, revokeCaller, summarize, createGatewayCaller, DEFAULT_ADMIN_TTL_DAYS, emptyManagement, isAdminPlaceholder, issueAdmin, revokeAdmin, summarizeAdmins };
355
286
 
356
- //# debugId=3023B85F5DE2326664756E2164756E21
287
+ //# debugId=96015426A0C339E864756E2164756E21
@@ -0,0 +1,66 @@
1
+ // @bun
2
+ import {
3
+ HERDR_WORKFLOW_METHODS
4
+ } from "./chunk-9tt13dm0.js";
5
+ import {
6
+ LUVUS_OPERATION_METHODS2
7
+ } from "./chunk-efty77sb.js";
8
+ import {
9
+ luvusMode,
10
+ CliError2
11
+ } from "./chunk-hpzr94hm.js";
12
+
13
+ // src/cli/setup-policy.ts
14
+ var SIMPLE_SETUP_ACTOR = "operator_simple_pairing";
15
+ var SIMPLE_SETUP_LINEAGE = "simple";
16
+ function setupSessions(input) {
17
+ if (input === undefined) {
18
+ return Object.freeze({});
19
+ }
20
+ const row = input;
21
+ if (row === null || typeof row !== "object" || Array.isArray(row) || Object.keys(row).some((key) => key !== "luvus") || row.luvus !== undefined && row.luvus !== "default" && row.luvus !== "rovloom") {
22
+ throw new CliError2("configuration_required");
23
+ }
24
+ return Object.freeze(row.luvus === undefined ? {} : { luvus: row.luvus });
25
+ }
26
+ function setupTarget(machine, kind = "luvus", sessions = {}) {
27
+ return {
28
+ machine_id: machine,
29
+ provider_id: kind,
30
+ profile: "session",
31
+ session: kind === "luvus" ? sessions.luvus ?? "rovloom" : "default"
32
+ };
33
+ }
34
+ function setupProviderKinds(input) {
35
+ if (!Array.isArray(input) || input.some((kind) => kind !== "luvus" && kind !== "herdr") || !["luvus", "herdr", "luvus,herdr"].includes(input.join(","))) {
36
+ throw new CliError2("configuration_required");
37
+ }
38
+ return Object.freeze([...input]);
39
+ }
40
+ function selectedSetupPolicies(plan, machine, kinds, sessions = {}) {
41
+ const grants = setupProviderKinds(kinds).map((kind) => ({
42
+ target: setupTarget(machine, kind, sessions),
43
+ methods: [...kind === "luvus" ? LUVUS_OPERATION_METHODS2 : HERDR_WORKFLOW_METHODS],
44
+ actions: ["dispatch", "read", "cancel"]
45
+ }));
46
+ return {
47
+ principal_id: plan.actor,
48
+ policies: {
49
+ caller: { revision: "setup_caller_" + (plan.lineage ?? plan.attempt_id), grants },
50
+ local: { revision: "setup_local_" + (plan.lineage ?? plan.attempt_id), grants: structuredClone(grants) }
51
+ }
52
+ };
53
+ }
54
+ function setupReference(attempt, kind = "luvus") {
55
+ return kind + "_" + attempt;
56
+ }
57
+ function setupSessionsFor(config) {
58
+ return Object.freeze({ luvus: luvusMode(config) === "attach" ? "default" : "rovloom" });
59
+ }
60
+ function simpleSetupAuthorization(machine, kinds, sessions = {}) {
61
+ return selectedSetupPolicies({ attempt_id: SIMPLE_SETUP_LINEAGE, actor: SIMPLE_SETUP_ACTOR, lineage: SIMPLE_SETUP_LINEAGE }, machine, kinds, sessions);
62
+ }
63
+
64
+ export { SIMPLE_SETUP_ACTOR, SIMPLE_SETUP_LINEAGE, setupSessions, setupTarget, setupProviderKinds, selectedSetupPolicies, setupReference, setupSessionsFor, simpleSetupAuthorization };
65
+
66
+ //# debugId=E4B9A88833E96D5764756E2164756E21
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  macosProcessState,
4
4
  windowsProcessState
5
- } from "./chunk-09f9q26d.js";
5
+ } from "./chunk-vdwzb63d.js";
6
6
 
7
7
  // src/storage/process-identity.ts
8
8
  import { connect } from "net";
@@ -22,21 +22,23 @@ import {
22
22
  SERVICE_ERROR_CODES,
23
23
  FacadeServiceError2,
24
24
  NativeRequestNotDispatchedError
25
- } from "./chunk-smpevv7n.js";
25
+ } from "./chunk-73aq2qkz.js";
26
26
  import {
27
- LuvusAdapterError2,
28
27
  terminalExecutionCatalog
29
- } from "./chunk-57ayxqnb.js";
28
+ } from "./chunk-8fy8w7ds.js";
30
29
  import {
31
30
  createLuvusCatalog2
32
- } from "./chunk-0xgpxdgc.js";
33
- import {
34
- NativeRequestPreflightError
35
- } from "./chunk-zj48jvfe.js";
31
+ } from "./chunk-bbdtsg4b.js";
36
32
  import {
37
33
  sampleManagementTransport2,
38
34
  createManagementTransportProjection2
39
35
  } from "./chunk-2tansfxf.js";
36
+ import {
37
+ NativeRequestPreflightError
38
+ } from "./chunk-xtvgm6kf.js";
39
+ import {
40
+ LuvusAdapterError2
41
+ } from "./chunk-pksaqt9a.js";
40
42
 
41
43
  // src/mcp/store-service.ts
42
44
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -989,4 +991,4 @@ class RuntimeGatewayService2 {
989
991
 
990
992
  export { resolveGatewayPrincipal, StoreGatewayService2, RuntimeGatewayService2 };
991
993
 
992
- //# debugId=13A7F49E5E901EE764756E2164756E21
994
+ //# debugId=045A814985626BAA64756E2164756E21
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  windowsInspectPath
4
- } from "./chunk-09f9q26d.js";
4
+ } from "./chunk-vdwzb63d.js";
5
5
  import {
6
6
  id2,
7
7
  boundedJson2,
@@ -10,10 +10,10 @@ import {
10
10
  import {
11
11
  LuvusAdapterError2,
12
12
  ConnectorCapacityError
13
- } from "./chunk-57ayxqnb.js";
13
+ } from "./chunk-pksaqt9a.js";
14
14
  import {
15
15
  currentProcessIdentity
16
- } from "./chunk-0pewfj89.js";
16
+ } from "./chunk-qp8tgms2.js";
17
17
  import {
18
18
  privatePath,
19
19
  privateFile,
@@ -1,4 +1,7 @@
1
1
  // @bun
2
+ import {
3
+ cliMessages2
4
+ } from "./chunk-pgs9jp6t.js";
2
5
  import {
3
6
  isRole,
4
7
  servicePlatform,
@@ -10,15 +13,6 @@ import {
10
13
 
11
14
  // src/service/command.ts
12
15
  var actions = new Set(["install", "uninstall", "start", "restart", "stop"]);
13
- var SERVICE_HELP2 = `service install --role gateway|connector [--executable ABS] [--config ABS] --workdir ABS --user ACCOUNT
14
- service uninstall|start|restart|stop --role gateway|connector
15
- install registers boot startup without starting; uninstall only revokes future boot startup and preserves running instances and their control records.
16
- Omitted --executable uses the current standalone binary; a different binary is rejected.
17
- Omitted --config uses the same current-user role file as foreground startup. Installation fixes its absolute path; background startup does not select another home.
18
- Linux uses systemd system units; macOS uses system LaunchDaemons; Windows uses boot-triggered tasks, not SCM services or login tasks.
19
- Gateway services support Linux systemd, macOS system LaunchDaemons and Windows boot-triggered tasks; the local native Connector service supports Linux x64, Windows x64 and macOS (x64 / arm64).
20
- Windows uses the explicitly selected existing user with S4U, without storing a password or requiring login. It does not provide an interactive desktop or Windows network credentials/EFS access. Running services receive a local shutdown request; queued/start-racing tasks return service_busy without forced termination; uninstall never stops it.
21
- `;
22
16
  function parseServiceCommand2(args, platform, resolveDefaultConfig, executable) {
23
17
  if (args[0] !== "service") {
24
18
  return;
@@ -64,7 +58,7 @@ async function handleServiceCommand2(args, host) {
64
58
  }
65
59
  try {
66
60
  if (args.length === 2 && args[1] === "--help") {
67
- host.diagnostic(SERVICE_HELP2);
61
+ host.diagnostic(cliMessages2(host.language)["help.service"]);
68
62
  return 0;
69
63
  }
70
64
  const request = parseServiceCommand2(args, servicePlatform(host.platform), host.resolveDefaultConfig, host.executable);
@@ -79,6 +73,6 @@ async function handleServiceCommand2(args, host) {
79
73
  }
80
74
  }
81
75
 
82
- export { SERVICE_HELP2, parseServiceCommand2, handleServiceCommand2 };
76
+ export { parseServiceCommand2, handleServiceCommand2 };
83
77
 
84
- //# debugId=48AFF39224DEDE2664756E2164756E21
78
+ //# debugId=D7F60C51F033ABF664756E2164756E21
@@ -0,0 +1,30 @@
1
+ // @bun
2
+ import {
3
+ hasPairingState2,
4
+ retirePairingState2,
5
+ handleConnectorUnpair2
6
+ } from "./chunk-y8zm75jt.js";
7
+ import"./chunk-1xer1ent.js";
8
+ import"./chunk-8ykrqhxh.js";
9
+ import"./chunk-1bf0wmgk.js";
10
+ import"./chunk-z7kkfrgz.js";
11
+ import"./chunk-hpzr94hm.js";
12
+ import"./chunk-pgs9jp6t.js";
13
+ import"./chunk-sf4ztxba.js";
14
+ import"./chunk-3nnahj0j.js";
15
+ import"./chunk-h3xyq7zk.js";
16
+ import"./chunk-qp8tgms2.js";
17
+ import"./chunk-0y5542k8.js";
18
+ import"./chunk-vdwzb63d.js";
19
+ import"./chunk-g7pnjzkk.js";
20
+ import"./chunk-qt9m2kg2.js";
21
+ import"./chunk-9tt13dm0.js";
22
+ import"./chunk-7crhmqn2.js";
23
+ import"./chunk-d71r315c.js";
24
+ export {
25
+ handleConnectorUnpair2 as handleConnectorUnpair,
26
+ hasPairingState2 as hasPairingState,
27
+ retirePairingState2 as retirePairingState
28
+ };
29
+
30
+ //# debugId=4B1FD15DC6D4072D64756E2164756E21
@@ -414,6 +414,6 @@ function windowsProcessState(pid) {
414
414
  }
415
415
  }
416
416
 
417
- export { macosPeer, macosProcessState, macosProcessUid, macosProcessImage, macosProcessArgv, windowsCurrentUserSid, windowsInspectPath, windowsPipeServerPid, windowsProcessFacts, windowsProcessState };
417
+ export { macosPeer, macosProcessState, macosProcessUid, macosProcessImage, macosProcessArgv, windowsInspectPath, windowsPipeServerPid, windowsProcessFacts, windowsProcessState };
418
418
 
419
- //# debugId=24B541853D8128AB64756E2164756E21
419
+ //# debugId=792167EE7EF656EE64756E2164756E21
@@ -0,0 +1,48 @@
1
+ // @bun
2
+ import {
3
+ GatewayError2
4
+ } from "./chunk-d71r315c.js";
5
+ import {
6
+ createNativeValidator2
7
+ } from "./chunk-mqyq5jh6.js";
8
+ import {
9
+ luvusOperationDescriptor2,
10
+ luvusOperationValidation2
11
+ } from "./chunk-efty77sb.js";
12
+
13
+ // src/runtime/request-preflight.ts
14
+ class NativeRequestPreflightError extends GatewayError2 {
15
+ outcome = "not_dispatched";
16
+ constructor() {
17
+ super("native_request_invalid");
18
+ }
19
+ }
20
+ function createLuvusRequestPreflight(contract) {
21
+ const validator = createNativeValidator2(contract);
22
+ return (request) => {
23
+ const checked = validator.checkRequestShape(request);
24
+ if (!checked.ok) {
25
+ if (checked.error.code === "native_request_invalid") {
26
+ throw new NativeRequestPreflightError;
27
+ }
28
+ throw new GatewayError2(checked.error.code);
29
+ }
30
+ };
31
+ }
32
+ function luvusValidation(kind, request, options) {
33
+ if (kind !== "luvus" || !luvusOperationDescriptor2(request.method)) {
34
+ return options;
35
+ }
36
+ const required = luvusOperationValidation2(request.method);
37
+ if (options.validation === undefined) {
38
+ return { ...options, validation: required };
39
+ }
40
+ if (options.validation !== required) {
41
+ throw new NativeRequestPreflightError;
42
+ }
43
+ return options;
44
+ }
45
+
46
+ export { NativeRequestPreflightError, createLuvusRequestPreflight, luvusValidation };
47
+
48
+ //# debugId=B81CED09F0DF168264756E2164756E21
@@ -0,0 +1,157 @@
1
+ // @bun
2
+ import {
3
+ boundedJson2
4
+ } from "./chunk-qt9m2kg2.js";
5
+ import {
6
+ cliMessages2,
7
+ formatMessage2
8
+ } from "./chunk-pgs9jp6t.js";
9
+ import {
10
+ setupFileStamp,
11
+ writeSetupFile
12
+ } from "./chunk-1xer1ent.js";
13
+ import {
14
+ privateDirectory
15
+ } from "./chunk-8ykrqhxh.js";
16
+ import {
17
+ runtimeReference
18
+ } from "./chunk-z7kkfrgz.js";
19
+ import {
20
+ CliError2,
21
+ configDocument2,
22
+ readConfig2
23
+ } from "./chunk-hpzr94hm.js";
24
+ import {
25
+ LUVUS_CLAIMS_LOCK_FORMAT
26
+ } from "./chunk-sf4ztxba.js";
27
+ import {
28
+ recordedProcess,
29
+ ownedFile
30
+ } from "./chunk-h3xyq7zk.js";
31
+ import {
32
+ ownerIsDead
33
+ } from "./chunk-qp8tgms2.js";
34
+ import {
35
+ syncParentDirectory
36
+ } from "./chunk-0y5542k8.js";
37
+
38
+ // src/cli/unpair.ts
39
+ import { existsSync, lstatSync, readFileSync, renameSync } from "fs";
40
+ import { dirname, join } from "path";
41
+ var PAIRING_FILES = ["device", "pairing", "pairing-claim", "providers", "native-setup", "herdr-setup"];
42
+ var PAIRING_DIRECTORIES = ["control", "n", "h", "w", "hr"];
43
+ var CLAIM_LOCKS = ["control/luvus-claims.db.lock", "hr/control/claims.db.lock"];
44
+ function hasPairingState2(directory) {
45
+ return PAIRING_FILES.some((reference) => existsSync(runtimeReference(directory, reference))) || PAIRING_DIRECTORIES.some((name) => existsSync(join(directory, name)));
46
+ }
47
+ function entry(path) {
48
+ try {
49
+ const info = lstatSync(path);
50
+ if (info.isFile()) {
51
+ return "file";
52
+ }
53
+ return info.isDirectory() ? "directory" : undefined;
54
+ } catch (error) {
55
+ if (error.code === "ENOENT") {
56
+ return;
57
+ }
58
+ throw new CliError2("config_unreadable");
59
+ }
60
+ }
61
+ function assertConnectorIdle(stateDir) {
62
+ for (const name of CLAIM_LOCKS) {
63
+ const path = join(stateDir, name);
64
+ if (ownedFile(path) !== true) {
65
+ continue;
66
+ }
67
+ try {
68
+ const bytes = readFileSync(path);
69
+ if (bytes.length === 0 || bytes.length > 1024) {
70
+ continue;
71
+ }
72
+ const recorded = recordedProcess(JSON.parse(bytes.toString("utf8")), LUVUS_CLAIMS_LOCK_FORMAT);
73
+ if (recorded && !ownerIsDead(recorded)) {
74
+ throw new CliError2("configuration_required");
75
+ }
76
+ } catch (error) {
77
+ if (error instanceof CliError2) {
78
+ throw error;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ function retireStamp(stateDir) {
84
+ const base = new Date().toISOString().replace(/[-:]/gu, "").replace(/\.\d+Z$/u, "Z");
85
+ for (let index = 0;; index++) {
86
+ const name = index === 0 ? base : base + "-" + index;
87
+ if (entry(join(stateDir, "retired", name)) === undefined) {
88
+ return name;
89
+ }
90
+ }
91
+ }
92
+ function retirePairingState2(config, console) {
93
+ console.assertOwner();
94
+ assertConnectorIdle(config.state_dir);
95
+ const moves = [];
96
+ const root = join(config.state_dir, "retired", retireStamp(config.state_dir));
97
+ for (const reference of PAIRING_FILES) {
98
+ const source = runtimeReference(config.state_dir, reference);
99
+ if (entry(source) === "file") {
100
+ moves.push({ source, target: join(root, "managed", reference + ".json") });
101
+ }
102
+ }
103
+ for (const name of PAIRING_DIRECTORIES) {
104
+ const source = join(config.state_dir, name);
105
+ if (entry(source) === "directory") {
106
+ moves.push({ source, target: join(root, name) });
107
+ }
108
+ }
109
+ if (moves.length === 0) {
110
+ return;
111
+ }
112
+ try {
113
+ privateDirectory(join(config.state_dir, "retired"));
114
+ privateDirectory(root);
115
+ for (const move of moves) {
116
+ privateDirectory(dirname(move.target));
117
+ renameSync(move.source, move.target);
118
+ syncParentDirectory(move.target);
119
+ syncParentDirectory(move.source);
120
+ }
121
+ } catch (error) {
122
+ throw error instanceof CliError2 ? error : new CliError2("config_unreadable");
123
+ }
124
+ return root;
125
+ }
126
+ async function handleConnectorUnpair2(path, io) {
127
+ const config = readConfig2(path);
128
+ if (config.role !== "connector") {
129
+ throw new CliError2("config_role_mismatch");
130
+ }
131
+ if (io.signal.aborted) {
132
+ return 0;
133
+ }
134
+ const console = {
135
+ io,
136
+ show: (text) => {
137
+ io.stderr.write(text);
138
+ },
139
+ confirm: async () => true,
140
+ assertOwner: () => {}
141
+ };
142
+ const retired = retirePairingState2(config, console);
143
+ privateDirectory(join(config.state_dir, "managed"));
144
+ if (config.gateway_url !== "" || retired !== undefined) {
145
+ if (boundedJson2(configDocument2(readConfig2(path))) !== boundedJson2(configDocument2(config))) {
146
+ throw new CliError2("config_changed");
147
+ }
148
+ writeSetupFile(path, JSON.stringify({ ...configDocument2(config), gateway: { url: "" } }, null, 2) + `
149
+ `, true, setupFileStamp(path));
150
+ }
151
+ io.stderr.write(retired === undefined ? cliMessages2(io.language)["unpair.empty"] : formatMessage2(cliMessages2(io.language)["unpair.completed"], { retired }));
152
+ return 0;
153
+ }
154
+
155
+ export { hasPairingState2, retirePairingState2, handleConnectorUnpair2 };
156
+
157
+ //# debugId=3C1C123FA665D9EE64756E2164756E21