yamlover 0.3.14 → 0.3.21

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 (34) hide show
  1. package/README.md +11 -2
  2. package/dist/agent-docs/AGENTS.md +4 -2
  3. package/dist/builtin-taxonomy/$defs/board +7 -7
  4. package/dist/builtin-taxonomy/$defs/chapter +17 -11
  5. package/dist/builtin-taxonomy/$defs/chunk +5 -3
  6. package/dist/builtin-taxonomy/$defs/task +15 -16
  7. package/dist/builtin-taxonomy/$defs/workflow +1 -1
  8. package/dist/client/assets/decoded-CY5-anyl.js +1 -0
  9. package/dist/client/assets/djvu-CbL4_9ak.js +1 -0
  10. package/dist/client/assets/{docx-GVXp5L4P.js → docx-CCEuxO9n.js} +1 -1
  11. package/dist/client/assets/{heic-DbBlQvYf.js → heic-BvS6Unla.js} +2 -2
  12. package/dist/client/assets/imagemap-DBji1qL1.js +1 -0
  13. package/dist/client/assets/index-1sCxQdj3.css +1 -0
  14. package/dist/client/assets/index-DqdQvRi4.js +632 -0
  15. package/dist/client/assets/map-BfHrzAqt.js +1 -0
  16. package/dist/client/assets/openable-DIyqYrzm.js +4 -0
  17. package/dist/client/assets/{paged-WlIU9WQ1.js → paged-COP9CRTO.js} +1 -1
  18. package/dist/client/assets/{pdf-DHNv60yi.js → pdf-C-kvASQl.js} +9 -9
  19. package/dist/client/assets/psd-KxbPOIwA.js +11 -0
  20. package/dist/client/assets/{spreadsheet-SjJAxcQm.js → spreadsheet-DkG5umsc.js} +1 -1
  21. package/dist/client/assets/tiff-sq_Q9sNj.js +1 -0
  22. package/dist/client/index.html +2 -2
  23. package/dist/server.js +631 -205
  24. package/package.json +1 -1
  25. package/dist/client/assets/decoded-CA1l_3Ew.js +0 -1
  26. package/dist/client/assets/djvu-DrHEpWlg.js +0 -1
  27. package/dist/client/assets/imagemap-cqYX2ztK.js +0 -1
  28. package/dist/client/assets/index-B9oI2Pn6.css +0 -1
  29. package/dist/client/assets/index-BPmg78f6.js +0 -624
  30. package/dist/client/assets/map-v0EOTKqe.js +0 -1
  31. package/dist/client/assets/panzoom-ClH7Eo7o.js +0 -4
  32. package/dist/client/assets/psd-BW2r7SHQ.js +0 -11
  33. package/dist/client/assets/tiff-BMu2DrjN.js +0 -1
  34. /package/dist/client/assets/{panzoom-CIGW-MKW.css → openable-CIGW-MKW.css} +0 -0
package/dist/server.js CHANGED
@@ -62953,7 +62953,7 @@ import fs2 from "node:fs";
62953
62953
  import path2 from "node:path";
62954
62954
  import { setImmediate as yieldLoop } from "node:timers/promises";
62955
62955
 
62956
- // ../engine/ts/node_modules/xxhash-wasm/esm/xxhash-wasm.js
62956
+ // ../../node_modules/xxhash-wasm/esm/xxhash-wasm.js
62957
62957
  var t = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 48, 8, 96, 3, 127, 127, 127, 1, 127, 96, 3, 127, 127, 127, 0, 96, 2, 127, 127, 0, 96, 1, 127, 1, 127, 96, 3, 127, 127, 126, 1, 126, 96, 3, 126, 127, 127, 1, 126, 96, 2, 127, 126, 0, 96, 1, 127, 1, 126, 3, 11, 10, 0, 0, 2, 1, 3, 4, 5, 6, 1, 7, 5, 3, 1, 0, 1, 7, 85, 9, 3, 109, 101, 109, 2, 0, 5, 120, 120, 104, 51, 50, 0, 0, 6, 105, 110, 105, 116, 51, 50, 0, 2, 8, 117, 112, 100, 97, 116, 101, 51, 50, 0, 3, 8, 100, 105, 103, 101, 115, 116, 51, 50, 0, 4, 5, 120, 120, 104, 54, 52, 0, 5, 6, 105, 110, 105, 116, 54, 52, 0, 7, 8, 117, 112, 100, 97, 116, 101, 54, 52, 0, 8, 8, 100, 105, 103, 101, 115, 116, 54, 52, 0, 9, 10, 251, 22, 10, 242, 1, 1, 4, 127, 32, 0, 32, 1, 106, 33, 3, 32, 1, 65, 16, 79, 4, 127, 32, 3, 65, 16, 107, 33, 6, 32, 2, 65, 168, 136, 141, 161, 2, 106, 33, 3, 32, 2, 65, 137, 235, 208, 208, 7, 107, 33, 4, 32, 2, 65, 207, 140, 162, 142, 6, 106, 33, 5, 3, 64, 32, 3, 32, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 4, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 4, 32, 2, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 5, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 6, 32, 0, 65, 4, 106, 34, 0, 79, 13, 0, 11, 32, 2, 65, 12, 119, 32, 5, 65, 18, 119, 106, 32, 4, 65, 7, 119, 106, 32, 3, 65, 1, 119, 106, 5, 32, 2, 65, 177, 207, 217, 178, 1, 106, 11, 32, 1, 106, 32, 0, 32, 1, 65, 15, 113, 16, 1, 11, 146, 1, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 1, 65, 4, 106, 32, 2, 75, 69, 4, 64, 32, 0, 32, 1, 40, 2, 0, 65, 189, 220, 202, 149, 124, 108, 106, 65, 17, 119, 65, 175, 214, 211, 190, 2, 108, 33, 0, 32, 1, 65, 4, 106, 33, 1, 12, 1, 11, 11, 3, 64, 32, 1, 32, 2, 79, 69, 4, 64, 32, 0, 32, 1, 45, 0, 0, 65, 177, 207, 217, 178, 1, 108, 106, 65, 11, 119, 65, 177, 243, 221, 241, 121, 108, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 65, 15, 118, 115, 65, 247, 148, 175, 175, 120, 108, 34, 0, 65, 13, 118, 32, 0, 115, 65, 189, 220, 202, 149, 124, 108, 34, 0, 65, 16, 118, 32, 0, 115, 11, 63, 0, 32, 0, 65, 8, 106, 32, 1, 65, 168, 136, 141, 161, 2, 106, 54, 2, 0, 32, 0, 65, 12, 106, 32, 1, 65, 137, 235, 208, 208, 7, 107, 54, 2, 0, 32, 0, 65, 16, 106, 32, 1, 54, 2, 0, 32, 0, 65, 20, 106, 32, 1, 65, 207, 140, 162, 142, 6, 106, 54, 2, 0, 11, 195, 4, 1, 6, 127, 32, 1, 32, 2, 106, 33, 6, 32, 0, 65, 24, 106, 33, 4, 32, 0, 65, 40, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 40, 2, 0, 32, 2, 106, 54, 2, 0, 32, 0, 65, 4, 106, 34, 5, 32, 5, 40, 2, 0, 32, 2, 65, 16, 79, 32, 0, 40, 2, 0, 65, 16, 79, 114, 114, 54, 2, 0, 32, 2, 32, 3, 106, 65, 16, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 16, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 12, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 4, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 8, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 20, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 12, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 40, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 32, 6, 65, 16, 107, 77, 4, 64, 32, 6, 65, 16, 107, 33, 8, 32, 0, 65, 8, 106, 40, 2, 0, 33, 2, 32, 0, 65, 12, 106, 40, 2, 0, 33, 3, 32, 0, 65, 16, 106, 40, 2, 0, 33, 5, 32, 0, 65, 20, 106, 40, 2, 0, 33, 7, 3, 64, 32, 2, 32, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 3, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 5, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 7, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 7, 32, 8, 32, 1, 65, 4, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 2, 54, 2, 0, 32, 0, 65, 12, 106, 32, 3, 54, 2, 0, 32, 0, 65, 16, 106, 32, 5, 54, 2, 0, 32, 0, 65, 20, 106, 32, 7, 54, 2, 0, 11, 32, 1, 32, 6, 73, 4, 64, 32, 4, 32, 1, 32, 6, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 1, 54, 2, 0, 11, 11, 97, 1, 1, 127, 32, 0, 65, 16, 106, 40, 2, 0, 33, 1, 32, 0, 65, 4, 106, 40, 2, 0, 4, 127, 32, 1, 65, 12, 119, 32, 0, 65, 20, 106, 40, 2, 0, 65, 18, 119, 106, 32, 0, 65, 12, 106, 40, 2, 0, 65, 7, 119, 106, 32, 0, 65, 8, 106, 40, 2, 0, 65, 1, 119, 106, 5, 32, 1, 65, 177, 207, 217, 178, 1, 106, 11, 32, 0, 40, 2, 0, 106, 32, 0, 65, 24, 106, 32, 0, 65, 40, 106, 40, 2, 0, 16, 1, 11, 255, 3, 2, 3, 126, 1, 127, 32, 0, 32, 1, 106, 33, 6, 32, 1, 65, 32, 79, 4, 126, 32, 6, 65, 32, 107, 33, 6, 32, 2, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 33, 3, 32, 2, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 33, 4, 32, 2, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 33, 5, 3, 64, 32, 3, 32, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 3, 32, 4, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 4, 32, 2, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 2, 32, 5, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 5, 32, 6, 32, 0, 65, 8, 106, 34, 0, 79, 13, 0, 11, 32, 2, 66, 12, 137, 32, 5, 66, 18, 137, 124, 32, 4, 66, 7, 137, 124, 32, 3, 66, 1, 137, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 2, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 2, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 1, 173, 124, 32, 0, 32, 1, 65, 31, 113, 16, 6, 11, 134, 2, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 2, 32, 1, 65, 8, 106, 79, 4, 64, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 32, 0, 133, 66, 27, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 33, 0, 32, 1, 65, 8, 106, 33, 1, 12, 1, 11, 11, 32, 1, 65, 4, 106, 32, 2, 77, 4, 64, 32, 0, 32, 1, 53, 2, 0, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 23, 137, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 124, 33, 0, 32, 1, 65, 4, 106, 33, 1, 11, 3, 64, 32, 1, 32, 2, 73, 4, 64, 32, 0, 32, 1, 49, 0, 0, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 126, 133, 66, 11, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 66, 33, 136, 133, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 34, 0, 32, 0, 66, 29, 136, 133, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 126, 34, 0, 32, 0, 66, 32, 136, 133, 11, 77, 0, 32, 0, 65, 8, 106, 32, 1, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 55, 3, 0, 32, 0, 65, 16, 106, 32, 1, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 55, 3, 0, 32, 0, 65, 24, 106, 32, 1, 55, 3, 0, 32, 0, 65, 32, 106, 32, 1, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 55, 3, 0, 11, 244, 4, 2, 3, 127, 4, 126, 32, 1, 32, 2, 106, 33, 5, 32, 0, 65, 40, 106, 33, 4, 32, 0, 65, 200, 0, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 41, 3, 0, 32, 2, 173, 124, 55, 3, 0, 32, 2, 32, 3, 106, 65, 32, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 32, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 8, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 24, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 16, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 32, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 24, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 200, 0, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 65, 32, 106, 32, 5, 77, 4, 64, 32, 5, 65, 32, 107, 33, 2, 32, 0, 65, 8, 106, 41, 3, 0, 33, 6, 32, 0, 65, 16, 106, 41, 3, 0, 33, 7, 32, 0, 65, 24, 106, 41, 3, 0, 33, 8, 32, 0, 65, 32, 106, 41, 3, 0, 33, 9, 3, 64, 32, 6, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 6, 32, 7, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 7, 32, 8, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 8, 32, 9, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 9, 32, 2, 32, 1, 65, 8, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 6, 55, 3, 0, 32, 0, 65, 16, 106, 32, 7, 55, 3, 0, 32, 0, 65, 24, 106, 32, 8, 55, 3, 0, 32, 0, 65, 32, 106, 32, 9, 55, 3, 0, 11, 32, 1, 32, 5, 73, 4, 64, 32, 4, 32, 1, 32, 5, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 1, 54, 2, 0, 11, 11, 188, 2, 1, 5, 126, 32, 0, 65, 24, 106, 41, 3, 0, 33, 1, 32, 0, 41, 3, 0, 34, 2, 66, 32, 90, 4, 126, 32, 0, 65, 8, 106, 41, 3, 0, 34, 3, 66, 1, 137, 32, 0, 65, 16, 106, 41, 3, 0, 34, 4, 66, 7, 137, 124, 32, 1, 66, 12, 137, 32, 0, 65, 32, 106, 41, 3, 0, 34, 5, 66, 18, 137, 124, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 1, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 1, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 2, 124, 32, 0, 65, 40, 106, 32, 2, 66, 31, 131, 167, 16, 6, 11]);
