dreamcontext 0.17.1 → 0.17.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 (124) hide show
  1. package/README.md +1 -1
  2. package/dist/dashboard/assets/{BrainCanvas3D-DyF_3yYD.js → BrainCanvas3D-BmE9c-fY.js} +1 -1
  3. package/dist/dashboard/assets/{_baseUniq-Do8VMBA0.js → _baseUniq-C4h3LMXa.js} +1 -1
  4. package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-DmbXDb2R.js → ar-SA-G6X2FPQ2-CiBeBuku.js} +1 -1
  5. package/dist/dashboard/assets/{arc-CwtUBQfU.js → arc-Dh9OLaRt.js} +1 -1
  6. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-O9bOog_f.js → architectureDiagram-Q4EWVU46-B5SN9uIW.js} +1 -1
  7. package/dist/dashboard/assets/{az-AZ-76LH7QW2-c9Zk10vG.js → az-AZ-76LH7QW2-C4n1wxZ6.js} +1 -1
  8. package/dist/dashboard/assets/{bg-BG-XCXSNQG7-uMTg84lX.js → bg-BG-XCXSNQG7-CPQuP6fM.js} +1 -1
  9. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-BTENXCSO.js → blockDiagram-DXYQGD6D-BHZe2v2l.js} +1 -1
  10. package/dist/dashboard/assets/{bn-BD-2XOGV67Q-DUFKHcua.js → bn-BD-2XOGV67Q-CkfPJKYN.js} +1 -1
  11. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-DMXPWRiQ.js → c4Diagram-AHTNJAMY-Cr8ikewQ.js} +1 -1
  12. package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-BuYX1q89.js → ca-ES-6MX7JW3Y-DSb9A-uO.js} +1 -1
  13. package/dist/dashboard/assets/channel-BATJLyDl.js +1 -0
  14. package/dist/dashboard/assets/{chunk-4BX2VUAB-DgefvnWS.js → chunk-4BX2VUAB-BKSSJPQN.js} +1 -1
  15. package/dist/dashboard/assets/{chunk-4TB4RGXK-BnFO5G1t.js → chunk-4TB4RGXK-BW3bbV8A.js} +1 -1
  16. package/dist/dashboard/assets/{chunk-55IACEB6-COm2TYEM.js → chunk-55IACEB6-TMgamyg1.js} +1 -1
  17. package/dist/dashboard/assets/{chunk-EDXVE4YY-CtsGCwZp.js → chunk-EDXVE4YY-C21wWkfJ.js} +1 -1
  18. package/dist/dashboard/assets/{chunk-FMBD7UC4-cfSvx35j.js → chunk-FMBD7UC4-Jgs85560.js} +1 -1
  19. package/dist/dashboard/assets/{chunk-OYMX7WX6-DAhDKteL.js → chunk-OYMX7WX6-DGVyPCY-.js} +1 -1
  20. package/dist/dashboard/assets/{chunk-QZHKN3VN-B5h4qML3.js → chunk-QZHKN3VN-CaB536B9.js} +1 -1
  21. package/dist/dashboard/assets/{chunk-YZCP3GAM-CGp_NiRg.js → chunk-YZCP3GAM-B5678oV6.js} +1 -1
  22. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DsrXpYhW.js +1 -0
  23. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DsrXpYhW.js +1 -0
  24. package/dist/dashboard/assets/clone-CL4CWABW.js +1 -0
  25. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-Dk7CMFA4.js → cose-bilkent-S5V4N54A-Cfo2Gh38.js} +1 -1
  26. package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-zfUTiS_d.js → cs-CZ-2BRQDIVT-DHFTb7Nf.js} +1 -1
  27. package/dist/dashboard/assets/{da-DK-5WZEPLOC-CU14f8NA.js → da-DK-5WZEPLOC-BXIvQ4fp.js} +1 -1
  28. package/dist/dashboard/assets/{dagre-KV5264BT-BiMVxC4Q.js → dagre-KV5264BT-fSOPShhM.js} +1 -1
  29. package/dist/dashboard/assets/{de-DE-XR44H4JA-CDOHAJGo.js → de-DE-XR44H4JA-TpauT9Dz.js} +1 -1
  30. package/dist/dashboard/assets/{diagram-5BDNPKRD-DfJEsVTA.js → diagram-5BDNPKRD-Drzr1k9m.js} +1 -1
  31. package/dist/dashboard/assets/{diagram-G4DWMVQ6-CztLHIcY.js → diagram-G4DWMVQ6-0EMIXQ8j.js} +1 -1
  32. package/dist/dashboard/assets/{diagram-MMDJMWI5-DqoQLlWK.js → diagram-MMDJMWI5-B4gAlQAU.js} +1 -1
  33. package/dist/dashboard/assets/{diagram-TYMM5635-DvyvQBCc.js → diagram-TYMM5635-Cb35vRAz.js} +1 -1
  34. package/dist/dashboard/assets/{el-GR-BZB4AONW-ChUphbcv.js → el-GR-BZB4AONW-C-AL3qBe.js} +1 -1
  35. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-D_uSs2_2.js → erDiagram-SMLLAGMA-DNrdnDHM.js} +1 -1
  36. package/dist/dashboard/assets/{es-ES-U4NZUMDT-BNalBEhb.js → es-ES-U4NZUMDT-BWpJorHA.js} +1 -1
  37. package/dist/dashboard/assets/{eu-ES-A7QVB2H4-BMiQyA2y.js → eu-ES-A7QVB2H4-qC7athaf.js} +1 -1
  38. package/dist/dashboard/assets/{fa-IR-HGAKTJCU-Bd6ZnTSo.js → fa-IR-HGAKTJCU-B3QcjMlj.js} +1 -1
  39. package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-BWAfJadC.js → fi-FI-Z5N7JZ37-B--tWG-3.js} +1 -1
  40. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-Bmsp6kyU.js → flowDiagram-DWJPFMVM-CzNjJYhW.js} +1 -1
  41. package/dist/dashboard/assets/{fr-FR-RHASNOE6-CspbYzOW.js → fr-FR-RHASNOE6-BAqr1UGs.js} +1 -1
  42. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-wEdysXo_.js → ganttDiagram-T4ZO3ILL-CoO72eho.js} +1 -1
  43. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-BEiGpPBj.js → gitGraphDiagram-UUTBAWPF-wOCXldeR.js} +1 -1
  44. package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-CV76vsWr.js → gl-ES-HMX3MZ6V-Ct0Kh-0r.js} +1 -1
  45. package/dist/dashboard/assets/{graph-CZFIeNHZ.js → graph-DK-0NQrf.js} +1 -1
  46. package/dist/dashboard/assets/{he-IL-6SHJWFNN-Y1VoXJ_H.js → he-IL-6SHJWFNN-_eIdOA1F.js} +1 -1
  47. package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-Crh5S49o.js → hi-IN-IWLTKZ5I-DCXAx0Ed.js} +1 -1
  48. package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-D4I3gCbp.js → hu-HU-A5ZG7DT2-g2pOOboC.js} +1 -1
  49. package/dist/dashboard/assets/{id-ID-SAP4L64H-Chvzkuvi.js → id-ID-SAP4L64H-nncKIomD.js} +1 -1
  50. package/dist/dashboard/assets/image-FgR93jdt.js +1 -0
  51. package/dist/dashboard/assets/index-2m8ueOUn.js +1 -0
  52. package/dist/dashboard/assets/{index-BdZ3tppu.css → index-BhGTUdzl.css} +1 -1
  53. package/dist/dashboard/assets/{index-C7Bo5AQH.js → index-NqQnRGLb.js} +1 -1
  54. package/dist/dashboard/assets/{index-BIfrbaFS.js → index-RYCWQyp_.js} +128 -126
  55. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-BzfuDHl4.js → infoDiagram-42DDH7IO-Ct0KiOeh.js} +1 -1
  56. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-BVoNJ9VS.js → ishikawaDiagram-UXIWVN3A-2UGJk4Te.js} +1 -1
  57. package/dist/dashboard/assets/{it-IT-JPQ66NNP-BH_gN5es.js → it-IT-JPQ66NNP-XMIC0CYZ.js} +1 -1
  58. package/dist/dashboard/assets/{ja-JP-DBVTYXUO-DU_WmLVa.js → ja-JP-DBVTYXUO-2-0l8yCd.js} +1 -1
  59. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-DbwICa_a.js → journeyDiagram-VCZTEJTY-V3bz3qVC.js} +1 -1
  60. package/dist/dashboard/assets/{kaa-6HZHGXH3-KYU9qowM.js → kaa-6HZHGXH3-mQ5TTVGp.js} +1 -1
  61. package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-bjhyiUq5.js → kab-KAB-ZGHBKWFO-CriUVt31.js} +1 -1
  62. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-D9XucLs4.js → kanban-definition-6JOO6SKY-Bn78IKO5.js} +1 -1
  63. package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-CYTx_dAZ.js → kk-KZ-P5N5QNE5-BAlV3q5m.js} +1 -1
  64. package/dist/dashboard/assets/{km-KH-HSX4SM5Z-DqsuY4Lf.js → km-KH-HSX4SM5Z-BhdYeIdp.js} +1 -1
  65. package/dist/dashboard/assets/{ko-KR-MTYHY66A-BZe7NywF.js → ko-KR-MTYHY66A-CAKtaTgT.js} +1 -1
  66. package/dist/dashboard/assets/{ku-TR-6OUDTVRD-F5d6HFWt.js → ku-TR-6OUDTVRD-aroxiDy2.js} +1 -1
  67. package/dist/dashboard/assets/{layout-CotqU0S9.js → layout-H9V_G3od.js} +1 -1
  68. package/dist/dashboard/assets/{linear-Dqv87Scf.js → linear-DvltrDet.js} +1 -1
  69. package/dist/dashboard/assets/{lt-LT-XHIRWOB4-BCCuaPbS.js → lt-LT-XHIRWOB4-DDSfhBL-.js} +1 -1
  70. package/dist/dashboard/assets/{lv-LV-5QDEKY6T-NLGi-vJ6.js → lv-LV-5QDEKY6T-DHwj30kv.js} +1 -1
  71. package/dist/dashboard/assets/{min-BbJdnc3h.js → min-D2j4bY60.js} +1 -1
  72. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-Dk4QySu7.js → mindmap-definition-QFDTVHPH-q-d1aQDU.js} +1 -1
  73. package/dist/dashboard/assets/{mr-IN-CRQNXWMA-BnGDIgVN.js → mr-IN-CRQNXWMA-DwiNWn2z.js} +1 -1
  74. package/dist/dashboard/assets/{my-MM-5M5IBNSE-CspgYE9_.js → my-MM-5M5IBNSE-d0ft8kqP.js} +1 -1
  75. package/dist/dashboard/assets/{nb-NO-T6EIAALU-BeRPw3hu.js → nb-NO-T6EIAALU-DkYMAbp0.js} +1 -1
  76. package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-C-G-bljM.js → nl-NL-IS3SIHDZ-DdQOLvgs.js} +1 -1
  77. package/dist/dashboard/assets/{nn-NO-6E72VCQL-Ct7VZY8D.js → nn-NO-6E72VCQL-CjV1UWFM.js} +1 -1
  78. package/dist/dashboard/assets/{oc-FR-POXYY2M6-Cv5-C4Qq.js → oc-FR-POXYY2M6-CVZoTE_i.js} +1 -1
  79. package/dist/dashboard/assets/{pa-IN-N4M65BXN-DAgkIThL.js → pa-IN-N4M65BXN-BupygyyC.js} +1 -1
  80. package/dist/dashboard/assets/{percentages-BXMCSKIN-vidRYabK.js → percentages-BXMCSKIN-Bu0vZZw_.js} +7 -7
  81. package/dist/dashboard/assets/{pica-Cy-Xl-mi.js → pica-mkWTjDU4.js} +1 -1
  82. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-BnP4-zwd.js → pieDiagram-DEJITSTG-CQF5LXYE.js} +1 -1
  83. package/dist/dashboard/assets/{pl-PL-T2D74RX3-BuJQ3HD-.js → pl-PL-T2D74RX3-BBXs3cmL.js} +1 -1
  84. package/dist/dashboard/assets/{pt-BR-5N22H2LF-BbAqsvD6.js → pt-BR-5N22H2LF-B93mlBha.js} +1 -1
  85. package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-DzFJedU3.js → pt-PT-UZXXM6DQ-xVjOmMs-.js} +1 -1
  86. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-BXN88cHy.js → quadrantDiagram-34T5L4WZ-DqivnL0s.js} +1 -1
  87. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-D34hL42a.js → requirementDiagram-MS252O5E-BIViT9zj.js} +1 -1
  88. package/dist/dashboard/assets/{ro-RO-JPDTUUEW-BV2-sOiv.js → ro-RO-JPDTUUEW-ClxrWe_s.js} +1 -1
  89. package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-BCL4N9Ej.js → ru-RU-B4JR7IUQ-LSY-t1rx.js} +1 -1
  90. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-0mFeok-3.js → sankeyDiagram-XADWPNL6-BhNfg4hX.js} +1 -1
  91. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-C-5nW5j6.js → sequenceDiagram-FGHM5R23-CYR3zuKy.js} +1 -1
  92. package/dist/dashboard/assets/{si-LK-N5RQ5JYF-CNhaw4jx.js → si-LK-N5RQ5JYF-BWqC_fm0.js} +1 -1
  93. package/dist/dashboard/assets/{sk-SK-C5VTKIMK-mHCphOXu.js → sk-SK-C5VTKIMK-DNzaj-nB.js} +1 -1
  94. package/dist/dashboard/assets/{sl-SI-NN7IZMDC--lzgHthQ.js → sl-SI-NN7IZMDC-Dr0L8iue.js} +1 -1
  95. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-C50iDFqe.js → stateDiagram-FHFEXIEX-ColiPt5A.js} +1 -1
  96. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-DF6l17l1.js +1 -0
  97. package/dist/dashboard/assets/{subset-shared.chunk-DNsjL37s.js → subset-shared.chunk-Djsk2OUB.js} +1 -1
  98. package/dist/dashboard/assets/{subset-worker.chunk-BaV3r-bl.js → subset-worker.chunk-DmFi9L0s.js} +1 -1
  99. package/dist/dashboard/assets/{sv-SE-XGPEYMSR-ckw8jfGN.js → sv-SE-XGPEYMSR-DYYaiKrL.js} +1 -1
  100. package/dist/dashboard/assets/{ta-IN-2NMHFXQM-CSeNmVhS.js → ta-IN-2NMHFXQM-Xswgugie.js} +1 -1
  101. package/dist/dashboard/assets/{th-TH-HPSO5L25-Cvn1sg_3.js → th-TH-HPSO5L25-B_zlnHli.js} +1 -1
  102. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-DRYfuqHT.js → timeline-definition-GMOUNBTQ-CEAWgKK1.js} +1 -1
  103. package/dist/dashboard/assets/{tr-TR-DEFEU3FU-CyhY22TB.js → tr-TR-DEFEU3FU-D6tTkvDX.js} +1 -1
  104. package/dist/dashboard/assets/{uk-UA-QMV73CPH-BvvAEO6U.js → uk-UA-QMV73CPH-Bra75jyv.js} +1 -1
  105. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-Crril7Cj.js → vennDiagram-DHZGUBPP-Am2c5V36.js} +1 -1
  106. package/dist/dashboard/assets/{vi-VN-M7AON7JQ-c7AwSUZ8.js → vi-VN-M7AON7JQ-CRhUTOPb.js} +1 -1
  107. package/dist/dashboard/assets/{wardley-RL74JXVD-Da5AhSWU.js → wardley-RL74JXVD-BlsSvNdP.js} +1 -1
  108. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-C4GeB_Df.js → wardleyDiagram-NUSXRM2D-BONuwasj.js} +1 -1
  109. package/dist/dashboard/assets/webviewWindow-Bwv2421L.js +1 -0
  110. package/dist/dashboard/assets/window-BObcHN8e.js +1 -0
  111. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-BPCFKXqR.js → xychartDiagram-5P7HB3ND-BCWtz6EH.js} +1 -1
  112. package/dist/dashboard/assets/{zh-CN-LNUGB5OW-BvNiZwKU.js → zh-CN-LNUGB5OW-BgEkcxVF.js} +1 -1
  113. package/dist/dashboard/assets/{zh-HK-E62DVLB3-CCFtoCWb.js → zh-HK-E62DVLB3-iXpoob62.js} +1 -1
  114. package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-bYBr-stu.js → zh-TW-RAJ6MFWO-BY7Ya34m.js} +1 -1
  115. package/dist/dashboard/index.html +2 -2
  116. package/dist/index.js +1119 -572
  117. package/package.json +1 -1
  118. package/dist/dashboard/assets/channel-2YfRjala.js +0 -1
  119. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DB_UnN1h.js +0 -1
  120. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DB_UnN1h.js +0 -1
  121. package/dist/dashboard/assets/clone-DaDvB3N6.js +0 -1
  122. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-eW9-s0Sm.js +0 -1
  123. package/dist/dashboard/assets/webviewWindow-BbG9Cr7f.js +0 -1
  124. package/dist/dashboard/assets/window-DmNpeJAL.js +0 -1
package/dist/index.js CHANGED
@@ -6618,13 +6618,13 @@ var init_promise_polyfill = __esm({
6618
6618
  // Available starting from Node 22
6619
6619
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
6620
6620
  static withResolver() {
6621
- let resolve26;
6621
+ let resolve27;
6622
6622
  let reject;
6623
6623
  const promise = new Promise((res, rej) => {
6624
- resolve26 = res;
6624
+ resolve27 = res;
6625
6625
  reject = rej;
6626
6626
  });
6627
- return { promise, resolve: resolve26, reject };
6627
+ return { promise, resolve: resolve27, reject };
6628
6628
  }
6629
6629
  };
6630
6630
  }
@@ -6662,7 +6662,7 @@ function createPrompt(view) {
6662
6662
  output
6663
6663
  });
6664
6664
  const screen = new ScreenManager(rl);
6665
- const { promise, resolve: resolve26, reject } = PromisePolyfill.withResolver();
6665
+ const { promise, resolve: resolve27, reject } = PromisePolyfill.withResolver();
6666
6666
  const cancel = () => reject(new CancelPromptError());
