dreamcontext 0.10.0 → 0.10.2

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 (121) hide show
  1. package/dist/dashboard/assets/{BrainCanvas3D-DPHKVW49.js → BrainCanvas3D-BuhjqMJE.js} +1 -1
  2. package/dist/dashboard/assets/{_baseUniq-CHd2laKt.js → _baseUniq-BFywhIrF.js} +1 -1
  3. package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-CJm41yHw.js → ar-SA-G6X2FPQ2-0wtAtjf3.js} +1 -1
  4. package/dist/dashboard/assets/{arc-DUqUK5I0.js → arc-CbIZg0XW.js} +1 -1
  5. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-CRDXKDvE.js → architectureDiagram-Q4EWVU46-DcA2m4dL.js} +1 -1
  6. package/dist/dashboard/assets/{az-AZ-76LH7QW2-BvugTMBT.js → az-AZ-76LH7QW2-DypXzn_9.js} +1 -1
  7. package/dist/dashboard/assets/{bg-BG-XCXSNQG7-CLr0Fn-e.js → bg-BG-XCXSNQG7-DqjNOvWi.js} +1 -1
  8. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-B8exO_lL.js → blockDiagram-DXYQGD6D-DGUYSkmu.js} +1 -1
  9. package/dist/dashboard/assets/{bn-BD-2XOGV67Q-D0vwADrS.js → bn-BD-2XOGV67Q-DMT15vLO.js} +1 -1
  10. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-Cejeoprm.js → c4Diagram-AHTNJAMY-D0ureHL0.js} +1 -1
  11. package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-CxqyG_0S.js → ca-ES-6MX7JW3Y-BIf8pakY.js} +1 -1
  12. package/dist/dashboard/assets/channel-C5uBjxRg.js +1 -0
  13. package/dist/dashboard/assets/{chunk-4BX2VUAB-BKe2HbO0.js → chunk-4BX2VUAB-BpMo9p3D.js} +1 -1
  14. package/dist/dashboard/assets/{chunk-4TB4RGXK-BYd5xUfH.js → chunk-4TB4RGXK-BjWqEumI.js} +1 -1
  15. package/dist/dashboard/assets/{chunk-55IACEB6-BRmdVuF4.js → chunk-55IACEB6-CoREiws2.js} +1 -1
  16. package/dist/dashboard/assets/{chunk-EDXVE4YY-B-pwoibO.js → chunk-EDXVE4YY-DWGx8NFS.js} +1 -1
  17. package/dist/dashboard/assets/{chunk-FMBD7UC4-LC1eQ6Bn.js → chunk-FMBD7UC4-BPHXOHEi.js} +1 -1
  18. package/dist/dashboard/assets/{chunk-OYMX7WX6-w2Fbw2qj.js → chunk-OYMX7WX6-Cg-AvRQR.js} +1 -1
  19. package/dist/dashboard/assets/{chunk-QZHKN3VN-BCWG4fy9.js → chunk-QZHKN3VN-oNBf0ZAT.js} +1 -1
  20. package/dist/dashboard/assets/{chunk-YZCP3GAM-CrKe7Bc4.js → chunk-YZCP3GAM-BWTEULwI.js} +1 -1
  21. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-MwUwKREr.js +1 -0
  22. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-MwUwKREr.js +1 -0
  23. package/dist/dashboard/assets/clone-CcQlDA5C.js +1 -0
  24. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-Csw9QUYq.js → cose-bilkent-S5V4N54A-CQAtltI5.js} +1 -1
  25. package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-CogQs_1l.js → cs-CZ-2BRQDIVT-sgLhn2uw.js} +1 -1
  26. package/dist/dashboard/assets/{da-DK-5WZEPLOC-CLE1k6n-.js → da-DK-5WZEPLOC-56JnY0Ou.js} +1 -1
  27. package/dist/dashboard/assets/{dagre-KV5264BT-CYO4L2oQ.js → dagre-KV5264BT-Czzd8AFD.js} +1 -1
  28. package/dist/dashboard/assets/{de-DE-XR44H4JA-Cyk4pAkD.js → de-DE-XR44H4JA-CLiIEbrn.js} +1 -1
  29. package/dist/dashboard/assets/{diagram-5BDNPKRD-_l3m-Gzf.js → diagram-5BDNPKRD-BYQz4Ej0.js} +1 -1
  30. package/dist/dashboard/assets/{diagram-G4DWMVQ6-ComC4npi.js → diagram-G4DWMVQ6-Bi69CX9y.js} +1 -1
  31. package/dist/dashboard/assets/{diagram-MMDJMWI5-xZ9cT0uu.js → diagram-MMDJMWI5-C9rH4USL.js} +1 -1
  32. package/dist/dashboard/assets/{diagram-TYMM5635-Dnq3s1v5.js → diagram-TYMM5635-CtGy_47Q.js} +1 -1
  33. package/dist/dashboard/assets/{el-GR-BZB4AONW-BFImbdQn.js → el-GR-BZB4AONW-DLKTMVgu.js} +1 -1
  34. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-kcbabKJD.js → erDiagram-SMLLAGMA-DYwZiwiF.js} +1 -1
  35. package/dist/dashboard/assets/{es-ES-U4NZUMDT-jGtxZhYt.js → es-ES-U4NZUMDT-B8vUZNzj.js} +1 -1
  36. package/dist/dashboard/assets/{eu-ES-A7QVB2H4-Bzz2d8CD.js → eu-ES-A7QVB2H4-DOBpB_xM.js} +1 -1
  37. package/dist/dashboard/assets/{fa-IR-HGAKTJCU-63k-G3tN.js → fa-IR-HGAKTJCU-BSo8AkJw.js} +1 -1
  38. package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-ezHcIK6s.js → fi-FI-Z5N7JZ37-IXouAsQf.js} +1 -1
  39. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-B1Uy8SMX.js → flowDiagram-DWJPFMVM-BfsdXM27.js} +1 -1
  40. package/dist/dashboard/assets/{fr-FR-RHASNOE6-C6Pe7vKj.js → fr-FR-RHASNOE6-Bq41-iWY.js} +1 -1
  41. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-CABaaerr.js → ganttDiagram-T4ZO3ILL-YFxSZdBo.js} +1 -1
  42. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-CcyLIbFK.js → gitGraphDiagram-UUTBAWPF-CzLILfBF.js} +1 -1
  43. package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-sdrg75Ty.js → gl-ES-HMX3MZ6V-kuzaTFsC.js} +1 -1
  44. package/dist/dashboard/assets/{graph-XfL-ygDi.js → graph-BOf2JBnY.js} +1 -1
  45. package/dist/dashboard/assets/{he-IL-6SHJWFNN-C9y7ygPP.js → he-IL-6SHJWFNN-RQ2NxAvm.js} +1 -1
  46. package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-Bf7GXs-7.js → hi-IN-IWLTKZ5I-D9xTaaPK.js} +1 -1
  47. package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-SU6SehRg.js → hu-HU-A5ZG7DT2-L1HNbSdl.js} +1 -1
  48. package/dist/dashboard/assets/{id-ID-SAP4L64H-DVtmANJA.js → id-ID-SAP4L64H-B33X72Ml.js} +1 -1
  49. package/dist/dashboard/assets/index--chDvBkZ.css +32 -0
  50. package/dist/dashboard/assets/{index-C64a-kHY.js → index-B-6R-7Ot.js} +1 -1
  51. package/dist/dashboard/assets/index-CwZ3YweD.js +582 -0
  52. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-DfBeu9Gz.js → infoDiagram-42DDH7IO-DTWl9Wxm.js} +1 -1
  53. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-CbBN1lYP.js → ishikawaDiagram-UXIWVN3A-C0CAoNgB.js} +1 -1
  54. package/dist/dashboard/assets/{it-IT-JPQ66NNP-BbmyFH6C.js → it-IT-JPQ66NNP-BK_HSf6M.js} +1 -1
  55. package/dist/dashboard/assets/{ja-JP-DBVTYXUO-Cbhk39-5.js → ja-JP-DBVTYXUO-BRVQwLJ-.js} +1 -1
  56. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-BW4WNn5U.js → journeyDiagram-VCZTEJTY-CADHnY3u.js} +1 -1
  57. package/dist/dashboard/assets/{kaa-6HZHGXH3-Cm-Swgc1.js → kaa-6HZHGXH3-CYGgpUSe.js} +1 -1
  58. package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-BX9BAQyv.js → kab-KAB-ZGHBKWFO-LMEkvoCj.js} +1 -1
  59. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-D6dnUpyA.js → kanban-definition-6JOO6SKY-D1ijOIDj.js} +1 -1
  60. package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-MHpPSoz0.js → kk-KZ-P5N5QNE5-JIbh9_iv.js} +1 -1
  61. package/dist/dashboard/assets/{km-KH-HSX4SM5Z-BU3ECFbO.js → km-KH-HSX4SM5Z-CrWx5kgt.js} +1 -1
  62. package/dist/dashboard/assets/{ko-KR-MTYHY66A-DqT3JGwF.js → ko-KR-MTYHY66A-BQFjXlBC.js} +1 -1
  63. package/dist/dashboard/assets/{ku-TR-6OUDTVRD-DN2-3fDm.js → ku-TR-6OUDTVRD-B6u43c-f.js} +1 -1
  64. package/dist/dashboard/assets/{layout-BZ4MGsUu.js → layout-CVIUlzFz.js} +1 -1
  65. package/dist/dashboard/assets/{linear-C0etayOa.js → linear-TmytBUBH.js} +1 -1
  66. package/dist/dashboard/assets/{lt-LT-XHIRWOB4-DQVwHiLl.js → lt-LT-XHIRWOB4-b8AKF48V.js} +1 -1
  67. package/dist/dashboard/assets/{lv-LV-5QDEKY6T-Dad8CoSF.js → lv-LV-5QDEKY6T-CRt75m7a.js} +1 -1
  68. package/dist/dashboard/assets/{min-Bl_tJyDg.js → min-CMOJsVTV.js} +1 -1
  69. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-BNw0aQbU.js → mindmap-definition-QFDTVHPH-DkzlAkBW.js} +1 -1
  70. package/dist/dashboard/assets/{mr-IN-CRQNXWMA-BbxiQT_Z.js → mr-IN-CRQNXWMA-Bw3MaxMe.js} +1 -1
  71. package/dist/dashboard/assets/{my-MM-5M5IBNSE-UoAgrIPq.js → my-MM-5M5IBNSE-Dw_tWZWl.js} +1 -1
  72. package/dist/dashboard/assets/{nb-NO-T6EIAALU-CImkOb7l.js → nb-NO-T6EIAALU-Ci_2058Y.js} +1 -1
  73. package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-vfeVTewJ.js → nl-NL-IS3SIHDZ-DYyqePg6.js} +1 -1
  74. package/dist/dashboard/assets/{nn-NO-6E72VCQL-DUCB91yA.js → nn-NO-6E72VCQL-NdjykAxN.js} +1 -1
  75. package/dist/dashboard/assets/{oc-FR-POXYY2M6-BkXl0YMF.js → oc-FR-POXYY2M6-DPEyc6hx.js} +1 -1
  76. package/dist/dashboard/assets/{pa-IN-N4M65BXN-CWiVQtSk.js → pa-IN-N4M65BXN-D_4V8i72.js} +1 -1
  77. package/dist/dashboard/assets/{percentages-BXMCSKIN-BGA-Ex2O.js → percentages-BXMCSKIN-4Hgy5SgQ.js} +7 -7
  78. package/dist/dashboard/assets/{pica-B8XEUChK.js → pica-D6rAZEqu.js} +1 -1
  79. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-Dic1EjdC.js → pieDiagram-DEJITSTG-BqsalDEv.js} +1 -1
  80. package/dist/dashboard/assets/{pl-PL-T2D74RX3-g55_1Rbd.js → pl-PL-T2D74RX3-CArl0OSe.js} +1 -1
  81. package/dist/dashboard/assets/{pt-BR-5N22H2LF-DQeCXlLm.js → pt-BR-5N22H2LF-BlA9u7zY.js} +1 -1
  82. package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-CHvZqZyF.js → pt-PT-UZXXM6DQ-ByCcYKU2.js} +1 -1
  83. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-CP7lQiIi.js → quadrantDiagram-34T5L4WZ-BtnExwNB.js} +1 -1
  84. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-BWtUEAf6.js → requirementDiagram-MS252O5E-jDWYOtpC.js} +1 -1
  85. package/dist/dashboard/assets/{ro-RO-JPDTUUEW-EwDfeMZo.js → ro-RO-JPDTUUEW-CafHxA38.js} +1 -1
  86. package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-CD2Zj2l8.js → ru-RU-B4JR7IUQ-BbJGwp-Z.js} +1 -1
  87. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-DwvQDD5y.js → sankeyDiagram-XADWPNL6-BSU4w3_8.js} +1 -1
  88. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-BRglyRtb.js → sequenceDiagram-FGHM5R23-DBHLScxa.js} +1 -1
  89. package/dist/dashboard/assets/{si-LK-N5RQ5JYF-BY5MM9Vd.js → si-LK-N5RQ5JYF-eDB0s9B0.js} +1 -1
  90. package/dist/dashboard/assets/{sk-SK-C5VTKIMK-5GG4lqoV.js → sk-SK-C5VTKIMK-qaYN0zkE.js} +1 -1
  91. package/dist/dashboard/assets/{sl-SI-NN7IZMDC-DX6b0Bj8.js → sl-SI-NN7IZMDC-BQ4pcyGF.js} +1 -1
  92. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-Dl3yCEGL.js → stateDiagram-FHFEXIEX-DqLkK6dC.js} +1 -1
  93. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-TpuacwBg.js +1 -0
  94. package/dist/dashboard/assets/{subset-shared.chunk-CmSgs0wP.js → subset-shared.chunk-Hm_CkSQB.js} +1 -1
  95. package/dist/dashboard/assets/{subset-worker.chunk-gyKmbtyq.js → subset-worker.chunk-YczznLkp.js} +1 -1
  96. package/dist/dashboard/assets/{sv-SE-XGPEYMSR-Cf_qIZ2K.js → sv-SE-XGPEYMSR-DD7_8pqE.js} +1 -1
  97. package/dist/dashboard/assets/{ta-IN-2NMHFXQM-zwatd37w.js → ta-IN-2NMHFXQM-Dd-RFvWz.js} +1 -1
  98. package/dist/dashboard/assets/{th-TH-HPSO5L25-Cw3uejzD.js → th-TH-HPSO5L25-C7x2tZrZ.js} +1 -1
  99. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-C7YbVDU1.js → timeline-definition-GMOUNBTQ-DILCBtIX.js} +1 -1
  100. package/dist/dashboard/assets/{tr-TR-DEFEU3FU-C15eSVKk.js → tr-TR-DEFEU3FU-BXDs1FJQ.js} +1 -1
  101. package/dist/dashboard/assets/{uk-UA-QMV73CPH-DtjXD0R5.js → uk-UA-QMV73CPH-Bp-yEHOn.js} +1 -1
  102. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-CM3qRaPy.js → vennDiagram-DHZGUBPP-CnQH3XJu.js} +1 -1
  103. package/dist/dashboard/assets/{vi-VN-M7AON7JQ-TYc9r2ul.js → vi-VN-M7AON7JQ-DQOsitU7.js} +1 -1
  104. package/dist/dashboard/assets/{wardley-RL74JXVD-hKHpsv-V.js → wardley-RL74JXVD-FdX4RiE_.js} +1 -1
  105. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-By2VWEm6.js → wardleyDiagram-NUSXRM2D-CK4rbC5W.js} +1 -1
  106. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-B_jwEdiv.js → xychartDiagram-5P7HB3ND-B6UGr9Rl.js} +1 -1
  107. package/dist/dashboard/assets/{zh-CN-LNUGB5OW-BMLBhdOl.js → zh-CN-LNUGB5OW-BMYbdc2b.js} +1 -1
  108. package/dist/dashboard/assets/{zh-HK-E62DVLB3-B3F6zPCV.js → zh-HK-E62DVLB3-CCcVgqN7.js} +1 -1
  109. package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-BtvvFKFv.js → zh-TW-RAJ6MFWO-C52SJlwU.js} +1 -1
  110. package/dist/dashboard/index.html +2 -2
  111. package/dist/index.js +1162 -602
  112. package/package.json +1 -1
  113. package/skill/SKILL.md +7 -7
  114. package/skill/references/sleep.md +12 -12
  115. package/dist/dashboard/assets/channel-44TauaoC.js +0 -1
  116. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DvAbYAqz.js +0 -1
  117. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DvAbYAqz.js +0 -1
  118. package/dist/dashboard/assets/clone-C56fm_aT.js +0 -1
  119. package/dist/dashboard/assets/index-CC4bLFLV.js +0 -579
  120. package/dist/dashboard/assets/index-DZ3FBso3.css +0 -32
  121. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-Q3JaGk-b.js +0 -1
