lula2 0.7.3 → 0.7.5-nightly.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 (51) hide show
  1. package/README.md +0 -1
  2. package/dist/_app/immutable/assets/{0.DqWJrcPI.css → 0.DLu2XH4u.css} +1 -1
  3. package/dist/_app/immutable/chunks/2BRL7VKY.js +1 -0
  4. package/dist/_app/immutable/chunks/{Cih4fRH-.js → B3K8aJnm.js} +1 -1
  5. package/dist/_app/immutable/chunks/{DHBD-O6i.js → BOr7AGz1.js} +1 -1
  6. package/dist/_app/immutable/chunks/BTEcqCut.js +1 -0
  7. package/dist/_app/immutable/chunks/C04NlUEE.js +2 -0
  8. package/dist/_app/immutable/chunks/CYCiyXhX.js +2 -0
  9. package/dist/_app/immutable/chunks/CvMmkcEK.js +1 -0
  10. package/dist/_app/immutable/chunks/DlvidjXv.js +1 -0
  11. package/dist/_app/immutable/chunks/Dqqytqkj.js +1 -0
  12. package/dist/_app/immutable/chunks/DveOLWfB.js +79 -0
  13. package/dist/_app/immutable/chunks/OZt-i3RT.js +1 -0
  14. package/dist/_app/immutable/entry/{app.BvGur0mr.js → app.DQYVFQmH.js} +2 -2
  15. package/dist/_app/immutable/entry/start.CRaGL1oc.js +1 -0
  16. package/dist/_app/immutable/nodes/{0.Dx6r-xPK.js → 0.VqJIWUds.js} +2 -2
  17. package/dist/_app/immutable/nodes/1.DOuy_I_c.js +1 -0
  18. package/dist/_app/immutable/nodes/{2.zlTZskRg.js → 2.CwWiKEBj.js} +1 -1
  19. package/dist/_app/immutable/nodes/3.UIV2UOH1.js +1 -0
  20. package/dist/_app/immutable/nodes/{4.CoEqSeTv.js → 4.BdgTjqjd.js} +7 -7
  21. package/dist/_app/version.json +1 -1
  22. package/dist/cli/commands/ui.js +46 -41
  23. package/dist/cli/server/index.js +46 -41
  24. package/dist/cli/server/server.js +46 -41
  25. package/dist/cli/server/serverState.js +23 -11
  26. package/dist/cli/server/websocketServer.js +40 -41
  27. package/dist/index.html +11 -11
  28. package/dist/index.js +49 -44
  29. package/package.json +127 -128
  30. package/src/lib/components/controls/MappingCard.svelte +9 -4
  31. package/src/lib/components/controls/MappingForm.svelte +36 -3
  32. package/src/lib/components/controls/renderers/EditableFieldRenderer.svelte +57 -0
  33. package/src/lib/components/controls/tabs/CustomFieldsTab.svelte +1 -0
  34. package/src/lib/components/controls/tabs/ImplementationTab.svelte +1 -0
  35. package/src/lib/components/controls/tabs/MappingsTab.svelte +44 -20
  36. package/src/lib/components/controls/tabs/OverviewTab.svelte +1 -0
  37. package/src/lib/components/forms/FormField.svelte +65 -3
  38. package/src/lib/types.ts +4 -1
  39. package/src/lib/websocket.ts +2 -6
  40. package/src/routes/control/[id]/+page.svelte +2 -2
  41. package/dist/_app/immutable/chunks/B3ME9fYB.js +0 -1
  42. package/dist/_app/immutable/chunks/BBITAbWI.js +0 -2
  43. package/dist/_app/immutable/chunks/CUt21Xol.js +0 -1
  44. package/dist/_app/immutable/chunks/D5ermNRH.js +0 -65
  45. package/dist/_app/immutable/chunks/DqNseCFX.js +0 -1
  46. package/dist/_app/immutable/chunks/DtiGB2s7.js +0 -2
  47. package/dist/_app/immutable/chunks/DzukiT8m.js +0 -1
  48. package/dist/_app/immutable/chunks/R-CI0WwD.js +0 -1
  49. package/dist/_app/immutable/entry/start.yE51hRYN.js +0 -1
  50. package/dist/_app/immutable/nodes/1.COpX6TiD.js +0 -1
  51. package/dist/_app/immutable/nodes/3.BafDPdLR.js +0 -1