62958
62958
  async function e() {
62959
62959
  return function(t3) {
@@ -63615,14 +63615,19 @@ var Block = class {
63615
63615
  return this.container(l2.indent);
63616
63616
  }
63617
63617
  this.i++;
63618
- let v = this.valueInline(
63619
- l2.text,
63620
- l2.indent,
63621
- /*allowBlock*/
63622
- true,
63623
- l2.n,
63624
- l2.indent
63625
- );
63618
+ let v;
63619
+ if (/^[|>][+-]?\d*$/.test(l2.text)) {
63620
+ v = this.blockScalar(l2.text, l2.indent, l2.n);
63621
+ } else {
63622
+ v = this.valueInline(
63623
+ l2.text,
63624
+ l2.indent,
63625
+ /*allowBlock*/
63626
+ true,
63627
+ l2.n,
63628
+ l2.indent
63629
+ );
63630
+ }
63626
63631
  const nxt = this.peek();
63627
63632
  if (nxt && nxt.indent === l2.indent && nxt.indent >= minIndent && !isPointer(v) && v.kind === "scalar") {
63628
63633
  v = this.mergeCont(v, this.container(l2.indent));
@@ -63642,6 +63647,7 @@ var Block = class {
63642
63647
  const entries = [];
63643
63648
  const anchors = [];
63644
63649
  let self2;
63650
+ let selfAt;
63645
63651
  for (; ; ) {
63646
63652
  const l2 = this.peek();
63647
63653
  if (!l2 || l2.indent !== indent) break;
@@ -63671,6 +63677,7 @@ var Block = class {
63671
63677
  if (isPointer(v) || v.kind !== "scalar") this.fail("only a scalar value may share a line with an own-line anchor");
63672
63678
  if (self2 !== void 0) this.fail("a node may carry at most one scalar value line");
63673
63679
  self2 = v;
63680
+ selfAt = entries.length;
63674
63681
  }
63675
63682
  continue;
63676
63683
  }
@@ -63706,17 +63713,24 @@ var Block = class {
63706
63713
  const kv = splitKV(l2.text);
63707
63714
  if (!kv) {
63708
63715
  this.i++;
63709
- const v = this.valueInline(
63710
- l2.text,
63711
- indent,
63712
- /*allowBlock*/
63713
- false,
63714
- l2.n,
63715
- l2.indent
63716
- );
63717
- if (isPointer(v) || v.kind !== "scalar") this.fail("unexpected content (expected an entry, an anchor, or a scalar value line)");
63716
+ let v;
63717
+ if (/^[|>][+-]?\d*$/.test(l2.text)) {
63718
+ v = this.blockScalar(l2.text, indent, l2.n);
63719
+ } else {
63720
+ const iv = this.valueInline(
63721
+ l2.text,
63722
+ indent,
63723
+ /*allowBlock*/
63724
+ false,
63725
+ l2.n,
63726
+ l2.indent
63727
+ );
63728
+ if (isPointer(iv) || iv.kind !== "scalar") this.fail("unexpected content (expected an entry, an anchor, or a scalar value line)");
63729
+ v = iv;
63730
+ }
63718
63731
  if (self2 !== void 0) this.fail("a node may carry at most one scalar value line");
63719
63732
  self2 = v;
63733
+ selfAt = entries.length;
63720
63734
  continue;
63721
63735
  }
63722
63736
  this.i++;
@@ -63738,6 +63752,7 @@ var Block = class {
63738
63752
  const owned = entries.filter((e3) => e3.edge !== "back");
63739
63753
  const array = owned.length > 0 && owned.every((e3) => e3.key === null);
63740
63754
  const node = self2 !== void 0 ? { ...self2, entries, array } : entries.length === 0 ? nul() : { kind: "mapping", entries, array };
63755
+ if (self2 !== void 0 && selfAt !== void 0 && selfAt > 0) node.meta = { ...node.meta, selfAt };
63741
63756
  this.attachAnchors(node, anchors);
63742
63757
  return node;
63743
63758
  }
@@ -64972,20 +64987,40 @@ function applySchemas(root, defsRoot, builtinDefs) {
64972
64987
  const s2 = inst.meta?.schema;
64973
64988
  return !!s2 && !isPointer(s2) && s2.kind === "mapping" && !!field(s2, "format");
64974
64989
  };
64990
+ const resolveSchema = (v) => {
64991
+ if (isPointer(v)) {
64992
+ const last = v.steps[v.steps.length - 1];
64993
+ const nm = last?.sel === "key" ? last.name : null;
64994
+ return { name: nm, node: nm ? loadDef(nm) : null };
64995
+ }
64996
+ return { name: null, node: v };
64997
+ };
64998
+ const isContainerSchema = (n2) => !!field(n2, "properties") || !!field(n2, "items") || !!field(n2, "allOf") || ["object", "variant", "mixed", "array"].includes(str(n2, "type") ?? "");
64999
+ const elemIsContainer = (el) => el.kind === "mapping";
65000
+ const applyItems = (inst, items, depth) => {
65001
+ const { node: itemsNode } = resolveSchema(items);
65002
+ const anyOf = itemsNode ? field(itemsNode, "anyOf") : null;
65003
+ const elems = (inst.entries ?? []).filter((e3) => e3.key == null && !isPointer(e3.value));
65004
+ if (anyOf && !isPointer(anyOf) && anyOf.entries) {
65005
+ const branches = anyOf.entries.map((e3) => e3.value).map((b) => ({ ptr: b, ...resolveSchema(b) }));
65006
+ for (const e3 of elems) {
65007
+ const want = elemIsContainer(e3.value);
65008
+ const pick = branches.find((b) => b.node && isContainerSchema(b.node) === want) ?? branches[0];
65009
+ if (pick) apply(e3.value, pick.ptr, depth + 1);
65010
+ }
65011
+ } else {
65012
+ for (const e3 of elems) apply(e3.value, items, depth + 1);
65013
+ }
65014
+ };
64975
65015
  const apply = (inst, schema, depth) => {
64976
65016
  if (depth > 64 || isPointer(inst)) return;
64977
- let name = null;
64978
- let s2;
64979
- if (isPointer(schema)) {
64980
- const last = schema.steps[schema.steps.length - 1];
64981
- name = last?.sel === "key" ? last.name : null;
64982
- s2 = name ? loadDef(name) : null;
64983
- } else s2 = schema;
65017
+ const { name, node: s2 } = resolveSchema(schema);
64984
65018
  if (!s2 || isPointer(s2)) return;
64985
- const fmt = str(s2, "format") ?? (name && str(s2, "type") === "object" ? `x-yamlover-${name}` : null);
64986
- if (fmt && !hasFormat(inst)) inst.meta = { ...inst.meta, schema: inlineFormat(fmt) };
64987
65019
  const stype = str(s2, "type");
64988
- if (stype === "object" || stype === "variant" || stype === "mixed") {
65020
+ const named = name && (stype === "object" || stype === "variant" || stype === "mixed" || !!field(s2, "allOf"));
65021
+ const fmt = str(s2, "format") ?? (named ? `x-yamlover-${name}` : null);
65022
+ if (fmt && !hasFormat(inst)) inst.meta = { ...inst.meta, schema: inlineFormat(fmt) };
65023
+ if (stype === "object" || stype === "variant" || stype === "mixed" || stype === "array" || field(s2, "items")) {
64989
65024
  const props = field(s2, "properties");
64990
65025
  const addl = field(s2, "additionalProperties");
64991
65026
  for (const e3 of inst.entries ?? []) {
@@ -64995,11 +65030,12 @@ function applySchemas(root, defsRoot, builtinDefs) {
64995
65030
  const sub = declared ?? addl;
64996
65031
  if (sub) apply(e3.value, sub, depth + 1);
64997
65032
  }
64998
- } else if (stype === "array") {
64999
65033
  const items = field(s2, "items");
65000
- if (items) {
65001
- for (const e3 of inst.entries ?? []) if (!isPointer(e3.value)) apply(e3.value, items, depth + 1);
65002
- }
65034
+ if (items) applyItems(inst, items, depth);
65035
+ }
65036
+ const allOf = field(s2, "allOf");
65037
+ if (allOf && !isPointer(allOf) && allOf.entries) {
65038
+ for (const b of allOf.entries) apply(inst, b.value, depth + 1);
65003
65039
  }
65004
65040
  };
65005
65041
  const walk = (node) => {
@@ -65033,16 +65069,23 @@ function applyBody(dir, node, ctx) {
65033
65069
  for (const e3 of node.entries) if (e3.key != null && byKey.has(e3.key)) ordered.push(e3);
65034
65070
  return { kind: "mapping", entries: ordered, array: true, meta };
65035
65071
  }
65036
- const merged = new Map(node.entries.map((e3) => [e3.key, e3]));
65037
- const order = node.entries.map((e3) => e3.key);
65072
+ const keyed = new Map(node.entries.filter((e3) => e3.key != null).map((e3) => [e3.key, e3]));
65073
+ const entries = [...node.entries];
65038
65074
  for (const e3 of bodyEntries) {
65039
- const existing = merged.get(e3.key);
65075
+ if (e3.key == null) {
65076
+ entries.push(e3);
65077
+ continue;
65078
+ }
65079
+ const existing = keyed.get(e3.key);
65040
65080
  if (!existing) {
65041
- order.push(e3.key);
65042
- merged.set(e3.key, e3);
65043
- } else merged.set(e3.key, augmentEntry(existing, e3));
65081
+ keyed.set(e3.key, e3);
65082
+ entries.push(e3);
65083
+ } else {
65084
+ const aug = augmentEntry(existing, e3);
65085
+ keyed.set(e3.key, aug);
65086
+ entries[entries.indexOf(existing)] = aug;
65087
+ }
65044
65088
  }
65045
- const entries = order.map((k) => merged.get(k));
65046
65089
  if (body.kind === "scalar") return { kind: "scalar", value: body.value, raw: body.raw, entries, array: false, meta };
65047
65090
  return { kind: "mapping", entries, array: false, meta };
65048
65091
  }
@@ -65513,8 +65556,7 @@ var DEFAULT_SETTINGS = {
65513
65556
  exports: [],
65514
65557
  annotations: ":annotations",
65515
65558
  tags: ":tags",
65516
- sidecars: "per-directory",
65517
- annotationTag: void 0
65559
+ sidecars: "per-directory"
65518
65560
  };
65519
65561
  var DEFAULT_SETTINGS_SOURCE = `# .yamlover/settings.yamlover \u2014 project settings for this root (created with defaults).
65520
65562
  # Settings are DEFAULTS, never constraints: they only say where the server CREATES things when you
@@ -65550,8 +65592,7 @@ function loadSettings(absRoot) {
65550
65592
  exports: exportsSetting(valueAt(root, "exports")),
65551
65593
  annotations: locationSetting(valueAt(root, "annotations"), DEFAULT_SETTINGS.annotations),
65552
65594
  tags: locationSetting(valueAt(root, "tags"), DEFAULT_SETTINGS.tags),
65553
- sidecars: sidecarLocation(valueAt(root, "sidecars"), DEFAULT_SETTINGS.sidecars),
65554
- annotationTag: locationSetting(valueAt(root, "annotation-tag"), void 0)
65595
+ sidecars: sidecarLocation(valueAt(root, "sidecars"), DEFAULT_SETTINGS.sidecars)
65555
65596
  };
65556
65597
  }
65557
65598
  function uriSetting(v) {
@@ -65572,17 +65613,6 @@ function exportsSetting(v) {
65572
65613
  }
65573
65614
  return out;
65574
65615
  }
65575
- function writeSettingKey(absRoot, key, valueText) {
65576
- const file = path6.join(absRoot, ".yamlover", "settings.yamlover");
65577
- const src = fs5.existsSync(file) ? fs5.readFileSync(file, "utf8") : "";
65578
- const line = `${key}: ${valueText}`;
65579
- const re = new RegExp("^" + key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ":.*$", "m");
65580
- let out = re.test(src) ? src.replace(re, line) : (src === "" || src.endsWith("\n") ? src : src + "\n") + line;
65581
- if (!out.endsWith("\n")) out += "\n";
65582
- fs5.mkdirSync(path6.dirname(file), { recursive: true });
65583
- fs5.writeFileSync(file, out);
65584
- return file;
65585
- }
65586
65616
  function sidecarLocation(v, dflt) {
65587
65617
  const s2 = v !== void 0 && !isPointer(v) && v.kind === "scalar" && typeof v.value === "string" ? v.value.trim() : "";
65588
65618
  if (s2 === "per-directory" || s2 === "document") return "per-directory";
@@ -66052,14 +66082,15 @@ function blockEnd(lines, from, hi, indent) {
66052
66082
  return trimBack(lines, last, hi);
66053
66083
  }
66054
66084
  function reachBody(lines, within) {
66055
- let lo = 0;
66056
- let hi = lines.length;
66057
- let indent = firstContentIndent(lines);
66085
+ let start = { lo: 0, hi: lines.length, indent: firstContentIndent(lines) };
66058
66086
  if (lines.length === 1 && lines[0] === "") {
66059
66087
  lines.length = 0;
66060
- hi = 0;
66061
- indent = 0;
66088
+ start = { lo: 0, hi: 0, indent: 0 };
66062
66089
  }
66090
+ return reachBodyAt(lines, start, within);
66091
+ }
66092
+ function reachBodyAt(lines, start, within) {
66093
+ let { lo, hi, indent } = start;
66063
66094
  for (const key of within) {
66064
66095
  const L2 = findKeyLine(lines, lo, hi, indent, key);
66065
66096
  if (L2 < 0) {
@@ -66110,7 +66141,10 @@ function seqItemLines(lines, region, key) {
66110
66141
  }
66111
66142
  function appendAnnotation(text, within, render) {
66112
66143
  const lines = text.replace(/\n$/, "").split("\n");
66113
- const region = reachBody(lines, within);
66144
+ appendAnnotationAt(lines, reachBody(lines, within), render);
66145
+ return lines.join("\n") + "\n";
66146
+ }
66147
+ function appendAnnotationAt(lines, region, render) {
66114
66148
  const seq = seqItemLines(lines, region, ANNOTATIONS_KEY);
66115
66149
  if (!seq) {
66116
66150
  const at = trimBack(lines, region.lo - 1, region.hi);
@@ -66118,11 +66152,13 @@ function appendAnnotation(text, within, render) {
66118
66152
  } else {
66119
66153
  lines.splice(seq.end, 0, ...render(region.indent));
66120
66154
  }
66121
- return lines.join("\n") + "\n";
66122
66155
  }
66123
66156
  function upsertMapEntry(text, within, mapKey, entryKey, render) {
66124
66157
  const lines = text.replace(/\n$/, "").split("\n");
66125
- const region = reachBody(lines, within);
66158
+ upsertMapEntryAt(lines, reachBody(lines, within), mapKey, entryKey, render);
66159
+ return lines.join("\n") + "\n";
66160
+ }
66161
+ function upsertMapEntryAt(lines, region, mapKey, entryKey, render) {
66126
66162
  let mapLine = findKeyLine(lines, region.lo, region.hi, region.indent, mapKey);
66127
66163
  if (mapLine < 0) {
66128
66164
  const at = trimBack(lines, region.lo - 1, region.hi);
@@ -66139,7 +66175,6 @@ function upsertMapEntry(text, within, mapKey, entryKey, render) {
66139
66175
  const at = trimBack(lines, mapLine, mapBody.hi);
66140
66176
  lines.splice(at, 0, ...render(mapIndent));
66141
66177
  }
66142
- return lines.join("\n") + "\n";
66143
66178
  }
66144
66179
  function upsertFragment(text, within, slug, render) {
66145
66180
  return upsertMapEntry(text, within, FRAGMENTS_KEY, slug, render);
@@ -66147,20 +66182,55 @@ function upsertFragment(text, within, slug, render) {
66147
66182
  function upsertThumbnail(text, within, resKey, render) {
66148
66183
  return upsertMapEntry(text, within, THUMBNAILS_KEY, resKey, render);
66149
66184
  }
66150
- function removeAnnotation(text, within, predicate) {
66185
+ function annotationsRemain(text, within) {
66151
66186
  const lines = text.replace(/\n$/, "").split("\n");
66152
- const region = reachBody(lines, within);
66187
+ return annotationsRemainAt(lines, reachBody(lines, within));
66188
+ }
66189
+ function annotationsRemainAt(lines, region) {
66153
66190
  const seq = seqItemLines(lines, region, ANNOTATIONS_KEY);
66154
- if (!seq) return text;
66155
- for (let k = 0; k < seq.items.length; k++) {
66191
+ return !!seq && seq.items.length > 0;
66192
+ }
66193
+ function removeMapEntry(text, within, mapKey, entryKey) {
66194
+ const lines = text.replace(/\n$/, "").split("\n");
66195
+ return removeMapEntryAt(lines, reachBody(lines, within), mapKey, entryKey) ? lines.join("\n") + "\n" : text;
66196
+ }
66197
+ function removeMapEntryAt(lines, region, mapKey, entryKey) {
66198
+ const mapLine = findKeyLine(lines, region.lo, region.hi, region.indent, mapKey);
66199
+ if (mapLine < 0) return false;
66200
+ const mapIndent = region.indent + 2;
66201
+ const mapHi = blockEnd(lines, mapLine + 1, lines.length, region.indent + 1);
66202
+ const entry = findKeyLine(lines, mapLine + 1, mapHi, mapIndent, entryKey);
66203
+ if (entry < 0) return false;
66204
+ const end = blockEnd(lines, entry + 1, mapHi, mapIndent + 1);
66205
+ lines.splice(entry, end - entry);
66206
+ const newHi = blockEnd(lines, mapLine + 1, lines.length, region.indent + 1);
66207
+ let hasChild = false;
66208
+ for (let i2 = mapLine + 1; i2 < newHi; i2++) {
66209
+ if (isContentLine(lines[i2]) && indentOf(lines[i2]) === mapIndent) {
66210
+ hasChild = true;
66211
+ break;
66212
+ }
66213
+ }
66214
+ if (!hasChild) lines.splice(mapLine, blockEnd(lines, mapLine + 1, lines.length, region.indent + 1) - mapLine);
66215
+ return true;
66216
+ }
66217
+ function removeAnnotation(text, within, predicate) {
66218
+ const lines = text.replace(/\n$/, "").split("\n");
66219
+ return removeAnnotationAt(lines, () => reachBody(lines, within), predicate) ? lines.join("\n") + "\n" : text;
66220
+ }
66221
+ function removeAnnotationAt(lines, region, predicate) {
66222
+ let removed = false;
66223
+ for (; ; ) {
66224
+ const seq = seqItemLines(lines, region(), ANNOTATIONS_KEY);
66225
+ if (!seq) break;
66226
+ const k = seq.items.findIndex((i3) => predicate(lines[i3].trim().replace(/^-\s*/, "")));
66227
+ if (k < 0) break;
66156
66228
  const i2 = seq.items[k];
66157
- const itemText = lines[i2].trim().replace(/^-\s*/, "");
66158
- if (!predicate(itemText)) continue;
66159
66229
  const next = k + 1 < seq.items.length ? seq.items[k + 1] : seq.end;
66160
66230
  lines.splice(i2, next - i2);
66161
- return lines.join("\n") + "\n";
66231
+ removed = true;
66162
66232
  }
66163
- return text;
66233
+ return removed;
66164
66234
  }
66165
66235
 
66166
66236
  // src/concrete.ts
@@ -66758,11 +66828,11 @@ function createHandlers(dataRoot, opts = {}) {
66758
66828
  readBody(req).then(
66759
66829
  (data) => enqueue(async () => {
66760
66830
  const b = data;
66761
- const cols = Array.isArray(b?.columns) ? b.columns.map((lane) => Array.isArray(lane) ? lane.map((p3) => String(p3)) : []) : [];
66831
+ const lanes = Array.isArray(b?.lanes) ? b.lanes.map((lane) => Array.isArray(lane) ? lane.map((p3) => String(p3)) : []) : [];
66762
66832
  const { bodyFile } = hostFor(dataRoot, s2, strToSegs(b?.path || ":"));
66763
66833
  fs10.mkdirSync(path10.dirname(bodyFile), { recursive: true });
66764
66834
  const src = fs10.existsSync(bodyFile) ? fs10.readFileSync(bodyFile, "utf8") : "";
66765
- fs10.writeFileSync(bodyFile, writeBoardColumns(src, cols));
66835
+ fs10.writeFileSync(bodyFile, writeBoardLanes(src, lanes));
66766
66836
  broadcast(await doReindex());
66767
66837
  scheduleHasher();
66768
66838
  return { ok: true };
@@ -66781,6 +66851,69 @@ function createHandlers(dataRoot, opts = {}) {
66781
66851
  ).then((result) => sendJson(res, 201, result)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66782
66852
  return;
66783
66853
  }
66854
+ if (req.method === "POST" && url.pathname === "/api/edit") {
66855
+ readBody(req).then(
66856
+ (data) => enqueue(async () => {
66857
+ const d = data;
66858
+ const edits = Array.isArray(d.edits) ? d.edits : [d];
66859
+ const touched = applyEdits2(dataRoot, s2, edits);
66860
+ for (const f2 of touched) broadcast(await doReindexFile(f2));
66861
+ scheduleHasher();
66862
+ return { ok: true };
66863
+ })
66864
+ ).then((body) => sendJson(res, 200, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66865
+ return;
66866
+ }
66867
+ if (req.method === "POST" && url.pathname === "/api/create") {
66868
+ readBody(req).then(
66869
+ (data) => enqueue(async () => {
66870
+ const b = data;
66871
+ const reg = CREATABLE[String(b.schema ?? "")];
66872
+ if (!reg) throw new Error(`unknown schema: ${b.schema}`);
66873
+ const concrete = String(b.concrete ?? "");
66874
+ const parentSegs = strToSegs(b.parent ?? ":");
66875
+ const row2 = s2.node(storePath(parentSegs));
66876
+ if (!row2) throw new Error(`no such node: ${b.parent}`);
66877
+ const title = String(b.title ?? "").trim() || defaultTitle(String(b.schema));
66878
+ const body = reg.body(title);
66879
+ const objSrc = objectFileSource(reg.tag, body);
66880
+ if (reg.childOf.includes(row2.format ?? "")) {
66881
+ const { docSegs, bodyFile, dirBacked } = chapterSource(dataRoot, s2, parentSegs);
66882
+ const within = parentSegs.slice(docSegs.length);
66883
+ if (concrete === "yamlover") {
66884
+ const src = fs10.readFileSync(bodyFile, "utf8");
66885
+ fs10.writeFileSync(bodyFile, appendBody(src, within, (indent) => inlineChildLines(body, indent)));
66886
+ broadcast(await doReindexFile(bodyFile));
66887
+ scheduleHasher();
66888
+ return { path: lastBodyChildPath(s2, parentSegs) };
66889
+ }
66890
+ if (concrete === "file/yamlover" || concrete === "dir/yamlover") {
66891
+ const writeDirSegs = dirBacked ? docSegs : docSegs.slice(0, -1);
66892
+ const writeDir = path10.resolve(dataRoot, ...writeDirSegs.map(String));
66893
+ const final = writeObject(dataRoot, writeDir, sanitizeName(title), concrete, objSrc);
66894
+ const targetSegs = [...writeDirSegs, final];
66895
+ const pointer = dirBacked ? `*/${final}` : `*/${segsToStr(targetSegs)}`;
66896
+ const src = fs10.readFileSync(bodyFile, "utf8");
66897
+ fs10.writeFileSync(bodyFile, appendBody(src, within, (indent) => [`${" ".repeat(indent)}- ${pointer}`]));
66898
+ broadcast(await doReindex());
66899
+ scheduleHasher();
66900
+ return { path: segsToStr(targetSegs) };
66901
+ }
66902
+ throw new Error(`invalid concrete for a child: ${concrete}`);
66903
+ }
66904
+ const abs = path10.resolve(dataRoot, ...parentSegs.map(String));
66905
+ if (parentSegs.every((g) => typeof g === "string") && fs10.existsSync(abs) && fs10.statSync(abs).isDirectory()) {
66906
+ if (concrete !== "file/yamlover" && concrete !== "dir/yamlover") throw new Error(`invalid concrete for a directory member: ${concrete}`);
66907
+ const final = writeObject(dataRoot, abs, objectBaseName(title), concrete, objSrc);
66908
+ broadcast(await doReindex());
66909
+ scheduleHasher();
66910
+ return { path: segsToStr([...parentSegs, final]) };
66911
+ }
66912
+ throw new Error("this schema can be created only inside a directory or a compatible parent");
66913
+ })
66914
+ ).then((body) => sendJson(res, 201, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66915
+ return;
66916
+ }
66784
66917
  if (req.method === "POST" && url.pathname === "/api/mv") {
66785
66918
  readBody(req).then(
66786
66919
  (data) => enqueue(async () => {
@@ -66800,28 +66933,25 @@ function createHandlers(dataRoot, opts = {}) {
66800
66933
  return;
66801
66934
  }
66802
66935
  if (req.method === "POST" && url.pathname === "/api/agent-docs") {
66803
- readBody(req).then(
66804
- (data) => enqueue(async () => {
66805
- const overwrite = !!data?.overwrite;
66806
- const files = [];
66807
- let wrote = false;
66808
- for (const doc of loadAgentDocs()) {
66809
- const exists = fs10.existsSync(path10.resolve(dataRoot, doc.name));
66810
- if (exists && !overwrite) {
66811
- files.push({ name: doc.name, status: "exists" });
66812
- continue;
66813
- }
66814
- writeInside(dataRoot, dataRoot, doc.name, Buffer.from(doc.content, "utf8"));
66815
- files.push({ name: doc.name, status: exists ? "overwritten" : "created" });
66936
+ enqueue(async () => {
66937
+ const files = [];
66938
+ let wrote = false;
66939
+ for (const doc of loadAgentDocs()) {
66940
+ const target = path10.resolve(dataRoot, doc.name);
66941
+ const existing = fs10.existsSync(target) ? fs10.readFileSync(target, "utf8") : null;
66942
+ const { text, status } = mergeAgentDoc(existing, doc.content);
66943
+ if (status !== "exists") {
66944
+ writeInside(dataRoot, dataRoot, doc.name, Buffer.from(text, "utf8"));
66816
66945
  wrote = true;
66817
66946
  }
66818
- if (wrote) {
66819
- broadcast(await doReindex());
66820
- scheduleHasher();
66821
- }
66822
- return { files };
66823
- })
66824
- ).then((body) => sendJson(res, 201, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66947
+ files.push({ name: doc.name, status });
66948
+ }
66949
+ if (wrote) {
66950
+ broadcast(await doReindex());
66951
+ scheduleHasher();
66952
+ }
66953
+ return { files };
66954
+ }).then((body) => sendJson(res, 201, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66825
66955
  return;
66826
66956
  }
66827
66957
  if (req.method !== "POST" && url.pathname === "/api/config") {
@@ -66843,21 +66973,6 @@ function createHandlers(dataRoot, opts = {}) {
66843
66973
  ).then((body) => sendJson(res, 200, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66844
66974
  return;
66845
66975
  }
66846
- if (req.method === "POST" && url.pathname === "/api/last-tag") {
66847
- readBody(req).then(
66848
- (data) => enqueue(async () => {
66849
- const tag = String(data?.tag ?? "").trim();
66850
- if (!tag) throw new Error("last-tag needs a `tag` path");
66851
- const segs2 = strToSegs(tag);
66852
- if (segs2.length === 0 || segs2.some((g) => typeof g === "number")) throw new Error(`not a tag node path: ${tag}`);
66853
- writeSettingKey(dataRoot, "annotation-tag", "*:: " + segs2.map((s3) => colonSegment(String(s3))).join(": "));
66854
- settings = loadSettings(dataRoot);
66855
- announce({ changed: [relFileOf(":.yamlover:settings.yamlover")] });
66856
- return { ok: true, annotationTag: settings.annotationTag };
66857
- })
66858
- ).then((body) => sendJson(res, 200, body)).catch((e3) => sendJson(res, 400, { error: String(e3.message || e3) }));
66859
- return;
66860
- }
66861
66976
  const segs = strToSegs(url.searchParams.get("path") || ":");
66862
66977
  const p2 = storePath(segs);
66863
66978
  const depth = parseDepth(url.searchParams.get("depth"));
@@ -66925,6 +67040,15 @@ function createHandlers(dataRoot, opts = {}) {
66925
67040
  const viewDepth = depth === void 0 ? defaultDepth(s2, dataRoot, segs, row, kind) : depth;
66926
67041
  if (url.pathname === "/api/json") {
66927
67042
  const wantBytes = row.type === "blob" && url.searchParams.get("binary") === "1";
67043
+ let value;
67044
+ if (!wantBytes) value = projectValue(dataRoot, s2, segs, viewDepth, true);
67045
+ else if (kind !== "omni") value = binaryContent(dataRoot, segs, row);
67046
+ else {
67047
+ const projected = projectValue(dataRoot, s2, segs, viewDepth, true);
67048
+ const marker = projected[MIXED_KEY];
67049
+ if (marker) marker.value = binaryContent(dataRoot, segs, row);
67050
+ value = projected;
67051
+ }
66928
67052
  sendJson(res, 200, {
66929
67053
  path: segsToStr(segs),
66930
67054
  type: tocType(s2, p2, row),
@@ -66936,8 +67060,8 @@ function createHandlers(dataRoot, opts = {}) {
66936
67060
  documentPath: documentPath(s2, segs),
66937
67061
  // nearest enclosing document root (for `/…` links)
66938
67062
  title: titleOf(s2, p2),
66939
- description: null,
66940
- value: wantBytes ? binaryContent(dataRoot, segs, row) : projectValue(dataRoot, s2, segs, viewDepth, true),
67063
+ description: descriptionOf(s2, p2),
67064
+ value,
66941
67065
  comments: cachedDoc && !wantBytes ? collectComments(cachedDoc, segs, viewDepth) : {},
66942
67066
  relations: buildRelations(dataRoot, s2, segs)
66943
67067
  });
@@ -66984,7 +67108,17 @@ function concreteOf(s2, dataRoot, segs, row) {
66984
67108
  }
66985
67109
  var relKey = (label, other) => `${label ?? ""}\0${other}`;
66986
67110
  var isHidden = (s2, to2) => !!s2.node(to2)?.meta?.hidden;
67111
+ var inHiddenSubtree = (s2, p2) => {
67112
+ for (let segs = storePathToSegs(p2); segs.length; segs = segs.slice(0, -1))
67113
+ if (isHidden(s2, storePath(segs))) return true;
67114
+ return false;
67115
+ };
66987
67116
  var visibleHasChildren = (s2, p2) => s2.children(p2).some((c3) => !isHidden(s2, c3.to));
67117
+ var hasSubchapterChild = (s2, p2) => s2.children(p2).some((c3) => {
67118
+ if (isHidden(s2, c3.to)) return false;
67119
+ const f2 = s2.node(c3.to)?.format;
67120
+ return f2 === "x-yamlover-chapter" || f2 === "x-yamlover-task";
67121
+ });
66988
67122
  function downstreamEntries(s2, p2) {
66989
67123
  const isSet = !!s2.node(p2)?.meta?.set;
66990
67124
  let own = s2.entries(p2).filter((e3) => e3.kind !== "back" && !(e3.kind === "contain" && isHidden(s2, e3.to)));
@@ -67028,7 +67162,10 @@ function projectValue(dataRoot, s2, segs, depth, top) {
67028
67162
  if (k === "omni" || k === "mix") {
67029
67163
  const entries = kids.map((c3) => ({ key: c3.label, value: project(c3) }));
67030
67164
  const marker = { kind: k, entries };
67031
- if (k === "omni") marker.value = wireScalar(row.value);
67165
+ if (k === "omni") {
67166
+ marker.value = row.type === "blob" ? binaryValueMarker(segs, row) : wireScalar(row.value);
67167
+ if (typeof row.meta?.selfAt === "number") marker.selfAt = row.meta.selfAt;
67168
+ }
67032
67169
  return { [MIXED_KEY]: marker };
67033
67170
  }
67034
67171
  if (k === "object") {
@@ -67056,11 +67193,7 @@ function irNodeAt(doc, segs) {
67056
67193
  return node;
67057
67194
  }
67058
67195
  function tagOf(n2) {
67059
- if (n2.meta?.set) return "!!set";
67060
- const owned = (n2.entries ?? []).filter((e3) => e3.edge !== "back");
67061
- if (n2.kind === "mapping" && owned.some((e3) => e3.key != null) && owned.some((e3) => e3.key === null)) return "!!mix";
67062
- if (n2.kind === "scalar" && owned.length > 0) return "!!var";
67063
- return void 0;
67196
+ return n2.meta?.set ? "!!set" : void 0;
67064
67197
  }
67065
67198
  function nodeDeco(bucket, node) {
67066
67199
  const anchors = (node.meta?.anchors ?? []).map(anchorBody);
@@ -67154,6 +67287,10 @@ function linkMarker(dataRoot, s2, segs) {
67154
67287
  const c3 = s2.node(p2 + ":color")?.value;
67155
67288
  if (typeof c3 === "string") info.color = c3;
67156
67289
  }
67290
+ if (row.format === FRAGMENT_FORMAT) {
67291
+ const imgEdge = s2.relationships(p2).out.find((o2) => o2.kind === "ref" && o2.label === "image");
67292
+ if (imgEdge) info.preview = segsToStr(storePathToSegs(imgEdge.to));
67293
+ }
67157
67294
  return { [LINK_KEY]: info };
67158
67295
  }
67159
67296
  var segsEqual = (a2, b) => a2.length === b.length && a2.every((x2, i2) => x2 === b[i2]);
@@ -67208,11 +67345,13 @@ function buildTree(dataRoot, s2, segs, label, depth) {
67208
67345
  format: row.format ?? null,
67209
67346
  ...facetsOf(s2, p2, row),
67210
67347
  concrete: concreteOf(s2, dataRoot, segs, row),
67211
- hasChildren: visibleHasChildren(s2, p2),
67348
+ // a CHAPTER's TOC entry expands to its SUBCHAPTERS only; count those, so a chunks-only chapter
67349
+ // is a leaf. Any other node reports the generic "has a visible child".
67350
+ hasChildren: row.format === "x-yamlover-chapter" || row.format === "x-yamlover-task" ? hasSubchapterChild(s2, p2) : visibleHasChildren(s2, p2),
67212
67351
  children: []
67213
67352
  };
67214
67353
  if (node.hasChildren && depth > 0) {
67215
- for (const c3 of s2.children(p2)) {
67354
+ for (const c3 of chapterOrderedChildren(s2, p2, row.format ?? null)) {
67216
67355
  if (isHidden(s2, c3.to)) continue;
67217
67356
  const seg = c3.label ?? c3.pos ?? 0;
67218
67357
  node.children.push(buildTree(dataRoot, s2, [...segs, seg], labelFor(s2, c3.to, seg), depth - 1));
@@ -67220,12 +67359,22 @@ function buildTree(dataRoot, s2, segs, label, depth) {
67220
67359
  }
67221
67360
  return node;
67222
67361
  }
67362
+ function chapterOrderedChildren(s2, p2, format) {
67363
+ const kids = s2.children(p2);
67364
+ if (format !== "x-yamlover-chapter" && format !== "x-yamlover-task") return kids;
67365
+ const bodyPos = /* @__PURE__ */ new Map();
67366
+ for (const e3 of s2.entries(p2)) if (e3.kind === "ref" && !bodyPos.has(e3.to)) bodyPos.set(e3.to, e3.pos ?? 0);
67367
+ if (bodyPos.size === 0) return kids;
67368
+ const key = (c3) => bodyPos.get(c3.to) ?? c3.pos ?? 0;
67369
+ return kids.map((c3, i2) => ({ c: c3, i: i2 })).sort((a2, b) => key(a2.c) - key(b.c) || a2.i - b.i).map((x2) => x2.c);
67370
+ }
67223
67371
  function labelFor(s2, p2, keyOrIdx) {
67224
67372
  const t3 = titleOf(s2, p2);
67225
67373
  if (t3) return t3;
67226
67374
  return typeof keyOrIdx === "number" ? `[${keyOrIdx}]` : keyOrIdx;
67227
67375
  }
67228
67376
  var TAG_FORMAT = "x-yamlover-tag";
67377
+ var FRAGMENT_FORMAT = "x-yamlover-fragment";
67229
67378
  var ANN_KEY = "yamlover-annotations";
67230
67379
  var FRAG_KEY = "yamlover-fragments";
67231
67380
  var CROP_SUBDIR = "fragments";
@@ -67280,11 +67429,18 @@ function readFragments(s2, hostStore) {
67280
67429
  function annotationsFor(dataRoot, s2, segs) {
67281
67430
  const p2 = storePath(segs);
67282
67431
  const out = [];
67283
- for (const a2 of readAnnotations(s2, p2)) out.push({ ...a2 });
67284
- for (const f2 of readFragments(s2, p2)) {
67285
- for (const a2 of readAnnotations(s2, f2.node)) {
67286
- out.push({ ...a2, selector: f2.selector, fragmentSlug: f2.slug, ...f2.imageUrl ? { imageUrl: f2.imageUrl } : {} });
67432
+ const gather = (hostStore, nodeClient) => {
67433
+ for (const a2 of readAnnotations(s2, hostStore)) out.push({ ...a2, node: nodeClient });
67434
+ for (const f2 of readFragments(s2, hostStore)) {
67435
+ for (const a2 of readAnnotations(s2, f2.node)) {
67436
+ out.push({ ...a2, node: nodeClient, selector: f2.selector, fragmentSlug: f2.slug, ...f2.imageUrl ? { imageUrl: f2.imageUrl } : {} });
67437
+ }
67287
67438
  }
67439
+ };
67440
+ gather(p2, segsToStr(segs));
67441
+ for (const c3 of s2.children(p2)) {
67442
+ if (isHidden(s2, c3.to)) continue;
67443
+ gather(c3.to, segsToStr(storePathToSegs(c3.to)));
67288
67444
  }
67289
67445
  return out;
67290
67446
  }
@@ -67295,7 +67451,7 @@ function taggedMaterials(dataRoot, s2, tagStorePath) {
67295
67451
  for (const e3 of ins) {
67296
67452
  const arrOwner = e3.from.replace(/\[\d+\]$/, "").match(/^(.*):yamlover-annotations$/);
67297
67453
  const owner = arrOwner ? arrOwner[1] || ":" : e3.from;
67298
- if (owner === tagStorePath || seen.has(owner) || !s2.node(owner)) continue;
67454
+ if (owner === tagStorePath || seen.has(owner) || !s2.node(owner) || inHiddenSubtree(s2, owner)) continue;
67299
67455
  seen.add(owner);
67300
67456
  out.push(linkMarker(dataRoot, s2, storePathToSegs(owner)));
67301
67457
  }
@@ -67308,12 +67464,12 @@ function pointerRaw(clientPath) {
67308
67464
  }
67309
67465
  return "::" + out;
67310
67466
  }
67311
- function writeBoardColumns(src, cols) {
67467
+ function writeBoardLanes(src, lanes) {
67312
67468
  const laneLine = (lane) => `- [${lane.map((p2) => pointerToken(pointerRaw(p2))).join(", ")}]`;
67313
- const block = cols.length === 0 ? ["columns: []"] : ["columns:", ...cols.map(laneLine)];
67469
+ const block = lanes.length === 0 ? ["lanes: []"] : ["lanes:", ...lanes.map(laneLine)];
67314
67470
  let lines = src.replace(/\n+$/, "").split("\n");
67315
67471
  if (src.trim() === "") lines = ["!!<*yamlover:$defs:board>"];
67316
- const start = lines.findIndex((l2) => /^columns:/.test(l2));
67472
+ const start = lines.findIndex((l2) => /^lanes:/.test(l2));
67317
67473
  if (start >= 0) {
67318
67474
  let end = start + 1;
67319
67475
  while (end < lines.length && (lines[end] === "" || /^[ \t-]/.test(lines[end]))) end++;
@@ -67378,7 +67534,22 @@ function fragmentBlockLines(slug, selector, imagePtr, indent) {
67378
67534
  return lines;
67379
67535
  }
67380
67536
  function embedAnnotation(dataRoot, s2, a2) {
67381
- const { bodyFile, within } = hostFor(dataRoot, s2, strToSegs(a2.target || ":"));
67537
+ const segs = strToSegs(a2.target || ":");
67538
+ if (isChunkTarget(s2, segs)) {
67539
+ const { docSegs, bodyFile: bodyFile2 } = chapterSource(dataRoot, s2, segs);
67540
+ const { indices, keys } = splitChunkWithin(segs.slice(docSegs.length));
67541
+ const lines = fs10.readFileSync(bodyFile2, "utf8").replace(/\n$/, "").split("\n");
67542
+ const region = reachBodyAt(lines, chunkFieldRegion(
67543
+ lines,
67544
+ indices,
67545
+ /*ensureOmni*/
67546
+ true
67547
+ ), keys);
67548
+ appendAnnotationAt(lines, region, (indent) => annotationItemLines(a2, indent));
67549
+ fs10.writeFileSync(bodyFile2, lines.join("\n") + "\n");
67550
+ return bodyFile2;
67551
+ }
67552
+ const { bodyFile, within } = hostFor(dataRoot, s2, segs);
67382
67553
  fs10.mkdirSync(path10.dirname(bodyFile), { recursive: true });
67383
67554
  const src = fs10.existsSync(bodyFile) ? fs10.readFileSync(bodyFile, "utf8") : "";
67384
67555
  fs10.writeFileSync(bodyFile, appendAnnotation(src, within, (indent) => annotationItemLines(a2, indent)));
@@ -67386,8 +67557,24 @@ function embedAnnotation(dataRoot, s2, a2) {
67386
67557
  }
67387
67558
  function embedFragment(dataRoot, s2, mode, f2) {
67388
67559
  const segs = strToSegs(f2.target || ":");
67389
- const { bodyFile, within } = hostFor(dataRoot, s2, segs);
67390
67560
  const slug = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
67561
+ if (isChunkTarget(s2, segs)) {
67562
+ const { docSegs, bodyFile: bodyFile2 } = chapterSource(dataRoot, s2, segs);
67563
+ const { indices, keys } = splitChunkWithin(segs.slice(docSegs.length));
67564
+ if (keys.length) throw new Error("a fragment target must be the chunk itself");
67565
+ const lines = fs10.readFileSync(bodyFile2, "utf8").replace(/\n$/, "").split("\n");
67566
+ assertProseChunk(lines, indices);
67567
+ const region = chunkFieldRegion(
67568
+ lines,
67569
+ indices,
67570
+ /*ensureOmni*/
67571
+ true
67572
+ );
67573
+ upsertMapEntryAt(lines, region, FRAG_KEY, slug, (indent) => fragmentBlockLines(slug, f2.selector, null, indent));
67574
+ fs10.writeFileSync(bodyFile2, lines.join("\n") + "\n");
67575
+ return { slug, fragmentPath: segsToStr([...segs, FRAG_KEY, slug]) };
67576
+ }
67577
+ const { bodyFile, within } = hostFor(dataRoot, s2, segs);
67391
67578
  let imagePtr = null;
67392
67579
  if (f2.imageBase64) {
67393
67580
  const bytes = Buffer.from(String(f2.imageBase64).replace(/^data:[^,]*,/, ""), "base64");
@@ -67438,11 +67625,34 @@ async function ensureThumbnail(dataRoot, s2, mode, segs, row, w, h) {
67438
67625
  return abs;
67439
67626
  }
67440
67627
  function unembedAnnotation(dataRoot, s2, target, tag) {
67441
- const { bodyFile, within } = hostFor(dataRoot, s2, strToSegs(target || ":"));
67628
+ const segs = strToSegs(target || ":");
67629
+ const needle = (":" + pointerRaw(tag).replace(/^:+/, "")).replace(/\s+/g, "");
67630
+ if (isChunkTarget(s2, segs)) {
67631
+ const { docSegs, bodyFile: bodyFile2 } = chapterSource(dataRoot, s2, segs);
67632
+ if (!fs10.existsSync(bodyFile2)) return bodyFile2;
67633
+ const { indices, keys } = splitChunkWithin(segs.slice(docSegs.length));
67634
+ const lines = fs10.readFileSync(bodyFile2, "utf8").replace(/\n$/, "").split("\n");
67635
+ const fragRegion = () => reachBodyAt(lines, chunkFieldRegion(
67636
+ lines,
67637
+ indices,
67638
+ /*ensureOmni*/
67639
+ false
67640
+ ), keys);
67641
+ removeAnnotationAt(lines, fragRegion, (t3) => t3.replace(/\s+/g, "").includes(needle));
67642
+ if (keys.length >= 2 && keys[keys.length - 2] === FRAG_KEY && !annotationsRemainAt(lines, fragRegion())) {
67643
+ removeMapEntryAt(lines, reachBodyAt(lines, chunkFieldRegion(lines, indices, false), keys.slice(0, -2)), FRAG_KEY, keys[keys.length - 1]);
67644
+ collapseChunkOmni(lines, indices);
67645
+ }
67646
+ fs10.writeFileSync(bodyFile2, lines.join("\n") + "\n");
67647
+ return bodyFile2;
67648
+ }
67649
+ const { bodyFile, within } = hostFor(dataRoot, s2, segs);
67442
67650
  if (!fs10.existsSync(bodyFile)) return bodyFile;
67443
- const needlePath = ":" + pointerRaw(tag).replace(/^:+/, "");
67444
- const src = fs10.readFileSync(bodyFile, "utf8");
67445
- fs10.writeFileSync(bodyFile, removeAnnotation(src, within, (itemText) => itemText.replace(/\s+/g, "").includes(needlePath)));
67651
+ let src = removeAnnotation(fs10.readFileSync(bodyFile, "utf8"), within, (itemText) => itemText.replace(/\s+/g, "").includes(needle));
67652
+ if (within.length >= 2 && within[within.length - 2] === FRAG_KEY && !annotationsRemain(src, within)) {
67653
+ src = removeMapEntry(src, within.slice(0, -2), FRAG_KEY, within[within.length - 1]);
67654
+ }
67655
+ fs10.writeFileSync(bodyFile, src);
67446
67656
  return bodyFile;
67447
67657
  }
67448
67658
  function writeTag(dataRoot, location, name) {
@@ -67520,14 +67730,14 @@ function pasteIntoChapter(dataRoot, s2, segs, name, bytes) {
67520
67730
  const pointer = dirBacked ? `*/${final}` : `*/${segsToStr(fileSegs)}`;
67521
67731
  const within = segs.slice(docSegs.length);
67522
67732
  const src = fs10.readFileSync(bodyFile, "utf8");
67523
- fs10.writeFileSync(bodyFile, appendToList(src, within, "chunks", (indent) => [`${" ".repeat(indent)}- ${pointer}`]));
67733
+ fs10.writeFileSync(bodyFile, appendBody(src, within, (indent) => [`${" ".repeat(indent)}- ${pointer}`]));
67524
67734
  return { path: segsToStr(fileSegs), chapter: segsToStr(segs), pointer };
67525
67735
  }
67526
67736
  function pasteTextIntoChapter(dataRoot, s2, segs, text) {
67527
67737
  const { docSegs, bodyFile } = chapterSource(dataRoot, s2, segs);
67528
67738
  const within = segs.slice(docSegs.length);
67529
67739
  const src = fs10.readFileSync(bodyFile, "utf8");
67530
- fs10.writeFileSync(bodyFile, appendToList(src, within, "chunks", (indent) => textChunkLines(text, indent)));
67740
+ fs10.writeFileSync(bodyFile, appendBody(src, within, (indent) => textChunkLines(text, indent)));
67531
67741
  return { path: segsToStr(segs), chapter: segsToStr(segs) };
67532
67742
  }
67533
67743
  function pasteTextAsChapterFile(dataRoot, segs, text) {
@@ -67536,7 +67746,7 @@ function pasteTextAsChapterFile(dataRoot, segs, text) {
67536
67746
  const dir = path10.resolve(dataRoot, ...dirSegs.map(String));
67537
67747
  const title = titleFromText(text);
67538
67748
  const final = uniqueName(dir, chapterFileName(title));
67539
- const src = ["!!<*::yamlover:$defs:chapter>", `title: ${JSON.stringify(title)}`, "chunks:", ...textChunkLines(text, 0), ""].join("\n");
67749
+ const src = ["!!<*::yamlover:$defs:chapter>", `title: ${JSON.stringify(title)}`, ...textChunkLines(text, 0), ""].join("\n");
67540
67750
  writeInside(dataRoot, dir, final, Buffer.from(src, "utf8"));
67541
67751
  return { path: segsToStr([...dirSegs, final]), dir: segsToStr(dirSegs), open: dirSegs.length !== segs.length };
67542
67752
  }
@@ -67573,10 +67783,16 @@ function richItemLines(item, indent, pointerFor) {
67573
67783
  function richChildLines(node, indent, pointerFor) {
67574
67784
  const pad = " ".repeat(indent);
67575
67785
  const lines = [`${pad}- title: ${JSON.stringify(node.title)}`];
67576
- if (node.chunks.length) lines.push(`${pad} chunks:`, ...node.chunks.flatMap((c3) => richItemLines(c3, indent + 2, pointerFor)));
67577
- if (node.children.length) lines.push(`${pad} children:`, ...node.children.flatMap((k) => richChildLines(k, indent + 2, pointerFor)));
67786
+ for (const c3 of node.chunks) lines.push(...richItemLines(c3, indent + 2, pointerFor));
67787
+ for (const k of node.children) lines.push(...richChildLines(k, indent + 2, pointerFor));
67578
67788
  return lines;
67579
67789
  }
67790
+ function richBodyLines(rich, indent, pointerFor) {
67791
+ return [
67792
+ ...rich.chunks.flatMap((c3) => richItemLines(c3, indent, pointerFor)),
67793
+ ...rich.children.flatMap((k) => richChildLines(k, indent, pointerFor))
67794
+ ];
67795
+ }
67580
67796
  function pasteRichIntoChapter(dataRoot, s2, segs, rich) {
67581
67797
  const { docSegs, bodyFile, dirBacked } = chapterSource(dataRoot, s2, segs);
67582
67798
  const writeDirSegs = dirBacked ? docSegs : docSegs.slice(0, -1);
@@ -67590,8 +67806,7 @@ function pasteRichIntoChapter(dataRoot, s2, segs, rich) {
67590
67806
  };
67591
67807
  const within = segs.slice(docSegs.length);
67592
67808
  let src = fs10.readFileSync(bodyFile, "utf8");
67593
- if (rich.chunks.length) src = appendToList(src, within, "chunks", (ind) => rich.chunks.flatMap((c3) => richItemLines(c3, ind, pointerFor)));
67594
- if (rich.children.length) src = appendToList(src, within, "children", (ind) => rich.children.flatMap((k) => richChildLines(k, ind, pointerFor)));
67809
+ if (rich.chunks.length || rich.children.length) src = appendBody(src, within, (ind) => richBodyLines(rich, ind, pointerFor));
67595
67810
  fs10.writeFileSync(bodyFile, src);
67596
67811
  return { path: segsToStr(segs), chapter: segsToStr(segs), files };
67597
67812
  }
@@ -67624,9 +67839,7 @@ function pasteRichAsChapter(dataRoot, segs, rich) {
67624
67839
  return { path: segsToStr([...dirSegs, name]), dir: segsToStr(dirSegs), open: dirSegs.length !== segs.length };
67625
67840
  }
67626
67841
  function renderChapterSource(title, rich, pointerFor) {
67627
- const lines = ["!!<*::yamlover:$defs:chapter>", `title: ${JSON.stringify(title)}`];
67628
- if (rich.chunks.length) lines.push("chunks:", ...rich.chunks.flatMap((c3) => richItemLines(c3, 0, pointerFor)));
67629
- if (rich.children.length) lines.push("children:", ...rich.children.flatMap((k) => richChildLines(k, 0, pointerFor)));
67842
+ const lines = ["!!<*::yamlover:$defs:chapter>", `title: ${JSON.stringify(title)}`, ...richBodyLines(rich, 0, pointerFor)];
67630
67843
  return lines.join("\n") + "\n";
67631
67844
  }
67632
67845
  function richHasFiles(rich) {
@@ -67637,6 +67850,47 @@ function titleFromText(text) {
67637
67850
  const t3 = first.replace(/^#{1,6}\s+/, "").trim();
67638
67851
  return (t3.length > 80 ? t3.slice(0, 79).trimEnd() + "\u2026" : t3) || "Pasted text";
67639
67852
  }
67853
+ var CREATABLE = {
67854
+ "::yamlover:$defs:chapter": {
67855
+ tag: "*::yamlover:$defs:chapter",
67856
+ childOf: ["x-yamlover-chapter", "x-yamlover-task"],
67857
+ // a chapter with one empty prose chunk (a positional body item), so it is immediately editable
67858
+ body: (title) => [`title: ${JSON.stringify(title)}`, `- ""`]
67859
+ }
67860
+ };
67861
+ function lastBodyChildPath(s2, parentSegs) {
67862
+ const positional = s2.entries(storePath(parentSegs)).filter((e3) => e3.kind === "contain" && e3.label == null);
67863
+ const last = positional[positional.length - 1];
67864
+ return last ? segsToStr(storePathToSegs(last.to)) : segsToStr([...parentSegs, 0]);
67865
+ }
67866
+ function defaultTitle(schema) {
67867
+ const segs = strToSegs(schema);
67868
+ return "New " + String(segs[segs.length - 1] ?? "object");
67869
+ }
67870
+ function objectFileSource(tag, body) {
67871
+ return `!!<${tag}>
67872
+ ${body.join("\n")}
67873
+ `;
67874
+ }
67875
+ function inlineChildLines(body, indent) {
67876
+ const pad = " ".repeat(indent);
67877
+ return body.map((line, i2) => i2 === 0 ? `${pad}- ${line}` : `${pad} ${line}`);
67878
+ }
67879
+ function objectBaseName(title) {
67880
+ const base = title.replace(/[^\p{L}\p{N} ._-]+/gu, " ").replace(/\s+/g, " ").trim().slice(0, 60).trim().replace(/^\.+/, "");
67881
+ return base || "new";
67882
+ }
67883
+ function writeObject(dataRoot, dir, base, concrete, src) {
67884
+ if (concrete === "dir/yamlover") {
67885
+ const final2 = uniqueName(dir, base);
67886
+ fs10.mkdirSync(path10.join(dir, final2, ".yamlover"), { recursive: true });
67887
+ writeInside(dataRoot, path10.join(dir, final2, ".yamlover"), "body.yamlover", Buffer.from(src, "utf8"));
67888
+ return final2;
67889
+ }
67890
+ const final = uniqueName(dir, base + ".yamlover");
67891
+ writeInside(dataRoot, dir, final, Buffer.from(src, "utf8"));
67892
+ return final;
67893
+ }
67640
67894
  function chapterFileName(title) {
67641
67895
  const base = title.replace(/[^\p{L}\p{N} ._-]+/gu, " ").replace(/\s+/g, " ").trim().slice(0, 60).trim().replace(/^\.+/, "");
67642
67896
  return `${base || "pasted"}.yamlover`;
@@ -67671,6 +67925,24 @@ function loadAgentDocs() {
67671
67925
  if (names3.length === 0) throw new Error(`no agent-docs resources at ${AGENT_DOCS_DIR}`);
67672
67926
  return names3.map((name) => ({ name, content: fs10.readFileSync(path10.join(AGENT_DOCS_DIR, name), "utf8") }));
67673
67927
  }
67928
+ var DOC_BEGIN = "<!-- BEGIN yamlover agent guide (auto-managed by `npx yamlover` \u2014 regenerated on reinstall) -->";
67929
+ var DOC_END = "<!-- END yamlover agent guide -->";
67930
+ function mergeAgentDoc(existing, content) {
67931
+ const block = `${DOC_BEGIN}
67932
+ ${content.trimEnd()}
67933
+ ${DOC_END}
67934
+ `;
67935
+ if (existing === null) return { text: block, status: "created" };
67936
+ const b = existing.indexOf(DOC_BEGIN);
67937
+ if (b === -1) {
67938
+ const sep2 = existing.endsWith("\n\n") ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
67939
+ return { text: existing + sep2 + block, status: "appended" };
67940
+ }
67941
+ const e3 = existing.indexOf(DOC_END, b);
67942
+ const end = e3 === -1 ? existing.length : e3 + DOC_END.length;
67943
+ const text = existing.slice(0, b) + block.trimEnd() + existing.slice(end);
67944
+ return { text, status: text === existing ? "exists" : "updated" };
67945
+ }
67674
67946
  var indentOf2 = (line) => {
67675
67947
  let i2 = 0;
67676
67948
  while (line[i2] === " ") i2++;
@@ -67688,76 +67960,218 @@ function textChunkLines(text, indent) {
67688
67960
  const head = text.endsWith("\n") ? "|" : "|-";
67689
67961
  return [`${pad}- ${head}`, ...body.split("\n").map((l2) => l2.trim().length ? `${pad} ${l2}` : "")];
67690
67962
  }
67691
- function appendToList(text, chapterPath, key, renderItems) {
67692
- const lines = text.split("\n");
67693
- let lo = 0;
67694
- let hi = lines.length;
67695
- let indent = firstContentIndent2(lines);
67696
- for (let i2 = 0; i2 < chapterPath.length; i2 += 2) {
67697
- const idx = Number(chapterPath[i2 + 1]);
67698
- const kids = findKeyLine2(lines, lo, hi, indent, "children");
67699
- if (kids < 0) throw new Error(`no 'children:' at indent ${indent}`);
67700
- const items = seqItems(lines, kids + 1, hi, indent);
67701
- if (!(idx >= 0 && idx < items.length)) throw new Error(`children[${idx}] out of range (${items.length})`);
67702
- hi = idx + 1 < items.length ? items[idx + 1] : seqEnd(lines, kids + 1, hi, indent);
67703
- lo = items[idx] + 1;
67704
- indent += 2;
67705
- }
67706
- const keyLine = findKeyLine2(lines, lo, hi, indent, key);
67707
- if (keyLine < 0) {
67708
- const end = trimBack2(lines, lo - 1, hi);
67709
- lines.splice(end, 0, `${" ".repeat(indent)}${key}:`, ...renderItems(indent));
67710
- } else {
67711
- const end = seqEnd(lines, keyLine + 1, hi, indent);
67712
- lines.splice(end, 0, ...renderItems(indent));
67963
+ function chapterEntries(lines, r2) {
67964
+ const starts = [];
67965
+ if (r2.marker >= 0) {
67966
+ const inline = lines[r2.marker].replace(/^\s*-\s*/, "");
67967
+ if (inline.trim()) starts.push({ key: /^-/.test(inline) ? null : inline.match(/^([^:\s]+):/)?.[1] ?? null, start: r2.marker, inline: true });
67713
67968
  }
67714
- return lines.join("\n");
67715
- }
67716
- function firstContentIndent2(lines) {
67717
- for (const l2 of lines) if (isContentLine2(l2)) return indentOf2(l2);
67718
- return 0;
67719
- }
67720
- function findKeyLine2(lines, lo, hi, indent, key) {
67721
- for (let i2 = lo; i2 < hi; i2++) {
67969
+ for (let i2 = r2.lo; i2 < r2.hi; i2++) {
67722
67970
  if (!isContentLine2(lines[i2])) continue;
67723
67971
  const ind = indentOf2(lines[i2]);
67724
- if (ind < indent) return -1;
67725
- if (ind !== indent) continue;
67972
+ if (ind < r2.indent) break;
67973
+ if (ind !== r2.indent) continue;
67726
67974
  const t3 = lines[i2].trim();
67727
- if (t3 === `${key}:` || t3.startsWith(`${key}:`)) return i2;
67975
+ if (t3.startsWith("!!<")) continue;
67976
+ starts.push({ key: t3 === "-" || t3.startsWith("- ") ? null : t3.match(/^([^:\s]+):/)?.[1] ?? null, start: i2, inline: false });
67977
+ }
67978
+ return starts.map((s2, k) => ({
67979
+ absIndex: k,
67980
+ key: s2.key,
67981
+ start: s2.start,
67982
+ end: k + 1 < starts.length ? starts[k + 1].start : trimBack2(lines, s2.start, r2.hi),
67983
+ inline: s2.inline
67984
+ }));
67985
+ }
67986
+ function bodyItems(lines, r2) {
67987
+ return chapterEntries(lines, r2).filter((e3) => e3.key === null);
67988
+ }
67989
+ function reachChapter(lines, chapterPath) {
67990
+ let r2 = { lo: 0, hi: lines.length, indent: firstContentIndent2(lines), marker: -1 };
67991
+ for (const seg of chapterPath) {
67992
+ const idx = Number(seg);
67993
+ const item = chapterEntries(lines, r2)[idx];
67994
+ if (!item || item.key !== null) throw new Error(`no subchapter at [${idx}]`);
67995
+ r2 = { lo: item.start + 1, hi: item.end, indent: r2.indent + 2, marker: item.start };
67996
+ }
67997
+ return r2;
67998
+ }
67999
+ function bodyAppendPoint(lines, r2) {
68000
+ const entries = chapterEntries(lines, r2);
68001
+ const items = entries.filter((e3) => e3.key === null);
68002
+ if (items.length) return items[items.length - 1].end;
68003
+ if (entries.length) return entries[entries.length - 1].end;
68004
+ return r2.marker >= 0 ? r2.marker + 1 : trimBack2(lines, r2.lo - 1, r2.hi);
68005
+ }
68006
+ function appendBody(text, chapterPath, renderItems) {
68007
+ const lines = text.split("\n");
68008
+ const r2 = reachChapter(lines, chapterPath);
68009
+ lines.splice(bodyAppendPoint(lines, r2), 0, ...renderItems(r2.indent));
68010
+ return lines.join("\n");
68011
+ }
68012
+ function bodyItemHead(lines, r2, rank) {
68013
+ const items = bodyItems(lines, r2);
68014
+ if (!(rank >= 0 && rank < items.length)) throw new Error(`body[${rank}] out of range (${items.length})`);
68015
+ return lines[items[rank].start].trim().replace(/^-\s*/, "");
68016
+ }
68017
+ function setScalarKey(lines, r2, key, value) {
68018
+ const entry = chapterEntries(lines, r2).find((e3) => e3.key === key);
68019
+ if (entry?.inline) {
68020
+ const pad3 = " ".repeat(indentOf2(lines[entry.start]));
68021
+ lines[entry.start] = `${pad3}- ${key}: ${JSON.stringify(value)}`;
68022
+ return;
67728
68023
  }
67729
- return -1;
68024
+ const pad = " ".repeat(r2.indent);
68025
+ if (!value) {
68026
+ if (entry) lines.splice(entry.start, 1);
68027
+ return;
68028
+ }
68029
+ const rendered = `${pad}${key}: ${JSON.stringify(value)}`;
68030
+ if (entry) lines.splice(entry.start, 1, rendered);
68031
+ else lines.splice(r2.marker >= 0 ? r2.marker + 1 : trimBack2(lines, r2.lo - 1, r2.hi), 0, rendered);
67730
68032
  }
67731
- function seqItems(lines, from, hi, indent) {
67732
- const out = [];
67733
- for (let i2 = from; i2 < hi; i2++) {
68033
+ function replaceBodyItem(lines, r2, rank, text) {
68034
+ const items = bodyItems(lines, r2);
68035
+ if (!(rank >= 0 && rank < items.length)) throw new Error(`body[${rank}] out of range (${items.length})`);
68036
+ const { start, end } = items[rank];
68037
+ const head = lines[start].trim().replace(/^-\s*/, "");
68038
+ const tag = head.match(/^(!!<[^>]*>)/)?.[1];
68039
+ const rendered = tag ? taggedChunkLines(text, r2.indent, tag) : textChunkLines(text, r2.indent);
68040
+ lines.splice(start, end - start, ...rendered);
68041
+ }
68042
+ function insertBodyItem(lines, r2, rank, text) {
68043
+ const items = bodyItems(lines, r2);
68044
+ const at = rank < items.length ? items[rank].start : bodyAppendPoint(lines, r2);
68045
+ lines.splice(at, 0, ...textChunkLines(text, r2.indent));
68046
+ }
68047
+ function removeBodyItem(lines, r2, rank) {
68048
+ const items = bodyItems(lines, r2);
68049
+ if (!(rank >= 0 && rank < items.length)) throw new Error(`body[${rank}] out of range (${items.length})`);
68050
+ const { start, end } = items[rank];
68051
+ lines.splice(start, end - start);
68052
+ }
68053
+ function taggedChunkLines(text, indent, tag) {
68054
+ const pad = " ".repeat(indent);
68055
+ const first = text.split("\n").find((l2) => l2.trim().length > 0);
68056
+ if (!first || /^\s/.test(first)) return [`${pad}- ${tag} ${JSON.stringify(text)}`];
68057
+ const body = text.endsWith("\n") ? text.slice(0, -1) : text;
68058
+ const head = text.endsWith("\n") ? "|" : "|-";
68059
+ return [`${pad}- ${tag} ${head}`, ...body.split("\n").map((l2) => l2.trim().length ? `${pad} ${l2}` : "")];
68060
+ }
68061
+ function assertProseBodyItem(lines, r2, rank) {
68062
+ const head = bodyItemHead(lines, r2, rank);
68063
+ if (head.startsWith("*")) throw new Error("cannot edit a file/pointer chunk as text");
68064
+ const tag = head.match(/^!!<([^>]*)>/)?.[1];
68065
+ if (tag && !/text\/(markdown|marklower|x-latex)/.test(tag)) throw new Error("cannot edit a non-text chunk as text");
68066
+ }
68067
+ function reachChapterItem(lines, indices) {
68068
+ const parent = reachChapter(lines, indices.slice(0, -1));
68069
+ const idx = indices[indices.length - 1];
68070
+ const item = chapterEntries(lines, parent)[idx];
68071
+ if (!item || item.key !== null) throw new Error(`no chapter body item at [${idx}]`);
68072
+ return { parent, item, itemIndent: parent.indent };
68073
+ }
68074
+ function itemHasFields(lines, item, fieldIndent) {
68075
+ for (let i2 = item.start + 1; i2 < item.end; i2++) {
67734
68076
  if (!isContentLine2(lines[i2])) continue;
67735
68077
  const ind = indentOf2(lines[i2]);
67736
- if (ind < indent) break;
67737
- if (ind !== indent) continue;
67738
- const t3 = lines[i2].trim();
67739
- if (t3 === "-" || t3.startsWith("- ")) out.push(i2);
67740
- else break;
68078
+ if (ind < fieldIndent) break;
68079
+ if (ind === fieldIndent && /^[^\s-][^:]*:(\s|$)/.test(lines[i2].trim())) return true;
67741
68080
  }
67742
- return out;
68081
+ return false;
67743
68082
  }
67744
- function seqEnd(lines, from, hi, indent) {
67745
- let last = from;
67746
- for (let i2 = from; i2 < hi; i2++) {
67747
- if (!isContentLine2(lines[i2])) continue;
67748
- const ind = indentOf2(lines[i2]);
67749
- if (ind < indent) return trimBack2(lines, last, i2);
67750
- if (ind === indent) {
67751
- const t3 = lines[i2].trim();
67752
- if (t3 === "-" || t3.startsWith("- ")) {
67753
- last = i2;
67754
- continue;
67755
- }
67756
- return trimBack2(lines, last, i2);
67757
- }
67758
- last = i2;
68083
+ function convertChunkToOmni(lines, item, itemIndent) {
68084
+ const head = lines[item.start].slice(itemIndent).replace(/^-\s*/, "");
68085
+ const tagMatch = head.match(/^(!!<[^>]*>)\s*/);
68086
+ const tag = tagMatch ? tagMatch[1] + " " : "";
68087
+ const rest = tagMatch ? head.slice(tagMatch[0].length) : head;
68088
+ if (/^[|>][+-]?\d*$/.test(rest.trim())) {
68089
+ for (let i2 = item.start + 1; i2 < item.end; i2++) if (lines[i2].trim().length) lines[i2] = " " + lines[i2];
68090
+ return;
68091
+ }
68092
+ const value = rest.startsWith('"') ? String(JSON.parse(rest)) : rest;
68093
+ const pad = " ".repeat(itemIndent);
68094
+ const chomp = value.endsWith("\n") ? "|" : "|-";
68095
+ const clean = value.endsWith("\n") ? value.slice(0, -1) : value;
68096
+ lines.splice(item.start, item.end - item.start, `${pad}- ${tag}${chomp}`, ...clean.split("\n").map((l2) => l2.trim() ? `${pad} ${l2}` : ""));
68097
+ }
68098
+ function chunkFieldRegion(lines, indices, ensureOmni) {
68099
+ const { item, itemIndent } = reachChapterItem(lines, indices);
68100
+ const fieldIndent = itemIndent + 2;
68101
+ if (ensureOmni && !itemHasFields(lines, item, fieldIndent)) convertChunkToOmni(lines, item, itemIndent);
68102
+ const { item: cur } = reachChapterItem(lines, indices);
68103
+ return { lo: cur.start + 1, hi: cur.end, indent: fieldIndent };
68104
+ }
68105
+ function collapseChunkOmni(lines, indices) {
68106
+ const { item, itemIndent } = reachChapterItem(lines, indices);
68107
+ if (itemHasFields(lines, item, itemIndent + 2)) return;
68108
+ for (let i2 = item.start + 1; i2 < item.end; i2++) {
68109
+ if (lines[i2].trim().length && indentOf2(lines[i2]) >= itemIndent + 2) lines[i2] = lines[i2].slice(2);
67759
68110
  }
67760
- return trimBack2(lines, last, hi);
68111
+ }
68112
+ function assertProseChunk(lines, indices) {
68113
+ const { item } = reachChapterItem(lines, indices);
68114
+ const head = lines[item.start].slice(indentOf2(lines[item.start])).replace(/^-\s*/, "");
68115
+ if (head.startsWith("*")) throw new Error("cannot tag a file/pointer chunk's text");
68116
+ const tag = head.match(/^!!<([^>]*)>/)?.[1];
68117
+ if (tag && !/text\/(markdown|marklower|x-latex)/.test(tag)) throw new Error("cannot tag a non-text chunk's text");
68118
+ }
68119
+ function isChunkTarget(s2, segs) {
68120
+ const within = segs.slice(documentRootSegs(s2, segs).length);
68121
+ return within.length > 0 && typeof within[0] === "number";
68122
+ }
68123
+ function splitChunkWithin(within) {
68124
+ let i2 = 0;
68125
+ while (i2 < within.length && typeof within[i2] === "number") i2++;
68126
+ return { indices: within.slice(0, i2).map(Number), keys: within.slice(i2).map(String) };
68127
+ }
68128
+ function editChapterSource(src, within, op, text, index) {
68129
+ const lines = src.split("\n");
68130
+ if (op === "set") {
68131
+ const key = within[within.length - 1];
68132
+ if (key !== "title" && key !== "description") throw new Error("`set` needs a title/description target");
68133
+ setScalarKey(lines, reachChapter(lines, within.slice(0, -1)), key, text);
68134
+ return lines.join("\n");
68135
+ }
68136
+ if (op === "insert") {
68137
+ insertBodyItem(lines, reachChapter(lines, within), index ?? Number.MAX_SAFE_INTEGER, text);
68138
+ return lines.join("\n");
68139
+ }
68140
+ const rank = within[within.length - 1];
68141
+ if (typeof rank !== "number") throw new Error(`\`${op}\` needs a body-element target (path ends \`[rank]\`)`);
68142
+ const region = reachChapter(lines, within.slice(0, -1));
68143
+ if (op === "replace") {
68144
+ assertProseBodyItem(lines, region, rank);
68145
+ replaceBodyItem(lines, region, rank, text);
68146
+ } else if (op === "remove") {
68147
+ removeBodyItem(lines, region, rank);
68148
+ } else {
68149
+ throw new Error(`unknown edit op: ${op}`);
68150
+ }
68151
+ return lines.join("\n");
68152
+ }
68153
+ function applyEdits2(dataRoot, s2, edits) {
68154
+ const byFile = /* @__PURE__ */ new Map();
68155
+ for (const e3 of edits) {
68156
+ const editSegs = strToSegs(e3.path ?? "");
68157
+ const { docSegs, bodyFile } = chapterSource(dataRoot, s2, editSegs);
68158
+ const within = editSegs.slice(docSegs.length);
68159
+ const list = byFile.get(bodyFile) ?? [];
68160
+ list.push({ within, op: String(e3.op ?? ""), text: String(e3.text ?? ""), index: typeof e3.index === "number" ? e3.index : void 0 });
68161
+ byFile.set(bodyFile, list);
68162
+ }
68163
+ const touched = [];
68164
+ for (const [bodyFile, ops] of byFile) {
68165
+ let src = fs10.readFileSync(bodyFile, "utf8");
68166
+ for (const o2 of ops) src = editChapterSource(src, o2.within, o2.op, o2.text, o2.index);
68167
+ fs10.writeFileSync(bodyFile, src);
68168
+ touched.push(bodyFile);
68169
+ }
68170
+ return touched;
68171
+ }
68172
+ function firstContentIndent2(lines) {
68173
+ for (const l2 of lines) if (isContentLine2(l2)) return indentOf2(l2);
68174
+ return 0;
67761
68175
  }
67762
68176
  function trimBack2(lines, lastItemLine, end) {
67763
68177
  let e3 = end;
@@ -67789,9 +68203,15 @@ function documentPath(s2, segs) {
67789
68203
  return segsToStr(documentRootSegs(s2, segs));
67790
68204
  }
67791
68205
  function titleOf(s2, p2) {
67792
- const titlePath = (p2 === ":" ? "" : p2) + ":title";
67793
- const t3 = s2.node(titlePath);
67794
- if (t3 && t3.type === "scalar" && !s2.hasChildren(titlePath) && t3.value != null) return String(t3.value);
68206
+ return scalarKeyOf(s2, p2, "title");
68207
+ }
68208
+ function descriptionOf(s2, p2) {
68209
+ return scalarKeyOf(s2, p2, "description");
68210
+ }
68211
+ function scalarKeyOf(s2, p2, key) {
68212
+ const kp = (p2 === ":" ? "" : p2) + ":" + key;
68213
+ const t3 = s2.node(kp);
68214
+ if (t3 && t3.type === "scalar" && !s2.hasChildren(kp) && t3.value != null) return String(t3.value);
67795
68215
  return null;
67796
68216
  }
67797
68217
  var PATH_TOKEN = /\[\d+\]|[^:\[\]]+/g;
@@ -67851,6 +68271,11 @@ function defaultDepth(s2, dataRoot, segs, row, kind) {
67851
68271
  function refMarker(text, path11) {
67852
68272
  return { [REF_KEY]: { text, path: path11 } };
67853
68273
  }
68274
+ function binaryValueMarker(segs, row) {
68275
+ const info = { kind: "binary", type: "blob", path: segsToStr(segs), size: row.size };
68276
+ if (row.format) info.format = row.format;
68277
+ return { [LINK_KEY]: info };
68278
+ }
67854
68279
  function clampThumbDim(raw, def) {
67855
68280
  const n2 = raw == null ? NaN : Math.round(Number(raw));
67856
68281
  return Number.isFinite(n2) && n2 >= 16 ? Math.min(n2, 2048) : def;
@@ -67864,7 +68289,8 @@ function notFound(res, url) {
67864
68289
  sendJson(res, 404, { error: `no such node/endpoint: ${url.pathname}?${url.searchParams}` });
67865
68290
  }
67866
68291
  export {
67867
- createHandlers
68292
+ createHandlers,
68293
+ mergeAgentDoc
67868
68294
  };
67869
68295
  /*! Bundled license information:
67870
68296