6667
6667
  if (signal) {
6668
6668
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -6689,7 +6689,7 @@ function createPrompt(view) {
6689
6689
  cycle(() => {
6690
6690
  try {
6691
6691
  const nextView = view(config, (value) => {
6692
- setImmediate(() => resolve26(value));
6692
+ setImmediate(() => resolve27(value));
6693
6693
  });
6694
6694
  if (nextView === void 0) {
6695
6695
  const callerFilename = callSites[1]?.getFileName();
@@ -12546,7 +12546,7 @@ var require_lib2 = __commonJS({
12546
12546
  return matches;
12547
12547
  };
12548
12548
  exports2.analyse = analyse;
12549
- var detectFile = (filepath, opts = {}) => new Promise((resolve26, reject) => {
12549
+ var detectFile = (filepath, opts = {}) => new Promise((resolve27, reject) => {
12550
12550
  let fd;
12551
12551
  const fs = (0, node_1.default)();
12552
12552
  const handler = (err, buffer) => {
@@ -12556,7 +12556,7 @@ var require_lib2 = __commonJS({
12556
12556
  if (err) {
12557
12557
  reject(err);
12558
12558
  } else if (buffer) {
12559
- resolve26((0, exports2.detect)(buffer));
12559
+ resolve27((0, exports2.detect)(buffer));
12560
12560
  } else {
12561
12561
  reject(new Error("No error and no buffer received"));
12562
12562
  }
@@ -22629,7 +22629,7 @@ var require_pattern = __commonJS({
22629
22629
  const absolute = [];
22630
22630
  const relative6 = [];
22631
22631
  for (const pattern of patterns) {
22632
- if (isAbsolute5(pattern)) {
22632
+ if (isAbsolute6(pattern)) {
22633
22633
  absolute.push(pattern);
22634
22634
  } else {
22635
22635
  relative6.push(pattern);
@@ -22638,10 +22638,10 @@ var require_pattern = __commonJS({
22638
22638
  return [absolute, relative6];
22639
22639
  }
22640
22640
  exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
22641
- function isAbsolute5(pattern) {
22641
+ function isAbsolute6(pattern) {
22642
22642
  return path2.isAbsolute(pattern);
22643
22643
  }
22644
- exports2.isAbsolute = isAbsolute5;
22644
+ exports2.isAbsolute = isAbsolute6;
22645
22645
  }
22646
22646
  });
22647
22647
 
@@ -23056,11 +23056,11 @@ var require_out = __commonJS({
23056
23056
  async.read(path2, getSettings(optionsOrSettingsOrCallback), callback);
23057
23057
  }
23058
23058
  exports2.stat = stat;
23059
- function statSync30(path2, optionsOrSettings) {
23059
+ function statSync31(path2, optionsOrSettings) {
23060
23060
  const settings = getSettings(optionsOrSettings);
23061
23061
  return sync.read(path2, settings);
23062
23062
  }
23063
- exports2.statSync = statSync30;
23063
+ exports2.statSync = statSync31;
23064
23064
  function getSettings(settingsOrOptions = {}) {
23065
23065
  if (settingsOrOptions instanceof settings_1.default) {
23066
23066
  return settingsOrOptions;
@@ -23727,41 +23727,41 @@ var require_queue = __commonJS({
23727
23727
  queue.drained = drained;
23728
23728
  return queue;
23729
23729
  function push2(value) {
23730
- var p = new Promise(function(resolve26, reject) {
23730
+ var p = new Promise(function(resolve27, reject) {
23731
23731
  pushCb(value, function(err, result) {
23732
23732
  if (err) {
23733
23733
  reject(err);
23734
23734
  return;
23735
23735
  }
23736
- resolve26(result);
23736
+ resolve27(result);
23737
23737
  });
23738
23738
  });
23739
23739
  p.catch(noop);
23740
23740
  return p;
23741
23741
  }
23742
23742
  function unshift(value) {
23743
- var p = new Promise(function(resolve26, reject) {
23743
+ var p = new Promise(function(resolve27, reject) {
23744
23744
  unshiftCb(value, function(err, result) {
23745
23745
  if (err) {
23746
23746
  reject(err);
23747
23747
  return;
23748
23748
  }
23749
- resolve26(result);
23749
+ resolve27(result);
23750
23750
  });
23751
23751
  });
23752
23752
  p.catch(noop);
23753
23753
  return p;
23754
23754
  }
23755
23755
  function drained() {
23756
- var p = new Promise(function(resolve26) {
23756
+ var p = new Promise(function(resolve27) {
23757
23757
  process.nextTick(function() {
23758
23758
  if (queue.idle()) {
23759
- resolve26();
23759
+ resolve27();
23760
23760
  } else {
23761
23761
  var previousDrain = queue.drain;
23762
23762
  queue.drain = function() {
23763
23763
  if (typeof previousDrain === "function") previousDrain();
23764
- resolve26();
23764
+ resolve27();
23765
23765
  queue.drain = previousDrain;
23766
23766
  };
23767
23767
  }
@@ -24247,9 +24247,9 @@ var require_stream3 = __commonJS({
24247
24247
  });
24248
24248
  }
24249
24249
  _getStat(filepath) {
24250
- return new Promise((resolve26, reject) => {
24250
+ return new Promise((resolve27, reject) => {
24251
24251
  this._stat(filepath, this._fsStatSettings, (error2, stats) => {
24252
- return error2 === null ? resolve26(stats) : reject(error2);
24252
+ return error2 === null ? resolve27(stats) : reject(error2);
24253
24253
  });
24254
24254
  });
24255
24255
  }
@@ -24273,10 +24273,10 @@ var require_async5 = __commonJS({
24273
24273
  this._readerStream = new stream_1.default(this._settings);
24274
24274
  }
24275
24275
  dynamic(root, options2) {
24276
- return new Promise((resolve26, reject) => {
24276
+ return new Promise((resolve27, reject) => {
24277
24277
  this._walkAsync(root, options2, (error2, entries) => {
24278
24278
  if (error2 === null) {
24279
- resolve26(entries);
24279
+ resolve27(entries);
24280
24280
  } else {
24281
24281
  reject(error2);
24282
24282
  }
@@ -24286,10 +24286,10 @@ var require_async5 = __commonJS({
24286
24286
  async static(patterns, options2) {
24287
24287
  const entries = [];
24288
24288
  const stream = this._readerStream.static(patterns, options2);
24289
- return new Promise((resolve26, reject) => {
24289
+ return new Promise((resolve27, reject) => {
24290
24290
  stream.once("error", reject);
24291
24291
  stream.on("data", (entry) => entries.push(entry));
24292
- stream.once("end", () => resolve26(entries));
24292
+ stream.once("end", () => resolve27(entries));
24293
24293
  });
24294
24294
  }
24295
24295
  };
@@ -28249,11 +28249,11 @@ var require_excerpt = __commonJS({
28249
28249
  if (typeof opts.excerpt === "function") {
28250
28250
  return opts.excerpt(file, opts);
28251
28251
  }
28252
- const sep18 = file.data.excerpt_separator || opts.excerpt_separator;
28253
- if (sep18 == null && (opts.excerpt === false || opts.excerpt == null)) {
28252
+ const sep19 = file.data.excerpt_separator || opts.excerpt_separator;
28253
+ if (sep19 == null && (opts.excerpt === false || opts.excerpt == null)) {
28254
28254
  return file;
28255
28255
  }
28256
- const delimiter2 = typeof opts.excerpt === "string" ? opts.excerpt : sep18 || opts.delimiters[0];
28256
+ const delimiter2 = typeof opts.excerpt === "string" ? opts.excerpt : sep19 || opts.delimiters[0];
28257
28257
  const idx = file.content.indexOf(delimiter2);
28258
28258
  if (idx !== -1) {
28259
28259
  file.excerpt = file.content.slice(0, idx);
@@ -29698,8 +29698,8 @@ async function installInstructions(projectRoot, platform2, requestedMode) {
29698
29698
  writeFileSync13(target, block, "utf-8");
29699
29699
  return { action: "replaced", target, platform: platform2, backup };
29700
29700
  }
29701
- const sep18 = existing.endsWith("\n") ? "\n" : "\n\n";
29702
- writeFileSync13(target, existing + sep18 + block, "utf-8");
29701
+ const sep19 = existing.endsWith("\n") ? "\n" : "\n\n";
29702
+ writeFileSync13(target, existing + sep19 + block, "utf-8");
29703
29703
  return { action: "appended", target, platform: platform2 };
29704
29704
  }
29705
29705
  async function installClaudeMd(projectRoot, requestedMode) {
@@ -32633,8 +32633,8 @@ ${input2.why || "(To be defined)"}
32633
32633
 
32634
32634
  // src/lib/task-backend/api-adapter.ts
32635
32635
  function defaultSleep(ms) {
32636
- return new Promise((resolve26) => {
32637
- const t = setTimeout(resolve26, ms);
32636
+ return new Promise((resolve27) => {
32637
+ const t = setTimeout(resolve27, ms);
32638
32638
  t.unref?.();
32639
32639
  });
32640
32640
  }
@@ -33174,7 +33174,7 @@ var init_gitignore = __esm({
33174
33174
  });
33175
33175
 
33176
33176
  // src/lib/task-backend/secrets.ts
33177
- import { chmodSync, existsSync as existsSync26, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync20 } from "fs";
33177
+ import { chmodSync, existsSync as existsSync26, mkdirSync as mkdirSync14, readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync20 } from "fs";
33178
33178
  import { dirname as dirname13, join as join26 } from "path";
33179
33179
  function secretsPath(projectRoot) {
33180
33180
  return join26(projectRoot, SECRETS_REL_PATH);
@@ -33246,6 +33246,26 @@ function writeGitHubToken(projectRoot, token, user) {
33246
33246
  } catch {
33247
33247
  }
33248
33248
  }
33249
+ function removeProjectGitHubToken(projectRoot) {
33250
+ const path2 = secretsPath(projectRoot);
33251
+ if (!existsSync26(path2)) return;
33252
+ const secrets = readSecretsFile(projectRoot);
33253
+ if (!secrets.github || secrets.github.token === void 0) return;
33254
+ delete secrets.github.token;
33255
+ if (Object.keys(secrets.github).length === 0) delete secrets.github;
33256
+ if (Object.keys(secrets).length === 0) {
33257
+ try {
33258
+ unlinkSync3(path2);
33259
+ } catch {
33260
+ }
33261
+ return;
33262
+ }
33263
+ writeFileSync20(path2, JSON.stringify(secrets, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33264
+ try {
33265
+ chmodSync(path2, 384);
33266
+ } catch {
33267
+ }
33268
+ }
33249
33269
  function resolveClickUpToken(projectRoot, opts) {
33250
33270
  if (opts?.envVar) {
33251
33271
  const v2 = process.env[opts.envVar];
@@ -37583,7 +37603,7 @@ var init__3 = __esm({
37583
37603
  });
37584
37604
 
37585
37605
  // src/lib/features-migration.ts
37586
- import { existsSync as existsSync40, mkdirSync as mkdirSync23, readdirSync as readdirSync10, renameSync as renameSync8, rmdirSync, unlinkSync as unlinkSync3 } from "fs";
37606
+ import { existsSync as existsSync40, mkdirSync as mkdirSync23, readdirSync as readdirSync10, renameSync as renameSync8, rmdirSync, unlinkSync as unlinkSync4 } from "fs";
37587
37607
  import { join as join40, basename as basename12 } from "path";
37588
37608
  function enrichFeatureFrontmatter(data, slug) {
37589
37609
  return {
@@ -37626,7 +37646,7 @@ function migrateFeaturesToKnowledge(contextRoot) {
37626
37646
  }
37627
37647
  for (const tmp of import_fast_glob9.default.sync("*.tmp", { cwd: newDir, absolute: true })) {
37628
37648
  try {
37629
- unlinkSync3(tmp);
37649
+ unlinkSync4(tmp);
37630
37650
  } catch {
37631
37651
  }
37632
37652
  }
@@ -37696,7 +37716,7 @@ function migrateFeaturesToKnowledge(contextRoot) {
37696
37716
  }
37697
37717
  for (const { slug, sourcePath, kind } of staged) {
37698
37718
  try {
37699
- unlinkSync3(sourcePath);
37719
+ unlinkSync4(sourcePath);
37700
37720
  } catch (err) {
37701
37721
  if (err.code !== "ENOENT") {
37702
37722
  result.failed.push({ slug, error: `source unlink failed: ${errText(err)}` });
@@ -37992,6 +38012,7 @@ __export(git_exports, {
37992
38012
  addRemote: () => addRemote,
37993
38013
  attemptMerge: () => attemptMerge,
37994
38014
  clone: () => clone,
38015
+ cloneStreaming: () => cloneStreaming,
37995
38016
  commit: () => commit,
37996
38017
  currentBranch: () => currentBranch,
37997
38018
  currentSha: () => currentSha,
@@ -38016,7 +38037,7 @@ __export(git_exports, {
38016
38037
  stagePath: () => stagePath,
38017
38038
  statusPorcelainTracked: () => statusPorcelainTracked
38018
38039
  });
38019
- import { execFileSync as execFileSync4 } from "child_process";
38040
+ import { execFileSync as execFileSync4, spawn as spawn3 } from "child_process";
38020
38041
  import { existsSync as existsSync43 } from "fs";
38021
38042
  import { join as join43 } from "path";
38022
38043
  function run2(cwd, args, opts) {
@@ -38118,6 +38139,67 @@ function push(cwd, remote, branch, env2) {
38118
38139
  function clone(url, dest, env2) {
38119
38140
  run2(process.cwd(), [...CREDENTIAL_HELPER_DISABLE_ARGS, ...SAFE_TRANSPORT_ARGS, "clone", "--", url, dest], { env: env2 });
38120
38141
  }
38142
+ function cloneStreaming(url, dest, env2, onProgress) {
38143
+ const child = spawn3(
38144
+ "git",
38145
+ [...CREDENTIAL_HELPER_DISABLE_ARGS, ...SAFE_TRANSPORT_ARGS, "clone", "--progress", "--", url, dest],
38146
+ { env: env2, stdio: ["ignore", "pipe", "pipe"] }
38147
+ );
38148
+ let canceled = false;
38149
+ let timedOut = false;
38150
+ let stderrTail = "";
38151
+ let hardKill;
38152
+ const onChunk = (chunk) => {
38153
+ const text = chunk.toString("utf-8");
38154
+ stderrTail = (stderrTail + text).slice(-4e3);
38155
+ onProgress?.(text);
38156
+ };
38157
+ child.stdout?.on("data", onChunk);
38158
+ child.stderr?.on("data", onChunk);
38159
+ const terminate = () => {
38160
+ try {
38161
+ child.kill("SIGTERM");
38162
+ } catch {
38163
+ }
38164
+ if (hardKill) return;
38165
+ hardKill = setTimeout(() => {
38166
+ try {
38167
+ child.kill("SIGKILL");
38168
+ } catch {
38169
+ }
38170
+ }, CLONE_HARD_KILL_GRACE_MS);
38171
+ hardKill.unref?.();
38172
+ };
38173
+ const promise = new Promise((resolvePromise, reject) => {
38174
+ const guard = setTimeout(() => {
38175
+ timedOut = true;
38176
+ terminate();
38177
+ }, CLONE_TIMEOUT_MS);
38178
+ guard.unref?.();
38179
+ child.on("error", (err) => {
38180
+ clearTimeout(guard);
38181
+ if (hardKill) clearTimeout(hardKill);
38182
+ reject(new GitSyncError(`git clone failed to start: ${err.message}`));
38183
+ });
38184
+ child.on("close", (code) => {
38185
+ clearTimeout(guard);
38186
+ if (hardKill) clearTimeout(hardKill);
38187
+ if (code === 0 && !canceled && !timedOut) {
38188
+ resolvePromise();
38189
+ return;
38190
+ }
38191
+ const detail = timedOut ? `Clone timed out after ${Math.round(CLONE_TIMEOUT_MS / 6e4)} minutes.` : canceled ? "Clone was canceled." : stderrTail.trim() || `git clone exited with code ${code}`;
38192
+ reject(new GitSyncError(`git clone failed: ${detail}`, stderrTail || void 0));
38193
+ });
38194
+ });
38195
+ return {
38196
+ promise,
38197
+ cancel: () => {
38198
+ canceled = true;
38199
+ terminate();
38200
+ }
38201
+ };
38202
+ }
38121
38203
  function mergeBase(cwd, a, b) {
38122
38204
  try {
38123
38205
  return run2(cwd, ["merge-base", a, b]).trim();
@@ -38223,7 +38305,7 @@ function abortMerge(cwd) {
38223
38305
  } catch {
38224
38306
  }
38225
38307
  }
38226
- var GitSyncError, CREDENTIAL_HELPER_DISABLE_ARGS, SAFE_TRANSPORT_ARGS;
38308
+ var GitSyncError, CREDENTIAL_HELPER_DISABLE_ARGS, SAFE_TRANSPORT_ARGS, CLONE_TIMEOUT_MS, CLONE_HARD_KILL_GRACE_MS;
38227
38309
  var init_git = __esm({
38228
38310
  "src/lib/git-sync/git.ts"() {
38229
38311
  "use strict";
@@ -38236,6 +38318,8 @@ var init_git = __esm({
38236
38318
  };
38237
38319
  CREDENTIAL_HELPER_DISABLE_ARGS = ["-c", "credential.helper="];
38238
38320
  SAFE_TRANSPORT_ARGS = ["-c", "protocol.ext.allow=never"];
38321
+ CLONE_TIMEOUT_MS = 10 * 60 * 1e3;
38322
+ CLONE_HARD_KILL_GRACE_MS = 1e4;
38239
38323
  }
38240
38324
  });
38241
38325
 
@@ -38628,7 +38712,7 @@ var init_semantic_merge = __esm({
38628
38712
  });
38629
38713
 
38630
38714
  // src/lib/git-sync/conflict-report.ts
38631
- import { existsSync as existsSync44, mkdirSync as mkdirSync26, readFileSync as readFileSync33, unlinkSync as unlinkSync4, writeFileSync as writeFileSync31 } from "fs";
38715
+ import { existsSync as existsSync44, mkdirSync as mkdirSync26, readFileSync as readFileSync33, unlinkSync as unlinkSync5, writeFileSync as writeFileSync31 } from "fs";
38632
38716
  import { join as join45 } from "path";
38633
38717
  function mergeDir(contextRoot) {
38634
38718
  return join45(contextRoot, MERGE_DIR);
@@ -38678,14 +38762,14 @@ function clearConflictReport(contextRoot) {
38678
38762
  for (const d of report.deferred) {
38679
38763
  for (const rel of [d.basePath, d.oursPath, d.theirsPath]) {
38680
38764
  try {
38681
- unlinkSync4(join45(contextRoot, rel));
38765
+ unlinkSync5(join45(contextRoot, rel));
38682
38766
  } catch {
38683
38767
  }
38684
38768
  }
38685
38769
  }
38686
38770
  }
38687
38771
  try {
38688
- unlinkSync4(reportPath(contextRoot));
38772
+ unlinkSync5(reportPath(contextRoot));
38689
38773
  } catch {
38690
38774
  }
38691
38775
  }
@@ -38941,7 +39025,7 @@ var init_brain_repo = __esm({
38941
39025
  });
38942
39026
 
38943
39027
  // src/lib/git-sync/credentials.ts
38944
- import { accessSync, chmodSync as chmodSync4, constants, existsSync as existsSync47, unlinkSync as unlinkSync5, writeFileSync as writeFileSync34 } from "fs";
39028
+ import { accessSync, chmodSync as chmodSync4, constants, existsSync as existsSync47, unlinkSync as unlinkSync6, writeFileSync as writeFileSync34 } from "fs";
38945
39029
  import { delimiter, dirname as dirname24, join as join48 } from "path";
38946
39030
  import { tmpdir as tmpdir2 } from "os";
38947
39031
  import { randomUUID as randomUUID2 } from "crypto";
@@ -38998,7 +39082,7 @@ async function withGitCredentials(token, fn) {
38998
39082
  return await fn(env2);
38999
39083
  } finally {
39000
39084
  try {
39001
- unlinkSync5(tmpPath);
39085
+ unlinkSync6(tmpPath);
39002
39086
  } catch {
39003
39087
  }
39004
39088
  }
@@ -39011,6 +39095,175 @@ var init_credentials = __esm({
39011
39095
  }
39012
39096
  });
39013
39097
 
39098
+ // src/lib/git-sync/failure.ts
39099
+ function githubSlug(s) {
39100
+ const m = s.match(/github\.com[/:]([^/\s]+\/[^/\s'".]+)/i);
39101
+ return m ? m[1].replace(/\.git$/, "") : void 0;
39102
+ }
39103
+ function extractRepo(message, fallbackRepo) {
39104
+ const perm = message.match(/Permission to ([^\s]+?)(?:\.git)? denied/i);
39105
+ if (perm) return perm[1];
39106
+ const fromMsg = githubSlug(message);
39107
+ if (fromMsg) return fromMsg;
39108
+ if (fallbackRepo) return githubSlug(fallbackRepo) ?? fallbackRepo;
39109
+ return void 0;
39110
+ }
39111
+ function classifySyncError(rawMessage, repoHint, opts) {
39112
+ const failure = classifyBase(rawMessage, repoHint);
39113
+ if (opts?.perProjectToken && (failure.kind === "auth" || failure.kind === "permission")) {
39114
+ return {
39115
+ ...failure,
39116
+ message: `${failure.message} Note: this project has its own GitHub token that overrides your signed-in account \u2014 it appears stale. Remove the project token (or re-sign-in) so sync uses your account.`
39117
+ };
39118
+ }
39119
+ return failure;
39120
+ }
39121
+ function classifyBase(rawMessage, repoHint) {
39122
+ const m = rawMessage || "";
39123
+ const repo = extractRepo(m, repoHint);
39124
+ const named = repo ? ` on ${repo}` : "";
39125
+ if (/non-fast-forward.*twice|rejected.*non-fast-forward|Push rejected \(non-fast-forward\) twice/i.test(m)) {
39126
+ return {
39127
+ kind: "push-rejected",
39128
+ recovery: "retry",
39129
+ repo,
39130
+ message: "The team pushed while your sync was in flight. Retry \u2014 dreamcontext will merge their changes and push again."
39131
+ };
39132
+ }
39133
+ if (/Contents\b.*write|permission to .* denied|protected branch|not authorized|remote: Permission|must have push access|403\b/i.test(m)) {
39134
+ return {
39135
+ kind: "permission",
39136
+ recovery: "check-permissions",
39137
+ repo,
39138
+ message: `Your GitHub token can't write to${named || " this repo"}. Give it Contents (read & write) access${repo ? ` on ${repo}` : ""}, then retry.`
39139
+ };
39140
+ }
39141
+ if (/no github token found|no token found for the brain/i.test(m)) {
39142
+ return {
39143
+ kind: "no-token",
39144
+ recovery: "reconnect-github",
39145
+ repo,
39146
+ message: "Cloud sync needs a GitHub account. Connect GitHub to start syncing."
39147
+ };
39148
+ }
39149
+ if (/authentication failed|could not read Username|bad credentials|invalid credentials|401\b|terminal prompts disabled|Support for password authentication/i.test(m)) {
39150
+ return {
39151
+ kind: "auth",
39152
+ recovery: "reconnect-github",
39153
+ repo,
39154
+ message: "Your GitHub sign-in expired or is invalid. Reconnect GitHub to keep syncing."
39155
+ };
39156
+ }
39157
+ if (/could ?n[o']t resolve host|could not resolve host|connection timed out|failed to connect|network is unreachable|temporary failure in name resolution|unable to access .*(?:Could not resolve|timed out|Failed to connect)|getaddrinfo|ENOTFOUND|ETIMEDOUT/i.test(m)) {
39158
+ return {
39159
+ kind: "network",
39160
+ recovery: "wait-online",
39161
+ repo,
39162
+ message: "You're offline \u2014 sync will retry automatically when you're back online. Nothing was lost."
39163
+ };
39164
+ }
39165
+ if (/unrelated histories/i.test(m)) {
39166
+ return {
39167
+ kind: "unknown",
39168
+ recovery: "manual",
39169
+ repo,
39170
+ message: "The remote contains content that did not come from this brain (e.g. a README). Attach an empty repo or reconcile the histories manually."
39171
+ };
39172
+ }
39173
+ return {
39174
+ kind: "unknown",
39175
+ recovery: "retry",
39176
+ repo,
39177
+ message: rawMessage.trim() || "Sync failed. Retry, or check your connection and GitHub access."
39178
+ };
39179
+ }
39180
+ var init_failure = __esm({
39181
+ "src/lib/git-sync/failure.ts"() {
39182
+ "use strict";
39183
+ }
39184
+ });
39185
+
39186
+ // src/lib/git-sync/token-fallback.ts
39187
+ function isPerProjectToken(t) {
39188
+ return !!t && t.source === "secrets" && t.via !== "global";
39189
+ }
39190
+ var defaultTokenFallbackDeps, BrainSyncTokenSession;
39191
+ var init_token_fallback = __esm({
39192
+ "src/lib/git-sync/token-fallback.ts"() {
39193
+ "use strict";
39194
+ init_secrets();
39195
+ init_auth_store();
39196
+ init_credentials();
39197
+ init_failure();
39198
+ defaultTokenFallbackDeps = {
39199
+ withGitCredentials,
39200
+ readGlobalGitHubToken,
39201
+ removeProjectGitHubToken
39202
+ };
39203
+ BrainSyncTokenSession = class {
39204
+ constructor(initial, projectRoot, deps = defaultTokenFallbackDeps) {
39205
+ this.projectRoot = projectRoot;
39206
+ this.deps = deps;
39207
+ this.active = initial;
39208
+ }
39209
+ /** The token every op currently runs with — swaps to global after a successful heal. */
39210
+ active;
39211
+ /** The single fallback attempt is consumed on first use, success OR failure — never loop. */
39212
+ fallbackConsumed = false;
39213
+ healed = false;
39214
+ /** True once the stale per-project token was replaced by the global one AND removed from disk. */
39215
+ get healedStaleProjectToken() {
39216
+ return this.healed;
39217
+ }
39218
+ /** The token the session is currently authenticating with. */
39219
+ get activeToken() {
39220
+ return this.active;
39221
+ }
39222
+ /**
39223
+ * Run one credentialed git network op. Transparently falls back to the global
39224
+ * token + self-heals on a per-project auth/permission failure (see module doc).
39225
+ */
39226
+ async run(fn) {
39227
+ try {
39228
+ return await this.deps.withGitCredentials(this.active.token, fn);
39229
+ } catch (err) {
39230
+ const global3 = this.fallbackCandidate(err);
39231
+ if (!global3) throw err;
39232
+ this.fallbackConsumed = true;
39233
+ let result;
39234
+ try {
39235
+ result = await this.deps.withGitCredentials(global3.token, fn);
39236
+ } catch {
39237
+ throw err;
39238
+ }
39239
+ this.active = global3;
39240
+ this.healed = true;
39241
+ try {
39242
+ this.deps.removeProjectGitHubToken(this.projectRoot);
39243
+ } catch {
39244
+ }
39245
+ return result;
39246
+ }
39247
+ }
39248
+ /**
39249
+ * Whether a failed op qualifies for the one-shot global fallback, returning the
39250
+ * global token to retry with (or null when it does not qualify). Guards, in order:
39251
+ * fallback not already used → active token is per-project → failure is auth/permission
39252
+ * → a global token exists whose VALUE differs from the (stale) per-project one.
39253
+ */
39254
+ fallbackCandidate(err) {
39255
+ if (this.fallbackConsumed) return null;
39256
+ if (!isPerProjectToken(this.active)) return null;
39257
+ const kind = classifySyncError(err?.message ?? String(err)).kind;
39258
+ if (kind !== "auth" && kind !== "permission") return null;
39259
+ const global3 = this.deps.readGlobalGitHubToken();
39260
+ if (!global3 || global3.token === this.active.token) return null;
39261
+ return global3;
39262
+ }
39263
+ };
39264
+ }
39265
+ });
39266
+
39014
39267
  // src/lib/git-sync/sync-engine.ts
39015
39268
  import { dirname as dirname25 } from "path";
39016
39269
  function syncCommitMessage(ctx) {
@@ -39045,6 +39298,26 @@ function personAuthorFor(ctx) {
39045
39298
  function authorFor(ctx) {
39046
39299
  return personAuthorFor(ctx) ?? (ctx.d.git.hasGitIdentity(ctx.gitCwd) ? void 0 : FALLBACK_AUTHOR);
39047
39300
  }
39301
+ function resolveTokenSession(ctx) {
39302
+ if (ctx.session) return ctx.session;
39303
+ const token = ctx.d.resolveBrainSyncToken(ctx.projectRoot);
39304
+ if (!token) return null;
39305
+ const session = new BrainSyncTokenSession(token, ctx.projectRoot, {
39306
+ withGitCredentials: ctx.d.withGitCredentials,
39307
+ readGlobalGitHubToken: ctx.d.readGlobalGitHubToken,
39308
+ removeProjectGitHubToken: ctx.d.removeProjectGitHubToken
39309
+ });
39310
+ ctx.session = session;
39311
+ return session;
39312
+ }
39313
+ function applyHealInfo(ctx, result) {
39314
+ if (!ctx.session?.healedStaleProjectToken) return result;
39315
+ return {
39316
+ ...result,
39317
+ healedStaleProjectToken: true,
39318
+ note: result.note ? `${result.note} ${HEALED_STALE_TOKEN_NOTE}` : HEALED_STALE_TOKEN_NOTE
39319
+ };
39320
+ }
39048
39321
  async function runBrainSync(opts, depsOverride = {}) {
39049
39322
  const d = { ...defaultDeps, ...depsOverride };
39050
39323
  const contextRoot = opts.cwd;
@@ -39152,7 +39425,7 @@ async function runBrainSync(opts, depsOverride = {}) {
39152
39425
  else if (opts.mode === "pull-only") result = await pullOnlySync(ctx);
39153
39426
  else if (opts.mode === "push-only") result = await pushOnlySync(ctx);
39154
39427
  else result = await autoSync(ctx);
39155
- return result;
39428
+ return applyHealInfo(ctx, result);
39156
39429
  } finally {
39157
39430
  d.releaseBrainLock(contextRoot);
39158
39431
  }
@@ -39182,9 +39455,9 @@ function scrubAndCommitMerge(ctx, effectiveStrict, message) {
39182
39455
  function withMergeOutcome(result, preMergeScrub) {
39183
39456
  return result.action === "blocked-scrub" ? result : { ...result, scrub: preMergeScrub };
39184
39457
  }
39185
- async function fetchRemoteIfExists(ctx, token) {
39458
+ async function fetchRemoteIfExists(ctx, session) {
39186
39459
  const { d, gitCwd } = ctx;
39187
- return d.withGitCredentials(token, async (env2) => {
39460
+ return session.run(async (env2) => {
39188
39461
  const exists = d.git.remoteBranchExists(gitCwd, REMOTE_NAME, ctx.branch, env2);
39189
39462
  if (exists) d.git.fetch(gitCwd, REMOTE_NAME, ctx.branch, env2);
39190
39463
  return exists;
@@ -39262,15 +39535,15 @@ function mergeAndMaybeDefer(ctx, opts) {
39262
39535
  const blocked = scrubAndCommitMerge(ctx, !!opts.effectiveStrict, MERGE_COMMIT_MESSAGE);
39263
39536
  return { result: blocked, needsTaskSync };
39264
39537
  }
39265
- async function pushWithRetry(ctx, scrub) {
39266
- const { d, gitCwd, projectRoot } = ctx;
39267
- const token = d.resolveBrainSyncToken(projectRoot);
39268
- if (!token) {
39269
- return { action: "no-remote", scrub, note: "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env)." };
39538
+ async function pushWithRetry(ctx, scrub, session) {
39539
+ const { d, gitCwd } = ctx;
39540
+ const s = session ?? resolveTokenSession(ctx);
39541
+ if (!s) {
39542
+ return { action: "no-remote", scrub, note: NO_TOKEN_NOTE };
39270
39543
  }
39271
39544
  const tryPush = async () => {
39272
39545
  try {
39273
- await d.withGitCredentials(token.token, async (env2) => {
39546
+ await s.run(async (env2) => {
39274
39547
  d.git.push(gitCwd, REMOTE_NAME, ctx.branch, env2);
39275
39548
  });
39276
39549
  return true;
@@ -39279,7 +39552,7 @@ async function pushWithRetry(ctx, scrub) {
39279
39552
  }
39280
39553
  };
39281
39554
  if (await tryPush()) return { action: "pushed", scrub, pushed: true };
39282
- const remoteExists = await fetchRemoteIfExists(ctx, token.token);
39555
+ const remoteExists = await fetchRemoteIfExists(ctx, s);
39283
39556
  if (!remoteExists) {
39284
39557
  throw new GitSyncError("Push to the empty brain remote failed \u2014 check the token has Contents read/write on that repo and the remote URL is correct.");
39285
39558
  }
@@ -39289,10 +39562,10 @@ async function pushWithRetry(ctx, scrub) {
39289
39562
  throw new GitSyncError("Push rejected (non-fast-forward) twice \u2014 the remote is still ahead after a merge + one retry. Run `dreamcontext brain sync` again or resolve manually.");
39290
39563
  }
39291
39564
  async function autoSync(ctx) {
39292
- const { d, gitCwd, projectRoot } = ctx;
39293
- const token = d.resolveBrainSyncToken(projectRoot);
39294
- if (!token) return { action: "no-remote", scrub: EMPTY_SCRUB, note: "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env)." };
39295
- const remoteExists = await fetchRemoteIfExists(ctx, token.token);
39565
+ const { d, gitCwd } = ctx;
39566
+ const session = resolveTokenSession(ctx);
39567
+ if (!session) return { action: "no-remote", scrub: EMPTY_SCRUB, note: NO_TOKEN_NOTE };
39568
+ const remoteExists = await fetchRemoteIfExists(ctx, session);
39296
39569
  const aheadCount = remoteExists ? d.git.revListCount(gitCwd, `HEAD..${ctx.remoteRef}`) : 0;
39297
39570
  const localAhead = remoteExists ? d.git.revListCount(gitCwd, `${ctx.remoteRef}..HEAD`) : 0;
39298
39571
  const dirty = d.git.statusPorcelainTracked(gitCwd);
@@ -39317,14 +39590,14 @@ async function autoSync(ctx) {
39317
39590
  if (isBlockingScrub(rangeScrub, ctx.strict)) return { action: "blocked-scrub", scrub: rangeScrub };
39318
39591
  if (rangeScrub.blocks.length > 0 || rangeScrub.warns.length > 0) scrub = rangeScrub;
39319
39592
  }
39320
- const pushResult = await pushWithRetry(ctx, scrub);
39593
+ const pushResult = await pushWithRetry(ctx, scrub, session);
39321
39594
  return { ...pushResult, needsTaskSync: needsTaskSync || pushResult.needsTaskSync };
39322
39595
  }
39323
39596
  async function pullOnlySync(ctx) {
39324
- const { d, gitCwd, projectRoot, contextRoot } = ctx;
39325
- const token = d.resolveBrainSyncToken(projectRoot);
39326
- if (!token) return { action: "no-remote", scrub: EMPTY_SCRUB, note: "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env)." };
39327
- if (!await fetchRemoteIfExists(ctx, token.token)) {
39597
+ const { d, gitCwd, projectRoot } = ctx;
39598
+ const session = resolveTokenSession(ctx);
39599
+ if (!session) return { action: "no-remote", scrub: EMPTY_SCRUB, note: NO_TOKEN_NOTE };
39600
+ if (!await fetchRemoteIfExists(ctx, session)) {
39328
39601
  return { action: "noop", scrub: EMPTY_SCRUB, note: "Remote brain repo is empty \u2014 nothing to pull yet. Run `dreamcontext brain sync` to push the first commit." };
39329
39602
  }
39330
39603
  const beforeSha = d.git.currentSha(gitCwd);
@@ -39396,9 +39669,9 @@ async function continueMerge(ctx) {
39396
39669
  async function resumeHandoff(ctx) {
39397
39670
  const { d, gitCwd, contextRoot, projectRoot } = ctx;
39398
39671
  clearConflictReport(contextRoot);
39399
- const token = d.resolveBrainSyncToken(projectRoot);
39400
- if (!token) return { action: "no-remote", scrub: EMPTY_SCRUB, note: "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env)." };
39401
- await fetchRemoteIfExists(ctx, token.token);
39672
+ const session = resolveTokenSession(ctx);
39673
+ if (!session) return { action: "no-remote", scrub: EMPTY_SCRUB, note: NO_TOKEN_NOTE };
39674
+ await fetchRemoteIfExists(ctx, session);
39402
39675
  const dirty = d.git.statusPorcelainTracked(gitCwd);
39403
39676
  const scrub = EMPTY_SCRUB;
39404
39677
  if (dirty.length > 0) {
@@ -39410,13 +39683,13 @@ async function resumeHandoff(ctx) {
39410
39683
  }
39411
39684
  const outcome = mergeAndMaybeDefer(ctx, { abortOnDefer: false, markPendingOnDefer: false });
39412
39685
  if (outcome.result) return withMergeOutcome(outcome.result, scrub);
39413
- const pushResult = await pushWithRetry(ctx, scrub);
39686
+ const pushResult = await pushWithRetry(ctx, scrub, session);
39414
39687
  if (pushResult.action === "pushed") {
39415
39688
  writeBrainLocal(projectRoot, { pendingAgentMerge: false });
39416
39689
  }
39417
39690
  return pushResult;
39418
39691
  }
39419
- var REMOTE_NAME, DEFAULT_BRANCH, EMPTY_TREE_SHA, MERGE_COMMIT_MESSAGE, AGENT_MERGE_COMMIT_MESSAGE, EMPTY_SCRUB, defaultDeps;
39692
+ var REMOTE_NAME, DEFAULT_BRANCH, EMPTY_TREE_SHA, MERGE_COMMIT_MESSAGE, AGENT_MERGE_COMMIT_MESSAGE, EMPTY_SCRUB, defaultDeps, NO_TOKEN_NOTE, HEALED_STALE_TOKEN_NOTE;
39420
39693
  var init_sync_engine = __esm({
39421
39694
  "src/lib/git-sync/sync-engine.ts"() {
39422
39695
  "use strict";
@@ -39429,6 +39702,8 @@ var init_sync_engine = __esm({
39429
39702
  init_brain_repo();
39430
39703
  init_credentials();
39431
39704
  init_auth_store();
39705
+ init_secrets();
39706
+ init_token_fallback();
39432
39707
  init_identity();
39433
39708
  init_id();
39434
39709
  REMOTE_NAME = "origin";
@@ -39446,86 +39721,12 @@ var init_sync_engine = __esm({
39446
39721
  withGitCredentials,
39447
39722
  acquireBrainLock,
39448
39723
  releaseBrainLock,
39449
- readGlobalGitHubLogin
39724
+ readGlobalGitHubLogin,
39725
+ readGlobalGitHubToken,
39726
+ removeProjectGitHubToken
39450
39727
  };
39451
- }
39452
- });
39453
-
39454
- // src/lib/git-sync/failure.ts
39455
- function githubSlug(s) {
39456
- const m = s.match(/github\.com[/:]([^/\s]+\/[^/\s'".]+)/i);
39457
- return m ? m[1].replace(/\.git$/, "") : void 0;
39458
- }
39459
- function extractRepo(message, fallbackRepo) {
39460
- const perm = message.match(/Permission to ([^\s]+?)(?:\.git)? denied/i);
39461
- if (perm) return perm[1];
39462
- const fromMsg = githubSlug(message);
39463
- if (fromMsg) return fromMsg;
39464
- if (fallbackRepo) return githubSlug(fallbackRepo) ?? fallbackRepo;
39465
- return void 0;
39466
- }
39467
- function classifySyncError(rawMessage, repoHint) {
39468
- const m = rawMessage || "";
39469
- const repo = extractRepo(m, repoHint);
39470
- const named = repo ? ` on ${repo}` : "";
39471
- if (/non-fast-forward.*twice|rejected.*non-fast-forward|Push rejected \(non-fast-forward\) twice/i.test(m)) {
39472
- return {
39473
- kind: "push-rejected",
39474
- recovery: "retry",
39475
- repo,
39476
- message: "The team pushed while your sync was in flight. Retry \u2014 dreamcontext will merge their changes and push again."
39477
- };
39478
- }
39479
- if (/Contents\b.*write|permission to .* denied|protected branch|not authorized|remote: Permission|must have push access|403\b/i.test(m)) {
39480
- return {
39481
- kind: "permission",
39482
- recovery: "check-permissions",
39483
- repo,
39484
- message: `Your GitHub token can't write to${named || " this repo"}. Give it Contents (read & write) access${repo ? ` on ${repo}` : ""}, then retry.`
39485
- };
39486
- }
39487
- if (/no github token found|no token found for the brain/i.test(m)) {
39488
- return {
39489
- kind: "no-token",
39490
- recovery: "reconnect-github",
39491
- repo,
39492
- message: "Cloud sync needs a GitHub account. Connect GitHub to start syncing."
39493
- };
39494
- }
39495
- if (/authentication failed|could not read Username|bad credentials|invalid credentials|401\b|terminal prompts disabled|Support for password authentication/i.test(m)) {
39496
- return {
39497
- kind: "auth",
39498
- recovery: "reconnect-github",
39499
- repo,
39500
- message: "Your GitHub sign-in expired or is invalid. Reconnect GitHub to keep syncing."
39501
- };
39502
- }
39503
- if (/could ?n[o']t resolve host|could not resolve host|connection timed out|failed to connect|network is unreachable|temporary failure in name resolution|unable to access .*(?:Could not resolve|timed out|Failed to connect)|getaddrinfo|ENOTFOUND|ETIMEDOUT/i.test(m)) {
39504
- return {
39505
- kind: "network",
39506
- recovery: "wait-online",
39507
- repo,
39508
- message: "You're offline \u2014 sync will retry automatically when you're back online. Nothing was lost."
39509
- };
39510
- }
39511
- if (/unrelated histories/i.test(m)) {
39512
- return {
39513
- kind: "unknown",
39514
- recovery: "manual",
39515
- repo,
39516
- message: "The remote contains content that did not come from this brain (e.g. a README). Attach an empty repo or reconcile the histories manually."
39517
- };
39518
- }
39519
- return {
39520
- kind: "unknown",
39521
- recovery: "retry",
39522
- repo,
39523
- message: rawMessage.trim() || "Sync failed. Retry, or check your connection and GitHub access."
39524
- };
39525
- }
39526
- var init_failure = __esm({
39527
- "src/lib/git-sync/failure.ts"() {
39528
- "use strict";
39728
+ NO_TOKEN_NOTE = "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env).";
39729
+ HEALED_STALE_TOKEN_NOTE = "This project had its own GitHub token that was stale \u2014 sync switched to your signed-in GitHub account and removed the stale project token.";
39529
39730
  }
39530
39731
  });
39531
39732
 
@@ -39534,13 +39735,14 @@ function reconcileBrainSyncSuccess(action) {
39534
39735
  if (AUTH_OK_ACTIONS.has(action)) setGlobalGitHubAuthValid(true);
39535
39736
  }
39536
39737
  function reconcileBrainSyncFailure(rawMessage, projectRoot, repoHint) {
39537
- const failure = classifySyncError(rawMessage, repoHint);
39738
+ const resolved = resolveBrainSyncToken(projectRoot);
39739
+ const failure = classifySyncError(rawMessage, repoHint, { perProjectToken: isPerProjectToken(resolved) });
39538
39740
  if (failure.kind === "permission") {
39539
39741
  setGlobalGitHubAuthValid(true);
39540
39742
  return;
39541
39743
  }
39542
39744
  if (failure.kind !== "auth") return;
39543
- if (resolveBrainSyncToken(projectRoot)?.via === "global") setGlobalGitHubAuthValid(false);
39745
+ if (resolved?.via === "global") setGlobalGitHubAuthValid(false);
39544
39746
  }
39545
39747
  var AUTH_OK_ACTIONS;
39546
39748
  var init_auth_reconcile = __esm({
@@ -39549,6 +39751,7 @@ var init_auth_reconcile = __esm({
39549
39751
  init_auth_store();
39550
39752
  init_brain_repo();
39551
39753
  init_failure();
39754
+ init_token_fallback();
39552
39755
  AUTH_OK_ACTIONS = /* @__PURE__ */ new Set([
39553
39756
  "pulled",
39554
39757
  "pushed",
@@ -39646,12 +39849,19 @@ function registerBrainCommand(program2) {
39646
39849
  renderBrainSyncResult(result);
39647
39850
  if (result.action === "invalid-flag" || result.action === "blocked-scrub") process.exitCode = 1;
39648
39851
  } catch (err) {
39649
- reconcileBrainSyncFailure(err.message, dirname26(contextRoot));
39852
+ const projectRoot = dirname26(contextRoot);
39853
+ reconcileBrainSyncFailure(err.message, projectRoot);
39650
39854
  if (err instanceof GitSyncError) {
39651
39855
  error(err.message);
39652
39856
  } else {
39653
39857
  error(`Brain sync failed: ${err.message}`);
39654
39858
  }
39859
+ const failure = classifySyncError(err.message, void 0, {
39860
+ perProjectToken: isPerProjectToken(resolveBrainSyncToken(projectRoot))
39861
+ });
39862
+ if ((failure.kind === "auth" || failure.kind === "permission") && isPerProjectToken(resolveBrainSyncToken(projectRoot))) {
39863
+ warn(failure.message);
39864
+ }
39655
39865
  process.exitCode = 1;
39656
39866
  }
39657
39867
  });
@@ -39694,6 +39904,7 @@ function renderBrainSyncResult(result) {
39694
39904
  default:
39695
39905
  info(`Brain sync: ${result.action}.`);
39696
39906
  }
39907
+ if (result.healedStaleProjectToken && result.note) info(result.note);
39697
39908
  }
39698
39909
  var init_brain = __esm({
39699
39910
  "src/cli/commands/brain.ts"() {
@@ -39704,6 +39915,8 @@ var init_brain = __esm({
39704
39915
  init_sync_engine();
39705
39916
  init_brain_repo();
39706
39917
  init_scrub();
39918
+ init_failure();
39919
+ init_token_fallback();
39707
39920
  init_auth_reconcile();
39708
39921
  init_git();
39709
39922
  init_git();
@@ -41547,8 +41760,14 @@ function registerSleepCommand(program2) {
41547
41760
  }
41548
41761
  }
41549
41762
  } catch (err) {
41550
- reconcileBrainSyncFailure(err.message ?? String(err), dirname28(root));
41763
+ const projectRoot = dirname28(root);
41764
+ reconcileBrainSyncFailure(err.message ?? String(err), projectRoot);
41551
41765
  warn(`Brain sync: skipped \u2014 ${err.message ?? err}`);
41766
+ const perProjectToken = isPerProjectToken(resolveBrainSyncToken(projectRoot));
41767
+ const failure = classifySyncError(err.message ?? String(err), void 0, { perProjectToken });
41768
+ if (perProjectToken && (failure.kind === "auth" || failure.kind === "permission")) {
41769
+ warn(failure.message);
41770
+ }
41552
41771
  }
41553
41772
  try {
41554
41773
  if (embeddingCacheExists(root)) {
@@ -41652,6 +41871,9 @@ var init_sleep = __esm({
41652
41871
  init_file_lock();
41653
41872
  init_sync_engine();
41654
41873
  init_auth_reconcile();
41874
+ init_failure();
41875
+ init_brain_repo();
41876
+ init_token_fallback();
41655
41877
  init_brain();
41656
41878
  init_recall();
41657
41879
  init_store();
@@ -42016,7 +42238,7 @@ import {
42016
42238
  existsSync as existsSync54,
42017
42239
  readFileSync as readFileSync39,
42018
42240
  writeFileSync as writeFileSync38,
42019
- unlinkSync as unlinkSync6,
42241
+ unlinkSync as unlinkSync7,
42020
42242
  renameSync as renameSync11,
42021
42243
  mkdirSync as mkdirSync31
42022
42244
  } from "fs";
@@ -42118,12 +42340,12 @@ ${srcBody}
42118
42340
  renameSync11(tmpPath, dstAbsPath);
42119
42341
  } catch (e) {
42120
42342
  try {
42121
- if (existsSync54(tmpPath)) unlinkSync6(tmpPath);
42343
+ if (existsSync54(tmpPath)) unlinkSync7(tmpPath);
42122
42344
  } catch {
42123
42345
  }
42124
42346
  throw e;
42125
42347
  }
42126
- unlinkSync6(srcAbsPath);
42348
+ unlinkSync7(srcAbsPath);
42127
42349
  return {
42128
42350
  ok: true,
42129
42351
  srcSlug,
@@ -42342,7 +42564,7 @@ var init_member_match = __esm({
42342
42564
  });
42343
42565
 
42344
42566
  // src/lib/objectives-store.ts
42345
- import { existsSync as existsSync56, mkdirSync as mkdirSync32, unlinkSync as unlinkSync7 } from "fs";
42567
+ import { existsSync as existsSync56, mkdirSync as mkdirSync32, unlinkSync as unlinkSync8 } from "fs";
42346
42568
  import { join as join57, basename as basename15 } from "path";
42347
42569
  function objectivesDir(contextRoot) {
42348
42570
  return join57(contextRoot, "core", "objectives");
@@ -42623,7 +42845,7 @@ function deleteObjective(contextRoot, slug) {
42623
42845
  }
42624
42846
  }
42625
42847
  }
42626
- unlinkSync7(existing.path);
42848
+ unlinkSync8(existing.path);
42627
42849
  return { unhealedTasks };
42628
42850
  }
42629
42851
  function addDependency(contextRoot, from, to) {
@@ -43862,8 +44084,10 @@ function buildRoadmapModel(contextRoot) {
43862
44084
  if (hasDates) {
43863
44085
  const earliestStart = minDate(tasks.map((t) => t.start_date));
43864
44086
  const latestDue = maxDate(tasks.map((t) => t.due_date));
43865
- forecastStart = maxDate([earliestStart, maxDepEnd]);
43866
- forecastEnd = maxDate([latestDue, forecastStart]);
44087
+ const committedEnd = o.target_date ?? o.start_date;
44088
+ forecastStart = maxDate([minDate([earliestStart, o.start_date]), maxDepEnd]) ?? latestDue;
44089
+ const workEnd = maxDate([latestDue, forecastStart]);
44090
+ forecastEnd = maxDate([committedEnd, workEnd]);
43867
44091
  } else if (o.start_date !== null) {
43868
44092
  const committedStart = o.start_date;
43869
44093
  const committedEnd = o.target_date ?? o.start_date;
@@ -45791,7 +46015,7 @@ import {
45791
46015
  readFileSync as readFileSync43,
45792
46016
  writeFileSync as writeFileSync43,
45793
46017
  renameSync as renameSync13,
45794
- unlinkSync as unlinkSync8,
46018
+ unlinkSync as unlinkSync9,
45795
46019
  readdirSync as readdirSync12
45796
46020
  } from "fs";
45797
46021
  import { dirname as dirname34, join as join67 } from "path";
@@ -45813,7 +46037,7 @@ function writeJsonWithBridge(jsonPath, bridgePath, jsonValue, bridgeMarkdown) {
45813
46037
  writeFileSync43(bridgeTmp, bridgeMarkdown, "utf8");
45814
46038
  } catch (e) {
45815
46039
  try {
45816
- unlinkSync8(jsonTmp);
46040
+ unlinkSync9(jsonTmp);
45817
46041
  } catch {
45818
46042
  }
45819
46043
  throw e;
@@ -45823,7 +46047,7 @@ function writeJsonWithBridge(jsonPath, bridgePath, jsonValue, bridgeMarkdown) {
45823
46047
  renameSync13(bridgeTmp, bridgePath);
45824
46048
  } catch (e) {
45825
46049
  try {
45826
- unlinkSync8(bridgeTmp);
46050
+ unlinkSync9(bridgeTmp);
45827
46051
  } catch {
45828
46052
  }
45829
46053
  throw e;
@@ -45849,7 +46073,7 @@ function acquireLock() {
45849
46073
  throw new LockBusyError(heldPid);
45850
46074
  }
45851
46075
  try {
45852
- unlinkSync8(lockPath);
46076
+ unlinkSync9(lockPath);
45853
46077
  } catch {
45854
46078
  }
45855
46079
  }
@@ -45873,7 +46097,7 @@ function acquireLock() {
45873
46097
  try {
45874
46098
  const heldRaw = readFileSync43(lockPath, "utf8").trim();
45875
46099
  if (Number.parseInt(heldRaw, 10) === process.pid) {
45876
- unlinkSync8(lockPath);
46100
+ unlinkSync9(lockPath);
45877
46101
  }
45878
46102
  } catch {
45879
46103
  }
@@ -47300,11 +47524,12 @@ function getVersionNudge(root) {
47300
47524
  const cache = readVersionCache(projectRoot);
47301
47525
  if (!cache || !isCacheFresh(cache)) return "";
47302
47526
  const installedCli = dreamcontextVersion();
47303
- const catalogPackNames = cache.availablePacks;
47304
- const installedPacks = catalogPackNames.filter((name) => isSkillInstalled(projectRoot, name));
47527
+ const optedInPacks = readSetupConfig(projectRoot)?.packs ?? [];
47528
+ const relevantPacks = cache.availablePacks.filter((name) => optedInPacks.includes(name));
47529
+ const installedPacks = relevantPacks.filter((name) => isSkillInstalled(projectRoot, name));
47305
47530
  const marker = readAutoUpgradeMarker(projectRoot);
47306
47531
  const suppressCliNudge = shouldSuppressCliNudge(cache.latestCli, marker, process.env);
47307
- const nudge = buildNudge(installedCli, cache, installedPacks, catalogPackNames, { suppressCliNudge });
47532
+ const nudge = buildNudge(installedCli, cache, installedPacks, relevantPacks, { suppressCliNudge });
47308
47533
  return nudge ?? "";
47309
47534
  } catch {
47310
47535
  return "";
@@ -49271,7 +49496,7 @@ var init_initializer_detect = __esm({
49271
49496
  });
49272
49497
 
49273
49498
  // src/lib/agent-session-map.ts
49274
- import { existsSync as existsSync77, lstatSync as lstatSync2, mkdirSync as mkdirSync42, readFileSync as readFileSync54, writeFileSync as writeFileSync48, renameSync as renameSync16, readdirSync as readdirSync16, unlinkSync as unlinkSync9, statSync as statSync14 } from "fs";
49499
+ import { existsSync as existsSync77, lstatSync as lstatSync2, mkdirSync as mkdirSync42, readFileSync as readFileSync54, writeFileSync as writeFileSync48, renameSync as renameSync16, readdirSync as readdirSync16, unlinkSync as unlinkSync10, statSync as statSync14 } from "fs";
49275
49500
  import { join as join75, dirname as dirname44, basename as basename24 } from "path";
49276
49501
  import { randomUUID as randomUUID3 } from "crypto";
49277
49502
  function mapDir(contextRoot) {
@@ -49339,7 +49564,7 @@ function recordAgentSession(contextRoot, tabId, sessionId) {
49339
49564
  const other = readEntry(p);
49340
49565
  if (other?.current === sessionId) {
49341
49566
  try {
49342
- unlinkSync9(p);
49567
+ unlinkSync10(p);
49343
49568
  } catch {
49344
49569
  }
49345
49570
  } else {
@@ -49349,7 +49574,7 @@ function recordAgentSession(contextRoot, tabId, sessionId) {
49349
49574
  if (survivors.length + 1 > MAX_ENTRIES) {
49350
49575
  survivors.sort((a, b) => a.updated === b.updated ? a.f < b.f ? -1 : 1 : a.updated < b.updated ? -1 : 1).slice(0, survivors.length + 1 - MAX_ENTRIES).forEach(({ f }) => {
49351
49576
  try {
49352
- unlinkSync9(join75(dir, f));
49577
+ unlinkSync10(join75(dir, f));
49353
49578
  } catch {
49354
49579
  }
49355
49580
  });
@@ -49418,7 +49643,7 @@ var init_agent_session_map = __esm({
49418
49643
 
49419
49644
  // src/cli/commands/hook.ts
49420
49645
  import { readFileSync as readFileSync55, existsSync as existsSync78, statSync as statSync15 } from "fs";
49421
- import { execFileSync as execFileSync8, spawn as spawn3 } from "child_process";
49646
+ import { execFileSync as execFileSync8, spawn as spawn4 } from "child_process";
49422
49647
  import { get as httpGet, request as httpRequest } from "http";
49423
49648
  import { dirname as dirname45, resolve as resolve17, join as join76, extname as extname3, basename as basename25, relative as relative5 } from "path";
49424
49649
  function readStdin() {
@@ -49743,12 +49968,12 @@ function resolveDashboardPort() {
49743
49968
  return DEFAULT_DASHBOARD_PORT;
49744
49969
  }
49745
49970
  function fetchDashboardHealth(port, timeoutMs = 700) {
49746
- return new Promise((resolve26) => {
49971
+ return new Promise((resolve27) => {
49747
49972
  let settled = false;
49748
49973
  const done = (val) => {
49749
49974
  if (settled) return;
49750
49975
  settled = true;
49751
- resolve26(val);
49976
+ resolve27(val);
49752
49977
  };
49753
49978
  try {
49754
49979
  const req = httpGet({ host: "127.0.0.1", port, path: "/api/health", timeout: timeoutMs }, (res) => {
@@ -49778,12 +50003,12 @@ function fetchDashboardHealth(port, timeoutMs = 700) {
49778
50003
  });
49779
50004
  }
49780
50005
  function requestDashboardShutdown(port, timeoutMs = 1500) {
49781
- return new Promise((resolve26) => {
50006
+ return new Promise((resolve27) => {
49782
50007
  let settled = false;
49783
50008
  const done = (val) => {
49784
50009
  if (settled) return;
49785
50010
  settled = true;
49786
- resolve26(val);
50011
+ resolve27(val);
49787
50012
  };
49788
50013
  try {
49789
50014
  const req = httpRequest(
@@ -49805,12 +50030,12 @@ function requestDashboardShutdown(port, timeoutMs = 1500) {
49805
50030
  });
49806
50031
  }
49807
50032
  function isDashboardUp(port, timeoutMs = 700) {
49808
- return new Promise((resolve26) => {
50033
+ return new Promise((resolve27) => {
49809
50034
  let settled = false;
49810
50035
  const done = (val) => {
49811
50036
  if (settled) return;
49812
50037
  settled = true;
49813
- resolve26(val);
50038
+ resolve27(val);
49814
50039
  };
49815
50040
  try {
49816
50041
  const req = httpGet({ host: "127.0.0.1", port, path: "/api/health", timeout: timeoutMs }, (res) => {
@@ -49830,7 +50055,7 @@ function isDashboardUp(port, timeoutMs = 700) {
49830
50055
  function spawnDashboard(port) {
49831
50056
  const cliEntry = process.argv[1];
49832
50057
  if (!cliEntry) return;
49833
- const child = spawn3(process.execPath, [cliEntry, "dashboard", "--port", String(port)], {
50058
+ const child = spawn4(process.execPath, [cliEntry, "dashboard", "--port", String(port)], {
49834
50059
  detached: true,
49835
50060
  stdio: "ignore",
49836
50061
  cwd: process.cwd()
@@ -49840,7 +50065,7 @@ function spawnDashboard(port) {
49840
50065
  function spawnAssetDriftRefresh() {
49841
50066
  const cliEntry = process.argv[1];
49842
50067
  if (!cliEntry) return;
49843
- const child = spawn3(process.execPath, [cliEntry, "hook", "refresh-asset-drift"], {
50068
+ const child = spawn4(process.execPath, [cliEntry, "hook", "refresh-asset-drift"], {
49844
50069
  detached: true,
49845
50070
  stdio: "ignore",
49846
50071
  cwd: process.cwd()
@@ -49850,7 +50075,7 @@ function spawnAssetDriftRefresh() {
49850
50075
  function spawnBrainPull(root) {
49851
50076
  const cliEntry = process.argv[1];
49852
50077
  if (!cliEntry) return;
49853
- const child = spawn3(process.execPath, [cliEntry, "brain", "sync", "--pull-only"], {
50078
+ const child = spawn4(process.execPath, [cliEntry, "brain", "sync", "--pull-only"], {
49854
50079
  detached: true,
49855
50080
  stdio: "ignore",
49856
50081
  cwd: root
@@ -50936,31 +51161,31 @@ var init_router = __esm({
50936
51161
 
50937
51162
  // src/server/middleware.ts
50938
51163
  async function parseJsonBody(req) {
50939
- return new Promise((resolve26) => {
51164
+ return new Promise((resolve27) => {
50940
51165
  const chunks = [];
50941
51166
  let size = 0;
50942
51167
  req.on("data", (chunk) => {
50943
51168
  size += chunk.length;
50944
51169
  if (size > MAX_BODY_SIZE) {
50945
51170
  req.destroy();
50946
- resolve26(null);
51171
+ resolve27(null);
50947
51172
  return;
50948
51173
  }
50949
51174
  chunks.push(chunk);
50950
51175
  });
50951
51176
  req.on("end", () => {
50952
51177
  if (chunks.length === 0) {
50953
- resolve26(null);
51178
+ resolve27(null);
50954
51179
  return;
50955
51180
  }
50956
51181
  try {
50957
51182
  const body = Buffer.concat(chunks).toString("utf-8");
50958
- resolve26(JSON.parse(body));
51183
+ resolve27(JSON.parse(body));
50959
51184
  } catch {
50960
- resolve26(null);
51185
+ resolve27(null);
50961
51186
  }
50962
51187
  });
50963
- req.on("error", () => resolve26(null));
51188
+ req.on("error", () => resolve27(null));
50964
51189
  });
50965
51190
  }
50966
51191
  function sendJson(res, statusCode, data) {
@@ -52328,14 +52553,14 @@ var require_filesystem = __commonJS({
52328
52553
  });
52329
52554
  return buffer.subarray(0, bytesRead);
52330
52555
  };
52331
- var readFile = (path2) => new Promise((resolve26, reject) => {
52556
+ var readFile = (path2) => new Promise((resolve27, reject) => {
52332
52557
  fs.open(path2, "r", (err, fd) => {
52333
52558
  if (err) {
52334
52559
  reject(err);
52335
52560
  } else {
52336
52561
  const buffer = Buffer.alloc(MAX_LENGTH);
52337
52562
  fs.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
52338
- resolve26(buffer.subarray(0, bytesRead));
52563
+ resolve27(buffer.subarray(0, bytesRead));
52339
52564
  fs.close(fd, () => {
52340
52565
  });
52341
52566
  });
@@ -52403,10 +52628,10 @@ var require_detect_libc = __commonJS({
52403
52628
  var commandOut = "";
52404
52629
  var safeCommand = () => {
52405
52630
  if (!commandOut) {
52406
- return new Promise((resolve26) => {
52631
+ return new Promise((resolve27) => {
52407
52632
  childProcess.exec(command, (err, out) => {
52408
52633
  commandOut = err ? " " : out;
52409
- resolve26(commandOut);
52634
+ resolve27(commandOut);
52410
52635
  });
52411
52636
  });
52412
52637
  }
@@ -55086,14 +55311,14 @@ var require_input = __commonJS({
55086
55311
  return this;
55087
55312
  } else {
55088
55313
  if (this._isStreamInput()) {
55089
- return new Promise((resolve26, reject) => {
55314
+ return new Promise((resolve27, reject) => {
55090
55315
  const finished = () => {
55091
55316
  this._flattenBufferIn();
55092
55317
  sharp.metadata(this.options, (err, metadata2) => {
55093
55318
  if (err) {
55094
55319
  reject(is.nativeError(err, stack));
55095
55320
  } else {
55096
- resolve26(metadata2);
55321
+ resolve27(metadata2);
55097
55322
  }
55098
55323
  });
55099
55324
  };
@@ -55104,12 +55329,12 @@ var require_input = __commonJS({
55104
55329
  }
55105
55330
  });
55106
55331
  } else {
55107
- return new Promise((resolve26, reject) => {
55332
+ return new Promise((resolve27, reject) => {
55108
55333
  sharp.metadata(this.options, (err, metadata2) => {
55109
55334
  if (err) {
55110
55335
  reject(is.nativeError(err, stack));
55111
55336
  } else {
55112
- resolve26(metadata2);
55337
+ resolve27(metadata2);
55113
55338
  }
55114
55339
  });
55115
55340
  });
@@ -55142,25 +55367,25 @@ var require_input = __commonJS({
55142
55367
  return this;
55143
55368
  } else {
55144
55369
  if (this._isStreamInput()) {
55145
- return new Promise((resolve26, reject) => {
55370
+ return new Promise((resolve27, reject) => {
55146
55371
  this.on("finish", function() {
55147
55372
  this._flattenBufferIn();
55148
55373
  sharp.stats(this.options, (err, stats2) => {
55149
55374
  if (err) {
55150
55375
  reject(is.nativeError(err, stack));
55151
55376
  } else {
55152
- resolve26(stats2);
55377
+ resolve27(stats2);
55153
55378
  }
55154
55379
  });
55155
55380
  });
55156
55381
  });
55157
55382
  } else {
55158
- return new Promise((resolve26, reject) => {
55383
+ return new Promise((resolve27, reject) => {
55159
55384
  sharp.stats(this.options, (err, stats2) => {
55160
55385
  if (err) {
55161
55386
  reject(is.nativeError(err, stack));
55162
55387
  } else {
55163
- resolve26(stats2);
55388
+ resolve27(stats2);
55164
55389
  }
55165
55390
  });
55166
55391
  });
@@ -58582,7 +58807,7 @@ var require_output = __commonJS({
58582
58807
  return this;
58583
58808
  } else {
58584
58809
  if (this._isStreamInput()) {
58585
- return new Promise((resolve26, reject) => {
58810
+ return new Promise((resolve27, reject) => {
58586
58811
  this.once("finish", () => {
58587
58812
  this._flattenBufferIn();
58588
58813
  sharp.pipeline(this.options, (err, data, info2) => {
@@ -58590,24 +58815,24 @@ var require_output = __commonJS({
58590
58815
  reject(is.nativeError(err, stack));
58591
58816
  } else {
58592
58817
  if (this.options.resolveWithObject) {
58593
- resolve26({ data, info: info2 });
58818
+ resolve27({ data, info: info2 });
58594
58819
  } else {
58595
- resolve26(data);
58820
+ resolve27(data);
58596
58821
  }
58597
58822
  }
58598
58823
  });
58599
58824
  });
58600
58825
  });
58601
58826
  } else {
58602
- return new Promise((resolve26, reject) => {
58827
+ return new Promise((resolve27, reject) => {
58603
58828
  sharp.pipeline(this.options, (err, data, info2) => {
58604
58829
  if (err) {
58605
58830
  reject(is.nativeError(err, stack));
58606
58831
  } else {
58607
58832
  if (this.options.resolveWithObject) {
58608
- resolve26({ data, info: info2 });
58833
+ resolve27({ data, info: info2 });
58609
58834
  } else {
58610
- resolve26(data);
58835
+ resolve27(data);
58611
58836
  }
58612
58837
  }
58613
58838
  });
@@ -60296,11 +60521,138 @@ var init_ensure_cli = __esm({
60296
60521
  }
60297
60522
  });
60298
60523
 
60524
+ // src/server/desktop.ts
60525
+ function isDesktop() {
60526
+ return process.env.DREAMCONTEXT_DESKTOP === "1";
60527
+ }
60528
+ var init_desktop = __esm({
60529
+ "src/server/desktop.ts"() {
60530
+ "use strict";
60531
+ }
60532
+ });
60533
+
60534
+ // src/lib/git-sync/github-browse.ts
60535
+ import { existsSync as existsSync89, statSync as statSync19 } from "fs";
60536
+ import { isAbsolute as isAbsolute4, join as join85, resolve as resolve22, sep as sep16 } from "path";
60537
+ function resolveLauncherGitHubToken(home) {
60538
+ const global3 = readGlobalGitHubToken(home);
60539
+ if (global3) return global3;
60540
+ for (const envVar of ["GITHUB_TOKEN", "GH_TOKEN"]) {
60541
+ const v = process.env[envVar];
60542
+ if (v && v.trim()) return { token: v.trim(), source: "env", via: envVar };
60543
+ }
60544
+ return null;
60545
+ }
60546
+ function toSummary(r) {
60547
+ return {
60548
+ fullName: r.full_name,
60549
+ private: r.private,
60550
+ description: r.description ?? null,
60551
+ defaultBranch: r.default_branch,
60552
+ pushedAt: r.pushed_at
60553
+ };
60554
+ }
60555
+ function defaultAdapter(token) {
60556
+ return new ApiAdapter({
60557
+ baseUrl: "https://api.github.com",
60558
+ authHeaders: () => ({ Authorization: `token ${token}` })
60559
+ });
60560
+ }
60561
+ async function listGitHubRepos(opts) {
60562
+ const api = opts.adapter ?? defaultAdapter(opts.token);
60563
+ const q = (opts.query ?? "").trim().toLowerCase();
60564
+ const all = [];
60565
+ for (let page = 1; page <= REPOS_MAX_PAGES; page++) {
60566
+ const batch = await api.request("GET", "/user/repos", {
60567
+ query: {
60568
+ sort: "pushed",
60569
+ per_page: REPOS_PER_PAGE,
60570
+ page,
60571
+ affiliation: "owner,collaborator,organization_member"
60572
+ }
60573
+ });
60574
+ all.push(...batch ?? []);
60575
+ if (!batch || batch.length < REPOS_PER_PAGE) break;
60576
+ }
60577
+ let results = q ? all.filter((r) => r.full_name.toLowerCase().includes(q)) : all;
60578
+ if (q.includes("/")) {
60579
+ const slug = parseRepoSlug(q);
60580
+ const already = slug && results.some(
60581
+ (r) => r.full_name.toLowerCase() === `${slug.owner}/${slug.repo}`.toLowerCase()
60582
+ );
60583
+ if (slug && !already) {
60584
+ try {
60585
+ const direct = await api.request("GET", `/repos/${slug.owner}/${slug.repo}`);
60586
+ if (direct) results = [direct, ...results];
60587
+ } catch (err) {
60588
+ if (!(err instanceof ApiError && err.kind === "not_found")) throw err;
60589
+ }
60590
+ }
60591
+ }
60592
+ return results.slice(0, REPOS_MAX_RESULTS).map(toSummary);
60593
+ }
60594
+ function planGitHubClone(url, parentDir) {
60595
+ const cloneUrl = canonicalRemote(url);
60596
+ if (!cloneUrl) {
60597
+ throw new GitSyncError(
60598
+ "That does not look like a GitHub repo URL (expected https://github.com/owner/repo or owner/repo)."
60599
+ );
60600
+ }
60601
+ const parentRaw = (parentDir ?? "").trim();
60602
+ if (!parentRaw || !isAbsolute4(parentRaw)) {
60603
+ throw new GitSyncError("parentDir must be an absolute path.");
60604
+ }
60605
+ const parent = resolve22(parentRaw);
60606
+ if (!existsSync89(parent) || !statSync19(parent).isDirectory()) {
60607
+ throw new GitSyncError(`Parent directory does not exist: ${parent}`);
60608
+ }
60609
+ const slug = parseRepoSlug(cloneUrl);
60610
+ const base = sanitizeRepoName(slug.repo);
60611
+ if (!base) throw new GitSyncError("Could not derive a safe folder name from that repo.");
60612
+ const dest = resolve22(parent, base);
60613
+ if (dest !== join85(parent, base) || !dest.startsWith(parent + sep16)) {
60614
+ throw new GitSyncError("Resolved clone path escapes the parent directory.");
60615
+ }
60616
+ if (existsSync89(dest)) {
60617
+ throw new GitSyncError(`A folder already exists at ${dest}. Move it or pick another location.`);
60618
+ }
60619
+ return { cloneUrl, dest, name: base };
60620
+ }
60621
+ async function cloneGitHubRepo(opts) {
60622
+ const gitModule = opts.gitModule ?? git_exports;
60623
+ const plan = planGitHubClone(opts.url, opts.parentDir);
60624
+ await withGitCredentials(opts.token, (env2) => {
60625
+ const handle = gitModule.cloneStreaming(plan.cloneUrl, plan.dest, env2, opts.onProgress);
60626
+ opts.registerCancel?.(handle.cancel);
60627
+ return handle.promise;
60628
+ });
60629
+ return {
60630
+ path: plan.dest,
60631
+ name: plan.name,
60632
+ hasContext: existsSync89(join85(plan.dest, "_dream_context"))
60633
+ };
60634
+ }
60635
+ var REPOS_PER_PAGE, REPOS_MAX_PAGES, REPOS_MAX_RESULTS;
60636
+ var init_github_browse = __esm({
60637
+ "src/lib/git-sync/github-browse.ts"() {
60638
+ "use strict";
60639
+ init_api_adapter();
60640
+ init_auth_store();
60641
+ init_origin_setup();
60642
+ init_credentials();
60643
+ init_git();
60644
+ init_git();
60645
+ REPOS_PER_PAGE = 100;
60646
+ REPOS_MAX_PAGES = 3;
60647
+ REPOS_MAX_RESULTS = 50;
60648
+ }
60649
+ });
60650
+
60299
60651
  // src/server/routes/launcher.ts
60300
- import { basename as basename28, isAbsolute as isAbsolute4, join as join85, resolve as resolve22, sep as sep16 } from "path";
60301
- import { existsSync as existsSync89, mkdirSync as mkdirSync44, readdirSync as readdirSync19, statSync as statSync19, createReadStream, readFileSync as readFileSync62, writeFileSync as writeFileSync50 } from "fs";
60652
+ import { basename as basename28, isAbsolute as isAbsolute5, join as join86, resolve as resolve23, sep as sep17 } from "path";
60653
+ import { existsSync as existsSync90, mkdirSync as mkdirSync44, readdirSync as readdirSync19, statSync as statSync20, createReadStream, readFileSync as readFileSync62, writeFileSync as writeFileSync50, rmSync as rmSync9 } from "fs";
60302
60654
  import { homedir as homedir7 } from "os";
60303
- import { execFile as execFile2, spawn as spawn4 } from "child_process";
60655
+ import { execFile as execFile2, spawn as spawn5 } from "child_process";
60304
60656
  import { promisify as promisify2 } from "util";
60305
60657
  import { randomUUID as randomUUID4 } from "crypto";
60306
60658
  function pruneCaptureRuns() {
@@ -60317,21 +60669,21 @@ function pruneCaptureRuns() {
60317
60669
  async function handleLauncherDiscover(req, res, _params, _contextRoot) {
60318
60670
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
60319
60671
  const root = url.searchParams.get("root");
60320
- if (!root || !isAbsolute4(root)) {
60672
+ if (!root || !isAbsolute5(root)) {
60321
60673
  sendError(res, 400, "invalid_root", "root must be an absolute path.");
60322
60674
  return;
60323
60675
  }
60324
- const resolvedRoot = resolve22(root);
60325
- if (!existsSync89(resolvedRoot)) {
60676
+ const resolvedRoot = resolve23(root);
60677
+ if (!existsSync90(resolvedRoot)) {
60326
60678
  sendError(res, 400, "invalid_root", `Path does not exist: ${resolvedRoot}`);
60327
60679
  return;
60328
60680
  }
60329
- const registeredPaths = new Set(listVaults().map((v) => resolve22(v.path)));
60681
+ const registeredPaths = new Set(listVaults().map((v) => resolve23(v.path)));
60330
60682
  const discovered = await discoverVaultsAsync(resolvedRoot);
60331
60683
  const projects = discovered.map((path2) => ({
60332
60684
  name: basename28(path2),
60333
60685
  path: path2,
60334
- registered: registeredPaths.has(resolve22(path2))
60686
+ registered: registeredPaths.has(resolve23(path2))
60335
60687
  }));
60336
60688
  sendJson(res, 200, { projects });
60337
60689
  }
@@ -60365,7 +60717,7 @@ async function handleLauncherRegister(req, res, _params, _contextRoot) {
60365
60717
  }
60366
60718
  function isNonEmptyDir(dir) {
60367
60719
  try {
60368
- return statSync19(dir).isDirectory() && readdirSync19(dir).length > 0;
60720
+ return statSync20(dir).isDirectory() && readdirSync19(dir).length > 0;
60369
60721
  } catch {
60370
60722
  return false;
60371
60723
  }
@@ -60386,34 +60738,34 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
60386
60738
  throw new ScaffoldError("Project name is invalid.");
60387
60739
  }
60388
60740
  const parentDir = (a.parentDir ?? "").trim();
60389
- if (!parentDir || !isAbsolute4(parentDir)) {
60741
+ if (!parentDir || !isAbsolute5(parentDir)) {
60390
60742
  throw new ScaffoldError("parentDir must be an absolute path.");
60391
60743
  }
60392
- const resolvedParent = resolve22(parentDir);
60393
- if (!existsSync89(resolvedParent) || !statSync19(resolvedParent).isDirectory()) {
60744
+ const resolvedParent = resolve23(parentDir);
60745
+ if (!existsSync90(resolvedParent) || !statSync20(resolvedParent).isDirectory()) {
60394
60746
  throw new ScaffoldError(`Parent directory does not exist: ${resolvedParent}`);
60395
60747
  }
60396
- target = resolve22(resolvedParent, name);
60397
- if (target !== join85(resolvedParent, name) || !target.startsWith(resolvedParent + sep16)) {
60748
+ target = resolve23(resolvedParent, name);
60749
+ if (target !== join86(resolvedParent, name) || !target.startsWith(resolvedParent + sep17)) {
60398
60750
  throw new ScaffoldError("Resolved project path escapes the parent directory.");
60399
60751
  }
60400
- if (isNonEmptyDir(target) && !existsSync89(join85(target, "_dream_context"))) {
60752
+ if (isNonEmptyDir(target) && !existsSync90(join86(target, "_dream_context"))) {
60401
60753
  throw new ScaffoldError(`A non-empty folder already exists at ${target}.`);
60402
60754
  }
60403
60755
  mkdirSync44(target, { recursive: true });
60404
60756
  } else if (a.mode === "existing") {
60405
60757
  const projectPath = (a.projectPath ?? "").trim();
60406
- if (!projectPath || !isAbsolute4(projectPath)) {
60758
+ if (!projectPath || !isAbsolute5(projectPath)) {
60407
60759
  throw new ScaffoldError("projectPath must be an absolute path.");
60408
60760
  }
60409
- target = resolve22(projectPath);
60410
- if (!existsSync89(target) || !statSync19(target).isDirectory()) {
60761
+ target = resolve23(projectPath);
60762
+ if (!existsSync90(target) || !statSync20(target).isDirectory()) {
60411
60763
  throw new ScaffoldError(`Folder does not exist: ${target}`);
60412
60764
  }
60413
60765
  } else {
60414
60766
  throw new ScaffoldError("mode must be 'new' or 'existing'.");
60415
60767
  }
60416
- const alreadyProject = existsSync89(join85(target, "_dream_context"));
60768
+ const alreadyProject = existsSync90(join86(target, "_dream_context"));
60417
60769
  if (!alreadyProject) {
60418
60770
  const initArgs = ["init", "--yes", "--platforms", platformArg, "--name", name];
60419
60771
  if (a.description?.trim()) initArgs.push("--description", a.description.trim());
@@ -60463,18 +60815,18 @@ async function handleLauncherScaffold(req, res, _params, _contextRoot) {
60463
60815
  async function handleLauncherDetect(req, res, _params, _contextRoot) {
60464
60816
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
60465
60817
  const path2 = url.searchParams.get("path");
60466
- if (!path2 || !isAbsolute4(path2)) {
60818
+ if (!path2 || !isAbsolute5(path2)) {
60467
60819
  sendError(res, 400, "invalid_path", "path must be an absolute path.");
60468
60820
  return;
60469
60821
  }
60470
- const resolved = resolve22(path2);
60471
- if (!existsSync89(resolved)) {
60822
+ const resolved = resolve23(path2);
60823
+ if (!existsSync90(resolved)) {
60472
60824
  sendError(res, 400, "invalid_path", `Path does not exist: ${resolved}`);
60473
60825
  return;
60474
60826
  }
60475
60827
  sendJson(res, 200, {
60476
60828
  stack: detectTechStack(resolved) ?? "",
60477
- hasContext: existsSync89(join85(resolved, "_dream_context")),
60829
+ hasContext: existsSync90(join86(resolved, "_dream_context")),
60478
60830
  name: basename28(resolved)
60479
60831
  });
60480
60832
  }
@@ -60493,15 +60845,202 @@ async function handleLauncherCatalog(_req, res, _params, _contextRoot) {
60493
60845
  }));
60494
60846
  sendJson(res, 200, { platforms, packs });
60495
60847
  }
60848
+ function desktopGate(res) {
60849
+ if (!isDesktop()) {
60850
+ sendError(res, 403, "desktop_only", "Clone from GitHub is only available in the desktop app.");
60851
+ return false;
60852
+ }
60853
+ return true;
60854
+ }
60855
+ async function handleLauncherGithubRepos(req, res, _params, _contextRoot) {
60856
+ if (!desktopGate(res)) return;
60857
+ const token = resolveLauncherGitHubToken();
60858
+ if (!token) {
60859
+ sendError(res, 401, "no_token", "Sign in with GitHub to browse your repositories.");
60860
+ return;
60861
+ }
60862
+ const url = new URL(req.url || "/", `http://${req.headers.host}`);
60863
+ const query = url.searchParams.get("q") ?? "";
60864
+ try {
60865
+ const repos = await listGitHubRepos({ token: token.token, query });
60866
+ sendJson(res, 200, { repos });
60867
+ } catch (err) {
60868
+ if (err instanceof ApiError && err.kind === "auth") {
60869
+ sendError(res, 401, "bad_token", "GitHub rejected the stored sign-in. Reconnect your account.");
60870
+ return;
60871
+ }
60872
+ console.error("[launcher] github repos failed:", err);
60873
+ const detail = err instanceof Error ? err.message : "unknown error";
60874
+ sendError(res, 502, "github_error", `Could not list repositories: ${detail}`);
60875
+ }
60876
+ }
60877
+ function pruneCloneRuns() {
60878
+ const now = Date.now();
60879
+ for (const [id, run3] of cloneRuns) {
60880
+ if (run3.endedAt && now - run3.endedAt > CLONE_RUN_TTL_MS) cloneRuns.delete(id);
60881
+ }
60882
+ if (cloneRuns.size <= CLONE_RUNS_MAX) return;
60883
+ for (const [id, run3] of cloneRuns) {
60884
+ if (cloneRuns.size <= CLONE_RUNS_MAX) break;
60885
+ if (run3.state !== "running") cloneRuns.delete(id);
60886
+ }
60887
+ }
60888
+ function registerClonedVault(name, path2) {
60889
+ let lastErr;
60890
+ for (const candidate of [name, ...[2, 3, 4, 5, 6, 7, 8, 9].map((n) => `${name}-${n}`)]) {
60891
+ try {
60892
+ addVault(candidate, path2);
60893
+ return candidate;
60894
+ } catch (err) {
60895
+ lastErr = err;
60896
+ if (!(err instanceof VaultError && /named .* already registered/i.test(err.message))) break;
60897
+ }
60898
+ }
60899
+ throw lastErr instanceof Error ? lastErr : new Error("Could not register the cloned project.");
60900
+ }
60901
+ async function handleLauncherClone(req, res, _params, _contextRoot) {
60902
+ if (!desktopGate(res)) return;
60903
+ const body = await parseJsonBody(req);
60904
+ if (!body) {
60905
+ sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
60906
+ return;
60907
+ }
60908
+ const repoUrl = typeof body.url === "string" ? body.url.trim() : "";
60909
+ const parentDir = typeof body.parentDir === "string" ? body.parentDir.trim() : "";
60910
+ if (!repoUrl || !parentDir) {
60911
+ sendError(res, 400, "invalid_body", "url and parentDir must be non-empty strings.");
60912
+ return;
60913
+ }
60914
+ const token = resolveLauncherGitHubToken();
60915
+ if (!token) {
60916
+ sendError(res, 401, "no_token", "Sign in with GitHub before cloning a repository.");
60917
+ return;
60918
+ }
60919
+ let dest;
60920
+ try {
60921
+ dest = planGitHubClone(repoUrl, parentDir).dest;
60922
+ } catch (err) {
60923
+ if (err instanceof GitSyncError) {
60924
+ sendError(res, 400, "clone_failed", err.message);
60925
+ return;
60926
+ }
60927
+ throw err;
60928
+ }
60929
+ const inFlightId = cloneDestsInFlight.get(dest);
60930
+ if (inFlightId && cloneRuns.get(inFlightId)?.state === "running") {
60931
+ sendError(res, 409, "clone_in_progress", "A clone into that folder is already running.");
60932
+ return;
60933
+ }
60934
+ pruneCloneRuns();
60935
+ const cloneId = randomUUID4();
60936
+ const run3 = { state: "running", progress: "", startedAt: Date.now() };
60937
+ cloneRuns.set(cloneId, run3);
60938
+ cloneDestsInFlight.set(dest, cloneId);
60939
+ const releaseDest = () => {
60940
+ if (cloneDestsInFlight.get(dest) === cloneId) cloneDestsInFlight.delete(dest);
60941
+ };
60942
+ void (async () => {
60943
+ let clonedPath;
60944
+ try {
60945
+ const cloned = await cloneGitHubRepo({
60946
+ url: repoUrl,
60947
+ parentDir,
60948
+ token: token.token,
60949
+ // git writes progress with \r-updated lines; normalize so the UI can
60950
+ // simply split on newlines and show the tail.
60951
+ onProgress: (chunk) => {
60952
+ run3.progress = (run3.progress + chunk.replace(/\r/g, "\n")).slice(-4e3);
60953
+ },
60954
+ registerCancel: (cancel) => {
60955
+ run3.cancel = cancel;
60956
+ }
60957
+ });
60958
+ clonedPath = cloned.path;
60959
+ const result = { ...cloned };
60960
+ if (cloned.hasContext) {
60961
+ result.vaultName = registerClonedVault(cloned.name, cloned.path);
60962
+ result.cli = await ensureCliInstalled();
60963
+ }
60964
+ if (run3.canceled) {
60965
+ if (result.vaultName) {
60966
+ try {
60967
+ removeVault(result.vaultName);
60968
+ } catch {
60969
+ }
60970
+ }
60971
+ try {
60972
+ rmSync9(cloned.path, { recursive: true, force: true });
60973
+ } catch {
60974
+ }
60975
+ run3.state = "error";
60976
+ run3.error = "Clone canceled.";
60977
+ return;
60978
+ }
60979
+ run3.result = result;
60980
+ run3.state = "done";
60981
+ } catch (err) {
60982
+ if (run3.canceled && clonedPath) {
60983
+ try {
60984
+ rmSync9(clonedPath, { recursive: true, force: true });
60985
+ } catch {
60986
+ }
60987
+ }
60988
+ run3.state = "error";
60989
+ run3.error = run3.canceled ? "Clone canceled." : err instanceof Error ? err.message : "Failed to clone the repository.";
60990
+ if (!run3.canceled) console.error("[launcher] clone failed:", err);
60991
+ } finally {
60992
+ run3.cancel = void 0;
60993
+ run3.endedAt = Date.now();
60994
+ releaseDest();
60995
+ }
60996
+ })();
60997
+ sendJson(res, 200, { ok: true, cloneId });
60998
+ }
60999
+ async function handleLauncherCloneStatus(req, res, _params, _contextRoot) {
61000
+ if (!desktopGate(res)) return;
61001
+ const url = new URL(req.url || "/", `http://${req.headers.host}`);
61002
+ const id = url.searchParams.get("id") ?? "";
61003
+ const run3 = id ? cloneRuns.get(id) : void 0;
61004
+ if (!run3) {
61005
+ sendJson(res, 200, { state: "unknown", progress: "" });
61006
+ return;
61007
+ }
61008
+ sendJson(res, 200, {
61009
+ state: run3.state,
61010
+ progress: run3.progress.trim(),
61011
+ result: run3.result,
61012
+ error: run3.error
61013
+ });
61014
+ }
61015
+ async function handleLauncherCloneCancel(req, res, _params, _contextRoot) {
61016
+ if (!desktopGate(res)) return;
61017
+ const body = await parseJsonBody(req);
61018
+ const id = typeof body?.id === "string" ? body.id : "";
61019
+ if (!id) {
61020
+ sendError(res, 400, "invalid_body", "id is required.");
61021
+ return;
61022
+ }
61023
+ const run3 = cloneRuns.get(id);
61024
+ if (!run3 || run3.state !== "running" || !run3.cancel) {
61025
+ sendJson(res, 200, { ok: true, canceled: false });
61026
+ return;
61027
+ }
61028
+ run3.canceled = true;
61029
+ try {
61030
+ run3.cancel();
61031
+ } catch {
61032
+ }
61033
+ sendJson(res, 200, { ok: true, canceled: true });
61034
+ }
60496
61035
  function sleepyConfigPath() {
60497
- return join85(homedir7(), ".dreamcontext", "sleepy.json");
61036
+ return join86(homedir7(), ".dreamcontext", "sleepy.json");
60498
61037
  }
60499
61038
  async function handleSleepyConfigGet(_req, res, _params, _contextRoot) {
60500
61039
  let enabled = false;
60501
61040
  let hotkey = "Alt+Cmd+S";
60502
61041
  try {
60503
61042
  const p = sleepyConfigPath();
60504
- if (existsSync89(p)) {
61043
+ if (existsSync90(p)) {
60505
61044
  const raw = JSON.parse(readFileSync62(p, "utf-8"));
60506
61045
  enabled = raw.enabled === true;
60507
61046
  if (typeof raw.hotkey === "string" && raw.hotkey.trim()) hotkey = raw.hotkey;
@@ -60520,7 +61059,7 @@ async function handleSleepyConfigSet(req, res, _params, _contextRoot) {
60520
61059
  const hotkey = typeof body.hotkey === "string" && body.hotkey.trim() ? body.hotkey.trim() : "Alt+Cmd+S";
60521
61060
  try {
60522
61061
  const p = sleepyConfigPath();
60523
- mkdirSync44(join85(homedir7(), ".dreamcontext"), { recursive: true });
61062
+ mkdirSync44(join86(homedir7(), ".dreamcontext"), { recursive: true });
60524
61063
  writeFileSync50(p, JSON.stringify({ enabled, hotkey }, null, 2) + "\n", "utf-8");
60525
61064
  sendJson(res, 200, { enabled, hotkey });
60526
61065
  } catch (err) {
@@ -60529,7 +61068,7 @@ async function handleSleepyConfigSet(req, res, _params, _contextRoot) {
60529
61068
  }
60530
61069
  }
60531
61070
  function agentSettingsPath() {
60532
- return join85(homedir7(), ".dreamcontext", "agent-ui.json");
61071
+ return join86(homedir7(), ".dreamcontext", "agent-ui.json");
60533
61072
  }
60534
61073
  function coerceAgentSettings(raw) {
60535
61074
  return {
@@ -60547,7 +61086,7 @@ async function handleAgentSettingsGet(_req, res, _params, _contextRoot) {
60547
61086
  let settings = { ...AGENT_UI_DEFAULTS };
60548
61087
  try {
60549
61088
  const p = agentSettingsPath();
60550
- if (existsSync89(p)) {
61089
+ if (existsSync90(p)) {
60551
61090
  settings = coerceAgentSettings(JSON.parse(readFileSync62(p, "utf-8")));
60552
61091
  }
60553
61092
  } catch {
@@ -60562,7 +61101,7 @@ async function handleAgentSettingsSet(req, res, _params, _contextRoot) {
60562
61101
  }
60563
61102
  const settings = coerceAgentSettings(body);
60564
61103
  try {
60565
- mkdirSync44(join85(homedir7(), ".dreamcontext"), { recursive: true });
61104
+ mkdirSync44(join86(homedir7(), ".dreamcontext"), { recursive: true });
60566
61105
  writeFileSync50(agentSettingsPath(), JSON.stringify(settings, null, 2) + "\n", "utf-8");
60567
61106
  sendJson(res, 200, settings);
60568
61107
  } catch (err) {
@@ -60583,13 +61122,13 @@ async function handleSleepyVideo(req, res, _params, _contextRoot) {
60583
61122
  res.end();
60584
61123
  return;
60585
61124
  }
60586
- const file = join85(dir, `${mode}.mp4`);
60587
- if (!existsSync89(file)) {
61125
+ const file = join86(dir, `${mode}.mp4`);
61126
+ if (!existsSync90(file)) {
60588
61127
  res.writeHead(404);
60589
61128
  res.end();
60590
61129
  return;
60591
61130
  }
60592
- const size = statSync19(file).size;
61131
+ const size = statSync20(file).size;
60593
61132
  const range = req.headers.range;
60594
61133
  if (range) {
60595
61134
  const m = /bytes=(\d+)-(\d*)/.exec(range);
@@ -60615,13 +61154,13 @@ async function handleSleepyAnim(req, res, _params, _contextRoot) {
60615
61154
  return;
60616
61155
  }
60617
61156
  const dir = process.env.DREAMCONTEXT_SLEEPY_DIR;
60618
- const file = dir ? join85(dir, `${mode}.webp`) : "";
60619
- if (!file || !existsSync89(file)) {
61157
+ const file = dir ? join86(dir, `${mode}.webp`) : "";
61158
+ if (!file || !existsSync90(file)) {
60620
61159
  res.writeHead(404);
60621
61160
  res.end();
60622
61161
  return;
60623
61162
  }
60624
- const size = statSync19(file).size;
61163
+ const size = statSync20(file).size;
60625
61164
  res.writeHead(200, {
60626
61165
  "Content-Type": "image/webp",
60627
61166
  "Content-Length": size,
@@ -60667,15 +61206,15 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
60667
61206
  sendError(res, 400, "unknown_vault", `No registered vault named "${vaultName}".`);
60668
61207
  return;
60669
61208
  }
60670
- const cwd = resolve22(vault.path);
60671
- if (!existsSync89(cwd)) {
61209
+ const cwd = resolve23(vault.path);
61210
+ if (!existsSync90(cwd)) {
60672
61211
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${cwd}`);
60673
61212
  return;
60674
61213
  }
60675
61214
  if (mode === "learn") {
60676
61215
  try {
60677
- const changelogPath = join85(cwd, "_dream_context", "core", "CHANGELOG.json");
60678
- if (!existsSync89(changelogPath)) {
61216
+ const changelogPath = join86(cwd, "_dream_context", "core", "CHANGELOG.json");
61217
+ if (!existsSync90(changelogPath)) {
60679
61218
  sendError(res, 400, "not_initialized", `"${vaultName}" has no _dream_context \u2014 run init first.`);
60680
61219
  return;
60681
61220
  }
@@ -60745,7 +61284,7 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
60745
61284
  }
60746
61285
  }
60747
61286
  const prompt = mode === "sleep" ? buildSleepPrompt(sleepDepth) : mode === "ask" ? buildAskPrompt(text) : buildCapturePrompt(text);
60748
- const child = spawn4(shell, ["-ilc", 'exec claude --model sonnet -p "$0"', prompt], {
61287
+ const child = spawn5(shell, ["-ilc", 'exec claude --model sonnet -p "$0"', prompt], {
60749
61288
  cwd,
60750
61289
  stdio: ["ignore", "pipe", "pipe"]
60751
61290
  });
@@ -60792,15 +61331,15 @@ async function handleLauncherCaptureStatus(req, res, _params, _contextRoot) {
60792
61331
  }
60793
61332
  async function handleLauncherDefaults(_req, res, _params, _contextRoot) {
60794
61333
  const home = homedir7();
60795
- sendJson(res, 200, { home, defaultParent: join85(home, "projects") });
61334
+ sendJson(res, 200, { home, defaultParent: join86(home, "projects") });
60796
61335
  }
60797
61336
  function computeVaultStatus(v, latest) {
60798
- const exists = existsSync89(resolve22(v.path));
61337
+ const exists = existsSync90(resolve23(v.path));
60799
61338
  let setupVersion = "0.0.0";
60800
61339
  let shareable = false;
60801
61340
  if (exists) {
60802
61341
  try {
60803
- const cfg = readSetupConfig(resolve22(v.path));
61342
+ const cfg = readSetupConfig(resolve23(v.path));
60804
61343
  if (cfg) {
60805
61344
  setupVersion = cfg.setupVersion || "0.0.0";
60806
61345
  shareable = cfg.shareable === true;
@@ -60846,8 +61385,8 @@ async function handleLauncherUpdate(req, res, _params, _contextRoot) {
60846
61385
  sendError(res, 400, "unknown_vault", `No registered vault named "${name}".`);
60847
61386
  return;
60848
61387
  }
60849
- const target = resolve22(vault.path);
60850
- if (!existsSync89(target)) {
61388
+ const target = resolve23(vault.path);
61389
+ if (!existsSync90(target)) {
60851
61390
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${target}`);
60852
61391
  return;
60853
61392
  }
@@ -60875,7 +61414,7 @@ async function handleLauncherUpgrade(_req, res, _params, _contextRoot) {
60875
61414
  upgradeRun = run3;
60876
61415
  try {
60877
61416
  const shell = process.env.SHELL || "/bin/zsh";
60878
- const child = spawn4(
61417
+ const child = spawn5(
60879
61418
  shell,
60880
61419
  ["-ilc", 'exec "$0" "$1" upgrade --yes', process.execPath, cliEntry],
60881
61420
  { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env } }
@@ -60926,7 +61465,7 @@ async function handleLauncherUpgradeStatus(_req, res, _params, _contextRoot) {
60926
61465
  async function handleLauncherRelaunch(_req, res, _params, _contextRoot) {
60927
61466
  const manifest = readAppManifest();
60928
61467
  const appPath = manifest?.path;
60929
- if (!appPath || !existsSync89(appPath)) {
61468
+ if (!appPath || !existsSync90(appPath)) {
60930
61469
  sendJson(res, 200, { ok: false, reason: "app_not_installed" });
60931
61470
  return;
60932
61471
  }
@@ -60936,7 +61475,7 @@ async function handleLauncherRelaunch(_req, res, _params, _contextRoot) {
60936
61475
  return;
60937
61476
  }
60938
61477
  try {
60939
- const child = spawn4("/bin/sh", ["-c", 'sleep 2; open "$0"', appPath], {
61478
+ const child = spawn5("/bin/sh", ["-c", 'sleep 2; open "$0"', appPath], {
60940
61479
  detached: true,
60941
61480
  stdio: "ignore"
60942
61481
  });
@@ -60959,8 +61498,8 @@ async function handleLauncherFederationGraph(_req, res, _params, _contextRoot) {
60959
61498
  const connections = [];
60960
61499
  const seen = /* @__PURE__ */ new Set();
60961
61500
  for (const v of vaults) {
60962
- if (!existsSync89(resolve22(v.path))) continue;
60963
- const conns = listConnections(join85(resolve22(v.path), "_dream_context"));
61501
+ if (!existsSync90(resolve23(v.path))) continue;
61502
+ const conns = listConnections(join86(resolve23(v.path), "_dream_context"));
60964
61503
  for (const c of conns) {
60965
61504
  if (!known.has(c.vault)) continue;
60966
61505
  if (c.status === "stale") continue;
@@ -60991,7 +61530,7 @@ async function handleLauncherConnectionCreate(req, res, _params, _contextRoot) {
60991
61530
  sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
60992
61531
  return;
60993
61532
  }
60994
- const fromRoot = join85(resolve22(fromVault.path), "_dream_context");
61533
+ const fromRoot = join86(resolve23(fromVault.path), "_dream_context");
60995
61534
  try {
60996
61535
  const cur = dirToward(fromRoot, to);
60997
61536
  addConnection(fromRoot, from, to, addOut(cur?.dir ?? null), cur?.topics ?? null);
@@ -61022,7 +61561,7 @@ async function handleLauncherConnectionRemove(req, res, _params, _contextRoot) {
61022
61561
  sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
61023
61562
  return;
61024
61563
  }
61025
- const fromRoot = join85(resolve22(fromVault.path), "_dream_context");
61564
+ const fromRoot = join86(resolve23(fromVault.path), "_dream_context");
61026
61565
  const a = dirToward(fromRoot, to);
61027
61566
  if (a) applyDir(fromRoot, from, to, dropOut(a.dir), a.topics);
61028
61567
  const toRoot = vaultRoot(to);
@@ -61038,7 +61577,7 @@ function dirToward(root, peer) {
61038
61577
  }
61039
61578
  function vaultRoot(name) {
61040
61579
  const v = listVaults().find((x) => x.name === name);
61041
- return v ? join85(resolve22(v.path), "_dream_context") : null;
61580
+ return v ? join86(resolve23(v.path), "_dream_context") : null;
61042
61581
  }
61043
61582
  function applyDir(fromRoot, fromName, peer, next, topics) {
61044
61583
  if (next === null) removeConnection(fromRoot, peer);
@@ -61117,8 +61656,8 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
61117
61656
  sendError(res, 400, "unknown_vault", `No registered vault named "${name}".`);
61118
61657
  return;
61119
61658
  }
61120
- const root = resolve22(vault.path);
61121
- if (!existsSync89(root)) {
61659
+ const root = resolve23(vault.path);
61660
+ if (!existsSync90(root)) {
61122
61661
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${root}`);
61123
61662
  return;
61124
61663
  }
@@ -61130,7 +61669,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
61130
61669
  sendError(res, 500, "shareable_failed", "Failed to update sharing.");
61131
61670
  }
61132
61671
  }
61133
- var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, sleepJobsInFlight, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, AGENT_UI_DEFAULTS, SLEEPY_MODES, upgradeRun, UPGRADE_MAX_MS, lastRelaunchArmedAt, RELAUNCH_ARM_TTL_MS, addOut, addIn, dropOut, dropIn;
61672
+ var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, sleepJobsInFlight, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, cloneRuns, CLONE_RUN_TTL_MS, CLONE_RUNS_MAX, cloneDestsInFlight, AGENT_UI_DEFAULTS, SLEEPY_MODES, upgradeRun, UPGRADE_MAX_MS, lastRelaunchArmedAt, RELAUNCH_ARM_TTL_MS, addOut, addIn, dropOut, dropIn;
61134
61673
  var init_launcher = __esm({
61135
61674
  "src/server/routes/launcher.ts"() {
61136
61675
  "use strict";
@@ -61147,6 +61686,10 @@ var init_launcher = __esm({
61147
61686
  init_catalog();
61148
61687
  init_json_file();
61149
61688
  init_id();
61689
+ init_desktop();
61690
+ init_github_browse();
61691
+ init_git();
61692
+ init_api_adapter();
61150
61693
  init_sleep();
61151
61694
  init_app();
61152
61695
  init_sleep_consolidation();
@@ -61175,6 +61718,10 @@ var init_launcher = __esm({
61175
61718
  });
61176
61719
  };
61177
61720
  SAFE_NAME_RE = /^[^/\\]+$/;
61721
+ cloneRuns = /* @__PURE__ */ new Map();
61722
+ CLONE_RUN_TTL_MS = 10 * 60 * 1e3;
61723
+ CLONE_RUNS_MAX = 20;
61724
+ cloneDestsInFlight = /* @__PURE__ */ new Map();
61178
61725
  AGENT_UI_DEFAULTS = {
61179
61726
  enabled: true,
61180
61727
  restoreTabs: true,
@@ -61195,14 +61742,14 @@ var init_launcher = __esm({
61195
61742
  });
61196
61743
 
61197
61744
  // src/server/routes/ui-settings.ts
61198
- import { dirname as dirname52, join as join86 } from "path";
61199
- import { existsSync as existsSync90, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync51 } from "fs";
61745
+ import { dirname as dirname52, join as join87 } from "path";
61746
+ import { existsSync as existsSync91, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync51 } from "fs";
61200
61747
  function settingsPath(contextRoot) {
61201
- return join86(contextRoot, BRAIN_SETTINGS_REL_PATH);
61748
+ return join87(contextRoot, BRAIN_SETTINGS_REL_PATH);
61202
61749
  }
61203
61750
  async function handleBrainSettingsGet(_req, res, _params, contextRoot) {
61204
61751
  const path2 = settingsPath(contextRoot);
61205
- if (!existsSync90(path2)) {
61752
+ if (!existsSync91(path2)) {
61206
61753
  sendJson(res, 200, { settings: {} });
61207
61754
  return;
61208
61755
  }
@@ -61241,10 +61788,10 @@ async function handleBrainSettingsPut(req, res, _params, contextRoot) {
61241
61788
  }
61242
61789
  }
61243
61790
  function makeSettingsHandlers(relPath, logTag) {
61244
- const pathFor = (contextRoot) => join86(contextRoot, relPath);
61791
+ const pathFor = (contextRoot) => join87(contextRoot, relPath);
61245
61792
  const get = async (_req, res, _params, contextRoot) => {
61246
61793
  const path2 = pathFor(contextRoot);
61247
- if (!existsSync90(path2)) {
61794
+ if (!existsSync91(path2)) {
61248
61795
  sendJson(res, 200, { settings: {} });
61249
61796
  return;
61250
61797
  }
@@ -61534,7 +62081,7 @@ function toPublicManifest(m) {
61534
62081
  tweaks: toPublicTweaks(m)
61535
62082
  };
61536
62083
  }
61537
- function toSummary(contextRoot, m) {
62084
+ function toSummary2(contextRoot, m) {
61538
62085
  const cache = readCache(contextRoot, m.slug);
61539
62086
  let staleMinutes = null;
61540
62087
  let stale = null;
@@ -61565,7 +62112,7 @@ function toSummary(contextRoot, m) {
61565
62112
  }
61566
62113
  async function handleLabList(_req, res, _params, contextRoot) {
61567
62114
  try {
61568
- const insights = listInsights(contextRoot).map((m) => toSummary(contextRoot, m));
62115
+ const insights = listInsights(contextRoot).map((m) => toSummary2(contextRoot, m));
61569
62116
  sendJson(res, 200, { insights });
61570
62117
  } catch (err) {
61571
62118
  console.error("[lab] list failed:", err);
@@ -61732,16 +62279,16 @@ var init_lab2 = __esm({
61732
62279
  });
61733
62280
 
61734
62281
  // src/server/routes/board.ts
61735
- import { dirname as dirname54, join as join87 } from "path";
61736
- import { existsSync as existsSync91, mkdirSync as mkdirSync46, readFileSync as readFileSync64, writeFileSync as writeFileSync52 } from "fs";
62282
+ import { dirname as dirname54, join as join88 } from "path";
62283
+ import { existsSync as existsSync92, mkdirSync as mkdirSync46, readFileSync as readFileSync64, writeFileSync as writeFileSync52 } from "fs";
61737
62284
  function sharedPath(contextRoot) {
61738
- return join87(contextRoot, SHARED_REL_PATH);
62285
+ return join88(contextRoot, SHARED_REL_PATH);
61739
62286
  }
61740
62287
  function localPath(contextRoot) {
61741
- return join87(contextRoot, LOCAL_REL_PATH);
62288
+ return join88(contextRoot, LOCAL_REL_PATH);
61742
62289
  }
61743
62290
  function readBlob(path2) {
61744
- if (!existsSync91(path2)) return {};
62291
+ if (!existsSync92(path2)) return {};
61745
62292
  try {
61746
62293
  const raw = JSON.parse(readFileSync64(path2, "utf-8"));
61747
62294
  return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -61820,9 +62367,9 @@ var init_board = __esm({
61820
62367
  });
61821
62368
 
61822
62369
  // src/server/routes/sleepy-chat.ts
61823
- import { spawn as spawn5 } from "child_process";
61824
- import { dirname as dirname55, join as join88 } from "path";
61825
- import { existsSync as existsSync92, mkdirSync as mkdirSync47, readFileSync as readFileSync65, writeFileSync as writeFileSync53 } from "fs";
62370
+ import { spawn as spawn6 } from "child_process";
62371
+ import { dirname as dirname55, join as join89 } from "path";
62372
+ import { existsSync as existsSync93, mkdirSync as mkdirSync47, readFileSync as readFileSync65, writeFileSync as writeFileSync53 } from "fs";
61826
62373
  import { randomUUID as randomUUID5 } from "crypto";
61827
62374
  function modelFor(tier) {
61828
62375
  return tier === "intelligent" ? "opus" : "sonnet";
@@ -61848,7 +62395,7 @@ function emit(run3, ev) {
61848
62395
  }
61849
62396
  }
61850
62397
  function storePath(contextRoot) {
61851
- return join88(contextRoot, "state", ".sleepy-chat.json");
62398
+ return join89(contextRoot, "state", ".sleepy-chat.json");
61852
62399
  }
61853
62400
  function readStore(contextRoot) {
61854
62401
  try {
@@ -61865,8 +62412,8 @@ function readStore(contextRoot) {
61865
62412
  }
61866
62413
  function writeStore(contextRoot, store) {
61867
62414
  try {
61868
- const dir = join88(contextRoot, "state");
61869
- if (!existsSync92(dir)) mkdirSync47(dir, { recursive: true });
62415
+ const dir = join89(contextRoot, "state");
62416
+ if (!existsSync93(dir)) mkdirSync47(dir, { recursive: true });
61870
62417
  store.messages = store.messages.slice(-MESSAGES_MAX);
61871
62418
  writeFileSync53(storePath(contextRoot), JSON.stringify(store, null, 2), "utf-8");
61872
62419
  } catch (err) {
@@ -62006,7 +62553,7 @@ async function handleSleepyChatSend(req, res, _params, contextRoot) {
62006
62553
  positionals.push(resumeId);
62007
62554
  }
62008
62555
  try {
62009
- const child = spawn5(shell, ["-ilc", script, ...positionals], {
62556
+ const child = spawn6(shell, ["-ilc", script, ...positionals], {
62010
62557
  cwd: projectRootOf(contextRoot),
62011
62558
  stdio: ["ignore", "pipe", "pipe"]
62012
62559
  });
@@ -62164,16 +62711,6 @@ var init_sleepy_chat = __esm({
62164
62711
  }
62165
62712
  });
62166
62713
 
62167
- // src/server/desktop.ts
62168
- function isDesktop() {
62169
- return process.env.DREAMCONTEXT_DESKTOP === "1";
62170
- }
62171
- var init_desktop = __esm({
62172
- "src/server/desktop.ts"() {
62173
- "use strict";
62174
- }
62175
- });
62176
-
62177
62714
  // node_modules/ws/lib/constants.js
62178
62715
  var require_constants5 = __commonJS({
62179
62716
  "node_modules/ws/lib/constants.js"(exports2, module2) {
@@ -65883,24 +66420,24 @@ var init_wrapper = __esm({
65883
66420
  });
65884
66421
 
65885
66422
  // src/server/routes/agent-terminal.ts
65886
- import { spawn as spawn6 } from "child_process";
66423
+ import { spawn as spawn7 } from "child_process";
65887
66424
  import { randomUUID as randomUUID6 } from "crypto";
65888
66425
  import { createRequire as createRequire2 } from "module";
65889
- import { basename as basename29, dirname as dirname56, join as join89 } from "path";
65890
- import { existsSync as existsSync93, readdirSync as readdirSync20, statSync as statSync20, chmodSync as chmodSync6, readFileSync as readFileSync66 } from "fs";
66426
+ import { basename as basename29, dirname as dirname56, join as join90 } from "path";
66427
+ import { existsSync as existsSync94, readdirSync as readdirSync20, statSync as statSync21, chmodSync as chmodSync6, readFileSync as readFileSync66 } from "fs";
65891
66428
  import { homedir as homedir8 } from "os";
65892
66429
  function ensurePtyHelperExecutable() {
65893
66430
  try {
65894
66431
  const require2 = createRequire2(import.meta.url);
65895
66432
  const root = dirname56(dirname56(require2.resolve("node-pty")));
65896
- const candidates = [join89(root, "build", "Release", "spawn-helper")];
65897
- const prebuilds = join89(root, "prebuilds");
65898
- if (existsSync93(prebuilds)) {
65899
- for (const d of readdirSync20(prebuilds)) candidates.push(join89(prebuilds, d, "spawn-helper"));
66433
+ const candidates = [join90(root, "build", "Release", "spawn-helper")];
66434
+ const prebuilds = join90(root, "prebuilds");
66435
+ if (existsSync94(prebuilds)) {
66436
+ for (const d of readdirSync20(prebuilds)) candidates.push(join90(prebuilds, d, "spawn-helper"));
65900
66437
  }
65901
66438
  for (const p of candidates) {
65902
- if (!existsSync93(p)) continue;
65903
- const mode = statSync20(p).mode;
66439
+ if (!existsSync94(p)) continue;
66440
+ const mode = statSync21(p).mode;
65904
66441
  if ((mode & 73) !== 73) chmodSync6(p, mode | 493);
65905
66442
  }
65906
66443
  } catch {
@@ -65921,7 +66458,7 @@ function resetPtyCache() {
65921
66458
  ptyAvailable = null;
65922
66459
  }
65923
66460
  function detectOnPath(cmd, timeoutMs = 8e3) {
65924
- return new Promise((resolve26) => {
66461
+ return new Promise((resolve27) => {
65925
66462
  const shell = process.env.SHELL || "/bin/zsh";
65926
66463
  let out = "";
65927
66464
  let settled = false;
@@ -65929,10 +66466,10 @@ function detectOnPath(cmd, timeoutMs = 8e3) {
65929
66466
  if (!settled) {
65930
66467
  settled = true;
65931
66468
  clearTimeout(timer);
65932
- resolve26(v);
66469
+ resolve27(v);
65933
66470
  }
65934
66471
  };
65935
- const child = spawn6(shell, ["-ilc", `command -v ${cmd}`], { stdio: ["ignore", "pipe", "ignore"] });
66472
+ const child = spawn7(shell, ["-ilc", `command -v ${cmd}`], { stdio: ["ignore", "pipe", "ignore"] });
65936
66473
  const timer = setTimeout(() => {
65937
66474
  try {
65938
66475
  child.kill();
@@ -65954,7 +66491,7 @@ function resolveVaultProjectRoot(name) {
65954
66491
  if (!name) return null;
65955
66492
  if (/[/\\:.\x00]/.test(name)) return null;
65956
66493
  const v = listVaults().find((x) => x.name === name);
65957
- if (!v || !existsSync93(v.path)) return null;
66494
+ if (!v || !existsSync94(v.path)) return null;
65958
66495
  return v.path;
65959
66496
  }
65960
66497
  async function handleAgentCapabilities(_req, res) {
@@ -66003,7 +66540,7 @@ async function handleOpenTerminal(req, res, _params, contextRoot) {
66003
66540
  do script "${escapeForAppleScript(shellCmd)}"
66004
66541
  end tell`;
66005
66542
  try {
66006
- const child = spawn6("osascript", ["-e", appleScript], { stdio: "ignore" });
66543
+ const child = spawn7("osascript", ["-e", appleScript], { stdio: "ignore" });
66007
66544
  child.on("error", () => {
66008
66545
  });
66009
66546
  sendJson(res, 200, { ok: true, bypass });
@@ -66026,7 +66563,7 @@ function cliPackageRoot() {
66026
66563
  let dir = process.argv[1] ? dirname56(process.argv[1]) : "";
66027
66564
  if (!dir) return null;
66028
66565
  for (let i = 0; i < 8; i++) {
66029
- if (existsSync93(join89(dir, "package.json"))) return dir;
66566
+ if (existsSync94(join90(dir, "package.json"))) return dir;
66030
66567
  const parent = dirname56(dir);
66031
66568
  if (parent === dir) break;
66032
66569
  dir = parent;
@@ -66068,7 +66605,7 @@ async function handleAgentInstall(req, res) {
66068
66605
  installRuns.set(runId, run3);
66069
66606
  try {
66070
66607
  const shell = process.env.SHELL || "/bin/zsh";
66071
- const child = spawn6(shell, ["-ilc", plan.script], {
66608
+ const child = spawn7(shell, ["-ilc", plan.script], {
66072
66609
  cwd: plan.cwd,
66073
66610
  stdio: ["ignore", "pipe", "pipe"]
66074
66611
  });
@@ -66202,13 +66739,13 @@ function findFirstTranscriptPath(ids) {
66202
66739
  const wanted = ids.filter(Boolean);
66203
66740
  if (wanted.length === 0) return null;
66204
66741
  try {
66205
- const base = join89(homedir8(), ".claude", "projects");
66206
- if (!existsSync93(base)) return null;
66742
+ const base = join90(homedir8(), ".claude", "projects");
66743
+ if (!existsSync94(base)) return null;
66207
66744
  const dirs = readdirSync20(base);
66208
66745
  for (const id of wanted) {
66209
66746
  for (const dir of dirs) {
66210
- const p = join89(base, dir, `${id}.jsonl`);
66211
- if (existsSync93(p)) return p;
66747
+ const p = join90(base, dir, `${id}.jsonl`);
66748
+ if (existsSync94(p)) return p;
66212
66749
  }
66213
66750
  }
66214
66751
  } catch {
@@ -66261,12 +66798,12 @@ function sanitizeTitle(raw) {
66261
66798
  return t.length >= 2 ? t : null;
66262
66799
  }
66263
66800
  function generateTitle(message, cwd) {
66264
- return new Promise((resolve26) => {
66801
+ return new Promise((resolve27) => {
66265
66802
  const shell = process.env.SHELL || "/bin/zsh";
66266
66803
  const prompt = "You name terminal tabs so a user can tell many open tabs apart at a glance. Read the user's first request to a coding agent and reply with ONLY a tab title in Title Case that is specific and clearly describes the actual task \u2014 name the concrete thing being worked on, not a vague category. 3 to 6 words, no quotes, no punctuation, no trailing period, max 48 characters.\n\nRequest:\n" + message;
66267
66804
  let out = "";
66268
66805
  let settled = false;
66269
- const child = spawn6(shell, ["-ilc", 'exec claude --model haiku -p "$0"', prompt], {
66806
+ const child = spawn7(shell, ["-ilc", 'exec claude --model haiku -p "$0"', prompt], {
66270
66807
  cwd,
66271
66808
  stdio: ["ignore", "pipe", "ignore"]
66272
66809
  });
@@ -66278,7 +66815,7 @@ function generateTitle(message, cwd) {
66278
66815
  child.kill();
66279
66816
  } catch {
66280
66817
  }
66281
- resolve26(v);
66818
+ resolve27(v);
66282
66819
  };
66283
66820
  const timer = setTimeout(() => done(null), 3e4);
66284
66821
  child.stdout?.on("data", (c) => {
@@ -66334,7 +66871,7 @@ function readJsonSafe(path2) {
66334
66871
  }
66335
66872
  }
66336
66873
  function parseEffortsFromCli() {
66337
- return new Promise((resolve26) => {
66874
+ return new Promise((resolve27) => {
66338
66875
  const shell = process.env.SHELL || "/bin/zsh";
66339
66876
  let out = "";
66340
66877
  let settled = false;
@@ -66342,10 +66879,10 @@ function parseEffortsFromCli() {
66342
66879
  if (!settled) {
66343
66880
  settled = true;
66344
66881
  clearTimeout(timer);
66345
- resolve26(v);
66882
+ resolve27(v);
66346
66883
  }
66347
66884
  };
66348
- const child = spawn6(shell, ["-ilc", "claude --help"], { stdio: ["ignore", "pipe", "ignore"] });
66885
+ const child = spawn7(shell, ["-ilc", "claude --help"], { stdio: ["ignore", "pipe", "ignore"] });
66349
66886
  const timer = setTimeout(() => {
66350
66887
  try {
66351
66888
  child.kill();
@@ -66366,7 +66903,7 @@ function parseEffortsFromCli() {
66366
66903
  }
66367
66904
  async function buildStaticModelConfig() {
66368
66905
  if (staticModelConfigCache) return staticModelConfigCache;
66369
- const globalJson = readJsonSafe(join89(homedir8(), ".claude.json")) ?? {};
66906
+ const globalJson = readJsonSafe(join90(homedir8(), ".claude.json")) ?? {};
66370
66907
  const base = [
66371
66908
  { id: "opus", label: "Opus" },
66372
66909
  { id: "sonnet", label: "Sonnet" },
@@ -66391,7 +66928,7 @@ async function buildStaticModelConfig() {
66391
66928
  }
66392
66929
  async function buildModelConfig() {
66393
66930
  const { models, efforts } = await buildStaticModelConfig();
66394
- const settings = readJsonSafe(join89(homedir8(), ".claude", "settings.json")) ?? {};
66931
+ const settings = readJsonSafe(join90(homedir8(), ".claude", "settings.json")) ?? {};
66395
66932
  const defaultEffort = typeof settings.effortLevel === "string" && efforts.includes(settings.effortLevel) ? settings.effortLevel : efforts.includes("high") ? "high" : efforts[0] ?? "high";
66396
66933
  const defaultModel = modelAlias(String(settings.model ?? "opus")) || "opus";
66397
66934
  return { models, efforts, defaultModel, defaultEffort };
@@ -66496,7 +67033,7 @@ function startPtySession(ws, pty, projectRoot, bypass, theme, sessionId, resumeI
66496
67033
  const flag = bypass ? " --permission-mode bypassPermissions" : "";
66497
67034
  const modelFlag = model ? ` --model ${model}` : "";
66498
67035
  const effortFlag = effort ? ` --effort ${effort}` : "";
66499
- const contextRoot = join89(projectRoot, "_dream_context");
67036
+ const contextRoot = join90(projectRoot, "_dream_context");
66500
67037
  const mappedId = kind === "agent" && resumeId ? resolveAgentSession(contextRoot, resumeId) : "";
66501
67038
  const resumeTarget = [mappedId, resumeId].find(
66502
67039
  (c) => c && !liveConversations.has(c) && claudeConversationExists(c)
@@ -66628,8 +67165,8 @@ var init_agent_terminal = __esm({
66628
67165
 
66629
67166
  // src/server/routes/agent-drop.ts
66630
67167
  import { randomUUID as randomUUID7 } from "crypto";
66631
- import { mkdirSync as mkdirSync48, writeFileSync as writeFileSync54, readdirSync as readdirSync21, statSync as statSync21, unlinkSync as unlinkSync10 } from "fs";
66632
- import { join as join90, basename as basename30 } from "path";
67168
+ import { mkdirSync as mkdirSync48, writeFileSync as writeFileSync54, readdirSync as readdirSync21, statSync as statSync22, unlinkSync as unlinkSync11 } from "fs";
67169
+ import { join as join91, basename as basename30 } from "path";
66633
67170
  function sniffImageType2(buf) {
66634
67171
  return sniffImageType(buf);
66635
67172
  }
@@ -66656,7 +67193,7 @@ function decodeFilenameHeader(h) {
66656
67193
  }
66657
67194
  function ensureTmpGitignored(contextRoot) {
66658
67195
  try {
66659
- writeFileSync54(join90(contextRoot, "tmp", ".gitignore"), "*\n");
67196
+ writeFileSync54(join91(contextRoot, "tmp", ".gitignore"), "*\n");
66660
67197
  } catch {
66661
67198
  }
66662
67199
  }
@@ -66664,10 +67201,10 @@ function pruneDrops(dir) {
66664
67201
  try {
66665
67202
  const now = Date.now();
66666
67203
  for (const name of readdirSync21(dir)) {
66667
- const p = join90(dir, name);
67204
+ const p = join91(dir, name);
66668
67205
  try {
66669
- const st = statSync21(p);
66670
- if (st.isFile() && now - st.mtimeMs > DROP_TTL_MS) unlinkSync10(p);
67206
+ const st = statSync22(p);
67207
+ if (st.isFile() && now - st.mtimeMs > DROP_TTL_MS) unlinkSync11(p);
66671
67208
  } catch {
66672
67209
  }
66673
67210
  }
@@ -66675,14 +67212,14 @@ function pruneDrops(dir) {
66675
67212
  }
66676
67213
  }
66677
67214
  function readCappedBody(req, res) {
66678
- return new Promise((resolve26) => {
67215
+ return new Promise((resolve27) => {
66679
67216
  const chunks = [];
66680
67217
  let size = 0;
66681
67218
  let done = false;
66682
67219
  const finish2 = (v) => {
66683
67220
  if (!done) {
66684
67221
  done = true;
66685
- resolve26(v);
67222
+ resolve27(v);
66686
67223
  }
66687
67224
  };
66688
67225
  req.on("data", (chunk) => {
@@ -66713,7 +67250,7 @@ async function handleAgentDrop(req, res, _params, contextRoot) {
66713
67250
  const sniffed = sniffImageType2(buf);
66714
67251
  const rawName = decodeFilenameHeader(req.headers["x-dreamcontext-filename"]);
66715
67252
  const safeName = sanitizeDropFilename(rawName, sniffed ? EXT_BY_TYPE[sniffed] : "");
66716
- const dropDir = join90(contextRoot, "tmp", "agent-drops");
67253
+ const dropDir = join91(contextRoot, "tmp", "agent-drops");
66717
67254
  try {
66718
67255
  mkdirSync48(dropDir, { recursive: true });
66719
67256
  ensureTmpGitignored(contextRoot);
@@ -66723,7 +67260,7 @@ async function handleAgentDrop(req, res, _params, contextRoot) {
66723
67260
  sendError(res, 500, "mkdir_failed", "Could not prepare the drop directory.");
66724
67261
  return;
66725
67262
  }
66726
- const finalPath = join90(dropDir, `${Date.now()}-${safeName}`);
67263
+ const finalPath = join91(dropDir, `${Date.now()}-${safeName}`);
66727
67264
  try {
66728
67265
  writeFileSync54(finalPath, buf);
66729
67266
  } catch (err) {
@@ -66747,11 +67284,11 @@ var init_agent_drop = __esm({
66747
67284
  });
66748
67285
 
66749
67286
  // src/server/routes/agent-sessions.ts
66750
- import { join as join91, dirname as dirname57 } from "path";
66751
- import { existsSync as existsSync94, mkdirSync as mkdirSync49, readFileSync as readFileSync67, writeFileSync as writeFileSync55, renameSync as renameSync17 } from "fs";
67287
+ import { join as join92, dirname as dirname57 } from "path";
67288
+ import { existsSync as existsSync95, mkdirSync as mkdirSync49, readFileSync as readFileSync67, writeFileSync as writeFileSync55, renameSync as renameSync17 } from "fs";
66752
67289
  import { randomUUID as randomUUID8 } from "crypto";
66753
67290
  function storePath2(contextRoot) {
66754
- return join91(contextRoot, ROSTER_REL_PATH);
67291
+ return join92(contextRoot, ROSTER_REL_PATH);
66755
67292
  }
66756
67293
  function coerceMeta(raw) {
66757
67294
  const o = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
@@ -66787,8 +67324,8 @@ function writeRoster(contextRoot, sessions) {
66787
67324
  });
66788
67325
  } catch {
66789
67326
  }
66790
- const dir = join91(contextRoot, "state");
66791
- if (!existsSync94(dir)) mkdirSync49(dir, { recursive: true });
67327
+ const dir = join92(contextRoot, "state");
67328
+ if (!existsSync95(dir)) mkdirSync49(dir, { recursive: true });
66792
67329
  const path2 = storePath2(contextRoot);
66793
67330
  const tmp = `${path2}.${randomUUID8()}.tmp`;
66794
67331
  writeFileSync55(tmp, JSON.stringify({ sessions }, null, 2) + "\n", "utf-8");
@@ -66844,7 +67381,7 @@ var init_agent_sessions = __esm({
66844
67381
  MAX_SIZE = 10;
66845
67382
  DEFAULT_SIZE = 1;
66846
67383
  MAX_BYTES3 = 64 * 1024;
66847
- ROSTER_REL_PATH = join91("state", ".agent-sessions.json");
67384
+ ROSTER_REL_PATH = join92("state", ".agent-sessions.json");
66848
67385
  }
66849
67386
  });
66850
67387
 
@@ -66926,8 +67463,8 @@ var init_connections2 = __esm({
66926
67463
  });
66927
67464
 
66928
67465
  // src/lib/federation-digest.ts
66929
- import { existsSync as existsSync95 } from "fs";
66930
- import { join as join92 } from "path";
67466
+ import { existsSync as existsSync96 } from "fs";
67467
+ import { join as join93 } from "path";
66931
67468
  function buildInterestProfile(peerRoot, topics) {
66932
67469
  if (topics && topics.length > 0) {
66933
67470
  const terms2 = Array.from(new Set(tokenize(topics.join(" "))));
@@ -66946,8 +67483,8 @@ function buildInterestProfile(peerRoot, topics) {
66946
67483
  return { terms, query: terms.join(" ") };
66947
67484
  }
66948
67485
  function activeTaskTerms(peerRoot) {
66949
- const stateDir = join92(peerRoot, "state");
66950
- if (!existsSync95(stateDir)) return [];
67486
+ const stateDir = join93(peerRoot, "state");
67487
+ if (!existsSync96(stateDir)) return [];
66951
67488
  let files;
66952
67489
  try {
66953
67490
  files = import_fast_glob22.default.sync("*.md", { cwd: stateDir, absolute: true });
@@ -67224,11 +67761,13 @@ async function handleVersionCheckGet(_req, res, _params, contextRoot) {
67224
67761
  const freshCli = readDreamcontextVersionFromDisk();
67225
67762
  const installedCli = freshCli === "0.0.0" ? dreamcontextVersion() : freshCli;
67226
67763
  const catalogPackNames = cache?.availablePacks ?? [];
67227
- const installedPacks = catalogPackNames.filter((name) => isSkillInstalled(projectRoot, name));
67228
- const newPacks = fresh ? catalogPackNames.filter((name) => !installedPacks.includes(name)) : [];
67764
+ const optedInPacks = readSetupConfig(projectRoot)?.packs ?? [];
67765
+ const relevantPacks = catalogPackNames.filter((name) => optedInPacks.includes(name));
67766
+ const installedPacks = relevantPacks.filter((name) => isSkillInstalled(projectRoot, name));
67767
+ const newPacks = fresh ? relevantPacks.filter((name) => !installedPacks.includes(name)) : [];
67229
67768
  const marker = readAutoUpgradeMarker(projectRoot);
67230
67769
  const suppressCliNudge = process.env.DREAMCONTEXT_DESKTOP === "1" || shouldSuppressCliNudge(fresh ? cache?.latestCli ?? null : null, marker, process.env);
67231
- const nudge = buildNudge(installedCli, fresh ? cache : null, installedPacks, catalogPackNames, {
67770
+ const nudge = buildNudge(installedCli, fresh ? cache : null, installedPacks, relevantPacks, {
67232
67771
  suppressCliNudge
67233
67772
  });
67234
67773
  const latestCli = fresh ? cache?.latestCli ?? null : null;
@@ -67245,6 +67784,7 @@ var init_version_check2 = __esm({
67245
67784
  init_version_check();
67246
67785
  init_manifest();
67247
67786
  init_catalog();
67787
+ init_setup_config();
67248
67788
  }
67249
67789
  });
67250
67790
 
@@ -67638,9 +68178,9 @@ var init_brain_auth = __esm({
67638
68178
  });
67639
68179
 
67640
68180
  // src/lib/git-sync/team-fetch.ts
67641
- import { join as join93 } from "path";
68181
+ import { join as join94 } from "path";
67642
68182
  function contextRootFor(vaultPath) {
67643
- return join93(vaultPath, "_dream_context");
68183
+ return join94(vaultPath, "_dream_context");
67644
68184
  }
67645
68185
  async function runTeamFetch(opts = {}) {
67646
68186
  const sync = opts.runBrainSyncImpl ?? runBrainSync;
@@ -67778,10 +68318,12 @@ async function runSyncPayload(projectRoot, contextRoot, opts) {
67778
68318
  checkpointed: !!result.checkpointed,
67779
68319
  checkpointSha: result.checkpointSha,
67780
68320
  codeConflicts: result.codeConflicts,
67781
- failure
68321
+ failure,
68322
+ healedStaleProjectToken: result.healedStaleProjectToken
67782
68323
  };
67783
68324
  } catch (err) {
67784
- const failure = classifySyncError(err.message, syncRepoHint(projectRoot));
68325
+ const perProjectToken = isPerProjectToken(resolveBrainSyncToken(projectRoot));
68326
+ const failure = classifySyncError(err.message, syncRepoHint(projectRoot), { perProjectToken });
67785
68327
  reconcileBrainSyncFailure(err.message, projectRoot, syncRepoHint(projectRoot));
67786
68328
  return {
67787
68329
  action: "error",
@@ -68074,6 +68616,7 @@ var init_brain2 = __esm({
68074
68616
  init_team_fetch();
68075
68617
  init_conflict_report();
68076
68618
  init_failure();
68619
+ init_token_fallback();
68077
68620
  init_auth_reconcile();
68078
68621
  init_gitignore();
68079
68622
  init_vaults();
@@ -68188,7 +68731,7 @@ var init_admin = __esm({
68188
68731
 
68189
68732
  // src/server/index.ts
68190
68733
  import { createServer } from "http";
68191
- import { join as join94, resolve as resolve23 } from "path";
68734
+ import { join as join95, resolve as resolve24 } from "path";
68192
68735
  import { fileURLToPath as fileURLToPath8 } from "url";
68193
68736
  import { exec } from "child_process";
68194
68737
  function buildRouter() {
@@ -68282,6 +68825,10 @@ function buildRouter() {
68282
68825
  router.post("/api/launcher/sync", handleLauncherSyncCreate);
68283
68826
  router.post("/api/launcher/sync/remove", handleLauncherSyncRemove);
68284
68827
  router.post("/api/launcher/shareable", handleLauncherShareable);
68828
+ router.get("/api/launcher/github/repos", handleLauncherGithubRepos);
68829
+ router.post("/api/launcher/clone", handleLauncherClone);
68830
+ router.get("/api/launcher/clone/status", handleLauncherCloneStatus);
68831
+ router.post("/api/launcher/clone/cancel", handleLauncherCloneCancel);
68285
68832
  router.get("/api/sleepy/video", handleSleepyVideo);
68286
68833
  router.get("/api/sleepy/anim", handleSleepyAnim);
68287
68834
  router.get("/api/sleepy/chat/stream", handleSleepyChatStream);
@@ -68355,11 +68902,11 @@ function resolveRequestVault(req) {
68355
68902
  if (/[/\\:.\x00]/.test(h)) return "INVALID";
68356
68903
  const v = listVaults().find((x) => x.name === h);
68357
68904
  if (!v) return "INVALID";
68358
- return join94(v.path, "_dream_context");
68905
+ return join95(v.path, "_dream_context");
68359
68906
  }
68360
68907
  function getDashboardDir() {
68361
68908
  const __dirname8 = fileURLToPath8(new URL(".", import.meta.url));
68362
- return resolve23(__dirname8, "dashboard");
68909
+ return resolve24(__dirname8, "dashboard");
68363
68910
  }
68364
68911
  function openBrowser(url) {
68365
68912
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
@@ -68674,8 +69221,8 @@ var init_trigger = __esm({
68674
69221
  });
68675
69222
 
68676
69223
  // src/lib/reflection.ts
68677
- import { existsSync as existsSync96, mkdirSync as mkdirSync50, writeFileSync as writeFileSync56 } from "fs";
68678
- import { join as join95, dirname as dirname65 } from "path";
69224
+ import { existsSync as existsSync97, mkdirSync as mkdirSync50, writeFileSync as writeFileSync56 } from "fs";
69225
+ import { join as join96, dirname as dirname65 } from "path";
68679
69226
  function buildExclusionSet(corpus, excludedExtra) {
68680
69227
  const excluded = new Set(excludedExtra);
68681
69228
  for (const doc of corpus) {
@@ -68851,12 +69398,12 @@ function formatReflection(result) {
68851
69398
  return capToBytes(lines, MAX_REFLECTION_BYTES);
68852
69399
  }
68853
69400
  function reflectionPath(root) {
68854
- return join95(root, "state", ".reflection.md");
69401
+ return join96(root, "state", ".reflection.md");
68855
69402
  }
68856
69403
  function writeReflection(root, md) {
68857
69404
  const outPath = reflectionPath(root);
68858
69405
  const dir = dirname65(outPath);
68859
- if (!existsSync96(dir)) {
69406
+ if (!existsSync97(dir)) {
68860
69407
  mkdirSync50(dir, { recursive: true });
68861
69408
  }
68862
69409
  const tsMatch = md.match(/Generated: ([^\n]+)/);
@@ -69044,12 +69591,12 @@ var init_reflection = __esm({
69044
69591
  });
69045
69592
 
69046
69593
  // src/cli/commands/reflect.ts
69047
- import { existsSync as existsSync97, readFileSync as readFileSync70 } from "fs";
69048
- import { join as join96 } from "path";
69594
+ import { existsSync as existsSync98, readFileSync as readFileSync70 } from "fs";
69595
+ import { join as join97 } from "path";
69049
69596
  function buildBookmarkSessions(root) {
69050
- const sleepPath = join96(root, "state", ".sleep.json");
69597
+ const sleepPath = join97(root, "state", ".sleep.json");
69051
69598
  const result = /* @__PURE__ */ new Map();
69052
- if (!existsSync97(sleepPath)) return result;
69599
+ if (!existsSync98(sleepPath)) return result;
69053
69600
  try {
69054
69601
  const parsed = JSON.parse(readFileSync70(sleepPath, "utf-8"));
69055
69602
  const bookmarks = parsed.bookmarks ?? [];
@@ -69065,11 +69612,11 @@ function buildBookmarkSessions(root) {
69065
69612
  function buildExcludedExtra(root) {
69066
69613
  const excluded = /* @__PURE__ */ new Set();
69067
69614
  const coreFiles = [
69068
- join96(root, "core", "0.soul.md"),
69069
- join96(root, "core", "1.user.md")
69615
+ join97(root, "core", "0.soul.md"),
69616
+ join97(root, "core", "1.user.md")
69070
69617
  ];
69071
69618
  for (const filePath of coreFiles) {
69072
- if (!existsSync97(filePath)) continue;
69619
+ if (!existsSync98(filePath)) continue;
69073
69620
  try {
69074
69621
  const content = readFileSync70(filePath, "utf-8");
69075
69622
  for (const tok of tokenize(content)) {
@@ -69122,8 +69669,8 @@ var init_reflect = __esm({
69122
69669
  });
69123
69670
 
69124
69671
  // src/cli/commands/council.ts
69125
- import { existsSync as existsSync98, mkdirSync as mkdirSync51, readFileSync as readFileSync71, writeFileSync as writeFileSync57 } from "fs";
69126
- import { join as join97 } from "path";
69672
+ import { existsSync as existsSync99, mkdirSync as mkdirSync51, readFileSync as readFileSync71, writeFileSync as writeFileSync57 } from "fs";
69673
+ import { join as join98 } from "path";
69127
69674
  function roundRunningStatus(n) {
69128
69675
  return `round_${n}_running`;
69129
69676
  }
@@ -69168,9 +69715,9 @@ function registerCreate(council) {
69168
69715
  mkdirSync51(dir, { recursive: true });
69169
69716
  const template = loadTemplate("council-debate.md");
69170
69717
  const content = template.replaceAll("{{ID}}", id).replaceAll("{{TOPIC}}", topic.replace(/"/g, '\\"')).replaceAll("{{ROUNDS}}", String(rounds)).replaceAll("{{INTERRUPT}}", opts.interrupt ? "true" : "false").replaceAll("{{DATE}}", today());
69171
- writeFileSync57(join97(dir, "debate.md"), content, "utf-8");
69718
+ writeFileSync57(join98(dir, "debate.md"), content, "utf-8");
69172
69719
  writeFileSync57(
69173
- join97(dir, "round-log.md"),
69720
+ join98(dir, "round-log.md"),
69174
69721
  `# Round log \u2014 ${id}
69175
69722
 
69176
69723
  (Main agent appends timeline entries here.)
@@ -69212,8 +69759,8 @@ function registerAgent(council) {
69212
69759
  process.exit(1);
69213
69760
  }
69214
69761
  const personaDir = getPersonaDir(debateId, slug);
69215
- const personaFile = join97(personaDir, "context-and-persona.md");
69216
- if (existsSync98(personaFile) && !opts.force) {
69762
+ const personaFile = join98(personaDir, "context-and-persona.md");
69763
+ if (existsSync99(personaFile) && !opts.force) {
69217
69764
  error(`Persona already exists: ${slug}`, "Use --force to overwrite.");
69218
69765
  process.exit(1);
69219
69766
  }
@@ -69229,8 +69776,8 @@ function registerAgent(council) {
69229
69776
  writeFileSync57(personaFile, personaContent, "utf-8");
69230
69777
  const reportTemplate = loadTemplate("council-report.md");
69231
69778
  const reportContent = reportTemplate.replaceAll("{{SLUG}}", slug);
69232
- writeFileSync57(join97(personaDir, "report.md"), reportContent, "utf-8");
69233
- const debateFile = join97(getDebateDir(debateId), "debate.md");
69779
+ writeFileSync57(join98(personaDir, "report.md"), reportContent, "utf-8");
69780
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69234
69781
  const { data } = readFrontmatter(debateFile);
69235
69782
  const personas = Array.isArray(data.personas) ? data.personas.slice() : [];
69236
69783
  if (!personas.includes(slug)) personas.push(slug);
@@ -69259,7 +69806,7 @@ function registerRound(council) {
69259
69806
  error(`Round ${n} exceeds planned rounds (${data.rounds_planned}).`);
69260
69807
  process.exit(1);
69261
69808
  }
69262
- const debateFile = join97(getDebateDir(debateId), "debate.md");
69809
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69263
69810
  const personas = data.personas ?? [];
69264
69811
  if (personas.length === 0) {
69265
69812
  error("No personas registered. Run `council agent create` first.");
@@ -69268,8 +69815,8 @@ function registerRound(council) {
69268
69815
  const crossContextHeader = `## Round ${n} \u2014 Cross-context loaded`;
69269
69816
  if (n >= 2) {
69270
69817
  for (const persona of personas) {
69271
- const personaFile = join97(getPersonaDir(debateId, persona), "context-and-persona.md");
69272
- if (!existsSync98(personaFile)) continue;
69818
+ const personaFile = join98(getPersonaDir(debateId, persona), "context-and-persona.md");
69819
+ if (!existsSync99(personaFile)) continue;
69273
69820
  const existing = readFileSync71(personaFile, "utf-8");
69274
69821
  if (existing.includes(crossContextHeader)) {
69275
69822
  continue;
@@ -69300,8 +69847,8 @@ ${peerLines.join("\n\n")}`;
69300
69847
  current_round: n,
69301
69848
  updated_at: today()
69302
69849
  });
69303
- const logFile = join97(getDebateDir(debateId), "round-log.md");
69304
- const logExisting = existsSync98(logFile) ? readFileSync71(logFile, "utf-8") : "";
69850
+ const logFile = join98(getDebateDir(debateId), "round-log.md");
69851
+ const logExisting = existsSync99(logFile) ? readFileSync71(logFile, "utf-8") : "";
69305
69852
  const logEntry = `
69306
69853
  ## Round ${n} started \u2014 ${today()}
69307
69854
  - Personas: ${formatPersonaList(personas)}
@@ -69340,13 +69887,13 @@ ${peerLines.join("\n\n")}`;
69340
69887
  error(`Round ${n} incomplete. Missing reports from: ${missing.join(", ")}`);
69341
69888
  process.exit(1);
69342
69889
  }
69343
- const debateFile = join97(getDebateDir(debateId), "debate.md");
69890
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69344
69891
  updateFrontmatterFields(debateFile, {
69345
69892
  status: roundCompleteStatus(n),
69346
69893
  updated_at: today()
69347
69894
  });
69348
- const logFile = join97(getDebateDir(debateId), "round-log.md");
69349
- const logExisting = existsSync98(logFile) ? readFileSync71(logFile, "utf-8") : "";
69895
+ const logFile = join98(getDebateDir(debateId), "round-log.md");
69896
+ const logExisting = existsSync99(logFile) ? readFileSync71(logFile, "utf-8") : "";
69350
69897
  const logEntry = `
69351
69898
  ## Round ${n} complete \u2014 ${today()}
69352
69899
  - All ${personas.length} personas submitted reports.
@@ -69374,7 +69921,7 @@ function registerRoundContext(council) {
69374
69921
  try {
69375
69922
  const data = readDebateFrontmatter(debateId);
69376
69923
  ensurePersonaExists(debateId, personaSlug);
69377
- const personaFile = join97(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
69924
+ const personaFile = join98(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
69378
69925
  const personaContent = readFileSync71(personaFile, "utf-8");
69379
69926
  console.log(`# Council debate: ${data.topic}`);
69380
69927
  console.log(`Debate ID: ${debateId}`);
@@ -69384,7 +69931,7 @@ function registerRoundContext(council) {
69384
69931
  console.log("---");
69385
69932
  console.log("");
69386
69933
  console.log(personaContent);
69387
- const debateFile = join97(getDebateDir(debateId), "debate.md");
69934
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69388
69935
  const debateRaw = readFileSync71(debateFile, "utf-8");
69389
69936
  const questionMatch = debateRaw.match(/##\s+Question\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
69390
69937
  const constraintsMatch = debateRaw.match(/##\s+Constraints & Known Facts\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
@@ -69428,7 +69975,7 @@ function registerReport(council) {
69428
69975
  process.exit(1);
69429
69976
  }
69430
69977
  for (const w of validation.warnings) warn(w);
69431
- const reportFile = join97(getPersonaDir(debateId, personaSlug), "report.md");
69978
+ const reportFile = join98(getPersonaDir(debateId, personaSlug), "report.md");
69432
69979
  const { data: reportData, content } = readFrontmatter(reportFile);
69433
69980
  const existingRounds = parseReportRounds(content);
69434
69981
  if (existingRounds.find((r) => r.round === round)) {
@@ -69450,7 +69997,7 @@ ${otherSerialized}
69450
69997
  persona: personaSlug,
69451
69998
  rounds_completed: Math.max(reportData.rounds_completed ?? 0, round)
69452
69999
  }, "\n" + merged);
69453
- const personaFile = join97(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
70000
+ const personaFile = join98(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
69454
70001
  const { data: pData } = readFrontmatter(personaFile);
69455
70002
  updateFrontmatterFields(personaFile, {
69456
70003
  round_entries: Math.max(pData.round_entries ?? 0, round)
@@ -69493,13 +70040,13 @@ function registerResearch(council) {
69493
70040
  error("Research topic is required.");
69494
70041
  process.exit(1);
69495
70042
  }
69496
- const researchesDir = join97(getPersonaDir(debateId, personaSlug), "researches");
70043
+ const researchesDir = join98(getPersonaDir(debateId, personaSlug), "researches");
69497
70044
  mkdirSync51(researchesDir, { recursive: true });
69498
- const indexPath2 = join97(researchesDir, "index.json");
69499
- if (!existsSync98(indexPath2)) writeJsonArray(indexPath2, []);
70045
+ const indexPath2 = join98(researchesDir, "index.json");
70046
+ if (!existsSync99(indexPath2)) writeJsonArray(indexPath2, []);
69500
70047
  const slug = slugify(topic);
69501
- const file = join97(researchesDir, `${slug}.md`);
69502
- if (existsSync98(file)) {
70048
+ const file = join98(researchesDir, `${slug}.md`);
70049
+ if (existsSync99(file)) {
69503
70050
  error(`Research note already exists: ${slug}.md`);
69504
70051
  process.exit(1);
69505
70052
  }
@@ -69529,9 +70076,9 @@ ${body.trim()}
69529
70076
  research.command("list").argument("<debate_id>").argument("<persona_slug>").description("List this persona's prior research notes.").action((debateId, personaSlug) => {
69530
70077
  try {
69531
70078
  ensurePersonaExists(debateId, personaSlug);
69532
- const researchesDir = join97(getPersonaDir(debateId, personaSlug), "researches");
69533
- const indexPath2 = join97(researchesDir, "index.json");
69534
- if (!existsSync98(indexPath2)) {
70079
+ const researchesDir = join98(getPersonaDir(debateId, personaSlug), "researches");
70080
+ const indexPath2 = join98(researchesDir, "index.json");
70081
+ if (!existsSync99(indexPath2)) {
69535
70082
  console.log(source_default.dim("(no researches)"));
69536
70083
  return;
69537
70084
  }
@@ -69553,7 +70100,7 @@ function registerSynthesize(council) {
69553
70100
  council.command("synthesize").argument("<debate_id>").description("Mark status=synthesizing; print manifest of files synthesizer should read.").action((debateId) => {
69554
70101
  try {
69555
70102
  const data = readDebateFrontmatter(debateId);
69556
- const debateFile = join97(getDebateDir(debateId), "debate.md");
70103
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69557
70104
  updateFrontmatterFields(debateFile, {
69558
70105
  status: "synthesizing",
69559
70106
  updated_at: today()
@@ -69575,8 +70122,8 @@ function registerSynthesize(council) {
69575
70122
  const personaDir = getPersonaDir(debateId, persona);
69576
70123
  manifest.push(`_dream_context/council/${debateId}/${persona}/context-and-persona.md`);
69577
70124
  manifest.push(`_dream_context/council/${debateId}/${persona}/report.md`);
69578
- const researchesIndex = join97(personaDir, "researches", "index.json");
69579
- if (existsSync98(researchesIndex)) {
70125
+ const researchesIndex = join98(personaDir, "researches", "index.json");
70126
+ if (existsSync99(researchesIndex)) {
69580
70127
  manifest.push(`_dream_context/council/${debateId}/${persona}/researches/`);
69581
70128
  }
69582
70129
  }
@@ -69594,12 +70141,12 @@ function registerComplete(council) {
69594
70141
  council.command("complete").argument("<debate_id>").description("Mark status=complete after final-report.md is written.").action((debateId) => {
69595
70142
  try {
69596
70143
  const data = readDebateFrontmatter(debateId);
69597
- const finalReport = join97(getDebateDir(debateId), "final-report.md");
69598
- if (!existsSync98(finalReport)) {
70144
+ const finalReport = join98(getDebateDir(debateId), "final-report.md");
70145
+ if (!existsSync99(finalReport)) {
69599
70146
  error("final-report.md not found.", "Synthesizer must write it before calling `council complete`.");
69600
70147
  process.exit(1);
69601
70148
  }
69602
- const debateFile = join97(getDebateDir(debateId), "debate.md");
70149
+ const debateFile = join98(getDebateDir(debateId), "debate.md");
69603
70150
  updateFrontmatterFields(debateFile, {
69604
70151
  status: "complete",
69605
70152
  updated_at: today()
@@ -69631,8 +70178,8 @@ function registerPromote(council) {
69631
70178
  error(`Cannot promote: debate status is "${data.status}", expected "complete".`);
69632
70179
  process.exit(1);
69633
70180
  }
69634
- const finalReport = join97(getDebateDir(debateId), "final-report.md");
69635
- if (!existsSync98(finalReport)) {
70181
+ const finalReport = join98(getDebateDir(debateId), "final-report.md");
70182
+ if (!existsSync99(finalReport)) {
69636
70183
  error("final-report.md not found.");
69637
70184
  process.exit(1);
69638
70185
  }
@@ -69645,12 +70192,12 @@ function registerPromote(council) {
69645
70192
 
69646
70193
  ${sec.body.trim()}` : null;
69647
70194
  }).filter(Boolean).join("\n\n");
69648
- const knowledgeDir = join97(root, "knowledge");
70195
+ const knowledgeDir = join98(root, "knowledge");
69649
70196
  mkdirSync51(knowledgeDir, { recursive: true });
69650
70197
  const slug = slugify(data.topic).slice(0, 80) || debateId;
69651
70198
  const filename = `decision-${slug}.md`;
69652
- const target = join97(knowledgeDir, filename);
69653
- if (existsSync98(target) && !opts.force) {
70199
+ const target = join98(knowledgeDir, filename);
70200
+ if (existsSync99(target) && !opts.force) {
69654
70201
  error(`Knowledge file exists: ${filename}`, "Use --force to overwrite.");
69655
70202
  process.exit(1);
69656
70203
  }
@@ -69674,7 +70221,7 @@ ${kept}
69674
70221
  _Promoted from council debate \`${debateId}\` on ${today()}. See \`_dream_context/council/${debateId}/final-report.md\` for the full record._
69675
70222
  `;
69676
70223
  writeFrontmatter(target, knowledgeFrontmatter, body);
69677
- updateFrontmatterFields(join97(getDebateDir(debateId), "debate.md"), {
70224
+ updateFrontmatterFields(join98(getDebateDir(debateId), "debate.md"), {
69678
70225
  promoted_to_knowledge: `knowledge/${filename}`,
69679
70226
  updated_at: today()
69680
70227
  });
@@ -69736,8 +70283,8 @@ function registerShow(council) {
69736
70283
  console.log(` promoted: ${data.promoted_to_knowledge ?? source_default.dim("(no)")}`);
69737
70284
  console.log(` created: ${data.created_at}`);
69738
70285
  console.log(` updated: ${data.updated_at}`);
69739
- const logFile = join97(getDebateDir(debateId), "round-log.md");
69740
- if (existsSync98(logFile)) {
70286
+ const logFile = join98(getDebateDir(debateId), "round-log.md");
70287
+ if (existsSync99(logFile)) {
69741
70288
  console.log("\n" + source_default.dim("\u2500\u2500\u2500 Round log \u2500\u2500\u2500"));
69742
70289
  console.log(readFileSync71(logFile, "utf-8"));
69743
70290
  }
@@ -69931,11 +70478,11 @@ var init_env_loader = __esm({
69931
70478
  });
69932
70479
 
69933
70480
  // src/lib/marketing/config.ts
69934
- import { existsSync as existsSync99, readFileSync as readFileSync72, writeFileSync as writeFileSync58, mkdirSync as mkdirSync52 } from "fs";
70481
+ import { existsSync as existsSync100, readFileSync as readFileSync72, writeFileSync as writeFileSync58, mkdirSync as mkdirSync52 } from "fs";
69935
70482
  import { dirname as dirname66 } from "path";
69936
70483
  function readEnvFile() {
69937
70484
  const path2 = MARKETING_PATHS.envFile();
69938
- if (!existsSync99(path2)) return {};
70485
+ if (!existsSync100(path2)) return {};
69939
70486
  const raw = readFileSync72(path2, "utf8");
69940
70487
  const parsed = parseEnv(raw);
69941
70488
  if (parsed.errors.length > 0) {
@@ -69980,7 +70527,7 @@ function requireEnv(keys = REQUIRED_KEYS) {
69980
70527
  }
69981
70528
  function loadConfig() {
69982
70529
  const path2 = MARKETING_PATHS.configFile();
69983
- if (!existsSync99(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
70530
+ if (!existsSync100(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
69984
70531
  try {
69985
70532
  const raw = readFileSync72(path2, "utf8");
69986
70533
  const parsed = JSON.parse(raw);
@@ -70002,14 +70549,14 @@ function writeConfig(cfg) {
70002
70549
  }
70003
70550
  function ensureConfigFile() {
70004
70551
  const path2 = MARKETING_PATHS.configFile();
70005
- if (existsSync99(path2)) return loadConfig();
70552
+ if (existsSync100(path2)) return loadConfig();
70006
70553
  const cfg = { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
70007
70554
  writeConfig(cfg);
70008
70555
  return cfg;
70009
70556
  }
70010
70557
  function ensureEnvFile() {
70011
70558
  const path2 = MARKETING_PATHS.envFile();
70012
- if (existsSync99(path2)) return;
70559
+ if (existsSync100(path2)) return;
70013
70560
  mkdirSync52(marketingRoot(), { recursive: true });
70014
70561
  writeFileSync58(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
70015
70562
  }
@@ -70051,20 +70598,20 @@ REINFLUENCE_BIN= # optional override; default uses .venv
70051
70598
  });
70052
70599
 
70053
70600
  // src/lib/marketing/bootstrap.ts
70054
- import { spawn as spawn7, spawnSync as spawnSync2 } from "child_process";
70055
- import { existsSync as existsSync100, mkdirSync as mkdirSync53, cpSync as cpSync3 } from "fs";
70601
+ import { spawn as spawn8, spawnSync as spawnSync2 } from "child_process";
70602
+ import { existsSync as existsSync101, mkdirSync as mkdirSync53, cpSync as cpSync3 } from "fs";
70056
70603
  import { fileURLToPath as fileURLToPath9 } from "url";
70057
- import { dirname as dirname67, resolve as resolve24, join as join98 } from "path";
70604
+ import { dirname as dirname67, resolve as resolve25, join as join99 } from "path";
70058
70605
  function findBundledReinfluence() {
70059
70606
  const candidates = [
70060
70607
  // Installed npm package: dist/<chunk>.js -> ../tools/reinfluence
70061
- resolve24(__dirname7, "..", "tools", "reinfluence"),
70062
- resolve24(__dirname7, "..", "..", "tools", "reinfluence"),
70608
+ resolve25(__dirname7, "..", "tools", "reinfluence"),
70609
+ resolve25(__dirname7, "..", "..", "tools", "reinfluence"),
70063
70610
  // Dev tree: src/lib/marketing -> ../../../tools/reinfluence
70064
- resolve24(__dirname7, "..", "..", "..", "tools", "reinfluence")
70611
+ resolve25(__dirname7, "..", "..", "..", "tools", "reinfluence")
70065
70612
  ];
70066
70613
  for (const c of candidates) {
70067
- if (existsSync100(join98(c, "__main__.py"))) return c;
70614
+ if (existsSync101(join99(c, "__main__.py"))) return c;
70068
70615
  }
70069
70616
  throw new Error(
70070
70617
  "Bundled reinfluence not found. Reinstall dreamcontext or set REINFLUENCE_BIN."
@@ -70106,7 +70653,7 @@ async function bootstrapMarketing(opts = {}) {
70106
70653
  throw new Error("python3 not found on PATH. Install Python 3.10+ and retry.");
70107
70654
  }
70108
70655
  const venv = MARKETING_PATHS.venvDir();
70109
- if (!existsSync100(MARKETING_PATHS.venvPython())) {
70656
+ if (!existsSync101(MARKETING_PATHS.venvPython())) {
70110
70657
  log(`creating venv \u2192 ${venv}`);
70111
70658
  const r2 = runBlocking(py, ["-m", "venv", venv]);
70112
70659
  if (r2.code !== 0) {
@@ -70119,7 +70666,7 @@ async function bootstrapMarketing(opts = {}) {
70119
70666
  log("upgrading pip");
70120
70667
  let r = runBlocking(venvPy, ["-m", "pip", "install", "--upgrade", "pip", "--quiet"]);
70121
70668
  if (r.code !== 0) log(`pip upgrade warning: ${r.stderr.trim().slice(0, 200)}`);
70122
- const reqs = join98(target, "requirements.txt");
70669
+ const reqs = join99(target, "requirements.txt");
70123
70670
  log("installing python deps (whisper / yt-dlp / instaloader) \u2014 first run can take several minutes");
70124
70671
  r = runBlocking(venvPy, ["-m", "pip", "install", "-r", reqs, "--quiet"]);
70125
70672
  if (r.code !== 0) {
@@ -70143,7 +70690,7 @@ ${r.stderr.trim() || r.stdout.trim()}`);
70143
70690
  function primeWhisper(model) {
70144
70691
  return new Promise((resolveP) => {
70145
70692
  const env2 = subprocessEnv();
70146
- const proc = spawn7(MARKETING_PATHS.venvPython(), [
70693
+ const proc = spawn8(MARKETING_PATHS.venvPython(), [
70147
70694
  "-c",
70148
70695
  `import whisper; whisper.load_model(${JSON.stringify(model)})`
70149
70696
  ], {
@@ -70169,15 +70716,15 @@ function subprocessEnv() {
70169
70716
  return {
70170
70717
  ...process.env,
70171
70718
  XDG_CACHE_HOME: cache,
70172
- HF_HOME: join98(cache, "hf"),
70173
- TRANSFORMERS_CACHE: join98(cache, "hf", "transformers"),
70719
+ HF_HOME: join99(cache, "hf"),
70720
+ TRANSFORMERS_CACHE: join99(cache, "hf", "transformers"),
70174
70721
  WHISPER_CACHE_DIR: MARKETING_PATHS.whisperCacheDir(),
70175
70722
  PYTHONUNBUFFERED: "1",
70176
70723
  PYTHONPATH: MARKETING_PATHS.toolsDir()
70177
70724
  };
70178
70725
  }
70179
70726
  function isBootstrapped() {
70180
- return existsSync100(MARKETING_PATHS.venvPython()) && existsSync100(join98(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
70727
+ return existsSync101(MARKETING_PATHS.venvPython()) && existsSync101(join99(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
70181
70728
  }
70182
70729
  var __filename, __dirname7;
70183
70730
  var init_bootstrap = __esm({
@@ -70254,8 +70801,8 @@ var init_init2 = __esm({
70254
70801
  });
70255
70802
 
70256
70803
  // src/lib/marketing/vision.ts
70257
- import { existsSync as existsSync101, readFileSync as readFileSync73, writeFileSync as writeFileSync59 } from "fs";
70258
- import { dirname as dirname68, join as join99 } from "path";
70804
+ import { existsSync as existsSync102, readFileSync as readFileSync73, writeFileSync as writeFileSync59 } from "fs";
70805
+ import { dirname as dirname68, join as join100 } from "path";
70259
70806
  function pickVisionProvider(env2 = process.env) {
70260
70807
  const oai = env2.OPENAI_VISION_API_KEY;
70261
70808
  if (oai && oai.trim().length > 0) return { provider: "openai", apiKey: oai.trim() };
@@ -70298,7 +70845,7 @@ async function readImageAsBase64(framePath) {
70298
70845
  return buf.toString("base64");
70299
70846
  }
70300
70847
  async function labelHookFrame(framePath, opts) {
70301
- if (!existsSync101(framePath)) return [];
70848
+ if (!existsSync102(framePath)) return [];
70302
70849
  const fetcher = opts.fetcher ?? defaultFetcher;
70303
70850
  const prompt = opts.promptOverride ?? PROMPT;
70304
70851
  const b64 = await readImageAsBase64(framePath);
@@ -70390,8 +70937,8 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
70390
70937
  writeFileSync59(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
70391
70938
  const fs = await import("fs");
70392
70939
  fs.renameSync(tmp, postJsonPath);
70393
- const mdPath = join99(dirname68(postJsonPath), `${shortcode}.md`);
70394
- if (existsSync101(mdPath)) {
70940
+ const mdPath = join100(dirname68(postJsonPath), `${shortcode}.md`);
70941
+ if (existsSync102(mdPath)) {
70395
70942
  try {
70396
70943
  const md = readFileSync73(mdPath, "utf-8");
70397
70944
  const refreshed = updatePatternTagsInBridge(md, post.pattern_tags);
@@ -70468,10 +71015,10 @@ Example output: ["talking-head","prop-driven"]`;
70468
71015
  });
70469
71016
 
70470
71017
  // src/lib/marketing/competitors.ts
70471
- import { spawn as spawn8 } from "child_process";
71018
+ import { spawn as spawn9 } from "child_process";
70472
71019
  import { spawnSync as spawnSync3 } from "child_process";
70473
- import { existsSync as existsSync102, mkdirSync as mkdirSync55, statfsSync } from "fs";
70474
- import { dirname as dirname69, join as join100, basename as basename32, extname as extname6 } from "path";
71020
+ import { existsSync as existsSync103, mkdirSync as mkdirSync55, statfsSync } from "fs";
71021
+ import { dirname as dirname69, join as join101, basename as basename32, extname as extname6 } from "path";
70475
71022
  function which(cmd) {
70476
71023
  const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
70477
71024
  if (r.status === 0) return (r.stdout || "").trim().split("\n")[0] || null;
@@ -70548,7 +71095,7 @@ ${h.installHints.join("\n")}`);
70548
71095
  skip_transcripts: !!opts.skipTranscripts,
70549
71096
  skip_frames: !!opts.skipFrames
70550
71097
  });
70551
- const outDir = join100(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run3.id);
71098
+ const outDir = join101(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run3.id);
70552
71099
  mkdirSync55(outDir, { recursive: true });
70553
71100
  const args = [
70554
71101
  "-m",
@@ -70570,7 +71117,7 @@ ${h.installHints.join("\n")}`);
70570
71117
  let postsIngested = 0;
70571
71118
  try {
70572
71119
  await new Promise((resolveP, rejectP) => {
70573
- const proc = spawn8(MARKETING_PATHS.venvPython(), args, {
71120
+ const proc = spawn9(MARKETING_PATHS.venvPython(), args, {
70574
71121
  env: subprocessEnv(),
70575
71122
  stdio: ["ignore", "pipe", "pipe"]
70576
71123
  });
@@ -70649,15 +71196,15 @@ stderr: ${stderrBuf.slice(0, 1e3)}`));
70649
71196
  return { runId: run3.id, postsIngested, warnings, errors };
70650
71197
  }
70651
71198
  function persistPost(evt) {
70652
- const handleDir = join100(MARKETING_PATHS.competitorsDir(), evt.handle);
70653
- const postsDir = join100(handleDir, "posts");
70654
- const mediaDir = join100(handleDir, "_media", evt.shortcode);
71199
+ const handleDir = join101(MARKETING_PATHS.competitorsDir(), evt.handle);
71200
+ const postsDir = join101(handleDir, "posts");
71201
+ const mediaDir = join101(handleDir, "_media", evt.shortcode);
70655
71202
  mkdirSync55(postsDir, { recursive: true });
70656
71203
  mkdirSync55(mediaDir, { recursive: true });
70657
- const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join100(mediaDir, basename32(evt.video_path))) : null;
71204
+ const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join101(mediaDir, basename32(evt.video_path))) : null;
70658
71205
  const finalFramePaths = [];
70659
71206
  for (const fr of evt.frames) {
70660
- const finalP = moveAsset(fr.path, join100(mediaDir, "frames", basename32(fr.path)));
71207
+ const finalP = moveAsset(fr.path, join101(mediaDir, "frames", basename32(fr.path)));
70661
71208
  finalFramePaths.push(finalP);
70662
71209
  }
70663
71210
  const id = `${evt.handle}__${evt.shortcode}`;
@@ -70677,14 +71224,14 @@ function persistPost(evt) {
70677
71224
  ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
70678
71225
  asset_paths: { video: finalVideoPath, frames: finalFramePaths }
70679
71226
  };
70680
- const jsonPath = join100(postsDir, `${evt.shortcode}.json`);
70681
- const bridgePath = join100(postsDir, `${evt.shortcode}.md`);
71227
+ const jsonPath = join101(postsDir, `${evt.shortcode}.json`);
71228
+ const bridgePath = join101(postsDir, `${evt.shortcode}.md`);
70682
71229
  writeJsonWithBridge(jsonPath, bridgePath, json, renderPostBridge(json));
70683
- const metaPath = join100(handleDir, "meta.json");
70684
- if (!existsSync102(metaPath)) {
71230
+ const metaPath = join101(handleDir, "meta.json");
71231
+ if (!existsSync103(metaPath)) {
70685
71232
  writeJsonWithBridge(
70686
71233
  metaPath,
70687
- join100(handleDir, "meta.md"),
71234
+ join101(handleDir, "meta.md"),
70688
71235
  { handle: evt.handle, first_seen_at: (/* @__PURE__ */ new Date()).toISOString() },
70689
71236
  `---
70690
71237
  id: competitor_${evt.handle}
@@ -70701,7 +71248,7 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
70701
71248
  return jsonPath;
70702
71249
  }
70703
71250
  function moveAsset(src, dest) {
70704
- if (!existsSync102(src)) return dest;
71251
+ if (!existsSync103(src)) return dest;
70705
71252
  mkdirSync55(dirname69(dest), { recursive: true });
70706
71253
  const fs = __require("fs");
70707
71254
  try {
@@ -70763,8 +71310,8 @@ var init_competitors = __esm({
70763
71310
  });
70764
71311
 
70765
71312
  // src/cli/commands/marketing/competitor.ts
70766
- import { existsSync as existsSync103, readdirSync as readdirSync22, statSync as statSync22 } from "fs";
70767
- import { join as join101 } from "path";
71313
+ import { existsSync as existsSync104, readdirSync as readdirSync22, statSync as statSync23 } from "fs";
71314
+ import { join as join102 } from "path";
70768
71315
  function registerMarketingCompetitor(parent) {
70769
71316
  const cmd = parent.command("competitor").description("Ingest competitor IG / YouTube content (Reinfluence pipeline).");
70770
71317
  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) => {
@@ -70814,15 +71361,15 @@ function registerMarketingCompetitor(parent) {
70814
71361
  });
70815
71362
  cmd.command("list").description("List ingested competitor handles.").action(() => {
70816
71363
  const dir = MARKETING_PATHS.competitorsDir();
70817
- if (!existsSync103(dir)) {
71364
+ if (!existsSync104(dir)) {
70818
71365
  info("No competitors ingested yet.");
70819
71366
  return;
70820
71367
  }
70821
71368
  const handles = readdirSync22(dir).filter((name) => {
70822
71369
  if (name.startsWith("_") || name.startsWith(".")) return false;
70823
- const full = join101(dir, name);
71370
+ const full = join102(dir, name);
70824
71371
  try {
70825
- return statSync22(full).isDirectory();
71372
+ return statSync23(full).isDirectory();
70826
71373
  } catch {
70827
71374
  return false;
70828
71375
  }
@@ -70833,8 +71380,8 @@ function registerMarketingCompetitor(parent) {
70833
71380
  }
70834
71381
  console.log(header("Competitors"));
70835
71382
  for (const handle of handles) {
70836
- const postsDir = join101(dir, handle, "posts");
70837
- const postCount = existsSync103(postsDir) ? readdirSync22(postsDir).filter((f) => f.endsWith(".json")).length : 0;
71383
+ const postsDir = join102(dir, handle, "posts");
71384
+ const postCount = existsSync104(postsDir) ? readdirSync22(postsDir).filter((f) => f.endsWith(".json")).length : 0;
70838
71385
  console.log(` ${source_default.cyan("@" + handle)} ${source_default.dim(`${postCount} post(s)`)}`);
70839
71386
  }
70840
71387
  });
@@ -70847,11 +71394,11 @@ function registerMarketingCompetitor(parent) {
70847
71394
  }
70848
71395
  info(`Provider: ${provider.provider}`);
70849
71396
  const competitorsDir = MARKETING_PATHS.competitorsDir();
70850
- const handles = opts.handle ? [opts.handle] : existsSync103(competitorsDir) ? readdirSync22(competitorsDir).filter((h) => !h.startsWith("_") && statSync22(join101(competitorsDir, h)).isDirectory()) : [];
71397
+ const handles = opts.handle ? [opts.handle] : existsSync104(competitorsDir) ? readdirSync22(competitorsDir).filter((h) => !h.startsWith("_") && statSync23(join102(competitorsDir, h)).isDirectory()) : [];
70851
71398
  const matches = [];
70852
71399
  for (const h of handles) {
70853
- const candidate = join101(competitorsDir, h, "posts", `${shortcode}.json`);
70854
- if (existsSync103(candidate)) matches.push(candidate);
71400
+ const candidate = join102(competitorsDir, h, "posts", `${shortcode}.json`);
71401
+ if (existsSync104(candidate)) matches.push(candidate);
70855
71402
  }
70856
71403
  if (matches.length === 0) {
70857
71404
  error(`No post JSON found for shortcode "${shortcode}".`);
@@ -70886,18 +71433,18 @@ function registerMarketingCompetitor(parent) {
70886
71433
  process.exit(1);
70887
71434
  }
70888
71435
  const competitorsDir = MARKETING_PATHS.competitorsDir();
70889
- if (!existsSync103(competitorsDir)) {
71436
+ if (!existsSync104(competitorsDir)) {
70890
71437
  warn("No competitors directory yet \u2014 nothing to relabel.");
70891
71438
  return;
70892
71439
  }
70893
- const handles = readdirSync22(competitorsDir).filter((h) => !h.startsWith("_") && statSync22(join101(competitorsDir, h)).isDirectory());
71440
+ const handles = readdirSync22(competitorsDir).filter((h) => !h.startsWith("_") && statSync23(join102(competitorsDir, h)).isDirectory());
70894
71441
  let labeled = 0;
70895
71442
  let skipped = 0;
70896
71443
  for (const h of handles) {
70897
- const postsDir = join101(competitorsDir, h, "posts");
70898
- if (!existsSync103(postsDir)) continue;
71444
+ const postsDir = join102(competitorsDir, h, "posts");
71445
+ if (!existsSync104(postsDir)) continue;
70899
71446
  for (const f of readdirSync22(postsDir).filter((n) => n.endsWith(".json"))) {
70900
- const path2 = join101(postsDir, f);
71447
+ const path2 = join102(postsDir, f);
70901
71448
  if (opts.dryRun) {
70902
71449
  info(`would relabel: ${path2}`);
70903
71450
  continue;
@@ -70944,7 +71491,7 @@ var init_competitor = __esm({
70944
71491
  });
70945
71492
 
70946
71493
  // src/lib/marketing/meta-fetch.ts
70947
- import { existsSync as existsSync104, mkdirSync as mkdirSync56, readFileSync as readFileSync74, writeFileSync as writeFileSync60, statSync as statSync23, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
71494
+ import { existsSync as existsSync105, mkdirSync as mkdirSync56, readFileSync as readFileSync74, writeFileSync as writeFileSync60, statSync as statSync24, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
70948
71495
  import { dirname as dirname70, basename as basename33 } from "path";
70949
71496
  import { randomUUID as randomUUID10 } from "crypto";
70950
71497
  function getQueue(accountId) {
@@ -70958,7 +71505,7 @@ function getQueue(accountId) {
70958
71505
  async function withWriteSlot(accountId, fn) {
70959
71506
  const q = getQueue(accountId);
70960
71507
  if (q.active >= PER_ACCOUNT_WRITE_CONCURRENCY) {
70961
- await new Promise((resolve26) => q.waiting.push(resolve26));
71508
+ await new Promise((resolve27) => q.waiting.push(resolve27));
70962
71509
  }
70963
71510
  q.active += 1;
70964
71511
  try {
@@ -70995,7 +71542,7 @@ function idemCachePath(key2) {
70995
71542
  }
70996
71543
  function readIdem(key2) {
70997
71544
  const p = idemCachePath(key2);
70998
- if (!existsSync104(p)) return null;
71545
+ if (!existsSync105(p)) return null;
70999
71546
  try {
71000
71547
  return JSON.parse(readFileSync74(p, "utf8"));
71001
71548
  } catch {
@@ -71210,7 +71757,7 @@ async function uploadVideoFile(ctx, filepath, fields = {}) {
71210
71757
  logLine(ctx, `[DRY] uploadVideoFile ${filepath}`);
71211
71758
  return { video_id: fakeId, upload_session_id: `DRY_session_${fakeId}` };
71212
71759
  }
71213
- const stat = statSync23(filepath);
71760
+ const stat = statSync24(filepath);
71214
71761
  const fileSize = stat.size;
71215
71762
  const path2 = `${ctx.adAccountId}/advideos`;
71216
71763
  if (fileSize <= CHUNKED_UPLOAD_THRESHOLD) {
@@ -71741,7 +72288,7 @@ var init_account = __esm({
71741
72288
  });
71742
72289
 
71743
72290
  // src/lib/marketing/hypothesis.ts
71744
- import { existsSync as existsSync105, readFileSync as readFileSync75 } from "fs";
72291
+ import { existsSync as existsSync106, readFileSync as readFileSync75 } from "fs";
71745
72292
  function validateHypothesis(raw, options2 = {}) {
71746
72293
  const errors = [];
71747
72294
  const fieldErrors = {};
@@ -71808,7 +72355,7 @@ function validateHypothesis(raw, options2 = {}) {
71808
72355
  };
71809
72356
  }
71810
72357
  function loadHypothesisFile(path2, options2 = {}) {
71811
- if (!existsSync105(path2)) {
72358
+ if (!existsSync106(path2)) {
71812
72359
  return { ok: false, errors: [`Hypothesis file not found: ${path2}`] };
71813
72360
  }
71814
72361
  let parsed;
@@ -72001,8 +72548,8 @@ var init_cohort2 = __esm({
72001
72548
  });
72002
72549
 
72003
72550
  // src/lib/marketing/insights-cache.ts
72004
- import { existsSync as existsSync106, readFileSync as readFileSync76, mkdirSync as mkdirSync57, writeFileSync as writeFileSync61, readdirSync as readdirSync23, statSync as statSync24 } from "fs";
72005
- import { join as join102 } from "path";
72551
+ import { existsSync as existsSync107, readFileSync as readFileSync76, mkdirSync as mkdirSync57, writeFileSync as writeFileSync61, readdirSync as readdirSync23, statSync as statSync25 } from "fs";
72552
+ import { join as join103 } from "path";
72006
72553
  import { randomBytes as randomBytes5 } from "crypto";
72007
72554
  function snapshotFilename(entityId, pulledAt) {
72008
72555
  const yyyy = pulledAt.getUTCFullYear();
@@ -72013,11 +72560,11 @@ function snapshotFilename(entityId, pulledAt) {
72013
72560
  return `${safe}__${yyyy}-${mm}-${dd}-${hh}.json`;
72014
72561
  }
72015
72562
  function indexPath() {
72016
- return join102(MARKETING_PATHS.insightsDir(), "_index.json");
72563
+ return join103(MARKETING_PATHS.insightsDir(), "_index.json");
72017
72564
  }
72018
72565
  function readIndex() {
72019
72566
  const p = indexPath();
72020
- if (!existsSync106(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
72567
+ if (!existsSync107(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
72021
72568
  try {
72022
72569
  return JSON.parse(readFileSync76(p, "utf8"));
72023
72570
  } catch {
@@ -72034,7 +72581,7 @@ function writeIndex(idx) {
72034
72581
  function saveInsightsSnapshot(snap) {
72035
72582
  mkdirSync57(MARKETING_PATHS.insightsDir(), { recursive: true });
72036
72583
  const filename = snapshotFilename(snap.entity_id, new Date(snap.pulled_at));
72037
- const fullPath = join102(MARKETING_PATHS.insightsDir(), filename);
72584
+ const fullPath = join103(MARKETING_PATHS.insightsDir(), filename);
72038
72585
  const tmp = `${fullPath}.tmp.${process.pid}.${randomBytes5(4).toString("hex")}`;
72039
72586
  writeFileSync61(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
72040
72587
  __require("fs").renameSync(tmp, fullPath);
@@ -72048,8 +72595,8 @@ function getCachedInsights(entityId) {
72048
72595
  const idx = readIndex();
72049
72596
  const filename = idx.latest[entityId];
72050
72597
  if (!filename) return null;
72051
- const fullPath = join102(MARKETING_PATHS.insightsDir(), filename);
72052
- if (!existsSync106(fullPath)) return null;
72598
+ const fullPath = join103(MARKETING_PATHS.insightsDir(), filename);
72599
+ if (!existsSync107(fullPath)) return null;
72053
72600
  try {
72054
72601
  const snap = JSON.parse(readFileSync76(fullPath, "utf8"));
72055
72602
  const ageMs = Date.now() - new Date(snap.pulled_at).getTime();
@@ -72063,8 +72610,8 @@ function getLatestSnapshot(entityId) {
72063
72610
  const idx = readIndex();
72064
72611
  const filename = idx.latest[entityId];
72065
72612
  if (!filename) return null;
72066
- const fullPath = join102(MARKETING_PATHS.insightsDir(), filename);
72067
- if (!existsSync106(fullPath)) return null;
72613
+ const fullPath = join103(MARKETING_PATHS.insightsDir(), filename);
72614
+ if (!existsSync107(fullPath)) return null;
72068
72615
  try {
72069
72616
  return JSON.parse(readFileSync76(fullPath, "utf8"));
72070
72617
  } catch {
@@ -72073,11 +72620,11 @@ function getLatestSnapshot(entityId) {
72073
72620
  }
72074
72621
  function getPriorSnapshot(entityId, beforeMs) {
72075
72622
  const dir = MARKETING_PATHS.insightsDir();
72076
- if (!existsSync106(dir)) return null;
72623
+ if (!existsSync107(dir)) return null;
72077
72624
  const safe = entityId.replace(/[^A-Za-z0-9_-]/g, "_");
72078
72625
  const candidates = readdirSync23(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
72079
- const p = join102(dir, f);
72080
- const stat = statSync24(p);
72626
+ const p = join103(dir, f);
72627
+ const stat = statSync25(p);
72081
72628
  return { f, p, mtimeMs: stat.mtimeMs };
72082
72629
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
72083
72630
  const cutoff = Date.now() - beforeMs;
@@ -72720,8 +73267,8 @@ var init_kill = __esm({
72720
73267
  });
72721
73268
 
72722
73269
  // src/cli/commands/marketing/doctor.ts
72723
- import { readFileSync as readFileSync77, readdirSync as readdirSync24, statSync as statSync25 } from "fs";
72724
- import { join as join103 } from "path";
73270
+ import { readFileSync as readFileSync77, readdirSync as readdirSync24, statSync as statSync26 } from "fs";
73271
+ import { join as join104 } from "path";
72725
73272
  function registerMarketingDoctor(parent) {
72726
73273
  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) => {
72727
73274
  console.log(header("Marketing doctor"));
@@ -72829,10 +73376,10 @@ function* walkText(dir) {
72829
73376
  }
72830
73377
  for (const e of entries) {
72831
73378
  if (e.startsWith(".") && (e === ".env" || e === ".env.local")) continue;
72832
- const full = join103(dir, e);
73379
+ const full = join104(dir, e);
72833
73380
  let stat;
72834
73381
  try {
72835
- stat = statSync25(full);
73382
+ stat = statSync26(full);
72836
73383
  } catch {
72837
73384
  continue;
72838
73385
  }
@@ -72867,8 +73414,8 @@ var init_doctor2 = __esm({
72867
73414
  });
72868
73415
 
72869
73416
  // src/lib/marketing/entity-store.ts
72870
- import { existsSync as existsSync108, readFileSync as readFileSync78, readdirSync as readdirSync25 } from "fs";
72871
- import { join as join104 } from "path";
73417
+ import { existsSync as existsSync109, readFileSync as readFileSync78, readdirSync as readdirSync25 } from "fs";
73418
+ import { join as join105 } from "path";
72872
73419
  function dirFor(kind) {
72873
73420
  switch (kind) {
72874
73421
  case "campaign":
@@ -72887,11 +73434,11 @@ function newEntityId(kind) {
72887
73434
  }
72888
73435
  function entityPaths(kind, id) {
72889
73436
  const d = dirFor(kind);
72890
- return { json: join104(d, `${id}.json`), md: join104(d, `${id}.md`) };
73437
+ return { json: join105(d, `${id}.json`), md: join105(d, `${id}.md`) };
72891
73438
  }
72892
73439
  function loadEntity(kind, id) {
72893
73440
  const { json } = entityPaths(kind, id);
72894
- if (!existsSync108(json)) return null;
73441
+ if (!existsSync109(json)) return null;
72895
73442
  try {
72896
73443
  return JSON.parse(readFileSync78(json, "utf8"));
72897
73444
  } catch {
@@ -72900,11 +73447,11 @@ function loadEntity(kind, id) {
72900
73447
  }
72901
73448
  function listEntities(kind) {
72902
73449
  const d = dirFor(kind);
72903
- if (!existsSync108(d)) return [];
73450
+ if (!existsSync109(d)) return [];
72904
73451
  const out = [];
72905
73452
  for (const f of readdirSync25(d).filter((x) => x.endsWith(".json"))) {
72906
73453
  try {
72907
- out.push(JSON.parse(readFileSync78(join104(d, f), "utf8")));
73454
+ out.push(JSON.parse(readFileSync78(join105(d, f), "utf8")));
72908
73455
  } catch {
72909
73456
  }
72910
73457
  }
@@ -73098,7 +73645,7 @@ var init_campaign = __esm({
73098
73645
  });
73099
73646
 
73100
73647
  // src/cli/commands/marketing/adset.ts
73101
- import { existsSync as existsSync109, readFileSync as readFileSync79 } from "fs";
73648
+ import { existsSync as existsSync110, readFileSync as readFileSync79 } from "fs";
73102
73649
  function registerMarketingAdSet(parent) {
73103
73650
  const cmd = parent.command("adset").description("Manage adsets.");
73104
73651
  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) => {
@@ -73118,7 +73665,7 @@ function registerMarketingAdSet(parent) {
73118
73665
  }
73119
73666
  throw e;
73120
73667
  }
73121
- if (!existsSync109(opts.targeting)) {
73668
+ if (!existsSync110(opts.targeting)) {
73122
73669
  error(`Targeting file not found: ${opts.targeting}`);
73123
73670
  process.exit(1);
73124
73671
  }
@@ -73381,12 +73928,12 @@ var init_creative = __esm({
73381
73928
  });
73382
73929
 
73383
73930
  // src/cli/commands/marketing/asset.ts
73384
- import { existsSync as existsSync110, statSync as statSync26 } from "fs";
73931
+ import { existsSync as existsSync111, statSync as statSync27 } from "fs";
73385
73932
  import { extname as extname7 } from "path";
73386
73933
  function registerMarketingAsset(parent) {
73387
73934
  const cmd = parent.command("asset").description("Upload creative assets to Meta.");
73388
73935
  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) => {
73389
- if (!existsSync110(path2)) {
73936
+ if (!existsSync111(path2)) {
73390
73937
  error(`File not found: ${path2}`);
73391
73938
  process.exit(1);
73392
73939
  }
@@ -73402,7 +73949,7 @@ function registerMarketingAsset(parent) {
73402
73949
  error(`Could not auto-detect asset type for "${ext}". Pass --type video|image.`);
73403
73950
  process.exit(1);
73404
73951
  }
73405
- const sizeMb = (statSync26(path2).size / (1024 * 1024)).toFixed(1);
73952
+ const sizeMb = (statSync27(path2).size / (1024 * 1024)).toFixed(1);
73406
73953
  console.log(header(`Asset upload \u2014 ${kind} (${sizeMb} MB)`));
73407
73954
  const ctx = buildCtx({ noDryRun: opts.dryRun === false });
73408
73955
  if (ctx.dryRun) info(source_default.yellow("[DRY-RUN] no live changes"));
@@ -73554,8 +74101,8 @@ var init_ad = __esm({
73554
74101
  });
73555
74102
 
73556
74103
  // src/lib/marketing/launch.ts
73557
- import { existsSync as existsSync111, readFileSync as readFileSync80, writeFileSync as writeFileSync62, mkdirSync as mkdirSync58, renameSync as renameSync18, readdirSync as readdirSync26 } from "fs";
73558
- import { dirname as dirname71, join as join105, basename as basename34 } from "path";
74104
+ import { existsSync as existsSync112, readFileSync as readFileSync80, writeFileSync as writeFileSync62, mkdirSync as mkdirSync58, renameSync as renameSync18, readdirSync as readdirSync26 } from "fs";
74105
+ import { dirname as dirname71, join as join106, basename as basename34 } from "path";
73559
74106
  import { randomBytes as randomBytes6 } from "crypto";
73560
74107
  function buildLaunchSummary(cohortId) {
73561
74108
  const cohort = loadCohort(cohortId);
@@ -73605,7 +74152,7 @@ function atomicWriteFile3(path2, data) {
73605
74152
  renameSync18(tmp, path2);
73606
74153
  }
73607
74154
  function readWal(path2) {
73608
- if (!existsSync111(path2)) return null;
74155
+ if (!existsSync112(path2)) return null;
73609
74156
  try {
73610
74157
  return JSON.parse(readFileSync80(path2, "utf8"));
73611
74158
  } catch {
@@ -73617,13 +74164,13 @@ function writeWal(path2, wal) {
73617
74164
  }
73618
74165
  function findWalByRunId(runId) {
73619
74166
  const dir = MARKETING_PATHS.runsDir();
73620
- if (!existsSync111(dir)) return null;
74167
+ if (!existsSync112(dir)) return null;
73621
74168
  for (const f of readdirSync26(dir)) {
73622
74169
  if (!f.endsWith(".json")) continue;
73623
74170
  if (f.startsWith("by-idem")) continue;
73624
74171
  const stem = f.replace(/\.json$/, "");
73625
74172
  if (stem === runId || f === runId || basename34(f, ".json") === runId) {
73626
- return join105(dir, f);
74173
+ return join106(dir, f);
73627
74174
  }
73628
74175
  }
73629
74176
  return null;
@@ -73663,7 +74210,7 @@ function createLaunchWal(args) {
73663
74210
  flipped_count: 0,
73664
74211
  error: null
73665
74212
  };
73666
- const walPath = join105(MARKETING_PATHS.runsDir(), `${id}.json`);
74213
+ const walPath = join106(MARKETING_PATHS.runsDir(), `${id}.json`);
73667
74214
  writeWal(walPath, wal);
73668
74215
  return { walPath, wal };
73669
74216
  }
@@ -73894,7 +74441,7 @@ var init_launch2 = __esm({
73894
74441
  });
73895
74442
 
73896
74443
  // src/cli/commands/marketing/learnings.ts
73897
- import { existsSync as existsSync112, readFileSync as readFileSync81 } from "fs";
74444
+ import { existsSync as existsSync113, readFileSync as readFileSync81 } from "fs";
73898
74445
  function registerMarketingLearnings(parent) {
73899
74446
  const cmd = parent.command("learnings").description("Performance Monitor learnings ledger (per-day .md + index).");
73900
74447
  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) => {
@@ -74037,19 +74584,19 @@ async function resolveBody(body, bodyFile) {
74037
74584
  if (body) return body;
74038
74585
  if (bodyFile === "-") return readStdin3();
74039
74586
  if (bodyFile) {
74040
- if (!existsSync112(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
74587
+ if (!existsSync113(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
74041
74588
  return readFileSync81(bodyFile, "utf8");
74042
74589
  }
74043
74590
  return null;
74044
74591
  }
74045
74592
  function readStdin3() {
74046
- return new Promise((resolve26, reject) => {
74593
+ return new Promise((resolve27, reject) => {
74047
74594
  let data = "";
74048
74595
  process.stdin.setEncoding("utf8");
74049
74596
  process.stdin.on("data", (chunk) => {
74050
74597
  data += chunk;
74051
74598
  });
74052
- process.stdin.on("end", () => resolve26(data));
74599
+ process.stdin.on("end", () => resolve27(data));
74053
74600
  process.stdin.on("error", reject);
74054
74601
  });
74055
74602
  }
@@ -74068,16 +74615,16 @@ var init_learnings2 = __esm({
74068
74615
 
74069
74616
  // src/lib/marketing/rem-sleep.ts
74070
74617
  import {
74071
- existsSync as existsSync113,
74618
+ existsSync as existsSync114,
74072
74619
  mkdirSync as mkdirSync59,
74073
74620
  readFileSync as readFileSync82,
74074
74621
  writeFileSync as writeFileSync63,
74075
74622
  readdirSync as readdirSync27,
74076
- statSync as statSync27,
74077
- unlinkSync as unlinkSync11,
74623
+ statSync as statSync28,
74624
+ unlinkSync as unlinkSync12,
74078
74625
  renameSync as renameSync19
74079
74626
  } from "fs";
74080
- import { dirname as dirname72, join as join106 } from "path";
74627
+ import { dirname as dirname72, join as join107 } from "path";
74081
74628
  import { randomBytes as randomBytes7 } from "crypto";
74082
74629
  function atomicWriteFile4(path2, data) {
74083
74630
  mkdirSync59(dirname72(path2), { recursive: true });
@@ -74088,11 +74635,11 @@ function atomicWriteFile4(path2, data) {
74088
74635
  function pruneRuns2(opts = {}) {
74089
74636
  const keepLast = opts.keepLast ?? 100;
74090
74637
  const dir = MARKETING_PATHS.runsDir();
74091
- if (!existsSync113(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
74638
+ if (!existsSync114(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
74092
74639
  const files = readdirSync27(dir).filter((f) => f.endsWith(".json")).map((f) => {
74093
- const p = join106(dir, f);
74640
+ const p = join107(dir, f);
74094
74641
  try {
74095
- return { f, p, mtimeMs: statSync27(p).mtimeMs };
74642
+ return { f, p, mtimeMs: statSync28(p).mtimeMs };
74096
74643
  } catch {
74097
74644
  return null;
74098
74645
  }
@@ -74105,7 +74652,7 @@ function pruneRuns2(opts = {}) {
74105
74652
  if (!opts.dryRun) {
74106
74653
  for (const x of toDelete) {
74107
74654
  try {
74108
- unlinkSync11(x.p);
74655
+ unlinkSync12(x.p);
74109
74656
  deletedFiles.push(x.f);
74110
74657
  } catch {
74111
74658
  }
@@ -74124,15 +74671,15 @@ function compactInsights(opts = {}) {
74124
74671
  const weeklyAfterDays = opts.weeklyAfterDays ?? 14;
74125
74672
  const now = opts.now ?? /* @__PURE__ */ new Date();
74126
74673
  const dir = MARKETING_PATHS.insightsDir();
74127
- if (!existsSync113(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
74674
+ if (!existsSync114(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
74128
74675
  const files = [];
74129
74676
  for (const f of readdirSync27(dir)) {
74130
74677
  if (!f.endsWith(".json") || f.startsWith("_")) continue;
74131
74678
  const m = f.match(SNAP_RE);
74132
74679
  if (!m) continue;
74133
- const p = join106(dir, f);
74680
+ const p = join107(dir, f);
74134
74681
  try {
74135
- const stat = statSync27(p);
74682
+ const stat = statSync28(p);
74136
74683
  files.push({ f, p, mtimeMs: stat.mtimeMs, entityId: m[1], bucket: m[2] });
74137
74684
  } catch {
74138
74685
  }
@@ -74169,7 +74716,7 @@ function compactInsights(opts = {}) {
74169
74716
  if (!opts.dryRun) {
74170
74717
  for (const sf of toDelete) {
74171
74718
  try {
74172
- unlinkSync11(sf.p);
74719
+ unlinkSync12(sf.p);
74173
74720
  deletedFiles.push(sf.f);
74174
74721
  } catch {
74175
74722
  }
@@ -74196,7 +74743,7 @@ function mergeDailyLearnings(opts = {}) {
74196
74743
  const retainDays = opts.retainDays ?? 7;
74197
74744
  const now = opts.now ?? /* @__PURE__ */ new Date();
74198
74745
  const dir = MARKETING_PATHS.learningsDir();
74199
- if (!existsSync113(dir)) {
74746
+ if (!existsSync114(dir)) {
74200
74747
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
74201
74748
  }
74202
74749
  const dayMs = 24 * 60 * 60 * 1e3;
@@ -74207,7 +74754,7 @@ function mergeDailyLearnings(opts = {}) {
74207
74754
  if (!m) continue;
74208
74755
  const date = m[1];
74209
74756
  const dateMs = (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getTime();
74210
- if (dateMs < cutoff) candidates.push({ f, p: join106(dir, f), date });
74757
+ if (dateMs < cutoff) candidates.push({ f, p: join107(dir, f), date });
74211
74758
  }
74212
74759
  if (candidates.length === 0) {
74213
74760
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
@@ -74221,10 +74768,10 @@ function mergeDailyLearnings(opts = {}) {
74221
74768
  const mergedFiles = [];
74222
74769
  let lastArchivePath = null;
74223
74770
  for (const [q, list] of byQuarter) {
74224
- const archivePath = join106(dir, `_archive-${q}.md`);
74771
+ const archivePath = join107(dir, `_archive-${q}.md`);
74225
74772
  list.sort((a, b) => a.date.localeCompare(b.date));
74226
74773
  for (const c of list) {
74227
- const existingArchive = existsSync113(archivePath) ? readFileSync82(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
74774
+ const existingArchive = existsSync114(archivePath) ? readFileSync82(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
74228
74775
  `;
74229
74776
  const dateMarker = `# Marketing learnings \u2014 ${c.date}`;
74230
74777
  const alreadyMerged = existingArchive.includes(dateMarker);
@@ -74238,7 +74785,7 @@ function mergeDailyLearnings(opts = {}) {
74238
74785
  atomicWriteFile4(archivePath, next2);
74239
74786
  }
74240
74787
  try {
74241
- unlinkSync11(c.p);
74788
+ unlinkSync12(c.p);
74242
74789
  mergedFiles.push(c.f);
74243
74790
  } catch {
74244
74791
  }
@@ -74276,11 +74823,11 @@ function quarterKey(yyyymmdd) {
74276
74823
  }
74277
74824
  function redactRunsSweep(opts = {}) {
74278
74825
  const dir = MARKETING_PATHS.runsDir();
74279
- if (!existsSync113(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
74826
+ if (!existsSync114(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
74280
74827
  const files = readdirSync27(dir).filter((f) => f.endsWith(".json"));
74281
74828
  const rewrittenFiles = [];
74282
74829
  for (const f of files) {
74283
- const p = join106(dir, f);
74830
+ const p = join107(dir, f);
74284
74831
  let raw;
74285
74832
  try {
74286
74833
  raw = readFileSync82(p, "utf8");
@@ -74305,7 +74852,7 @@ function redactRunsSweep(opts = {}) {
74305
74852
  function runRemSleep(opts = {}) {
74306
74853
  const ranAt = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
74307
74854
  const root = marketingRootIfExists();
74308
- if (!root || !existsSync113(root)) {
74855
+ if (!root || !existsSync114(root)) {
74309
74856
  return {
74310
74857
  ranAt,
74311
74858
  marketingPresent: false,
@@ -74386,9 +74933,9 @@ var init_rem_sleep2 = __esm({
74386
74933
  });
74387
74934
 
74388
74935
  // src/cli/commands/marketing/hooks.ts
74389
- import { existsSync as existsSync114, readFileSync as readFileSync83, writeFileSync as writeFileSync64, chmodSync as chmodSync7, mkdirSync as mkdirSync60, statSync as statSync28 } from "fs";
74936
+ import { existsSync as existsSync115, readFileSync as readFileSync83, writeFileSync as writeFileSync64, chmodSync as chmodSync7, mkdirSync as mkdirSync60, statSync as statSync29 } from "fs";
74390
74937
  import { execFileSync as execFileSync9 } from "child_process";
74391
- import { join as join107 } from "path";
74938
+ import { join as join108 } from "path";
74392
74939
  function findGitDir(cwd = process.cwd()) {
74393
74940
  try {
74394
74941
  const out = execFileSync9("git", ["rev-parse", "--git-dir"], {
@@ -74397,7 +74944,7 @@ function findGitDir(cwd = process.cwd()) {
74397
74944
  stdio: ["ignore", "pipe", "ignore"]
74398
74945
  }).trim();
74399
74946
  if (!out) return null;
74400
- return out.startsWith("/") ? out : join107(cwd, out);
74947
+ return out.startsWith("/") ? out : join108(cwd, out);
74401
74948
  } catch {
74402
74949
  return null;
74403
74950
  }
@@ -74428,10 +74975,10 @@ function registerMarketingHooks(parent) {
74428
74975
  error("Not inside a git repository (or `git` is not on PATH).");
74429
74976
  process.exit(1);
74430
74977
  }
74431
- const hooksDir = join107(gitDir, "hooks");
74978
+ const hooksDir = join108(gitDir, "hooks");
74432
74979
  mkdirSync60(hooksDir, { recursive: true });
74433
- const target = join107(hooksDir, "pre-commit");
74434
- if (existsSync114(target)) {
74980
+ const target = join108(hooksDir, "pre-commit");
74981
+ if (existsSync115(target)) {
74435
74982
  const existing = readFileSync83(target, "utf-8");
74436
74983
  if (existing.includes(MANAGED_MARKER)) {
74437
74984
  info("pre-commit hook already managed by dreamcontext \u2014 refreshing.");
@@ -74450,7 +74997,7 @@ function registerMarketingHooks(parent) {
74450
74997
  } catch {
74451
74998
  }
74452
74999
  try {
74453
- const st = statSync28(target);
75000
+ const st = statSync29(target);
74454
75001
  const execMask = 73;
74455
75002
  if ((st.mode & execMask) === 0) {
74456
75003
  warn("Could not set exec bit on the hook file. Run `chmod +x .git/hooks/pre-commit` manually.");
@@ -74483,21 +75030,21 @@ exec dreamcontext mk hooks check-staged
74483
75030
  });
74484
75031
 
74485
75032
  // src/lib/marketing/council-personas.ts
74486
- import { existsSync as existsSync115, readFileSync as readFileSync84, readdirSync as readdirSync28 } from "fs";
75033
+ import { existsSync as existsSync116, readFileSync as readFileSync84, readdirSync as readdirSync28 } from "fs";
74487
75034
  import { fileURLToPath as fileURLToPath10 } from "url";
74488
- import { join as join108, dirname as dirname73 } from "path";
75035
+ import { join as join109, dirname as dirname73 } from "path";
74489
75036
  function findPersonasDir() {
74490
75037
  const candidates = [
74491
75038
  // dev: src/lib/marketing/council-personas.ts → ../../../skill-packs/...
74492
- join108(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
75039
+ join109(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
74493
75040
  // built: dist/index.js → ./skill-packs/...
74494
- join108(__dirname_local, PERSONA_SUBPATH),
75041
+ join109(__dirname_local, PERSONA_SUBPATH),
74495
75042
  // tsup-bundled (deeper nesting if ever): ../skill-packs/...
74496
- join108(__dirname_local, "..", PERSONA_SUBPATH),
74497
- join108(__dirname_local, "..", "..", PERSONA_SUBPATH)
75043
+ join109(__dirname_local, "..", PERSONA_SUBPATH),
75044
+ join109(__dirname_local, "..", "..", PERSONA_SUBPATH)
74498
75045
  ];
74499
75046
  for (const candidate of candidates) {
74500
- if (existsSync115(candidate)) return candidate;
75047
+ if (existsSync116(candidate)) return candidate;
74501
75048
  }
74502
75049
  return null;
74503
75050
  }
@@ -74522,9 +75069,9 @@ function parsePersonaFile(filePath) {
74522
75069
  }
74523
75070
  function loadAllPersonas(personasDir) {
74524
75071
  const dir = personasDir ?? findPersonasDir();
74525
- if (!dir || !existsSync115(dir)) return [];
75072
+ if (!dir || !existsSync116(dir)) return [];
74526
75073
  const files = readdirSync28(dir).filter((n) => n.endsWith(".md")).sort();
74527
- return files.map((name) => parsePersonaFile(join108(dir, name)));
75074
+ return files.map((name) => parsePersonaFile(join109(dir, name)));
74528
75075
  }
74529
75076
  function selectPersonas(all, requested) {
74530
75077
  if (requested.length === 0) return [...all];
@@ -74549,17 +75096,17 @@ var init_council_personas = __esm({
74549
75096
  }
74550
75097
  })();
74551
75098
  VALID_MODELS2 = /* @__PURE__ */ new Set(["opus", "sonnet", "haiku"]);
74552
- PERSONA_SUBPATH = join108("skill-packs", "meta-marketing", "council-personas");
75099
+ PERSONA_SUBPATH = join109("skill-packs", "meta-marketing", "council-personas");
74553
75100
  }
74554
75101
  });
74555
75102
 
74556
75103
  // src/cli/commands/marketing/council.ts
74557
75104
  import { spawnSync as spawnSync4 } from "child_process";
74558
- import { existsSync as existsSync116 } from "fs";
75105
+ import { existsSync as existsSync117 } from "fs";
74559
75106
  function resolveDreamcontextEntry() {
74560
75107
  const node = process.argv[0];
74561
75108
  const script = process.argv[1];
74562
- if (script && existsSync116(script)) {
75109
+ if (script && existsSync117(script)) {
74563
75110
  return { node, script };
74564
75111
  }
74565
75112
  return { node, script: null };
@@ -74731,8 +75278,8 @@ var init_marketing = __esm({
74731
75278
  });
74732
75279
 
74733
75280
  // src/cli/commands/memory.ts
74734
- import { existsSync as existsSync117, unlinkSync as unlinkSync12 } from "fs";
74735
- import { join as join109, dirname as dirname74 } from "path";
75281
+ import { existsSync as existsSync118, unlinkSync as unlinkSync13 } from "fs";
75282
+ import { join as join110, dirname as dirname74 } from "path";
74736
75283
  function collectVault(value, previous) {
74737
75284
  return [...previous, value];
74738
75285
  }
@@ -74914,7 +75461,7 @@ function registerMemoryCommand(program2) {
74914
75461
  const summary = opts.summary ?? (text.length > 200 ? text.slice(0, 197) + "..." : text);
74915
75462
  const references = opts.references ? opts.references.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
74916
75463
  const authors = opts.person ? opts.person.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
74917
- const changelogPath = join109(root, "core", "CHANGELOG.json");
75464
+ const changelogPath = join110(root, "core", "CHANGELOG.json");
74918
75465
  const entry = {
74919
75466
  date: today(),
74920
75467
  type: opts.type ?? "note",
@@ -74932,8 +75479,8 @@ function registerMemoryCommand(program2) {
74932
75479
  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(
74933
75480
  async (slug, opts) => {
74934
75481
  const root = ensureContextRoot();
74935
- const filePath = join109(root, "knowledge", `${slug}.md`);
74936
- if (!existsSync117(filePath)) {
75482
+ const filePath = join110(root, "knowledge", `${slug}.md`);
75483
+ if (!existsSync118(filePath)) {
74937
75484
  error(`Knowledge file not found: ${slug}.md`);
74938
75485
  return;
74939
75486
  }
@@ -74980,8 +75527,8 @@ ${opts.append}
74980
75527
  );
74981
75528
  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) => {
74982
75529
  const root = ensureContextRoot();
74983
- const filePath = join109(root, "knowledge", `${slug}.md`);
74984
- if (!existsSync117(filePath)) {
75530
+ const filePath = join110(root, "knowledge", `${slug}.md`);
75531
+ if (!existsSync118(filePath)) {
74985
75532
  error(`Knowledge file not found: ${slug}.md`);
74986
75533
  return;
74987
75534
  }
@@ -74995,7 +75542,7 @@ ${opts.append}
74995
75542
  return;
74996
75543
  }
74997
75544
  }
74998
- unlinkSync12(filePath);
75545
+ unlinkSync13(filePath);
74999
75546
  success(`Deleted: knowledge/${slug}.md`);
75000
75547
  });
75001
75548
  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) => {
@@ -75098,8 +75645,8 @@ var init_memory = __esm({
75098
75645
  });
75099
75646
 
75100
75647
  // src/cli/commands/embed.ts
75101
- import { existsSync as existsSync118, statSync as statSync29, readFileSync as readFileSync86 } from "fs";
75102
- import { join as join110 } from "path";
75648
+ import { existsSync as existsSync119, statSync as statSync30, readFileSync as readFileSync86 } from "fs";
75649
+ import { join as join111 } from "path";
75103
75650
  function registerEmbedCommand(program2) {
75104
75651
  const embed = program2.command("embed").description("EXPERIMENTAL: manage the local embedding index used by hybrid recall");
75105
75652
  embed.command("refresh").description("Bring the embedding index up to date with the corpus (embeds only changed chunks)").option("--force", "Re-chunk every doc (content hash fully authoritative; catches same-mtime+size edits)").option("--if-present", "Exit quietly unless an embedding cache already exists (safe for cron/sleep: never triggers a first-time model download)").action(async (opts) => {
@@ -75129,14 +75676,14 @@ function registerEmbedCommand(program2) {
75129
75676
  embed.command("status").description("Show embedding cache presence, size, and model").action(() => {
75130
75677
  const root = ensureContextRoot();
75131
75678
  console.log(header("Embedding Index"));
75132
- const path2 = join110(root, ".embeddings", "cache.json");
75133
- if (!existsSync118(path2)) {
75679
+ const path2 = join111(root, ".embeddings", "cache.json");
75680
+ if (!existsSync119(path2)) {
75134
75681
  info("No embedding cache \u2014 hybrid recall has not been used in this vault.");
75135
75682
  info(`Enable: ${source_default.cyan("dreamcontext recall hybrid")} (or DREAMCONTEXT_RECALL_MODE=hybrid), then run ${source_default.cyan("dreamcontext embed refresh")} to prewarm.`);
75136
75683
  return;
75137
75684
  }
75138
75685
  try {
75139
- const raw = statSync29(path2);
75686
+ const raw = statSync30(path2);
75140
75687
  const parsed = JSON.parse(readFileSync86(path2, "utf-8"));
75141
75688
  console.log(` Model: ${parsed.model ?? "unknown"}`);
75142
75689
  console.log(` Docs: ${Object.keys(parsed.docs ?? {}).length}`);
@@ -75163,12 +75710,12 @@ var init_embed = __esm({
75163
75710
  // src/cli/commands/upgrade.ts
75164
75711
  import { execFileSync as execFileSync11 } from "child_process";
75165
75712
  import { dirname as dirname75 } from "path";
75166
- import { existsSync as existsSync119 } from "fs";
75713
+ import { existsSync as existsSync120 } from "fs";
75167
75714
  function defaultInstaller(args) {
75168
75715
  execFileSync11("npm", args, { stdio: "inherit" });
75169
75716
  }
75170
75717
  function defaultProjectUpdater(vault) {
75171
- if (!existsSync119(vault.path)) {
75718
+ if (!existsSync120(vault.path)) {
75172
75719
  return { vault, ok: false, error: "project folder no longer exists" };
75173
75720
  }
75174
75721
  try {
@@ -75570,7 +76117,7 @@ var init_taxonomy3 = __esm({
75570
76117
  });
75571
76118
 
75572
76119
  // src/cli/commands/vaults.ts
75573
- import { basename as basename35, resolve as resolve25 } from "path";
76120
+ import { basename as basename35, resolve as resolve26 } from "path";
75574
76121
  function registerVaultsCommand(program2) {
75575
76122
  const vaults = program2.command("vaults").description("Manage the global vault registry (multi-project)");
75576
76123
  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) => {
@@ -75598,7 +76145,7 @@ function registerVaultsCommand(program2) {
75598
76145
  }
75599
76146
  });
75600
76147
  vaults.command("discover [root]").description("Find every _dream_context/ project under a directory tree (node_modules ignored)").option("--register", "Register newly-found projects as vaults (idempotent; already-registered skipped)").action((root, opts) => {
75601
- const searchRoot = resolve25(root ?? process.cwd());
76148
+ const searchRoot = resolve26(root ?? process.cwd());
75602
76149
  const found = discoverVaults(searchRoot);
75603
76150
  if (found.length === 0) {
75604
76151
  info(`No dreamcontext projects found under ${searchRoot}.`);
@@ -75612,12 +76159,12 @@ function registerVaultsCommand(program2) {
75612
76159
  info(source_default.dim("Re-run with --register to add the new ones to the vault registry."));
75613
76160
  return;
75614
76161
  }
75615
- const registered = new Set(listVaults().map((v) => resolve25(v.path)));
76162
+ const registered = new Set(listVaults().map((v) => resolve26(v.path)));
75616
76163
  const takenNames = new Set(listVaults().map((v) => v.name));
75617
76164
  let added = 0;
75618
76165
  let skipped = 0;
75619
76166
  for (const projectPath of found) {
75620
- if (registered.has(resolve25(projectPath))) {
76167
+ if (registered.has(resolve26(projectPath))) {
75621
76168
  skipped++;
75622
76169
  continue;
75623
76170
  }
@@ -75628,7 +76175,7 @@ function registerVaultsCommand(program2) {
75628
76175
  try {
75629
76176
  const vault = addVault(name, projectPath);
75630
76177
  takenNames.add(vault.name);
75631
- registered.add(resolve25(vault.path));
76178
+ registered.add(resolve26(vault.path));
75632
76179
  added++;
75633
76180
  success(`Registered "${vault.name}" \u2192 ${vault.path}`);
75634
76181
  } catch (err) {
@@ -75753,8 +76300,8 @@ var init_connections3 = __esm({
75753
76300
  });
75754
76301
 
75755
76302
  // src/cli/commands/federation.ts
75756
- import { realpathSync as realpathSync2, unlinkSync as unlinkSync13 } from "fs";
75757
- import { join as join111, sep as sep17 } from "path";
76303
+ import { realpathSync as realpathSync2, unlinkSync as unlinkSync14 } from "fs";
76304
+ import { join as join112, sep as sep18 } from "path";
75758
76305
  function registerFederationCommand(program2) {
75759
76306
  const federation = program2.command("federation").description("Cross-project federation: read peers live; manage leftover copies");
75760
76307
  federation.command("drain").description("(disabled) copy-based ingest is parked on the roadmap \u2014 no-op").action(() => {
@@ -75811,7 +76358,7 @@ function registerFederationCommand(program2) {
75811
76358
  continue;
75812
76359
  }
75813
76360
  try {
75814
- unlinkSync13(f.path);
76361
+ unlinkSync14(f.path);
75815
76362
  removed++;
75816
76363
  console.log(` removed: ${f.relPath}${f.originVault ? source_default.dim(` (from ${f.originVault})`) : ""}`);
75817
76364
  } catch (err) {
@@ -75852,7 +76399,7 @@ function registerFederationCommand(program2) {
75852
76399
  });
75853
76400
  }
75854
76401
  function findFederatedCopies(contextRoot, originVault) {
75855
- const knowledgeDir = join111(contextRoot, "knowledge");
76402
+ const knowledgeDir = join112(contextRoot, "knowledge");
75856
76403
  let files;
75857
76404
  try {
75858
76405
  files = import_fast_glob23.default.sync("**/*.md", { cwd: knowledgeDir, absolute: true, followSymbolicLinks: false });
@@ -75861,7 +76408,7 @@ function findFederatedCopies(contextRoot, originVault) {
75861
76408
  }
75862
76409
  let guard;
75863
76410
  try {
75864
- guard = realpathSync2(knowledgeDir) + sep17;
76411
+ guard = realpathSync2(knowledgeDir) + sep18;
75865
76412
  } catch {
75866
76413
  return [];
75867
76414
  }
@@ -75963,8 +76510,8 @@ var init_people = __esm({
75963
76510
 
75964
76511
  // src/cli/commands/config.ts
75965
76512
  import { dirname as dirname77 } from "path";
75966
- import { existsSync as existsSync120, readFileSync as readFileSync87, writeFileSync as writeFileSync66 } from "fs";
75967
- import { join as join112 } from "path";
76513
+ import { existsSync as existsSync121, readFileSync as readFileSync87, writeFileSync as writeFileSync66 } from "fs";
76514
+ import { join as join113 } from "path";
75968
76515
  function resolveProjectRoot() {
75969
76516
  const contextRoot = resolveContextRoot();
75970
76517
  return contextRoot ? dirname77(contextRoot) : null;
@@ -76137,7 +76684,7 @@ function registerConfigCommand(program2) {
76137
76684
  const liveToken = resolveClickUpToken(projectRoot);
76138
76685
  let connected = false;
76139
76686
  if (liveToken) {
76140
- const contextRoot = join112(projectRoot, "_dream_context");
76687
+ const contextRoot = join113(projectRoot, "_dream_context");
76141
76688
  const probe = createClickUpBackend(contextRoot, readSetupConfig(projectRoot));
76142
76689
  const test = await probe.testConnection();
76143
76690
  if (test.ok) {
@@ -76180,7 +76727,7 @@ function registerConfigCommand(program2) {
76180
76727
  cfgNow = readSetupConfig(projectRoot);
76181
76728
  }
76182
76729
  if (connected && cfgNow?.clickup?.listId) {
76183
- const contextRoot = join112(projectRoot, "_dream_context");
76730
+ const contextRoot = join113(projectRoot, "_dream_context");
76184
76731
  const backend2 = createClickUpBackend(contextRoot, cfgNow);
76185
76732
  if (await esm_default4({ message: "Create the recommended custom fields on the list (urgency, summary, RICE, \u2026)?", default: true })) {
76186
76733
  const result = await backend2.provisionRemote();
@@ -76232,7 +76779,7 @@ function registerConfigCommand(program2) {
76232
76779
  const liveToken = resolveGitHubToken(projectRoot);
76233
76780
  let connected = false;
76234
76781
  if (liveToken) {
76235
- const contextRoot = join112(projectRoot, "_dream_context");
76782
+ const contextRoot = join113(projectRoot, "_dream_context");
76236
76783
  const probe = createGitHubBackend(contextRoot, readSetupConfig(projectRoot));
76237
76784
  const test = await probe.testConnection();
76238
76785
  if (test.ok) {
@@ -76274,7 +76821,7 @@ function registerConfigCommand(program2) {
76274
76821
  cfgNow = readSetupConfig(projectRoot);
76275
76822
  }
76276
76823
  if (connected && cfgNow?.github?.owner && cfgNow?.github?.repo) {
76277
- const contextRoot = join112(projectRoot, "_dream_context");
76824
+ const contextRoot = join113(projectRoot, "_dream_context");
76278
76825
  const backend2 = createGitHubBackend(contextRoot, cfgNow);
76279
76826
  if (await esm_default4({ message: "Create the recommended `dc:*` labels on the repo (sub-status, priority, urgency, \u2026)?", default: true })) {
76280
76827
  const result = await backend2.provisionRemote();
@@ -76318,8 +76865,8 @@ function registerConfigCommand(program2) {
76318
76865
  const contextRoot = resolveContextRoot();
76319
76866
  let userMdSynced = false;
76320
76867
  if (contextRoot) {
76321
- const userMdPath = join112(contextRoot, "core", "1.user.md");
76322
- if (existsSync120(userMdPath)) {
76868
+ const userMdPath = join113(contextRoot, "core", "1.user.md");
76869
+ if (existsSync121(userMdPath)) {
76323
76870
  try {
76324
76871
  const before = readFileSync87(userMdPath, "utf-8");
76325
76872
  const after = ensurePeopleSection(before, roster);
@@ -76382,7 +76929,7 @@ function registerConfigCommand(program2) {
76382
76929
  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) => {
76383
76930
  const projectRoot = requireProjectRoot();
76384
76931
  if (!projectRoot) return;
76385
- const contextRoot = join112(projectRoot, "_dream_context");
76932
+ const contextRoot = join113(projectRoot, "_dream_context");
76386
76933
  const existing = readSetupConfig(projectRoot)?.clickup ?? {};
76387
76934
  const ledger = new SyncLedger(contextRoot);
76388
76935
  const changingList = !!existing.listId && existing.listId !== listId && ledger.readMap().length > 0;
@@ -77684,12 +78231,12 @@ __export(index_exports, {
77684
78231
  function getBanner() {
77685
78232
  const logo = renderBanner();
77686
78233
  const title = `${source_default.bold.cyan("D R E A M")}${source_default.bold.cyanBright(" C O N T E X T")}`;
77687
- const sep18 = source_default.dim("\u2501".repeat(25));
78234
+ const sep19 = source_default.dim("\u2501".repeat(25));
77688
78235
  const tagline = source_default.dim("persistent memory for AI agents");
77689
78236
  const text = [
77690
78237
  "",
77691
78238
  ` ${title}`,
77692
- ` ${sep18}`,
78239
+ ` ${sep19}`,
77693
78240
  ` ${tagline}`
77694
78241
  ].join("\n");
77695
78242
  return "\n" + logo + text + "\n";