package/dist/index.js CHANGED
@@ -26381,8 +26381,8 @@ var require_pattern = __commonJS({
26381
26381
  }
26382
26382
  exports2.endsWithSlashGlobStar = endsWithSlashGlobStar;
26383
26383
  function isAffectDepthOfReadingPattern(pattern) {
26384
- const basename28 = path2.basename(pattern);
26385
- return endsWithSlashGlobStar(pattern) || isStaticPattern(basename28);
26384
+ const basename29 = path2.basename(pattern);
26385
+ return endsWithSlashGlobStar(pattern) || isStaticPattern(basename29);
26386
26386
  }
26387
26387
  exports2.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
26388
26388
  function expandPatternsWithBraceExpansion(patterns) {
@@ -26856,11 +26856,11 @@ var require_out = __commonJS({
26856
26856
  async.read(path2, getSettings(optionsOrSettingsOrCallback), callback);
26857
26857
  }
26858
26858
  exports2.stat = stat;
26859
- function statSync22(path2, optionsOrSettings) {
26859
+ function statSync24(path2, optionsOrSettings) {
26860
26860
  const settings = getSettings(optionsOrSettings);
26861
26861
  return sync.read(path2, settings);
26862
26862
  }
26863
- exports2.statSync = statSync22;
26863
+ exports2.statSync = statSync24;
26864
26864
  function getSettings(settingsOrOptions = {}) {
26865
26865
  if (settingsOrOptions instanceof settings_1.default) {
26866
26866
  return settingsOrOptions;
@@ -37533,25 +37533,71 @@ var init_migration_runner = __esm({
37533
37533
  }
37534
37534
  });
37535
37535
 
37536
+ // src/lib/file-lock.ts
37537
+ import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync31, readFileSync as readFileSync34, statSync as statSync6, rmSync as rmSync6 } from "fs";
37538
+ import { dirname as dirname23 } from "path";
37539
+ function acquireFileLock(lockPath, nowMs, staleMs) {
37540
+ mkdirSync25(dirname23(lockPath), { recursive: true });
37541
+ const tryCreate = () => {
37542
+ try {
37543
+ writeFileSync31(lockPath, JSON.stringify({ pid: process.pid, at: nowMs }) + "\n", { flag: "wx" });
37544
+ return true;
37545
+ } catch {
37546
+ return false;
37547
+ }
37548
+ };
37549
+ if (tryCreate()) return true;
37550
+ let heldSince = null;
37551
+ try {
37552
+ const info2 = JSON.parse(readFileSync34(lockPath, "utf-8"));
37553
+ if (typeof info2.at === "number") heldSince = info2.at;
37554
+ } catch {
37555
+ }
37556
+ if (heldSince === null) {
37557
+ try {
37558
+ heldSince = statSync6(lockPath).mtimeMs;
37559
+ } catch {
37560
+ return tryCreate();
37561
+ }
37562
+ }
37563
+ if (nowMs - heldSince <= staleMs) return false;
37564
+ try {
37565
+ rmSync6(lockPath, { force: true });
37566
+ } catch {
37567
+ }
37568
+ return tryCreate();
37569
+ }
37570
+ function releaseFileLock(lockPath) {
37571
+ try {
37572
+ rmSync6(lockPath, { force: true });
37573
+ } catch {
37574
+ }
37575
+ }
37576
+ var init_file_lock = __esm({
37577
+ "src/lib/file-lock.ts"() {
37578
+ "use strict";
37579
+ }
37580
+ });
37581
+
37536
37582
  // src/lib/sleep-consolidation.ts
37537
37583
  function sleepinessLevel(debt) {
37538
- if (debt <= 3) return "Alert";
37539
- if (debt <= 6) return "Drowsy";
37540
- if (debt <= 9) return "Sleepy";
37584
+ if (debt < DEBT_DROWSY) return "Alert";
37585
+ if (debt < DEBT_SLEEPY) return "Drowsy";
37586
+ if (debt < DEBT_MUST_SLEEP) return "Sleepy";
37541
37587
  return "Must Sleep";
37542
37588
  }
37543
37589
  function sleepinessRange(debt) {
37544
- if (debt <= 3) return "0-3";
37545
- if (debt <= 6) return "4-6";
37546
- if (debt <= 9) return "7-9";
37547
- return "10+";
37590
+ if (debt < DEBT_DROWSY) return `0-${DEBT_DROWSY - 1}`;
37591
+ if (debt < DEBT_SLEEPY) return `${DEBT_DROWSY}-${DEBT_SLEEPY - 1}`;
37592
+ if (debt < DEBT_MUST_SLEEP) return `${DEBT_SLEEPY}-${DEBT_MUST_SLEEP - 1}`;
37593
+ return `${DEBT_MUST_SLEEP}+`;
37548
37594
  }
37549
37595
  function recomputeDebt(sessions) {
37550
37596
  return sessions.reduce((sum, s) => sum + (s.score ?? 0), 0);
37551
37597
  }
37552
37598
  function depthFromDebt(debt) {
37553
- if (debt <= 3) return "light";
37554
- if (debt <= 9) return "standard";
37599
+ if (debt < DEBT_DROWSY) return "light";
37600
+ if (debt < DEBT_MUST_SLEEP) return "standard";
37555
37601
  return "deep";
37556
37602
  }
37557
37603
  function consolidationDepth(debt, opts = {}) {
@@ -37655,6 +37701,13 @@ function validateSleepAdd(scoreStr, desc) {
37655
37701
  }
37656
37702
  return { ok: true };
37657
37703
  }
37704
+ function inspectSleepLock(state, nowMs) {
37705
+ const startedAt = state.sleep_started_at;
37706
+ if (!startedAt) return { locked: false, startedAt: null, ageMs: 0, stale: false };
37707
+ const startedMs = Date.parse(startedAt);
37708
+ const ageMs = Number.isFinite(startedMs) ? Math.max(0, nowMs - startedMs) : Infinity;
37709
+ return { locked: true, startedAt, ageMs, stale: ageMs >= SLEEP_LOCK_STALE_MS };
37710
+ }
37658
37711
  function buildHistoryEntry(prevDebt, result, summary, today2) {
37659
37712
  return {
37660
37713
  date: today2,
@@ -37688,24 +37741,33 @@ function cloneState(state) {
37688
37741
  pendingMigrationNotices: [...state.pendingMigrationNotices]
37689
37742
  };
37690
37743
  }
37691
- var DEPTH_ORDER, COMPACTION_LOG_CAP;
37744
+ var DEBT_DROWSY, DEBT_SLEEPY, DEBT_MUST_SLEEP, RHYTHM_SESSIONS, DEPTH_ORDER, COMPACTION_LOG_CAP, SLEEP_LOCK_STALE_MS, SLEEP_START_LOCK_STALE_MS;
37692
37745
  var init_sleep_consolidation = __esm({
37693
37746
  "src/lib/sleep-consolidation.ts"() {
37694
37747
  "use strict";
37748
+ DEBT_DROWSY = 8;
37749
+ DEBT_SLEEPY = 14;
37750
+ DEBT_MUST_SLEEP = 20;
37751
+ RHYTHM_SESSIONS = 5;
37695
37752
  DEPTH_ORDER = ["light", "standard", "deep"];
37696
37753
  COMPACTION_LOG_CAP = 20;
37754
+ SLEEP_LOCK_STALE_MS = 30 * 60 * 1e3;
37755
+ SLEEP_START_LOCK_STALE_MS = 60 * 1e3;
37697
37756
  }
37698
37757
  });
37699
37758
 
37700
37759
  // src/cli/commands/sleep.ts
37701
37760
  import { existsSync as existsSync42 } from "fs";
37702
- import { join as join42, dirname as dirname23 } from "path";
37761
+ import { join as join42, dirname as dirname24 } from "path";
37703
37762
  function getSleepPath(root) {
37704
37763
  return join42(root, "state", ".sleep.json");
37705
37764
  }
37706
37765
  function getSleepHistoryPath(root) {
37707
37766
  return join42(root, "state", ".sleep-history.json");
37708
37767
  }
37768
+ function getSleepStartLockPath(root) {
37769
+ return join42(root, "state", ".sleep.start.lock");
37770
+ }
37709
37771
  function freshDefaults() {
37710
37772
  return {
37711
37773
  debt: 0,
@@ -37840,46 +37902,74 @@ function registerSleepCommand(program2) {
37840
37902
  writeSleepState(root, state);
37841
37903
  const level = sleepinessLevel(state.debt);
37842
37904
  success(`Sleep debt: ${state.debt} (${level})`);
37843
- if (state.debt >= 10) {
37844
- warn("Must sleep! Debt is 10+. Consolidation needed.");
37845
- } else if (state.debt >= 7) {
37905
+ if (state.debt >= DEBT_MUST_SLEEP) {
37906
+ warn(`Must sleep! Debt is ${DEBT_MUST_SLEEP}+. Consolidation needed.`);
37907
+ } else if (state.debt >= DEBT_SLEEPY) {
37846
37908
  info("Getting sleepy. Consider consolidating soon.");
37847
37909
  }
37848
37910
  });
37849
- sleep2.command("start").description("Mark beginning of consolidation (sets epoch for safe clearing)").option("--deep", "Force a deep consolidation (authorizes destructive knowledge ops)").action((opts) => {
37911
+ sleep2.command("start").description("Mark beginning of consolidation (sets epoch for safe clearing)").option("--deep", "Force a deep consolidation (authorizes destructive knowledge ops)").option("--force", "Take over an in-progress consolidation lock (a stuck or parallel sleep)").action((opts) => {
37850
37912
  const root = ensureContextRoot();
37851
- const state = readSleepState(root);
37852
- if (state.sleep_started_at) {
37853
- warn(`Consolidation already in progress (started ${state.sleep_started_at}). Overwriting epoch.`);
37854
- }
37855
- const decision = consolidationDepth(state.debt, { userRequestedDeep: !!opts.deep });
37856
- state.consolidation_depth = decision.depth;
37857
- state.pendingMigrationNotices = [];
37858
- const projectRoot = dirname23(root);
37859
- const config = readSetupConfig(projectRoot);
37860
- const fromVersion = config?.setupVersion ?? "0.0.0";
37861
- const migResult = runMigrations(root, fromVersion, dreamcontextVersion());
37862
- const codeNotices = [];
37863
- for (const entry of migResult.applied) {
37864
- if (entry.executor === "code") {
37865
- success(`Migration ${entry.version}/${entry.step}: ${entry.summary}`);
37866
- codeNotices.push(`${entry.version} ${entry.step}: ${entry.summary}`);
37867
- }
37868
- }
37869
- if (codeNotices.length > 0) {
37870
- state.pendingMigrationNotices = codeNotices;
37871
- }
37872
- for (const pat of migResult.pendingAgentTasks) {
37873
- info(
37874
- `Migration ${pat.version} has a pending agent task (${pat.agentTask.id}). Run \`dreamcontext migrations pending\` for instructions.`
37913
+ const startLockPath = getSleepStartLockPath(root);
37914
+ if (!acquireFileLock(startLockPath, Date.now(), SLEEP_START_LOCK_STALE_MS)) {
37915
+ error(
37916
+ "Consolidation already in progress (another `sleep start` is stamping the epoch right now).",
37917
+ "Wait a moment and retry. To take over a genuinely stuck cycle, run `dreamcontext sleep start --force`."
37875
37918
  );
37919
+ process.exitCode = 1;
37920
+ return;
37876
37921
  }
37877
- state.sleep_started_at = (/* @__PURE__ */ new Date()).toISOString();
37878
- writeSleepState(root, state);
37879
- success(`Consolidation epoch set: ${state.sleep_started_at}`);
37880
- info(`Consolidation depth: ${decision.depth} (source: ${decision.source}) \u2014 ${decision.reason}`);
37881
- if (decision.depth !== "deep") {
37882
- info("Light/standard consolidation: do NOT merge/summarize-replace/delete knowledge \u2014 flag candidates in the report instead.");
37922
+ try {
37923
+ const state = readSleepState(root);
37924
+ const lock = inspectSleepLock(state, Date.now());
37925
+ if (lock.locked && !lock.stale && !opts.force) {
37926
+ const ageMin = Math.max(1, Math.round(lock.ageMs / 6e4));
37927
+ error(
37928
+ `Consolidation already in progress (started ${lock.startedAt}, ~${ageMin}m ago).`,
37929
+ "Another session or the desktop Sleep button is consolidating this brain. Wait for it to finish before starting a new sleep \u2014 do NOT dispatch sleep agents now. To take over a stuck cycle, run `dreamcontext sleep start --force`."
37930
+ );
37931
+ process.exitCode = 1;
37932
+ return;
37933
+ }
37934
+ if (lock.locked && lock.stale) {
37935
+ const ageMin = Math.round(lock.ageMs / 6e4);
37936
+ warn(
37937
+ `Reclaiming a stale consolidation lock (started ${lock.startedAt}, ~${ageMin}m ago \u2014 exceeds the ${SLEEP_LOCK_STALE_MS / 6e4}m TTL). The previous sleep likely crashed without \`sleep done\`. Taking over.`
37938
+ );
37939
+ } else if (lock.locked && opts.force) {
37940
+ warn(`--force: taking over an in-progress consolidation lock (started ${lock.startedAt}).`);
37941
+ }
37942
+ const decision = consolidationDepth(state.debt, { userRequestedDeep: !!opts.deep });
37943
+ state.consolidation_depth = decision.depth;
37944
+ state.pendingMigrationNotices = [];
37945
+ const projectRoot = dirname24(root);
37946
+ const config = readSetupConfig(projectRoot);
37947
+ const fromVersion = config?.setupVersion ?? "0.0.0";
37948
+ const migResult = runMigrations(root, fromVersion, dreamcontextVersion());
37949
+ const codeNotices = [];
37950
+ for (const entry of migResult.applied) {
37951
+ if (entry.executor === "code") {
37952
+ success(`Migration ${entry.version}/${entry.step}: ${entry.summary}`);
37953
+ codeNotices.push(`${entry.version} ${entry.step}: ${entry.summary}`);
37954
+ }
37955
+ }
37956
+ if (codeNotices.length > 0) {
37957
+ state.pendingMigrationNotices = codeNotices;
37958
+ }
37959
+ for (const pat of migResult.pendingAgentTasks) {
37960
+ info(
37961
+ `Migration ${pat.version} has a pending agent task (${pat.agentTask.id}). Run \`dreamcontext migrations pending\` for instructions.`
37962
+ );
37963
+ }
37964
+ state.sleep_started_at = (/* @__PURE__ */ new Date()).toISOString();
37965
+ writeSleepState(root, state);
37966
+ success(`Consolidation epoch set: ${state.sleep_started_at}`);
37967
+ info(`Consolidation depth: ${decision.depth} (source: ${decision.source}) \u2014 ${decision.reason}`);
37968
+ if (decision.depth !== "deep") {
37969
+ info("Light/standard consolidation: do NOT merge/summarize-replace/delete knowledge \u2014 flag candidates in the report instead.");
37970
+ }
37971
+ } finally {
37972
+ releaseFileLock(startLockPath);
37883
37973
  }
37884
37974
  });
37885
37975
  sleep2.command("done").argument("<summary...>", "Summary of what was consolidated").description("Mark consolidation complete, reset debt").action(async (summaryParts) => {
@@ -38008,6 +38098,7 @@ var init_sleep = __esm({
38008
38098
  init_migration_runner();
38009
38099
  init_setup_config();
38010
38100
  init_manifest();
38101
+ init_file_lock();
38011
38102
  init_sleep_consolidation();
38012
38103
  }
38013
38104
  });
@@ -38220,7 +38311,7 @@ var init_member_match = __esm({
38220
38311
  });
38221
38312
 
38222
38313
  // src/cli/commands/tasks.ts
38223
- import { join as join44, basename as basename12, dirname as dirname24 } from "path";
38314
+ import { join as join44, basename as basename12, dirname as dirname25 } from "path";
38224
38315
  function getStateDir() {
38225
38316
  const root = ensureContextRoot();
38226
38317
  return join44(root, "state");
@@ -38499,7 +38590,7 @@ function registerTasksCommand(program2) {
38499
38590
  const description = opts.description || name;
38500
38591
  const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
38501
38592
  if (opts.person && opts.person.trim()) {
38502
- const projectRoot = dirname24(ensureContextRoot());
38593
+ const projectRoot = dirname25(ensureContextRoot());
38503
38594
  if (isMultiPerson(readSetupConfig(projectRoot))) {
38504
38595
  const resolved = await resolvePersonSlug(backend, opts.person);
38505
38596
  if ("abort" in resolved) return;
@@ -38967,7 +39058,7 @@ function registerTasksCommand(program2) {
38967
39058
  }
38968
39059
  });
38969
39060
  tasks.command("sync-hooks").argument("<action>", "install | uninstall").description("Install/uninstall best-effort git sync triggers (post-commit, pre-push)").action((action) => {
38970
- const projectRoot = dirname24(ensureContextRoot());
39061
+ const projectRoot = dirname25(ensureContextRoot());
38971
39062
  if (action === "install") {
38972
39063
  const res = installTaskSyncHooks(projectRoot);
38973
39064
  if (res.noGit) {
@@ -39112,7 +39203,7 @@ var init_tasks = __esm({
39112
39203
  });
39113
39204
 
39114
39205
  // src/cli/commands/update.ts
39115
- import { existsSync as existsSync44, readdirSync as readdirSync10, rmSync as rmSync6 } from "fs";
39206
+ import { existsSync as existsSync44, readdirSync as readdirSync10, rmSync as rmSync7 } from "fs";
39116
39207
  import { join as join45 } from "path";
39117
39208
  function buildUpdateSummary(input2) {
39118
39209
  const { platforms, installedCount, packs, removed, setupVersion } = input2;
@@ -39205,7 +39296,7 @@ async function pruneStaleFiles(projectRoot, oldManifest, newManifest, isFirstRun
39205
39296
  for (const rel of owned) {
39206
39297
  const abs = join45(projectRoot, rel);
39207
39298
  try {
39208
- rmSync6(abs, { force: true });
39299
+ rmSync7(abs, { force: true });
39209
39300
  removed.push(rel);
39210
39301
  } catch (e) {
39211
39302
  const msg = e instanceof Error ? e.message : String(e);
@@ -39502,32 +39593,32 @@ var init_secrets2 = __esm({
39502
39593
  // src/lib/marketing/store.ts
39503
39594
  import {
39504
39595
  existsSync as existsSync46,
39505
- mkdirSync as mkdirSync25,
39596
+ mkdirSync as mkdirSync26,
39506
39597
  openSync,
39507
39598
  closeSync,
39508
- readFileSync as readFileSync34,
39509
- writeFileSync as writeFileSync31,
39599
+ readFileSync as readFileSync35,
39600
+ writeFileSync as writeFileSync32,
39510
39601
  renameSync as renameSync10,
39511
39602
  unlinkSync as unlinkSync4,
39512
39603
  readdirSync as readdirSync11
39513
39604
  } from "fs";
39514
- import { dirname as dirname25, join as join48 } from "path";
39605
+ import { dirname as dirname26, join as join48 } from "path";
39515
39606
  import { randomBytes as randomBytes2 } from "crypto";
39516
39607
  function atomicWriteFile(path2, data) {
39517
- mkdirSync25(dirname25(path2), { recursive: true });
39608
+ mkdirSync26(dirname26(path2), { recursive: true });
39518
39609
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
39519
- writeFileSync31(tmp, data, "utf8");
39610
+ writeFileSync32(tmp, data, "utf8");
39520
39611
  renameSync10(tmp, path2);
39521
39612
  }
39522
39613
  function writeJsonWithBridge(jsonPath, bridgePath, jsonValue, bridgeMarkdown) {
39523
- mkdirSync25(dirname25(jsonPath), { recursive: true });
39524
- mkdirSync25(dirname25(bridgePath), { recursive: true });
39614
+ mkdirSync26(dirname26(jsonPath), { recursive: true });
39615
+ mkdirSync26(dirname26(bridgePath), { recursive: true });
39525
39616
  const jsonStr = JSON.stringify(jsonValue, null, 2) + "\n";
39526
39617
  const jsonTmp = `${jsonPath}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
39527
39618
  const bridgeTmp = `${bridgePath}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
39528
- writeFileSync31(jsonTmp, jsonStr, "utf8");
39619
+ writeFileSync32(jsonTmp, jsonStr, "utf8");
39529
39620
  try {
39530
- writeFileSync31(bridgeTmp, bridgeMarkdown, "utf8");
39621
+ writeFileSync32(bridgeTmp, bridgeMarkdown, "utf8");
39531
39622
  } catch (e) {
39532
39623
  try {
39533
39624
  unlinkSync4(jsonTmp);
@@ -39558,9 +39649,9 @@ function pidAlive(pid) {
39558
39649
  }
39559
39650
  function acquireLock() {
39560
39651
  const lockPath = MARKETING_PATHS.lockFile();
39561
- mkdirSync25(marketingRoot(), { recursive: true });
39652
+ mkdirSync26(marketingRoot(), { recursive: true });
39562
39653
  if (existsSync46(lockPath)) {
39563
- const heldRaw = readFileSync34(lockPath, "utf8").trim();
39654
+ const heldRaw = readFileSync35(lockPath, "utf8").trim();
39564
39655
  const heldPid = Number.parseInt(heldRaw, 10);
39565
39656
  if (pidAlive(heldPid)) {
39566
39657
  throw new LockBusyError(heldPid);
@@ -39576,19 +39667,19 @@ function acquireLock() {
39576
39667
  } catch (e) {
39577
39668
  const code = e.code;
39578
39669
  if (code === "EEXIST") {
39579
- const heldRaw = existsSync46(lockPath) ? readFileSync34(lockPath, "utf8").trim() : "?";
39670
+ const heldRaw = existsSync46(lockPath) ? readFileSync35(lockPath, "utf8").trim() : "?";
39580
39671
  throw new LockBusyError(Number.parseInt(heldRaw, 10) || -1);
39581
39672
  }
39582
39673
  throw e;
39583
39674
  }
39584
39675
  try {
39585
- writeFileSync31(fd, String(process.pid), "utf8");
39676
+ writeFileSync32(fd, String(process.pid), "utf8");
39586
39677
  } finally {
39587
39678
  closeSync(fd);
39588
39679
  }
39589
39680
  return function release2() {
39590
39681
  try {
39591
- const heldRaw = readFileSync34(lockPath, "utf8").trim();
39682
+ const heldRaw = readFileSync35(lockPath, "utf8").trim();
39592
39683
  if (Number.parseInt(heldRaw, 10) === process.pid) {
39593
39684
  unlinkSync4(lockPath);
39594
39685
  }
@@ -39650,24 +39741,24 @@ function beginRun(verb, inputs) {
39650
39741
  }
39651
39742
  function appendIndex(runId, verb, status) {
39652
39743
  const path2 = MARKETING_PATHS.runsIndex();
39653
- mkdirSync25(dirname25(path2), { recursive: true });
39744
+ mkdirSync26(dirname26(path2), { recursive: true });
39654
39745
  const ts = (/* @__PURE__ */ new Date()).toISOString();
39655
39746
  const line = `- \`${ts}\` **${verb}** (${status}) \u2014 [\`${runId}\`](./${runId}.json)
39656
39747
  `;
39657
39748
  let header2 = "";
39658
39749
  let body = "";
39659
39750
  if (existsSync46(path2)) {
39660
- body = readFileSync34(path2, "utf8");
39751
+ body = readFileSync35(path2, "utf8");
39661
39752
  } else {
39662
39753
  header2 = "# Marketing runs (LIFO)\n\n";
39663
39754
  }
39664
39755
  if (header2) {
39665
- writeFileSync31(path2, header2 + line + body, "utf8");
39756
+ writeFileSync32(path2, header2 + line + body, "utf8");
39666
39757
  } else if (body.startsWith("# Marketing runs (LIFO)\n\n")) {
39667
39758
  const HDR = "# Marketing runs (LIFO)\n\n";
39668
- writeFileSync31(path2, HDR + line + body.slice(HDR.length), "utf8");
39759
+ writeFileSync32(path2, HDR + line + body.slice(HDR.length), "utf8");
39669
39760
  } else {
39670
- writeFileSync31(path2, "# Marketing runs (LIFO)\n\n" + line + body, "utf8");
39761
+ writeFileSync32(path2, "# Marketing runs (LIFO)\n\n" + line + body, "utf8");
39671
39762
  }
39672
39763
  }
39673
39764
  var LockBusyError;
@@ -39687,7 +39778,7 @@ var init_store = __esm({
39687
39778
  });
39688
39779
 
39689
39780
  // src/lib/marketing/cohort.ts
39690
- import { existsSync as existsSync47, readFileSync as readFileSync35, readdirSync as readdirSync12 } from "fs";
39781
+ import { existsSync as existsSync47, readFileSync as readFileSync36, readdirSync as readdirSync12 } from "fs";
39691
39782
  import { join as join49 } from "path";
39692
39783
  function newCohortId() {
39693
39784
  return `coh_${idgen()}`;
@@ -39703,7 +39794,7 @@ function loadCohort(id) {
39703
39794
  const { json } = cohortPaths(id);
39704
39795
  if (!existsSync47(json)) return null;
39705
39796
  try {
39706
- return JSON.parse(readFileSync35(json, "utf8"));
39797
+ return JSON.parse(readFileSync36(json, "utf8"));
39707
39798
  } catch {
39708
39799
  return null;
39709
39800
  }
@@ -39715,7 +39806,7 @@ function listCohorts() {
39715
39806
  const cohorts = [];
39716
39807
  for (const f of files) {
39717
39808
  try {
39718
- const c = JSON.parse(readFileSync35(join49(dir, f), "utf8"));
39809
+ const c = JSON.parse(readFileSync36(join49(dir, f), "utf8"));
39719
39810
  cohorts.push(c);
39720
39811
  } catch {
39721
39812
  }
@@ -39769,17 +39860,17 @@ var init_cohort = __esm({
39769
39860
  // src/lib/marketing/learnings.ts
39770
39861
  import {
39771
39862
  existsSync as existsSync48,
39772
- mkdirSync as mkdirSync26,
39773
- readFileSync as readFileSync36,
39774
- writeFileSync as writeFileSync32,
39863
+ mkdirSync as mkdirSync27,
39864
+ readFileSync as readFileSync37,
39865
+ writeFileSync as writeFileSync33,
39775
39866
  renameSync as renameSync11
39776
39867
  } from "fs";
39777
- import { dirname as dirname26 } from "path";
39868
+ import { dirname as dirname27 } from "path";
39778
39869
  import { randomBytes as randomBytes3 } from "crypto";
39779
39870
  function atomicWriteFile2(path2, data) {
39780
- mkdirSync26(dirname26(path2), { recursive: true });
39871
+ mkdirSync27(dirname27(path2), { recursive: true });
39781
39872
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
39782
- writeFileSync32(tmp, data, "utf8");
39873
+ writeFileSync33(tmp, data, "utf8");
39783
39874
  renameSync11(tmp, path2);
39784
39875
  }
39785
39876
  function newLearningId(type) {
@@ -39794,7 +39885,7 @@ function loadIndex() {
39794
39885
  return { version: INDEX_VERSION, entries: [] };
39795
39886
  }
39796
39887
  try {
39797
- const parsed = JSON.parse(readFileSync36(path2, "utf8"));
39888
+ const parsed = JSON.parse(readFileSync37(path2, "utf8"));
39798
39889
  if (parsed.version !== INDEX_VERSION || !Array.isArray(parsed.entries)) {
39799
39890
  return { version: INDEX_VERSION, entries: [] };
39800
39891
  }
@@ -39809,7 +39900,7 @@ function saveIndex(index) {
39809
39900
  function loadByDate(date) {
39810
39901
  const path2 = MARKETING_PATHS.learningsFile(date);
39811
39902
  if (!existsSync48(path2)) return null;
39812
- return readFileSync36(path2, "utf8");
39903
+ return readFileSync37(path2, "utf8");
39813
39904
  }
39814
39905
  function renderEntryBlock(entry, body) {
39815
39906
  const time = entry.created_at.slice(11, 16);
@@ -39844,7 +39935,7 @@ function ensureDailyHeader(date, existing) {
39844
39935
  }
39845
39936
  function appendToDayFile(entry, body) {
39846
39937
  const path2 = MARKETING_PATHS.learningsFile(entry.date_file);
39847
- const existing = existsSync48(path2) ? readFileSync36(path2, "utf8") : null;
39938
+ const existing = existsSync48(path2) ? readFileSync37(path2, "utf8") : null;
39848
39939
  const base = ensureDailyHeader(entry.date_file, existing);
39849
39940
  const block = renderEntryBlock(entry, body);
39850
39941
  const next = existing && existing.startsWith("# Marketing learnings") ? existing.endsWith("\n") ? existing + block : existing + "\n" + block : base + block;
@@ -39853,7 +39944,7 @@ function appendToDayFile(entry, body) {
39853
39944
  function rewriteDayFileForStatusUpdate(oldEntry, newEntry) {
39854
39945
  const path2 = MARKETING_PATHS.learningsFile(oldEntry.date_file);
39855
39946
  if (!existsSync48(path2)) return;
39856
- const text = readFileSync36(path2, "utf8");
39947
+ const text = readFileSync37(path2, "utf8");
39857
39948
  const re = new RegExp(
39858
39949
  `<!-- entry ([^>]*?id=${escapeRegExp(oldEntry.id)}[^>]*) -->`
39859
39950
  );
@@ -39961,7 +40052,7 @@ var init_learnings = __esm({
39961
40052
  });
39962
40053
 
39963
40054
  // src/lib/marketing/snapshot.ts
39964
- import { existsSync as existsSync49, readFileSync as readFileSync37 } from "fs";
40055
+ import { existsSync as existsSync49, readFileSync as readFileSync38 } from "fs";
39965
40056
  function buildMarketingSnapshot(opts = {}) {
39966
40057
  const root = marketingRootIfExists();
39967
40058
  if (!root || !existsSync49(root)) return null;
@@ -40023,7 +40114,7 @@ function readLastInsightsPull() {
40023
40114
  const idxPath = MARKETING_PATHS.insightsDir() + "/_index.json";
40024
40115
  if (!existsSync49(idxPath)) return null;
40025
40116
  try {
40026
- const raw = JSON.parse(readFileSync37(idxPath, "utf8"));
40117
+ const raw = JSON.parse(readFileSync38(idxPath, "utf8"));
40027
40118
  return raw.updated_at && raw.updated_at !== "1970-01-01T00:00:00Z" ? raw.updated_at : null;
40028
40119
  } catch {
40029
40120
  return null;
@@ -40121,8 +40212,8 @@ var init_setup_drift = __esm({
40121
40212
  });
40122
40213
 
40123
40214
  // src/lib/asset-drift-cache.ts
40124
- import { existsSync as existsSync50, readFileSync as readFileSync38, writeFileSync as writeFileSync33, mkdirSync as mkdirSync27 } from "fs";
40125
- import { join as join50, dirname as dirname27 } from "path";
40215
+ import { existsSync as existsSync50, readFileSync as readFileSync39, writeFileSync as writeFileSync34, mkdirSync as mkdirSync28 } from "fs";
40216
+ import { join as join50, dirname as dirname28 } from "path";
40126
40217
  function assetDriftCachePath(contextRoot) {
40127
40218
  return join50(contextRoot, "state", ".asset-drift.json");
40128
40219
  }
@@ -40130,7 +40221,7 @@ function readAssetDriftCache(contextRoot) {
40130
40221
  try {
40131
40222
  const p = assetDriftCachePath(contextRoot);
40132
40223
  if (!existsSync50(p)) return null;
40133
- const parsed = JSON.parse(readFileSync38(p, "utf-8"));
40224
+ const parsed = JSON.parse(readFileSync39(p, "utf-8"));
40134
40225
  if (!parsed || typeof parsed.cliVersion !== "string" || typeof parsed.setupVersion !== "string" || typeof parsed.usedAssetsChanged !== "boolean") {
40135
40226
  return null;
40136
40227
  }
@@ -40146,8 +40237,8 @@ function readAssetDriftCache(contextRoot) {
40146
40237
  }
40147
40238
  function writeAssetDriftCache(contextRoot, cache) {
40148
40239
  const p = assetDriftCachePath(contextRoot);
40149
- mkdirSync27(dirname27(p), { recursive: true });
40150
- writeFileSync33(p, JSON.stringify(cache, null, 2) + "\n", "utf-8");
40240
+ mkdirSync28(dirname28(p), { recursive: true });
40241
+ writeFileSync34(p, JSON.stringify(cache, null, 2) + "\n", "utf-8");
40151
40242
  }
40152
40243
  function cacheConfidentlyClean(cache, cliVersion, setupVersion) {
40153
40244
  return cache !== null && cache.cliVersion === cliVersion && cache.setupVersion === setupVersion && cache.usedAssetsChanged === false;
@@ -40292,7 +40383,7 @@ var init_recall_synonyms = __esm({
40292
40383
  });
40293
40384
 
40294
40385
  // src/lib/session-digest.ts
40295
- import { existsSync as existsSync51, mkdirSync as mkdirSync28, writeFileSync as writeFileSync34 } from "fs";
40386
+ import { existsSync as existsSync51, mkdirSync as mkdirSync29, writeFileSync as writeFileSync35 } from "fs";
40296
40387
  import { join as join51 } from "path";
40297
40388
  function coerceCreatedAt(value) {
40298
40389
  if (typeof value === "string" && value.trim()) return value.trim();
@@ -40372,7 +40463,7 @@ function digestIsPartial(root, sessionId) {
40372
40463
  }
40373
40464
  function writeDigest(root, sessionId, md, opts = {}) {
40374
40465
  const dir = digestsDir(root);
40375
- mkdirSync28(dir, { recursive: true });
40466
+ mkdirSync29(dir, { recursive: true });
40376
40467
  const file = digestPath(root, sessionId);
40377
40468
  const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
40378
40469
  const frontmatter = [
@@ -40384,7 +40475,7 @@ function writeDigest(root, sessionId, md, opts = {}) {
40384
40475
  "---",
40385
40476
  ""
40386
40477
  ].join("\n");
40387
- writeFileSync34(file, frontmatter + md, "utf-8");
40478
+ writeFileSync35(file, frontmatter + md, "utf-8");
40388
40479
  return file;
40389
40480
  }
40390
40481
  function loadDigestDocs(root) {
@@ -40452,8 +40543,8 @@ var init_session_digest = __esm({
40452
40543
  });
40453
40544
 
40454
40545
  // src/lib/recall.ts
40455
- import { existsSync as existsSync52, readFileSync as readFileSync40 } from "fs";
40456
- import { join as join52, basename as basename14, dirname as dirname28, relative as relative3 } from "path";
40546
+ import { existsSync as existsSync52, readFileSync as readFileSync41 } from "fs";
40547
+ import { join as join52, basename as basename14, dirname as dirname29, relative as relative3 } from "path";
40457
40548
  function isFederated(doc) {
40458
40549
  return doc.federated === true;
40459
40550
  }
@@ -40590,7 +40681,7 @@ function loadChangelogEntries(contextRoot) {
40590
40681
  if (!existsSync52(path2)) return [];
40591
40682
  let entries = [];
40592
40683
  try {
40593
- const raw = readFileSync40(path2, "utf-8");
40684
+ const raw = readFileSync41(path2, "utf-8");
40594
40685
  const parsed = JSON.parse(raw);
40595
40686
  if (Array.isArray(parsed)) entries = parsed;
40596
40687
  } catch {
@@ -40640,7 +40731,7 @@ function loadChangelogEntries(contextRoot) {
40640
40731
  function loadMemoryFile(contextRoot) {
40641
40732
  const path2 = join52(contextRoot, "core", "2.memory.md");
40642
40733
  if (!existsSync52(path2)) return [];
40643
- const raw = readFileSync40(path2, "utf-8");
40734
+ const raw = readFileSync41(path2, "utf-8");
40644
40735
  const sections = raw.split(/^##\s+/m).slice(1);
40645
40736
  const out = [];
40646
40737
  for (let i = 0; i < sections.length; i++) {
@@ -40676,7 +40767,7 @@ function loadBookmarkDocs(contextRoot) {
40676
40767
  if (!existsSync52(path2)) return [];
40677
40768
  let bookmarks = [];
40678
40769
  try {
40679
- const parsed = JSON.parse(readFileSync40(path2, "utf-8"));
40770
+ const parsed = JSON.parse(readFileSync41(path2, "utf-8"));
40680
40771
  if (parsed && typeof parsed === "object" && Array.isArray(parsed.bookmarks)) {
40681
40772
  bookmarks = parsed.bookmarks;
40682
40773
  }
@@ -40725,7 +40816,7 @@ function loadSkillDocs(skillsRoot) {
40725
40816
  try {
40726
40817
  const { data, content } = readFrontmatter(file);
40727
40818
  if (data.alwaysApply === true) continue;
40728
- const slug = typeof data.name === "string" && data.name ? data.name : basename14(dirname28(file));
40819
+ const slug = typeof data.name === "string" && data.name ? data.name : basename14(dirname29(file));
40729
40820
  const title = slug;
40730
40821
  const description = typeof data.description === "string" ? data.description : "";
40731
40822
  const tags = Array.isArray(data.tags) ? data.tags.map(String) : [];
@@ -41125,7 +41216,7 @@ var init_federation_config = __esm({
41125
41216
  });
41126
41217
 
41127
41218
  // src/lib/federation-recall.ts
41128
- import { basename as basename15, dirname as dirname29 } from "path";
41219
+ import { basename as basename15, dirname as dirname30 } from "path";
41129
41220
  function namespacedKey(vault, type, slug) {
41130
41221
  return `${vault}::${type}/${slug}`;
41131
41222
  }
@@ -41150,7 +41241,7 @@ function crossVaultRecall(query, opts) {
41150
41241
  }
41151
41242
  const isCurrent = target.current === true;
41152
41243
  if (!isCurrent) {
41153
- const projectRoot = dirname29(contextRoot);
41244
+ const projectRoot = dirname30(contextRoot);
41154
41245
  if (!isShareable(projectRoot)) continue;
41155
41246
  }
41156
41247
  const corpus = buildCorpus(contextRoot, opts.types ? { types: opts.types } : {}).filter((doc) => !isFederated(doc));
@@ -41223,8 +41314,8 @@ var init_federation_recall = __esm({
41223
41314
  });
41224
41315
 
41225
41316
  // src/lib/federation-peer-summary.ts
41226
- import { existsSync as existsSync53, mkdirSync as mkdirSync29, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
41227
- import { dirname as dirname30, join as join53 } from "path";
41317
+ import { existsSync as existsSync53, mkdirSync as mkdirSync30, readFileSync as readFileSync42, writeFileSync as writeFileSync36 } from "fs";
41318
+ import { dirname as dirname31, join as join53 } from "path";
41228
41319
  function peerSummaryCachePath(contextRoot) {
41229
41320
  return join53(contextRoot, CACHE_REL_PATH2);
41230
41321
  }
@@ -41232,7 +41323,7 @@ function readPeerSummaryCache(contextRoot) {
41232
41323
  const path2 = peerSummaryCachePath(contextRoot);
41233
41324
  if (!existsSync53(path2)) return null;
41234
41325
  try {
41235
- const parsed = JSON.parse(readFileSync41(path2, "utf-8"));
41326
+ const parsed = JSON.parse(readFileSync42(path2, "utf-8"));
41236
41327
  if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.peers)) return null;
41237
41328
  const peers = parsed.peers.filter((p) => p !== null && typeof p === "object").map(sanitizePeer);
41238
41329
  return {
@@ -41353,7 +41444,7 @@ function readTopTags(peerRoot) {
41353
41444
  return Array.from(counts.entries()).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_TAGS).map(([t]) => t);
41354
41445
  }
41355
41446
  function refreshPeerSummaries(contextRoot, home) {
41356
- const { name, target } = currentVaultTarget(dirname30(contextRoot), home);
41447
+ const { name, target } = currentVaultTarget(dirname31(contextRoot), home);
41357
41448
  const targets = resolveConnectedVaults(target, contextRoot, home).filter(
41358
41449
  (t) => t.current !== true && t.name !== name
41359
41450
  );
@@ -41373,8 +41464,8 @@ function refreshPeerSummaries(contextRoot, home) {
41373
41464
  }
41374
41465
  function writePeerSummaryCache(contextRoot, cache) {
41375
41466
  const path2 = peerSummaryCachePath(contextRoot);
41376
- mkdirSync29(dirname30(path2), { recursive: true });
41377
- writeFileSync35(path2, JSON.stringify(cache, null, 2) + "\n", "utf-8");
41467
+ mkdirSync30(dirname31(path2), { recursive: true });
41468
+ writeFileSync36(path2, JSON.stringify(cache, null, 2) + "\n", "utf-8");
41378
41469
  }
41379
41470
  var import_fast_glob13, CACHE_REL_PATH2, MAX_ACTIVITY, MAX_TAGS, WHAT_IT_IS_CHARS;
41380
41471
  var init_federation_peer_summary = __esm({
@@ -41497,8 +41588,8 @@ var init_snapshot_budget = __esm({
41497
41588
  });
41498
41589
 
41499
41590
  // src/cli/commands/snapshot.ts
41500
- import { readFileSync as readFileSync42, existsSync as existsSync54, statSync as statSync6 } from "fs";
41501
- import { join as join54, basename as basename16, dirname as dirname31 } from "path";
41591
+ import { readFileSync as readFileSync43, existsSync as existsSync54, statSync as statSync7 } from "fs";
41592
+ import { join as join54, basename as basename16, dirname as dirname32 } from "path";
41502
41593
  function extractFirstParagraph(content) {
41503
41594
  const lines = content.split("\n");
41504
41595
  const paragraphLines = [];
@@ -41582,7 +41673,7 @@ function resolveActiveTaskPath(root) {
41582
41673
  const overridePath = join54(stateDir, ".active-task");
41583
41674
  if (existsSync54(overridePath)) {
41584
41675
  try {
41585
- const slug = readFileSync42(overridePath, "utf-8").trim();
41676
+ const slug = readFileSync43(overridePath, "utf-8").trim();
41586
41677
  if (slug) {
41587
41678
  const taskPath = join54(stateDir, `${slug}.md`);
41588
41679
  if (existsSync54(taskPath)) return taskPath;
@@ -41599,7 +41690,7 @@ function resolveActiveTaskPath(root) {
41599
41690
  if (status !== "in_progress") continue;
41600
41691
  let mtime = 0;
41601
41692
  try {
41602
- mtime = statSync6(file).mtimeMs;
41693
+ mtime = statSync7(file).mtimeMs;
41603
41694
  } catch {
41604
41695
  }
41605
41696
  candidates.push({ path: file, mtime });
@@ -41611,7 +41702,7 @@ function resolveActiveTaskPath(root) {
41611
41702
  return candidates[0].path;
41612
41703
  }
41613
41704
  function getActiveProductKnowledge(root) {
41614
- const config = readSetupConfig(dirname31(root));
41705
+ const config = readSetupConfig(dirname32(root));
41615
41706
  if (!config || !Array.isArray(config.multiProduct) || config.multiProduct.length === 0) {
41616
41707
  return [];
41617
41708
  }
@@ -41632,7 +41723,7 @@ function getActiveProductKnowledge(root) {
41632
41723
  if (!existsSync54(productKnowledgePath)) return [];
41633
41724
  let raw;
41634
41725
  try {
41635
- raw = readFileSync42(productKnowledgePath, "utf-8");
41726
+ raw = readFileSync43(productKnowledgePath, "utf-8");
41636
41727
  } catch {
41637
41728
  return [];
41638
41729
  }
@@ -41667,7 +41758,7 @@ function getActiveProductKnowledge(root) {
41667
41758
  }
41668
41759
  function getVersionNudge(root) {
41669
41760
  try {
41670
- const projectRoot = dirname31(root);
41761
+ const projectRoot = dirname32(root);
41671
41762
  const cache = readVersionCache(projectRoot);
41672
41763
  if (!cache || !isCacheFresh(cache)) return "";
41673
41764
  const installedCli = dreamcontextVersion();
@@ -41685,7 +41776,7 @@ function getMigrationNote(root) {
41685
41776
  try {
41686
41777
  const sleepPath = join54(root, "state", ".sleep.json");
41687
41778
  if (!existsSync54(sleepPath)) return "";
41688
- const raw = readFileSync42(sleepPath, "utf-8");
41779
+ const raw = readFileSync43(sleepPath, "utf-8");
41689
41780
  const parsed = JSON.parse(raw);
41690
41781
  if (!parsed || !Array.isArray(parsed.pendingMigrationNotices) || parsed.pendingMigrationNotices.length === 0) {
41691
41782
  return "";
@@ -41703,7 +41794,7 @@ Migrations applied since last session: ${notices.join("; ")}`;
41703
41794
  }
41704
41795
  function getDriftDirective(root) {
41705
41796
  try {
41706
- const projectRoot = dirname31(root);
41797
+ const projectRoot = dirname32(root);
41707
41798
  const config = readSetupConfig(projectRoot);
41708
41799
  if (!config) return "";
41709
41800
  const cliVersion = dreamcontextVersion();
@@ -41735,14 +41826,14 @@ function generateSnapshot(rootOverride) {
41735
41826
  };
41736
41827
  const soulPath = join54(root, "core", "0.soul.md");
41737
41828
  if (existsSync54(soulPath)) {
41738
- const content = readFileSync42(soulPath, "utf-8").trim();
41829
+ const content = readFileSync43(soulPath, "utf-8").trim();
41739
41830
  parts.push("## Soul (Agent Identity, Principles, Rules)\n");
41740
41831
  parts.push(content);
41741
41832
  parts.push("");
41742
41833
  }
41743
41834
  const userPath = join54(root, "core", "1.user.md");
41744
41835
  if (existsSync54(userPath)) {
41745
- const content = readFileSync42(userPath, "utf-8").trim();
41836
+ const content = readFileSync43(userPath, "utf-8").trim();
41746
41837
  parts.push("## User (Preferences, Project Details, Rules)\n");
41747
41838
  parts.push(content);
41748
41839
  parts.push("");
@@ -41757,7 +41848,7 @@ function generateSnapshot(rootOverride) {
41757
41848
  }
41758
41849
  const memoryPath = join54(root, "core", "2.memory.md");
41759
41850
  if (existsSync54(memoryPath)) {
41760
- const content = readFileSync42(memoryPath, "utf-8").trim();
41851
+ const content = readFileSync43(memoryPath, "utf-8").trim();
41761
41852
  if (content) {
41762
41853
  parts.push("## Memory (Technical Decisions, Known Issues, Session Log)\n");
41763
41854
  parts.push(content);
@@ -41859,7 +41950,7 @@ function generateSnapshot(rootOverride) {
41859
41950
  const CHANGELOG_TIER2 = 10;
41860
41951
  const TIER1_BODY_CHARS = 300;
41861
41952
  const TIER2_LINE_CHARS = 140;
41862
- const multiPerson = isMultiPerson(readSetupConfig(dirname31(root)));
41953
+ const multiPerson = isMultiPerson(readSetupConfig(dirname32(root)));
41863
41954
  const authorSuffix = (e) => {
41864
41955
  if (!multiPerson) return "";
41865
41956
  const authors = Array.isArray(e.authors) ? e.authors.filter((a) => typeof a === "string") : [];
@@ -42398,7 +42489,7 @@ var init_snapshot2 = __esm({
42398
42489
  });
42399
42490
 
42400
42491
  // src/cli/commands/transcript.ts
42401
- import { readFileSync as readFileSync43, existsSync as existsSync55, statSync as statSync7 } from "fs";
42492
+ import { readFileSync as readFileSync44, existsSync as existsSync55, statSync as statSync8 } from "fs";
42402
42493
  function isSystemNoiseMessage(text) {
42403
42494
  const t = text.trim();
42404
42495
  if (!t) return true;
@@ -42419,9 +42510,9 @@ function distillTranscript(transcriptPath, sinceTimestamp) {
42419
42510
  };
42420
42511
  if (!existsSync55(transcriptPath)) return result;
42421
42512
  try {
42422
- const stat = statSync7(transcriptPath);
42513
+ const stat = statSync8(transcriptPath);
42423
42514
  if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES) return result;
42424
- const content = readFileSync43(transcriptPath, "utf-8");
42515
+ const content = readFileSync44(transcriptPath, "utf-8");
42425
42516
  const lines = content.split("\n").filter((l) => l.trim());
42426
42517
  for (const line of lines) {
42427
42518
  let entry;
@@ -42691,7 +42782,7 @@ var init_salience = __esm({
42691
42782
 
42692
42783
  // src/lib/marketing/path-guards.ts
42693
42784
  import { existsSync as existsSync56, realpathSync } from "fs";
42694
- import { basename as basename17, dirname as dirname32, resolve as resolve11, sep as sep7 } from "path";
42785
+ import { basename as basename17, dirname as dirname33, resolve as resolve11, sep as sep7 } from "path";
42695
42786
  function isMarketingEnvPath(filePath, from) {
42696
42787
  if (!filePath) return false;
42697
42788
  const root = resolveContextRoot(from);
@@ -42715,7 +42806,7 @@ function realpathOfNearestAncestor(p) {
42715
42806
  const tail = [];
42716
42807
  while (current && current !== sep7 && !existsSync56(current)) {
42717
42808
  tail.unshift(basename17(current));
42718
- current = dirname32(current);
42809
+ current = dirname33(current);
42719
42810
  }
42720
42811
  if (!current || current === sep7) return p;
42721
42812
  try {
@@ -42856,9 +42947,9 @@ If pure greeting: {"skip":true}`;
42856
42947
  });
42857
42948
 
42858
42949
  // src/cli/commands/asset-drift.ts
42859
- import { mkdtempSync as mkdtempSync2, rmSync as rmSync7, existsSync as existsSync57, readFileSync as readFileSync44, readdirSync as readdirSync13 } from "fs";
42950
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync8, existsSync as existsSync57, readFileSync as readFileSync45, readdirSync as readdirSync13 } from "fs";
42860
42951
  import { tmpdir as tmpdir2 } from "os";
42861
- import { join as join55, dirname as dirname33 } from "path";
42952
+ import { join as join55, dirname as dirname34 } from "path";
42862
42953
  function walkFiles(dir, base, out) {
42863
42954
  for (const entry of readdirSync13(dir, { withFileTypes: true })) {
42864
42955
  const abs = join55(dir, entry.name);
@@ -42882,18 +42973,18 @@ async function computeUsedAssetsChanged(projectRoot, config) {
42882
42973
  if (rel.startsWith("_dream_context/")) continue;
42883
42974
  const onDisk = join55(projectRoot, rel);
42884
42975
  if (!existsSync57(onDisk)) return true;
42885
- if (!readFileSync44(join55(tmp, rel)).equals(readFileSync44(onDisk))) return true;
42976
+ if (!readFileSync45(join55(tmp, rel)).equals(readFileSync45(onDisk))) return true;
42886
42977
  }
42887
42978
  return false;
42888
42979
  } finally {
42889
42980
  try {
42890
- rmSync7(tmp, { recursive: true, force: true });
42981
+ rmSync8(tmp, { recursive: true, force: true });
42891
42982
  } catch {
42892
42983
  }
42893
42984
  }
42894
42985
  }
42895
42986
  async function runAssetDriftRefresh(contextRoot) {
42896
- const projectRoot = dirname33(contextRoot);
42987
+ const projectRoot = dirname34(contextRoot);
42897
42988
  const config = readSetupConfig(projectRoot);
42898
42989
  if (!config) return;
42899
42990
  const cliVersion = dreamcontextVersion();
@@ -42923,8 +43014,8 @@ var init_asset_drift = __esm({
42923
43014
  });
42924
43015
 
42925
43016
  // src/lib/initializer-detect.ts
42926
- import { existsSync as existsSync58, statSync as statSync8, readdirSync as readdirSync14, readFileSync as readFileSync45 } from "fs";
42927
- import { join as join56, dirname as dirname34, basename as basename18, extname as extname2, isAbsolute, resolve as resolve12, sep as sep8 } from "path";
43017
+ import { existsSync as existsSync58, statSync as statSync9, readdirSync as readdirSync14, readFileSync as readFileSync46 } from "fs";
43018
+ import { join as join56, dirname as dirname35, basename as basename18, extname as extname2, isAbsolute, resolve as resolve12, sep as sep8 } from "path";
42928
43019
  import { homedir as homedir3 } from "os";
42929
43020
  function isUntouchedTemplateCore(root) {
42930
43021
  try {
@@ -42936,7 +43027,7 @@ function isUntouchedTemplateCore(root) {
42936
43027
  if (!existsSync58(p)) continue;
42937
43028
  let content;
42938
43029
  try {
42939
- content = readFileSync45(p, "utf-8");
43030
+ content = readFileSync46(p, "utf-8");
42940
43031
  } catch {
42941
43032
  continue;
42942
43033
  }
@@ -43007,7 +43098,7 @@ function hasProjectSignal(cwd) {
43007
43098
  }
43008
43099
  for (const d of PROJECT_DIRS) {
43009
43100
  try {
43010
- if (statSync8(join56(cwd, d)).isDirectory()) return true;
43101
+ if (statSync9(join56(cwd, d)).isDirectory()) return true;
43011
43102
  } catch {
43012
43103
  }
43013
43104
  }
@@ -43109,7 +43200,7 @@ function isOwnProject(absPath, contextRoot, cwd) {
43109
43200
  if (norm2 === resolve12(cwd)) return true;
43110
43201
  if (contextRoot) {
43111
43202
  const cr = resolve12(contextRoot);
43112
- const projectRoot = dirname34(cr);
43203
+ const projectRoot = dirname35(cr);
43113
43204
  if (norm2 === cr || norm2 === projectRoot) return true;
43114
43205
  if (norm2.startsWith(cr + sep8)) return true;
43115
43206
  }
@@ -43147,7 +43238,7 @@ function detectPromptTrigger(prompt, opts) {
43147
43238
  if (!abs) continue;
43148
43239
  let st;
43149
43240
  try {
43150
- st = statSync8(abs);
43241
+ st = statSync9(abs);
43151
43242
  } catch {
43152
43243
  continue;
43153
43244
  }
@@ -43294,14 +43385,14 @@ var init_initializer_detect = __esm({
43294
43385
  });
43295
43386
 
43296
43387
  // src/cli/commands/hook.ts
43297
- import { readFileSync as readFileSync46, existsSync as existsSync59, statSync as statSync9 } from "fs";
43388
+ import { readFileSync as readFileSync47, existsSync as existsSync59, statSync as statSync10 } from "fs";
43298
43389
  import { execFileSync as execFileSync5, spawn as spawn3 } from "child_process";
43299
43390
  import { get as httpGet } from "http";
43300
- import { dirname as dirname35, resolve as resolve13, join as join57, extname as extname3, basename as basename19, relative as relative4 } from "path";
43391
+ import { dirname as dirname36, resolve as resolve13, join as join57, extname as extname3, basename as basename19, relative as relative4 } from "path";
43301
43392
  function readStdin() {
43302
43393
  if (process.stdin.isTTY) return null;
43303
43394
  try {
43304
- const raw = readFileSync46(0, "utf-8");
43395
+ const raw = readFileSync47(0, "utf-8");
43305
43396
  if (!raw.trim()) return null;
43306
43397
  const parsed = JSON.parse(raw);
43307
43398
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
@@ -43313,9 +43404,9 @@ function readStdin() {
43313
43404
  function analyzeTranscript(transcriptPath) {
43314
43405
  if (!existsSync59(transcriptPath)) return ZERO_ANALYSIS;
43315
43406
  try {
43316
- const stat = statSync9(transcriptPath);
43407
+ const stat = statSync10(transcriptPath);
43317
43408
  if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES2) return ZERO_ANALYSIS;
43318
- const content = readFileSync46(transcriptPath, "utf-8");
43409
+ const content = readFileSync47(transcriptPath, "utf-8");
43319
43410
  const changeMatches = content.match(/"name"\s*:\s*"(?:Write|Edit)"/g);
43320
43411
  const toolMatches = content.match(/"name"\s*:\s*"[A-Za-z_]+"/g);
43321
43412
  const slugs = /* @__PURE__ */ new Set();
@@ -43411,7 +43502,7 @@ function isJsTsFile(filePath) {
43411
43502
  return JS_TS_EXTENSIONS.has(extname3(filePath).toLowerCase());
43412
43503
  }
43413
43504
  function findProjectConfig(filePath) {
43414
- let dir = dirname35(resolve13(filePath));
43505
+ let dir = dirname36(resolve13(filePath));
43415
43506
  let formatter = null;
43416
43507
  let tsconfig = null;
43417
43508
  for (let i = 0; i <= MAX_WALK_LEVELS; i++) {
@@ -43435,7 +43526,7 @@ function findProjectConfig(filePath) {
43435
43526
  tsconfig = join57(dir, "tsconfig.json");
43436
43527
  }
43437
43528
  if (formatter && tsconfig) break;
43438
- const parent = dirname35(dir);
43529
+ const parent = dirname36(dir);
43439
43530
  if (parent === dir) break;
43440
43531
  dir = parent;
43441
43532
  }
@@ -43485,7 +43576,7 @@ function runFormatter(detection, filePath) {
43485
43576
  }
43486
43577
  }
43487
43578
  function runTscCheckWithConfig(filePath, tsconfigPath) {
43488
- const projectRoot = dirname35(tsconfigPath);
43579
+ const projectRoot = dirname36(tsconfigPath);
43489
43580
  let tscOutput;
43490
43581
  try {
43491
43582
  const localBin = resolveLocalBin("tsc", projectRoot);
@@ -43528,22 +43619,23 @@ function runTscCheckWithConfig(filePath, tsconfigPath) {
43528
43619
  ${relevantErrors.join("\n")}`;
43529
43620
  }
43530
43621
  function getConsolidationDirective(state) {
43531
- const { debt, bookmarks, sessions_since_last_sleep, sleep_started_at } = state;
43532
- if (sleep_started_at) {
43533
- if (debt >= 4) {
43622
+ const { debt, bookmarks, sessions_since_last_sleep } = state;
43623
+ const lock = inspectSleepLock(state, Date.now());
43624
+ if (lock.locked && !lock.stale) {
43625
+ if (debt >= DEBT_DROWSY) {
43534
43626
  return [
43535
- `> Consolidation already in progress (started: ${sleep_started_at}). Do NOT dispatch another sleep agent.`,
43627
+ `> Consolidation already in progress (started: ${lock.startedAt}). Do NOT dispatch another sleep agent.`,
43536
43628
  ""
43537
43629
  ].join("\n");
43538
43630
  }
43539
43631
  return null;
43540
43632
  }
43541
43633
  const criticalBookmarks = bookmarks.filter((b) => b.salience === 3);
43542
- if (debt >= 10) {
43634
+ if (debt >= DEBT_MUST_SLEEP) {
43543
43635
  return [
43544
43636
  ">>> CONSOLIDATION REQUIRED <<<",
43545
43637
  "",
43546
- `Sleep debt is ${debt} (threshold: 10). Context files are stale and bloated.`,
43638
+ `Sleep debt is ${debt} (threshold: ${DEBT_MUST_SLEEP}). Context files are stale and bloated.`,
43547
43639
  ...criticalBookmarks.length > 0 ? [`${criticalBookmarks.length} critical bookmark(s) awaiting consolidation.`] : [],
43548
43640
  "You MUST inform the user and consolidate NOW.",
43549
43641
  'Run sleep consolidation: follow SKILL.md "Sleep" flow \u2014 main agent does `sleep start`, then dispatches sleep-tasks/sleep-state (and sleep-product when signals warrant) in parallel, then `sleep done`.',
@@ -43562,23 +43654,23 @@ function getConsolidationDirective(state) {
43562
43654
  ""
43563
43655
  ].join("\n");
43564
43656
  }
43565
- if (debt >= 7) {
43657
+ if (debt >= DEBT_SLEEPY) {
43566
43658
  return [
43567
43659
  ">> CONSOLIDATION RECOMMENDED <<",
43568
43660
  "",
43569
- `Sleep debt is ${debt}/10. Context files are growing stale.`,
43661
+ `Sleep debt is ${debt}/${DEBT_MUST_SLEEP}. Context files are growing stale.`,
43570
43662
  "You MUST inform the user and recommend consolidation before starting new work.",
43571
43663
  'Run sleep consolidation: follow SKILL.md "Sleep" flow \u2014 main agent does `sleep start`, then dispatches sleep-tasks/sleep-state (and sleep-product when signals warrant) in parallel, then `sleep done`.',
43572
43664
  ""
43573
43665
  ].join("\n");
43574
43666
  }
43575
- if (debt >= 4) {
43667
+ if (debt >= DEBT_DROWSY) {
43576
43668
  return [
43577
43669
  `> Sleep debt is ${debt}. After completing the current task, you MUST offer to consolidate.`,
43578
43670
  ""
43579
43671
  ].join("\n");
43580
43672
  }
43581
- if (sessions_since_last_sleep >= 3) {
43673
+ if (sessions_since_last_sleep >= RHYTHM_SESSIONS) {
43582
43674
  return [
43583
43675
  `> ${sessions_since_last_sleep} sessions since last consolidation. After completing the current task, offer to consolidate.`,
43584
43676
  ""
@@ -43587,24 +43679,25 @@ function getConsolidationDirective(state) {
43587
43679
  return null;
43588
43680
  }
43589
43681
  function userPromptReminder(state) {
43590
- const { debt, bookmarks, sleep_started_at } = state;
43591
- if (sleep_started_at) {
43592
- if (debt >= 4) {
43593
- return `Consolidation already in progress (started: ${sleep_started_at}). Do NOT dispatch another sleep agent.`;
43682
+ const { debt, bookmarks } = state;
43683
+ const lock = inspectSleepLock(state, Date.now());
43684
+ if (lock.locked && !lock.stale) {
43685
+ if (debt >= DEBT_DROWSY) {
43686
+ return `Consolidation already in progress (started: ${lock.startedAt}). Do NOT dispatch another sleep agent.`;
43594
43687
  }
43595
43688
  return null;
43596
43689
  }
43597
43690
  const criticalBookmarks = bookmarks.filter((b) => b.salience === 3);
43598
- if (debt >= 10) {
43691
+ if (debt >= DEBT_MUST_SLEEP) {
43599
43692
  return `Sleep debt is ${debt}. CONSOLIDATION REQUIRED. Run sleep flow per SKILL.md (parallel specialist fan-out) NOW.`;
43600
43693
  }
43601
43694
  if (criticalBookmarks.length > 0) {
43602
43695
  return `${criticalBookmarks.length} critical bookmark(s) need consolidation. Run sleep flow per SKILL.md.`;
43603
43696
  }
43604
- if (debt >= 7) {
43697
+ if (debt >= DEBT_SLEEPY) {
43605
43698
  return `Sleep debt is ${debt}. Consolidation recommended before starting new work.`;
43606
43699
  }
43607
- if (debt >= 4) {
43700
+ if (debt >= DEBT_DROWSY) {
43608
43701
  return `Sleep debt is ${debt}. After completing the current task, offer to consolidate.`;
43609
43702
  }
43610
43703
  return null;
@@ -43855,7 +43948,8 @@ function registerHookCommand(program2) {
43855
43948
  if (!root) process.exit(0);
43856
43949
  const state = readSleepState(root);
43857
43950
  const reminder = userPromptReminder(state);
43858
- if (state.sleep_started_at) {
43951
+ const lock = inspectSleepLock(state, Date.now());
43952
+ if (lock.locked && !lock.stale) {
43859
43953
  if (reminder) console.log(reminder);
43860
43954
  return;
43861
43955
  }
@@ -43882,7 +43976,7 @@ function registerHookCommand(program2) {
43882
43976
  }
43883
43977
  if (process.env.DREAMCONTEXT_VERSION_CHECK !== "0") {
43884
43978
  try {
43885
- const projectRoot = dirname35(root);
43979
+ const projectRoot = dirname36(root);
43886
43980
  let vcache = readVersionCache(projectRoot);
43887
43981
  if (!isCacheFresh(vcache)) {
43888
43982
  const loaded = loadCatalog();
@@ -43949,7 +44043,7 @@ function registerHookCommand(program2) {
43949
44043
  if (bumped) writeSleepState(root, state);
43950
44044
  }
43951
44045
  try {
43952
- const { target: currentTarget } = currentVaultTarget(dirname35(root));
44046
+ const { target: currentTarget } = currentVaultTarget(dirname36(root));
43953
44047
  const peerTargets = resolveConnectedVaults(currentTarget, root).filter(
43954
44048
  (t) => t.current !== true
43955
44049
  );
@@ -44147,7 +44241,7 @@ var init_hook = __esm({
44147
44241
  });
44148
44242
 
44149
44243
  // src/cli/commands/doctor.ts
44150
- import { existsSync as existsSync60, readFileSync as readFileSync47, readdirSync as readdirSync15, statSync as statSync10 } from "fs";
44244
+ import { existsSync as existsSync60, readFileSync as readFileSync48, readdirSync as readdirSync15, statSync as statSync11 } from "fs";
44151
44245
  import { join as join58 } from "path";
44152
44246
  function stripDocumentedMentions(content) {
44153
44247
  let result = content.replace(/```[\s\S]*?```/g, "");
@@ -44164,7 +44258,7 @@ function checkFile(root, relPath, label, required) {
44164
44258
  message: required ? `Missing: ${relPath}` : `Optional file not found: ${relPath}`
44165
44259
  };
44166
44260
  }
44167
- const stat = statSync10(fullPath);
44261
+ const stat = statSync11(fullPath);
44168
44262
  if (stat.size === 0) {
44169
44263
  return {
44170
44264
  name: label,
@@ -44173,7 +44267,7 @@ function checkFile(root, relPath, label, required) {
44173
44267
  };
44174
44268
  }
44175
44269
  if (relPath.endsWith(".md")) {
44176
- const content = readFileSync47(fullPath, "utf-8");
44270
+ const content = readFileSync48(fullPath, "utf-8");
44177
44271
  const stripped = stripDocumentedMentions(content);
44178
44272
  if (stripped.includes("(Add your") || stripped.includes("{{") || stripped.includes("(To be defined)")) {
44179
44273
  return {
@@ -44191,7 +44285,7 @@ function checkJson(root, relPath, label) {
44191
44285
  return { name: label, status: "error", message: `Missing: ${relPath}` };
44192
44286
  }
44193
44287
  try {
44194
- const content = readFileSync47(fullPath, "utf-8");
44288
+ const content = readFileSync48(fullPath, "utf-8");
44195
44289
  JSON.parse(content);
44196
44290
  return { name: label, status: "ok", message: relPath };
44197
44291
  } catch {
@@ -44345,7 +44439,7 @@ function registerDoctorCommand(program2) {
44345
44439
  const sleepPath = join58(root, "state", ".sleep.json");
44346
44440
  if (existsSync60(sleepPath)) {
44347
44441
  try {
44348
- const parsed = JSON.parse(readFileSync47(sleepPath, "utf-8"));
44442
+ const parsed = JSON.parse(readFileSync48(sleepPath, "utf-8"));
44349
44443
  if (typeof parsed.debt !== "number" || parsed.debt < 0) {
44350
44444
  results.push({ name: "Sleep debt", status: "warn", message: "Invalid debt value in .sleep.json" });
44351
44445
  }
@@ -44509,7 +44603,7 @@ var init_middleware = __esm({
44509
44603
  });
44510
44604
 
44511
44605
  // src/server/static.ts
44512
- import { existsSync as existsSync61, readFileSync as readFileSync48, statSync as statSync11 } from "fs";
44606
+ import { existsSync as existsSync61, readFileSync as readFileSync49, statSync as statSync12 } from "fs";
44513
44607
  import { join as join59, extname as extname4 } from "path";
44514
44608
  function serveStatic(req, res, staticDir) {
44515
44609
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
@@ -44519,13 +44613,13 @@ function serveStatic(req, res, staticDir) {
44519
44613
  res.end("Forbidden");
44520
44614
  return;
44521
44615
  }
44522
- if (existsSync61(filePath) && statSync11(filePath).isDirectory()) {
44616
+ if (existsSync61(filePath) && statSync12(filePath).isDirectory()) {
44523
44617
  filePath = join59(filePath, "index.html");
44524
44618
  }
44525
- if (existsSync61(filePath) && statSync11(filePath).isFile()) {
44619
+ if (existsSync61(filePath) && statSync12(filePath).isFile()) {
44526
44620
  const ext = extname4(filePath);
44527
44621
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
44528
- const content = readFileSync48(filePath);
44622
+ const content = readFileSync49(filePath);
44529
44623
  res.writeHead(200, {
44530
44624
  "Content-Type": contentType,
44531
44625
  "Content-Length": content.length,
@@ -44534,16 +44628,20 @@ function serveStatic(req, res, staticDir) {
44534
44628
  res.end(content);
44535
44629
  return;
44536
44630
  }
44537
- const indexPath2 = join59(staticDir, "index.html");
44538
- if (existsSync61(indexPath2)) {
44539
- const content = readFileSync48(indexPath2);
44540
- res.writeHead(200, {
44541
- "Content-Type": "text/html; charset=utf-8",
44542
- "Content-Length": content.length,
44543
- "Cache-Control": "no-cache"
44544
- });
44545
- res.end(content);
44546
- return;
44631
+ const acceptsHtml = (req.headers.accept ?? "").includes("text/html");
44632
+ const looksLikeFile = extname4(url.pathname) !== "";
44633
+ if (acceptsHtml || !looksLikeFile) {
44634
+ const indexPath2 = join59(staticDir, "index.html");
44635
+ if (existsSync61(indexPath2)) {
44636
+ const content = readFileSync49(indexPath2);
44637
+ res.writeHead(200, {
44638
+ "Content-Type": "text/html; charset=utf-8",
44639
+ "Content-Length": content.length,
44640
+ "Cache-Control": "no-cache"
44641
+ });
44642
+ res.end(content);
44643
+ return;
44644
+ }
44547
44645
  }
44548
44646
  res.writeHead(404, { "Content-Type": "text/plain" });
44549
44647
  res.end("Not Found");
@@ -44555,11 +44653,14 @@ var init_static = __esm({
44555
44653
  MIME_TYPES = {
44556
44654
  ".html": "text/html; charset=utf-8",
44557
44655
  ".js": "application/javascript; charset=utf-8",
44656
+ ".mjs": "application/javascript; charset=utf-8",
44558
44657
  ".css": "text/css; charset=utf-8",
44559
44658
  ".json": "application/json; charset=utf-8",
44659
+ ".map": "application/json; charset=utf-8",
44560
44660
  ".svg": "image/svg+xml",
44561
44661
  ".png": "image/png",
44562
44662
  ".jpg": "image/jpeg",
44663
+ ".webp": "image/webp",
44563
44664
  ".ico": "image/x-icon",
44564
44665
  ".woff": "font/woff",
44565
44666
  ".woff2": "font/woff2",
@@ -44599,7 +44700,7 @@ var init_change_tracker2 = __esm({
44599
44700
  });
44600
44701
 
44601
44702
  // src/server/routes/tasks.ts
44602
- import { dirname as dirname36 } from "path";
44703
+ import { dirname as dirname37 } from "path";
44603
44704
  function toApiTask(task) {
44604
44705
  const { raw: _raw, rawBody: _rawBody, ...api } = task;
44605
44706
  return api;
@@ -44866,7 +44967,7 @@ function slugToName(slug) {
44866
44967
  return slug.split("-").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
44867
44968
  }
44868
44969
  function rosterMembers(contextRoot) {
44869
- const config = readSetupConfig(dirname36(contextRoot));
44970
+ const config = readSetupConfig(dirname37(contextRoot));
44870
44971
  const people = config?.people ?? [];
44871
44972
  return people.map((slug) => ({
44872
44973
  slug,
@@ -45357,8 +45458,8 @@ async function handleCoreGet(_req, res, params, contextRoot) {
45357
45458
  return;
45358
45459
  }
45359
45460
  if (filename.endsWith(".json")) {
45360
- const { readFileSync: readFileSync77 } = await import("fs");
45361
- const raw2 = readFileSync77(filePath, "utf-8");
45461
+ const { readFileSync: readFileSync79 } = await import("fs");
45462
+ const raw2 = readFileSync79(filePath, "utf-8");
45362
45463
  try {
45363
45464
  const data = JSON.parse(raw2);
45364
45465
  sendJson(res, 200, { filename, type: "json", data });
@@ -45392,8 +45493,8 @@ async function handleCoreGet(_req, res, params, contextRoot) {
45392
45493
  });
45393
45494
  return;
45394
45495
  }
45395
- const { readFileSync: readFileSync76 } = await import("fs");
45396
- const raw = readFileSync76(filePath, "utf-8");
45496
+ const { readFileSync: readFileSync78 } = await import("fs");
45497
+ const raw = readFileSync78(filePath, "utf-8");
45397
45498
  sendJson(res, 200, { filename, type: "text", content: raw });
45398
45499
  }
45399
45500
  async function handleCoreUpdate(req, res, params, contextRoot) {
@@ -45443,8 +45544,8 @@ async function handleCoreUpdate(req, res, params, contextRoot) {
45443
45544
  return;
45444
45545
  }
45445
45546
  changedParts.push("content");
45446
- const { writeFileSync: writeFileSync52 } = await import("fs");
45447
- writeFileSync52(filePath, body.content, "utf-8");
45547
+ const { writeFileSync: writeFileSync55 } = await import("fs");
45548
+ writeFileSync55(filePath, body.content, "utf-8");
45448
45549
  }
45449
45550
  const what = changedParts.length > 0 ? changedParts.join(" and ") : "file";
45450
45551
  recordDashboardChange(contextRoot, {
@@ -45557,7 +45658,7 @@ var require_filesystem = __commonJS({
45557
45658
  var LDD_PATH = "/usr/bin/ldd";
45558
45659
  var SELF_PATH = "/proc/self/exe";
45559
45660
  var MAX_LENGTH = 2048;
45560
- var readFileSync76 = (path2) => {
45661
+ var readFileSync78 = (path2) => {
45561
45662
  const fd = fs.openSync(path2, "r");
45562
45663
  const buffer = Buffer.alloc(MAX_LENGTH);
45563
45664
  const bytesRead = fs.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -45582,7 +45683,7 @@ var require_filesystem = __commonJS({
45582
45683
  module2.exports = {
45583
45684
  LDD_PATH,
45584
45685
  SELF_PATH,
45585
- readFileSync: readFileSync76,
45686
+ readFileSync: readFileSync78,
45586
45687
  readFile
45587
45688
  };
45588
45689
  }
@@ -45631,7 +45732,7 @@ var require_detect_libc = __commonJS({
45631
45732
  "use strict";
45632
45733
  var childProcess = __require("child_process");
45633
45734
  var { isLinux, getReport } = require_process();
45634
- var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync76 } = require_filesystem();
45735
+ var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync78 } = require_filesystem();
45635
45736
  var { interpreterPath } = require_elf();
45636
45737
  var cachedFamilyInterpreter;
45637
45738
  var cachedFamilyFilesystem;
@@ -45723,7 +45824,7 @@ var require_detect_libc = __commonJS({
45723
45824
  }
45724
45825
  cachedFamilyFilesystem = null;
45725
45826
  try {
45726
- const lddContent = readFileSync76(LDD_PATH);
45827
+ const lddContent = readFileSync78(LDD_PATH);
45727
45828
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
45728
45829
  } catch (e) {
45729
45830
  }
@@ -45748,7 +45849,7 @@ var require_detect_libc = __commonJS({
45748
45849
  }
45749
45850
  cachedFamilyInterpreter = null;
45750
45851
  try {
45751
- const selfContent = readFileSync76(SELF_PATH);
45852
+ const selfContent = readFileSync78(SELF_PATH);
45752
45853
  const path2 = interpreterPath(selfContent);
45753
45854
  cachedFamilyInterpreter = familyFromInterpreterPath(path2);
45754
45855
  } catch (e) {
@@ -45812,7 +45913,7 @@ var require_detect_libc = __commonJS({
45812
45913
  }
45813
45914
  cachedVersionFilesystem = null;
45814
45915
  try {
45815
- const lddContent = readFileSync76(LDD_PATH);
45916
+ const lddContent = readFileSync78(LDD_PATH);
45816
45917
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
45817
45918
  if (versionMatch) {
45818
45919
  cachedVersionFilesystem = versionMatch[1];
@@ -52028,8 +52129,8 @@ var require_lib4 = __commonJS({
52028
52129
  });
52029
52130
 
52030
52131
  // src/server/routes/knowledge.ts
52031
- import { existsSync as existsSync63, readFileSync as readFileSync49, statSync as statSync12 } from "fs";
52032
- import { join as join61, dirname as dirname37, basename as basename20, extname as extname5 } from "path";
52132
+ import { existsSync as existsSync63, readFileSync as readFileSync50, statSync as statSync13 } from "fs";
52133
+ import { join as join61, dirname as dirname38, basename as basename20, extname as extname5 } from "path";
52033
52134
  function getKnowledgeDir2(contextRoot) {
52034
52135
  return join61(contextRoot, "knowledge");
52035
52136
  }
@@ -52065,7 +52166,7 @@ function compressionFor(imageCount) {
52065
52166
  async function loadAssetDataURL(abs, maxDim, quality) {
52066
52167
  let mtimeMs;
52067
52168
  try {
52068
- mtimeMs = statSync12(abs).mtimeMs;
52169
+ mtimeMs = statSync13(abs).mtimeMs;
52069
52170
  } catch {
52070
52171
  return null;
52071
52172
  }
@@ -52089,7 +52190,7 @@ async function loadAssetDataURL(abs, maxDim, quality) {
52089
52190
  }
52090
52191
  }
52091
52192
  try {
52092
- const raw = readFileSync49(abs);
52193
+ const raw = readFileSync50(abs);
52093
52194
  const out = {
52094
52195
  mimeType: origMime,
52095
52196
  dataURL: `data:${origMime};base64,${raw.toString("base64")}`,
@@ -52128,7 +52229,7 @@ async function handleKnowledgeGet(_req, res, params, contextRoot) {
52128
52229
  content,
52129
52230
  // mtime lets the dashboard compare the rendered version against the polled
52130
52231
  // list and live-refetch this doc only when its file actually changed.
52131
- mtime: statSync12(filePath).mtimeMs
52232
+ mtime: statSync13(filePath).mtimeMs
52132
52233
  }
52133
52234
  });
52134
52235
  }
@@ -52145,8 +52246,8 @@ async function handleKnowledgeAssets(_req, res, params, contextRoot) {
52145
52246
  }
52146
52247
  const { content } = readFrontmatter(filePath);
52147
52248
  const embedded = parseEmbeddedFiles(content);
52148
- const vaultRoot2 = dirname37(contextRoot);
52149
- const boardDir = dirname37(filePath);
52249
+ const vaultRoot2 = dirname38(contextRoot);
52250
+ const boardDir = dirname38(filePath);
52150
52251
  const imageCount = embedded.filter((e) => IMAGE_MIME[extname5(e.path).toLowerCase()]).length;
52151
52252
  const { maxDim, quality } = compressionFor(imageCount);
52152
52253
  const files = {};
@@ -52227,7 +52328,7 @@ async function handleKnowledgeUpdate(req, res, params, contextRoot) {
52227
52328
  date: data.date ?? "",
52228
52329
  pinned: data.pinned === true,
52229
52330
  content,
52230
- mtime: statSync12(filePath).mtimeMs
52331
+ mtime: statSync13(filePath).mtimeMs
52231
52332
  }
52232
52333
  });
52233
52334
  }
@@ -52614,7 +52715,7 @@ var init_changelog = __esm({
52614
52715
  });
52615
52716
 
52616
52717
  // src/lib/graph.ts
52617
- import { existsSync as existsSync66, readFileSync as readFileSync50 } from "fs";
52718
+ import { existsSync as existsSync66, readFileSync as readFileSync51 } from "fs";
52618
52719
  import { join as join64, basename as basename22 } from "path";
52619
52720
  function buildGraph(contextRoot) {
52620
52721
  const nodes = [];
@@ -52785,7 +52886,7 @@ function buildGraph(contextRoot) {
52785
52886
  let releases = [];
52786
52887
  if (existsSync66(releasesPath)) {
52787
52888
  try {
52788
- const parsed = JSON.parse(readFileSync50(releasesPath, "utf-8"));
52889
+ const parsed = JSON.parse(readFileSync51(releasesPath, "utf-8"));
52789
52890
  if (Array.isArray(parsed)) releases = parsed;
52790
52891
  } catch {
52791
52892
  }
@@ -52881,7 +52982,7 @@ var init_graph = __esm({
52881
52982
  });
52882
52983
 
52883
52984
  // src/server/routes/graph.ts
52884
- import { existsSync as existsSync67, readFileSync as readFileSync51 } from "fs";
52985
+ import { existsSync as existsSync67, readFileSync as readFileSync52 } from "fs";
52885
52986
  import { normalize, resolve as resolve14, sep as sep9 } from "path";
52886
52987
  async function handleGraphGet(_req, res, _params, contextRoot) {
52887
52988
  try {
@@ -52926,7 +53027,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
52926
53027
  }
52927
53028
  if (absTarget.endsWith(".json")) {
52928
53029
  try {
52929
- const raw = readFileSync51(absTarget, "utf-8");
53030
+ const raw = readFileSync52(absTarget, "utf-8");
52930
53031
  try {
52931
53032
  sendJson(res, 200, { path: rawPath, type: "json", data: JSON.parse(raw) });
52932
53033
  } catch {
@@ -52939,7 +53040,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
52939
53040
  return;
52940
53041
  }
52941
53042
  try {
52942
- const content = readFileSync51(absTarget, "utf-8");
53043
+ const content = readFileSync52(absTarget, "utf-8");
52943
53044
  sendJson(res, 200, { path: rawPath, type: "text", content });
52944
53045
  } catch (err) {
52945
53046
  const message = err instanceof Error ? err.message : "Failed to read file";
@@ -52956,7 +53057,7 @@ var init_graph2 = __esm({
52956
53057
  });
52957
53058
 
52958
53059
  // src/lib/council.ts
52959
- import { existsSync as existsSync68, mkdirSync as mkdirSync30, readFileSync as readFileSync52 } from "fs";
53060
+ import { existsSync as existsSync68, mkdirSync as mkdirSync31, readFileSync as readFileSync53 } from "fs";
52960
53061
  import { join as join65, resolve as resolve15, sep as sep10 } from "path";
52961
53062
  import { fileURLToPath as fileURLToPath6 } from "url";
52962
53063
  function getCouncilDir() {
@@ -52997,7 +53098,7 @@ function getCouncilIndexPath() {
52997
53098
  }
52998
53099
  function ensureCouncilDir() {
52999
53100
  const dir = getCouncilDir();
53000
- mkdirSync30(dir, { recursive: true });
53101
+ mkdirSync31(dir, { recursive: true });
53001
53102
  const indexPath2 = getCouncilIndexPath();
53002
53103
  if (!existsSync68(indexPath2)) {
53003
53104
  writeJsonArray(indexPath2, []);
@@ -53054,7 +53155,7 @@ function loadTemplate(filename) {
53054
53155
  ];
53055
53156
  for (const path2 of candidates) {
53056
53157
  if (existsSync68(path2)) {
53057
- return readFileSync52(path2, "utf-8");
53158
+ return readFileSync53(path2, "utf-8");
53058
53159
  }
53059
53160
  }
53060
53161
  throw new Error(`Template not found: ${filename}`);
@@ -53364,9 +53465,9 @@ var init_council2 = __esm({
53364
53465
  });
53365
53466
 
53366
53467
  // src/server/routes/config.ts
53367
- import { dirname as dirname38 } from "path";
53468
+ import { dirname as dirname39 } from "path";
53368
53469
  async function handleConfigGet(_req, res, _params, contextRoot) {
53369
- const config = readSetupConfig(dirname38(contextRoot));
53470
+ const config = readSetupConfig(dirname39(contextRoot));
53370
53471
  sendJson(res, 200, { config });
53371
53472
  }
53372
53473
  async function handleConfigUpdate(req, res, _params, contextRoot) {
@@ -53450,7 +53551,7 @@ async function handleConfigUpdate(req, res, _params, contextRoot) {
53450
53551
  }
53451
53552
  picked.changelogTarget = "comments";
53452
53553
  }
53453
- const existing = readSetupConfig(dirname38(contextRoot))?.clickup ?? {};
53554
+ const existing = readSetupConfig(dirname39(contextRoot))?.clickup ?? {};
53454
53555
  patch.clickup = { ...existing, ...picked };
53455
53556
  }
53456
53557
  if (body.github !== void 0) {
@@ -53476,14 +53577,14 @@ async function handleConfigUpdate(req, res, _params, contextRoot) {
53476
53577
  }
53477
53578
  picked.changelogTarget = "comments";
53478
53579
  }
53479
- const existing = readSetupConfig(dirname38(contextRoot))?.github ?? {};
53580
+ const existing = readSetupConfig(dirname39(contextRoot))?.github ?? {};
53480
53581
  patch.github = { ...existing, ...picked };
53481
53582
  }
53482
53583
  if (patch.platforms === void 0 && patch.packs === void 0 && patch.disableNativeMemory === void 0 && patch.taskBackend === void 0 && patch.cloudTaskManagement === void 0 && patch.clickup === void 0 && patch.github === void 0 && patch.shareable === void 0) {
53483
53584
  sendError(res, 400, "no_changes", "Provide at least one of: platforms, packs, disableNativeMemory, taskBackend, cloudTaskManagement, clickup, github, shareable.");
53484
53585
  return;
53485
53586
  }
53486
- const projectRoot = dirname38(contextRoot);
53587
+ const projectRoot = dirname39(contextRoot);
53487
53588
  if (patch.taskBackend === "clickup" || patch.taskBackend === "github") {
53488
53589
  try {
53489
53590
  ensureRemoteBackendGitignore(projectRoot);
@@ -53510,11 +53611,11 @@ var init_config = __esm({
53510
53611
  });
53511
53612
 
53512
53613
  // src/server/routes/vaults.ts
53513
- import { dirname as dirname39, resolve as resolve17 } from "path";
53614
+ import { dirname as dirname40, resolve as resolve17 } from "path";
53514
53615
  import { existsSync as existsSync70 } from "fs";
53515
53616
  async function handleVaultsGet(_req, res, _params, contextRoot) {
53516
53617
  const vaults = listVaults().map((v) => ({ ...v, exists: existsSync70(resolve17(v.path)) }));
53517
- const current = contextRoot ? vaults.find((v) => resolve17(v.path) === resolve17(dirname39(contextRoot)))?.name ?? null : null;
53618
+ const current = contextRoot ? vaults.find((v) => resolve17(v.path) === resolve17(dirname40(contextRoot)))?.name ?? null : null;
53518
53619
  sendJson(res, 200, { vaults, current });
53519
53620
  }
53520
53621
  var init_vaults2 = __esm({
@@ -53526,7 +53627,7 @@ var init_vaults2 = __esm({
53526
53627
  });
53527
53628
 
53528
53629
  // src/lib/vault-discovery.ts
53529
- import { dirname as dirname40 } from "path";
53630
+ import { dirname as dirname41 } from "path";
53530
53631
  function discoverVaults(root) {
53531
53632
  const matches = import_fast_glob17.default.sync("**/_dream_context", {
53532
53633
  cwd: root,
@@ -53537,7 +53638,7 @@ function discoverVaults(root) {
53537
53638
  suppressErrors: true
53538
53639
  });
53539
53640
  const projects = /* @__PURE__ */ new Set();
53540
- for (const ctx of matches) projects.add(dirname40(ctx));
53641
+ for (const ctx of matches) projects.add(dirname41(ctx));
53541
53642
  return Array.from(projects).sort();
53542
53643
  }
53543
53644
  async function discoverVaultsAsync(root) {
@@ -53550,7 +53651,7 @@ async function discoverVaultsAsync(root) {
53550
53651
  suppressErrors: true
53551
53652
  });
53552
53653
  const projects = /* @__PURE__ */ new Set();
53553
- for (const ctx of matches) projects.add(dirname40(ctx));
53654
+ for (const ctx of matches) projects.add(dirname41(ctx));
53554
53655
  return Array.from(projects).sort();
53555
53656
  }
53556
53657
  var import_fast_glob17;
@@ -53609,7 +53710,7 @@ var init_ensure_cli = __esm({
53609
53710
 
53610
53711
  // src/server/routes/launcher.ts
53611
53712
  import { basename as basename23, isAbsolute as isAbsolute2, join as join67, resolve as resolve18, sep as sep12 } from "path";
53612
- import { existsSync as existsSync71, mkdirSync as mkdirSync31, readdirSync as readdirSync17, statSync as statSync13, createReadStream, readFileSync as readFileSync53, writeFileSync as writeFileSync37 } from "fs";
53713
+ import { existsSync as existsSync71, mkdirSync as mkdirSync32, readdirSync as readdirSync17, statSync as statSync14, createReadStream, readFileSync as readFileSync54, writeFileSync as writeFileSync38 } from "fs";
53613
53714
  import { homedir as homedir4 } from "os";
53614
53715
  import { execFile as execFile2, spawn as spawn4 } from "child_process";
53615
53716
  import { promisify as promisify2 } from "util";
@@ -53676,7 +53777,7 @@ async function handleLauncherRegister(req, res, _params, _contextRoot) {
53676
53777
  }
53677
53778
  function isNonEmptyDir(dir) {
53678
53779
  try {
53679
- return statSync13(dir).isDirectory() && readdirSync17(dir).length > 0;
53780
+ return statSync14(dir).isDirectory() && readdirSync17(dir).length > 0;
53680
53781
  } catch {
53681
53782
  return false;
53682
53783
  }
@@ -53701,7 +53802,7 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
53701
53802
  throw new ScaffoldError("parentDir must be an absolute path.");
53702
53803
  }
53703
53804
  const resolvedParent = resolve18(parentDir);
53704
- if (!existsSync71(resolvedParent) || !statSync13(resolvedParent).isDirectory()) {
53805
+ if (!existsSync71(resolvedParent) || !statSync14(resolvedParent).isDirectory()) {
53705
53806
  throw new ScaffoldError(`Parent directory does not exist: ${resolvedParent}`);
53706
53807
  }
53707
53808
  target = resolve18(resolvedParent, name);
@@ -53711,14 +53812,14 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
53711
53812
  if (isNonEmptyDir(target) && !existsSync71(join67(target, "_dream_context"))) {
53712
53813
  throw new ScaffoldError(`A non-empty folder already exists at ${target}.`);
53713
53814
  }
53714
- mkdirSync31(target, { recursive: true });
53815
+ mkdirSync32(target, { recursive: true });
53715
53816
  } else if (a.mode === "existing") {
53716
53817
  const projectPath = (a.projectPath ?? "").trim();
53717
53818
  if (!projectPath || !isAbsolute2(projectPath)) {
53718
53819
  throw new ScaffoldError("projectPath must be an absolute path.");
53719
53820
  }
53720
53821
  target = resolve18(projectPath);
53721
- if (!existsSync71(target) || !statSync13(target).isDirectory()) {
53822
+ if (!existsSync71(target) || !statSync14(target).isDirectory()) {
53722
53823
  throw new ScaffoldError(`Folder does not exist: ${target}`);
53723
53824
  }
53724
53825
  } else {
@@ -53813,7 +53914,7 @@ async function handleSleepyConfigGet(_req, res, _params, _contextRoot) {
53813
53914
  try {
53814
53915
  const p = sleepyConfigPath();
53815
53916
  if (existsSync71(p)) {
53816
- const raw = JSON.parse(readFileSync53(p, "utf-8"));
53917
+ const raw = JSON.parse(readFileSync54(p, "utf-8"));
53817
53918
  enabled = raw.enabled === true;
53818
53919
  if (typeof raw.hotkey === "string" && raw.hotkey.trim()) hotkey = raw.hotkey;
53819
53920
  }
@@ -53831,8 +53932,8 @@ async function handleSleepyConfigSet(req, res, _params, _contextRoot) {
53831
53932
  const hotkey = typeof body.hotkey === "string" && body.hotkey.trim() ? body.hotkey.trim() : "Alt+Cmd+S";
53832
53933
  try {
53833
53934
  const p = sleepyConfigPath();
53834
- mkdirSync31(join67(homedir4(), ".dreamcontext"), { recursive: true });
53835
- writeFileSync37(p, JSON.stringify({ enabled, hotkey }, null, 2) + "\n", "utf-8");
53935
+ mkdirSync32(join67(homedir4(), ".dreamcontext"), { recursive: true });
53936
+ writeFileSync38(p, JSON.stringify({ enabled, hotkey }, null, 2) + "\n", "utf-8");
53836
53937
  sendJson(res, 200, { enabled, hotkey });
53837
53938
  } catch (err) {
53838
53939
  console.error("[launcher] sleepy-config write failed:", err);
@@ -53858,7 +53959,7 @@ async function handleSleepyVideo(req, res, _params, _contextRoot) {
53858
53959
  res.end();
53859
53960
  return;
53860
53961
  }
53861
- const size = statSync13(file).size;
53962
+ const size = statSync14(file).size;
53862
53963
  const range = req.headers.range;
53863
53964
  if (range) {
53864
53965
  const m = /bytes=(\d+)-(\d*)/.exec(range);
@@ -53890,7 +53991,7 @@ async function handleSleepyAnim(req, res, _params, _contextRoot) {
53890
53991
  res.end();
53891
53992
  return;
53892
53993
  }
53893
- const size = statSync13(file).size;
53994
+ const size = statSync14(file).size;
53894
53995
  res.writeHead(200, {
53895
53996
  "Content-Type": "image/webp",
53896
53997
  "Content-Length": size,
@@ -53964,10 +54065,42 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
53964
54065
  return;
53965
54066
  }
53966
54067
  }
54068
+ if (mode === "sleep") {
54069
+ const inFlightId = sleepJobsInFlight.get(cwd);
54070
+ if (inFlightId && captureRuns.get(inFlightId)?.state === "running") {
54071
+ sendError(
54072
+ res,
54073
+ 409,
54074
+ "sleep_in_progress",
54075
+ "A Sleep consolidation is already running for this vault. Wait for it to finish."
54076
+ );
54077
+ return;
54078
+ }
54079
+ try {
54080
+ const lock = inspectSleepLock(readSleepState(cwd), Date.now());
54081
+ if (lock.locked && !lock.stale) {
54082
+ sendError(
54083
+ res,
54084
+ 409,
54085
+ "sleep_in_progress",
54086
+ `A consolidation is already in progress for this vault (started ${lock.startedAt}). Wait for it to finish before starting another.`
54087
+ );
54088
+ return;
54089
+ }
54090
+ } catch (err) {
54091
+ console.error("[launcher] could not read sleep lock state:", err);
54092
+ }
54093
+ }
53967
54094
  pruneCaptureRuns();
53968
54095
  const captureId = randomUUID2();
53969
54096
  const run2 = { state: "running", output: "", stderr: "", startedAt: Date.now() };
53970
54097
  captureRuns.set(captureId, run2);
54098
+ if (mode === "sleep") sleepJobsInFlight.set(cwd, captureId);
54099
+ const releaseSleepSlot = () => {
54100
+ if (mode === "sleep" && sleepJobsInFlight.get(cwd) === captureId) {
54101
+ sleepJobsInFlight.delete(cwd);
54102
+ }
54103
+ };
53971
54104
  try {
53972
54105
  const shell = process.env.SHELL || "/bin/zsh";
53973
54106
  let sleepDepth = "deep";
@@ -53996,8 +54129,10 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
53996
54129
  run2.state = "error";
53997
54130
  run2.output = `Couldn't start claude: ${err.message}`;
53998
54131
  run2.endedAt = Date.now();
54132
+ releaseSleepSlot();
53999
54133
  });
54000
54134
  child.on("close", (code) => {
54135
+ releaseSleepSlot();
54001
54136
  if (run2.state !== "running") return;
54002
54137
  if (code === 0) {
54003
54138
  run2.state = "done";
@@ -54011,6 +54146,7 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
54011
54146
  run2.state = "error";
54012
54147
  run2.output = `Couldn't start claude: ${err instanceof Error ? err.message : "spawn failed"}`;
54013
54148
  run2.endedAt = Date.now();
54149
+ releaseSleepSlot();
54014
54150
  }
54015
54151
  sendJson(res, 200, { ok: true, captureId });
54016
54152
  }
@@ -54276,7 +54412,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
54276
54412
  sendError(res, 500, "shareable_failed", "Failed to update sharing.");
54277
54413
  }
54278
54414
  }
54279
- var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, SLEEPY_MODES, addOut, addIn, dropOut, dropIn;
54415
+ var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, sleepJobsInFlight, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, SLEEPY_MODES, addOut, addIn, dropOut, dropIn;
54280
54416
  var init_launcher = __esm({
54281
54417
  "src/server/routes/launcher.ts"() {
54282
54418
  "use strict";
@@ -54299,6 +54435,7 @@ var init_launcher = __esm({
54299
54435
  captureRuns = /* @__PURE__ */ new Map();
54300
54436
  CAPTURE_RUN_TTL_MS = 10 * 60 * 1e3;
54301
54437
  CAPTURE_RUNS_MAX = 50;
54438
+ sleepJobsInFlight = /* @__PURE__ */ new Map();
54302
54439
  ScaffoldError = class extends Error {
54303
54440
  constructor(message) {
54304
54441
  super(message);
@@ -54328,8 +54465,8 @@ var init_launcher = __esm({
54328
54465
  });
54329
54466
 
54330
54467
  // src/server/routes/ui-settings.ts
54331
- import { dirname as dirname41, join as join68 } from "path";
54332
- import { existsSync as existsSync72, mkdirSync as mkdirSync32, readFileSync as readFileSync54, writeFileSync as writeFileSync38 } from "fs";
54468
+ import { dirname as dirname42, join as join68 } from "path";
54469
+ import { existsSync as existsSync72, mkdirSync as mkdirSync33, readFileSync as readFileSync55, writeFileSync as writeFileSync39 } from "fs";
54333
54470
  function settingsPath(contextRoot) {
54334
54471
  return join68(contextRoot, BRAIN_SETTINGS_REL_PATH);
54335
54472
  }
@@ -54340,7 +54477,7 @@ async function handleBrainSettingsGet(_req, res, _params, contextRoot) {
54340
54477
  return;
54341
54478
  }
54342
54479
  try {
54343
- const raw = JSON.parse(readFileSync54(path2, "utf-8"));
54480
+ const raw = JSON.parse(readFileSync55(path2, "utf-8"));
54344
54481
  const settings = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
54345
54482
  sendJson(res, 200, { settings });
54346
54483
  } catch {
@@ -54365,8 +54502,8 @@ async function handleBrainSettingsPut(req, res, _params, contextRoot) {
54365
54502
  }
54366
54503
  try {
54367
54504
  const path2 = settingsPath(contextRoot);
54368
- mkdirSync32(dirname41(path2), { recursive: true });
54369
- writeFileSync38(path2, serialized + "\n", "utf-8");
54505
+ mkdirSync33(dirname42(path2), { recursive: true });
54506
+ writeFileSync39(path2, serialized + "\n", "utf-8");
54370
54507
  sendJson(res, 200, { ok: true });
54371
54508
  } catch (err) {
54372
54509
  console.error("[ui-settings] brain-settings write failed:", err);
@@ -54384,8 +54521,8 @@ var init_ui_settings = __esm({
54384
54521
  });
54385
54522
 
54386
54523
  // src/server/routes/board.ts
54387
- import { dirname as dirname42, join as join69 } from "path";
54388
- import { existsSync as existsSync73, mkdirSync as mkdirSync33, readFileSync as readFileSync55, writeFileSync as writeFileSync39 } from "fs";
54524
+ import { dirname as dirname43, join as join69 } from "path";
54525
+ import { existsSync as existsSync73, mkdirSync as mkdirSync34, readFileSync as readFileSync56, writeFileSync as writeFileSync40 } from "fs";
54389
54526
  function sharedPath(contextRoot) {
54390
54527
  return join69(contextRoot, SHARED_REL_PATH);
54391
54528
  }
@@ -54395,7 +54532,7 @@ function localPath(contextRoot) {
54395
54532
  function readBlob(path2) {
54396
54533
  if (!existsSync73(path2)) return {};
54397
54534
  try {
54398
- const raw = JSON.parse(readFileSync55(path2, "utf-8"));
54535
+ const raw = JSON.parse(readFileSync56(path2, "utf-8"));
54399
54536
  return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
54400
54537
  } catch {
54401
54538
  return {};
@@ -54420,8 +54557,8 @@ function writeBlob(path2, board) {
54420
54557
  if (Buffer.byteLength(serialized, "utf-8") > MAX_BYTES2) {
54421
54558
  return "board payload is too large.";
54422
54559
  }
54423
- mkdirSync33(dirname42(path2), { recursive: true });
54424
- writeFileSync39(path2, serialized + "\n", "utf-8");
54560
+ mkdirSync34(dirname43(path2), { recursive: true });
54561
+ writeFileSync40(path2, serialized + "\n", "utf-8");
54425
54562
  return null;
54426
54563
  }
54427
54564
  async function handleBoardSharedPut(req, res, _params, contextRoot) {
@@ -54473,8 +54610,8 @@ var init_board = __esm({
54473
54610
 
54474
54611
  // src/server/routes/sleepy-chat.ts
54475
54612
  import { spawn as spawn5 } from "child_process";
54476
- import { dirname as dirname43, join as join70 } from "path";
54477
- import { existsSync as existsSync74, mkdirSync as mkdirSync34, readFileSync as readFileSync56, writeFileSync as writeFileSync40 } from "fs";
54613
+ import { dirname as dirname44, join as join70 } from "path";
54614
+ import { existsSync as existsSync74, mkdirSync as mkdirSync35, readFileSync as readFileSync57, writeFileSync as writeFileSync41 } from "fs";
54478
54615
  import { randomUUID as randomUUID3 } from "crypto";
54479
54616
  function modelFor(tier) {
54480
54617
  return tier === "intelligent" ? "opus" : "sonnet";
@@ -54504,7 +54641,7 @@ function storePath(contextRoot) {
54504
54641
  }
54505
54642
  function readStore(contextRoot) {
54506
54643
  try {
54507
- const raw = readFileSync56(storePath(contextRoot), "utf-8");
54644
+ const raw = readFileSync57(storePath(contextRoot), "utf-8");
54508
54645
  const o = JSON.parse(raw);
54509
54646
  return {
54510
54647
  sessionId: typeof o.sessionId === "string" ? o.sessionId : null,
@@ -54518,15 +54655,15 @@ function readStore(contextRoot) {
54518
54655
  function writeStore(contextRoot, store) {
54519
54656
  try {
54520
54657
  const dir = join70(contextRoot, "state");
54521
- if (!existsSync74(dir)) mkdirSync34(dir, { recursive: true });
54658
+ if (!existsSync74(dir)) mkdirSync35(dir, { recursive: true });
54522
54659
  store.messages = store.messages.slice(-MESSAGES_MAX);
54523
- writeFileSync40(storePath(contextRoot), JSON.stringify(store, null, 2), "utf-8");
54660
+ writeFileSync41(storePath(contextRoot), JSON.stringify(store, null, 2), "utf-8");
54524
54661
  } catch (err) {
54525
54662
  console.error("[sleepy-chat] failed to persist transcript:", err);
54526
54663
  }
54527
54664
  }
54528
54665
  function projectRootOf(contextRoot) {
54529
- return contextRoot.endsWith("_dream_context") ? dirname43(contextRoot) : contextRoot;
54666
+ return contextRoot.endsWith("_dream_context") ? dirname44(contextRoot) : contextRoot;
54530
54667
  }
54531
54668
  function handleStreamLine(run2, obj) {
54532
54669
  const type = obj.type;
@@ -58526,16 +58663,18 @@ var init_wrapper = __esm({
58526
58663
 
58527
58664
  // src/server/routes/agent-terminal.ts
58528
58665
  import { spawn as spawn6 } from "child_process";
58666
+ import { randomUUID as randomUUID4 } from "crypto";
58529
58667
  import { createRequire } from "module";
58530
- import { dirname as dirname44, join as join71 } from "path";
58531
- import { existsSync as existsSync75, readdirSync as readdirSync18, statSync as statSync14, chmodSync as chmodSync3 } from "fs";
58668
+ import { dirname as dirname45, join as join71 } from "path";
58669
+ import { existsSync as existsSync75, readdirSync as readdirSync18, statSync as statSync15, chmodSync as chmodSync3 } from "fs";
58670
+ import { homedir as homedir5 } from "os";
58532
58671
  function isDesktop() {
58533
58672
  return process.env.DREAMCONTEXT_DESKTOP === "1";
58534
58673
  }
58535
58674
  function ensurePtyHelperExecutable() {
58536
58675
  try {
58537
58676
  const require2 = createRequire(import.meta.url);
58538
- const root = dirname44(dirname44(require2.resolve("node-pty")));
58677
+ const root = dirname45(dirname45(require2.resolve("node-pty")));
58539
58678
  const candidates = [join71(root, "build", "Release", "spawn-helper")];
58540
58679
  const prebuilds = join71(root, "prebuilds");
58541
58680
  if (existsSync75(prebuilds)) {
@@ -58543,7 +58682,7 @@ function ensurePtyHelperExecutable() {
58543
58682
  }
58544
58683
  for (const p of candidates) {
58545
58684
  if (!existsSync75(p)) continue;
58546
- const mode = statSync14(p).mode;
58685
+ const mode = statSync15(p).mode;
58547
58686
  if ((mode & 73) !== 73) chmodSync3(p, mode | 493);
58548
58687
  }
58549
58688
  } catch {
@@ -58560,8 +58699,38 @@ async function hasNodePty() {
58560
58699
  }
58561
58700
  return ptyAvailable;
58562
58701
  }
58702
+ function resetPtyCache() {
58703
+ ptyAvailable = null;
58704
+ }
58705
+ function detectOnPath(cmd, timeoutMs = 8e3) {
58706
+ return new Promise((resolve22) => {
58707
+ const shell = process.env.SHELL || "/bin/zsh";
58708
+ let out = "";
58709
+ let settled = false;
58710
+ const done = (v) => {
58711
+ if (!settled) {
58712
+ settled = true;
58713
+ clearTimeout(timer);
58714
+ resolve22(v);
58715
+ }
58716
+ };
58717
+ const child = spawn6(shell, ["-ilc", `command -v ${cmd}`], { stdio: ["ignore", "pipe", "ignore"] });
58718
+ const timer = setTimeout(() => {
58719
+ try {
58720
+ child.kill();
58721
+ } catch {
58722
+ }
58723
+ done(false);
58724
+ }, timeoutMs);
58725
+ child.stdout?.on("data", (c) => {
58726
+ out += c.toString("utf-8");
58727
+ });
58728
+ child.on("error", () => done(false));
58729
+ child.on("close", () => done(out.trim().length > 0));
58730
+ });
58731
+ }
58563
58732
  function projectRootOf2(contextRoot) {
58564
- return contextRoot.endsWith("_dream_context") ? dirname44(contextRoot) : contextRoot;
58733
+ return contextRoot.endsWith("_dream_context") ? dirname45(contextRoot) : contextRoot;
58565
58734
  }
58566
58735
  function resolveVaultProjectRoot(name) {
58567
58736
  if (!name) return null;
@@ -58572,13 +58741,18 @@ function resolveVaultProjectRoot(name) {
58572
58741
  }
58573
58742
  async function handleAgentCapabilities(_req, res) {
58574
58743
  const desktop = isDesktop();
58744
+ const [nodePty, claudeCli, npm] = desktop ? await Promise.all([hasNodePty(), detectOnPath("claude"), detectOnPath("npm")]) : [false, false, false];
58575
58745
  sendJson(res, 200, {
58576
58746
  desktop,
58577
58747
  platform: process.platform,
58578
58748
  // Embedded terminal needs the desktop shell AND the native node-pty module.
58579
- embeddedTerminal: desktop && process.platform !== "win32" && await hasNodePty(),
58749
+ embeddedTerminal: desktop && process.platform !== "win32" && nodePty,
58580
58750
  // Launching the user's real terminal is macOS-only (osascript) today.
58581
- openTerminal: desktop && process.platform === "darwin"
58751
+ openTerminal: desktop && process.platform === "darwin",
58752
+ // Prerequisite breakdown for the in-app Setup panel.
58753
+ nodePty,
58754
+ claudeCli,
58755
+ npm
58582
58756
  });
58583
58757
  }
58584
58758
  function escapeForAppleScript(s) {
@@ -58619,6 +58793,122 @@ end tell`;
58619
58793
  sendError(res, 500, "spawn_failed", err instanceof Error ? err.message : "Could not open Terminal.");
58620
58794
  }
58621
58795
  }
58796
+ function pruneInstallRuns() {
58797
+ const now = Date.now();
58798
+ for (const [id, run2] of installRuns) {
58799
+ if (run2.endedAt && now - run2.endedAt > INSTALL_RUN_TTL_MS) installRuns.delete(id);
58800
+ }
58801
+ while (installRuns.size > INSTALL_RUNS_MAX) {
58802
+ const oldest = installRuns.keys().next().value;
58803
+ if (oldest === void 0) break;
58804
+ installRuns.delete(oldest);
58805
+ }
58806
+ }
58807
+ function cliPackageRoot() {
58808
+ let dir = process.argv[1] ? dirname45(process.argv[1]) : "";
58809
+ if (!dir) return null;
58810
+ for (let i = 0; i < 8; i++) {
58811
+ if (existsSync75(join71(dir, "package.json"))) return dir;
58812
+ const parent = dirname45(dir);
58813
+ if (parent === dir) break;
58814
+ dir = parent;
58815
+ }
58816
+ return null;
58817
+ }
58818
+ function installPlan(target) {
58819
+ if (target === "claude") {
58820
+ return { script: "npm install -g @anthropic-ai/claude-code" };
58821
+ }
58822
+ const root = cliPackageRoot();
58823
+ if (!root) return null;
58824
+ return { script: "npm install node-pty@^1.1.0 --no-save", cwd: root };
58825
+ }
58826
+ async function handleAgentInstall(req, res) {
58827
+ if (!isDesktop()) {
58828
+ sendError(res, 403, "desktop_only", "The in-app installer is only available in the desktop app.");
58829
+ return;
58830
+ }
58831
+ let target;
58832
+ try {
58833
+ const chunks = [];
58834
+ for await (const c of req) chunks.push(c);
58835
+ target = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf-8")).target : void 0;
58836
+ } catch {
58837
+ }
58838
+ if (target !== "claude" && target !== "pty") {
58839
+ sendError(res, 400, "bad_target", "Body must be { target: 'claude' | 'pty' }.");
58840
+ return;
58841
+ }
58842
+ const plan = installPlan(target);
58843
+ if (!plan) {
58844
+ sendError(res, 500, "no_install_path", "Couldn't locate the CLI package to install node-pty into.");
58845
+ return;
58846
+ }
58847
+ pruneInstallRuns();
58848
+ const runId = randomUUID4();
58849
+ const run2 = { state: "running", target, output: "", startedAt: Date.now() };
58850
+ installRuns.set(runId, run2);
58851
+ try {
58852
+ const shell = process.env.SHELL || "/bin/zsh";
58853
+ const child = spawn6(shell, ["-ilc", plan.script], {
58854
+ cwd: plan.cwd,
58855
+ stdio: ["ignore", "pipe", "pipe"]
58856
+ });
58857
+ const append = (chunk) => {
58858
+ run2.output = (run2.output + chunk.toString("utf-8")).slice(-8e3);
58859
+ };
58860
+ child.stdout?.on("data", append);
58861
+ child.stderr?.on("data", append);
58862
+ const watchdog = setTimeout(() => {
58863
+ try {
58864
+ child.kill();
58865
+ } catch {
58866
+ }
58867
+ if (run2.state === "running") {
58868
+ run2.state = "error";
58869
+ run2.output += "\n[timed out after 5 min]";
58870
+ run2.endedAt = Date.now();
58871
+ }
58872
+ }, INSTALL_WATCHDOG_MS);
58873
+ child.on("error", (err) => {
58874
+ clearTimeout(watchdog);
58875
+ if (run2.state !== "running") return;
58876
+ run2.state = "error";
58877
+ run2.output = `Couldn't start install: ${err.message}. Run manually: ${plan.script}`;
58878
+ run2.endedAt = Date.now();
58879
+ });
58880
+ child.on("close", (code) => {
58881
+ clearTimeout(watchdog);
58882
+ if (run2.state !== "running") return;
58883
+ if (code === 0) {
58884
+ if (target === "pty") {
58885
+ ensurePtyHelperExecutable();
58886
+ resetPtyCache();
58887
+ }
58888
+ run2.state = "done";
58889
+ } else {
58890
+ run2.state = "error";
58891
+ if (!run2.output.trim()) run2.output = `Install exited with code ${code}. Run manually: ${plan.script}`;
58892
+ }
58893
+ run2.endedAt = Date.now();
58894
+ });
58895
+ } catch (err) {
58896
+ run2.state = "error";
58897
+ run2.output = `Couldn't start install: ${err instanceof Error ? err.message : "spawn failed"}`;
58898
+ run2.endedAt = Date.now();
58899
+ }
58900
+ sendJson(res, 200, { ok: true, runId });
58901
+ }
58902
+ async function handleAgentInstallStatus(req, res) {
58903
+ const url = new URL(req.url || "/", `http://${req.headers.host}`);
58904
+ const id = url.searchParams.get("id") ?? "";
58905
+ const run2 = id ? installRuns.get(id) : void 0;
58906
+ if (!run2) {
58907
+ sendJson(res, 200, { state: "unknown", output: "" });
58908
+ return;
58909
+ }
58910
+ sendJson(res, 200, { state: run2.state, target: run2.target, output: run2.output.trim() });
58911
+ }
58622
58912
  function attachAgentTerminal(server) {
58623
58913
  server.on("upgrade", (req, socket, head) => {
58624
58914
  let url;
@@ -58642,6 +58932,8 @@ function attachAgentTerminal(server) {
58642
58932
  }
58643
58933
  const bypass = url.searchParams.get("bypass") === "1";
58644
58934
  const theme = url.searchParams.get("theme") === "light" ? "light" : "dark";
58935
+ const sessionId = sanitizeUuid(url.searchParams.get("sessionId"));
58936
+ const resumeId = sanitizeUuid(url.searchParams.get("resume"));
58645
58937
  void (async () => {
58646
58938
  let pty;
58647
58939
  let WebSocketServer2;
@@ -58655,7 +58947,7 @@ function attachAgentTerminal(server) {
58655
58947
  }
58656
58948
  const wss = new WebSocketServer2({ noServer: true });
58657
58949
  wss.handleUpgrade(req, socket, head, (ws) => {
58658
- startPtySession(ws, pty, projectRoot, bypass, theme);
58950
+ startPtySession(ws, pty, projectRoot, bypass, theme, sessionId, resumeId);
58659
58951
  });
58660
58952
  })();
58661
58953
  });
@@ -58668,11 +58960,30 @@ Connection: close\r
58668
58960
  `);
58669
58961
  socket.destroy();
58670
58962
  }
58671
- function startPtySession(ws, pty, projectRoot, bypass, theme) {
58963
+ function sanitizeUuid(v) {
58964
+ return v && /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(v) ? v : "";
58965
+ }
58966
+ function claudeConversationExists(id) {
58967
+ if (!id) return false;
58968
+ try {
58969
+ const base = join71(homedir5(), ".claude", "projects");
58970
+ if (!existsSync75(base)) return false;
58971
+ for (const dir of readdirSync18(base)) {
58972
+ if (existsSync75(join71(base, dir, `${id}.jsonl`))) return true;
58973
+ }
58974
+ return false;
58975
+ } catch {
58976
+ return false;
58977
+ }
58978
+ }
58979
+ function startPtySession(ws, pty, projectRoot, bypass, theme, sessionId, resumeId) {
58672
58980
  const shell = process.env.SHELL || "/bin/zsh";
58673
58981
  const flag = bypass ? " --permission-mode bypassPermissions" : "";
58982
+ const resumable = resumeId && claudeConversationExists(resumeId);
58983
+ const pinId = resumeId || sessionId;
58984
+ const idArg = resumable ? ` --resume ${resumeId}` : pinId ? ` --session-id ${pinId}` : "";
58674
58985
  const colorfgbg = theme === "light" ? "0;15" : "15;0";
58675
- const term = pty.spawn(shell, ["-ilc", `exec claude${flag}`], {
58986
+ const term = pty.spawn(shell, ["-ilc", `exec claude${idArg}${flag}`], {
58676
58987
  name: "xterm-color",
58677
58988
  cols: 80,
58678
58989
  rows: 24,
@@ -58726,20 +59037,262 @@ function startPtySession(ws, pty, projectRoot, bypass, theme) {
58726
59037
  ws.on("close", teardown);
58727
59038
  ws.on("error", teardown);
58728
59039
  }
58729
- var ptyAvailable;
59040
+ var ptyAvailable, installRuns, INSTALL_RUN_TTL_MS, INSTALL_RUNS_MAX, INSTALL_WATCHDOG_MS;
58730
59041
  var init_agent_terminal = __esm({
58731
59042
  "src/server/routes/agent-terminal.ts"() {
58732
59043
  "use strict";
58733
59044
  init_middleware();
58734
59045
  init_vaults();
58735
59046
  ptyAvailable = null;
59047
+ installRuns = /* @__PURE__ */ new Map();
59048
+ INSTALL_RUN_TTL_MS = 10 * 60 * 1e3;
59049
+ INSTALL_RUNS_MAX = 20;
59050
+ INSTALL_WATCHDOG_MS = 5 * 60 * 1e3;
59051
+ }
59052
+ });
59053
+
59054
+ // src/server/routes/agent-drop.ts
59055
+ import { randomUUID as randomUUID5 } from "crypto";
59056
+ import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync42, readdirSync as readdirSync19, statSync as statSync16, unlinkSync as unlinkSync5 } from "fs";
59057
+ import { join as join72, basename as basename24 } from "path";
59058
+ function isDesktop2() {
59059
+ return process.env.DREAMCONTEXT_DESKTOP === "1";
59060
+ }
59061
+ function sniffImageType(buf) {
59062
+ if (buf.length >= 8 && buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71 && buf[4] === 13 && buf[5] === 10 && buf[6] === 26 && buf[7] === 10) return "image/png";
59063
+ if (buf.length >= 3 && buf[0] === 255 && buf[1] === 216 && buf[2] === 255) return "image/jpeg";
59064
+ if (buf.length >= 6 && buf[0] === 71 && buf[1] === 73 && buf[2] === 70 && buf[3] === 56 && (buf[4] === 55 || buf[4] === 57) && buf[5] === 97) return "image/gif";
59065
+ if (buf.length >= 12 && buf.toString("ascii", 0, 4) === "RIFF" && buf.toString("ascii", 8, 12) === "WEBP") return "image/webp";
59066
+ return null;
59067
+ }
59068
+ function sanitizeDropFilename(raw, ext) {
59069
+ let base = "";
59070
+ try {
59071
+ base = basename24(String(raw ?? "").replace(/\\/g, "/").trim());
59072
+ } catch {
59073
+ base = "";
59074
+ }
59075
+ base = base.replace(/^\.+/, "");
59076
+ const safe = base.replace(/[^\w.\-]/g, "_");
59077
+ if (!safe || !/[A-Za-z0-9]/.test(safe)) return `${randomUUID5()}${ext}`;
59078
+ return /\.[A-Za-z0-9]+$/.test(safe) ? safe : `${safe}${ext}`;
59079
+ }
59080
+ function decodeFilenameHeader(h) {
59081
+ const v = Array.isArray(h) ? h[0] : h;
59082
+ if (!v) return "";
59083
+ try {
59084
+ return decodeURIComponent(v);
59085
+ } catch {
59086
+ return v;
59087
+ }
59088
+ }
59089
+ function ensureTmpGitignored(contextRoot) {
59090
+ try {
59091
+ writeFileSync42(join72(contextRoot, "tmp", ".gitignore"), "*\n");
59092
+ } catch {
59093
+ }
59094
+ }
59095
+ function pruneDrops(dir) {
59096
+ try {
59097
+ const now = Date.now();
59098
+ for (const name of readdirSync19(dir)) {
59099
+ const p = join72(dir, name);
59100
+ try {
59101
+ const st = statSync16(p);
59102
+ if (st.isFile() && now - st.mtimeMs > DROP_TTL_MS) unlinkSync5(p);
59103
+ } catch {
59104
+ }
59105
+ }
59106
+ } catch {
59107
+ }
59108
+ }
59109
+ function readCappedBody(req, res) {
59110
+ return new Promise((resolve22) => {
59111
+ const chunks = [];
59112
+ let size = 0;
59113
+ let done = false;
59114
+ const finish2 = (v) => {
59115
+ if (!done) {
59116
+ done = true;
59117
+ resolve22(v);
59118
+ }
59119
+ };
59120
+ req.on("data", (chunk) => {
59121
+ size += chunk.length;
59122
+ if (size > MAX_DROP_BYTES) {
59123
+ sendError(res, 413, "too_large", "Dropped file exceeds the 25 MB limit.");
59124
+ req.destroy();
59125
+ finish2(null);
59126
+ return;
59127
+ }
59128
+ chunks.push(chunk);
59129
+ });
59130
+ req.on("end", () => finish2(Buffer.concat(chunks)));
59131
+ req.on("error", () => finish2(null));
59132
+ });
59133
+ }
59134
+ async function handleAgentDrop(req, res, _params, contextRoot) {
59135
+ if (!isDesktop2()) {
59136
+ sendError(res, 403, "desktop_only", "Agent file drop is only available in the desktop app.");
59137
+ return;
59138
+ }
59139
+ const buf = await readCappedBody(req, res);
59140
+ if (!buf) return;
59141
+ if (buf.length === 0) {
59142
+ sendError(res, 400, "empty", "No file data was received.");
59143
+ return;
59144
+ }
59145
+ const sniffed = sniffImageType(buf);
59146
+ if (!sniffed) {
59147
+ sendError(res, 415, "unsupported_type", "Only PNG, JPEG, GIF or WebP images can be dropped onto the agent.");
59148
+ return;
59149
+ }
59150
+ const rawName = decodeFilenameHeader(req.headers["x-dreamcontext-filename"]);
59151
+ const safeName = sanitizeDropFilename(rawName, EXT_BY_TYPE[sniffed]);
59152
+ const dropDir = join72(contextRoot, "tmp", "agent-drops");
59153
+ try {
59154
+ mkdirSync36(dropDir, { recursive: true });
59155
+ ensureTmpGitignored(contextRoot);
59156
+ pruneDrops(dropDir);
59157
+ } catch (err) {
59158
+ console.error("[agent-drop] could not prepare drop dir", err);
59159
+ sendError(res, 500, "mkdir_failed", "Could not prepare the drop directory.");
59160
+ return;
59161
+ }
59162
+ const finalPath = join72(dropDir, `${Date.now()}-${safeName}`);
59163
+ try {
59164
+ writeFileSync42(finalPath, buf);
59165
+ } catch (err) {
59166
+ console.error("[agent-drop] could not write drop", err);
59167
+ sendError(res, 500, "write_failed", "Could not save the dropped file.");
59168
+ return;
59169
+ }
59170
+ sendJson(res, 200, { path: finalPath, contentType: sniffed });
59171
+ }
59172
+ var MAX_DROP_BYTES, DROP_TTL_MS, EXT_BY_TYPE;
59173
+ var init_agent_drop = __esm({
59174
+ "src/server/routes/agent-drop.ts"() {
59175
+ "use strict";
59176
+ init_middleware();
59177
+ MAX_DROP_BYTES = 25 * 1024 * 1024;
59178
+ DROP_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
59179
+ EXT_BY_TYPE = {
59180
+ "image/png": ".png",
59181
+ "image/jpeg": ".jpg",
59182
+ "image/gif": ".gif",
59183
+ "image/webp": ".webp"
59184
+ };
59185
+ }
59186
+ });
59187
+
59188
+ // src/server/routes/agent-sessions.ts
59189
+ import { join as join73, dirname as dirname46 } from "path";
59190
+ import { existsSync as existsSync76, mkdirSync as mkdirSync37, readFileSync as readFileSync58, writeFileSync as writeFileSync43, renameSync as renameSync12 } from "fs";
59191
+ import { randomUUID as randomUUID6 } from "crypto";
59192
+ function isDesktop3() {
59193
+ return process.env.DREAMCONTEXT_DESKTOP === "1";
59194
+ }
59195
+ function storePath2(contextRoot) {
59196
+ return join73(contextRoot, ROSTER_REL_PATH);
59197
+ }
59198
+ function coerceMeta(raw) {
59199
+ const o = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
59200
+ const title = typeof o.title === "string" ? o.title.trim().slice(0, MAX_TITLE) : "";
59201
+ const size = typeof o.size === "number" && Number.isFinite(o.size) ? Math.min(MAX_SIZE, Math.max(MIN_SIZE, o.size)) : DEFAULT_SIZE;
59202
+ const sessionId = typeof o.sessionId === "string" && UUID_RE.test(o.sessionId) ? o.sessionId : void 0;
59203
+ return {
59204
+ title: title || DEFAULT_TITLE,
59205
+ bypass: o.bypass === true,
59206
+ minimized: o.minimized === true,
59207
+ size,
59208
+ ...sessionId ? { sessionId } : {}
59209
+ };
59210
+ }
59211
+ function sanitizeRoster(body) {
59212
+ if (!body || typeof body !== "object" || Array.isArray(body)) return null;
59213
+ const sessions = body.sessions;
59214
+ if (!Array.isArray(sessions)) return null;
59215
+ return sessions.slice(0, MAX_SESSIONS).map(coerceMeta);
59216
+ }
59217
+ function readRoster(contextRoot) {
59218
+ try {
59219
+ const raw = readFileSync58(storePath2(contextRoot), "utf-8");
59220
+ return sanitizeRoster(JSON.parse(raw)) ?? [];
59221
+ } catch {
59222
+ return [];
59223
+ }
59224
+ }
59225
+ function writeRoster(contextRoot, sessions) {
59226
+ try {
59227
+ ensureGitignoreEntries(dirname46(contextRoot), ["_dream_context/state/.agent-sessions.json"], {
59228
+ comment: "dreamcontext: machine-local agent session roster (Claude resume ids)"
59229
+ });
59230
+ } catch {
59231
+ }
59232
+ const dir = join73(contextRoot, "state");
59233
+ if (!existsSync76(dir)) mkdirSync37(dir, { recursive: true });
59234
+ const path2 = storePath2(contextRoot);
59235
+ const tmp = `${path2}.${randomUUID6()}.tmp`;
59236
+ writeFileSync43(tmp, JSON.stringify({ sessions }, null, 2) + "\n", "utf-8");
59237
+ renameSync12(tmp, path2);
59238
+ }
59239
+ async function handleAgentSessionsGet(_req, res, _params, contextRoot) {
59240
+ if (!isDesktop3()) {
59241
+ sendError(res, 403, "desktop_only", "Agent session roster is only available in the desktop app.");
59242
+ return;
59243
+ }
59244
+ sendJson(res, 200, { sessions: readRoster(contextRoot) });
59245
+ }
59246
+ async function handleAgentSessionsPut(req, res, _params, contextRoot) {
59247
+ if (!isDesktop3()) {
59248
+ sendError(res, 403, "desktop_only", "Agent session roster is only available in the desktop app.");
59249
+ return;
59250
+ }
59251
+ const body = await parseJsonBody(req);
59252
+ if (!body) {
59253
+ sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
59254
+ return;
59255
+ }
59256
+ const sessions = sanitizeRoster(body);
59257
+ if (sessions === null) {
59258
+ sendError(res, 400, "invalid_sessions", "sessions must be an array.");
59259
+ return;
59260
+ }
59261
+ const serialized = JSON.stringify({ sessions });
59262
+ if (Buffer.byteLength(serialized, "utf-8") > MAX_BYTES3) {
59263
+ sendError(res, 400, "too_large", "session roster payload is too large.");
59264
+ return;
59265
+ }
59266
+ try {
59267
+ writeRoster(contextRoot, sessions);
59268
+ sendJson(res, 200, { ok: true });
59269
+ } catch (err) {
59270
+ console.error("[agent-sessions] roster write failed:", err);
59271
+ sendError(res, 500, "write_failed", "Failed to persist the session roster.");
59272
+ }
59273
+ }
59274
+ var UUID_RE, MAX_SESSIONS, MAX_TITLE, DEFAULT_TITLE, MIN_SIZE, MAX_SIZE, DEFAULT_SIZE, MAX_BYTES3, ROSTER_REL_PATH;
59275
+ var init_agent_sessions = __esm({
59276
+ "src/server/routes/agent-sessions.ts"() {
59277
+ "use strict";
59278
+ init_middleware();
59279
+ init_gitignore();
59280
+ UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
59281
+ MAX_SESSIONS = 20;
59282
+ MAX_TITLE = 200;
59283
+ DEFAULT_TITLE = "Agent";
59284
+ MIN_SIZE = 0.1;
59285
+ MAX_SIZE = 10;
59286
+ DEFAULT_SIZE = 1;
59287
+ MAX_BYTES3 = 64 * 1024;
59288
+ ROSTER_REL_PATH = join73("state", ".agent-sessions.json");
58736
59289
  }
58737
59290
  });
58738
59291
 
58739
59292
  // src/server/routes/connections.ts
58740
- import { dirname as dirname45 } from "path";
59293
+ import { dirname as dirname47 } from "path";
58741
59294
  function currentVaultName(contextRoot) {
58742
- return currentVaultTarget(dirname45(contextRoot)).name;
59295
+ return currentVaultTarget(dirname47(contextRoot)).name;
58743
59296
  }
58744
59297
  async function handleConnectionsList(_req, res, _params, contextRoot) {
58745
59298
  sendJson(res, 200, { connections: listConnections(contextRoot) });
@@ -58814,8 +59367,8 @@ var init_connections2 = __esm({
58814
59367
  });
58815
59368
 
58816
59369
  // src/lib/federation-digest.ts
58817
- import { existsSync as existsSync76 } from "fs";
58818
- import { join as join72 } from "path";
59370
+ import { existsSync as existsSync77 } from "fs";
59371
+ import { join as join74 } from "path";
58819
59372
  function buildInterestProfile(peerRoot, topics) {
58820
59373
  if (topics && topics.length > 0) {
58821
59374
  const terms2 = Array.from(new Set(tokenize(topics.join(" "))));
@@ -58834,8 +59387,8 @@ function buildInterestProfile(peerRoot, topics) {
58834
59387
  return { terms, query: terms.join(" ") };
58835
59388
  }
58836
59389
  function activeTaskTerms(peerRoot) {
58837
- const stateDir = join72(peerRoot, "state");
58838
- if (!existsSync76(stateDir)) return [];
59390
+ const stateDir = join74(peerRoot, "state");
59391
+ if (!existsSync77(stateDir)) return [];
58839
59392
  let files;
58840
59393
  try {
58841
59394
  files = import_fast_glob18.default.sync("*.md", { cwd: stateDir, absolute: true });
@@ -58936,7 +59489,7 @@ var init_federation_digest = __esm({
58936
59489
  });
58937
59490
 
58938
59491
  // src/server/routes/federation.ts
58939
- import { dirname as dirname46 } from "path";
59492
+ import { dirname as dirname48 } from "path";
58940
59493
  async function handleFederationInboxGet(_req, res, _params, contextRoot) {
58941
59494
  const { entries, quarantined } = drainInbox(contextRoot);
58942
59495
  const pending = entries.map((e) => e.entry);
@@ -58948,7 +59501,7 @@ async function handleFederationInboxGet(_req, res, _params, contextRoot) {
58948
59501
  });
58949
59502
  }
58950
59503
  async function handleFederationSyncPost(_req, res, _params, contextRoot) {
58951
- const senderName = currentVaultTarget(dirname46(contextRoot)).name;
59504
+ const senderName = currentVaultTarget(dirname48(contextRoot)).name;
58952
59505
  const outbound = listConnections(contextRoot).filter(
58953
59506
  (c) => (c.direction === "out" || c.direction === "both") && c.status !== "stale"
58954
59507
  );
@@ -58996,14 +59549,14 @@ var init_federation = __esm({
58996
59549
  });
58997
59550
 
58998
59551
  // src/server/routes/packs.ts
58999
- import { dirname as dirname47 } from "path";
59552
+ import { dirname as dirname49 } from "path";
59000
59553
  async function handlePacksGet(_req, res, _params, contextRoot) {
59001
59554
  const loaded = loadCatalog();
59002
59555
  if (!loaded) {
59003
59556
  sendJson(res, 200, { packs: [], standalone: [] });
59004
59557
  return;
59005
59558
  }
59006
- const projectRoot = dirname47(contextRoot);
59559
+ const projectRoot = dirname49(contextRoot);
59007
59560
  const packs = loaded.catalog.packs.map((p) => ({ ...p, installed: isSkillInstalled(projectRoot, p.name) }));
59008
59561
  const standalone = loaded.catalog.standalone.map((s) => ({ ...s, installed: isSkillInstalled(projectRoot, s.name) }));
59009
59562
  sendJson(res, 200, { packs, standalone });
@@ -59017,7 +59570,7 @@ var init_packs = __esm({
59017
59570
  });
59018
59571
 
59019
59572
  // src/server/routes/packs-install.ts
59020
- import { dirname as dirname48 } from "path";
59573
+ import { dirname as dirname50 } from "path";
59021
59574
  function validatePackName(name, contextRoot) {
59022
59575
  if (name.includes("/") || name.includes("\0") || safeChildPath2("/x", name) === null) {
59023
59576
  return { ok: false, status: 400, code: "invalid_name", message: "Invalid pack name." };
@@ -59030,7 +59583,7 @@ function validatePackName(name, contextRoot) {
59030
59583
  if (!known) {
59031
59584
  return { ok: false, status: 404, code: "unknown_pack", message: `Pack "${name}" not found.` };
59032
59585
  }
59033
- const projectRoot = dirname48(contextRoot);
59586
+ const projectRoot = dirname50(contextRoot);
59034
59587
  const config = readSetupConfig(projectRoot);
59035
59588
  const platforms = normalizePlatforms(config?.platforms ?? []);
59036
59589
  const resolved = platforms.length > 0 ? platforms : [...DEFAULT_PLATFORMS];
@@ -59103,10 +59656,10 @@ var init_packs_install = __esm({
59103
59656
  });
59104
59657
 
59105
59658
  // src/server/routes/version-check.ts
59106
- import { dirname as dirname49 } from "path";
59659
+ import { dirname as dirname51 } from "path";
59107
59660
  async function handleVersionCheckGet(_req, res, _params, contextRoot) {
59108
59661
  try {
59109
- const projectRoot = dirname49(contextRoot);
59662
+ const projectRoot = dirname51(contextRoot);
59110
59663
  const cache = readVersionCache(projectRoot);
59111
59664
  const fresh = isCacheFresh(cache);
59112
59665
  const installedCli = dreamcontextVersion();
@@ -59252,7 +59805,7 @@ var init_recall2 = __esm({
59252
59805
 
59253
59806
  // src/server/index.ts
59254
59807
  import { createServer } from "http";
59255
- import { join as join73, resolve as resolve19 } from "path";
59808
+ import { join as join75, resolve as resolve19 } from "path";
59256
59809
  import { fileURLToPath as fileURLToPath7 } from "url";
59257
59810
  import { exec } from "child_process";
59258
59811
  function buildRouter() {
@@ -59325,6 +59878,11 @@ function buildRouter() {
59325
59878
  router.post("/api/sleepy/chat", handleSleepyChatSend);
59326
59879
  router.get("/api/agent/capabilities", handleAgentCapabilities);
59327
59880
  router.post("/api/agent/open-terminal", handleOpenTerminal);
59881
+ router.post("/api/agent/install", handleAgentInstall);
59882
+ router.get("/api/agent/install/status", handleAgentInstallStatus);
59883
+ router.post("/api/agent/drop", handleAgentDrop);
59884
+ router.get("/api/agent/sessions", handleAgentSessionsGet);
59885
+ router.put("/api/agent/sessions", handleAgentSessionsPut);
59328
59886
  router.get("/api/vaults", handleVaultsGet);
59329
59887
  router.get("/api/connections", handleConnectionsList);
59330
59888
  router.post("/api/connections", handleConnectionsCreate);
@@ -59363,7 +59921,7 @@ function resolveRequestVault(req) {
59363
59921
  if (/[/\\:.\x00]/.test(h)) return "INVALID";
59364
59922
  const v = listVaults().find((x) => x.name === h);
59365
59923
  if (!v) return "INVALID";
59366
- return join73(v.path, "_dream_context");
59924
+ return join75(v.path, "_dream_context");
59367
59925
  }
59368
59926
  function getDashboardDir() {
59369
59927
  const __dirname8 = fileURLToPath7(new URL(".", import.meta.url));
@@ -59468,6 +60026,8 @@ var init_server = __esm({
59468
60026
  init_board();
59469
60027
  init_sleepy_chat();
59470
60028
  init_agent_terminal();
60029
+ init_agent_drop();
60030
+ init_agent_sessions();
59471
60031
  init_connections2();
59472
60032
  init_federation();
59473
60033
  init_packs();
@@ -59476,7 +60036,7 @@ var init_server = __esm({
59476
60036
  init_taxonomy2();
59477
60037
  init_recall2();
59478
60038
  init_vaults();
59479
- VAULT_AGNOSTIC_PREFIXES = ["/api/health", "/api/vaults", "/api/launcher", "/api/sleepy", "/api/agent/capabilities"];
60039
+ VAULT_AGNOSTIC_PREFIXES = ["/api/health", "/api/vaults", "/api/launcher", "/api/sleepy", "/api/agent/capabilities", "/api/agent/install"];
59480
60040
  }
59481
60041
  });
59482
60042
 
@@ -59660,8 +60220,8 @@ var init_trigger = __esm({
59660
60220
  });
59661
60221
 
59662
60222
  // src/lib/reflection.ts
59663
- import { existsSync as existsSync77, mkdirSync as mkdirSync35, writeFileSync as writeFileSync41 } from "fs";
59664
- import { join as join74, dirname as dirname50 } from "path";
60223
+ import { existsSync as existsSync78, mkdirSync as mkdirSync38, writeFileSync as writeFileSync44 } from "fs";
60224
+ import { join as join76, dirname as dirname52 } from "path";
59665
60225
  function buildExclusionSet(corpus, excludedExtra) {
59666
60226
  const excluded = new Set(excludedExtra);
59667
60227
  for (const doc of corpus) {
@@ -59837,13 +60397,13 @@ function formatReflection(result) {
59837
60397
  return capToBytes(lines, MAX_REFLECTION_BYTES);
59838
60398
  }
59839
60399
  function reflectionPath(root) {
59840
- return join74(root, "state", ".reflection.md");
60400
+ return join76(root, "state", ".reflection.md");
59841
60401
  }
59842
60402
  function writeReflection(root, md) {
59843
60403
  const outPath = reflectionPath(root);
59844
- const dir = dirname50(outPath);
59845
- if (!existsSync77(dir)) {
59846
- mkdirSync35(dir, { recursive: true });
60404
+ const dir = dirname52(outPath);
60405
+ if (!existsSync78(dir)) {
60406
+ mkdirSync38(dir, { recursive: true });
59847
60407
  }
59848
60408
  const tsMatch = md.match(/Generated: ([^\n]+)/);
59849
60409
  const generatedAt = tsMatch ? tsMatch[1].trim() : (/* @__PURE__ */ new Date()).toISOString();
@@ -59854,7 +60414,7 @@ function writeReflection(root, md) {
59854
60414
  "---",
59855
60415
  ""
59856
60416
  ].join("\n");
59857
- writeFileSync41(outPath, frontmatter + md, "utf-8");
60417
+ writeFileSync44(outPath, frontmatter + md, "utf-8");
59858
60418
  return outPath;
59859
60419
  }
59860
60420
  var MAX_REFLECTION_BYTES, DEFAULT_MIN_SESSIONS, DEFAULT_MAX_CANDIDATES, REFLECTION_NOISE;
@@ -60030,14 +60590,14 @@ var init_reflection = __esm({
60030
60590
  });
60031
60591
 
60032
60592
  // src/cli/commands/reflect.ts
60033
- import { existsSync as existsSync78, readFileSync as readFileSync59 } from "fs";
60034
- import { join as join75 } from "path";
60593
+ import { existsSync as existsSync79, readFileSync as readFileSync61 } from "fs";
60594
+ import { join as join77 } from "path";
60035
60595
  function buildBookmarkSessions(root) {
60036
- const sleepPath = join75(root, "state", ".sleep.json");
60596
+ const sleepPath = join77(root, "state", ".sleep.json");
60037
60597
  const result = /* @__PURE__ */ new Map();
60038
- if (!existsSync78(sleepPath)) return result;
60598
+ if (!existsSync79(sleepPath)) return result;
60039
60599
  try {
60040
- const parsed = JSON.parse(readFileSync59(sleepPath, "utf-8"));
60600
+ const parsed = JSON.parse(readFileSync61(sleepPath, "utf-8"));
60041
60601
  const bookmarks = parsed.bookmarks ?? [];
60042
60602
  for (const b of bookmarks) {
60043
60603
  if (b.id && b.session_id) {
@@ -60051,13 +60611,13 @@ function buildBookmarkSessions(root) {
60051
60611
  function buildExcludedExtra(root) {
60052
60612
  const excluded = /* @__PURE__ */ new Set();
60053
60613
  const coreFiles = [
60054
- join75(root, "core", "0.soul.md"),
60055
- join75(root, "core", "1.user.md")
60614
+ join77(root, "core", "0.soul.md"),
60615
+ join77(root, "core", "1.user.md")
60056
60616
  ];
60057
60617
  for (const filePath of coreFiles) {
60058
- if (!existsSync78(filePath)) continue;
60618
+ if (!existsSync79(filePath)) continue;
60059
60619
  try {
60060
- const content = readFileSync59(filePath, "utf-8");
60620
+ const content = readFileSync61(filePath, "utf-8");
60061
60621
  for (const tok of tokenize(content)) {
60062
60622
  excluded.add(tok);
60063
60623
  }
@@ -60108,8 +60668,8 @@ var init_reflect = __esm({
60108
60668
  });
60109
60669
 
60110
60670
  // src/cli/commands/council.ts
60111
- import { existsSync as existsSync79, mkdirSync as mkdirSync36, readFileSync as readFileSync60, writeFileSync as writeFileSync42 } from "fs";
60112
- import { join as join76 } from "path";
60671
+ import { existsSync as existsSync80, mkdirSync as mkdirSync39, readFileSync as readFileSync62, writeFileSync as writeFileSync45 } from "fs";
60672
+ import { join as join78 } from "path";
60113
60673
  function roundRunningStatus(n) {
60114
60674
  return `round_${n}_running`;
60115
60675
  }
@@ -60151,12 +60711,12 @@ function registerCreate(council) {
60151
60711
  }
60152
60712
  const id = generateId("council");
60153
60713
  const dir = getDebateDir(id);
60154
- mkdirSync36(dir, { recursive: true });
60714
+ mkdirSync39(dir, { recursive: true });
60155
60715
  const template = loadTemplate("council-debate.md");
60156
60716
  const content = template.replaceAll("{{ID}}", id).replaceAll("{{TOPIC}}", topic.replace(/"/g, '\\"')).replaceAll("{{ROUNDS}}", String(rounds)).replaceAll("{{INTERRUPT}}", opts.interrupt ? "true" : "false").replaceAll("{{DATE}}", today());
60157
- writeFileSync42(join76(dir, "debate.md"), content, "utf-8");
60158
- writeFileSync42(
60159
- join76(dir, "round-log.md"),
60717
+ writeFileSync45(join78(dir, "debate.md"), content, "utf-8");
60718
+ writeFileSync45(
60719
+ join78(dir, "round-log.md"),
60160
60720
  `# Round log \u2014 ${id}
60161
60721
 
60162
60722
  (Main agent appends timeline entries here.)
@@ -60198,8 +60758,8 @@ function registerAgent(council) {
60198
60758
  process.exit(1);
60199
60759
  }
60200
60760
  const personaDir = getPersonaDir(debateId, slug);
60201
- const personaFile = join76(personaDir, "context-and-persona.md");
60202
- if (existsSync79(personaFile) && !opts.force) {
60761
+ const personaFile = join78(personaDir, "context-and-persona.md");
60762
+ if (existsSync80(personaFile) && !opts.force) {
60203
60763
  error(`Persona already exists: ${slug}`, "Use --force to overwrite.");
60204
60764
  process.exit(1);
60205
60765
  }
@@ -60209,14 +60769,14 @@ function registerAgent(council) {
60209
60769
  process.exit(1);
60210
60770
  }
60211
60771
  const aspects = opts.aspects ? opts.aspects.split(",").map((a) => a.trim()).filter(Boolean) : [];
60212
- mkdirSync36(personaDir, { recursive: true });
60772
+ mkdirSync39(personaDir, { recursive: true });
60213
60773
  const template = loadTemplate("council-persona.md");
60214
60774
  const personaContent = template.replaceAll("{{SLUG}}", slug).replaceAll("{{MODEL}}", opts.model).replaceAll("{{ASPECTS}}", JSON.stringify(aspects)).replaceAll("{{PERSONA_BODY}}", body.trim());
60215
- writeFileSync42(personaFile, personaContent, "utf-8");
60775
+ writeFileSync45(personaFile, personaContent, "utf-8");
60216
60776
  const reportTemplate = loadTemplate("council-report.md");
60217
60777
  const reportContent = reportTemplate.replaceAll("{{SLUG}}", slug);
60218
- writeFileSync42(join76(personaDir, "report.md"), reportContent, "utf-8");
60219
- const debateFile = join76(getDebateDir(debateId), "debate.md");
60778
+ writeFileSync45(join78(personaDir, "report.md"), reportContent, "utf-8");
60779
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60220
60780
  const { data } = readFrontmatter(debateFile);
60221
60781
  const personas = Array.isArray(data.personas) ? data.personas.slice() : [];
60222
60782
  if (!personas.includes(slug)) personas.push(slug);
@@ -60245,7 +60805,7 @@ function registerRound(council) {
60245
60805
  error(`Round ${n} exceeds planned rounds (${data.rounds_planned}).`);
60246
60806
  process.exit(1);
60247
60807
  }
60248
- const debateFile = join76(getDebateDir(debateId), "debate.md");
60808
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60249
60809
  const personas = data.personas ?? [];
60250
60810
  if (personas.length === 0) {
60251
60811
  error("No personas registered. Run `council agent create` first.");
@@ -60254,9 +60814,9 @@ function registerRound(council) {
60254
60814
  const crossContextHeader = `## Round ${n} \u2014 Cross-context loaded`;
60255
60815
  if (n >= 2) {
60256
60816
  for (const persona of personas) {
60257
- const personaFile = join76(getPersonaDir(debateId, persona), "context-and-persona.md");
60258
- if (!existsSync79(personaFile)) continue;
60259
- const existing = readFileSync60(personaFile, "utf-8");
60817
+ const personaFile = join78(getPersonaDir(debateId, persona), "context-and-persona.md");
60818
+ if (!existsSync80(personaFile)) continue;
60819
+ const existing = readFileSync62(personaFile, "utf-8");
60260
60820
  if (existing.includes(crossContextHeader)) {
60261
60821
  continue;
60262
60822
  }
@@ -60278,7 +60838,7 @@ _(no round ${n - 1} report submitted)_`);
60278
60838
 
60279
60839
  ${peerLines.join("\n\n")}`;
60280
60840
  const updated = existing.trimEnd() + "\n\n" + newSection + "\n";
60281
- writeFileSync42(personaFile, updated, "utf-8");
60841
+ writeFileSync45(personaFile, updated, "utf-8");
60282
60842
  }
60283
60843
  }
60284
60844
  updateFrontmatterFields(debateFile, {
@@ -60286,13 +60846,13 @@ ${peerLines.join("\n\n")}`;
60286
60846
  current_round: n,
60287
60847
  updated_at: today()
60288
60848
  });
60289
- const logFile = join76(getDebateDir(debateId), "round-log.md");
60290
- const logExisting = existsSync79(logFile) ? readFileSync60(logFile, "utf-8") : "";
60849
+ const logFile = join78(getDebateDir(debateId), "round-log.md");
60850
+ const logExisting = existsSync80(logFile) ? readFileSync62(logFile, "utf-8") : "";
60291
60851
  const logEntry = `
60292
60852
  ## Round ${n} started \u2014 ${today()}
60293
60853
  - Personas: ${formatPersonaList(personas)}
60294
60854
  `;
60295
- writeFileSync42(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
60855
+ writeFileSync45(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
60296
60856
  upsertCouncilIndex({
60297
60857
  id: debateId,
60298
60858
  topic: data.topic,
@@ -60326,18 +60886,18 @@ ${peerLines.join("\n\n")}`;
60326
60886
  error(`Round ${n} incomplete. Missing reports from: ${missing.join(", ")}`);
60327
60887
  process.exit(1);
60328
60888
  }
60329
- const debateFile = join76(getDebateDir(debateId), "debate.md");
60889
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60330
60890
  updateFrontmatterFields(debateFile, {
60331
60891
  status: roundCompleteStatus(n),
60332
60892
  updated_at: today()
60333
60893
  });
60334
- const logFile = join76(getDebateDir(debateId), "round-log.md");
60335
- const logExisting = existsSync79(logFile) ? readFileSync60(logFile, "utf-8") : "";
60894
+ const logFile = join78(getDebateDir(debateId), "round-log.md");
60895
+ const logExisting = existsSync80(logFile) ? readFileSync62(logFile, "utf-8") : "";
60336
60896
  const logEntry = `
60337
60897
  ## Round ${n} complete \u2014 ${today()}
60338
60898
  - All ${personas.length} personas submitted reports.
60339
60899
  `;
60340
- writeFileSync42(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
60900
+ writeFileSync45(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
60341
60901
  upsertCouncilIndex({
60342
60902
  id: debateId,
60343
60903
  topic: data.topic,
@@ -60360,8 +60920,8 @@ function registerRoundContext(council) {
60360
60920
  try {
60361
60921
  const data = readDebateFrontmatter(debateId);
60362
60922
  ensurePersonaExists(debateId, personaSlug);
60363
- const personaFile = join76(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
60364
- const personaContent = readFileSync60(personaFile, "utf-8");
60923
+ const personaFile = join78(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
60924
+ const personaContent = readFileSync62(personaFile, "utf-8");
60365
60925
  console.log(`# Council debate: ${data.topic}`);
60366
60926
  console.log(`Debate ID: ${debateId}`);
60367
60927
  console.log(`Current round: ${data.current_round}/${data.rounds_planned}`);
@@ -60370,8 +60930,8 @@ function registerRoundContext(council) {
60370
60930
  console.log("---");
60371
60931
  console.log("");
60372
60932
  console.log(personaContent);
60373
- const debateFile = join76(getDebateDir(debateId), "debate.md");
60374
- const debateRaw = readFileSync60(debateFile, "utf-8");
60933
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60934
+ const debateRaw = readFileSync62(debateFile, "utf-8");
60375
60935
  const questionMatch = debateRaw.match(/##\s+Question\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
60376
60936
  const constraintsMatch = debateRaw.match(/##\s+Constraints & Known Facts\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
60377
60937
  if (questionMatch) {
@@ -60414,7 +60974,7 @@ function registerReport(council) {
60414
60974
  process.exit(1);
60415
60975
  }
60416
60976
  for (const w of validation.warnings) warn(w);
60417
- const reportFile = join76(getPersonaDir(debateId, personaSlug), "report.md");
60977
+ const reportFile = join78(getPersonaDir(debateId, personaSlug), "report.md");
60418
60978
  const { data: reportData, content } = readFrontmatter(reportFile);
60419
60979
  const existingRounds = parseReportRounds(content);
60420
60980
  if (existingRounds.find((r) => r.round === round)) {
@@ -60436,7 +60996,7 @@ ${otherSerialized}
60436
60996
  persona: personaSlug,
60437
60997
  rounds_completed: Math.max(reportData.rounds_completed ?? 0, round)
60438
60998
  }, "\n" + merged);
60439
- const personaFile = join76(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
60999
+ const personaFile = join78(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
60440
61000
  const { data: pData } = readFrontmatter(personaFile);
60441
61001
  updateFrontmatterFields(personaFile, {
60442
61002
  round_entries: Math.max(pData.round_entries ?? 0, round)
@@ -60479,13 +61039,13 @@ function registerResearch(council) {
60479
61039
  error("Research topic is required.");
60480
61040
  process.exit(1);
60481
61041
  }
60482
- const researchesDir = join76(getPersonaDir(debateId, personaSlug), "researches");
60483
- mkdirSync36(researchesDir, { recursive: true });
60484
- const indexPath2 = join76(researchesDir, "index.json");
60485
- if (!existsSync79(indexPath2)) writeJsonArray(indexPath2, []);
61042
+ const researchesDir = join78(getPersonaDir(debateId, personaSlug), "researches");
61043
+ mkdirSync39(researchesDir, { recursive: true });
61044
+ const indexPath2 = join78(researchesDir, "index.json");
61045
+ if (!existsSync80(indexPath2)) writeJsonArray(indexPath2, []);
60486
61046
  const slug = slugify(topic);
60487
- const file = join76(researchesDir, `${slug}.md`);
60488
- if (existsSync79(file)) {
61047
+ const file = join78(researchesDir, `${slug}.md`);
61048
+ if (existsSync80(file)) {
60489
61049
  error(`Research note already exists: ${slug}.md`);
60490
61050
  process.exit(1);
60491
61051
  }
@@ -60500,7 +61060,7 @@ _Added ${today()} by ${personaSlug}_
60500
61060
 
60501
61061
  ${body.trim()}
60502
61062
  `;
60503
- writeFileSync42(file, noteContent, "utf-8");
61063
+ writeFileSync45(file, noteContent, "utf-8");
60504
61064
  insertToJsonArray(indexPath2, {
60505
61065
  slug,
60506
61066
  topic,
@@ -60515,9 +61075,9 @@ ${body.trim()}
60515
61075
  research.command("list").argument("<debate_id>").argument("<persona_slug>").description("List this persona's prior research notes.").action((debateId, personaSlug) => {
60516
61076
  try {
60517
61077
  ensurePersonaExists(debateId, personaSlug);
60518
- const researchesDir = join76(getPersonaDir(debateId, personaSlug), "researches");
60519
- const indexPath2 = join76(researchesDir, "index.json");
60520
- if (!existsSync79(indexPath2)) {
61078
+ const researchesDir = join78(getPersonaDir(debateId, personaSlug), "researches");
61079
+ const indexPath2 = join78(researchesDir, "index.json");
61080
+ if (!existsSync80(indexPath2)) {
60521
61081
  console.log(source_default.dim("(no researches)"));
60522
61082
  return;
60523
61083
  }
@@ -60539,7 +61099,7 @@ function registerSynthesize(council) {
60539
61099
  council.command("synthesize").argument("<debate_id>").description("Mark status=synthesizing; print manifest of files synthesizer should read.").action((debateId) => {
60540
61100
  try {
60541
61101
  const data = readDebateFrontmatter(debateId);
60542
- const debateFile = join76(getDebateDir(debateId), "debate.md");
61102
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60543
61103
  updateFrontmatterFields(debateFile, {
60544
61104
  status: "synthesizing",
60545
61105
  updated_at: today()
@@ -60561,8 +61121,8 @@ function registerSynthesize(council) {
60561
61121
  const personaDir = getPersonaDir(debateId, persona);
60562
61122
  manifest.push(`_dream_context/council/${debateId}/${persona}/context-and-persona.md`);
60563
61123
  manifest.push(`_dream_context/council/${debateId}/${persona}/report.md`);
60564
- const researchesIndex = join76(personaDir, "researches", "index.json");
60565
- if (existsSync79(researchesIndex)) {
61124
+ const researchesIndex = join78(personaDir, "researches", "index.json");
61125
+ if (existsSync80(researchesIndex)) {
60566
61126
  manifest.push(`_dream_context/council/${debateId}/${persona}/researches/`);
60567
61127
  }
60568
61128
  }
@@ -60580,12 +61140,12 @@ function registerComplete(council) {
60580
61140
  council.command("complete").argument("<debate_id>").description("Mark status=complete after final-report.md is written.").action((debateId) => {
60581
61141
  try {
60582
61142
  const data = readDebateFrontmatter(debateId);
60583
- const finalReport = join76(getDebateDir(debateId), "final-report.md");
60584
- if (!existsSync79(finalReport)) {
61143
+ const finalReport = join78(getDebateDir(debateId), "final-report.md");
61144
+ if (!existsSync80(finalReport)) {
60585
61145
  error("final-report.md not found.", "Synthesizer must write it before calling `council complete`.");
60586
61146
  process.exit(1);
60587
61147
  }
60588
- const debateFile = join76(getDebateDir(debateId), "debate.md");
61148
+ const debateFile = join78(getDebateDir(debateId), "debate.md");
60589
61149
  updateFrontmatterFields(debateFile, {
60590
61150
  status: "complete",
60591
61151
  updated_at: today()
@@ -60617,8 +61177,8 @@ function registerPromote(council) {
60617
61177
  error(`Cannot promote: debate status is "${data.status}", expected "complete".`);
60618
61178
  process.exit(1);
60619
61179
  }
60620
- const finalReport = join76(getDebateDir(debateId), "final-report.md");
60621
- if (!existsSync79(finalReport)) {
61180
+ const finalReport = join78(getDebateDir(debateId), "final-report.md");
61181
+ if (!existsSync80(finalReport)) {
60622
61182
  error("final-report.md not found.");
60623
61183
  process.exit(1);
60624
61184
  }
@@ -60631,12 +61191,12 @@ function registerPromote(council) {
60631
61191
 
60632
61192
  ${sec.body.trim()}` : null;
60633
61193
  }).filter(Boolean).join("\n\n");
60634
- const knowledgeDir = join76(root, "knowledge");
60635
- mkdirSync36(knowledgeDir, { recursive: true });
61194
+ const knowledgeDir = join78(root, "knowledge");
61195
+ mkdirSync39(knowledgeDir, { recursive: true });
60636
61196
  const slug = slugify(data.topic).slice(0, 80) || debateId;
60637
61197
  const filename = `decision-${slug}.md`;
60638
- const target = join76(knowledgeDir, filename);
60639
- if (existsSync79(target) && !opts.force) {
61198
+ const target = join78(knowledgeDir, filename);
61199
+ if (existsSync80(target) && !opts.force) {
60640
61200
  error(`Knowledge file exists: ${filename}`, "Use --force to overwrite.");
60641
61201
  process.exit(1);
60642
61202
  }
@@ -60660,7 +61220,7 @@ ${kept}
60660
61220
  _Promoted from council debate \`${debateId}\` on ${today()}. See \`_dream_context/council/${debateId}/final-report.md\` for the full record._
60661
61221
  `;
60662
61222
  writeFrontmatter(target, knowledgeFrontmatter, body);
60663
- updateFrontmatterFields(join76(getDebateDir(debateId), "debate.md"), {
61223
+ updateFrontmatterFields(join78(getDebateDir(debateId), "debate.md"), {
60664
61224
  promoted_to_knowledge: `knowledge/${filename}`,
60665
61225
  updated_at: today()
60666
61226
  });
@@ -60722,10 +61282,10 @@ function registerShow(council) {
60722
61282
  console.log(` promoted: ${data.promoted_to_knowledge ?? source_default.dim("(no)")}`);
60723
61283
  console.log(` created: ${data.created_at}`);
60724
61284
  console.log(` updated: ${data.updated_at}`);
60725
- const logFile = join76(getDebateDir(debateId), "round-log.md");
60726
- if (existsSync79(logFile)) {
61285
+ const logFile = join78(getDebateDir(debateId), "round-log.md");
61286
+ if (existsSync80(logFile)) {
60727
61287
  console.log("\n" + source_default.dim("\u2500\u2500\u2500 Round log \u2500\u2500\u2500"));
60728
- console.log(readFileSync60(logFile, "utf-8"));
61288
+ console.log(readFileSync62(logFile, "utf-8"));
60729
61289
  }
60730
61290
  } catch (err) {
60731
61291
  error(err.message);
@@ -60917,12 +61477,12 @@ var init_env_loader = __esm({
60917
61477
  });
60918
61478
 
60919
61479
  // src/lib/marketing/config.ts
60920
- import { existsSync as existsSync80, readFileSync as readFileSync61, writeFileSync as writeFileSync43, mkdirSync as mkdirSync37 } from "fs";
60921
- import { dirname as dirname51 } from "path";
61480
+ import { existsSync as existsSync81, readFileSync as readFileSync63, writeFileSync as writeFileSync46, mkdirSync as mkdirSync40 } from "fs";
61481
+ import { dirname as dirname53 } from "path";
60922
61482
  function readEnvFile() {
60923
61483
  const path2 = MARKETING_PATHS.envFile();
60924
- if (!existsSync80(path2)) return {};
60925
- const raw = readFileSync61(path2, "utf8");
61484
+ if (!existsSync81(path2)) return {};
61485
+ const raw = readFileSync63(path2, "utf8");
60926
61486
  const parsed = parseEnv(raw);
60927
61487
  if (parsed.errors.length > 0) {
60928
61488
  for (const e of parsed.errors) {
@@ -60966,9 +61526,9 @@ function requireEnv(keys = REQUIRED_KEYS) {
60966
61526
  }
60967
61527
  function loadConfig() {
60968
61528
  const path2 = MARKETING_PATHS.configFile();
60969
- if (!existsSync80(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
61529
+ if (!existsSync81(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
60970
61530
  try {
60971
- const raw = readFileSync61(path2, "utf8");
61531
+ const raw = readFileSync63(path2, "utf8");
60972
61532
  const parsed = JSON.parse(raw);
60973
61533
  return {
60974
61534
  default_profile: parsed.default_profile ?? null,
@@ -60983,21 +61543,21 @@ function loadConfig() {
60983
61543
  }
60984
61544
  function writeConfig(cfg) {
60985
61545
  const path2 = MARKETING_PATHS.configFile();
60986
- mkdirSync37(dirname51(path2), { recursive: true });
60987
- writeFileSync43(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
61546
+ mkdirSync40(dirname53(path2), { recursive: true });
61547
+ writeFileSync46(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
60988
61548
  }
60989
61549
  function ensureConfigFile() {
60990
61550
  const path2 = MARKETING_PATHS.configFile();
60991
- if (existsSync80(path2)) return loadConfig();
61551
+ if (existsSync81(path2)) return loadConfig();
60992
61552
  const cfg = { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
60993
61553
  writeConfig(cfg);
60994
61554
  return cfg;
60995
61555
  }
60996
61556
  function ensureEnvFile() {
60997
61557
  const path2 = MARKETING_PATHS.envFile();
60998
- if (existsSync80(path2)) return;
60999
- mkdirSync37(marketingRoot(), { recursive: true });
61000
- writeFileSync43(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
61558
+ if (existsSync81(path2)) return;
61559
+ mkdirSync40(marketingRoot(), { recursive: true });
61560
+ writeFileSync46(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
61001
61561
  }
61002
61562
  var DEFAULT_API_VERSION, EMPTY_CONFIG, REQUIRED_KEYS, OPTIONAL_KEYS, ENV_TEMPLATE;
61003
61563
  var init_config2 = __esm({
@@ -61038,9 +61598,9 @@ REINFLUENCE_BIN= # optional override; default uses .venv
61038
61598
 
61039
61599
  // src/lib/marketing/bootstrap.ts
61040
61600
  import { spawn as spawn7, spawnSync as spawnSync2 } from "child_process";
61041
- import { existsSync as existsSync81, mkdirSync as mkdirSync38, cpSync as cpSync3 } from "fs";
61601
+ import { existsSync as existsSync82, mkdirSync as mkdirSync41, cpSync as cpSync3 } from "fs";
61042
61602
  import { fileURLToPath as fileURLToPath8 } from "url";
61043
- import { dirname as dirname52, resolve as resolve20, join as join77 } from "path";
61603
+ import { dirname as dirname54, resolve as resolve20, join as join79 } from "path";
61044
61604
  function findBundledReinfluence() {
61045
61605
  const candidates = [
61046
61606
  // Installed npm package: dist/<chunk>.js -> ../tools/reinfluence
@@ -61050,7 +61610,7 @@ function findBundledReinfluence() {
61050
61610
  resolve20(__dirname7, "..", "..", "..", "tools", "reinfluence")
61051
61611
  ];
61052
61612
  for (const c of candidates) {
61053
- if (existsSync81(join77(c, "__main__.py"))) return c;
61613
+ if (existsSync82(join79(c, "__main__.py"))) return c;
61054
61614
  }
61055
61615
  throw new Error(
61056
61616
  "Bundled reinfluence not found. Reinstall dreamcontext or set REINFLUENCE_BIN."
@@ -61081,18 +61641,18 @@ async function bootstrapMarketing(opts = {}) {
61081
61641
  if (verbose) process.stderr.write(`[mk init] ${msg}
61082
61642
  `);
61083
61643
  };
61084
- mkdirSync38(marketingRoot(), { recursive: true });
61644
+ mkdirSync41(marketingRoot(), { recursive: true });
61085
61645
  const bundled = findBundledReinfluence();
61086
61646
  const target = MARKETING_PATHS.reinfluenceDir();
61087
61647
  log(`copying tools \u2192 ${target}`);
61088
- mkdirSync38(MARKETING_PATHS.toolsDir(), { recursive: true });
61648
+ mkdirSync41(MARKETING_PATHS.toolsDir(), { recursive: true });
61089
61649
  cpSync3(bundled, target, { recursive: true });
61090
61650
  const py = findPython3();
61091
61651
  if (!py) {
61092
61652
  throw new Error("python3 not found on PATH. Install Python 3.10+ and retry.");
61093
61653
  }
61094
61654
  const venv = MARKETING_PATHS.venvDir();
61095
- if (!existsSync81(MARKETING_PATHS.venvPython())) {
61655
+ if (!existsSync82(MARKETING_PATHS.venvPython())) {
61096
61656
  log(`creating venv \u2192 ${venv}`);
61097
61657
  const r2 = runBlocking(py, ["-m", "venv", venv]);
61098
61658
  if (r2.code !== 0) {
@@ -61105,7 +61665,7 @@ async function bootstrapMarketing(opts = {}) {
61105
61665
  log("upgrading pip");
61106
61666
  let r = runBlocking(venvPy, ["-m", "pip", "install", "--upgrade", "pip", "--quiet"]);
61107
61667
  if (r.code !== 0) log(`pip upgrade warning: ${r.stderr.trim().slice(0, 200)}`);
61108
- const reqs = join77(target, "requirements.txt");
61668
+ const reqs = join79(target, "requirements.txt");
61109
61669
  log("installing python deps (whisper / yt-dlp / instaloader) \u2014 first run can take several minutes");
61110
61670
  r = runBlocking(venvPy, ["-m", "pip", "install", "-r", reqs, "--quiet"]);
61111
61671
  if (r.code !== 0) {
@@ -61115,7 +61675,7 @@ ${r.stderr.trim() || r.stdout.trim()}`);
61115
61675
  let whisperPrimed = false;
61116
61676
  if (whisperModel) {
61117
61677
  log(`pre-pulling whisper model "${whisperModel}" into ${MARKETING_PATHS.whisperCacheDir()}`);
61118
- mkdirSync38(MARKETING_PATHS.whisperCacheDir(), { recursive: true });
61678
+ mkdirSync41(MARKETING_PATHS.whisperCacheDir(), { recursive: true });
61119
61679
  whisperPrimed = await primeWhisper(whisperModel);
61120
61680
  if (!whisperPrimed) log("whisper pre-pull failed (will retry on first ingest)");
61121
61681
  }
@@ -61155,15 +61715,15 @@ function subprocessEnv() {
61155
61715
  return {
61156
61716
  ...process.env,
61157
61717
  XDG_CACHE_HOME: cache,
61158
- HF_HOME: join77(cache, "hf"),
61159
- TRANSFORMERS_CACHE: join77(cache, "hf", "transformers"),
61718
+ HF_HOME: join79(cache, "hf"),
61719
+ TRANSFORMERS_CACHE: join79(cache, "hf", "transformers"),
61160
61720
  WHISPER_CACHE_DIR: MARKETING_PATHS.whisperCacheDir(),
61161
61721
  PYTHONUNBUFFERED: "1",
61162
61722
  PYTHONPATH: MARKETING_PATHS.toolsDir()
61163
61723
  };
61164
61724
  }
61165
61725
  function isBootstrapped() {
61166
- return existsSync81(MARKETING_PATHS.venvPython()) && existsSync81(join77(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
61726
+ return existsSync82(MARKETING_PATHS.venvPython()) && existsSync82(join79(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
61167
61727
  }
61168
61728
  var __filename, __dirname7;
61169
61729
  var init_bootstrap = __esm({
@@ -61171,12 +61731,12 @@ var init_bootstrap = __esm({
61171
61731
  "use strict";
61172
61732
  init_paths2();
61173
61733
  __filename = fileURLToPath8(import.meta.url);
61174
- __dirname7 = dirname52(__filename);
61734
+ __dirname7 = dirname54(__filename);
61175
61735
  }
61176
61736
  });
61177
61737
 
61178
61738
  // src/cli/commands/marketing/init.ts
61179
- import { mkdirSync as mkdirSync39 } from "fs";
61739
+ import { mkdirSync as mkdirSync42 } from "fs";
61180
61740
  function registerMarketingInit(parent) {
61181
61741
  parent.command("init").description("Bootstrap _dream_context/marketing/ (folders, .env, venv, reinfluence tools, whisper cache)").option("--skip-bootstrap", "Only create folders + .env template; skip venv + pip install", false).option("--whisper-model <model>", "Whisper model to pre-pull (default: medium)", "medium").option("--no-whisper", "Skip Whisper model pre-pull").action(async (opts) => {
61182
61742
  try {
@@ -61187,7 +61747,7 @@ function registerMarketingInit(parent) {
61187
61747
  }
61188
61748
  console.log(header("Marketing init"));
61189
61749
  const root = marketingRoot();
61190
- mkdirSync39(root, { recursive: true });
61750
+ mkdirSync42(root, { recursive: true });
61191
61751
  for (const dir of [
61192
61752
  MARKETING_PATHS.cohortsDir(),
61193
61753
  MARKETING_PATHS.campaignsDir(),
@@ -61200,7 +61760,7 @@ function registerMarketingInit(parent) {
61200
61760
  MARKETING_PATHS.byIdemDir(),
61201
61761
  MARKETING_PATHS.cacheDir()
61202
61762
  ]) {
61203
- mkdirSync39(dir, { recursive: true });
61763
+ mkdirSync42(dir, { recursive: true });
61204
61764
  }
61205
61765
  info(`folders ready under ${source_default.dim(root)}`);
61206
61766
  ensureEnvFile();
@@ -61240,8 +61800,8 @@ var init_init2 = __esm({
61240
61800
  });
61241
61801
 
61242
61802
  // src/lib/marketing/vision.ts
61243
- import { existsSync as existsSync82, readFileSync as readFileSync62, writeFileSync as writeFileSync44 } from "fs";
61244
- import { dirname as dirname53, join as join78 } from "path";
61803
+ import { existsSync as existsSync83, readFileSync as readFileSync64, writeFileSync as writeFileSync47 } from "fs";
61804
+ import { dirname as dirname55, join as join80 } from "path";
61245
61805
  function pickVisionProvider(env2 = process.env) {
61246
61806
  const oai = env2.OPENAI_VISION_API_KEY;
61247
61807
  if (oai && oai.trim().length > 0) return { provider: "openai", apiKey: oai.trim() };
@@ -61280,11 +61840,11 @@ function parseLabelsFromText(text, allowlist = LABEL_ALLOWLIST) {
61280
61840
  return out;
61281
61841
  }
61282
61842
  async function readImageAsBase64(framePath) {
61283
- const buf = readFileSync62(framePath);
61843
+ const buf = readFileSync64(framePath);
61284
61844
  return buf.toString("base64");
61285
61845
  }
61286
61846
  async function labelHookFrame(framePath, opts) {
61287
- if (!existsSync82(framePath)) return [];
61847
+ if (!existsSync83(framePath)) return [];
61288
61848
  const fetcher = opts.fetcher ?? defaultFetcher;
61289
61849
  const prompt = opts.promptOverride ?? PROMPT;
61290
61850
  const b64 = await readImageAsBase64(framePath);
@@ -61334,7 +61894,7 @@ async function labelHookFrame(framePath, opts) {
61334
61894
  return parseLabelsFromText(text);
61335
61895
  }
61336
61896
  async function runVisionPassOnPost(postJsonPath, opts = {}) {
61337
- const raw = readFileSync62(postJsonPath, "utf-8");
61897
+ const raw = readFileSync64(postJsonPath, "utf-8");
61338
61898
  const post = JSON.parse(raw);
61339
61899
  const shortcode = post.shortcode ?? "?";
61340
61900
  const provider = opts.provider && opts.apiKey ? { provider: opts.provider, apiKey: opts.apiKey } : pickVisionProvider();
@@ -61373,15 +61933,15 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
61373
61933
  post.pattern_tags = [...aggregated].sort();
61374
61934
  post.vision_summary = post.pattern_tags.length > 0 ? `Vision-tagged ${framesLabeled}/${hookFrames.length} hook frames; patterns: ${post.pattern_tags.join(", ")}.` : `Vision pass found no allowlisted patterns across ${hookFrames.length} hook frames.`;
61375
61935
  const tmp = postJsonPath + ".tmp";
61376
- writeFileSync44(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
61936
+ writeFileSync47(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
61377
61937
  const fs = await import("fs");
61378
61938
  fs.renameSync(tmp, postJsonPath);
61379
- const mdPath = join78(dirname53(postJsonPath), `${shortcode}.md`);
61380
- if (existsSync82(mdPath)) {
61939
+ const mdPath = join80(dirname55(postJsonPath), `${shortcode}.md`);
61940
+ if (existsSync83(mdPath)) {
61381
61941
  try {
61382
- const md = readFileSync62(mdPath, "utf-8");
61942
+ const md = readFileSync64(mdPath, "utf-8");
61383
61943
  const refreshed = updatePatternTagsInBridge(md, post.pattern_tags);
61384
- writeFileSync44(mdPath, refreshed, "utf-8");
61944
+ writeFileSync47(mdPath, refreshed, "utf-8");
61385
61945
  } catch {
61386
61946
  }
61387
61947
  }
@@ -61456,8 +62016,8 @@ Example output: ["talking-head","prop-driven"]`;
61456
62016
  // src/lib/marketing/competitors.ts
61457
62017
  import { spawn as spawn8 } from "child_process";
61458
62018
  import { spawnSync as spawnSync3 } from "child_process";
61459
- import { existsSync as existsSync83, mkdirSync as mkdirSync40, statfsSync } from "fs";
61460
- import { dirname as dirname54, join as join79, basename as basename24, extname as extname6 } from "path";
62019
+ import { existsSync as existsSync84, mkdirSync as mkdirSync43, statfsSync } from "fs";
62020
+ import { dirname as dirname56, join as join81, basename as basename25, extname as extname6 } from "path";
61461
62021
  function which(cmd) {
61462
62022
  const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
61463
62023
  if (r.status === 0) return (r.stdout || "").trim().split("\n")[0] || null;
@@ -61534,8 +62094,8 @@ ${h.installHints.join("\n")}`);
61534
62094
  skip_transcripts: !!opts.skipTranscripts,
61535
62095
  skip_frames: !!opts.skipFrames
61536
62096
  });
61537
- const outDir = join79(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run2.id);
61538
- mkdirSync40(outDir, { recursive: true });
62097
+ const outDir = join81(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run2.id);
62098
+ mkdirSync43(outDir, { recursive: true });
61539
62099
  const args = [
61540
62100
  "-m",
61541
62101
  "reinfluence",
@@ -61635,15 +62195,15 @@ stderr: ${stderrBuf.slice(0, 1e3)}`));
61635
62195
  return { runId: run2.id, postsIngested, warnings, errors };
61636
62196
  }
61637
62197
  function persistPost(evt) {
61638
- const handleDir = join79(MARKETING_PATHS.competitorsDir(), evt.handle);
61639
- const postsDir = join79(handleDir, "posts");
61640
- const mediaDir = join79(handleDir, "_media", evt.shortcode);
61641
- mkdirSync40(postsDir, { recursive: true });
61642
- mkdirSync40(mediaDir, { recursive: true });
61643
- const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join79(mediaDir, basename24(evt.video_path))) : null;
62198
+ const handleDir = join81(MARKETING_PATHS.competitorsDir(), evt.handle);
62199
+ const postsDir = join81(handleDir, "posts");
62200
+ const mediaDir = join81(handleDir, "_media", evt.shortcode);
62201
+ mkdirSync43(postsDir, { recursive: true });
62202
+ mkdirSync43(mediaDir, { recursive: true });
62203
+ const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join81(mediaDir, basename25(evt.video_path))) : null;
61644
62204
  const finalFramePaths = [];
61645
62205
  for (const fr of evt.frames) {
61646
- const finalP = moveAsset(fr.path, join79(mediaDir, "frames", basename24(fr.path)));
62206
+ const finalP = moveAsset(fr.path, join81(mediaDir, "frames", basename25(fr.path)));
61647
62207
  finalFramePaths.push(finalP);
61648
62208
  }
61649
62209
  const id = `${evt.handle}__${evt.shortcode}`;
@@ -61663,14 +62223,14 @@ function persistPost(evt) {
61663
62223
  ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
61664
62224
  asset_paths: { video: finalVideoPath, frames: finalFramePaths }
61665
62225
  };
61666
- const jsonPath = join79(postsDir, `${evt.shortcode}.json`);
61667
- const bridgePath = join79(postsDir, `${evt.shortcode}.md`);
62226
+ const jsonPath = join81(postsDir, `${evt.shortcode}.json`);
62227
+ const bridgePath = join81(postsDir, `${evt.shortcode}.md`);
61668
62228
  writeJsonWithBridge(jsonPath, bridgePath, json, renderPostBridge(json));
61669
- const metaPath = join79(handleDir, "meta.json");
61670
- if (!existsSync83(metaPath)) {
62229
+ const metaPath = join81(handleDir, "meta.json");
62230
+ if (!existsSync84(metaPath)) {
61671
62231
  writeJsonWithBridge(
61672
62232
  metaPath,
61673
- join79(handleDir, "meta.md"),
62233
+ join81(handleDir, "meta.md"),
61674
62234
  { handle: evt.handle, first_seen_at: (/* @__PURE__ */ new Date()).toISOString() },
61675
62235
  `---
61676
62236
  id: competitor_${evt.handle}
@@ -61687,8 +62247,8 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
61687
62247
  return jsonPath;
61688
62248
  }
61689
62249
  function moveAsset(src, dest) {
61690
- if (!existsSync83(src)) return dest;
61691
- mkdirSync40(dirname54(dest), { recursive: true });
62250
+ if (!existsSync84(src)) return dest;
62251
+ mkdirSync43(dirname56(dest), { recursive: true });
61692
62252
  const fs = __require("fs");
61693
62253
  try {
61694
62254
  fs.renameSync(src, dest);
@@ -61749,8 +62309,8 @@ var init_competitors = __esm({
61749
62309
  });
61750
62310
 
61751
62311
  // src/cli/commands/marketing/competitor.ts
61752
- import { existsSync as existsSync84, readdirSync as readdirSync19, statSync as statSync15 } from "fs";
61753
- import { join as join80 } from "path";
62312
+ import { existsSync as existsSync85, readdirSync as readdirSync20, statSync as statSync17 } from "fs";
62313
+ import { join as join82 } from "path";
61754
62314
  function registerMarketingCompetitor(parent) {
61755
62315
  const cmd = parent.command("competitor").description("Ingest competitor IG / YouTube content (Reinfluence pipeline).");
61756
62316
  cmd.command("ingest <target>").description("Ingest a single URL or an IG handle. Outputs land under _dream_context/marketing/competitors/<handle>/.").option("--model <name>", "Whisper model size (tiny|base|small|medium|large)", "medium").option("--max <n>", "Max reels for IG handle ingest (0 = all)", "0").option("--skip-transcripts", "Skip Whisper transcription", false).option("--skip-frames", "Skip frame extraction", false).option("--timeout <seconds>", "Wall-clock kill", "600").action(async (target, opts) => {
@@ -61800,15 +62360,15 @@ function registerMarketingCompetitor(parent) {
61800
62360
  });
61801
62361
  cmd.command("list").description("List ingested competitor handles.").action(() => {
61802
62362
  const dir = MARKETING_PATHS.competitorsDir();
61803
- if (!existsSync84(dir)) {
62363
+ if (!existsSync85(dir)) {
61804
62364
  info("No competitors ingested yet.");
61805
62365
  return;
61806
62366
  }
61807
- const handles = readdirSync19(dir).filter((name) => {
62367
+ const handles = readdirSync20(dir).filter((name) => {
61808
62368
  if (name.startsWith("_") || name.startsWith(".")) return false;
61809
- const full = join80(dir, name);
62369
+ const full = join82(dir, name);
61810
62370
  try {
61811
- return statSync15(full).isDirectory();
62371
+ return statSync17(full).isDirectory();
61812
62372
  } catch {
61813
62373
  return false;
61814
62374
  }
@@ -61819,8 +62379,8 @@ function registerMarketingCompetitor(parent) {
61819
62379
  }
61820
62380
  console.log(header("Competitors"));
61821
62381
  for (const handle of handles) {
61822
- const postsDir = join80(dir, handle, "posts");
61823
- const postCount = existsSync84(postsDir) ? readdirSync19(postsDir).filter((f) => f.endsWith(".json")).length : 0;
62382
+ const postsDir = join82(dir, handle, "posts");
62383
+ const postCount = existsSync85(postsDir) ? readdirSync20(postsDir).filter((f) => f.endsWith(".json")).length : 0;
61824
62384
  console.log(` ${source_default.cyan("@" + handle)} ${source_default.dim(`${postCount} post(s)`)}`);
61825
62385
  }
61826
62386
  });
@@ -61833,11 +62393,11 @@ function registerMarketingCompetitor(parent) {
61833
62393
  }
61834
62394
  info(`Provider: ${provider.provider}`);
61835
62395
  const competitorsDir = MARKETING_PATHS.competitorsDir();
61836
- const handles = opts.handle ? [opts.handle] : existsSync84(competitorsDir) ? readdirSync19(competitorsDir).filter((h) => !h.startsWith("_") && statSync15(join80(competitorsDir, h)).isDirectory()) : [];
62396
+ const handles = opts.handle ? [opts.handle] : existsSync85(competitorsDir) ? readdirSync20(competitorsDir).filter((h) => !h.startsWith("_") && statSync17(join82(competitorsDir, h)).isDirectory()) : [];
61837
62397
  const matches = [];
61838
62398
  for (const h of handles) {
61839
- const candidate = join80(competitorsDir, h, "posts", `${shortcode}.json`);
61840
- if (existsSync84(candidate)) matches.push(candidate);
62399
+ const candidate = join82(competitorsDir, h, "posts", `${shortcode}.json`);
62400
+ if (existsSync85(candidate)) matches.push(candidate);
61841
62401
  }
61842
62402
  if (matches.length === 0) {
61843
62403
  error(`No post JSON found for shortcode "${shortcode}".`);
@@ -61872,18 +62432,18 @@ function registerMarketingCompetitor(parent) {
61872
62432
  process.exit(1);
61873
62433
  }
61874
62434
  const competitorsDir = MARKETING_PATHS.competitorsDir();
61875
- if (!existsSync84(competitorsDir)) {
62435
+ if (!existsSync85(competitorsDir)) {
61876
62436
  warn("No competitors directory yet \u2014 nothing to relabel.");
61877
62437
  return;
61878
62438
  }
61879
- const handles = readdirSync19(competitorsDir).filter((h) => !h.startsWith("_") && statSync15(join80(competitorsDir, h)).isDirectory());
62439
+ const handles = readdirSync20(competitorsDir).filter((h) => !h.startsWith("_") && statSync17(join82(competitorsDir, h)).isDirectory());
61880
62440
  let labeled = 0;
61881
62441
  let skipped = 0;
61882
62442
  for (const h of handles) {
61883
- const postsDir = join80(competitorsDir, h, "posts");
61884
- if (!existsSync84(postsDir)) continue;
61885
- for (const f of readdirSync19(postsDir).filter((n) => n.endsWith(".json"))) {
61886
- const path2 = join80(postsDir, f);
62443
+ const postsDir = join82(competitorsDir, h, "posts");
62444
+ if (!existsSync85(postsDir)) continue;
62445
+ for (const f of readdirSync20(postsDir).filter((n) => n.endsWith(".json"))) {
62446
+ const path2 = join82(postsDir, f);
61887
62447
  if (opts.dryRun) {
61888
62448
  info(`would relabel: ${path2}`);
61889
62449
  continue;
@@ -61930,9 +62490,9 @@ var init_competitor = __esm({
61930
62490
  });
61931
62491
 
61932
62492
  // src/lib/marketing/meta-fetch.ts
61933
- import { existsSync as existsSync85, mkdirSync as mkdirSync41, readFileSync as readFileSync63, writeFileSync as writeFileSync45, statSync as statSync16, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
61934
- import { dirname as dirname55, basename as basename25 } from "path";
61935
- import { randomUUID as randomUUID4 } from "crypto";
62493
+ import { existsSync as existsSync86, mkdirSync as mkdirSync44, readFileSync as readFileSync65, writeFileSync as writeFileSync48, statSync as statSync18, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
62494
+ import { dirname as dirname57, basename as basename26 } from "path";
62495
+ import { randomUUID as randomUUID7 } from "crypto";
61936
62496
  function getQueue(accountId) {
61937
62497
  let q = writeQueues.get(accountId);
61938
62498
  if (!q) {
@@ -61981,17 +62541,17 @@ function idemCachePath(key2) {
61981
62541
  }
61982
62542
  function readIdem(key2) {
61983
62543
  const p = idemCachePath(key2);
61984
- if (!existsSync85(p)) return null;
62544
+ if (!existsSync86(p)) return null;
61985
62545
  try {
61986
- return JSON.parse(readFileSync63(p, "utf8"));
62546
+ return JSON.parse(readFileSync65(p, "utf8"));
61987
62547
  } catch {
61988
62548
  return null;
61989
62549
  }
61990
62550
  }
61991
62551
  function writeIdem(rec) {
61992
62552
  const p = idemCachePath(rec.key);
61993
- mkdirSync41(dirname55(p), { recursive: true });
61994
- writeFileSync45(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
62553
+ mkdirSync44(dirname57(p), { recursive: true });
62554
+ writeFileSync48(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
61995
62555
  }
61996
62556
  function backoffMs(attempt, hintSec) {
61997
62557
  if (hintSec != null && Number.isFinite(hintSec) && hintSec > 0) {
@@ -62106,7 +62666,7 @@ async function metaFetch(ctx, init) {
62106
62666
  }
62107
62667
  let idemKey;
62108
62668
  if (isCreate(init)) {
62109
- idemKey = randomUUID4();
62669
+ idemKey = randomUUID7();
62110
62670
  const cached = readIdem(idemKey);
62111
62671
  if (cached) {
62112
62672
  logLine(ctx, `[idem] cache hit ${idemKey} on ${init.path}`);
@@ -62196,7 +62756,7 @@ async function uploadVideoFile(ctx, filepath, fields = {}) {
62196
62756
  logLine(ctx, `[DRY] uploadVideoFile ${filepath}`);
62197
62757
  return { video_id: fakeId, upload_session_id: `DRY_session_${fakeId}` };
62198
62758
  }
62199
- const stat = statSync16(filepath);
62759
+ const stat = statSync18(filepath);
62200
62760
  const fileSize = stat.size;
62201
62761
  const path2 = `${ctx.adAccountId}/advideos`;
62202
62762
  if (fileSize <= CHUNKED_UPLOAD_THRESHOLD) {
@@ -62224,12 +62784,12 @@ async function uploadVideoFile(ctx, filepath, fields = {}) {
62224
62784
  form.set("upload_session_id", sessionId);
62225
62785
  form.set("start_offset", String(startOffset));
62226
62786
  const blob = new Blob([new Uint8Array(buf)], { type: "application/octet-stream" });
62227
- form.set("video_file_chunk", blob, basename25(filepath));
62787
+ form.set("video_file_chunk", blob, basename26(filepath));
62228
62788
  const transfer = await uploadFormDataChunked(ctx, path2, form);
62229
62789
  const next = transfer;
62230
62790
  startOffset = Number(next.start_offset);
62231
62791
  endOffset = Number(next.end_offset);
62232
- logLine(ctx, `[upload] ${basename25(filepath)} progress: ${startOffset}/${fileSize}`);
62792
+ logLine(ctx, `[upload] ${basename26(filepath)} progress: ${startOffset}/${fileSize}`);
62233
62793
  }
62234
62794
  } finally {
62235
62795
  closeSync2(fd);
@@ -62259,9 +62819,9 @@ async function singleShotVideoUpload(ctx, filepath, fields) {
62259
62819
  if (fields.name) form.set("name", fields.name);
62260
62820
  if (fields.title) form.set("title", fields.title);
62261
62821
  if (fields.description) form.set("description", fields.description);
62262
- const buffer = readFileSync63(filepath);
62822
+ const buffer = readFileSync65(filepath);
62263
62823
  const blob = new Blob([new Uint8Array(buffer)], { type: "video/mp4" });
62264
- form.set("source", blob, basename25(filepath));
62824
+ form.set("source", blob, basename26(filepath));
62265
62825
  const resp = await fetch(url, {
62266
62826
  method: "POST",
62267
62827
  headers: { Authorization: `Bearer ${ctx.accessToken}` },
@@ -62308,9 +62868,9 @@ async function uploadImageFile(ctx, filepath) {
62308
62868
  return withWriteSlot(ctx.adAccountId, async () => {
62309
62869
  const url = buildUrl(ctx, { method: "POST", path: `${ctx.adAccountId}/adimages` });
62310
62870
  const form = new FormData();
62311
- const buffer = readFileSync63(filepath);
62871
+ const buffer = readFileSync65(filepath);
62312
62872
  const blob = new Blob([new Uint8Array(buffer)], { type: "image/png" });
62313
- form.set("filename", blob, basename25(filepath));
62873
+ form.set("filename", blob, basename26(filepath));
62314
62874
  const resp = await fetch(url, {
62315
62875
  method: "POST",
62316
62876
  headers: { Authorization: `Bearer ${ctx.accessToken}` },
@@ -62727,7 +63287,7 @@ var init_account = __esm({
62727
63287
  });
62728
63288
 
62729
63289
  // src/lib/marketing/hypothesis.ts
62730
- import { existsSync as existsSync86, readFileSync as readFileSync64 } from "fs";
63290
+ import { existsSync as existsSync87, readFileSync as readFileSync66 } from "fs";
62731
63291
  function validateHypothesis(raw, options2 = {}) {
62732
63292
  const errors = [];
62733
63293
  const fieldErrors = {};
@@ -62794,12 +63354,12 @@ function validateHypothesis(raw, options2 = {}) {
62794
63354
  };
62795
63355
  }
62796
63356
  function loadHypothesisFile(path2, options2 = {}) {
62797
- if (!existsSync86(path2)) {
63357
+ if (!existsSync87(path2)) {
62798
63358
  return { ok: false, errors: [`Hypothesis file not found: ${path2}`] };
62799
63359
  }
62800
63360
  let parsed;
62801
63361
  try {
62802
- parsed = JSON.parse(readFileSync64(path2, "utf8"));
63362
+ parsed = JSON.parse(readFileSync66(path2, "utf8"));
62803
63363
  } catch (e) {
62804
63364
  return { ok: false, errors: [`Failed to parse JSON at ${path2}: ${e.message}`] };
62805
63365
  }
@@ -62987,8 +63547,8 @@ var init_cohort2 = __esm({
62987
63547
  });
62988
63548
 
62989
63549
  // src/lib/marketing/insights-cache.ts
62990
- import { existsSync as existsSync87, readFileSync as readFileSync65, mkdirSync as mkdirSync42, writeFileSync as writeFileSync46, readdirSync as readdirSync20, statSync as statSync17 } from "fs";
62991
- import { join as join81 } from "path";
63550
+ import { existsSync as existsSync88, readFileSync as readFileSync67, mkdirSync as mkdirSync45, writeFileSync as writeFileSync49, readdirSync as readdirSync21, statSync as statSync19 } from "fs";
63551
+ import { join as join83 } from "path";
62992
63552
  import { randomBytes as randomBytes4 } from "crypto";
62993
63553
  function snapshotFilename(entityId, pulledAt) {
62994
63554
  const yyyy = pulledAt.getUTCFullYear();
@@ -62999,30 +63559,30 @@ function snapshotFilename(entityId, pulledAt) {
62999
63559
  return `${safe}__${yyyy}-${mm}-${dd}-${hh}.json`;
63000
63560
  }
63001
63561
  function indexPath() {
63002
- return join81(MARKETING_PATHS.insightsDir(), "_index.json");
63562
+ return join83(MARKETING_PATHS.insightsDir(), "_index.json");
63003
63563
  }
63004
63564
  function readIndex() {
63005
63565
  const p = indexPath();
63006
- if (!existsSync87(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
63566
+ if (!existsSync88(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
63007
63567
  try {
63008
- return JSON.parse(readFileSync65(p, "utf8"));
63568
+ return JSON.parse(readFileSync67(p, "utf8"));
63009
63569
  } catch {
63010
63570
  return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
63011
63571
  }
63012
63572
  }
63013
63573
  function writeIndex(idx) {
63014
63574
  const p = indexPath();
63015
- mkdirSync42(MARKETING_PATHS.insightsDir(), { recursive: true });
63575
+ mkdirSync45(MARKETING_PATHS.insightsDir(), { recursive: true });
63016
63576
  const tmp = `${p}.tmp.${process.pid}.${randomBytes4(4).toString("hex")}`;
63017
- writeFileSync46(tmp, JSON.stringify(idx, null, 2) + "\n", "utf8");
63577
+ writeFileSync49(tmp, JSON.stringify(idx, null, 2) + "\n", "utf8");
63018
63578
  __require("fs").renameSync(tmp, p);
63019
63579
  }
63020
63580
  function saveInsightsSnapshot(snap) {
63021
- mkdirSync42(MARKETING_PATHS.insightsDir(), { recursive: true });
63581
+ mkdirSync45(MARKETING_PATHS.insightsDir(), { recursive: true });
63022
63582
  const filename = snapshotFilename(snap.entity_id, new Date(snap.pulled_at));
63023
- const fullPath = join81(MARKETING_PATHS.insightsDir(), filename);
63583
+ const fullPath = join83(MARKETING_PATHS.insightsDir(), filename);
63024
63584
  const tmp = `${fullPath}.tmp.${process.pid}.${randomBytes4(4).toString("hex")}`;
63025
- writeFileSync46(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
63585
+ writeFileSync49(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
63026
63586
  __require("fs").renameSync(tmp, fullPath);
63027
63587
  const idx = readIndex();
63028
63588
  idx.latest[snap.entity_id] = filename;
@@ -63034,10 +63594,10 @@ function getCachedInsights(entityId) {
63034
63594
  const idx = readIndex();
63035
63595
  const filename = idx.latest[entityId];
63036
63596
  if (!filename) return null;
63037
- const fullPath = join81(MARKETING_PATHS.insightsDir(), filename);
63038
- if (!existsSync87(fullPath)) return null;
63597
+ const fullPath = join83(MARKETING_PATHS.insightsDir(), filename);
63598
+ if (!existsSync88(fullPath)) return null;
63039
63599
  try {
63040
- const snap = JSON.parse(readFileSync65(fullPath, "utf8"));
63600
+ const snap = JSON.parse(readFileSync67(fullPath, "utf8"));
63041
63601
  const ageMs = Date.now() - new Date(snap.pulled_at).getTime();
63042
63602
  if (ageMs > INSIGHTS_TTL_MS) return null;
63043
63603
  return snap;
@@ -63049,28 +63609,28 @@ function getLatestSnapshot(entityId) {
63049
63609
  const idx = readIndex();
63050
63610
  const filename = idx.latest[entityId];
63051
63611
  if (!filename) return null;
63052
- const fullPath = join81(MARKETING_PATHS.insightsDir(), filename);
63053
- if (!existsSync87(fullPath)) return null;
63612
+ const fullPath = join83(MARKETING_PATHS.insightsDir(), filename);
63613
+ if (!existsSync88(fullPath)) return null;
63054
63614
  try {
63055
- return JSON.parse(readFileSync65(fullPath, "utf8"));
63615
+ return JSON.parse(readFileSync67(fullPath, "utf8"));
63056
63616
  } catch {
63057
63617
  return null;
63058
63618
  }
63059
63619
  }
63060
63620
  function getPriorSnapshot(entityId, beforeMs) {
63061
63621
  const dir = MARKETING_PATHS.insightsDir();
63062
- if (!existsSync87(dir)) return null;
63622
+ if (!existsSync88(dir)) return null;
63063
63623
  const safe = entityId.replace(/[^A-Za-z0-9_-]/g, "_");
63064
- const candidates = readdirSync20(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
63065
- const p = join81(dir, f);
63066
- const stat = statSync17(p);
63624
+ const candidates = readdirSync21(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
63625
+ const p = join83(dir, f);
63626
+ const stat = statSync19(p);
63067
63627
  return { f, p, mtimeMs: stat.mtimeMs };
63068
63628
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
63069
63629
  const cutoff = Date.now() - beforeMs;
63070
63630
  for (const c of candidates) {
63071
63631
  if (c.mtimeMs <= cutoff) {
63072
63632
  try {
63073
- return JSON.parse(readFileSync65(c.p, "utf8"));
63633
+ return JSON.parse(readFileSync67(c.p, "utf8"));
63074
63634
  } catch {
63075
63635
  continue;
63076
63636
  }
@@ -63706,8 +64266,8 @@ var init_kill = __esm({
63706
64266
  });
63707
64267
 
63708
64268
  // src/cli/commands/marketing/doctor.ts
63709
- import { readFileSync as readFileSync66, readdirSync as readdirSync21, statSync as statSync18 } from "fs";
63710
- import { join as join82 } from "path";
64269
+ import { readFileSync as readFileSync68, readdirSync as readdirSync22, statSync as statSync20 } from "fs";
64270
+ import { join as join84 } from "path";
63711
64271
  function registerMarketingDoctor(parent) {
63712
64272
  parent.command("doctor").description("Run diagnostics: env, FK integrity, retroactive secret scan, Reinfluence health.").option("--scan", "Run retroactive secret scan over the entire _dream_context/ tree", false).action(async (opts) => {
63713
64273
  console.log(header("Marketing doctor"));
@@ -63788,7 +64348,7 @@ function scanForSecrets(root) {
63788
64348
  for (const file of walkText(root)) {
63789
64349
  let txt;
63790
64350
  try {
63791
- txt = readFileSync66(file, "utf8");
64351
+ txt = readFileSync68(file, "utf8");
63792
64352
  } catch {
63793
64353
  continue;
63794
64354
  }
@@ -63809,16 +64369,16 @@ function scanForSecrets(root) {
63809
64369
  function* walkText(dir) {
63810
64370
  let entries;
63811
64371
  try {
63812
- entries = readdirSync21(dir);
64372
+ entries = readdirSync22(dir);
63813
64373
  } catch {
63814
64374
  return;
63815
64375
  }
63816
64376
  for (const e of entries) {
63817
64377
  if (e.startsWith(".") && (e === ".env" || e === ".env.local")) continue;
63818
- const full = join82(dir, e);
64378
+ const full = join84(dir, e);
63819
64379
  let stat;
63820
64380
  try {
63821
- stat = statSync18(full);
64381
+ stat = statSync20(full);
63822
64382
  } catch {
63823
64383
  continue;
63824
64384
  }
@@ -63853,8 +64413,8 @@ var init_doctor2 = __esm({
63853
64413
  });
63854
64414
 
63855
64415
  // src/lib/marketing/entity-store.ts
63856
- import { existsSync as existsSync89, readFileSync as readFileSync67, readdirSync as readdirSync22 } from "fs";
63857
- import { join as join83 } from "path";
64416
+ import { existsSync as existsSync90, readFileSync as readFileSync69, readdirSync as readdirSync23 } from "fs";
64417
+ import { join as join85 } from "path";
63858
64418
  function dirFor(kind) {
63859
64419
  switch (kind) {
63860
64420
  case "campaign":
@@ -63873,24 +64433,24 @@ function newEntityId(kind) {
63873
64433
  }
63874
64434
  function entityPaths(kind, id) {
63875
64435
  const d = dirFor(kind);
63876
- return { json: join83(d, `${id}.json`), md: join83(d, `${id}.md`) };
64436
+ return { json: join85(d, `${id}.json`), md: join85(d, `${id}.md`) };
63877
64437
  }
63878
64438
  function loadEntity(kind, id) {
63879
64439
  const { json } = entityPaths(kind, id);
63880
- if (!existsSync89(json)) return null;
64440
+ if (!existsSync90(json)) return null;
63881
64441
  try {
63882
- return JSON.parse(readFileSync67(json, "utf8"));
64442
+ return JSON.parse(readFileSync69(json, "utf8"));
63883
64443
  } catch {
63884
64444
  return null;
63885
64445
  }
63886
64446
  }
63887
64447
  function listEntities(kind) {
63888
64448
  const d = dirFor(kind);
63889
- if (!existsSync89(d)) return [];
64449
+ if (!existsSync90(d)) return [];
63890
64450
  const out = [];
63891
- for (const f of readdirSync22(d).filter((x) => x.endsWith(".json"))) {
64451
+ for (const f of readdirSync23(d).filter((x) => x.endsWith(".json"))) {
63892
64452
  try {
63893
- out.push(JSON.parse(readFileSync67(join83(d, f), "utf8")));
64453
+ out.push(JSON.parse(readFileSync69(join85(d, f), "utf8")));
63894
64454
  } catch {
63895
64455
  }
63896
64456
  }
@@ -64084,7 +64644,7 @@ var init_campaign = __esm({
64084
64644
  });
64085
64645
 
64086
64646
  // src/cli/commands/marketing/adset.ts
64087
- import { existsSync as existsSync90, readFileSync as readFileSync68 } from "fs";
64647
+ import { existsSync as existsSync91, readFileSync as readFileSync70 } from "fs";
64088
64648
  function registerMarketingAdSet(parent) {
64089
64649
  const cmd = parent.command("adset").description("Manage adsets.");
64090
64650
  cmd.command("create").description("Create an adset (PAUSED). --daily-budget required (no fallback).").requiredOption("--campaign <id>", "parent campaign local id").requiredOption("--name <name>", "adset name").requiredOption("--daily-budget <amount>", "daily budget (major-currency units)").requiredOption("--targeting <file>", "JSON file with Meta targeting spec").option("--currency <code>", "currency code", "TRY").option("--optimization-goal <goal>", "OFFSITE_CONVERSIONS|LINK_CLICKS|...", "OFFSITE_CONVERSIONS").option("--billing-event <event>", "IMPRESSIONS|LINK_CLICKS|THRUPLAY", "IMPRESSIONS").option("--custom-event-type <evt>", "e.g. PURCHASE, COMPLETE_REGISTRATION (for OFFSITE_CONVERSIONS)").option("--no-dry-run", "Actually create on Meta").action(async (opts) => {
@@ -64104,13 +64664,13 @@ function registerMarketingAdSet(parent) {
64104
64664
  }
64105
64665
  throw e;
64106
64666
  }
64107
- if (!existsSync90(opts.targeting)) {
64667
+ if (!existsSync91(opts.targeting)) {
64108
64668
  error(`Targeting file not found: ${opts.targeting}`);
64109
64669
  process.exit(1);
64110
64670
  }
64111
64671
  let targeting;
64112
64672
  try {
64113
- targeting = JSON.parse(readFileSync68(opts.targeting, "utf8"));
64673
+ targeting = JSON.parse(readFileSync70(opts.targeting, "utf8"));
64114
64674
  } catch (e) {
64115
64675
  error(`Failed to parse targeting JSON: ${e.message}`);
64116
64676
  process.exit(1);
@@ -64367,12 +64927,12 @@ var init_creative = __esm({
64367
64927
  });
64368
64928
 
64369
64929
  // src/cli/commands/marketing/asset.ts
64370
- import { existsSync as existsSync91, statSync as statSync19 } from "fs";
64930
+ import { existsSync as existsSync92, statSync as statSync21 } from "fs";
64371
64931
  import { extname as extname7 } from "path";
64372
64932
  function registerMarketingAsset(parent) {
64373
64933
  const cmd = parent.command("asset").description("Upload creative assets to Meta.");
64374
64934
  cmd.command("upload <path>").description("Upload a video (>50MB \u2192 chunked) or image to Meta. Returns id/hash.").option("--type <type>", "override auto-detection (video|image)").option("--name <name>", "asset name (videos)").option("--no-dry-run", "Actually upload to Meta").action(async (path2, opts) => {
64375
- if (!existsSync91(path2)) {
64935
+ if (!existsSync92(path2)) {
64376
64936
  error(`File not found: ${path2}`);
64377
64937
  process.exit(1);
64378
64938
  }
@@ -64388,7 +64948,7 @@ function registerMarketingAsset(parent) {
64388
64948
  error(`Could not auto-detect asset type for "${ext}". Pass --type video|image.`);
64389
64949
  process.exit(1);
64390
64950
  }
64391
- const sizeMb = (statSync19(path2).size / (1024 * 1024)).toFixed(1);
64951
+ const sizeMb = (statSync21(path2).size / (1024 * 1024)).toFixed(1);
64392
64952
  console.log(header(`Asset upload \u2014 ${kind} (${sizeMb} MB)`));
64393
64953
  const ctx = buildCtx({ noDryRun: opts.dryRun === false });
64394
64954
  if (ctx.dryRun) info(source_default.yellow("[DRY-RUN] no live changes"));
@@ -64540,8 +65100,8 @@ var init_ad = __esm({
64540
65100
  });
64541
65101
 
64542
65102
  // src/lib/marketing/launch.ts
64543
- import { existsSync as existsSync92, readFileSync as readFileSync69, writeFileSync as writeFileSync47, mkdirSync as mkdirSync43, renameSync as renameSync12, readdirSync as readdirSync23 } from "fs";
64544
- import { dirname as dirname56, join as join84, basename as basename26 } from "path";
65103
+ import { existsSync as existsSync93, readFileSync as readFileSync71, writeFileSync as writeFileSync50, mkdirSync as mkdirSync46, renameSync as renameSync13, readdirSync as readdirSync24 } from "fs";
65104
+ import { dirname as dirname58, join as join86, basename as basename27 } from "path";
64545
65105
  import { randomBytes as randomBytes5 } from "crypto";
64546
65106
  function buildLaunchSummary(cohortId) {
64547
65107
  const cohort = loadCohort(cohortId);
@@ -64585,15 +65145,15 @@ function isoTs2() {
64585
65145
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
64586
65146
  }
64587
65147
  function atomicWriteFile3(path2, data) {
64588
- mkdirSync43(dirname56(path2), { recursive: true });
65148
+ mkdirSync46(dirname58(path2), { recursive: true });
64589
65149
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes5(4).toString("hex")}`;
64590
- writeFileSync47(tmp, data, "utf8");
64591
- renameSync12(tmp, path2);
65150
+ writeFileSync50(tmp, data, "utf8");
65151
+ renameSync13(tmp, path2);
64592
65152
  }
64593
65153
  function readWal(path2) {
64594
- if (!existsSync92(path2)) return null;
65154
+ if (!existsSync93(path2)) return null;
64595
65155
  try {
64596
- return JSON.parse(readFileSync69(path2, "utf8"));
65156
+ return JSON.parse(readFileSync71(path2, "utf8"));
64597
65157
  } catch {
64598
65158
  return null;
64599
65159
  }
@@ -64603,13 +65163,13 @@ function writeWal(path2, wal) {
64603
65163
  }
64604
65164
  function findWalByRunId(runId) {
64605
65165
  const dir = MARKETING_PATHS.runsDir();
64606
- if (!existsSync92(dir)) return null;
64607
- for (const f of readdirSync23(dir)) {
65166
+ if (!existsSync93(dir)) return null;
65167
+ for (const f of readdirSync24(dir)) {
64608
65168
  if (!f.endsWith(".json")) continue;
64609
65169
  if (f.startsWith("by-idem")) continue;
64610
65170
  const stem = f.replace(/\.json$/, "");
64611
- if (stem === runId || f === runId || basename26(f, ".json") === runId) {
64612
- return join84(dir, f);
65171
+ if (stem === runId || f === runId || basename27(f, ".json") === runId) {
65172
+ return join86(dir, f);
64613
65173
  }
64614
65174
  }
64615
65175
  return null;
@@ -64649,7 +65209,7 @@ function createLaunchWal(args) {
64649
65209
  flipped_count: 0,
64650
65210
  error: null
64651
65211
  };
64652
- const walPath = join84(MARKETING_PATHS.runsDir(), `${id}.json`);
65212
+ const walPath = join86(MARKETING_PATHS.runsDir(), `${id}.json`);
64653
65213
  writeWal(walPath, wal);
64654
65214
  return { walPath, wal };
64655
65215
  }
@@ -64880,7 +65440,7 @@ var init_launch2 = __esm({
64880
65440
  });
64881
65441
 
64882
65442
  // src/cli/commands/marketing/learnings.ts
64883
- import { existsSync as existsSync93, readFileSync as readFileSync70 } from "fs";
65443
+ import { existsSync as existsSync94, readFileSync as readFileSync72 } from "fs";
64884
65444
  function registerMarketingLearnings(parent) {
64885
65445
  const cmd = parent.command("learnings").description("Performance Monitor learnings ledger (per-day .md + index).");
64886
65446
  cmd.command("show").description("Show today's (or specified day's) learnings file.").option("--date <YYYY-MM-DD>", "Day to show (default: today UTC)").option("--id <id>", "Show a single entry by id").action((opts) => {
@@ -65023,8 +65583,8 @@ async function resolveBody(body, bodyFile) {
65023
65583
  if (body) return body;
65024
65584
  if (bodyFile === "-") return readStdin3();
65025
65585
  if (bodyFile) {
65026
- if (!existsSync93(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
65027
- return readFileSync70(bodyFile, "utf8");
65586
+ if (!existsSync94(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
65587
+ return readFileSync72(bodyFile, "utf8");
65028
65588
  }
65029
65589
  return null;
65030
65590
  }
@@ -65054,31 +65614,31 @@ var init_learnings2 = __esm({
65054
65614
 
65055
65615
  // src/lib/marketing/rem-sleep.ts
65056
65616
  import {
65057
- existsSync as existsSync94,
65058
- mkdirSync as mkdirSync44,
65059
- readFileSync as readFileSync71,
65060
- writeFileSync as writeFileSync48,
65061
- readdirSync as readdirSync24,
65062
- statSync as statSync20,
65063
- unlinkSync as unlinkSync5,
65064
- renameSync as renameSync13
65617
+ existsSync as existsSync95,
65618
+ mkdirSync as mkdirSync47,
65619
+ readFileSync as readFileSync73,
65620
+ writeFileSync as writeFileSync51,
65621
+ readdirSync as readdirSync25,
65622
+ statSync as statSync22,
65623
+ unlinkSync as unlinkSync6,
65624
+ renameSync as renameSync14
65065
65625
  } from "fs";
65066
- import { dirname as dirname57, join as join85 } from "path";
65626
+ import { dirname as dirname59, join as join87 } from "path";
65067
65627
  import { randomBytes as randomBytes6 } from "crypto";
65068
65628
  function atomicWriteFile4(path2, data) {
65069
- mkdirSync44(dirname57(path2), { recursive: true });
65629
+ mkdirSync47(dirname59(path2), { recursive: true });
65070
65630
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes6(4).toString("hex")}`;
65071
- writeFileSync48(tmp, data, "utf8");
65072
- renameSync13(tmp, path2);
65631
+ writeFileSync51(tmp, data, "utf8");
65632
+ renameSync14(tmp, path2);
65073
65633
  }
65074
65634
  function pruneRuns2(opts = {}) {
65075
65635
  const keepLast = opts.keepLast ?? 100;
65076
65636
  const dir = MARKETING_PATHS.runsDir();
65077
- if (!existsSync94(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
65078
- const files = readdirSync24(dir).filter((f) => f.endsWith(".json")).map((f) => {
65079
- const p = join85(dir, f);
65637
+ if (!existsSync95(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
65638
+ const files = readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) => {
65639
+ const p = join87(dir, f);
65080
65640
  try {
65081
- return { f, p, mtimeMs: statSync20(p).mtimeMs };
65641
+ return { f, p, mtimeMs: statSync22(p).mtimeMs };
65082
65642
  } catch {
65083
65643
  return null;
65084
65644
  }
@@ -65091,7 +65651,7 @@ function pruneRuns2(opts = {}) {
65091
65651
  if (!opts.dryRun) {
65092
65652
  for (const x of toDelete) {
65093
65653
  try {
65094
- unlinkSync5(x.p);
65654
+ unlinkSync6(x.p);
65095
65655
  deletedFiles.push(x.f);
65096
65656
  } catch {
65097
65657
  }
@@ -65110,15 +65670,15 @@ function compactInsights(opts = {}) {
65110
65670
  const weeklyAfterDays = opts.weeklyAfterDays ?? 14;
65111
65671
  const now = opts.now ?? /* @__PURE__ */ new Date();
65112
65672
  const dir = MARKETING_PATHS.insightsDir();
65113
- if (!existsSync94(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
65673
+ if (!existsSync95(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
65114
65674
  const files = [];
65115
- for (const f of readdirSync24(dir)) {
65675
+ for (const f of readdirSync25(dir)) {
65116
65676
  if (!f.endsWith(".json") || f.startsWith("_")) continue;
65117
65677
  const m = f.match(SNAP_RE);
65118
65678
  if (!m) continue;
65119
- const p = join85(dir, f);
65679
+ const p = join87(dir, f);
65120
65680
  try {
65121
- const stat = statSync20(p);
65681
+ const stat = statSync22(p);
65122
65682
  files.push({ f, p, mtimeMs: stat.mtimeMs, entityId: m[1], bucket: m[2] });
65123
65683
  } catch {
65124
65684
  }
@@ -65155,7 +65715,7 @@ function compactInsights(opts = {}) {
65155
65715
  if (!opts.dryRun) {
65156
65716
  for (const sf of toDelete) {
65157
65717
  try {
65158
- unlinkSync5(sf.p);
65718
+ unlinkSync6(sf.p);
65159
65719
  deletedFiles.push(sf.f);
65160
65720
  } catch {
65161
65721
  }
@@ -65182,18 +65742,18 @@ function mergeDailyLearnings(opts = {}) {
65182
65742
  const retainDays = opts.retainDays ?? 7;
65183
65743
  const now = opts.now ?? /* @__PURE__ */ new Date();
65184
65744
  const dir = MARKETING_PATHS.learningsDir();
65185
- if (!existsSync94(dir)) {
65745
+ if (!existsSync95(dir)) {
65186
65746
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
65187
65747
  }
65188
65748
  const dayMs = 24 * 60 * 60 * 1e3;
65189
65749
  const cutoff = now.getTime() - retainDays * dayMs;
65190
65750
  const candidates = [];
65191
- for (const f of readdirSync24(dir)) {
65751
+ for (const f of readdirSync25(dir)) {
65192
65752
  const m = f.match(/^(\d{4}-\d{2}-\d{2})\.md$/);
65193
65753
  if (!m) continue;
65194
65754
  const date = m[1];
65195
65755
  const dateMs = (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getTime();
65196
- if (dateMs < cutoff) candidates.push({ f, p: join85(dir, f), date });
65756
+ if (dateMs < cutoff) candidates.push({ f, p: join87(dir, f), date });
65197
65757
  }
65198
65758
  if (candidates.length === 0) {
65199
65759
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
@@ -65207,10 +65767,10 @@ function mergeDailyLearnings(opts = {}) {
65207
65767
  const mergedFiles = [];
65208
65768
  let lastArchivePath = null;
65209
65769
  for (const [q, list] of byQuarter) {
65210
- const archivePath = join85(dir, `_archive-${q}.md`);
65770
+ const archivePath = join87(dir, `_archive-${q}.md`);
65211
65771
  list.sort((a, b) => a.date.localeCompare(b.date));
65212
65772
  for (const c of list) {
65213
- const existingArchive = existsSync94(archivePath) ? readFileSync71(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
65773
+ const existingArchive = existsSync95(archivePath) ? readFileSync73(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
65214
65774
  `;
65215
65775
  const dateMarker = `# Marketing learnings \u2014 ${c.date}`;
65216
65776
  const alreadyMerged = existingArchive.includes(dateMarker);
@@ -65219,12 +65779,12 @@ function mergeDailyLearnings(opts = {}) {
65219
65779
  continue;
65220
65780
  }
65221
65781
  if (!alreadyMerged) {
65222
- const body = readFileSync71(c.p, "utf8").trimEnd();
65782
+ const body = readFileSync73(c.p, "utf8").trimEnd();
65223
65783
  const next2 = existingArchive.trimEnd() + "\n\n" + body + "\n";
65224
65784
  atomicWriteFile4(archivePath, next2);
65225
65785
  }
65226
65786
  try {
65227
- unlinkSync5(c.p);
65787
+ unlinkSync6(c.p);
65228
65788
  mergedFiles.push(c.f);
65229
65789
  } catch {
65230
65790
  }
@@ -65262,14 +65822,14 @@ function quarterKey(yyyymmdd) {
65262
65822
  }
65263
65823
  function redactRunsSweep(opts = {}) {
65264
65824
  const dir = MARKETING_PATHS.runsDir();
65265
- if (!existsSync94(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
65266
- const files = readdirSync24(dir).filter((f) => f.endsWith(".json"));
65825
+ if (!existsSync95(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
65826
+ const files = readdirSync25(dir).filter((f) => f.endsWith(".json"));
65267
65827
  const rewrittenFiles = [];
65268
65828
  for (const f of files) {
65269
- const p = join85(dir, f);
65829
+ const p = join87(dir, f);
65270
65830
  let raw;
65271
65831
  try {
65272
- raw = readFileSync71(p, "utf8");
65832
+ raw = readFileSync73(p, "utf8");
65273
65833
  } catch {
65274
65834
  continue;
65275
65835
  }
@@ -65291,7 +65851,7 @@ function redactRunsSweep(opts = {}) {
65291
65851
  function runRemSleep(opts = {}) {
65292
65852
  const ranAt = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
65293
65853
  const root = marketingRootIfExists();
65294
- if (!root || !existsSync94(root)) {
65854
+ if (!root || !existsSync95(root)) {
65295
65855
  return {
65296
65856
  ranAt,
65297
65857
  marketingPresent: false,
@@ -65313,7 +65873,7 @@ function runRemSleep(opts = {}) {
65313
65873
  now: opts.now
65314
65874
  });
65315
65875
  const redaction = redactRunsSweep({ dryRun: opts.dryRun });
65316
- void mkdirSync44;
65876
+ void mkdirSync47;
65317
65877
  return { ranAt, marketingPresent: true, runs: runs2, insights, learnings, redaction };
65318
65878
  }
65319
65879
  var SNAP_RE;
@@ -65410,9 +65970,9 @@ var init_git_guard = __esm({
65410
65970
  });
65411
65971
 
65412
65972
  // src/cli/commands/marketing/hooks.ts
65413
- import { existsSync as existsSync95, readFileSync as readFileSync72, writeFileSync as writeFileSync49, chmodSync as chmodSync4, mkdirSync as mkdirSync45, statSync as statSync21 } from "fs";
65973
+ import { existsSync as existsSync96, readFileSync as readFileSync74, writeFileSync as writeFileSync52, chmodSync as chmodSync4, mkdirSync as mkdirSync48, statSync as statSync23 } from "fs";
65414
65974
  import { execFileSync as execFileSync7 } from "child_process";
65415
- import { join as join86 } from "path";
65975
+ import { join as join88 } from "path";
65416
65976
  function findGitDir(cwd = process.cwd()) {
65417
65977
  try {
65418
65978
  const out = execFileSync7("git", ["rev-parse", "--git-dir"], {
@@ -65421,7 +65981,7 @@ function findGitDir(cwd = process.cwd()) {
65421
65981
  stdio: ["ignore", "pipe", "ignore"]
65422
65982
  }).trim();
65423
65983
  if (!out) return null;
65424
- return out.startsWith("/") ? out : join86(cwd, out);
65984
+ return out.startsWith("/") ? out : join88(cwd, out);
65425
65985
  } catch {
65426
65986
  return null;
65427
65987
  }
@@ -65452,11 +66012,11 @@ function registerMarketingHooks(parent) {
65452
66012
  error("Not inside a git repository (or `git` is not on PATH).");
65453
66013
  process.exit(1);
65454
66014
  }
65455
- const hooksDir = join86(gitDir, "hooks");
65456
- mkdirSync45(hooksDir, { recursive: true });
65457
- const target = join86(hooksDir, "pre-commit");
65458
- if (existsSync95(target)) {
65459
- const existing = readFileSync72(target, "utf-8");
66015
+ const hooksDir = join88(gitDir, "hooks");
66016
+ mkdirSync48(hooksDir, { recursive: true });
66017
+ const target = join88(hooksDir, "pre-commit");
66018
+ if (existsSync96(target)) {
66019
+ const existing = readFileSync74(target, "utf-8");
65460
66020
  if (existing.includes(MANAGED_MARKER)) {
65461
66021
  info("pre-commit hook already managed by dreamcontext \u2014 refreshing.");
65462
66022
  } else if (!opts.force) {
@@ -65468,13 +66028,13 @@ function registerMarketingHooks(parent) {
65468
66028
  warn("Overwriting existing pre-commit hook (--force).");
65469
66029
  }
65470
66030
  }
65471
- writeFileSync49(target, HOOK_LAUNCHER, "utf-8");
66031
+ writeFileSync52(target, HOOK_LAUNCHER, "utf-8");
65472
66032
  try {
65473
66033
  chmodSync4(target, 493);
65474
66034
  } catch {
65475
66035
  }
65476
66036
  try {
65477
- const st = statSync21(target);
66037
+ const st = statSync23(target);
65478
66038
  const execMask = 73;
65479
66039
  if ((st.mode & execMask) === 0) {
65480
66040
  warn("Could not set exec bit on the hook file. Run `chmod +x .git/hooks/pre-commit` manually.");
@@ -65507,26 +66067,26 @@ exec dreamcontext mk hooks check-staged
65507
66067
  });
65508
66068
 
65509
66069
  // src/lib/marketing/council-personas.ts
65510
- import { existsSync as existsSync96, readFileSync as readFileSync73, readdirSync as readdirSync25 } from "fs";
66070
+ import { existsSync as existsSync97, readFileSync as readFileSync75, readdirSync as readdirSync26 } from "fs";
65511
66071
  import { fileURLToPath as fileURLToPath9 } from "url";
65512
- import { join as join87, dirname as dirname58 } from "path";
66072
+ import { join as join89, dirname as dirname60 } from "path";
65513
66073
  function findPersonasDir() {
65514
66074
  const candidates = [
65515
66075
  // dev: src/lib/marketing/council-personas.ts → ../../../skill-packs/...
65516
- join87(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
66076
+ join89(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
65517
66077
  // built: dist/index.js → ./skill-packs/...
65518
- join87(__dirname_local, PERSONA_SUBPATH),
66078
+ join89(__dirname_local, PERSONA_SUBPATH),
65519
66079
  // tsup-bundled (deeper nesting if ever): ../skill-packs/...
65520
- join87(__dirname_local, "..", PERSONA_SUBPATH),
65521
- join87(__dirname_local, "..", "..", PERSONA_SUBPATH)
66080
+ join89(__dirname_local, "..", PERSONA_SUBPATH),
66081
+ join89(__dirname_local, "..", "..", PERSONA_SUBPATH)
65522
66082
  ];
65523
66083
  for (const candidate of candidates) {
65524
- if (existsSync96(candidate)) return candidate;
66084
+ if (existsSync97(candidate)) return candidate;
65525
66085
  }
65526
66086
  return null;
65527
66087
  }
65528
66088
  function parsePersonaFile(filePath) {
65529
- const raw = readFileSync73(filePath, "utf-8");
66089
+ const raw = readFileSync75(filePath, "utf-8");
65530
66090
  const parsed = (0, import_gray_matter8.default)(raw);
65531
66091
  const data = parsed.data;
65532
66092
  const slug = typeof data.slug === "string" ? data.slug.trim() : "";
@@ -65546,9 +66106,9 @@ function parsePersonaFile(filePath) {
65546
66106
  }
65547
66107
  function loadAllPersonas(personasDir) {
65548
66108
  const dir = personasDir ?? findPersonasDir();
65549
- if (!dir || !existsSync96(dir)) return [];
65550
- const files = readdirSync25(dir).filter((n) => n.endsWith(".md")).sort();
65551
- return files.map((name) => parsePersonaFile(join87(dir, name)));
66109
+ if (!dir || !existsSync97(dir)) return [];
66110
+ const files = readdirSync26(dir).filter((n) => n.endsWith(".md")).sort();
66111
+ return files.map((name) => parsePersonaFile(join89(dir, name)));
65552
66112
  }
65553
66113
  function selectPersonas(all, requested) {
65554
66114
  if (requested.length === 0) return [...all];
@@ -65567,23 +66127,23 @@ var init_council_personas = __esm({
65567
66127
  import_gray_matter8 = __toESM(require_gray_matter(), 1);
65568
66128
  __dirname_local = (() => {
65569
66129
  try {
65570
- return dirname58(fileURLToPath9(import.meta.url));
66130
+ return dirname60(fileURLToPath9(import.meta.url));
65571
66131
  } catch {
65572
66132
  return process.cwd();
65573
66133
  }
65574
66134
  })();
65575
66135
  VALID_MODELS2 = /* @__PURE__ */ new Set(["opus", "sonnet", "haiku"]);
65576
- PERSONA_SUBPATH = join87("skill-packs", "meta-marketing", "council-personas");
66136
+ PERSONA_SUBPATH = join89("skill-packs", "meta-marketing", "council-personas");
65577
66137
  }
65578
66138
  });
65579
66139
 
65580
66140
  // src/cli/commands/marketing/council.ts
65581
66141
  import { spawnSync as spawnSync4 } from "child_process";
65582
- import { existsSync as existsSync97 } from "fs";
66142
+ import { existsSync as existsSync98 } from "fs";
65583
66143
  function resolveDreamcontextEntry() {
65584
66144
  const node = process.argv[0];
65585
66145
  const script = process.argv[1];
65586
- if (script && existsSync97(script)) {
66146
+ if (script && existsSync98(script)) {
65587
66147
  return { node, script };
65588
66148
  }
65589
66149
  return { node, script: null };
@@ -65755,8 +66315,8 @@ var init_marketing = __esm({
65755
66315
  });
65756
66316
 
65757
66317
  // src/cli/commands/memory.ts
65758
- import { existsSync as existsSync98, unlinkSync as unlinkSync6 } from "fs";
65759
- import { join as join88, dirname as dirname59 } from "path";
66318
+ import { existsSync as existsSync99, unlinkSync as unlinkSync7 } from "fs";
66319
+ import { join as join90, dirname as dirname61 } from "path";
65760
66320
  function collectVault(value, previous) {
65761
66321
  return [...previous, value];
65762
66322
  }
@@ -65768,7 +66328,7 @@ function parseTypes2(value) {
65768
66328
  return filtered.length > 0 ? filtered : void 0;
65769
66329
  }
65770
66330
  function recallFederated(contextRoot, query, topK, types, opts) {
65771
- const projectRoot = dirname59(contextRoot);
66331
+ const projectRoot = dirname61(contextRoot);
65772
66332
  const { target: currentTarget } = currentVaultTarget(projectRoot);
65773
66333
  const byName = /* @__PURE__ */ new Map();
65774
66334
  const add = (t) => {
@@ -65857,7 +66417,7 @@ function registerMemoryCommand(program2) {
65857
66417
  recallFederated(root, query, topK, types, opts);
65858
66418
  return;
65859
66419
  }
65860
- const projectRoot = dirname59(root);
66420
+ const projectRoot = dirname61(root);
65861
66421
  const { target: currentTarget } = currentVaultTarget(projectRoot);
65862
66422
  const connectedTargets = resolveConnectedVaults(currentTarget, root);
65863
66423
  if (connectedTargets.length > 1) {
@@ -65928,7 +66488,7 @@ function registerMemoryCommand(program2) {
65928
66488
  const summary = opts.summary ?? (text.length > 200 ? text.slice(0, 197) + "..." : text);
65929
66489
  const references = opts.references ? opts.references.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
65930
66490
  const authors = opts.person ? opts.person.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
65931
- const changelogPath = join88(root, "core", "CHANGELOG.json");
66491
+ const changelogPath = join90(root, "core", "CHANGELOG.json");
65932
66492
  const entry = {
65933
66493
  date: today(),
65934
66494
  type: opts.type ?? "note",
@@ -65946,8 +66506,8 @@ function registerMemoryCommand(program2) {
65946
66506
  memory.command("update").argument("<slug>", "Knowledge file slug (without .md)").option("-d, --description <desc>", "New description (replaces existing)").option("-t, --tags <tags>", "New tags (comma-separated, replaces existing)").option("-c, --content <content>", "New body content (replaces existing)").option("--append <text>", "Append text to body (preserves existing content)").option("--pin", "Set pinned: true").option("--unpin", "Set pinned: false").description("Update a knowledge file (frontmatter and/or body)").action(
65947
66507
  async (slug, opts) => {
65948
66508
  const root = ensureContextRoot();
65949
- const filePath = join88(root, "knowledge", `${slug}.md`);
65950
- if (!existsSync98(filePath)) {
66509
+ const filePath = join90(root, "knowledge", `${slug}.md`);
66510
+ if (!existsSync99(filePath)) {
65951
66511
  error(`Knowledge file not found: ${slug}.md`);
65952
66512
  return;
65953
66513
  }
@@ -65994,8 +66554,8 @@ ${opts.append}
65994
66554
  );
65995
66555
  memory.command("delete").argument("<slug>", "Knowledge file slug to delete (without .md)").option("-f, --force", "Skip confirmation prompt").description("Delete a knowledge file (irreversible; use git to recover)").action(async (slug, opts) => {
65996
66556
  const root = ensureContextRoot();
65997
- const filePath = join88(root, "knowledge", `${slug}.md`);
65998
- if (!existsSync98(filePath)) {
66557
+ const filePath = join90(root, "knowledge", `${slug}.md`);
66558
+ if (!existsSync99(filePath)) {
65999
66559
  error(`Knowledge file not found: ${slug}.md`);
66000
66560
  return;
66001
66561
  }
@@ -66009,7 +66569,7 @@ ${opts.append}
66009
66569
  return;
66010
66570
  }
66011
66571
  }
66012
- unlinkSync6(filePath);
66572
+ unlinkSync7(filePath);
66013
66573
  success(`Deleted: knowledge/${slug}.md`);
66014
66574
  });
66015
66575
  memory.command("list").description("List all docs in the memory corpus (knowledge, features, tasks, memory)").option("--types <types>", "Comma-separated subset: knowledge,feature,task,memory").option("--plain", "Plain text (no colors)").action((opts) => {
@@ -66103,13 +66663,13 @@ var init_memory = __esm({
66103
66663
 
66104
66664
  // src/cli/commands/upgrade.ts
66105
66665
  import { execFileSync as execFileSync9 } from "child_process";
66106
- import { dirname as dirname60 } from "path";
66107
- import { existsSync as existsSync99 } from "fs";
66666
+ import { dirname as dirname62 } from "path";
66667
+ import { existsSync as existsSync100 } from "fs";
66108
66668
  function defaultInstaller(args) {
66109
66669
  execFileSync9("npm", args, { stdio: "inherit" });
66110
66670
  }
66111
66671
  function defaultProjectUpdater(vault) {
66112
- if (!existsSync99(vault.path)) {
66672
+ if (!existsSync100(vault.path)) {
66113
66673
  return { vault, ok: false, error: "project folder no longer exists" };
66114
66674
  }
66115
66675
  try {
@@ -66138,7 +66698,7 @@ function defaultAppUpdater() {
66138
66698
  }
66139
66699
  function projectRootForCache() {
66140
66700
  const contextDir = resolveContextRoot();
66141
- return contextDir ? dirname60(contextDir) : process.cwd();
66701
+ return contextDir ? dirname62(contextDir) : process.cwd();
66142
66702
  }
66143
66703
  function defaultLiveLatest() {
66144
66704
  let latest = null;
@@ -66511,7 +67071,7 @@ var init_taxonomy3 = __esm({
66511
67071
  });
66512
67072
 
66513
67073
  // src/cli/commands/vaults.ts
66514
- import { basename as basename27, resolve as resolve21 } from "path";
67074
+ import { basename as basename28, resolve as resolve21 } from "path";
66515
67075
  function registerVaultsCommand(program2) {
66516
67076
  const vaults = program2.command("vaults").description("Manage the global vault registry (multi-project)");
66517
67077
  vaults.command("add").argument("<name>", "Vault name (unique identifier)").argument("<path>", "Path to the project directory (must contain _dream_context/)").description("Register a project directory as a vault").action((name, dirPath) => {
@@ -66548,7 +67108,7 @@ function registerVaultsCommand(program2) {
66548
67108
  if (!opts.register) {
66549
67109
  console.log(header(`Discovered ${found.length} project${found.length === 1 ? "" : "s"}`));
66550
67110
  for (const projectPath of found) {
66551
- console.log(` ${source_default.magentaBright(basename27(projectPath))} ${source_default.dim(projectPath)}`);
67111
+ console.log(` ${source_default.magentaBright(basename28(projectPath))} ${source_default.dim(projectPath)}`);
66552
67112
  }
66553
67113
  info(source_default.dim("Re-run with --register to add the new ones to the vault registry."));
66554
67114
  return;
@@ -66562,7 +67122,7 @@ function registerVaultsCommand(program2) {
66562
67122
  skipped++;
66563
67123
  continue;
66564
67124
  }
66565
- const base = slugify(basename27(projectPath)) || "vault";
67125
+ const base = slugify(basename28(projectPath)) || "vault";
66566
67126
  let name = base;
66567
67127
  let suffix = 2;
66568
67128
  while (takenNames.has(name)) name = `${base}-${suffix++}`;
@@ -66601,7 +67161,7 @@ var init_vaults3 = __esm({
66601
67161
  });
66602
67162
 
66603
67163
  // src/cli/commands/connections.ts
66604
- import { dirname as dirname61 } from "path";
67164
+ import { dirname as dirname63 } from "path";
66605
67165
  function refreshPeerSummariesQuietly(contextRoot) {
66606
67166
  try {
66607
67167
  refreshPeerSummaries(contextRoot);
@@ -66609,7 +67169,7 @@ function refreshPeerSummariesQuietly(contextRoot) {
66609
67169
  }
66610
67170
  }
66611
67171
  function currentVaultName2(contextRoot) {
66612
- return currentVaultTarget(dirname61(contextRoot)).name;
67172
+ return currentVaultTarget(dirname63(contextRoot)).name;
66613
67173
  }
66614
67174
  function registerConnectionsCommand(program2) {
66615
67175
  program2.command("connect <vault>").description("Connect this vault to read a peer (live reference; out is a read edge)").option("-d, --direction <direction>", "Connection direction: out | in | both (out = read)", "out").option("--topics <list>", "Comma-separated topic filter (default: all topics)").action((vault, opts) => {
@@ -66694,8 +67254,8 @@ var init_connections3 = __esm({
66694
67254
  });
66695
67255
 
66696
67256
  // src/cli/commands/federation.ts
66697
- import { realpathSync as realpathSync2, unlinkSync as unlinkSync7 } from "fs";
66698
- import { join as join89, sep as sep13 } from "path";
67257
+ import { realpathSync as realpathSync2, unlinkSync as unlinkSync8 } from "fs";
67258
+ import { join as join91, sep as sep13 } from "path";
66699
67259
  function registerFederationCommand(program2) {
66700
67260
  const federation = program2.command("federation").description("Cross-project federation: read peers live; manage leftover copies");
66701
67261
  federation.command("drain").description("(disabled) copy-based ingest is parked on the roadmap \u2014 no-op").action(() => {
@@ -66752,7 +67312,7 @@ function registerFederationCommand(program2) {
66752
67312
  continue;
66753
67313
  }
66754
67314
  try {
66755
- unlinkSync7(f.path);
67315
+ unlinkSync8(f.path);
66756
67316
  removed++;
66757
67317
  console.log(` removed: ${f.relPath}${f.originVault ? source_default.dim(` (from ${f.originVault})`) : ""}`);
66758
67318
  } catch (err) {
@@ -66793,7 +67353,7 @@ function registerFederationCommand(program2) {
66793
67353
  });
66794
67354
  }
66795
67355
  function findFederatedCopies(contextRoot, originVault) {
66796
- const knowledgeDir = join89(contextRoot, "knowledge");
67356
+ const knowledgeDir = join91(contextRoot, "knowledge");
66797
67357
  let files;
66798
67358
  try {
66799
67359
  files = import_fast_glob19.default.sync("**/*.md", { cwd: knowledgeDir, absolute: true, followSymbolicLinks: false });
@@ -66903,12 +67463,12 @@ var init_people = __esm({
66903
67463
  });
66904
67464
 
66905
67465
  // src/cli/commands/config.ts
66906
- import { dirname as dirname62 } from "path";
66907
- import { existsSync as existsSync100, readFileSync as readFileSync75, writeFileSync as writeFileSync51 } from "fs";
66908
- import { join as join90 } from "path";
67466
+ import { dirname as dirname64 } from "path";
67467
+ import { existsSync as existsSync101, readFileSync as readFileSync77, writeFileSync as writeFileSync54 } from "fs";
67468
+ import { join as join92 } from "path";
66909
67469
  function resolveProjectRoot() {
66910
67470
  const contextRoot = resolveContextRoot();
66911
- return contextRoot ? dirname62(contextRoot) : null;
67471
+ return contextRoot ? dirname64(contextRoot) : null;
66912
67472
  }
66913
67473
  function requireProjectRoot() {
66914
67474
  const projectRoot = resolveProjectRoot();
@@ -67078,7 +67638,7 @@ function registerConfigCommand(program2) {
67078
67638
  const liveToken = resolveClickUpToken(projectRoot);
67079
67639
  let connected = false;
67080
67640
  if (liveToken) {
67081
- const contextRoot = join90(projectRoot, "_dream_context");
67641
+ const contextRoot = join92(projectRoot, "_dream_context");
67082
67642
  const probe = createClickUpBackend(contextRoot, readSetupConfig(projectRoot));
67083
67643
  const test = await probe.testConnection();
67084
67644
  if (test.ok) {
@@ -67121,7 +67681,7 @@ function registerConfigCommand(program2) {
67121
67681
  cfgNow = readSetupConfig(projectRoot);
67122
67682
  }
67123
67683
  if (connected && cfgNow?.clickup?.listId) {
67124
- const contextRoot = join90(projectRoot, "_dream_context");
67684
+ const contextRoot = join92(projectRoot, "_dream_context");
67125
67685
  const backend2 = createClickUpBackend(contextRoot, cfgNow);
67126
67686
  if (await esm_default4({ message: "Create the recommended custom fields on the list (urgency, summary, RICE, \u2026)?", default: true })) {
67127
67687
  const result = await backend2.provisionRemote();
@@ -67173,7 +67733,7 @@ function registerConfigCommand(program2) {
67173
67733
  const liveToken = resolveGitHubToken(projectRoot);
67174
67734
  let connected = false;
67175
67735
  if (liveToken) {
67176
- const contextRoot = join90(projectRoot, "_dream_context");
67736
+ const contextRoot = join92(projectRoot, "_dream_context");
67177
67737
  const probe = createGitHubBackend(contextRoot, readSetupConfig(projectRoot));
67178
67738
  const test = await probe.testConnection();
67179
67739
  if (test.ok) {
@@ -67215,7 +67775,7 @@ function registerConfigCommand(program2) {
67215
67775
  cfgNow = readSetupConfig(projectRoot);
67216
67776
  }
67217
67777
  if (connected && cfgNow?.github?.owner && cfgNow?.github?.repo) {
67218
- const contextRoot = join90(projectRoot, "_dream_context");
67778
+ const contextRoot = join92(projectRoot, "_dream_context");
67219
67779
  const backend2 = createGitHubBackend(contextRoot, cfgNow);
67220
67780
  if (await esm_default4({ message: "Create the recommended `dc:*` labels on the repo (sub-status, priority, urgency, \u2026)?", default: true })) {
67221
67781
  const result = await backend2.provisionRemote();
@@ -67259,13 +67819,13 @@ function registerConfigCommand(program2) {
67259
67819
  const contextRoot = resolveContextRoot();
67260
67820
  let userMdSynced = false;
67261
67821
  if (contextRoot) {
67262
- const userMdPath = join90(contextRoot, "core", "1.user.md");
67263
- if (existsSync100(userMdPath)) {
67822
+ const userMdPath = join92(contextRoot, "core", "1.user.md");
67823
+ if (existsSync101(userMdPath)) {
67264
67824
  try {
67265
- const before = readFileSync75(userMdPath, "utf-8");
67825
+ const before = readFileSync77(userMdPath, "utf-8");
67266
67826
  const after = ensurePeopleSection(before, roster);
67267
67827
  if (after !== before) {
67268
- writeFileSync51(userMdPath, after, "utf-8");
67828
+ writeFileSync54(userMdPath, after, "utf-8");
67269
67829
  userMdSynced = true;
67270
67830
  }
67271
67831
  } catch (err) {
@@ -67309,7 +67869,7 @@ function registerConfigCommand(program2) {
67309
67869
  config.command("clickup-list <teamId> <spaceId> <listId>").description("Set the ClickUp team/space/list the tasks sync against").option("--migrate", "When changing lists: reset the sync ledger so the next sync recreates every local task in the NEW list").option("--keep", "When changing lists: keep existing task mappings (tasks were moved in ClickUp itself)").action(async (teamId, spaceId, listId, opts) => {
67310
67870
  const projectRoot = requireProjectRoot();
67311
67871
  if (!projectRoot) return;
67312
- const contextRoot = join90(projectRoot, "_dream_context");
67872
+ const contextRoot = join92(projectRoot, "_dream_context");
67313
67873
  const existing = readSetupConfig(projectRoot)?.clickup ?? {};
67314
67874
  const ledger = new SyncLedger(contextRoot);
67315
67875
  const changingList = !!existing.listId && existing.listId !== listId && ledger.readMap().length > 0;
@@ -67350,8 +67910,8 @@ function registerConfigCommand(program2) {
67350
67910
  if (!value) {
67351
67911
  if (!process.stdin.isTTY) {
67352
67912
  try {
67353
- const { readFileSync: readFileSync76 } = await import("fs");
67354
- value = readFileSync76(0, "utf-8").trim();
67913
+ const { readFileSync: readFileSync78 } = await import("fs");
67914
+ value = readFileSync78(0, "utf-8").trim();
67355
67915
  } catch {
67356
67916
  value = "";
67357
67917
  }
@@ -67401,8 +67961,8 @@ function registerConfigCommand(program2) {
67401
67961
  if (!value) {
67402
67962
  if (!process.stdin.isTTY) {
67403
67963
  try {
67404
- const { readFileSync: readFileSync76 } = await import("fs");
67405
- value = readFileSync76(0, "utf-8").trim();
67964
+ const { readFileSync: readFileSync78 } = await import("fs");
67965
+ value = readFileSync78(0, "utf-8").trim();
67406
67966
  } catch {
67407
67967
  value = "";
67408
67968
  }
@@ -67762,12 +68322,12 @@ var init_feedback2 = __esm({
67762
68322
  });
67763
68323
 
67764
68324
  // src/cli/commands/migrations.ts
67765
- import { dirname as dirname63 } from "path";
68325
+ import { dirname as dirname65 } from "path";
67766
68326
  function registerMigrationsCommand(program2) {
67767
68327
  const migrations = program2.command("migrations").description("Inspect and record brain structure migrations");
67768
68328
  migrations.command("pending").description("Print pending agent task instructions for any unfinished migrations").action(() => {
67769
68329
  const root = ensureContextRoot();
67770
- const projectRoot = dirname63(root);
68330
+ const projectRoot = dirname65(root);
67771
68331
  const config = readSetupConfig(projectRoot);
67772
68332
  const fromVersion = config?.setupVersion ?? "0.0.0";
67773
68333
  const toVersion = dreamcontextVersion();