glimmervoid 0.0.0-stage → 0.30.0

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 (59) hide show
  1. package/LICENSE +48 -0
  2. package/README.md +195 -2
  3. package/dist/bin/glimmervoid.js +275 -0
  4. package/dist/chunks/adapters-Dho1VSY5.js +2 -0
  5. package/dist/chunks/adapters-zPDx1Xox.js +575 -0
  6. package/dist/chunks/agent-api-cli-D0MmtEdz.js +71 -0
  7. package/dist/chunks/agent-api-core-Dz0r21y9.js +103 -0
  8. package/dist/chunks/agent-setup-cli-B5Atxr3F.js +139 -0
  9. package/dist/chunks/ascii-figure-core-pDAwtlKO.js +45 -0
  10. package/dist/chunks/child-process-safe-DRGsp0TE.js +69 -0
  11. package/dist/chunks/child-process-safe-DvQjXsgz.js +2 -0
  12. package/dist/chunks/config-path-core-DFt-TemS.js +38 -0
  13. package/dist/chunks/config-store-CC8T3okC.js +2 -0
  14. package/dist/chunks/config-store-mm7MgzoL.js +1412 -0
  15. package/dist/chunks/contracts-DGkKNh9W.js +3020 -0
  16. package/dist/chunks/grok-DuU8xVLZ.js +436 -0
  17. package/dist/chunks/hook-command-core-DclEoE9e.js +14 -0
  18. package/dist/chunks/hook-relay-core-BHfYFnYV.js +88 -0
  19. package/dist/chunks/hook-tools-pSJia7ks.js +74 -0
  20. package/dist/chunks/ingest-core-DWI1Mbu4.js +342 -0
  21. package/dist/chunks/ingest-editor-core-BuI1gMF_.js +445 -0
  22. package/dist/chunks/loopback-post-C7C22eYi.js +79 -0
  23. package/dist/chunks/main-CuIZQPhZ.js +43559 -0
  24. package/dist/chunks/node-pty-preflight-CK1knGIR.js +162 -0
  25. package/dist/chunks/pair-cli-w-gCAF-1.js +110 -0
  26. package/dist/chunks/path-doctor-C23VAqeu.js +63 -0
  27. package/dist/chunks/refocus-core-BKQKllq7.js +38 -0
  28. package/dist/chunks/relay-stdin-CpHvLu6M.js +20 -0
  29. package/dist/chunks/remote-config-C2ytQwrs.js +525 -0
  30. package/dist/chunks/rtk-hook-core-Bl6gYHPN.js +133 -0
  31. package/dist/chunks/rtk-resolver-CLo-gZzw.js +21 -0
  32. package/dist/chunks/rtk-resolver-CMQAidlI.js +2 -0
  33. package/dist/chunks/runtime-paths-Ci_ksSkj.js +75 -0
  34. package/dist/chunks/runtime-paths-JLrZ3wyi.js +2 -0
  35. package/dist/chunks/sandbox-deps-Dd5-kZnf.js +67 -0
  36. package/dist/chunks/session-Cez8aIWg.js +164 -0
  37. package/dist/chunks/spawn-command-Cc40FiZI.js +134 -0
  38. package/dist/chunks/visions-cli-BXQFIBCX.js +98 -0
  39. package/dist/chunks/visions-setup-CvVnOe1r.js +1753 -0
  40. package/dist/client/assets/favicon-CKygeLwW.svg +7 -0
  41. package/dist/client/assets/index-B1MFijjb.css +1 -0
  42. package/dist/client/assets/index-CU1iPPdn.js +249 -0
  43. package/dist/client/index.html +108 -0
  44. package/dist/package.json +3 -0
  45. package/dist/scripts/postinstall-path-check.js +36 -0
  46. package/dist/server/index.js +92 -0
  47. package/dist/session/command-hook-relay.js +16 -0
  48. package/dist/session/hook-relay.js +24 -0
  49. package/dist/session/hook-tool-relay.js +107 -0
  50. package/dist/session/statusline-relay.js +82 -0
  51. package/dist/session/visions-relay.js +627 -0
  52. package/dist/tools/vscode-visions/extension.js +289 -0
  53. package/dist/tools/vscode-visions/lsp-convert.js +80 -0
  54. package/dist/tools/vscode-visions/package.json +32 -0
  55. package/dist/tools/vscode-visions/visions-lsp-core.js +112 -0
  56. package/package.json +96 -4
  57. package/scripts/postinstall.mjs +4 -0
  58. package/scripts/prepare-build.js +38 -0
  59. package/scripts/recover-handoff.mjs +82 -0