@@ -109,6 +109,7 @@ import {
109
109
  } from "fs";
110
110
  import * as yaml2 from "js-yaml";
111
111
  import { join as join2 } from "path";
112
+ import { createHash } from "crypto";
112
113
  var FileStore;
113
114
  var init_fileStore = __esm({
114
115
  "cli/server/infrastructure/fileStore.ts"() {
@@ -406,6 +407,10 @@ var init_fileStore = __esm({
406
407
  const content = readFileSync2(mappingFile, "utf8");
407
408
  const parsed = yaml2.load(content);
408
409
  if (Array.isArray(parsed)) {
410
+ parsed.forEach((mapping) => {
411
+ mapping.hash = createHash("sha256").update(JSON.stringify(mapping)).digest("hex");
412
+ return mapping;
413
+ });
409
414
  mappings.push(...parsed);
410
415
  }
411
416
  } catch (error) {
@@ -440,12 +445,9 @@ var init_fileStore = __esm({
440
445
  existingMappings = [];
441
446
  }
442
447
  }
443
- const existingIndex = existingMappings.findIndex((m) => m.uuid === mapping.uuid);
444
- if (existingIndex >= 0) {
445
- existingMappings[existingIndex] = mapping;
446
- } else {
447
- existingMappings.push(mapping);
448
- }
448
+ const cleanMapping = { ...mapping };
449
+ delete cleanMapping.hash;
450
+ existingMappings.push(cleanMapping);
449
451
  try {
450
452
  const yamlContent = yaml2.dump(existingMappings, {
451
453
  indent: 2,
@@ -470,7 +472,8 @@ var init_fileStore = __esm({
470
472
  let mappings = yaml2.load(content) || [];
471
473
  const originalLength = mappings.length;
472
474
  mappings = mappings.filter((m) => {
473
- return `${m.control_id}:${m.uuid}` !== compositeKey;
475
+ const hash = createHash("sha256").update(JSON.stringify(m)).digest("hex");
476
+ return `${m.control_id}:${hash}` !== compositeKey;
474
477
  });
475
478
  if (mappings.length < originalLength) {
476
479
  if (mappings.length === 0) {
@@ -533,8 +536,13 @@ var init_fileStore = __esm({
533
536
  if (!existsSync2(familyDir)) {
534
537
  mkdirSync(familyDir, { recursive: true });
535
538
  }
539
+ const cleanMappings = controlMappings.map((m) => {
540
+ const clean = { ...m };
541
+ delete clean.hash;
542
+ return clean;
543
+ });
536
544
  try {
537
- const yamlContent = yaml2.dump(controlMappings, {
545
+ const yamlContent = yaml2.dump(cleanMappings, {
538
546
  indent: 2,
539
547
  lineWidth: -1,
540
548
  noRefs: true
@@ -1453,6 +1461,7 @@ __export(serverState_exports, {
1453
1461
  saveMappingsToFile: () => saveMappingsToFile
1454
1462
  });
1455
1463
  import { join as join3 } from "path";
1464
+ import { createHash as createHash2 } from "crypto";
1456
1465
  function initializeServerState(controlSetDir, subdir = ".") {
1457
1466
  const fullPath = subdir === "." ? controlSetDir : join3(controlSetDir, subdir);
1458
1467
  serverState = {
@@ -1495,11 +1504,11 @@ function addMappingToIndexes(mapping) {
1495
1504
  if (!state.mappingsByFamily.has(family)) {
1496
1505
  state.mappingsByFamily.set(family, /* @__PURE__ */ new Set());
1497
1506
  }
1498
- state.mappingsByFamily.get(family).add(mapping.uuid);
1507
+ state.mappingsByFamily.get(family).add(mapping.hash);
1499
1508
  if (!state.mappingsByControl.has(mapping.control_id)) {
1500
1509
  state.mappingsByControl.set(mapping.control_id, /* @__PURE__ */ new Set());
1501
1510
  }
1502
- state.mappingsByControl.get(mapping.control_id).add(mapping.uuid);
1511
+ state.mappingsByControl.get(mapping.control_id).add(mapping.hash);
1503
1512
  }
1504
1513
  async function loadAllData() {
1505
1514
  const state = getServerState();
@@ -1513,7 +1522,10 @@ async function loadAllData() {
1513
1522
  debug(`Loaded ${controls.length} controls from individual files`);
1514
1523
  const mappings = await state.fileStore.loadMappings();
1515
1524
  for (const mapping of mappings) {
1516
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
1525
+ if (!mapping.hash) {
1526
+ mapping.hash = createHash2("sha256").update(JSON.stringify(mapping)).digest("hex");
1527
+ }
1528
+ const compositeKey = `${mapping.control_id}:${mapping.hash}`;
1517
1529
  state.mappingsCache.set(compositeKey, mapping);
1518
1530
  addMappingToIndexes(mapping);
1519
1531
  }
@@ -2646,6 +2658,7 @@ init_gitHistory();
2646
2658
  import * as yaml5 from "js-yaml";
2647
2659
  import { join as join5 } from "path";
2648
2660
  import { WebSocket, WebSocketServer } from "ws";
2661
+ import crypto2 from "node:crypto";
2649
2662
  var WebSocketManager = class {
2650
2663
  wss = null;
2651
2664
  clients = /* @__PURE__ */ new Set();
@@ -2710,21 +2723,24 @@ var WebSocketManager = class {
2710
2723
  if (payload && payload.control_id) {
2711
2724
  const mapping = payload;
2712
2725
  if (!mapping.uuid) {
2713
- const crypto2 = await import("crypto");
2714
- mapping.uuid = crypto2.randomUUID();
2726
+ const crypto3 = await import("crypto");
2727
+ mapping.uuid = crypto3.randomUUID();
2715
2728
  }
2729
+ if (!mapping.hash || mapping.hash === "") {
2730
+ mapping.hash = crypto2.createHash("sha256").update(JSON.stringify(mapping)).digest("hex");
2731
+ }
2732
+ const compositeKey = `${mapping.control_id}:${mapping.hash}`;
2716
2733
  await state.fileStore.saveMapping(mapping);
2717
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
2718
2734
  state.mappingsCache.set(compositeKey, mapping);
2719
2735
  const family = mapping.control_id.split("-")[0];
2720
2736
  if (!state.mappingsByFamily.has(family)) {
2721
2737
  state.mappingsByFamily.set(family, /* @__PURE__ */ new Set());
2722
2738
  }
2723
- state.mappingsByFamily.get(family)?.add(mapping.uuid);
2739
+ state.mappingsByFamily.get(family)?.add(mapping.hash);
2724
2740
  if (!state.mappingsByControl.has(mapping.control_id)) {
2725
2741
  state.mappingsByControl.set(mapping.control_id, /* @__PURE__ */ new Set());
2726
2742
  }
2727
- state.mappingsByControl.get(mapping.control_id)?.add(mapping.uuid);
2743
+ state.mappingsByControl.get(mapping.control_id)?.add(mapping.hash);
2728
2744
  ws.send(
2729
2745
  JSON.stringify({
2730
2746
  type: "mapping-created",
@@ -2735,38 +2751,21 @@ var WebSocketManager = class {
2735
2751
  }
2736
2752
  break;
2737
2753
  }
2738
- case "update-mapping": {
2739
- const state = getServerState();
2740
- if (payload && payload.uuid) {
2741
- const mapping = payload;
2742
- await state.fileStore.saveMapping(mapping);
2743
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
2744
- state.mappingsCache.set(compositeKey, mapping);
2745
- ws.send(
2746
- JSON.stringify({
2747
- type: "mapping-updated",
2748
- payload: { uuid: mapping.uuid, success: true }
2749
- })
2750
- );
2751
- this.broadcastState();
2752
- }
2753
- break;
2754
- }
2755
2754
  case "delete-mapping": {
2756
2755
  const state = getServerState();
2757
- if (payload && payload.uuid) {
2758
- const uuid = payload.uuid;
2759
- const mapping = state.mappingsCache.get(uuid);
2756
+ if (payload && payload.composite_key) {
2757
+ const composite_key = payload.composite_key;
2758
+ const mapping = state.mappingsCache.get(composite_key);
2760
2759
  if (mapping) {
2761
- await state.fileStore.deleteMapping(uuid);
2762
- state.mappingsCache.delete(uuid);
2760
+ await state.fileStore.deleteMapping(composite_key);
2761
+ state.mappingsCache.delete(composite_key);
2763
2762
  const family = mapping.control_id.split("-")[0];
2764
- state.mappingsByFamily.get(family)?.delete(uuid);
2765
- state.mappingsByControl.get(mapping.control_id)?.delete(uuid);
2763
+ state.mappingsByFamily.get(family)?.delete(mapping.hash);
2764
+ state.mappingsByControl.get(mapping.control_id)?.delete(mapping.hash);
2766
2765
  ws.send(
2767
2766
  JSON.stringify({
2768
2767
  type: "mapping-deleted",
2769
- payload: { uuid, success: true }
2768
+ payload: { hash: mapping.hash, success: true }
2770
2769
  })
2771
2770
  );
2772
2771
  this.broadcastState();
package/dist/index.html CHANGED
@@ -6,28 +6,28 @@
6
6
  <link rel="icon" href="/lula.png" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1" />
8
8
 
9
- <link rel="modulepreload" href="/_app/immutable/entry/start.yE51hRYN.js">
10
- <link rel="modulepreload" href="/_app/immutable/chunks/CUt21Xol.js">
11
- <link rel="modulepreload" href="/_app/immutable/chunks/B3ME9fYB.js">
12
- <link rel="modulepreload" href="/_app/immutable/entry/app.BvGur0mr.js">
13
- <link rel="modulepreload" href="/_app/immutable/chunks/BBITAbWI.js">
14
- <link rel="modulepreload" href="/_app/immutable/chunks/DzukiT8m.js">
15
- <link rel="modulepreload" href="/_app/immutable/chunks/R-CI0WwD.js">
16
- <link rel="modulepreload" href="/_app/immutable/chunks/Cih4fRH-.js">
9
+ <link rel="modulepreload" href="/_app/immutable/entry/start.CRaGL1oc.js">
10
+ <link rel="modulepreload" href="/_app/immutable/chunks/OZt-i3RT.js">
11
+ <link rel="modulepreload" href="/_app/immutable/chunks/DlvidjXv.js">
12
+ <link rel="modulepreload" href="/_app/immutable/entry/app.DQYVFQmH.js">
13
+ <link rel="modulepreload" href="/_app/immutable/chunks/C04NlUEE.js">
14
+ <link rel="modulepreload" href="/_app/immutable/chunks/Dqqytqkj.js">
15
+ <link rel="modulepreload" href="/_app/immutable/chunks/CvMmkcEK.js">
16
+ <link rel="modulepreload" href="/_app/immutable/chunks/B3K8aJnm.js">
17
17
  </head>
18
18
  <body data-sveltekit-preload-data="hover">
19
19
  <div style="display: contents">
20
20
  <script>
21
21
  {
22
- __sveltekit_owc510 = {
22
+ __sveltekit_fxn20 = {
23
23
  base: ""
24
24
  };
25
25
 
26
26
  const element = document.currentScript.parentElement;
27
27
 
28
28
  Promise.all([
29
- import("/_app/immutable/entry/start.yE51hRYN.js"),
30
- import("/_app/immutable/entry/app.BvGur0mr.js")
29
+ import("/_app/immutable/entry/start.CRaGL1oc.js"),
30
+ import("/_app/immutable/entry/app.DQYVFQmH.js")
31
31
  ]).then(([kit, app]) => {
32
32
  kit.start(app, element);
33
33
  });
package/dist/index.js CHANGED
@@ -1681,6 +1681,7 @@ import {
1681
1681
  } from "fs";
1682
1682
  import * as yaml2 from "js-yaml";
1683
1683
  import { join as join2 } from "path";
1684
+ import { createHash as createHash2 } from "crypto";
1684
1685
  var FileStore;
1685
1686
  var init_fileStore = __esm({
1686
1687
  "cli/server/infrastructure/fileStore.ts"() {
@@ -1978,6 +1979,10 @@ var init_fileStore = __esm({
1978
1979
  const content = readFileSync2(mappingFile, "utf8");
1979
1980
  const parsed = yaml2.load(content);
1980
1981
  if (Array.isArray(parsed)) {
1982
+ parsed.forEach((mapping) => {
1983
+ mapping.hash = createHash2("sha256").update(JSON.stringify(mapping)).digest("hex");
1984
+ return mapping;
1985
+ });
1981
1986
  mappings.push(...parsed);
1982
1987
  }
1983
1988
  } catch (error) {
@@ -2012,12 +2017,9 @@ var init_fileStore = __esm({
2012
2017
  existingMappings = [];
2013
2018
  }
2014
2019
  }
2015
- const existingIndex = existingMappings.findIndex((m) => m.uuid === mapping.uuid);
2016
- if (existingIndex >= 0) {
2017
- existingMappings[existingIndex] = mapping;
2018
- } else {
2019
- existingMappings.push(mapping);
2020
- }
2020
+ const cleanMapping = { ...mapping };
2021
+ delete cleanMapping.hash;
2022
+ existingMappings.push(cleanMapping);
2021
2023
  try {
2022
2024
  const yamlContent = yaml2.dump(existingMappings, {
2023
2025
  indent: 2,
@@ -2042,7 +2044,8 @@ var init_fileStore = __esm({
2042
2044
  let mappings = yaml2.load(content) || [];
2043
2045
  const originalLength = mappings.length;
2044
2046
  mappings = mappings.filter((m) => {
2045
- return `${m.control_id}:${m.uuid}` !== compositeKey;
2047
+ const hash = createHash2("sha256").update(JSON.stringify(m)).digest("hex");
2048
+ return `${m.control_id}:${hash}` !== compositeKey;
2046
2049
  });
2047
2050
  if (mappings.length < originalLength) {
2048
2051
  if (mappings.length === 0) {
@@ -2105,8 +2108,13 @@ var init_fileStore = __esm({
2105
2108
  if (!existsSync2(familyDir)) {
2106
2109
  mkdirSync(familyDir, { recursive: true });
2107
2110
  }
2111
+ const cleanMappings = controlMappings.map((m) => {
2112
+ const clean = { ...m };
2113
+ delete clean.hash;
2114
+ return clean;
2115
+ });
2108
2116
  try {
2109
- const yamlContent = yaml2.dump(controlMappings, {
2117
+ const yamlContent = yaml2.dump(cleanMappings, {
2110
2118
  indent: 2,
2111
2119
  lineWidth: -1,
2112
2120
  noRefs: true
@@ -3025,6 +3033,7 @@ __export(serverState_exports, {
3025
3033
  saveMappingsToFile: () => saveMappingsToFile
3026
3034
  });
3027
3035
  import { join as join3 } from "path";
3036
+ import { createHash as createHash3 } from "crypto";
3028
3037
  function initializeServerState(controlSetDir, subdir = ".") {
3029
3038
  const fullPath = subdir === "." ? controlSetDir : join3(controlSetDir, subdir);
3030
3039
  serverState = {
@@ -3067,11 +3076,11 @@ function addMappingToIndexes(mapping) {
3067
3076
  if (!state.mappingsByFamily.has(family)) {
3068
3077
  state.mappingsByFamily.set(family, /* @__PURE__ */ new Set());
3069
3078
  }
3070
- state.mappingsByFamily.get(family).add(mapping.uuid);
3079
+ state.mappingsByFamily.get(family).add(mapping.hash);
3071
3080
  if (!state.mappingsByControl.has(mapping.control_id)) {
3072
3081
  state.mappingsByControl.set(mapping.control_id, /* @__PURE__ */ new Set());
3073
3082
  }
3074
- state.mappingsByControl.get(mapping.control_id).add(mapping.uuid);
3083
+ state.mappingsByControl.get(mapping.control_id).add(mapping.hash);
3075
3084
  }
3076
3085
  async function loadAllData() {
3077
3086
  const state = getServerState();
@@ -3085,7 +3094,10 @@ async function loadAllData() {
3085
3094
  debug(`Loaded ${controls.length} controls from individual files`);
3086
3095
  const mappings = await state.fileStore.loadMappings();
3087
3096
  for (const mapping of mappings) {
3088
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
3097
+ if (!mapping.hash) {
3098
+ mapping.hash = createHash3("sha256").update(JSON.stringify(mapping)).digest("hex");
3099
+ }
3100
+ const compositeKey = `${mapping.control_id}:${mapping.hash}`;
3089
3101
  state.mappingsCache.set(compositeKey, mapping);
3090
3102
  addMappingToIndexes(mapping);
3091
3103
  }
@@ -5136,6 +5148,7 @@ init_gitHistory();
5136
5148
  import * as yaml5 from "js-yaml";
5137
5149
  import { join as join5 } from "path";
5138
5150
  import { WebSocket, WebSocketServer } from "ws";
5151
+ import crypto2 from "node:crypto";
5139
5152
  var WebSocketManager = class {
5140
5153
  wss = null;
5141
5154
  clients = /* @__PURE__ */ new Set();
@@ -5200,21 +5213,24 @@ var WebSocketManager = class {
5200
5213
  if (payload && payload.control_id) {
5201
5214
  const mapping = payload;
5202
5215
  if (!mapping.uuid) {
5203
- const crypto2 = await import("crypto");
5204
- mapping.uuid = crypto2.randomUUID();
5216
+ const crypto3 = await import("crypto");
5217
+ mapping.uuid = crypto3.randomUUID();
5205
5218
  }
5219
+ if (!mapping.hash || mapping.hash === "") {
5220
+ mapping.hash = crypto2.createHash("sha256").update(JSON.stringify(mapping)).digest("hex");
5221
+ }
5222
+ const compositeKey = `${mapping.control_id}:${mapping.hash}`;
5206
5223
  await state.fileStore.saveMapping(mapping);
5207
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
5208
5224
  state.mappingsCache.set(compositeKey, mapping);
5209
5225
  const family = mapping.control_id.split("-")[0];
5210
5226
  if (!state.mappingsByFamily.has(family)) {
5211
5227
  state.mappingsByFamily.set(family, /* @__PURE__ */ new Set());
5212
5228
  }
5213
- state.mappingsByFamily.get(family)?.add(mapping.uuid);
5229
+ state.mappingsByFamily.get(family)?.add(mapping.hash);
5214
5230
  if (!state.mappingsByControl.has(mapping.control_id)) {
5215
5231
  state.mappingsByControl.set(mapping.control_id, /* @__PURE__ */ new Set());
5216
5232
  }
5217
- state.mappingsByControl.get(mapping.control_id)?.add(mapping.uuid);
5233
+ state.mappingsByControl.get(mapping.control_id)?.add(mapping.hash);
5218
5234
  ws.send(
5219
5235
  JSON.stringify({
5220
5236
  type: "mapping-created",
@@ -5225,38 +5241,21 @@ var WebSocketManager = class {
5225
5241
  }
5226
5242
  break;
5227
5243
  }
5228
- case "update-mapping": {
5229
- const state = getServerState();
5230
- if (payload && payload.uuid) {
5231
- const mapping = payload;
5232
- await state.fileStore.saveMapping(mapping);
5233
- const compositeKey = `${mapping.control_id}:${mapping.uuid}`;
5234
- state.mappingsCache.set(compositeKey, mapping);
5235
- ws.send(
5236
- JSON.stringify({
5237
- type: "mapping-updated",
5238
- payload: { uuid: mapping.uuid, success: true }
5239
- })
5240
- );
5241
- this.broadcastState();
5242
- }
5243
- break;
5244
- }
5245
5244
  case "delete-mapping": {
5246
5245
  const state = getServerState();
5247
- if (payload && payload.uuid) {
5248
- const uuid = payload.uuid;
5249
- const mapping = state.mappingsCache.get(uuid);
5246
+ if (payload && payload.composite_key) {
5247
+ const composite_key = payload.composite_key;
5248
+ const mapping = state.mappingsCache.get(composite_key);
5250
5249
  if (mapping) {
5251
- await state.fileStore.deleteMapping(uuid);
5252
- state.mappingsCache.delete(uuid);
5250
+ await state.fileStore.deleteMapping(composite_key);
5251
+ state.mappingsCache.delete(composite_key);
5253
5252
  const family = mapping.control_id.split("-")[0];
5254
- state.mappingsByFamily.get(family)?.delete(uuid);
5255
- state.mappingsByControl.get(mapping.control_id)?.delete(uuid);
5253
+ state.mappingsByFamily.get(family)?.delete(mapping.hash);
5254
+ state.mappingsByControl.get(mapping.control_id)?.delete(mapping.hash);
5256
5255
  ws.send(
5257
5256
  JSON.stringify({
5258
5257
  type: "mapping-deleted",
5259
- payload: { uuid, success: true }
5258
+ payload: { hash: mapping.hash, success: true }
5260
5259
  })
5261
5260
  );
5262
5261
  this.broadcastState();
@@ -5733,6 +5732,7 @@ var WebSocketManager = class {
5733
5732
  var wsManager = new WebSocketManager();
5734
5733
 
5735
5734
  // cli/server/server.ts
5735
+ import { createHash as createHash4 } from "crypto";
5736
5736
  var __filename = fileURLToPath(import.meta.url);
5737
5737
  var __dirname = dirname2(__filename);
5738
5738
  async function createServer(options) {
@@ -5758,6 +5758,11 @@ async function createServer(options) {
5758
5758
  app.get("/*splat", (req, res) => {
5759
5759
  res.sendFile("index.html", { root: distPath });
5760
5760
  });
5761
+ app.post("/hash", (req, res) => {
5762
+ delete req.body.hash;
5763
+ const hash = createHash4("sha256").update(JSON.stringify(req.body)).digest("hex");
5764
+ res.status(200).json({ hash });
5765
+ });
5761
5766
  const httpServer = createHttpServer(app);
5762
5767
  wsManager.initialize(httpServer);
5763
5768
  return {
@@ -5869,7 +5874,7 @@ function getVersion() {
5869
5874
  import fs4 from "fs";
5870
5875
  import { Octokit } from "@octokit/rest";
5871
5876
  import { Command, Option } from "commander";
5872
- import { createHash as createHash2 } from "crypto";
5877
+ import { createHash as createHash5 } from "crypto";
5873
5878
  var closingBody = `
5874
5879
 
5875
5880
  ---
@@ -6077,7 +6082,7 @@ function generateChangedBlocksContent(filename, changedBlocks, newText) {
6077
6082
  `;
6078
6083
  for (const block of changedBlocks) {
6079
6084
  const newBlockText = newText.split("\n").slice(block.startLine, block.endLine).join("\n");
6080
- const blockSha256 = createHash2("sha256").update(newBlockText).digest("hex");
6085
+ const blockSha256 = createHash5("sha256").update(newBlockText).digest("hex");
6081
6086
  content += `**UUID:** \`${block.uuid}\`
6082
6087
  **sha256:** \`${blockSha256}\`
6083
6088
 
@@ -6110,7 +6115,7 @@ function generateRemovedBlocksContent(filename, removedBlocks, oldText) {
6110
6115
  `;
6111
6116
  for (const block of removedBlocks) {
6112
6117
  const oldBlockText = oldText.split("\n").slice(block.startLine, block.endLine).join("\n");
6113
- const blockSha256 = createHash2("sha256").update(oldBlockText).digest("hex");
6118
+ const blockSha256 = createHash5("sha256").update(oldBlockText).digest("hex");
6114
6119
  content += `**UUID:** \`${block.uuid}\`
6115
6120
  **sha256:** \`${blockSha256}\`
6116
6121