@@ -0,0 +1,525 @@
1
+ import { X as equalsIgnoringCaseOnWindows, g as writeJsonAtomicSync, h as writeJsonAtomic, q as canonicalizePath, s as glimmervoidHomeDir } from "./config-store-mm7MgzoL.js";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import crypto from "node:crypto";
5
+ //#region server/core/pairing-token.ts
6
+ var DEFAULT_TOKEN_TTL_MS = 6e5;
7
+ var DEFAULT_DEVICE_MAX_AGE_MS = 15552e6;
8
+ function hashSecret(value) {
9
+ return crypto.createHash("sha256").update(String(value), "utf8").digest("hex");
10
+ }
11
+ function mintPairingToken({ now = Date.now(), ttlMs = DEFAULT_TOKEN_TTL_MS, randomBytes = crypto.randomBytes } = {}) {
12
+ const token = Buffer.from(randomBytes(32)).toString("base64url");
13
+ return {
14
+ token,
15
+ tokenHash: hashSecret(token),
16
+ createdAt: now,
17
+ expiresAt: now + ttlMs
18
+ };
19
+ }
20
+ function decideRedemption({ record, now = Date.now() }) {
21
+ if (!record) return {
22
+ ok: false,
23
+ reason: "unknown"
24
+ };
25
+ if (record.usedAt) return {
26
+ ok: false,
27
+ reason: "used"
28
+ };
29
+ if (typeof record.expiresAt === "number" && now > record.expiresAt) return {
30
+ ok: false,
31
+ reason: "expired"
32
+ };
33
+ return {
34
+ ok: true,
35
+ reason: null
36
+ };
37
+ }
38
+ function mintDeviceCredential({ randomBytes = crypto.randomBytes } = {}) {
39
+ const id = Buffer.from(randomBytes(8)).toString("base64url");
40
+ const secret = Buffer.from(randomBytes(32)).toString("base64url");
41
+ return {
42
+ id,
43
+ secret,
44
+ secretHash: hashSecret(secret),
45
+ cookieValue: `${id}.${secret}`
46
+ };
47
+ }
48
+ function decideDeviceAuth({ record, now = Date.now(), maxAgeMs = DEFAULT_DEVICE_MAX_AGE_MS, secretMatches } = {}) {
49
+ if (!record) return {
50
+ ok: false,
51
+ reason: "unknown"
52
+ };
53
+ if (record.revokedAt) return {
54
+ ok: false,
55
+ reason: "revoked"
56
+ };
57
+ if (typeof record.createdAt === "number" && maxAgeMs > 0 && now - record.createdAt > maxAgeMs) return {
58
+ ok: false,
59
+ reason: "expired"
60
+ };
61
+ if (secretMatches !== true) return {
62
+ ok: false,
63
+ reason: "bad-secret"
64
+ };
65
+ return {
66
+ ok: true,
67
+ reason: null
68
+ };
69
+ }
70
+ var UA_PATTERNS = [
71
+ [/iphone/i, "iPhone"],
72
+ [/ipad/i, "iPad"],
73
+ [/android/i, "Android"],
74
+ [/mac os x|macintosh/i, "Mac"],
75
+ [/windows/i, "Windows"],
76
+ [/cros/i, "ChromeOS"],
77
+ [/linux/i, "Linux"]
78
+ ];
79
+ function deviceNameFromUserAgent(ua) {
80
+ if (typeof ua !== "string" || ua.trim() === "") return "unnamed device";
81
+ for (const [pattern, label] of UA_PATTERNS) if (pattern.test(ua)) return label;
82
+ return "unnamed device";
83
+ }
84
+ //#endregion
85
+ //#region server/pairings-store.ts
86
+ var SNAPSHOT_RELOAD_MS = 3e4;
87
+ var REVOCATION_PROPAGATION_SECONDS = Math.ceil(SNAPSHOT_RELOAD_MS / 1e3);
88
+ var LOCK_SUFFIX = ".lock";
89
+ var LOCK_RETRY_MS = 50;
90
+ var LOCK_MAX_ATTEMPTS = 10;
91
+ var LOCK_STALE_MS = 5e3;
92
+ function errorLabel(err) {
93
+ const failure = err ?? {};
94
+ return String(failure.code || failure.message || err);
95
+ }
96
+ function errorMessage(err) {
97
+ return err instanceof Error ? err.message : String(err);
98
+ }
99
+ function sleepSync(ms) {
100
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
101
+ }
102
+ function emptyDoc() {
103
+ return {
104
+ version: 1,
105
+ pending: [],
106
+ devices: []
107
+ };
108
+ }
109
+ function configSiblingPath(configPath, name) {
110
+ if (configPath) return path.join(path.dirname(configPath), name);
111
+ return path.join(glimmervoidHomeDir(), name);
112
+ }
113
+ function defaultPairingsPath(configPath) {
114
+ return configSiblingPath(configPath, "pairings.json");
115
+ }
116
+ function defaultSeenPath(configPath) {
117
+ return configSiblingPath(configPath, "pairings-seen.json");
118
+ }
119
+ function coerceDoc(parsed) {
120
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return emptyDoc();
121
+ const source = parsed;
122
+ return {
123
+ version: 1,
124
+ pending: Array.isArray(source.pending) ? source.pending.filter((r) => r && typeof r.tokenHash === "string") : [],
125
+ devices: Array.isArray(source.devices) ? source.devices.filter((r) => r && typeof r.id === "string") : []
126
+ };
127
+ }
128
+ function pairingsSignature(doc) {
129
+ const safe = coerceDoc(doc);
130
+ return JSON.stringify(safe);
131
+ }
132
+ function createPairingsStore({ filePath = defaultPairingsPath(), now = Date.now, randomBytes, warn = console.warn, setIntervalFn = (fn, ms) => setInterval(fn, ms), clearIntervalFn = (handle) => clearInterval(handle) } = {}) {
133
+ const pairingsPath = filePath;
134
+ let snapshot = emptyDoc();
135
+ function readDocSync() {
136
+ let raw;
137
+ try {
138
+ raw = fs.readFileSync(pairingsPath, "utf8");
139
+ } catch (err) {
140
+ if (err?.code === "ENOENT") return {
141
+ doc: emptyDoc(),
142
+ missing: true,
143
+ corrupt: false
144
+ };
145
+ warn(`[pairings] Failed to read ${pairingsPath}: ${errorLabel(err)}`);
146
+ return {
147
+ doc: emptyDoc(),
148
+ missing: false,
149
+ corrupt: true
150
+ };
151
+ }
152
+ try {
153
+ return {
154
+ doc: coerceDoc(JSON.parse(raw)),
155
+ missing: false,
156
+ corrupt: false
157
+ };
158
+ } catch (err) {
159
+ warn(`[pairings] Invalid JSON in ${pairingsPath}: ${errorMessage(err)} - treating as no paired devices`);
160
+ return {
161
+ doc: emptyDoc(),
162
+ missing: false,
163
+ corrupt: true
164
+ };
165
+ }
166
+ }
167
+ function load() {
168
+ snapshot = readDocSync().doc;
169
+ return snapshot;
170
+ }
171
+ const lockPath = `${pairingsPath}${LOCK_SUFFIX}`;
172
+ function ensureDir() {
173
+ fs.mkdirSync(path.dirname(pairingsPath), {
174
+ recursive: true,
175
+ mode: 448
176
+ });
177
+ }
178
+ function removeIfStale() {
179
+ try {
180
+ const stat = fs.statSync(lockPath);
181
+ if (Date.now() - stat.mtimeMs <= LOCK_STALE_MS) return false;
182
+ fs.unlinkSync(lockPath);
183
+ warn("[pairings] Removed a stale write lock left by an earlier process");
184
+ return true;
185
+ } catch {
186
+ return true;
187
+ }
188
+ }
189
+ function acquireLock() {
190
+ for (let attempt = 0; attempt < LOCK_MAX_ATTEMPTS; attempt += 1) {
191
+ try {
192
+ fs.closeSync(fs.openSync(lockPath, "wx", 384));
193
+ return true;
194
+ } catch (err) {
195
+ if (err?.code !== "EEXIST") {
196
+ warn(`[pairings] Could not take the write lock: ${errorLabel(err)}`);
197
+ return false;
198
+ }
199
+ }
200
+ if (removeIfStale()) continue;
201
+ sleepSync(LOCK_RETRY_MS);
202
+ }
203
+ return false;
204
+ }
205
+ function releaseLock() {
206
+ try {
207
+ fs.unlinkSync(lockPath);
208
+ } catch {}
209
+ }
210
+ function save(mutator) {
211
+ try {
212
+ ensureDir();
213
+ } catch (err) {
214
+ warn(`[pairings] Failed to create ${path.dirname(pairingsPath)}: ${errorLabel(err)}`);
215
+ return null;
216
+ }
217
+ if (!acquireLock()) {
218
+ warn("[pairings] Another process holds the pairings write lock - nothing was written");
219
+ return null;
220
+ }
221
+ try {
222
+ const { doc, corrupt } = readDocSync();
223
+ if (corrupt) {
224
+ warn("[pairings] Refusing to write over an unreadable pairings file");
225
+ return null;
226
+ }
227
+ if (!mutator(doc)) {
228
+ snapshot = doc;
229
+ return doc;
230
+ }
231
+ writeJsonAtomicSync(pairingsPath, doc, { mode: 384 });
232
+ snapshot = doc;
233
+ return doc;
234
+ } catch (err) {
235
+ warn(`[pairings] Failed to write ${pairingsPath}: ${errorLabel(err)}`);
236
+ return null;
237
+ } finally {
238
+ releaseLock();
239
+ }
240
+ }
241
+ function isDeadPending(record, at) {
242
+ if (!record) return true;
243
+ if (record.usedAt) return true;
244
+ return typeof record.expiresAt === "number" && at > record.expiresAt;
245
+ }
246
+ function mintPending({ name = "", ttlMs } = {}) {
247
+ const minted = mintPairingToken({
248
+ now: now(),
249
+ ttlMs,
250
+ randomBytes
251
+ });
252
+ if (!save((doc) => {
253
+ doc.pending = doc.pending.filter((p) => !isDeadPending(p, now()));
254
+ doc.pending.push({
255
+ tokenHash: minted.tokenHash,
256
+ name: String(name || ""),
257
+ createdAt: minted.createdAt,
258
+ expiresAt: minted.expiresAt,
259
+ usedAt: null
260
+ });
261
+ return true;
262
+ })) return null;
263
+ return {
264
+ token: minted.token,
265
+ expiresAt: minted.expiresAt,
266
+ name: String(name || "")
267
+ };
268
+ }
269
+ function redeem(token, { fallbackName = "" } = {}) {
270
+ const tokenHash = hashSecret(token);
271
+ let outcome = {
272
+ ok: false,
273
+ reason: "unknown",
274
+ device: null
275
+ };
276
+ if (!save((doc) => {
277
+ const record = doc.pending.find((p) => p.tokenHash === tokenHash) || null;
278
+ const verdict = decideRedemption({
279
+ record,
280
+ now: now()
281
+ });
282
+ if (!verdict.ok) {
283
+ outcome = {
284
+ ok: false,
285
+ reason: verdict.reason,
286
+ device: null
287
+ };
288
+ return false;
289
+ }
290
+ if (!record) return false;
291
+ const credential = mintDeviceCredential({ randomBytes });
292
+ record.usedAt = now();
293
+ const device = {
294
+ id: credential.id,
295
+ secretHash: credential.secretHash,
296
+ name: record.name || String(fallbackName || "") || "unnamed device",
297
+ createdAt: now(),
298
+ revokedAt: null
299
+ };
300
+ doc.devices.push(device);
301
+ outcome = {
302
+ ok: true,
303
+ reason: null,
304
+ device,
305
+ cookieValue: credential.cookieValue
306
+ };
307
+ return true;
308
+ })) return {
309
+ ok: false,
310
+ reason: "write-failed",
311
+ device: null
312
+ };
313
+ return outcome;
314
+ }
315
+ function findDevice(id) {
316
+ if (typeof id !== "string" || id === "") return null;
317
+ return snapshot.devices.find((d) => d.id === id) || null;
318
+ }
319
+ function listDevices() {
320
+ return snapshot.devices.map((d) => ({ ...d }));
321
+ }
322
+ function revokeDevice(id) {
323
+ let found = false;
324
+ if (!save((doc) => {
325
+ const device = doc.devices.find((d) => d.id === id);
326
+ if (!device) return false;
327
+ found = true;
328
+ device.revokedAt = now();
329
+ return true;
330
+ })) return {
331
+ ok: false,
332
+ reason: "write-failed"
333
+ };
334
+ if (!found) return {
335
+ ok: false,
336
+ reason: "unknown"
337
+ };
338
+ return {
339
+ ok: true,
340
+ reason: null
341
+ };
342
+ }
343
+ function prunePending() {
344
+ const at = now();
345
+ let removed = 0;
346
+ save((doc) => {
347
+ const kept = doc.pending.filter((p) => !isDeadPending(p, at));
348
+ removed = doc.pending.length - kept.length;
349
+ if (removed === 0) return false;
350
+ doc.pending = kept;
351
+ return true;
352
+ });
353
+ return removed;
354
+ }
355
+ function watch(onChange) {
356
+ let timer = null;
357
+ let watcher = null;
358
+ const dir = path.dirname(pairingsPath);
359
+ let lastSignature = pairingsSignature(snapshot);
360
+ function refresh() {
361
+ load();
362
+ const signature = pairingsSignature(snapshot);
363
+ if (signature === lastSignature) return;
364
+ lastSignature = signature;
365
+ if (onChange) onChange(snapshot);
366
+ }
367
+ const reloadInterval = setIntervalFn(refresh, SNAPSHOT_RELOAD_MS);
368
+ if (reloadInterval.unref) reloadInterval.unref();
369
+ try {
370
+ ensureDir();
371
+ watcher = fs.watch(canonicalizePath(dir), (_event, filename) => {
372
+ if (filename && !equalsIgnoringCaseOnWindows(path.basename(String(filename)), path.basename(pairingsPath))) return;
373
+ if (timer) clearTimeout(timer);
374
+ timer = setTimeout(refresh, 200);
375
+ if (timer.unref) timer.unref();
376
+ });
377
+ } catch (err) {
378
+ warn(`[pairings] Failed to watch ${dir}: ${errorMessage(err)} - falling back to the ${REVOCATION_PROPAGATION_SECONDS}s reload interval`);
379
+ }
380
+ return function stop() {
381
+ if (timer) clearTimeout(timer);
382
+ clearIntervalFn(reloadInterval);
383
+ if (watcher) try {
384
+ watcher.close();
385
+ } catch {}
386
+ watcher = null;
387
+ };
388
+ }
389
+ load();
390
+ return {
391
+ path: pairingsPath,
392
+ load,
393
+ save,
394
+ mintPending,
395
+ redeem,
396
+ findDevice,
397
+ listDevices,
398
+ revokeDevice,
399
+ prunePending,
400
+ watch,
401
+ get snapshot() {
402
+ return snapshot;
403
+ }
404
+ };
405
+ }
406
+ function createSeenStore({ filePath = defaultSeenPath(), throttleMs = 6e4, now = Date.now } = {}) {
407
+ const lastWriteByDevice = /* @__PURE__ */ new Map();
408
+ let pending = null;
409
+ function readAll() {
410
+ try {
411
+ const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
412
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
413
+ return {};
414
+ } catch {
415
+ return {};
416
+ }
417
+ }
418
+ const doc = readAll();
419
+ function touch(deviceId) {
420
+ if (!deviceId) return;
421
+ const at = now();
422
+ const last = lastWriteByDevice.get(deviceId);
423
+ if (last != null && at - last < throttleMs) return;
424
+ lastWriteByDevice.set(deviceId, at);
425
+ doc[deviceId] = at;
426
+ pending = writeJsonAtomic(filePath, doc, { mode: 384 }).catch(() => {});
427
+ }
428
+ return {
429
+ touch,
430
+ readAll,
431
+ get pending() {
432
+ return pending;
433
+ }
434
+ };
435
+ }
436
+ //#endregion
437
+ //#region server/core/remote-config.ts
438
+ function toPort(value) {
439
+ if (typeof value === "number" && Number.isInteger(value)) return value;
440
+ if (typeof value === "string" && /^\d+$/.test(value.trim())) return Number.parseInt(value.trim(), 10);
441
+ return null;
442
+ }
443
+ function normalizeRemoteConfig(raw) {
444
+ const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
445
+ const enabled = src.enabled === true;
446
+ const port = toPort(src.port);
447
+ const publicHost = typeof src.publicHost === "string" ? src.publicHost.trim() : "";
448
+ const ownerLogin = typeof src.ownerLogin === "string" ? src.ownerLogin.trim().toLowerCase() : "";
449
+ if (!enabled) return {
450
+ enabled,
451
+ port,
452
+ publicHost,
453
+ allowedOrigins: [],
454
+ ownerLogin
455
+ };
456
+ const listed = Array.isArray(src.allowedOrigins) ? src.allowedOrigins.filter((o) => typeof o === "string" && o.trim() !== "").map((o) => o.trim()) : [];
457
+ if (listed.length === 0 && publicHost !== "") return {
458
+ enabled,
459
+ port,
460
+ publicHost,
461
+ allowedOrigins: [`https://${publicHost}`],
462
+ ownerLogin
463
+ };
464
+ return {
465
+ enabled,
466
+ port,
467
+ publicHost,
468
+ allowedOrigins: listed,
469
+ ownerLogin
470
+ };
471
+ }
472
+ function validateRemoteConfig(remote, localPort) {
473
+ if (!remote || remote.enabled !== true) return {
474
+ ok: true,
475
+ error: null
476
+ };
477
+ if (remote.port == null) return {
478
+ ok: false,
479
+ error: "remote.enabled is true but remote.port is not set"
480
+ };
481
+ if (!Number.isInteger(remote.port) || remote.port < 1 || remote.port > 65535) return {
482
+ ok: false,
483
+ error: `remote.port must be an integer 1-65535 (got ${JSON.stringify(remote.port)})`
484
+ };
485
+ if (remote.port === localPort) return {
486
+ ok: false,
487
+ error: `remote.port (${remote.port}) must differ from the local port (${localPort})`
488
+ };
489
+ return {
490
+ ok: true,
491
+ error: null
492
+ };
493
+ }
494
+ function isLoopbackHost(host) {
495
+ if (typeof host !== "string") return false;
496
+ const bare = host.trim().toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
497
+ if (bare === "" || bare === "localhost") return bare === "localhost";
498
+ if (bare === "::1" || bare === "0:0:0:0:0:0:0:1") return true;
499
+ return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bare);
500
+ }
501
+ function decideBindHost({ envHost, insecureBind } = {}) {
502
+ const host = typeof envHost === "string" ? envHost.trim() : "";
503
+ if (host === "") return {
504
+ host: "127.0.0.1",
505
+ allowed: true,
506
+ reason: null
507
+ };
508
+ if (isLoopbackHost(host)) return {
509
+ host,
510
+ allowed: true,
511
+ reason: null
512
+ };
513
+ if (insecureBind === true) return {
514
+ host,
515
+ allowed: true,
516
+ reason: "insecure-bind"
517
+ };
518
+ return {
519
+ host,
520
+ allowed: false,
521
+ reason: "non-loopback"
522
+ };
523
+ }
524
+ //#endregion
525
+ export { configSiblingPath as a, defaultPairingsPath as c, decideDeviceAuth as d, deviceNameFromUserAgent as f, REVOCATION_PROPAGATION_SECONDS as i, defaultSeenPath as l, normalizeRemoteConfig as n, createPairingsStore as o, hashSecret as p, validateRemoteConfig as r, createSeenStore as s, decideBindHost as t, DEFAULT_DEVICE_MAX_AGE_MS as u };
@@ -0,0 +1,133 @@
1
+ //#region session/core/sane-yolo.ts
2
+ var SANE_YOLO_PATH_ENV = "GLIMMERVOID_SANE_YOLO_PATH";
3
+ var SANE_YOLO_POLICY = {
4
+ version: 1,
5
+ destructive_command_protection: {
6
+ enabled: true,
7
+ overrides: {
8
+ "git.branch-force-delete": "off",
9
+ "git.merge-abort": "off",
10
+ "git.rebase-abort": "off",
11
+ "rm.recursive-force-dynamic-target": "on"
12
+ }
13
+ },
14
+ secret_protection: { enabled: false }
15
+ };
16
+ var SANE_YOLO_RULES = {
17
+ version: 1,
18
+ rules: ["infra"],
19
+ overrides: {},
20
+ transparent_wrappers: ["rtk", "npx"]
21
+ };
22
+ var INFRA_REASON = "Sane YOLO blocks infrastructure teardown; run this command by hand.";
23
+ var TERRAFORM_DESTROY_FLAGS = [
24
+ "-destroy",
25
+ "--destroy",
26
+ "-destroy=true",
27
+ "--destroy=true"
28
+ ];
29
+ var SANE_YOLO_FILES = {
30
+ "policy.json": SANE_YOLO_POLICY,
31
+ "rules/rule.json": SANE_YOLO_RULES,
32
+ "rules/infra/rulebook.json": {
33
+ rulebook_version: 1,
34
+ name: "infra",
35
+ version: "1.1.0",
36
+ allowed_commands: [
37
+ "terraform",
38
+ "tofu",
39
+ "pulumi",
40
+ "kubectl"
41
+ ],
42
+ rules: [
43
+ {
44
+ name: "terraform-destroy",
45
+ command: "terraform",
46
+ subcommand: "destroy",
47
+ block_args: ["destroy"],
48
+ reason: INFRA_REASON
49
+ },
50
+ {
51
+ name: "terraform-apply-destroy",
52
+ command: "terraform",
53
+ subcommand: "apply",
54
+ block_args: TERRAFORM_DESTROY_FLAGS,
55
+ reason: INFRA_REASON
56
+ },
57
+ {
58
+ name: "tofu-destroy",
59
+ command: "tofu",
60
+ subcommand: "destroy",
61
+ block_args: ["destroy"],
62
+ reason: INFRA_REASON
63
+ },
64
+ {
65
+ name: "tofu-apply-destroy",
66
+ command: "tofu",
67
+ subcommand: "apply",
68
+ block_args: TERRAFORM_DESTROY_FLAGS,
69
+ reason: INFRA_REASON
70
+ },
71
+ {
72
+ name: "pulumi-destroy",
73
+ command: "pulumi",
74
+ subcommand: "destroy",
75
+ block_args: ["destroy"],
76
+ reason: INFRA_REASON
77
+ },
78
+ {
79
+ name: "pulumi-down",
80
+ command: "pulumi",
81
+ subcommand: "down",
82
+ block_args: ["down"],
83
+ reason: INFRA_REASON
84
+ },
85
+ {
86
+ name: "kubectl-delete-namespace",
87
+ command: "kubectl",
88
+ subcommand: "delete",
89
+ block_args: [
90
+ "ns",
91
+ "namespace",
92
+ "namespaces"
93
+ ],
94
+ reason: INFRA_REASON
95
+ }
96
+ ]
97
+ }
98
+ };
99
+ function saneYoloEnv(homeDir) {
100
+ return {
101
+ CC_SAFETY_NET_HOME: homeDir,
102
+ CC_SAFETY_NET_PROJECT_TIGHTEN_ONLY: "1",
103
+ CC_SAFETY_NET_AUDIT_HOME: homeDir,
104
+ CC_SAFETY_NET_AUDIT_SCOPE: "blocked"
105
+ };
106
+ }
107
+ //#endregion
108
+ //#region session/core/rtk-hook-core.ts
109
+ var RTK_PATH_ENV = "GLIMMERVOID_RTK_PATH";
110
+ var MAX_RTK_STDOUT_BYTES = 65536;
111
+ function isPlainObject(value) {
112
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
113
+ }
114
+ function normalizeRtkHookResponse(stdoutText) {
115
+ if (typeof stdoutText !== "string") return "";
116
+ const trimmed = stdoutText.trim();
117
+ if (!trimmed) return "";
118
+ if (Buffer.byteLength(trimmed) > 65536) return "";
119
+ let parsed = null;
120
+ try {
121
+ parsed = JSON.parse(trimmed);
122
+ } catch {
123
+ return "";
124
+ }
125
+ if (!isPlainObject(parsed)) return "";
126
+ const hookSpecificOutput = parsed.hookSpecificOutput;
127
+ if (isPlainObject(hookSpecificOutput) && isPlainObject(hookSpecificOutput.updatedInput)) {
128
+ if (typeof hookSpecificOutput.permissionDecision !== "string") hookSpecificOutput.permissionDecision = "allow";
129
+ }
130
+ return JSON.stringify(parsed);
131
+ }
132
+ //#endregion
133
+ export { SANE_YOLO_PATH_ENV as a, SANE_YOLO_FILES as i, RTK_PATH_ENV as n, saneYoloEnv as o, normalizeRtkHookResponse as r, MAX_RTK_STDOUT_BYTES as t };
@@ -0,0 +1,21 @@
1
+ import { i as execSync } from "./child-process-safe-DRGsp0TE.js";
2
+ import { n as glimmervoidHomeDir } from "./config-path-core-DFt-TemS.js";
3
+ import { r as resolveRtkPath } from "./hook-tools-pSJia7ks.js";
4
+ import fs from "node:fs";
5
+ import os from "node:os";
6
+ //#region server/rtk-resolver.ts
7
+ function resolveRtkPathFromSystem() {
8
+ return resolveRtkPath({
9
+ glimmervoidHome: glimmervoidHomeDir(os.homedir(), process.env),
10
+ platform: process.platform,
11
+ exec: execSync,
12
+ fsApi: fs
13
+ });
14
+ }
15
+ var cachedRtkPath = null;
16
+ function getRtkPath(resolve = resolveRtkPathFromSystem) {
17
+ if (!cachedRtkPath) cachedRtkPath = resolve();
18
+ return cachedRtkPath;
19
+ }
20
+ //#endregion
21
+ export { getRtkPath as t };
@@ -0,0 +1,2 @@
1
+ import { t as getRtkPath } from "./rtk-resolver-CLo-gZzw.js";
2
+ export { getRtkPath };